mirror of https://github.com/acidanthera/audk.git
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:
parent
0cc00bf06b
commit
d66974717c
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
|
@ -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) {
|
||||||
|
//
|
||||||
|
// Firmware Volume Image in this Section
|
||||||
|
// Skip the section header to get FvHeader
|
||||||
//
|
//
|
||||||
// Skip the section header and
|
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);
|
||||||
// adjust the pointer alignment to 16
|
|
||||||
//
|
|
||||||
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);
|
|
||||||
|
|
||||||
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
|
// When FvImage support Alignment, we need to check whether
|
||||||
);
|
// its alignment is correct.
|
||||||
|
//
|
||||||
if (EFI_ERROR (Status)) {
|
if (FvHeader->Attributes | EFI_FVB_ALIGNMENT_CAP) {
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OrigHob != NULL) {
|
|
||||||
//
|
//
|
||||||
//
|
// 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) {
|
||||||
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;
|
||||||
|
@ -973,11 +1018,17 @@ Returns:
|
||||||
FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
|
FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
|
||||||
FileSize &= 0x00FFFFFF;
|
FileSize &= 0x00FFFFFF;
|
||||||
} 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,
|
||||||
|
|
Loading…
Reference in New Issue