--*/\r
\r
#include "DxeIpl.h"\r
+#include <Ppi/GuidedSectionExtraction.h>\r
\r
// porting note remove later\r
-#include "DecompressLibrary.h"\r
#include "FrameworkPei.h"\r
// end of remove later\r
\r
+EFI_STATUS\r
+CustomDecompressExtractSection (\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
BOOLEAN gInMemory = FALSE;\r
\r
//\r
DxeIplLoadFile\r
};\r
\r
+static EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomDecompressExtractiongPpi = {\r
+ CustomDecompressExtractSection\r
+};\r
+\r
static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {\r
{\r
EFI_PEI_PPI_DESCRIPTOR_PPI,\r
NULL\r
};\r
\r
-GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gEfiDecompress = {\r
- UefiDecompressGetInfo,\r
- UefiDecompress\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gCustomDecompress = {\r
- CustomDecompressGetInfo,\r
- CustomDecompress\r
-};\r
-\r
EFI_STATUS\r
EFIAPI\r
PeimInitializeDxeIpl (\r
EFI_STATUS Status;\r
EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader;\r
EFI_BOOT_MODE BootMode;\r
-\r
+ EFI_GUID **DecompressGuidList;\r
+ UINT32 DecompressMethodNumber;\r
+ EFI_PEI_PPI_DESCRIPTOR *GuidPpi;\r
+ \r
Status = PeiServicesGetBootMode (&BootMode);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);\r
} else {\r
+ //\r
+ // Get custom decompress method guid list \r
+ //\r
+ DecompressGuidList = NULL;\r
+ DecompressMethodNumber = 0;\r
+ Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);\r
+ if (Status == EFI_OUT_OF_RESOURCES) {\r
+ DecompressGuidList = (EFI_GUID **) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber * sizeof (EFI_GUID *)));\r
+ ASSERT (DecompressGuidList != NULL);\r
+ Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);\r
+ }\r
+ ASSERT_EFI_ERROR(Status);\r
+\r
+ //\r
+ // Install custom decompress extraction guid ppi\r
+ //\r
+ if (DecompressMethodNumber > 0) {\r
+ GuidPpi = NULL;\r
+ GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR)));\r
+ ASSERT (GuidPpi != NULL);\r
+ while (DecompressMethodNumber-- > 0) {\r
+ GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
+ GuidPpi->Ppi = &mCustomDecompressExtractiongPpi;\r
+ GuidPpi->Guid = DecompressGuidList [DecompressMethodNumber];\r
+ Status = PeiServicesInstallPpi (GuidPpi++);\r
+ ASSERT_EFI_ERROR(Status);\r
+ }\r
+ }\r
+ \r
//\r
// Install FvFileLoader and DxeIpl PPIs.\r
//\r
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
ASSERT (PeiEfiPeiPeCoffLoader != NULL);\r
\r
-\r
//\r
// Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file\r
// The file found will be processed by PeiProcessFile: It will first be decompressed to\r
);\r
\r
//\r
+ // Add HOB for the PE/COFF Loader Protocol\r
+ //\r
+ BuildGuidDataHob (\r
+ &gEfiPeiPeCoffLoaderGuid,\r
+ (VOID *)&PeiEfiPeiPeCoffLoader,\r
+ sizeof (VOID *)\r
+ );\r
+ //\r
// Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT\r
//\r
REPORT_STATUS_CODE (\r
EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT\r
);\r
\r
- if (FeaturePcdGet (PcdDxeIplBuildShareCodeHobs)) {\r
- if (FeaturePcdGet (PcdDxeIplSupportEfiDecompress)) {\r
- //\r
- // Add HOB for the EFI Decompress Protocol\r
- //\r
- BuildGuidDataHob (\r
- &gEfiDecompressProtocolGuid,\r
- (VOID *)&gEfiDecompress,\r
- sizeof (gEfiDecompress)\r
- );\r
- }\r
- if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) {\r
- //\r
- // Add HOB for the user customized Decompress Protocol\r
- //\r
- BuildGuidDataHob (\r
- &gEfiCustomizedDecompressProtocolGuid,\r
- (VOID *)&gCustomDecompress,\r
- sizeof (gCustomDecompress)\r
- );\r
- }\r
-\r
- //\r
- // Add HOB for the PE/COFF Loader Protocol\r
- //\r
- BuildGuidDataHob (\r
- &gEfiPeiPeCoffLoaderGuid,\r
- (VOID *)&PeiEfiPeiPeCoffLoader,\r
- sizeof (VOID *)\r
- );\r
- }\r
-\r
//\r
// Transfer control to the DXE Core\r
// The handoff state is simply a pointer to the HOB list\r
EFI_STATUS\r
PeiFindFile (\r
IN UINT8 Type,\r
- IN UINT16 SectionType,\r
+ IN EFI_SECTION_TYPE SectionType,\r
OUT EFI_GUID *FileName,\r
OUT VOID **Pe32Data\r
)\r
\r
EFI_STATUS\r
PeiProcessFile (\r
- IN UINT16 SectionType,\r
+ IN EFI_SECTION_TYPE SectionType,\r
IN EFI_FFS_FILE_HEADER *FfsFileHeader,\r
OUT VOID **Pe32Data,\r
IN EFI_PEI_HOB_POINTERS *OrigHob\r
--*/\r
{\r
EFI_STATUS Status;\r
- VOID *SectionData;\r
- DECOMPRESS_LIBRARY *DecompressLibrary;\r
UINT8 *DstBuffer;\r
UINT8 *ScratchBuffer;\r
- UINT32 DstBufferSize;\r
+ UINTN DstBufferSize;\r
UINT32 ScratchBufferSize;\r
EFI_COMMON_SECTION_HEADER *CmpSection;\r
UINTN CmpSectionLength;\r
EFI_COMMON_SECTION_HEADER *Section;\r
UINTN SectionLength;\r
UINTN OccupiedSectionLength;\r
- UINT64 FileSize;\r
- UINT32 AuthenticationStatus;\r
- EFI_PEI_SECTION_EXTRACTION_PPI *SectionExtract;\r
- UINT32 BufferSize;\r
- UINT8 *Buffer;\r
- EFI_PEI_SECURITY_PPI *Security;\r
- BOOLEAN StartCrisisRecovery;\r
- EFI_GUID TempGuid;\r
+ UINTN FileSize;\r
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
EFI_COMPRESSION_SECTION *CompressionSection;\r
+ EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *SectionExtract;\r
+ UINT32 AuthenticationStatus;\r
\r
//\r
- // Initialize local variables.\r
+ // First try to find the required section in this ffs file.\r
//\r
- DecompressLibrary = NULL;\r
- DstBuffer = NULL;\r
- DstBufferSize = 0;\r
-\r
Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_COMPRESSION,\r
+ SectionType,\r
FfsFileHeader,\r
- &SectionData\r
+ Pe32Data\r
);\r
-\r
+ if (!EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
//\r
- // First process the compression section\r
+ // If not found, the required section may be in guided or compressed section.\r
+ // So, search guided or compressed section to process\r
//\r
- if (!EFI_ERROR (Status)) {\r
+ Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));\r
+ FileSize = FfsFileHeader->Size[0] & 0xFF;\r
+ FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;\r
+ FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;\r
+ FileSize &= 0x00FFFFFF;\r
+ OccupiedSectionLength = 0;\r
+\r
+ do {\r
//\r
- // Yes, there is a compression section, so extract the contents\r
- // Decompress the image here\r
+ // Initialize local variables.\r
//\r
- Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));\r
+ DstBuffer = NULL;\r
+ DstBufferSize = 0; \r
\r
- do {\r
- SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
- OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
+ Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
+ SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
+ OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
\r
+ //\r
+ // Was the DXE Core file encapsulated in a GUID'd section?\r
+ //\r
+ if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
+ //\r
+ // Set a default authenticatino state\r
//\r
- // Was the DXE Core file encapsulated in a GUID'd section?\r
+ AuthenticationStatus = 0;\r
//\r
- if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
+ // Locate extract guid section ppi\r
+ //\r
+ Status = PeiServicesLocatePpi (\r
+ (EFI_GUID *) (Section + 1),\r
+ 0,\r
+ NULL,\r
+ (VOID **)&SectionExtract\r
+ );\r
\r
+ if (EFI_ERROR (Status)) {\r
//\r
- // This following code constitutes the addition of the security model\r
- // to the DXE IPL.\r
+ // ignore the unknown guid section\r
//\r
+ continue;\r
+ }\r
+ //\r
+ // Extract the contents from guid section\r
+ //\r
+ Status = SectionExtract->ExtractSection (\r
+ SectionExtract,\r
+ (VOID *) Section,\r
+ (VOID **) &DstBuffer,\r
+ &DstBufferSize,\r
+ &AuthenticationStatus\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Extract section content failed - %r\n", Status));\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // Todo check AuthenticationStatus and do the verify\r
+ //\r
+ } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
+ //\r
+ // This is a compression set, expand it\r
+ //\r
+ CompressionSection = (EFI_COMPRESSION_SECTION *) Section;\r
+\r
+ switch (CompressionSection->CompressionType) {\r
+ case EFI_STANDARD_COMPRESSION:\r
//\r
- // Set a default authenticatino state\r
+ // Load EFI standard compression.\r
+ // For compressed data, decompress them to dstbuffer.\r
//\r
- AuthenticationStatus = 0;\r
-\r
- Status = PeiServicesLocatePpi (\r
- &gEfiPeiSectionExtractionPpiGuid,\r
- 0,\r
- NULL,\r
- (VOID **)&SectionExtract\r
+ Status = UefiDecompressGetInfo (\r
+ (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
+ (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
+ (UINT32 *) &DstBufferSize,\r
+ &ScratchBufferSize\r
);\r
-\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ //\r
+ // GetInfo failed\r
+ //\r
+ DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
+ return EFI_NOT_FOUND;\r
}\r
//\r
- // Verify Authentication State\r
+ // Allocate scratch buffer\r
//\r
- CopyMem (&TempGuid, Section + 1, sizeof (EFI_GUID));\r
-\r
- Status = SectionExtract->PeiGetSection (\r
- GetPeiServicesTablePointer(),\r
- SectionExtract,\r
- (EFI_SECTION_TYPE *) &SectionType,\r
- &TempGuid,\r
- 0,\r
- (VOID **) &Buffer,\r
- &BufferSize,\r
- &AuthenticationStatus\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
+ if (ScratchBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
- // If not ask the Security PPI, if exists, for disposition\r
+ // Allocate destination buffer\r
//\r
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+ if (DstBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
//\r
- Status = PeiServicesLocatePpi (\r
- &gEfiPeiSecurityPpiGuid,\r
- 0,\r
- NULL,\r
- (VOID **)&Security\r
- );\r
+ // Call decompress function\r
+ //\r
+ Status = UefiDecompress (\r
+ (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
+ DstBuffer,\r
+ ScratchBuffer\r
+ );\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ //\r
+ // Decompress failed\r
+ //\r
+ DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));\r
+ return EFI_NOT_FOUND;\r
}\r
+ break;\r
\r
- Status = Security->AuthenticationState (\r
- GetPeiServicesTablePointer(),\r
- (struct _EFI_PEI_SECURITY_PPI *) Security,\r
- AuthenticationStatus,\r
- FfsFileHeader,\r
- &StartCrisisRecovery\r
- );\r
+ // porting note the original branch for customized compress is removed, it should be change to use GUID compress\r
\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ case EFI_NOT_COMPRESSED:\r
//\r
- // If there is a security violation, report to caller and have\r
- // the upper-level logic possible engender a crisis recovery\r
+ // Allocate destination buffer\r
//\r
- if (StartCrisisRecovery) {\r
- return EFI_SECURITY_VIOLATION;\r
+ DstBufferSize = CompressionSection->UncompressedLength;\r
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+ if (DstBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
- }\r
-\r
- if (Section->Type == EFI_SECTION_PE32) {\r
//\r
- // This is what we want\r
+ // stream is not actually compressed, just encapsulated. So just copy it.\r
//\r
- *Pe32Data = (VOID *) (Section + 1);\r
- return EFI_SUCCESS;\r
- } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
+ CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
+ break;\r
+\r
+ default:\r
//\r
- // This is a compression set, expand it\r
+ // Don't support other unknown compression type.\r
//\r
- CompressionSection = (EFI_COMPRESSION_SECTION *) Section;\r
-\r
- switch (CompressionSection->CompressionType) {\r
- case EFI_STANDARD_COMPRESSION:\r
- //\r
- // Load EFI standard compression.\r
- //\r
- if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {\r
- DecompressLibrary = &gEfiDecompress;\r
- } else {\r
- ASSERT (FALSE);\r
- return EFI_NOT_FOUND;\r
- }\r
- break;\r
-\r
- // porting note the original branch for customized compress is removed, it should be change to use GUID compress\r
+ ASSERT_EFI_ERROR (Status);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ } else {\r
+ //\r
+ // ignore other type sections\r
+ //\r
+ continue;\r
+ }\r
\r
- case EFI_NOT_COMPRESSED:\r
- //\r
- // Allocate destination buffer\r
- //\r
- DstBufferSize = CompressionSection->UncompressedLength;\r
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
- if (DstBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // stream is not actually compressed, just encapsulated. So just copy it.\r
+ //\r
+ // Extract contents from guided or compressed sections.\r
+ // Loop the decompressed data searching for expected section.\r
+ //\r
+ CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
+ CmpFileData = (VOID *) DstBuffer;\r
+ CmpFileSize = DstBufferSize;\r
+ do {\r
+ CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;\r
+ if (CmpSection->Type == SectionType) {\r
+ //\r
+ // This is what we want\r
+ //\r
+ if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+ // \r
+ // Firmware Volume Image in this Section\r
+ // Skip the section header to get FvHeader\r
//\r
- CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
- break;\r
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);\r
\r
- default:\r
- //\r
- // Don't support other unknown compression type.\r
- //\r
- ASSERT_EFI_ERROR (Status);\r
- return EFI_NOT_FOUND;\r
- }\r
- \r
- if (CompressionSection->CompressionType != EFI_NOT_COMPRESSED) {\r
- //\r
- // For compressed data, decompress them to dstbuffer.\r
- //\r
- Status = DecompressLibrary->GetInfo (\r
- (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
- (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
- &DstBufferSize,\r
- &ScratchBufferSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
//\r
- // GetInfo failed\r
+ // Because FvLength in FvHeader is UINT64 type, \r
+ // so FvHeader must meed at least 8 bytes alignment.\r
+ // If current FvImage base address doesn't meet its alignment,\r
+ // we need to reload this FvImage to another correct memory address.\r
//\r
- DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
- return EFI_NOT_FOUND;\r
- }\r
- \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
- // Allocate destination buffer\r
- //\r
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
- if (DstBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- \r
- //\r
- // Call decompress function\r
- //\r
- Status = DecompressLibrary->Decompress (\r
- (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
- DstBuffer,\r
- ScratchBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
+ if (((UINTN) FvHeader % sizeof (UINT64)) != 0) {\r
+ CopyMem (DstBuffer, FvHeader, (UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer; \r
+ }\r
+\r
//\r
- // Decompress failed\r
+ // Build new FvHob for new decompressed Fv image.\r
//\r
- DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
-\r
- //\r
- // Decompress successfully.\r
- // Loop the decompressed data searching for expected section.\r
- //\r
- CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
- CmpFileData = (VOID *) DstBuffer;\r
- CmpFileSize = DstBufferSize;\r
- do {\r
- CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;\r
- if (CmpSection->Type == SectionType) {\r
+ BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
+ \r
//\r
- // This is what we want\r
+ // Set the original FvHob to unused.\r
//\r
- if (SectionType == EFI_SECTION_PE32) {\r
- *Pe32Data = (VOID *) (CmpSection + 1);\r
- return EFI_SUCCESS;\r
- } else if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
- // \r
- // Firmware Volume Image in this Section\r
- // Skip the section header to get FvHeader\r
- //\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);\r
- \r
- if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
- //\r
- // Because FvLength in FvHeader is UINT64 type, \r
- // so FvHeader must meed at least 8 bytes alignment.\r
- // If current FvImage base address doesn't meet its alignment,\r
- // we need to reload this FvImage to another correct memory address.\r
- //\r
- if (((UINTN) FvHeader % sizeof (UINT64)) != 0) {\r
- DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), sizeof (UINT64));\r
- if (DstBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- CopyMem (DstBuffer, FvHeader, (UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer; \r
- }\r
-\r
- //\r
- // Build new FvHob for new decompressed Fv image.\r
- //\r
- BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
- \r
- //\r
- // Set the original FvHob to unused.\r
- //\r
- if (OrigHob != NULL) {\r
- OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;\r
- }\r
- \r
- //\r
- // return found FvImage data.\r
- //\r
- *Pe32Data = (VOID *) FvHeader;\r
- return EFI_SUCCESS;\r
- }\r
+ if (OrigHob != NULL) {\r
+ OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;\r
}\r
+ //\r
+ // return found FvImage data.\r
+ //\r
+ *Pe32Data = (VOID *) FvHeader;\r
+ return EFI_SUCCESS;\r
}\r
- OccupiedCmpSectionLength = GET_OCCUPIED_SIZE (CmpSectionLength, 4);\r
- CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);\r
- } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);\r
+ } else {\r
+ //\r
+ // direct return the found section.\r
+ //\r
+ *Pe32Data = (VOID *) (CmpSection + 1);\r
+ return EFI_SUCCESS;\r
+ }\r
}\r
- //\r
- // End of the decompression activity\r
- //\r
+ OccupiedCmpSectionLength = GET_OCCUPIED_SIZE (CmpSectionLength, 4);\r
+ CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);\r
+ } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);\r
+ } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section + OccupiedSectionLength - (UINT8 *) FfsFileHeader) < FileSize);\r
\r
- Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
- FileSize = FfsFileHeader->Size[0] & 0xFF;\r
- FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;\r
- FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;\r
- FileSize &= 0x00FFFFFF;\r
- } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);\r
- \r
- //\r
- // search all sections (compression and non compression) in this FFS, don't \r
- // find expected section.\r
- //\r
- return EFI_NOT_FOUND;\r
- } else {\r
+ //\r
+ // search all sections (compression and non compression) in this FFS, don't \r
+ // find expected section.\r
+ //\r
+ return EFI_NOT_FOUND;\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
+ \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
+ \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
+ @reteval EFI_INVALID_PARAMETER The GUID in InputSection does\r
+ not match this instance of the\r
+ GUIDed Section Extraction PPI.\r
+**/\r
+EFI_STATUS\r
+CustomDecompressExtractSection (\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 ScratchSize;\r
+ UINT32 SectionLength;\r
+ UINT32 DestinationSize; \r
+ \r
+ //\r
+ // Set authentic value to zero.\r
+ //\r
+ *AuthenticationStatus = 0;\r
+ //\r
+ // Calculate Section data Size\r
+ //\r
+ SectionLength = *(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff;\r
+ //\r
+ // Get compressed data information\r
+ //\r
+ Status = CustomDecompressGetInfo (\r
+ (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),\r
+ (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),\r
+ SectionLength - sizeof (EFI_GUID_DEFINED_SECTION),\r
+ &DestinationSize,\r
+ &ScratchSize\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
//\r
- // For those FFS that doesn't contain compression section, directly search \r
- // PE or TE section in this FFS.\r
+ // GetInfo failed\r
//\r
+ DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));\r
+ return Status;\r
+ }\r
\r
- Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_PE32,\r
- FfsFileHeader,\r
- &SectionData\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_TE,\r
- FfsFileHeader,\r
- &SectionData\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
+ //\r
+ // Allocate scratch buffer\r
+ //\r
+ ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchSize));\r
+ if (ScratchBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Allocate destination buffer\r
+ //\r
+ *OutputSize = (UINTN) DestinationSize;\r
+ *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (*OutputSize));\r
+ if (*OutputBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- *Pe32Data = SectionData;\r
+ //\r
+ // Call decompress function\r
+ //\r
+ Status = CustomDecompress (\r
+ (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),\r
+ (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),\r
+ *OutputBuffer,\r
+ ScratchBuffer\r
+ );\r
\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Decompress failed\r
+ //\r
+ DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));\r
+ return Status;\r
+ }\r
+ \r
return EFI_SUCCESS;\r
}\r
-\r