Enhance DxeIpl module to support EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE ffs type, and Enhance DxeIpl module decompression function to load the decompressed FvImage to the memory address aligned at FvImage required alignment.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1875 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lgao4 2006-10-31 08:22:25 +00:00
parent 0cc00bf06b
commit d66974717c
2 changed files with 87 additions and 36 deletions

View File

@ -103,7 +103,7 @@ DxeLoadCore (
EFI_STATUS EFI_STATUS
PeiProcessFile ( PeiProcessFile (
IN UINT16 SectionType, IN UINT16 SectionType,
IN OUT EFI_FFS_FILE_HEADER **RealFfsFileHeader, IN EFI_FFS_FILE_HEADER *FfsFileHeader,
OUT VOID **Pe32Data, OUT VOID **Pe32Data,
IN EFI_PEI_HOB_POINTERS *OrigHob IN EFI_PEI_HOB_POINTERS *OrigHob
); );

View File

@ -207,7 +207,9 @@ Returns:
EFI_PHYSICAL_ADDRESS BaseOfStack; EFI_PHYSICAL_ADDRESS BaseOfStack;
EFI_PHYSICAL_ADDRESS BspStore; EFI_PHYSICAL_ADDRESS BspStore;
EFI_GUID DxeCoreFileName; EFI_GUID DxeCoreFileName;
EFI_GUID FirmwareFileName;
VOID *DxeCorePe32Data; VOID *DxeCorePe32Data;
VOID *FvImageData;
EFI_PHYSICAL_ADDRESS DxeCoreAddress; EFI_PHYSICAL_ADDRESS DxeCoreAddress;
UINT64 DxeCoreSize; UINT64 DxeCoreSize;
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint; EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;
@ -288,6 +290,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 // Find the DXE Core in a Firmware Volume
// //
@ -418,10 +432,11 @@ Returns:
FwVolHeader = NULL; FwVolHeader = NULL;
FfsFileHeader = NULL; FfsFileHeader = NULL;
SectionData = NULL; SectionData = NULL;
Status = EFI_SUCCESS;
// //
// Foreach Firmware Volume, look for a specified type // For each Firmware Volume, look for a specified type
// of file and break out when one is found // of file and break out until no one is found
// //
Hob.Raw = GetHobList (); Hob.Raw = GetHobList ();
while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) { while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {
@ -434,12 +449,14 @@ Returns:
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
Status = PeiProcessFile ( Status = PeiProcessFile (
SectionType, SectionType,
&FfsFileHeader, FfsFileHeader,
Pe32Data, Pe32Data,
&Hob &Hob
); );
CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID)); CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));
return Status; if (!EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
} }
Hob.Raw = GET_NEXT_HOB (Hob); Hob.Raw = GET_NEXT_HOB (Hob);
} }
@ -650,7 +667,7 @@ Returns:
// //
Status = PeiProcessFile ( Status = PeiProcessFile (
EFI_SECTION_PE32, EFI_SECTION_PE32,
&FfsHeader, FfsHeader,
&Pe32Data, &Pe32Data,
NULL NULL
); );
@ -676,7 +693,7 @@ Returns:
EFI_STATUS EFI_STATUS
PeiProcessFile ( PeiProcessFile (
IN UINT16 SectionType, IN UINT16 SectionType,
IN OUT EFI_FFS_FILE_HEADER **RealFfsFileHeader, IN EFI_FFS_FILE_HEADER *FfsFileHeader,
OUT VOID **Pe32Data, OUT VOID **Pe32Data,
IN EFI_PEI_HOB_POINTERS *OrigHob IN EFI_PEI_HOB_POINTERS *OrigHob
) )
@ -726,9 +743,7 @@ Returns:
EFI_GUID TempGuid; EFI_GUID TempGuid;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader; EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
EFI_COMPRESSION_SECTION *CompressionSection; EFI_COMPRESSION_SECTION *CompressionSection;
EFI_FFS_FILE_HEADER *FfsFileHeader; UINT32 FvAlignment;
FfsFileHeader = *RealFfsFileHeader;
Status = PeiServicesFfsFindSectionData ( Status = PeiServicesFfsFindSectionData (
EFI_SECTION_COMPRESSION, EFI_SECTION_COMPRESSION,
@ -737,7 +752,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)) { if (!EFI_ERROR (Status)) {
// //
@ -913,37 +928,64 @@ Returns:
); );
CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer; CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;
if (CmpSection->Type == EFI_SECTION_RAW) { if (CmpSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
// //
// Skip the section header and // Firmware Volume Image in this Section
// adjust the pointer alignment to 16 // Skip the section header to get FvHeader
// //
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16); FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);
if (FvHeader->Signature == EFI_FVH_SIGNATURE) { if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
FfsFileHeader = NULL; //
BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength); // Adjust Fv Base Address Alignment based on Align Attributes in Fv Header
Status = PeiServicesFfsFindNextFile ( //
EFI_FV_FILETYPE_DXE_CORE,
FvHeader,
&FfsFileHeader
);
if (EFI_ERROR (Status)) { //
return EFI_NOT_FOUND; // 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);
//
// Set the original FvHob to unused.
//
if (OrigHob != NULL) { if (OrigHob != NULL) {
//
//
OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED; OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;
} }
// //
// Reture the FfsHeader that contain Pe32Data. // when search FvImage Section return true.
// //
*RealFfsFileHeader = FfsFileHeader; if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data, OrigHob); *Pe32Data = (VOID *) FvHeader;
return EFI_SUCCESS;
} else {
return EFI_NOT_FOUND;
}
} }
} }
// //
@ -966,6 +1008,9 @@ Returns:
CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength); CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);
} while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize); } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);
} }
//
// End of the decompression activity
//
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength); Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
FileSize = FfsFileHeader->Size[0] & 0xFF; FileSize = FfsFileHeader->Size[0] & 0xFF;
@ -975,9 +1020,15 @@ Returns:
} while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize); } 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 { } else {
//
// For those FFS that doesn't contain compression section, directly search
// PE or TE section in this FFS.
//
Status = PeiServicesFfsFindSectionData ( Status = PeiServicesFfsFindSectionData (
EFI_SECTION_PE32, EFI_SECTION_PE32,