Private->AprioriCount -= sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_COMMON_SECTION_HEADER);\r
Private->AprioriCount /= sizeof (EFI_GUID);\r
\r
- SetMem (FileGuid, sizeof (FileGuid), 0);\r
+ ZeroMem (FileGuid, sizeof (FileGuid));\r
for (Index = 0; Index < PeimCount; Index++) {\r
//\r
// Make an array of file name guids that matches the FileHandle array so we can convert\r
/**\r
Shadow PeiCore module from flash to installed memory.\r
\r
- @param PeiServices Pointer to PeiService table\r
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
@param PrivateInMem PeiCore's private data structure\r
\r
+ @return PeiCore function address after shadowing.\r
**/\r
VOID*\r
ShadowPeiCore(\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ //\r
+ // Compute the PeiCore's function address after shaowed PeiCore.\r
+ // _ModuleEntryPoint is PeiCore main function entry\r
+ //\r
return (VOID*) ((UINTN) EntryPoint + (UINTN) PeiCore - (UINTN) _ModuleEntryPoint);\r
}\r
\r
the BFV location.\r
@param Private Pointer to the private data passed in from caller\r
\r
- @retval EFI_SUCCESS - Successfully dispatched PEIM.\r
- @retval EFI_NOT_FOUND - The dispatch failed.\r
-\r
**/\r
VOID\r
PeiDispatcher (\r
UINT32 AuthenticationState;\r
EFI_PHYSICAL_ADDRESS EntryPoint;\r
EFI_PEIM_ENTRY_POINT2 PeimEntryPoint;\r
- BOOLEAN PeimNeedingDispatch;\r
- BOOLEAN PeimDispatchOnThisPass;\r
UINTN SaveCurrentPeimCount;\r
UINTN SaveCurrentFvCount;\r
EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;\r
// satisfied, this dipatcher should run only once.\r
//\r
do {\r
- PeimNeedingDispatch = FALSE;\r
- PeimDispatchOnThisPass = FALSE;\r
-\r
+ //\r
+ // In case that reenter PeiCore happens, the last pass record is still available. \r
+ //\r
+ if (!Private->PeimDispatcherReenter) {\r
+ Private->PeimNeedingDispatch = FALSE;\r
+ Private->PeimDispatchOnThisPass = FALSE;\r
+ } else {\r
+ Private->PeimDispatcherReenter = FALSE;\r
+ }\r
+ \r
for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {\r
Private->CurrentPeimFvCount = FvCount;\r
- VolumeHandle = Private->Fv[FvCount].FvHeader;\r
+ //\r
+ // Get this Fv Handle by PeiService FvFindNextVolume.\r
+ //\r
+ PeiFvFindNextVolume ((CONST EFI_PEI_SERVICES **) PeiServices, FvCount, &VolumeHandle);\r
\r
if (Private->CurrentPeimCount == 0) {\r
//\r
\r
if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {\r
if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {\r
- PeimNeedingDispatch = TRUE;\r
+ Private->PeimNeedingDispatch = TRUE;\r
} else {\r
Status = PeiFfsGetFileInfo (PeimFileHandle, &FvFileInfo);\r
ASSERT_EFI_ERROR (Status);\r
PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);\r
}\r
\r
- PeimDispatchOnThisPass = TRUE;\r
+ Private->PeimDispatchOnThisPass = TRUE;\r
}\r
\r
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
//\r
// Reserve the size of new stack at bottom of physical memory\r
//\r
- OldPeiStackSize = Private->StackSize;\r
+ OldPeiStackSize = (UINT64) SecCoreData->StackSize;\r
NewPeiStackSize = (RShiftU64 (Private->PhysicalMemoryLength, 1) + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;\r
if (FixedPcdGet32(PcdPeiCoreMaxPeiStackSize) > (UINT32) NewPeiStackSize) {\r
Private->StackSize = NewPeiStackSize;\r
// But if new stack is smaller than the size of old stack, we also reserve\r
// the size of old stack at bottom of permenent memory.\r
//\r
- StackGap = 0;\r
- if (Private->StackSize > OldPeiStackSize) {\r
- StackGap = Private->StackSize - OldPeiStackSize;\r
- }\r
+ ASSERT (Private->StackSize >= OldPeiStackSize);\r
+ StackGap = Private->StackSize - OldPeiStackSize;\r
\r
//\r
// Update HandOffHob for new installed permenent memory\r
// CAUTION: The new base is computed accounding to gap of new stack.\r
//\r
NewPermenentMemoryBase = Private->PhysicalMemoryBegin + StackGap;\r
+ \r
+ //\r
+ // Caculate stack offset and heap offset between CAR and new permement \r
+ // memory seperately.\r
+ //\r
StackOffset = (UINTN) NewPermenentMemoryBase - (UINTN) SecCoreData->StackBase;\r
HeapOffset = (INTN) ((UINTN) Private->PhysicalMemoryBegin + Private->StackSize - \\r
(UINTN) SecCoreData->PeiTemporaryRamBase);\r
DEBUG ((EFI_D_INFO, "Heap Offset = 0x%X Stack Offset = 0x%X\n", HeapOffset, StackOffset));\r
\r
+ //\r
+ // Caculate new HandOffTable and PrivateData address in permenet memory's stack\r
+ //\r
NewHandOffTable = (EFI_HOB_HANDOFF_INFO_TABLE *)((UINTN)OldHandOffTable + HeapOffset);\r
PrivateInMem = (PEI_CORE_INSTANCE *)((UINTN) (VOID*) Private + StackOffset);\r
\r
\r
\r
if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Temporary Ram support Ppi is provided by platform, it will copy \r
+ // temporary memory to permenent memory and do stack switching.\r
+ // After invoken temporary Ram support, following code's stack is in \r
+ // memory but not in CAR.\r
+ //\r
TemporaryRamSupportPpi->TemporaryRamMigration (\r
(CONST EFI_PEI_SERVICES **) PeiServices,\r
(EFI_PHYSICAL_ADDRESS)(UINTN) SecCoreData->TemporaryRamBase,\r
//\r
// We need convert the PPI desciptor's pointer\r
//\r
- ConvertPpiPointers ((CONST EFI_PEI_SERVICES **)PeiServices, \r
+ ConvertPpiPointers (PrivateInMem, \r
OldCheckingBottom, \r
OldCheckingTop, \r
HeapOffset\r
PrivateInMem->PeiMemoryInstalled = TRUE;\r
\r
//\r
- // Restart scan of all PEIMs on next pass\r
+ // Indicate that PeiCore reenter\r
//\r
- PrivateInMem->CurrentPeimCount = 0;\r
-\r
+ PrivateInMem->PeimDispatcherReenter = TRUE;\r
+ \r
//\r
// Shadow PEI Core. When permanent memory is avaiable, shadow\r
// PEI Core and PEIMs to get high performance.\r
// pass. If we did not dispatch a PEIM there is no point in trying again\r
// as it will fail the next time too (nothing has changed).\r
//\r
- } while (PeimNeedingDispatch && PeimDispatchOnThisPass);\r
+ } while (Private->PeimNeedingDispatch && Private->PeimDispatchOnThisPass);\r
\r
}\r
\r
)\r
{\r
if (OldCoreData == NULL) {\r
+ PrivateData->PeimDispatcherReenter = FALSE;\r
PeiInitializeFv (PrivateData, SecCoreData);\r
}\r
\r
return EFI_SUCCESS;\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 FvFileHandle 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