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