X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FCore%2FDxeIplPeim%2FDxeLoad.c;h=cd38a03e5787af9b11b2cda3d019717728a5ec11;hp=8dbc3763d656cd4e97481df19abfd6cbb2eea2b0;hb=2008636e60313c220e8b2517e4acae710e3aa320;hpb=b32a39b3287e8f03b7701619e140f814a0a61a48 diff --git a/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c b/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c index 8dbc3763d6..cd38a03e57 100644 --- a/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -241,14 +241,6 @@ Returns: ); ASSERT_EFI_ERROR (Status); - // - // Transfer control to the DXE Core - // The handoff state is simply a pointer to the HOB list - // - - Status = PeiServicesInstallPpi (&mPpiSignal); - ASSERT_EFI_ERROR (Status); - // // Add HOB for the DXE Core // @@ -309,8 +301,13 @@ Returns: ); } + // + // 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); + HandOffToDxeCore (DxeCoreEntryPoint, HobList, &mPpiSignal); // // If we get here, then the DXE Core returned. This is an error // Dxe Core should not return. @@ -358,14 +355,12 @@ 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; // @@ -388,7 +383,10 @@ Returns: &Hob ); CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID)); - if (!EFI_ERROR (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; } } @@ -657,7 +655,6 @@ Returns: UINTN SectionLength; UINTN OccupiedSectionLength; UINT64 FileSize; - EFI_GUID_DEFINED_SECTION *GuidedSectionHeader; UINT32 AuthenticationStatus; EFI_PEI_SECTION_EXTRACTION_PPI *SectionExtract; UINT32 BufferSize; @@ -667,7 +664,13 @@ Returns: EFI_GUID TempGuid; EFI_FIRMWARE_VOLUME_HEADER *FvHeader; EFI_COMPRESSION_SECTION *CompressionSection; - UINT32 FvAlignment; + + // + // Initialize local variables. + // + DecompressLibrary = NULL; + DstBuffer = NULL; + DstBufferSize = 0; Status = PeiServicesFfsFindSectionData ( EFI_SECTION_COMPRESSION, @@ -693,10 +696,6 @@ Returns: // 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 @@ -784,8 +783,11 @@ Returns: switch (CompressionSection->CompressionType) { case EFI_STANDARD_COMPRESSION: + // + // Load EFI standard compression. + // if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) { - DecompressLibrary = &gTianoDecompress; + DecompressLibrary = &gEfiDecompress; } else { ASSERT (FALSE); return EFI_NOT_FOUND; @@ -794,7 +796,7 @@ Returns: case EFI_CUSTOMIZED_COMPRESSION: // - // Load user customized compression protocol. + // Load user customized compression. // if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) { DecompressLibrary = &gCustomDecompress; @@ -805,129 +807,138 @@ Returns: break; case EFI_NOT_COMPRESSED: - default: // - // Need to support not compressed file + // Allocate destination buffer // - ASSERT_EFI_ERROR (Status); - return EFI_NOT_FOUND; - } + 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; - Status = DecompressLibrary->GetInfo ( - (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1), - (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION), - &DstBufferSize, - &ScratchBufferSize - ); - if (EFI_ERROR (Status)) { + default: // - // GetInfo failed + // Don't support other unknown compression type. // + ASSERT_EFI_ERROR (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 - ); - - CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer; - if (CmpSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) { - // - // Firmware Volume Image in this Section - // Skip the section header to get FvHeader + + if (CompressionSection->CompressionType != EFI_NOT_COMPRESSED) { // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1); - - if (FvHeader->Signature == EFI_FVH_SIGNATURE) { - // - // Adjust Fv Base Address Alignment based on Align Attributes in Fv Header - // - - // - // When FvImage support Alignment, we need to check whether - // its alignment is correct. - // - if (FvHeader->Attributes | EFI_FVB_ALIGNMENT_CAP) { - - // - // Calculate the mini alignment for this FvImage - // - FvAlignment = 1 << (LowBitSet32 (FvHeader->Attributes >> 16) + 1); - - // - // If current FvImage base address doesn't meet the its alignment, - // we need to reload this FvImage to another correct memory address. - // - if (((UINTN) FvHeader % FvAlignment) != 0) { - DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength), FvAlignment); - if (DstBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - CopyMem (DstBuffer, FvHeader, (UINTN) FvHeader->FvLength); - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer; - } - } - // - // Build new FvHob for new decompressed Fv image. - // - BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength); - + // 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)) { // - // Set the original FvHob to unused. + // GetInfo failed // - if (OrigHob != NULL) { - OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED; - } - + 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)) { // - // when search FvImage Section return true. + // Decompress failed // - if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) { - *Pe32Data = (VOID *) FvHeader; - return EFI_SUCCESS; - } else { - return EFI_NOT_FOUND; - } - + 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 = GET_OCCUPIED_SIZE (CmpSectionLength, 4); CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength); } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);