Home | History | Annotate | Download | only in SectionExtractionPei
      1 /** @file
      2  Section Extraction PEIM
      3 
      4 Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <PiPei.h>
     16 #include <Ppi/GuidedSectionExtraction.h>
     17 #include <Library/DebugLib.h>
     18 #include <Library/ExtractGuidedSectionLib.h>
     19 #include <Library/MemoryAllocationLib.h>
     20 #include <Library/PeiServicesLib.h>
     21 
     22 /**
     23   The ExtractSection() function processes the input section and
     24   returns a pointer to the section contents. If the section being
     25   extracted does not require processing (if the section
     26   GuidedSectionHeader.Attributes has the
     27   EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
     28   OutputBuffer is just updated to point to the start of the
     29   section's contents. Otherwise, *Buffer must be allocated
     30   from PEI permanent memory.
     31 
     32   @param This                   Indicates the
     33                                 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
     34                                 Buffer containing the input GUIDed section to be
     35                                 processed. OutputBuffer OutputBuffer is
     36                                 allocated from PEI permanent memory and contains
     37                                 the new section stream.
     38   @param InputSection           A pointer to the input buffer, which contains
     39                                 the input section to be processed.
     40   @param OutputBuffer           A pointer to a caller-allocated buffer, whose
     41                                 size is specified by the contents of OutputSize.
     42   @param OutputSize             A pointer to a caller-allocated
     43                                 UINTN in which the size of *OutputBuffer
     44                                 allocation is stored. If the function
     45                                 returns anything other than EFI_SUCCESS,
     46                                 the value of OutputSize is undefined.
     47   @param AuthenticationStatus   A pointer to a caller-allocated
     48                                 UINT32 that indicates the
     49                                 authentication status of the
     50                                 output buffer. If the input
     51                                 section's GuidedSectionHeader.
     52                                 Attributes field has the
     53                                 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
     54                                 bit as clear,
     55                                 AuthenticationStatus must return
     56                                 zero. These bits reflect the
     57                                 status of the extraction
     58                                 operation. If the function
     59                                 returns anything other than
     60                                 EFI_SUCCESS, the value of
     61                                 AuthenticationStatus is
     62                                 undefined.
     63 
     64   @retval EFI_SUCCESS           The InputSection was
     65                                 successfully processed and the
     66                                 section contents were returned.
     67 
     68   @retval EFI_OUT_OF_RESOURCES  The system has insufficient
     69                                 resources to process the request.
     70 
     71   @retval EFI_INVALID_PARAMETER The GUID in InputSection does
     72                                 not match this instance of the
     73                                 GUIDed Section Extraction PPI.
     74 
     75 **/
     76 EFI_STATUS
     77 EFIAPI
     78 CustomGuidedSectionExtract (
     79   IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
     80   IN CONST  VOID                                  *InputSection,
     81   OUT       VOID                                  **OutputBuffer,
     82   OUT       UINTN                                 *OutputSize,
     83   OUT       UINT32                                *AuthenticationStatus
     84   );
     85 
     86 //
     87 // Module global for the Section Extraction PPI instance
     88 //
     89 CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
     90   CustomGuidedSectionExtract
     91 };
     92 
     93 /**
     94   The ExtractSection() function processes the input section and
     95   returns a pointer to the section contents. If the section being
     96   extracted does not require processing (if the section
     97   GuidedSectionHeader.Attributes has the
     98   EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
     99   OutputBuffer is just updated to point to the start of the
    100   section's contents. Otherwise, *Buffer must be allocated
    101   from PEI permanent memory.
    102 
    103   @param This                   Indicates the
    104                                 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
    105                                 Buffer containing the input GUIDed section to be
    106                                 processed. OutputBuffer OutputBuffer is
    107                                 allocated from PEI permanent memory and contains
    108                                 the new section stream.
    109   @param InputSection           A pointer to the input buffer, which contains
    110                                 the input section to be processed.
    111   @param OutputBuffer           A pointer to a caller-allocated buffer, whose
    112                                 size is specified by the contents of OutputSize.
    113   @param OutputSize             A pointer to a caller-allocated
    114                                 UINTN in which the size of *OutputBuffer
    115                                 allocation is stored. If the function
    116                                 returns anything other than EFI_SUCCESS,
    117                                 the value of OutputSize is undefined.
    118   @param AuthenticationStatus   A pointer to a caller-allocated
    119                                 UINT32 that indicates the
    120                                 authentication status of the
    121                                 output buffer. If the input
    122                                 section's GuidedSectionHeader.
    123                                 Attributes field has the
    124                                 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
    125                                 bit as clear,
    126                                 AuthenticationStatus must return
    127                                 zero. These bits reflect the
    128                                 status of the extraction
    129                                 operation. If the function
    130                                 returns anything other than
    131                                 EFI_SUCCESS, the value of
    132                                 AuthenticationStatus is
    133                                 undefined.
    134 
    135   @retval EFI_SUCCESS           The InputSection was
    136                                 successfully processed and the
    137                                 section contents were returned.
    138 
    139   @retval EFI_OUT_OF_RESOURCES  The system has insufficient
    140                                 resources to process the request.
    141 
    142   @retval EFI_INVALID_PARAMETER The GUID in InputSection does
    143                                 not match this instance of the
    144                                 GUIDed Section Extraction PPI.
    145 
    146 **/
    147 EFI_STATUS
    148 EFIAPI
    149 CustomGuidedSectionExtract (
    150   IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
    151   IN CONST  VOID                                  *InputSection,
    152   OUT       VOID                                  **OutputBuffer,
    153   OUT       UINTN                                 *OutputSize,
    154   OUT       UINT32                                *AuthenticationStatus
    155   )
    156 {
    157   EFI_STATUS      Status;
    158   UINT8           *ScratchBuffer;
    159   UINT32          ScratchBufferSize;
    160   UINT32          OutputBufferSize;
    161   UINT16          SectionAttribute;
    162 
    163   //
    164   // Init local variable
    165   //
    166   ScratchBuffer = NULL;
    167 
    168   //
    169   // Call GetInfo to get the size and attribute of input guided section data.
    170   //
    171   Status = ExtractGuidedSectionGetInfo (
    172              InputSection,
    173              &OutputBufferSize,
    174              &ScratchBufferSize,
    175              &SectionAttribute
    176              );
    177 
    178   if (EFI_ERROR (Status)) {
    179     DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
    180     return Status;
    181   }
    182 
    183   if (ScratchBufferSize != 0) {
    184     //
    185     // Allocate scratch buffer
    186     //
    187     ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
    188     if (ScratchBuffer == NULL) {
    189       return EFI_OUT_OF_RESOURCES;
    190     }
    191   }
    192 
    193   if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {
    194     //
    195     // Allocate output buffer
    196     //
    197     *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
    198     if (*OutputBuffer == NULL) {
    199       return EFI_OUT_OF_RESOURCES;
    200     }
    201     DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
    202     //
    203     // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
    204     // skip EFI section header to make section data at page alignment.
    205     //
    206     *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
    207   }
    208 
    209   Status = ExtractGuidedSectionDecode (
    210              InputSection,
    211              OutputBuffer,
    212              ScratchBuffer,
    213              AuthenticationStatus
    214              );
    215   if (EFI_ERROR (Status)) {
    216     //
    217     // Decode failed
    218     //
    219     DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
    220     return Status;
    221   }
    222 
    223   *OutputSize = (UINTN) OutputBufferSize;
    224 
    225   return EFI_SUCCESS;
    226 }
    227 
    228 /**
    229   Main entry for Section Extraction PEIM driver.
    230 
    231   This routine registers the Section Extraction PPIs that have been registered
    232   with the Section Extraction Library.
    233 
    234   @param  FileHandle  Handle of the file being invoked.
    235   @param  PeiServices Describes the list of possible PEI Services.
    236 
    237   @retval EFI_SUCCESS       The entry point is executed successfully.
    238   @retval other             Some error occurs when executing this entry point.
    239 
    240 **/
    241 EFI_STATUS
    242 EFIAPI
    243 SectionExtractionPeiEntry (
    244   IN       EFI_PEI_FILE_HANDLE  FileHandle,
    245   IN CONST EFI_PEI_SERVICES     **PeiServices
    246   )
    247 {
    248   EFI_STATUS              Status;
    249   EFI_GUID                *ExtractHandlerGuidTable;
    250   UINTN                   ExtractHandlerNumber;
    251   EFI_PEI_PPI_DESCRIPTOR  *GuidPpi;
    252 
    253   //
    254   // Get custom extract guided section method guid list
    255   //
    256   ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
    257 
    258   //
    259   // Install custom extraction guid PPI
    260   //
    261   if (ExtractHandlerNumber > 0) {
    262     GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
    263     ASSERT (GuidPpi != NULL);
    264     while (ExtractHandlerNumber-- > 0) {
    265       GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
    266       GuidPpi->Ppi   = (VOID *) &mCustomGuidedSectionExtractionPpi;
    267       GuidPpi->Guid  = &ExtractHandlerGuidTable[ExtractHandlerNumber];
    268       Status = PeiServicesInstallPpi (GuidPpi++);
    269       ASSERT_EFI_ERROR (Status);
    270     }
    271   }
    272 
    273   return EFI_SUCCESS;
    274 }
    275