summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Core/DxeIplPeim
diff options
context:
space:
mode:
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2007-08-08 10:17:57 +0000
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2007-08-08 10:17:57 +0000
commitd8c79a815f9e993b741ec38cd39498e674e1739e (patch)
tree271166e1be541db9e47baa8ea9b12488afb57999 /MdeModulePkg/Core/DxeIplPeim
parentc76af11785efe49e91b2cd3eef61cebf61e00549 (diff)
downloadedk2-d8c79a815f9e993b741ec38cd39498e674e1739e.zip
edk2-d8c79a815f9e993b741ec38cd39498e674e1739e.tar.gz
edk2-d8c79a815f9e993b741ec38cd39498e674e1739e.tar.bz2
Update CustomDecompress library to support algorithm guid and Update DxeIpl and DxeCore to support custom decompress guid section parse.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3573 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Core/DxeIplPeim')
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DecompressLibrary.h47
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeIpl.h4
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeLoad.c670
3 files changed, 361 insertions, 360 deletions
diff --git a/MdeModulePkg/Core/DxeIplPeim/DecompressLibrary.h b/MdeModulePkg/Core/DxeIplPeim/DecompressLibrary.h
deleted file mode 100644
index 31cb3e8..0000000
--- a/MdeModulePkg/Core/DxeIplPeim/DecompressLibrary.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*++
-
-Copyright (c) 2006, Intel Corporation
-All rights reserved. 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.
-
-Module Name:
-
- DecompressLibraryHob.h
-
-Abstract:
-
- Declaration of HOB that is used to pass decompressor library functions from PEI to DXE
-
---*/
-
-#ifndef __DECOMPRESS_LIBRARY_H__
-#define __DECOMPRESS_LIBRARY_H__
-
-typedef
-RETURN_STATUS
-(EFIAPI *DECOMPRESS_LIBRARY_GET_INFO) (
- IN CONST VOID *Source,
- IN UINT32 SourceSize,
- OUT UINT32 *DestinationSize,
- OUT UINT32 *ScratchSize
- );
-
-typedef
-RETURN_STATUS
-(EFIAPI *DECOMPRESS_LIBRARY_DECOMPRESS) (
- IN CONST VOID *Source,
- IN OUT VOID *Destination,
- IN OUT VOID *Scratch
- );
-
-typedef struct {
- DECOMPRESS_LIBRARY_GET_INFO GetInfo;
- DECOMPRESS_LIBRARY_DECOMPRESS Decompress;
-} DECOMPRESS_LIBRARY;
-
-#endif
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
index 6438391..1907077 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
@@ -59,7 +59,7 @@ extern BOOLEAN gInMemory;
EFI_STATUS
PeiFindFile (
IN UINT8 Type,
- IN UINT16 SectionType,
+ IN EFI_SECTION_TYPE SectionType,
OUT EFI_GUID *FileName,
OUT VOID **Pe32Data
)
@@ -124,7 +124,7 @@ HandOffToDxeCore (
EFI_STATUS
PeiProcessFile (
- IN UINT16 SectionType,
+ IN EFI_SECTION_TYPE SectionType,
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
OUT VOID **Pe32Data,
IN EFI_PEI_HOB_POINTERS *OrigHob
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
index b749fb1..e7359e5 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
@@ -21,12 +21,21 @@ Abstract:
--*/
#include "DxeIpl.h"
+#include <Ppi/GuidedSectionExtraction.h>
// porting note remove later
-#include "DecompressLibrary.h"
#include "FrameworkPei.h"
// end of remove later
+EFI_STATUS
+CustomDecompressExtractSection (
+ IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
+ IN CONST VOID *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize,
+ OUT UINT32 *AuthenticationStatus
+);
+
BOOLEAN gInMemory = FALSE;
//
@@ -41,6 +50,10 @@ static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi = {
DxeIplLoadFile
};
+static EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomDecompressExtractiongPpi = {
+ CustomDecompressExtractSection
+};
+
static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
@@ -60,16 +73,6 @@ static EFI_PEI_PPI_DESCRIPTOR mPpiSignal = {
NULL
};
-GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gEfiDecompress = {
- UefiDecompressGetInfo,
- UefiDecompress
-};
-
-GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gCustomDecompress = {
- CustomDecompressGetInfo,
- CustomDecompress
-};
-
EFI_STATUS
EFIAPI
PeimInitializeDxeIpl (
@@ -96,7 +99,10 @@ Returns:
EFI_STATUS Status;
EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader;
EFI_BOOT_MODE BootMode;
-
+ EFI_GUID **DecompressGuidList;
+ UINT32 DecompressMethodNumber;
+ EFI_PEI_PPI_DESCRIPTOR *GuidPpi;
+
Status = PeiServicesGetBootMode (&BootMode);
ASSERT_EFI_ERROR (Status);
@@ -112,6 +118,35 @@ Returns:
Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);
} else {
//
+ // Get custom decompress method guid list
+ //
+ DecompressGuidList = NULL;
+ DecompressMethodNumber = 0;
+ Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ DecompressGuidList = (EFI_GUID **) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber * sizeof (EFI_GUID *)));
+ ASSERT (DecompressGuidList != NULL);
+ Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);
+ }
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Install custom decompress extraction guid ppi
+ //
+ if (DecompressMethodNumber > 0) {
+ GuidPpi = NULL;
+ GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR)));
+ ASSERT (GuidPpi != NULL);
+ while (DecompressMethodNumber-- > 0) {
+ GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ GuidPpi->Ppi = &mCustomDecompressExtractiongPpi;
+ GuidPpi->Guid = DecompressGuidList [DecompressMethodNumber];
+ Status = PeiServicesInstallPpi (GuidPpi++);
+ ASSERT_EFI_ERROR(Status);
+ }
+ }
+
+ //
// Install FvFileLoader and DxeIpl PPIs.
//
Status = PeiServicesInstallPpi (mPpiList);
@@ -205,7 +240,6 @@ Returns:
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
ASSERT (PeiEfiPeiPeCoffLoader != NULL);
-
//
// Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file
// The file found will be processed by PeiProcessFile: It will first be decompressed to
@@ -252,6 +286,14 @@ Returns:
);
//
+ // Add HOB for the PE/COFF Loader Protocol
+ //
+ BuildGuidDataHob (
+ &gEfiPeiPeCoffLoaderGuid,
+ (VOID *)&PeiEfiPeiPeCoffLoader,
+ sizeof (VOID *)
+ );
+ //
// Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
//
REPORT_STATUS_CODE (
@@ -259,38 +301,6 @@ Returns:
EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
);
- if (FeaturePcdGet (PcdDxeIplBuildShareCodeHobs)) {
- if (FeaturePcdGet (PcdDxeIplSupportEfiDecompress)) {
- //
- // Add HOB for the EFI Decompress Protocol
- //
- BuildGuidDataHob (
- &gEfiDecompressProtocolGuid,
- (VOID *)&gEfiDecompress,
- sizeof (gEfiDecompress)
- );
- }
- if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) {
- //
- // Add HOB for the user customized Decompress Protocol
- //
- BuildGuidDataHob (
- &gEfiCustomizedDecompressProtocolGuid,
- (VOID *)&gCustomDecompress,
- sizeof (gCustomDecompress)
- );
- }
-
- //
- // Add HOB for the PE/COFF Loader Protocol
- //
- BuildGuidDataHob (
- &gEfiPeiPeCoffLoaderGuid,
- (VOID *)&PeiEfiPeiPeCoffLoader,
- sizeof (VOID *)
- );
- }
-
//
// Transfer control to the DXE Core
// The handoff state is simply a pointer to the HOB list
@@ -311,7 +321,7 @@ Returns:
EFI_STATUS
PeiFindFile (
IN UINT8 Type,
- IN UINT16 SectionType,
+ IN EFI_SECTION_TYPE SectionType,
OUT EFI_GUID *FileName,
OUT VOID **Pe32Data
)
@@ -609,7 +619,7 @@ Returns:
EFI_STATUS
PeiProcessFile (
- IN UINT16 SectionType,
+ IN EFI_SECTION_TYPE SectionType,
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
OUT VOID **Pe32Data,
IN EFI_PEI_HOB_POINTERS *OrigHob
@@ -635,8 +645,6 @@ Returns:
--*/
{
EFI_STATUS Status;
- VOID *SectionData;
- DECOMPRESS_LIBRARY *DecompressLibrary;
UINT8 *DstBuffer;
UINT8 *ScratchBuffer;
UINT32 DstBufferSize;
@@ -649,327 +657,367 @@ Returns:
EFI_COMMON_SECTION_HEADER *Section;
UINTN SectionLength;
UINTN OccupiedSectionLength;
- UINT64 FileSize;
- UINT32 AuthenticationStatus;
- EFI_PEI_SECTION_EXTRACTION_PPI *SectionExtract;
- UINT32 BufferSize;
- UINT8 *Buffer;
- EFI_PEI_SECURITY_PPI *Security;
- BOOLEAN StartCrisisRecovery;
- EFI_GUID TempGuid;
+ UINTN FileSize;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
EFI_COMPRESSION_SECTION *CompressionSection;
+ EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *SectionExtract;
+ UINT32 AuthenticationStatus;
//
- // Initialize local variables.
+ // First try to find the required section in this ffs file.
//
- DecompressLibrary = NULL;
- DstBuffer = NULL;
- DstBufferSize = 0;
-
Status = PeiServicesFfsFindSectionData (
- EFI_SECTION_COMPRESSION,
+ SectionType,
FfsFileHeader,
- &SectionData
+ Pe32Data
);
-
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
//
- // First process the compression section
+ // If not found, the required section may be in guided or compressed section.
+ // So, search guided or compressed section to process
//
- if (!EFI_ERROR (Status)) {
+ Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));
+ FileSize = FfsFileHeader->Size[0] & 0xFF;
+ FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;
+ FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
+ FileSize &= 0x00FFFFFF;
+ OccupiedSectionLength = 0;
+
+ do {
//
- // Yes, there is a compression section, so extract the contents
- // Decompress the image here
+ // Initialize local variables.
//
- Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));
+ DstBuffer = NULL;
+ DstBufferSize = 0;
- do {
- SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
- OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
+ Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
+ SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
+ OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
+ //
+ // Was the DXE Core file encapsulated in a GUID'd section?
+ //
+ if (Section->Type == EFI_SECTION_GUID_DEFINED) {
//
- // Was the DXE Core file encapsulated in a GUID'd section?
+ // Set a default authenticatino state
//
- if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+ AuthenticationStatus = 0;
+ //
+ // Locate extract guid section ppi
+ //
+ Status = PeiServicesLocatePpi (
+ (EFI_GUID *) (Section + 1),
+ 0,
+ NULL,
+ (VOID **)&SectionExtract
+ );
+ if (EFI_ERROR (Status)) {
//
- // This following code constitutes the addition of the security model
- // to the DXE IPL.
+ // ignore the unknown guid section
//
+ continue;
+ }
+ //
+ // Extract the contents from guid section
+ //
+ Status = SectionExtract->ExtractSection (
+ SectionExtract,
+ (VOID *) Section,
+ (VOID **) &DstBuffer,
+ &DstBufferSize,
+ &AuthenticationStatus
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Extract section content failed - %r\n", Status));
+ return Status;
+ }
+ //
+ // Todo check AuthenticationStatus and do the verify
+ //
+ } else if (Section->Type == EFI_SECTION_COMPRESSION) {
+ //
+ // This is a compression set, expand it
+ //
+ CompressionSection = (EFI_COMPRESSION_SECTION *) Section;
+
+ switch (CompressionSection->CompressionType) {
+ case EFI_STANDARD_COMPRESSION:
//
- // Set a default authenticatino state
+ // Load EFI standard compression.
+ // For compressed data, decompress them to dstbuffer.
//
- AuthenticationStatus = 0;
-
- Status = PeiServicesLocatePpi (
- &gEfiPeiSectionExtractionPpiGuid,
- 0,
- NULL,
- (VOID **)&SectionExtract
+ Status = UefiDecompressGetInfo (
+ (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+ (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
+ &DstBufferSize,
+ &ScratchBufferSize
);
-
if (EFI_ERROR (Status)) {
- return Status;
+ //
+ // GetInfo failed
+ //
+ DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
}
//
- // Verify Authentication State
+ // Allocate scratch buffer
//
- CopyMem (&TempGuid, Section + 1, sizeof (EFI_GUID));
-
- Status = SectionExtract->PeiGetSection (
- GetPeiServicesTablePointer(),
- SectionExtract,
- (EFI_SECTION_TYPE *) &SectionType,
- &TempGuid,
- 0,
- (VOID **) &Buffer,
- &BufferSize,
- &AuthenticationStatus
- );
-
- if (EFI_ERROR (Status)) {
- return Status;
+ ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
+ if (ScratchBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
}
//
- // If not ask the Security PPI, if exists, for disposition
+ // Allocate destination buffer
+ //
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
+ if (DstBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
//
+ // Call decompress function
//
- Status = PeiServicesLocatePpi (
- &gEfiPeiSecurityPpiGuid,
- 0,
- NULL,
- (VOID **)&Security
- );
+ Status = UefiDecompress (
+ (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+ DstBuffer,
+ ScratchBuffer
+ );
if (EFI_ERROR (Status)) {
- return Status;
+ //
+ // Decompress failed
+ //
+ DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
}
+ break;
- Status = Security->AuthenticationState (
- GetPeiServicesTablePointer(),
- (struct _EFI_PEI_SECURITY_PPI *) Security,
- AuthenticationStatus,
- FfsFileHeader,
- &StartCrisisRecovery
- );
+ // porting note the original branch for customized compress is removed, it should be change to use GUID compress
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ case EFI_NOT_COMPRESSED:
//
- // If there is a security violation, report to caller and have
- // the upper-level logic possible engender a crisis recovery
+ // Allocate destination buffer
//
- if (StartCrisisRecovery) {
- return EFI_SECURITY_VIOLATION;
+ DstBufferSize = CompressionSection->UncompressedLength;
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
+ if (DstBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
}
- }
-
- if (Section->Type == EFI_SECTION_PE32) {
//
- // This is what we want
+ // stream is not actually compressed, just encapsulated. So just copy it.
//
- *Pe32Data = (VOID *) (Section + 1);
- return EFI_SUCCESS;
- } else if (Section->Type == EFI_SECTION_COMPRESSION) {
+ CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
+ break;
+
+ default:
//
- // This is a compression set, expand it
+ // Don't support other unknown compression type.
//
- CompressionSection = (EFI_COMPRESSION_SECTION *) Section;
-
- switch (CompressionSection->CompressionType) {
- case EFI_STANDARD_COMPRESSION:
- //
- // Load EFI standard compression.
- //
- if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {
- DecompressLibrary = &gEfiDecompress;
- } else {
- ASSERT (FALSE);
- return EFI_NOT_FOUND;
- }
- break;
-
- // porting note the original branch for customized compress is removed, it should be change to use GUID compress
+ ASSERT_EFI_ERROR (Status);
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ //
+ // ignore other type sections
+ //
+ continue;
+ }
- case EFI_NOT_COMPRESSED:
- //
- // Allocate destination buffer
- //
- DstBufferSize = CompressionSection->UncompressedLength;
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
- if (DstBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // stream is not actually compressed, just encapsulated. So just copy it.
+ //
+ // Extract contents from guided or compressed sections.
+ // Loop the decompressed data searching for expected section.
+ //
+ CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;
+ CmpFileData = (VOID *) DstBuffer;
+ CmpFileSize = DstBufferSize;
+ do {
+ CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;
+ if (CmpSection->Type == SectionType) {
+ //
+ // This is what we want
+ //
+ if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
+ //
+ // Firmware Volume Image in this Section
+ // Skip the section header to get FvHeader
//
- CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
- break;
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);
- default:
- //
- // Don't support other unknown compression type.
- //
- ASSERT_EFI_ERROR (Status);
- return EFI_NOT_FOUND;
- }
-
- if (CompressionSection->CompressionType != EFI_NOT_COMPRESSED) {
- //
- // For compressed data, decompress them to dstbuffer.
- //
- Status = DecompressLibrary->GetInfo (
- (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
- (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
- &DstBufferSize,
- &ScratchBufferSize
- );
- if (EFI_ERROR (Status)) {
+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
//
- // GetInfo failed
+ // Because FvLength in FvHeader is UINT64 type,
+ // so FvHeader must meed at least 8 bytes alignment.
+ // If current FvImage base address doesn't meet its alignment,
+ // we need to reload this FvImage to another correct memory address.
//
- DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));
- return EFI_NOT_FOUND;
- }
-
- //
- // Allocate scratch buffer
- //
- ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
- if (ScratchBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Allocate destination buffer
- //
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
- if (DstBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Call decompress function
- //
- Status = DecompressLibrary->Decompress (
- (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
- DstBuffer,
- ScratchBuffer
- );
- if (EFI_ERROR (Status)) {
+ if (((UINTN) FvHeader % sizeof (UINT64)) != 0) {
+ CopyMem (DstBuffer, FvHeader, (UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER));
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;
+ }
+
//
- // Decompress failed
+ // Build new FvHob for new decompressed Fv image.
//
- DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));
- return EFI_NOT_FOUND;
- }
- }
-
- //
- // Decompress successfully.
- // Loop the decompressed data searching for expected section.
- //
- CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;
- CmpFileData = (VOID *) DstBuffer;
- CmpFileSize = DstBufferSize;
- do {
- CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;
- if (CmpSection->Type == SectionType) {
+ BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);
+
//
- // This is what we want
+ // Set the original FvHob to unused.
//
- if (SectionType == EFI_SECTION_PE32) {
- *Pe32Data = (VOID *) (CmpSection + 1);
- return EFI_SUCCESS;
- } else if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
- //
- // Firmware Volume Image in this Section
- // Skip the section header to get FvHeader
- //
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);
-
- if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
- //
- // Because FvLength in FvHeader is UINT64 type,
- // so FvHeader must meed at least 8 bytes alignment.
- // If current FvImage base address doesn't meet its alignment,
- // we need to reload this FvImage to another correct memory address.
- //
- if (((UINTN) FvHeader % sizeof (UINT64)) != 0) {
- DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), sizeof (UINT64));
- if (DstBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (DstBuffer, FvHeader, (UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER));
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;
- }
-
- //
- // Build new FvHob for new decompressed Fv image.
- //
- BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);
-
- //
- // Set the original FvHob to unused.
- //
- if (OrigHob != NULL) {
- OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;
- }
-
- //
- // return found FvImage data.
- //
- *Pe32Data = (VOID *) FvHeader;
- return EFI_SUCCESS;
- }
+ if (OrigHob != NULL) {
+ OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;
}
+ //
+ // return found FvImage data.
+ //
+ *Pe32Data = (VOID *) FvHeader;
+ return EFI_SUCCESS;
}
- OccupiedCmpSectionLength = GET_OCCUPIED_SIZE (CmpSectionLength, 4);
- CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);
- } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);
+ } else {
+ //
+ // direct return the found section.
+ //
+ *Pe32Data = (VOID *) (CmpSection + 1);
+ return EFI_SUCCESS;
+ }
}
- //
- // End of the decompression activity
- //
+ OccupiedCmpSectionLength = GET_OCCUPIED_SIZE (CmpSectionLength, 4);
+ CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);
+ } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);
+ } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section + OccupiedSectionLength - (UINT8 *) FfsFileHeader) < FileSize);
- Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
- FileSize = FfsFileHeader->Size[0] & 0xFF;
- FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;
- FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
- FileSize &= 0x00FFFFFF;
- } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);
-
- //
- // search all sections (compression and non compression) in this FFS, don't
- // find expected section.
- //
- return EFI_NOT_FOUND;
- } else {
+ //
+ // search all sections (compression and non compression) in this FFS, don't
+ // find expected section.
+ //
+ return EFI_NOT_FOUND;
+}
+
+/**
+ 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 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.
+
+ @reteval EFI_INVALID_PARAMETER The GUID in InputSection does
+ not match this instance of the
+ GUIDed Section Extraction PPI.
+**/
+EFI_STATUS
+CustomDecompressExtractSection (
+ 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 ScratchSize;
+ UINT32 SectionLength;
+
+ //
+ // Set authentic value to zero.
+ //
+ *AuthenticationStatus = 0;
+ //
+ // Calculate Section data Size
+ //
+ SectionLength = *(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff;
+ //
+ // Get compressed data information
+ //
+ Status = CustomDecompressGetInfo (
+ (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),
+ (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),
+ SectionLength - sizeof (EFI_GUID_DEFINED_SECTION),
+ OutputSize,
+ &ScratchSize
+ );
+ if (EFI_ERROR (Status)) {
//
- // For those FFS that doesn't contain compression section, directly search
- // PE or TE section in this FFS.
+ // GetInfo failed
//
+ DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));
+ return Status;
+ }
- Status = PeiServicesFfsFindSectionData (
- EFI_SECTION_PE32,
- FfsFileHeader,
- &SectionData
- );
-
- if (EFI_ERROR (Status)) {
- Status = PeiServicesFfsFindSectionData (
- EFI_SECTION_TE,
- FfsFileHeader,
- &SectionData
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
+ //
+ // Allocate scratch buffer
+ //
+ ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchSize));
+ if (ScratchBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Allocate destination buffer
+ //
+ *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (*OutputSize));
+ if (*OutputBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
}
- *Pe32Data = SectionData;
+ //
+ // Call decompress function
+ //
+ Status = CustomDecompress (
+ (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),
+ (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),
+ *OutputBuffer,
+ ScratchBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Decompress failed
+ //
+ DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));
+ return Status;
+ }
+
return EFI_SUCCESS;
}
-