Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15827 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			275 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			275 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|  Section Extraction PEIM
 | |
| 
 | |
| Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
 | |
| This program and the accompanying materials                          
 | |
| are licensed and made available under the terms and conditions of the BSD License         
 | |
| which accompanies this distribution.  The full text of the license may be found at        
 | |
| http://opensource.org/licenses/bsd-license.php                                            
 | |
|                                                                                           
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <PiPei.h>
 | |
| #include <Ppi/GuidedSectionExtraction.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/ExtractGuidedSectionLib.h>
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| #include <Library/PeiServicesLib.h>
 | |
| 
 | |
| /**
 | |
|   The ExtractSection() function processes the input section and
 | |
|   returns a pointer to the section contents. If the section being
 | |
|   extracted does not require processing (if the section
 | |
|   GuidedSectionHeader.Attributes has the
 | |
|   EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
 | |
|   OutputBuffer is just updated to point to the start of the
 | |
|   section's contents. Otherwise, *Buffer must be allocated
 | |
|   from PEI permanent memory.
 | |
| 
 | |
|   @param This                   Indicates the
 | |
|                                 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
 | |
|                                 Buffer containing the input GUIDed section to be
 | |
|                                 processed. OutputBuffer OutputBuffer is
 | |
|                                 allocated from PEI permanent memory and contains
 | |
|                                 the new section stream.
 | |
|   @param InputSection           A pointer to the input buffer, which contains
 | |
|                                 the input section to be processed.
 | |
|   @param OutputBuffer           A pointer to a caller-allocated buffer, whose
 | |
|                                 size is specified by the contents of OutputSize.
 | |
|   @param OutputSize             A pointer to a caller-allocated
 | |
|                                 UINTN in which the size of *OutputBuffer
 | |
|                                 allocation is stored. If the function
 | |
|                                 returns anything other than EFI_SUCCESS,
 | |
|                                 the value of OutputSize is undefined.
 | |
|   @param AuthenticationStatus   A pointer to a caller-allocated
 | |
|                                 UINT32 that indicates the
 | |
|                                 authentication status of the
 | |
|                                 output buffer. If the input
 | |
|                                 section's GuidedSectionHeader.
 | |
|                                 Attributes field has the
 | |
|                                 EFI_GUIDED_SECTION_AUTH_STATUS_VALID 
 | |
|                                 bit as clear,
 | |
|                                 AuthenticationStatus must return
 | |
|                                 zero. These bits reflect the
 | |
|                                 status of the extraction
 | |
|                                 operation. If the function
 | |
|                                 returns anything other than
 | |
|                                 EFI_SUCCESS, the value of
 | |
|                                 AuthenticationStatus is
 | |
|                                 undefined.
 | |
|   
 | |
|   @retval EFI_SUCCESS           The InputSection was
 | |
|                                 successfully processed and the
 | |
|                                 section contents were returned.
 | |
|   
 | |
|   @retval EFI_OUT_OF_RESOURCES  The system has insufficient
 | |
|                                 resources to process the request.
 | |
|   
 | |
|   @retval EFI_INVALID_PARAMETER The GUID in InputSection does
 | |
|                                 not match this instance of the
 | |
|                                 GUIDed Section Extraction PPI.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| CustomGuidedSectionExtract (
 | |
|   IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
 | |
|   IN CONST  VOID                                  *InputSection,
 | |
|   OUT       VOID                                  **OutputBuffer,
 | |
|   OUT       UINTN                                 *OutputSize,
 | |
|   OUT       UINT32                                *AuthenticationStatus
 | |
|   );
 | |
| 
 | |
| //
 | |
| // Module global for the Section Extraction PPI instance
 | |
| //
 | |
| CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
 | |
|   CustomGuidedSectionExtract
 | |
| };
 | |
| 
 | |
| /**
 | |
|   The ExtractSection() function processes the input section and
 | |
|   returns a pointer to the section contents. If the section being
 | |
|   extracted does not require processing (if the section
 | |
|   GuidedSectionHeader.Attributes has the
 | |
|   EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
 | |
|   OutputBuffer is just updated to point to the start of the
 | |
|   section's contents. Otherwise, *Buffer must be allocated
 | |
|   from PEI permanent memory.
 | |
| 
 | |
|   @param This                   Indicates the
 | |
|                                 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
 | |
|                                 Buffer containing the input GUIDed section to be
 | |
|                                 processed. OutputBuffer OutputBuffer is
 | |
|                                 allocated from PEI permanent memory and contains
 | |
|                                 the new section stream.
 | |
|   @param InputSection           A pointer to the input buffer, which contains
 | |
|                                 the input section to be processed.
 | |
|   @param OutputBuffer           A pointer to a caller-allocated buffer, whose
 | |
|                                 size is specified by the contents of OutputSize.
 | |
|   @param OutputSize             A pointer to a caller-allocated
 | |
|                                 UINTN in which the size of *OutputBuffer
 | |
|                                 allocation is stored. If the function
 | |
|                                 returns anything other than EFI_SUCCESS,
 | |
|                                 the value of OutputSize is undefined.
 | |
|   @param AuthenticationStatus   A pointer to a caller-allocated
 | |
|                                 UINT32 that indicates the
 | |
|                                 authentication status of the
 | |
|                                 output buffer. If the input
 | |
|                                 section's GuidedSectionHeader.
 | |
|                                 Attributes field has the
 | |
|                                 EFI_GUIDED_SECTION_AUTH_STATUS_VALID 
 | |
|                                 bit as clear,
 | |
|                                 AuthenticationStatus must return
 | |
|                                 zero. These bits reflect the
 | |
|                                 status of the extraction
 | |
|                                 operation. If the function
 | |
|                                 returns anything other than
 | |
|                                 EFI_SUCCESS, the value of
 | |
|                                 AuthenticationStatus is
 | |
|                                 undefined.
 | |
|   
 | |
|   @retval EFI_SUCCESS           The InputSection was
 | |
|                                 successfully processed and the
 | |
|                                 section contents were returned.
 | |
|   
 | |
|   @retval EFI_OUT_OF_RESOURCES  The system has insufficient
 | |
|                                 resources to process the request.
 | |
|   
 | |
|   @retval EFI_INVALID_PARAMETER The GUID in InputSection does
 | |
|                                 not match this instance of the
 | |
|                                 GUIDed Section Extraction PPI.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| CustomGuidedSectionExtract (
 | |
|   IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
 | |
|   IN CONST  VOID                                  *InputSection,
 | |
|   OUT       VOID                                  **OutputBuffer,
 | |
|   OUT       UINTN                                 *OutputSize,
 | |
|   OUT       UINT32                                *AuthenticationStatus
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS      Status;
 | |
|   UINT8           *ScratchBuffer;
 | |
|   UINT32          ScratchBufferSize;
 | |
|   UINT32          OutputBufferSize;
 | |
|   UINT16          SectionAttribute;
 | |
|   
 | |
|   //
 | |
|   // Init local variable
 | |
|   //
 | |
|   ScratchBuffer = NULL;
 | |
| 
 | |
|   //
 | |
|   // Call GetInfo to get the size and attribute of input guided section data.
 | |
|   //
 | |
|   Status = ExtractGuidedSectionGetInfo (
 | |
|              InputSection,
 | |
|              &OutputBufferSize,
 | |
|              &ScratchBufferSize,
 | |
|              &SectionAttribute
 | |
|              );
 | |
|   
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
 | |
|     return Status;
 | |
|   }
 | |
|   
 | |
|   if (ScratchBufferSize != 0) {
 | |
|     //
 | |
|     // Allocate scratch buffer
 | |
|     //
 | |
|     ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
 | |
|     if (ScratchBuffer == NULL) {
 | |
|       return EFI_OUT_OF_RESOURCES;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {  
 | |
|     //
 | |
|     // Allocate output buffer
 | |
|     //
 | |
|     *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
 | |
|     if (*OutputBuffer == NULL) {
 | |
|       return EFI_OUT_OF_RESOURCES;
 | |
|     }
 | |
|     DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
 | |
|     //
 | |
|     // *OutputBuffer still is one section. Adjust *OutputBuffer offset, 
 | |
|     // skip EFI section header to make section data at page alignment.
 | |
|     //
 | |
|     *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
 | |
|   }
 | |
|   
 | |
|   Status = ExtractGuidedSectionDecode (
 | |
|              InputSection, 
 | |
|              OutputBuffer,
 | |
|              ScratchBuffer,
 | |
|              AuthenticationStatus
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     //
 | |
|     // Decode failed
 | |
|     //
 | |
|     DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
 | |
|     return Status;
 | |
|   }
 | |
|   
 | |
|   *OutputSize = (UINTN) OutputBufferSize;
 | |
|   
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Main entry for Section Extraction PEIM driver.
 | |
|   
 | |
|   This routine registers the Section Extraction PPIs that have been registered 
 | |
|   with the Section Extraction Library.
 | |
| 
 | |
|   @param  FileHandle  Handle of the file being invoked.
 | |
|   @param  PeiServices Describes the list of possible PEI Services.
 | |
| 
 | |
|   @retval EFI_SUCCESS       The entry point is executed successfully.
 | |
|   @retval other             Some error occurs when executing this entry point.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| SectionExtractionPeiEntry (
 | |
|   IN       EFI_PEI_FILE_HANDLE  FileHandle,
 | |
|   IN CONST EFI_PEI_SERVICES     **PeiServices
 | |
|   ) 
 | |
| {
 | |
|   EFI_STATUS              Status;
 | |
|   EFI_GUID                *ExtractHandlerGuidTable;
 | |
|   UINTN                   ExtractHandlerNumber;
 | |
|   EFI_PEI_PPI_DESCRIPTOR  *GuidPpi;
 | |
| 
 | |
|   //
 | |
|   // Get custom extract guided section method guid list 
 | |
|   //
 | |
|   ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
 | |
|   
 | |
|   //
 | |
|   // Install custom extraction guid PPI
 | |
|   //
 | |
|   if (ExtractHandlerNumber > 0) {
 | |
|     GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
 | |
|     ASSERT (GuidPpi != NULL);
 | |
|     while (ExtractHandlerNumber-- > 0) {
 | |
|       GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
 | |
|       GuidPpi->Ppi   = (VOID *) &mCustomGuidedSectionExtractionPpi;
 | |
|       GuidPpi->Guid  = &ExtractHandlerGuidTable[ExtractHandlerNumber];
 | |
|       Status = PeiServicesInstallPpi (GuidPpi++);
 | |
|       ASSERT_EFI_ERROR (Status);
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   return EFI_SUCCESS;
 | |
| }
 |