| /** @file | |
| Section Extraction PEIM | |
| Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #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)); | |
| 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)); | |
| } | |
| 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); | |
| if (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; | |
| } |