- EFI_STATUS Status;\r
- EFI_STATUS VolumeStatus;\r
- UINTN Index;\r
- EFI_FV_INFO VolumeInfo; \r
- EFI_PEI_FV_HANDLE VolumeHandle;\r
- EFI_PEI_FILE_HANDLE FileHandle;\r
- UINT32 SectionLength;\r
- EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
- EFI_FIRMWARE_VOLUME_IMAGE_SECTION *SectionHeader;\r
- VOID *DstBuffer;\r
- UINT32 FvAlignment;\r
-\r
- Status = EFI_NOT_FOUND;\r
- Index = 0;\r
-\r
- do {\r
- VolumeStatus = DxeIplFindFirmwareVolumeInstance (\r
- &Index, \r
- EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
- &VolumeHandle, \r
- &FileHandle\r
- );\r
- \r
- if (!EFI_ERROR (VolumeStatus)) {\r
- Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_FIRMWARE_VOLUME_IMAGE, \r
- (EFI_FFS_FILE_HEADER *)FileHandle, \r
- (VOID **)&FvHeader\r
- );\r
- \r
- if (!EFI_ERROR (Status)) {\r
- if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
- //\r
- // Because FvLength in FvHeader is UINT64 type, \r
- // so FvHeader must meed at least 8 bytes alignment.\r
- // If current FvImage base address doesn't meet its alignment,\r
- // we need to reload this FvImage to another correct memory address.\r
- //\r
- Status = GetFvAlignment(FvHeader, &FvAlignment); \r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- if (((UINTN) FvHeader % FvAlignment) != 0) {\r
- SectionHeader = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)((UINTN)FvHeader - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
- SectionLength = *(UINT32 *)SectionHeader->Size & 0x00FFFFFF;\r
- \r
- DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), FvAlignment);\r
- if (DstBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- CopyMem (DstBuffer, FvHeader, (UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer; \r
- }\r
-\r
- //\r
- // This new Firmware Volume comes from a firmware file within a firmware volume.\r
- // Record the original Firmware Volume Name.\r
- //\r
- PeiServicesFfsGetVolumeInfo (&VolumeHandle, &VolumeInfo);\r
-\r
- PiLibInstallFvInfoPpi (\r
- NULL,\r
- FvHeader,\r
- (UINT32) FvHeader->FvLength,\r
- &(VolumeInfo.FvName),\r
- &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name)\r
- );\r
-\r
- //\r
- // Inform HOB consumer phase, i.e. DXE core, the existance of this FV\r
- //\r
- BuildFvHob (\r
- (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
- FvHeader->FvLength\r
- );\r
- \r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Makes the encapsulated volume show up in DXE phase to skip processing of\r
- // encapsulated file again.\r
- //\r
- BuildFv2Hob (\r
- (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
- FvHeader->FvLength, \r
- &VolumeInfo.FvName,\r
- &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name)\r
- );\r
- return Status;\r
- }\r
- }\r
- }\r
- } while (!EFI_ERROR (VolumeStatus));\r