EFI_PHYSICAL_ADDRESS BaseOfStack;\r
EFI_PHYSICAL_ADDRESS BspStore;\r
EFI_GUID DxeCoreFileName;\r
+ EFI_GUID FirmwareFileName;\r
VOID *DxeCorePe32Data;\r
+ VOID *FvImageData; \r
EFI_PHYSICAL_ADDRESS DxeCoreAddress;\r
UINT64 DxeCoreSize;\r
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;\r
}\r
}\r
\r
+ //\r
+ // Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file\r
+ // The file found will be processed by PeiProcessFile: It will first be decompressed to\r
+ // a normal FV, then a corresponding FV type hob will be built. \r
+ //\r
+ Status = PeiFindFile (\r
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+ &FirmwareFileName,\r
+ &FvImageData\r
+ );\r
+\r
//\r
// Find the DXE Core in a Firmware Volume\r
//\r
FwVolHeader = NULL;\r
FfsFileHeader = NULL;\r
SectionData = NULL;\r
+ Status = EFI_SUCCESS;\r
\r
//\r
- // Foreach Firmware Volume, look for a specified type\r
- // of file and break out when one is found\r
+ // For each Firmware Volume, look for a specified type\r
+ // of file and break out until no one is found \r
//\r
Hob.Raw = GetHobList ();\r
while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {\r
if (!EFI_ERROR (Status)) {\r
Status = PeiProcessFile (\r
SectionType,\r
- &FfsFileHeader,\r
+ FfsFileHeader,\r
Pe32Data,\r
&Hob\r
);\r
CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));\r
- return Status;\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
}\r
Hob.Raw = GET_NEXT_HOB (Hob);\r
}\r
//\r
Status = PeiProcessFile (\r
EFI_SECTION_PE32,\r
- &FfsHeader,\r
+ FfsHeader,\r
&Pe32Data,\r
NULL\r
);\r
EFI_STATUS\r
PeiProcessFile (\r
IN UINT16 SectionType,\r
- IN OUT EFI_FFS_FILE_HEADER **RealFfsFileHeader,\r
+ IN EFI_FFS_FILE_HEADER *FfsFileHeader,\r
OUT VOID **Pe32Data,\r
IN EFI_PEI_HOB_POINTERS *OrigHob\r
)\r
EFI_GUID TempGuid;\r
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
EFI_COMPRESSION_SECTION *CompressionSection;\r
- EFI_FFS_FILE_HEADER *FfsFileHeader;\r
- \r
- FfsFileHeader = *RealFfsFileHeader;\r
+ UINT32 FvAlignment;\r
\r
Status = PeiServicesFfsFindSectionData (\r
EFI_SECTION_COMPRESSION,\r
);\r
\r
//\r
- // Upon finding a DXE Core file, see if there is first a compression section\r
+ // First process the compression section\r
//\r
if (!EFI_ERROR (Status)) {\r
//\r
);\r
\r
CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
- if (CmpSection->Type == EFI_SECTION_RAW) {\r
+ if (CmpSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+ // \r
+ // Firmware Volume Image in this Section\r
+ // Skip the section header to get FvHeader\r
//\r
- // Skip the section header and\r
- // adjust the pointer alignment to 16\r
- //\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);\r
-\r
- if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
- FfsFileHeader = NULL;\r
- BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
- Status = PeiServicesFfsFindNextFile (\r
- EFI_FV_FILETYPE_DXE_CORE,\r
- FvHeader,\r
- &FfsFileHeader\r
- );\r
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);\r
\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) { \r
+ //\r
+ // Adjust Fv Base Address Alignment based on Align Attributes in Fv Header\r
+ //\r
+ \r
+ //\r
+ // When FvImage support Alignment, we need to check whether \r
+ // its alignment is correct. \r
+ //\r
+ if (FvHeader->Attributes | EFI_FVB_ALIGNMENT_CAP) {\r
+ \r
+ //\r
+ // Calculate the mini alignment for this FvImage\r
+ //\r
+ FvAlignment = 1 << (LowBitSet32 (FvHeader->Attributes >> 16) + 1);\r
+ \r
+ //\r
+ // If current FvImage base address doesn't meet the its alignment,\r
+ // we need to reload this FvImage to another correct memory address.\r
+ //\r
+ if (((UINTN) FvHeader % FvAlignment) != 0) {\r
+ DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength), FvAlignment);\r
+ if (DstBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (DstBuffer, FvHeader, (UINTN) FvHeader->FvLength);\r
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer; \r
+ }\r
}\r
-\r
+ //\r
+ // Build new FvHob for new decompressed Fv image.\r
+ //\r
+ BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
+ \r
+ //\r
+ // Set the original FvHob to unused.\r
+ //\r
if (OrigHob != NULL) {\r
- //\r
- // \r
OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;\r
}\r
\r
//\r
- // Reture the FfsHeader that contain Pe32Data.\r
+ // when search FvImage Section return true.\r
//\r
- *RealFfsFileHeader = FfsFileHeader;\r
- return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data, OrigHob);\r
+ if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+ *Pe32Data = (VOID *) FvHeader;\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
}\r
}\r
//\r
CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);\r
} while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);\r
}\r
+ //\r
+ // End of the decompression activity\r
+ //\r
\r
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
FileSize = FfsFileHeader->Size[0] & 0xFF;\r
FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;\r
FileSize &= 0x00FFFFFF;\r
} while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);\r
-\r
+ \r
//\r
- // End of the decompression activity\r
+ // search all sections (compression and non compression) in this FFS, don't \r
+ // find expected section.\r
//\r
+ return EFI_NOT_FOUND;\r
} else {\r
+ //\r
+ // For those FFS that doesn't contain compression section, directly search \r
+ // PE or TE section in this FFS.\r
+ //\r
\r
Status = PeiServicesFfsFindSectionData (\r
EFI_SECTION_PE32,\r