\r
#include <PeiMain.h>\r
\r
+typedef struct {\r
+ EFI_STATUS_CODE_DATA DataHeader;\r
+ EFI_HANDLE Handle;\r
+} PEIM_FILE_HANDLE_EXTENDED_DATA;\r
+\r
STATIC\r
VOID\r
InvokePeiCore (\r
VOID *Context2\r
);\r
\r
-\r
VOID\r
DiscoverPeimsAndOrderWithApriori (\r
IN PEI_CORE_INSTANCE *Private,\r
UINTN PeimCount;\r
UINT32 AuthenticationState;\r
EFI_PHYSICAL_ADDRESS EntryPoint;\r
- EFI_PEIM_ENTRY_POINT PeimEntryPoint;\r
+ EFI_PEIM_ENTRY_POINT2 PeimEntryPoint;\r
BOOLEAN PeimNeedingDispatch;\r
BOOLEAN PeimDispatchOnThisPass;\r
UINTN SaveCurrentPeimCount;\r
EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;\r
VOID *TopOfStack;\r
PEI_CORE_PARAMETERS PeiCoreParameters;\r
- EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;\r
+ PEIM_FILE_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
//\r
// Call the PEIM entry point\r
//\r
- PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;\r
+ PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;\r
\r
PERF_START (0, "PEIM", NULL, 0);\r
- PeimEntryPoint(PeimFileHandle, &Private->PS);\r
+ PeimEntryPoint(PeimFileHandle, (const EFI_PEI_SERVICES **) &Private->PS);\r
PERF_END (0, "PEIM", NULL, 0);\r
} \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
\r
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
EFI_PROGRESS_CODE,\r
- EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN,\r
+ FixedPcdGet32(PcdStatusCodeValuePeimDispatch),\r
(VOID *)(&ExtendedData),\r
sizeof (ExtendedData)\r
);\r
// PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED\r
//\r
Private->Fv[FvCount].PeimState[PeimCount]++;\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_POINT2)(UINTN)EntryPoint;\r
+ PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);\r
+ }\r
\r
- //\r
- // Call the PEIM entry point\r
- //\r
- PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;\r
- PeimEntryPoint (PeimFileHandle, PeiServices);\r
PeimDispatchOnThisPass = TRUE;\r
}\r
\r
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
EFI_PROGRESS_CODE,\r
- EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END,\r
+ FixedPcdGet32(PcdStatusCodeValuePeimDispatch),\r
(VOID *)(&ExtendedData),\r
sizeof (ExtendedData)\r
);\r
PERF_END (0, "PEIM", NULL, 0);\r
\r
+ } else {\r
+ //\r
+ // If PeiLoadImage fails, the section extraction PPI or Decompress PPI may not be ready,\r
+ // we flag that more Peims need to be dispatched.\r
+ //\r
+ PeimNeedingDispatch = TRUE;\r
}\r
\r
//\r
\r
PeiSwitchStacks (\r
InvokePeiCore,\r
- (VOID*) (UINTN) PeiCore,\r
+ (VOID*) ((UINTN) EntryPoint + ((UINTN) PeiCore - (UINTN) _ModuleEntryPoint)),\r
(VOID*) &PeiCoreParameters, \r
TopOfStack,\r
(VOID*)(UINTN)Private->StackBase\r
// We call the entry point a 2nd time so the module knows it's shadowed. \r
//\r
//PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);\r
- PeimEntryPoint (PeimFileHandle, PeiServices);\r
+ PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);\r
//PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);\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
//\r
// Never returns\r
//\r
- ASSERT_EFI_ERROR (FALSE);\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