#include <Library/PeCoffLib.h>\r
#include <Library/S3Lib.h>\r
#include <Library/RecoveryLib.h>\r
-#include <Library/PeiPiLib.h>\r
\r
#define STACK_SIZE 0x20000\r
#define BSP_STORE_SIZE 0x4000\r
;\r
\r
EFI_STATUS\r
-DxeIplAddEncapsulatedFirmwareVolumes (\r
- VOID\r
- )\r
-;\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
+DxeIplFindDxeCore (\r
OUT EFI_PEI_FILE_HANDLE *FileHandle\r
)\r
;\r
DebugLib\r
S3Lib\r
RecoveryLib\r
- PeiPiLib\r
-\r
-[Protocols]\r
- gEfiCustomizedDecompressProtocolGuid # PROTOCOL SOMETIMES_PRODUCED\r
- gEfiTianoDecompressProtocolGuid # PROTOCOL SOMETIMES_PRODUCED\r
- gEfiDecompressProtocolGuid # PROTOCOL SOMETIMES_PRODUCED\r
-\r
+ PerformanceLib\r
\r
[Ppis]\r
gEfiPeiSecurityPpiGuid # PPI SOMETIMES_CONSUMED\r
}\r
\r
//\r
- // Install FvFileLoader and DxeIpl PPIs.\r
+ // Install DxeIpl and Decompress PPIs.\r
//\r
Status = PeiServicesInstallPpi (mPpiList);\r
- ASSERT_EFI_ERROR(Status); \r
- \r
+ ASSERT_EFI_ERROR(Status);\r
+\r
return Status;\r
}\r
\r
UINT64 DxeCoreSize;\r
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;\r
EFI_BOOT_MODE BootMode;\r
- EFI_PEI_FV_HANDLE VolumeHandle;\r
EFI_PEI_FILE_HANDLE FileHandle;\r
- UINTN Instance;\r
EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;\r
UINTN DataSize;\r
EFI_MEMORY_TYPE_INFORMATION MemoryData [EfiMaxMemoryType + 1];\r
// Now should have a HOB with the DXE core w/ the old HOB destroyed\r
//\r
}\r
- \r
+\r
Status = PeiServicesLocatePpi (\r
&gEfiPeiReadOnlyVariable2PpiGuid,\r
0,\r
DataSize\r
);\r
}\r
- //\r
- // If any FV contains an encapsulated FV extract that FV\r
- //\r
- DxeIplAddEncapsulatedFirmwareVolumes ();\r
- \r
+\r
//\r
// Look in all the FVs present in PEI and find the DXE Core\r
//\r
- Instance = 0;\r
- Status = DxeIplFindFirmwareVolumeInstance (&Instance, EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
+ FileHandle = NULL;\r
+ Status = DxeIplFindDxeCore (&FileHandle);\r
ASSERT_EFI_ERROR (Status);\r
\r
CopyMem(&DxeCoreFileName, &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name), sizeof (EFI_GUID));\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
-\r
-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
+ Find DxeCore driver from all First Volumes.\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
+DxeIplFindDxeCore (\r
OUT EFI_PEI_FILE_HANDLE *FileHandle\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_STATUS VolumeStatus;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS FileStatus;\r
+ UINTN Instance;\r
+ EFI_PEI_FV_HANDLE VolumeHandle;\r
+ \r
+ Instance = 0;\r
+ *FileHandle = NULL;\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
+ Status = PeiServicesFfsFindNextVolume (Instance++, &VolumeHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ FileStatus = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, FileHandle);\r
+ if (!EFI_ERROR (FileStatus)) {\r
+ return FileStatus;\r
}\r
}\r
- *Instance += 1;\r
- } while (!EFI_ERROR (VolumeStatus));\r
+ } while (!EFI_ERROR (Status));\r
\r
- return VolumeStatus;\r
+ return EFI_NOT_FOUND;\r
}\r
\r
/**\r
//\r
// Allocate output buffer\r
//\r
- *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));\r
+ *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);\r
if (*OutputBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
+ DEBUG ((EFI_D_INFO, "Customed Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));\r
+ //\r
+ // *OutputBuffer still is one section. Adjust *OutputBuffer offset, \r
+ // skip EFI section header to make section data at page alignment.\r
+ //\r
+ *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));\r
}\r
\r
Status = ExtractGuidedSectionDecode (\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
- // Allocate destination buffer\r
+ // Allocate destination buffer, extra one page for adjustment \r
//\r
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
if (DstBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
+ // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header\r
+ // to make section data at page alignment.\r
+ //\r
+ DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+ //\r
// Call decompress function\r
//\r
Status = UefiDecompress (\r
}\r
break;\r
\r
- // porting note the original branch for customized compress is removed, it should be change to use GUID compress\r
-\r
case EFI_NOT_COMPRESSED:\r
//\r
// Allocate destination buffer\r
//\r
DstBufferSize = CompressionSection->UncompressedLength;\r
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
if (DstBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
+ // Adjust DstBuffer offset, skip EFI section header\r
+ // to make section data at page alignment.\r
+ //\r
+ DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+ //\r
// stream is not actually compressed, just encapsulated. So just copy it.\r
//\r
CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
VOID *Context2\r
);\r
\r
-\r
VOID\r
DiscoverPeimsAndOrderWithApriori (\r
IN PEI_CORE_INSTANCE *Private,\r
VOID *TopOfStack;\r
PEI_CORE_PARAMETERS PeiCoreParameters;\r
EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;\r
+ EFI_FV_FILE_INFO FvFileInfo;\r
\r
\r
PeiServices = &Private->PS;\r
PeimEntryPoint = NULL;\r
PeimFileHandle = NULL;\r
+ EntryPoint = 0;\r
\r
if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
//\r
if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {\r
PeimNeedingDispatch = TRUE;\r
} else {\r
- Status = PeiLoadImage (\r
- PeiServices, \r
- PeimFileHandle, \r
- &EntryPoint, \r
- &AuthenticationState\r
- );\r
+ Status = PeiFfsGetFileInfo (PeimFileHandle, &FvFileInfo);\r
+ ASSERT_EFI_ERROR (Status);\r
+ if (FvFileInfo.FileType == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {\r
+ //\r
+ // For Fv type file, Produce new FV PPI and FV hob\r
+ //\r
+ Status = ProcessFvFile (PeiServices, PeimFileHandle, &AuthenticationState);\r
+ } else {\r
+ //\r
+ // For PEIM driver, Load its entry point\r
+ //\r
+ Status = PeiLoadImage (\r
+ PeiServices, \r
+ PeimFileHandle, \r
+ &EntryPoint, \r
+ &AuthenticationState\r
+ );\r
+ }\r
+\r
if ((Status == EFI_SUCCESS)) {\r
//\r
- // The PEIM has its dependencies satisfied, and its entry point\r
- // has been found, so invoke it.\r
+ // The PEIM has its dependencies satisfied, and is processed.\r
//\r
PERF_START (0, "PEIM", NULL, 0);\r
\r
// PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED\r
//\r
Private->Fv[FvCount].PeimState[PeimCount]++;\r
-\r
+ \r
+ if (FvFileInfo.FileType != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {\r
+ //\r
+ // Call the PEIM entry point for PEIM driver\r
+ //\r
+ PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;\r
+ PeimEntryPoint (PeimFileHandle, PeiServices);\r
+ }\r
//\r
- // Call the PEIM entry point\r
+ // One module has been dispatched.\r
//\r
- PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;\r
- PeimEntryPoint (PeimFileHandle, PeiServices);\r
PeimDispatchOnThisPass = TRUE;\r
}\r
\r
\r
--*/\r
{\r
- EFI_STATUS Status;\r
- VOID *DepexData;\r
+ EFI_STATUS Status;\r
+ VOID *DepexData;\r
\r
if (PeimCount < Private->AprioriCount) {\r
//\r
//\r
return TRUE;\r
}\r
+ \r
+ //\r
+ // Depex section not in the encapsulated section. \r
+ //\r
+ Status = PeiServicesFfsFindSectionData (\r
+ EFI_SECTION_PEI_DEPEX,\r
+ FileHandle, \r
+ (VOID **)&DepexData\r
+ );\r
\r
- Status = PeiServicesFfsFindSectionData (EFI_SECTION_PEI_DEPEX, FileHandle, (VOID **) &DepexData);\r
if (EFI_ERROR (Status)) {\r
//\r
// If there is no DEPEX, assume the module can be executed\r
ASSERT (FALSE);\r
CpuDeadLoop ();\r
}\r
+\r
+/**\r
+ Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.\r
+\r
+ @param PeiServices Pointer to the PEI Core Services Table.\r
+ @param FileHandle File handle of a Fv type file.\r
+ @param AuthenticationState Pointer to attestation authentication state of image.\r
+\r
+ \r
+ @retval EFI_NOT_FOUND FV image can't be found.\r
+ @retval EFI_SUCCESS Successfully to process it.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessFvFile (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_FILE_HANDLE FvFileHandle,\r
+ OUT UINT32 *AuthenticationState\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PEI_FV_HANDLE FvImageHandle;\r
+ EFI_FV_INFO FvImageInfo;\r
+ UINT32 FvAlignment;\r
+ VOID *FvBuffer;\r
+ EFI_PEI_HOB_POINTERS HobFv2;\r
+ \r
+ FvBuffer = NULL;\r
+ *AuthenticationState = 0;\r
+\r
+ //\r
+ // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already \r
+ // been extracted.\r
+ //\r
+ HobFv2.Raw = GetHobList ();\r
+ while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {\r
+ if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobFv2.FirmwareVolume2->FileName)) {\r
+ //\r
+ // this FILE has been dispatched, it will not be dispatched again.\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+ HobFv2.Raw = GET_NEXT_HOB (HobFv2);\r
+ }\r
+ \r
+ //\r
+ // Find FvImage in FvFile\r
+ //\r
+ Status = PeiFfsFindSectionData (\r
+ (CONST EFI_PEI_SERVICES **) PeiServices,\r
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+ FvFileHandle,\r
+ (VOID **)&FvImageHandle\r
+ );\r
+ \r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Collect FvImage Info.\r
+ //\r
+ Status = PeiFfsGetVolumeInfo (FvImageHandle, &FvImageInfo);\r
+ ASSERT_EFI_ERROR (Status);\r
+ //\r
+ // FvAlignment must be more than 8 bytes required by FvHeader structure.\r
+ //\r
+ FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+ if (FvAlignment < 8) {\r
+ FvAlignment = 8;\r
+ }\r
+ // \r
+ // Check FvImage\r
+ //\r
+ if ((UINTN) FvImageInfo.FvStart % FvAlignment != 0) {\r
+ FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvImageInfo.FvSize), FvAlignment);\r
+ if (FvBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN) FvImageInfo.FvSize);\r
+ //\r
+ // Update FvImageInfo after reload FvImage to new aligned memory\r
+ //\r
+ PeiFfsGetVolumeInfo ((EFI_PEI_FV_HANDLE) FvBuffer, &FvImageInfo);\r
+ }\r
+ \r
+ //\r
+ // Install FvPpi and Build FvHob\r
+ //\r
+ PiLibInstallFvInfoPpi (\r
+ NULL,\r
+ FvImageInfo.FvStart,\r
+ (UINT32) FvImageInfo.FvSize,\r
+ &(FvImageInfo.FvName),\r
+ &(((EFI_FFS_FILE_HEADER*)FvFileHandle)->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) FvImageInfo.FvStart,\r
+ FvImageInfo.FvSize\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) FvImageInfo.FvStart,\r
+ FvImageInfo.FvSize,\r
+ &FvImageInfo.FvName,\r
+ &(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name)\r
+ );\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
}\r
} else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {\r
if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r
- (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) { \r
+ (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||\r
+ (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) { \r
\r
*FileHeader = FfsFileHeader;\r
return EFI_SUCCESS;\r
UINT8 FvCount;\r
EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;\r
PEI_CORE_INSTANCE *PrivateData;\r
+ EFI_PEI_FILE_HANDLE FileHandle;\r
+ VOID *DepexData;\r
+ UINT32 AuthenticationStatus;\r
+ EFI_STATUS Status;\r
\r
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+ FileHandle = NULL;\r
+ DepexData = NULL;\r
+ Status = EFI_SUCCESS;\r
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
\r
if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
ASSERT (FALSE);\r
\r
Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;\r
\r
- if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {\r
- for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {\r
- if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
+ if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {\r
+ for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {\r
+ if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
PrivateData->Fv[PrivateData->FvCount++].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv->FvInfo;\r
- }\r
\r
- //\r
- // Allways add to the All list\r
- //\r
- PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;\r
+ //\r
+ // Only add FileSystem2 Fv to the All list\r
+ //\r
+ PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;\r
+ \r
+ DEBUG ((EFI_D_INFO, "The %dth FvImage start address is 0x%10p and size is 0x%08x\n", PrivateData->AllFvCount, (VOID *) Fv->FvInfo, Fv->FvInfoSize));\r
+ //\r
+ // Preprocess all FV type files in this new FileSystem2 Fv image\r
+ //\r
+ do {\r
+ Status = PeiFindFileEx (\r
+ (EFI_PEI_FV_HANDLE)Fv->FvInfo, \r
+ NULL, \r
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
+ &FileHandle, \r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = PeiFfsFindSectionData (\r
+ (CONST EFI_PEI_SERVICES **) PeiServices,\r
+ EFI_SECTION_PEI_DEPEX,\r
+ FileHandle, \r
+ (VOID **)&DepexData\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r
+ //\r
+ // Dependency is not satisfied.\r
+ //\r
+ continue;\r
+ }\r
+ }\r
+ //\r
+ // Process FvFile to install FvInfo ppi and build FvHob\r
+ // \r
+ ProcessFvFile (PeiServices, FileHandle, &AuthenticationStatus);\r
+ }\r
+ } while (FileHandle != NULL);\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r
IN EFI_SECTION_TYPE SectionType,\r
IN EFI_COMMON_SECTION_HEADER *Section,\r
IN UINTN SectionSize,\r
- OUT VOID **OutputBuffer,\r
- OUT UINTN *OutputSize,\r
- OUT UINT32 *Authentication\r
+ OUT VOID **OutputBuffer\r
)\r
/*++\r
\r
Routine Description:\r
\r
Go through the file to search SectionType section,\r
- when meeting an encapsuled section, search recursively. \r
+ when meeting an encapsuled section. \r
\r
Arguments:\r
- PeiServices - Pointer to the PEI Core Services Table.\r
+ PeiServices - General purpose services available to every PEIM.\r
SearchType - Filter to find only section of this type.\r
Section - From where to search.\r
SectionSize - The file size to search.\r
OutputBuffer - Pointer to the section to search.\r
- OutputSize - The size of the section to search.\r
- Authentication - Authenticate the section.\r
\r
Returns:\r
EFI_STATUS\r
EFI_STATUS Status;\r
UINT32 SectionLength;\r
UINT32 ParsedLength;\r
- EFI_GUID_DEFINED_SECTION *GuidSection; \r
EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;\r
- EFI_COMPRESSION_SECTION *CompressionSection;\r
EFI_PEI_DECOMPRESS_PPI *DecompressPpi;\r
VOID *PpiOutput;\r
UINTN PpiOutputSize;\r
+ UINTN Index;\r
+ UINT32 Authentication;\r
+ PEI_CORE_INSTANCE *PrivateData;\r
\r
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
*OutputBuffer = NULL;\r
- ParsedLength = 0;\r
+ ParsedLength = 0;\r
+ Index = 0;\r
+ Status = EFI_NOT_FOUND;\r
+ PpiOutput = NULL;\r
+ PpiOutputSize = 0;\r
while (ParsedLength < SectionSize) {\r
if (Section->Type == SectionType) {\r
*OutputBuffer = (VOID *)(Section + 1);\r
return EFI_SUCCESS;\r
- } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
- GuidSection = (EFI_GUID_DEFINED_SECTION *)Section;\r
- Status = PeiServicesLocatePpi (&GuidSection->SectionDefinitionGuid, 0, NULL, (VOID **) &GuidSectionPpi);\r
- if (!EFI_ERROR (Status)) {\r
- Status = GuidSectionPpi->ExtractSection (\r
- GuidSectionPpi,\r
- Section,\r
- &PpiOutput,\r
- &PpiOutputSize,\r
- Authentication\r
- );\r
- if (!EFI_ERROR (Status)) {\r
+ } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) {\r
+ //\r
+ // Check the encapsulated section is extracted into the cache data.\r
+ //\r
+ for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index ++) {\r
+ if (Section == PrivateData->CacheSection.Section[Index]) {\r
+ PpiOutput = PrivateData->CacheSection.SectionData[Index];\r
+ PpiOutputSize = PrivateData->CacheSection.SectionSize[Index];\r
+ //\r
+ // Search section directly from the cache data.\r
+ //\r
return PeiFfsProcessSection (\r
PeiServices,\r
SectionType, \r
PpiOutput, \r
PpiOutputSize, \r
- OutputBuffer, \r
- OutputSize, \r
- Authentication\r
+ OutputBuffer \r
);\r
}\r
}\r
- } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
- CompressionSection = (EFI_COMPRESSION_SECTION *)Section;\r
- Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);\r
- if (!EFI_ERROR (Status)) {\r
- Status = DecompressPpi->Decompress (\r
- DecompressPpi,\r
- CompressionSection,\r
- &PpiOutput,\r
- &PpiOutputSize\r
- );\r
+ \r
+ Status = EFI_NOT_FOUND;\r
+ if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
+ Status = PeiServicesLocatePpi (\r
+ &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid, \r
+ 0, \r
+ NULL, \r
+ (VOID **) &GuidSectionPpi\r
+ );\r
if (!EFI_ERROR (Status)) {\r
- return PeiFfsProcessSection (\r
- PeiServices, SectionType, PpiOutput, PpiOutputSize, OutputBuffer, OutputSize, Authentication\r
- );\r
+ Status = GuidSectionPpi->ExtractSection (\r
+ GuidSectionPpi,\r
+ Section,\r
+ &PpiOutput,\r
+ &PpiOutputSize,\r
+ &Authentication\r
+ );\r
+ }\r
+ } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
+ Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = DecompressPpi->Decompress (\r
+ DecompressPpi,\r
+ (CONST EFI_COMPRESSION_SECTION*) Section,\r
+ &PpiOutput,\r
+ &PpiOutputSize\r
+ );\r
}\r
}\r
+ \r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Update cache section data.\r
+ //\r
+ if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {\r
+ PrivateData->CacheSection.AllSectionCount ++;\r
+ }\r
+ PrivateData->CacheSection.Section [PrivateData->CacheSection.SectionIndex] = Section;\r
+ PrivateData->CacheSection.SectionData [PrivateData->CacheSection.SectionIndex] = PpiOutput;\r
+ PrivateData->CacheSection.SectionSize [PrivateData->CacheSection.SectionIndex] = PpiOutputSize;\r
+ PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;\r
+ \r
+ return PeiFfsProcessSection (\r
+ PeiServices,\r
+ SectionType, \r
+ PpiOutput, \r
+ PpiOutputSize, \r
+ OutputBuffer \r
+ );\r
+ }\r
}\r
\r
//\r
EFI_FFS_FILE_HEADER *FfsFileHeader;\r
UINT32 FileSize;\r
EFI_COMMON_SECTION_HEADER *Section;\r
- UINTN OutputSize;\r
- UINT32 AuthenticationStatus;\r
-\r
\r
FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);\r
\r
FileSize -= sizeof (EFI_FFS_FILE_HEADER);\r
\r
return PeiFfsProcessSection (\r
- PeiServices, \r
+ PeiServices,\r
SectionType, \r
Section, \r
FileSize, \r
- SectionData, \r
- &OutputSize, \r
- &AuthenticationStatus\r
+ SectionData\r
);\r
}\r
\r
\r
Routine Description:\r
\r
- Return the BFV location\r
+ Return the firmware volumes.\r
\r
BugBug -- Move this to the location of this code to where the\r
other FV and FFS support code lives.\r
\r
--*/ \r
{\r
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
+ EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;\r
EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;\r
\r
if (VolumeInfo == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
+ \r
+ //\r
+ // VolumeHandle may not align at 8 byte, \r
+ // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte. \r
+ // So, Copy FvHeader into the local FvHeader structure.\r
+ //\r
+ CopyMem (&FwVolHeader, VolumeHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
+ //\r
+ // Check Fv Image Signature\r
+ //\r
+ if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ VolumeInfo->FvAttributes = FwVolHeader.Attributes;\r
+ VolumeInfo->FvStart = (VOID *) VolumeHandle;\r
+ VolumeInfo->FvSize = FwVolHeader.FvLength;\r
+ CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));\r
\r
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(VolumeHandle);\r
- VolumeInfo->FvAttributes = FwVolHeader->Attributes;\r
- VolumeInfo->FvStart = FwVolHeader;\r
- VolumeInfo->FvSize = FwVolHeader->FvLength;\r
- CopyMem (&VolumeInfo->FvFormat, &FwVolHeader->FileSystemGuid,sizeof(EFI_GUID));\r
-\r
- if (FwVolHeader->ExtHeaderOffset != 0) {\r
- FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);\r
+ if (FwVolHeader.ExtHeaderOffset != 0) {\r
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)VolumeHandle) + FwVolHeader.ExtHeaderOffset);\r
CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));\r
}\r
return EFI_SUCCESS;\r
// When Image has no reloc section, it can't be relocated into memory.\r
//\r
if (ImageContext.RelocationsStripped) {\r
- DEBUG ((EFI_D_ERROR, "The image at 0x%08x without reloc section can't be loaded into memory", (UINTN) Pe32Data));\r
+ DEBUG ((EFI_D_ERROR, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data));\r
return EFI_INVALID_PARAMETER;\r
}\r
//\r
#include <IndustryStandard/PeImage.h>\r
#include <Library/PeiServicesTablePointerLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PeiPiLib.h>\r
#include <Guid/FirmwareFileSystem2.h>\r
#include <Guid/AprioriFileName.h>\r
\r
BOOLEAN ScanFv;\r
} PEI_CORE_FV_HANDLE;\r
\r
+#define CACHE_SETION_MAX_NUMBER 0x10\r
+typedef struct {\r
+ EFI_COMMON_SECTION_HEADER* Section[CACHE_SETION_MAX_NUMBER];\r
+ VOID* SectionData[CACHE_SETION_MAX_NUMBER];\r
+ UINTN SectionSize[CACHE_SETION_MAX_NUMBER];\r
+ UINTN AllSectionCount;\r
+ UINTN SectionIndex;\r
+} CACHE_SECTION_DATA;\r
+\r
//\r
// Pei Core private data structure instance\r
//\r
UINTN SizeOfCacheAsRam;\r
VOID *MaxTopOfCarHeap;\r
EFI_PEI_PPI_DESCRIPTOR *XipLoadFile;\r
+ CACHE_SECTION_DATA CacheSection;\r
} PEI_CORE_INSTANCE;\r
\r
//\r
--*/ \r
;\r
\r
+/**\r
+ Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.\r
+\r
+ @param PeiServices Pointer to the PEI Core Services Table.\r
+ @param FileHandle File handle of a Fv type file.\r
+ @param AuthenticationState Pointer to attestation authentication state of image.\r
+\r
+ \r
+ @retval EFI_NOT_FOUND FV image can't be found.\r
+ @retval EFI_SUCCESS Successfully to process it.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessFvFile (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_FILE_HANDLE FvFileHandle,\r
+ OUT UINT32 *AuthenticationState\r
+ );\r
+\r
#endif\r
MemoryAllocationLib\r
CacheMaintenanceLib\r
PeCoffLib\r
+ PeiPiLib\r
\r
[Guids]\r
gPeiAprioriFileNameGuid\r
\r
[FeaturePcd.common]\r
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst\r
-\r
-\r
-\r