X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FCore%2FDxeIplX64Peim%2FDxeLoadX64.c;h=c9792eeaa194cb5abe8e1220542e7bb866b12e4d;hp=9a036e62466edd490ceec3f716233698c07fd63a;hb=5a0c25f8177525999683c4dc875217c3eab93d29;hpb=f78797d5b7d1501c108c8e2c3c8850e06129a209 diff --git a/EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c b/EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c index 9a036e6246..c9792eeaa1 100644 --- a/EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c +++ b/EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c @@ -62,17 +62,17 @@ 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 }; @@ -207,7 +207,9 @@ Returns: EFI_PHYSICAL_ADDRESS BaseOfStack; EFI_PHYSICAL_ADDRESS BspStore; EFI_GUID DxeCoreFileName; + EFI_GUID FirmwareFileName; VOID *DxeCorePe32Data; + VOID *FvImageData; EFI_PHYSICAL_ADDRESS DxeCoreAddress; UINT64 DxeCoreSize; EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint; @@ -247,7 +249,7 @@ Returns: // // Install the PEI Protocols that are shared between PEI and DXE // - PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderX64Protocol (); + PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol (); ASSERT (PeiEfiPeiPeCoffLoader != NULL); // @@ -260,7 +262,8 @@ Returns: // Compute the top of the stack we were allocated. Pre-allocate a 32 bytes // for safety (PpisNeededByDxe and DxeCore). // - TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32; + TopOfStack = 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) @@ -288,6 +291,18 @@ Returns: } } + // + // 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. + // + Status = PeiFindFile ( + EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, + EFI_SECTION_FIRMWARE_VOLUME_IMAGE, + &FirmwareFileName, + &FvImageData + ); + // // Find the DXE Core in a Firmware Volume // @@ -313,7 +328,7 @@ Returns: // // Load the DXE Core from a Firmware Volume // - Status = PeiLoadx64File ( + Status = PeiLoadPeImage ( PeiEfiPeiPeCoffLoader, DxeCorePe32Data, EfiBootServicesData, @@ -418,10 +433,11 @@ Returns: 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) { @@ -434,11 +450,14 @@ Returns: if (!EFI_ERROR (Status)) { Status = PeiProcessFile ( SectionType, - &FfsFileHeader, - Pe32Data + FfsFileHeader, + Pe32Data, + &Hob ); CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID)); - return Status; + if (!EFI_ERROR (Status)) { + return EFI_SUCCESS; + } } Hob.Raw = GET_NEXT_HOB (Hob); } @@ -446,7 +465,7 @@ Returns: } EFI_STATUS -PeiLoadx64File ( +PeiLoadPeImage ( IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader, IN VOID *Pe32Data, IN EFI_MEMORY_TYPE MemoryType, @@ -578,7 +597,7 @@ Returns: // // Relocate DxeIpl into memory by using loadfile service // - Status = PeiLoadx64File ( + Status = PeiLoadPeImage ( PeiEfiPeiPeCoffLoader, (VOID *) (Section + 1), EfiBootServicesData, @@ -649,8 +668,9 @@ Returns: // Status = PeiProcessFile ( EFI_SECTION_PE32, - &FfsHeader, - &Pe32Data + FfsHeader, + &Pe32Data, + NULL ); if (EFI_ERROR (Status)) { @@ -659,7 +679,7 @@ Returns: // // Load the PE image from the FFS file // - Status = PeiLoadx64File ( + Status = PeiLoadPeImage ( PeiEfiPeiPeCoffLoader, Pe32Data, EfiBootServicesData, @@ -674,8 +694,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 ) /*++ @@ -723,9 +744,7 @@ Returns: EFI_GUID TempGuid; EFI_FIRMWARE_VOLUME_HEADER *FvHeader; EFI_COMPRESSION_SECTION *CompressionSection; - EFI_FFS_FILE_HEADER *FfsFileHeader; - - FfsFileHeader = *RealFfsFileHeader; + UINT32 FvAlignment; Status = PeiServicesFfsFindSectionData ( EFI_SECTION_COMPRESSION, @@ -734,7 +753,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)) { // @@ -842,14 +861,24 @@ Returns: switch (CompressionSection->CompressionType) { case EFI_STANDARD_COMPRESSION: - DecompressLibrary = &gTianoDecompress; + if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) { + DecompressLibrary = &gTianoDecompress; + } else { + ASSERT (FALSE); + return EFI_NOT_FOUND; + } break; case EFI_CUSTOMIZED_COMPRESSION: // // Load user customized compression protocol. // - DecompressLibrary = &gCustomDecompress; + if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) { + DecompressLibrary = &gCustomDecompress; + } else { + ASSERT (FALSE); + return EFI_NOT_FOUND; + } break; case EFI_NOT_COMPRESSED: @@ -900,31 +929,64 @@ Returns: ); CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer; - if (CmpSection->Type == EFI_SECTION_RAW) { + if (CmpSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) { + // + // Firmware Volume Image in this Section + // Skip the section header to get FvHeader // - // Skip the section header and - // adjust the pointer alignment to 16 - // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16); + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1); - if (FvHeader->Signature == EFI_FVH_SIGNATURE) { - FfsFileHeader = NULL; + 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); - Status = PeiServicesFfsFindNextFile ( - EFI_FV_FILETYPE_DXE_CORE, - FvHeader, - &FfsFileHeader - ); - - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; + + // + // Set the original FvHob to unused. + // + if (OrigHob != NULL) { + OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED; } - + // - // Reture the FfsHeader that contain Pe32Data. + // when search FvImage Section return true. // - *RealFfsFileHeader = FfsFileHeader; - return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data); + if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) { + *Pe32Data = (VOID *) FvHeader; + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } + } } // @@ -947,6 +1009,9 @@ Returns: 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; @@ -954,11 +1019,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,