-STATIC\r
-EFI_STATUS\r
-GetFvAlignment (\r
- IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,\r
- OUT UINT32 *FvAlignment\r
- )\r
-{\r
- //\r
- // Because FvLength in FvHeader is UINT64 type, \r
- // so FvHeader must meed at least 8 bytes alignment.\r
- // Get the appropriate alignment requirement.\r
- // \r
- if ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) < EFI_FVB2_ALIGNMENT_8) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- \r
- *FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand \r
- as memory FV \r
- \r
- @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV\r
- @return EFI_SUCESS Sucess to find the FV \r
-**/\r
-EFI_STATUS\r
-DxeIplAddEncapsulatedFirmwareVolumes (\r
- VOID\r
- )\r
-{\r
- 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
- \r
- return Status;\r
-}\r
-\r
-/**\r
- Find the First Volume that contains the first FileType.\r
-\r
- @param Instance The Fv instance.\r
- @param SeachType The type of file to search.\r
- @param VolumeHandle Pointer to Fv which contains the file to search. \r
- @param FileHandle Pointer to FFS file to search.\r
- \r
- @return EFI_SUCESS Success to find the FFS in specificed FV\r
- @return others Fail to find the FFS in specificed FV\r
- */\r
-EFI_STATUS\r
-DxeIplFindFirmwareVolumeInstance (\r
- IN OUT UINTN *Instance,\r
- IN EFI_FV_FILETYPE SeachType,\r
- OUT EFI_PEI_FV_HANDLE *VolumeHandle,\r
- OUT EFI_PEI_FILE_HANDLE *FileHandle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS VolumeStatus;\r
-\r
- do {\r
- VolumeStatus = PeiServicesFfsFindNextVolume (*Instance, VolumeHandle);\r
- if (!EFI_ERROR (VolumeStatus)) {\r
- *FileHandle = NULL;\r
- Status = PeiServicesFfsFindNextFile (SeachType, *VolumeHandle, FileHandle);\r
- if (!EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
- *Instance += 1;\r
- } while (!EFI_ERROR (VolumeStatus));\r
-\r
- return VolumeStatus;\r
-}\r
-\r