X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FCore%2FDxeIplPeim%2FDxeLoad.c;h=1133f6286074afa8d88cc1eaff040176316d0176;hp=fdd6c24b2ee03fba3be644957a91f352fc3774e0;hb=7689c0808e654d53f28c7993cb97a5dd9ecc9627;hpb=395859376eb5342ea1fd06f0c8d8682be8921d6f diff --git a/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c b/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c index fdd6c24b2e..1133f62860 100644 --- a/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -20,7 +20,7 @@ Abstract: --*/ -#include +#include "DxeIpl.h" BOOLEAN gInMemory = FALSE; @@ -36,22 +36,17 @@ static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi = { DxeIplLoadFile }; -static EFI_PEI_PPI_DESCRIPTOR mPpiLoadFile = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), +static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, &gEfiPeiFvFileLoaderPpiGuid, &mLoadFilePpi -}; - -static EFI_PEI_PPI_DESCRIPTOR mPpiList = { + }, + { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiDxeIplPpiGuid, &mDxeIplPpi -}; - -static EFI_PEI_PPI_DESCRIPTOR mPpiPeiInMemory = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gPeiInMemoryGuid, - NULL + } }; static EFI_PEI_PPI_DESCRIPTOR mPpiSignal = { @@ -60,38 +55,21 @@ static EFI_PEI_PPI_DESCRIPTOR mPpiSignal = { NULL }; -DECOMPRESS_LIBRARY gEfiDecompress = { +GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gEfiDecompress = { UefiDecompressGetInfo, UefiDecompress }; -DECOMPRESS_LIBRARY gTianoDecompress = { +GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gTianoDecompress = { TianoDecompressGetInfo, TianoDecompress }; -DECOMPRESS_LIBRARY gCustomDecompress = { +GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gCustomDecompress = { CustomDecompressGetInfo, CustomDecompress }; -STATIC -UINTN -GetOccupiedSize ( - IN UINTN ActualSize, - IN UINTN Alignment - ) -{ - UINTN OccupiedSize; - - OccupiedSize = ActualSize; - while ((OccupiedSize & (Alignment - 1)) != 0) { - OccupiedSize++; - } - - return OccupiedSize; -} - EFI_STATUS EFIAPI PeimInitializeDxeIpl ( @@ -120,17 +98,9 @@ Returns: EFI_BOOT_MODE BootMode; Status = PeiServicesGetBootMode (&BootMode); - ASSERT_EFI_ERROR (Status); - Status = PeiServicesLocatePpi ( - &gPeiInMemoryGuid, - 0, - NULL, - NULL - ); - - if (EFI_ERROR (Status) && (BootMode != BOOT_ON_S3_RESUME)) { + if (!gInMemory && (BootMode != BOOT_ON_S3_RESUME)) { // // The DxeIpl has not yet been shadowed // @@ -140,38 +110,15 @@ Returns: // Shadow DxeIpl and then re-run its entry point // Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader); - if (EFI_ERROR (Status)) { - return Status; - } - } else { - if (BootMode != BOOT_ON_S3_RESUME) { - // - // The DxeIpl has been shadowed // - gInMemory = TRUE; - - // - // Install LoadFile PPI + // Install FvFileLoader and DxeIpl PPIs. // - Status = PeiServicesInstallPpi (&mPpiLoadFile); - - if (EFI_ERROR (Status)) { - return Status; - } - } - // - // Install DxeIpl PPI - // - PeiServicesInstallPpi (&mPpiList); - - if (EFI_ERROR (Status)) { - return Status; - } - + Status = PeiServicesInstallPpi (mPpiList); + ASSERT_EFI_ERROR(Status); } - - return EFI_SUCCESS; + + return Status; } EFI_STATUS @@ -200,12 +147,10 @@ Returns: --*/ { EFI_STATUS Status; - VOID *TopOfStack; - VOID *BaseOfStack; - EFI_PHYSICAL_ADDRESS BspStore; EFI_GUID DxeCoreFileName; EFI_GUID FirmwareFileName; VOID *Pe32Data; + VOID *FvImageData; EFI_PHYSICAL_ADDRESS DxeCoreAddress; UINT64 DxeCoreSize; EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint; @@ -215,102 +160,25 @@ Returns: EFI_PEI_S3_RESUME_PPI *S3Resume; // PERF_START (PeiServices, L"DxeIpl", NULL, 0); - TopOfStack = NULL; - BaseOfStack = NULL; - BspStore = 0; - Status = EFI_SUCCESS; // // if in S3 Resume, restore configure // Status = PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR(Status); - if (!EFI_ERROR (Status) && (BootMode == BOOT_ON_S3_RESUME)) { + if (BootMode == BOOT_ON_S3_RESUME) { Status = PeiServicesLocatePpi ( &gEfiPeiS3ResumePpiGuid, 0, NULL, (VOID **)&S3Resume ); - ASSERT_EFI_ERROR (Status); Status = S3Resume->S3RestoreConfig (PeiServices); - ASSERT_EFI_ERROR (Status); - } - - Status = EFI_SUCCESS; - - // - // Install the PEI Protocols that are shared between PEI and DXE - // - PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol (); - ASSERT (PeiEfiPeiPeCoffLoader != NULL); - - - // - // Allocate 128KB for the Stack - // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE)); - ASSERT (BaseOfStack != NULL); - - // - // Compute the top of the stack we were allocated. Pre-allocate a UINTN - // for safety. - // - TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - // - // Add architecture-specifc HOBs (including the BspStore HOB) - // - Status = CreateArchSpecificHobs (&BspStore); - - ASSERT_EFI_ERROR (Status); - - // - // Add HOB for the EFI Decompress Protocol - // - BuildGuidDataHob ( - &gEfiDecompressProtocolGuid, - (VOID *)&gEfiDecompress, - sizeof (gEfiDecompress) - ); - - // - // Add HOB for the Tiano Decompress Protocol - // - BuildGuidDataHob ( - &gEfiTianoDecompressProtocolGuid, - (VOID *)&gTianoDecompress, - sizeof (gTianoDecompress) - ); - - // - // 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 *) - ); - - // - // See if we are in crisis recovery - // - Status = PeiServicesGetBootMode (&BootMode); - - if (!EFI_ERROR (Status) && (BootMode == BOOT_IN_RECOVERY_MODE)) { + } else if (BootMode == BOOT_IN_RECOVERY_MODE) { Status = PeiServicesLocatePpi ( &gEfiPeiRecoveryModulePpiGuid, @@ -318,8 +186,8 @@ Returns: NULL, (VOID **)&PeiRecovery ); - ASSERT_EFI_ERROR (Status); + Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status)); @@ -332,19 +200,23 @@ Returns: } // - // Find the EFI_FV_FILETYPE_RAW type compressed Firmware Volume file in FTW spare block + // Install the PEI Protocols that are shared between PEI and DXE + // + 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 - // a normal FV, then a corresponding FV type hob will be built which is provided for DXE - // core to find and dispatch drivers in this FV. Because PeiProcessFile typically checks - // for EFI_FV_FILETYPE_DXE_CORE type file, in this condition we need not check returned - // status + // a normal FV, then a corresponding FV type hob will be built. // Status = PeiFindFile ( - EFI_FV_FILETYPE_RAW, - EFI_SECTION_PE32, - &FirmwareFileName, - &Pe32Data - ); + EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, + EFI_SECTION_FIRMWARE_VOLUME_IMAGE, + &FirmwareFileName, + &FvImageData + ); // // Find the DXE Core in a Firmware Volume @@ -355,29 +227,18 @@ Returns: &DxeCoreFileName, &Pe32Data ); - ASSERT_EFI_ERROR (Status); // // Load the DXE Core from a Firmware Volume // Status = PeiLoadFile ( - PeiEfiPeiPeCoffLoader, - Pe32Data, - &DxeCoreAddress, - &DxeCoreSize, - &DxeCoreEntryPoint - ); - - ASSERT_EFI_ERROR (Status); - - // - // Transfer control to the DXE Core - // The handoff state is simply a pointer to the HOB list - // - - Status = PeiServicesInstallPpi (&mPpiSignal); - + PeiEfiPeiPeCoffLoader, + Pe32Data, + &DxeCoreAddress, + &DxeCoreSize, + &DxeCoreEntryPoint + ); ASSERT_EFI_ERROR (Status); // @@ -398,15 +259,55 @@ Returns: EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT ); - DEBUG ((EFI_D_INFO, "DXE Core Entry\n")); - SwitchIplStacks ( - (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint, - HobList.Raw, - NULL, - TopOfStack, - (VOID *) (UINTN) BspStore - ); + if (FeaturePcdGet (PcdDxeIplBuildShareCodeHobs)) { + if (FeaturePcdGet (PcdDxeIplSupportEfiDecompress)) { + // + // Add HOB for the EFI Decompress Protocol + // + BuildGuidDataHob ( + &gEfiDecompressProtocolGuid, + (VOID *)&gEfiDecompress, + sizeof (gEfiDecompress) + ); + } + if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) { + // + // Add HOB for the Tiano Decompress Protocol + // + BuildGuidDataHob ( + &gEfiTianoDecompressProtocolGuid, + (VOID *)&gTianoDecompress, + sizeof (gTianoDecompress) + ); + } + 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 + // + + DEBUG ((EFI_D_INFO, "DXE Core Entry Point 0x%08x\n", (UINTN) DxeCoreEntryPoint)); + HandOffToDxeCore (DxeCoreEntryPoint, HobList, &mPpiSignal); // // If we get here, then the DXE Core returned. This is an error // Dxe Core should not return. @@ -454,22 +355,26 @@ Returns: { EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; EFI_FFS_FILE_HEADER *FfsFileHeader; - VOID *SectionData; EFI_STATUS Status; EFI_PEI_HOB_POINTERS Hob; FwVolHeader = NULL; FfsFileHeader = NULL; - SectionData = NULL; + Status = EFI_SUCCESS; // - // Foreach Firmware Volume, look for a specified type - // of file and break out when one is found + // For each Firmware Volume, look for a specified type + // of file and break out until no one is found // Hob.Raw = GetHobList (); while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) { FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (Hob.FirmwareVolume->BaseAddress); + // + // Make sure the FV HOB does not get corrupted. + // + ASSERT (FwVolHeader->Signature == EFI_FVH_SIGNATURE); + Status = PeiServicesFfsFindNextFile ( Type, FwVolHeader, @@ -478,11 +383,17 @@ Returns: if (!EFI_ERROR (Status)) { Status = PeiProcessFile ( SectionType, - &FfsFileHeader, - Pe32Data + FfsFileHeader, + Pe32Data, + &Hob ); CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID)); - return Status; + // + // Find all Fv type ffs to get all FvImage and add them into FvHob + // + if (!EFI_ERROR (Status) && (Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) { + return EFI_SUCCESS; + } } Hob.Raw = GET_NEXT_HOB (Hob); } @@ -608,7 +519,7 @@ Returns: while ((Section->Type != EFI_SECTION_PE32) && (Section->Type != EFI_SECTION_TE)) { SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff; - OccupiedSectionLength = GetOccupiedSize (SectionLength, 4); + OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength); } // @@ -624,14 +535,9 @@ Returns: if (Status == EFI_SUCCESS) { // - // Install PeiInMemory to indicate the Dxeipl is shadowed + // Set gInMemory global variable to TRUE to indicate the dxeipl is shadowed. // - Status = PeiServicesInstallPpi (&mPpiPeiInMemory); - - if (EFI_ERROR (Status)) { - return Status; - } - + *(BOOLEAN *) ((UINTN) &gInMemory + (UINTN) DxeIplEntryPoint - (UINTN) _ModuleEntryPoint) = TRUE; Status = ((EFI_PEIM_ENTRY_POINT) (UINTN) DxeIplEntryPoint) (DxeIplFileHeader, GetPeiServicesTablePointer()); } @@ -689,8 +595,9 @@ Returns: // Status = PeiProcessFile ( EFI_SECTION_PE32, - &FfsHeader, - &Pe32Data + FfsHeader, + &Pe32Data, + NULL ); if (EFI_ERROR (Status)) { @@ -713,8 +620,9 @@ Returns: EFI_STATUS PeiProcessFile ( IN UINT16 SectionType, - IN OUT EFI_FFS_FILE_HEADER **RealFfsFileHeader, - OUT VOID **Pe32Data + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + OUT VOID **Pe32Data, + IN EFI_PEI_HOB_POINTERS *OrigHob ) /*++ @@ -752,7 +660,6 @@ Returns: UINTN SectionLength; UINTN OccupiedSectionLength; UINT64 FileSize; - EFI_GUID_DEFINED_SECTION *GuidedSectionHeader; UINT32 AuthenticationStatus; EFI_PEI_SECTION_EXTRACTION_PPI *SectionExtract; UINT32 BufferSize; @@ -762,9 +669,13 @@ Returns: EFI_GUID TempGuid; EFI_FIRMWARE_VOLUME_HEADER *FvHeader; EFI_COMPRESSION_SECTION *CompressionSection; - EFI_FFS_FILE_HEADER *FfsFileHeader; - FfsFileHeader = *RealFfsFileHeader; + // + // Initialize local variables. + // + DecompressLibrary = NULL; + DstBuffer = NULL; + DstBufferSize = 0; Status = PeiServicesFfsFindSectionData ( EFI_SECTION_COMPRESSION, @@ -773,7 +684,7 @@ Returns: ); // - // Upon finding a DXE Core file, see if there is first a compression section + // First process the compression section // if (!EFI_ERROR (Status)) { // @@ -784,16 +695,12 @@ Returns: do { SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff; - OccupiedSectionLength = GetOccupiedSize (SectionLength, 4); + OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); // // Was the DXE Core file encapsulated in a GUID'd section? // if (Section->Type == EFI_SECTION_GUID_DEFINED) { - // - // Locate the GUID'd Section Extractor - // - GuidedSectionHeader = (VOID *) (Section + 1); // // This following code constitutes the addition of the security model @@ -881,111 +788,169 @@ Returns: switch (CompressionSection->CompressionType) { case EFI_STANDARD_COMPRESSION: - DecompressLibrary = &gTianoDecompress; + // + // Load EFI standard compression. + // + if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) { + DecompressLibrary = &gEfiDecompress; + } else { + ASSERT (FALSE); + return EFI_NOT_FOUND; + } break; case EFI_CUSTOMIZED_COMPRESSION: // - // Load user customized compression protocol. + // Load user customized compression. // - DecompressLibrary = &gCustomDecompress; + if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) { + DecompressLibrary = &gCustomDecompress; + } else { + ASSERT (FALSE); + return EFI_NOT_FOUND; + } break; 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. + // + CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize); + break; + default: // - // Need to support not compressed file + // Don't support other unknown compression type. // ASSERT_EFI_ERROR (Status); return EFI_NOT_FOUND; } - - Status = DecompressLibrary->GetInfo ( - (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1), - (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION), - &DstBufferSize, - &ScratchBufferSize - ); - if (EFI_ERROR (Status)) { + + if (CompressionSection->CompressionType != EFI_NOT_COMPRESSED) { // - // GetInfo failed + // For compressed data, decompress them to dstbuffer. // - 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 - ); - - CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer; - if (CmpSection->Type == EFI_SECTION_RAW) { + Status = DecompressLibrary->GetInfo ( + (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1), + (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION), + &DstBufferSize, + &ScratchBufferSize + ); + if (EFI_ERROR (Status)) { + // + // GetInfo failed + // + DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status)); + return EFI_NOT_FOUND; + } + // - // Skip the section header and - // adjust the pointer alignment to 16 + // Allocate scratch buffer // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16); - - if (FvHeader->Signature == EFI_FVH_SIGNATURE) { - FfsFileHeader = NULL; - BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength); - Status = PeiServicesFfsFindNextFile ( - EFI_FV_FILETYPE_DXE_CORE, - FvHeader, - &FfsFileHeader - ); - - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - + 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)) { // - // Reture the FfsHeader that contain Pe32Data. + // Decompress failed // - *RealFfsFileHeader = FfsFileHeader; - return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data); + 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 == EFI_SECTION_PE32) { + if (CmpSection->Type == SectionType) { // // This is what we want // - *Pe32Data = (VOID *) (CmpSection + 1); - return EFI_SUCCESS; + 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; + } + } } - - OccupiedCmpSectionLength = GetOccupiedSize (CmpSectionLength, 4); + OccupiedCmpSectionLength = GET_OCCUPIED_SIZE (CmpSectionLength, 4); CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength); } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize); } + // + // End of the decompression activity + // Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength); FileSize = FfsFileHeader->Size[0] & 0xFF; @@ -993,11 +958,17 @@ Returns: FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000; FileSize &= 0x00FFFFFF; } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize); - + // - // End of the decompression activity + // search all sections (compression and non compression) in this FFS, don't + // find expected section. // + return EFI_NOT_FOUND; } else { + // + // For those FFS that doesn't contain compression section, directly search + // PE or TE section in this FFS. + // Status = PeiServicesFfsFindSectionData ( EFI_SECTION_PE32, @@ -1021,3 +992,4 @@ Returns: return EFI_SUCCESS; } +