UINTN PeimIndex;\r
UINTN PeimCount;\r
EFI_GUID *Guid;\r
- EFI_PEI_FILE_HANDLE TempFileHandles[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)];\r
+ EFI_PEI_FILE_HANDLE TempFileHandles[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv) + 1];\r
EFI_GUID FileGuid[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)];\r
EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
EFI_FV_FILE_INFO FileInfo;\r
//\r
// Go ahead to scan this Fv, and cache FileHandles within it.\r
//\r
- for (PeimCount = 0; PeimCount < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv); PeimCount++) {\r
+ Status = EFI_NOT_FOUND;\r
+ for (PeimCount = 0; PeimCount <= FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv); PeimCount++) {\r
Status = FvPpi->FindFileByType (FvPpi, PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, CoreFileHandle->FvHandle, &FileHandle);\r
- if (Status != EFI_SUCCESS) {\r
+ if (Status != EFI_SUCCESS || PeimCount == FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)) {\r
break;\r
}\r
\r
Private->CurrentFvFileHandles[PeimCount] = FileHandle;\r
}\r
- \r
+\r
//\r
// Check whether the count of Peims exceeds the max support PEIMs in a FV image\r
// If more Peims are required in a FV image, PcdPeiCoreMaxPeimPerFv can be set to a larger value in DSC file.\r
//\r
- ASSERT (PeimCount < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv));\r
+ ASSERT ((Status != EFI_SUCCESS) || (PeimCount < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)));\r
\r
//\r
// Get Apriori File handle\r
PrivateData->PhysicalMemoryBegin = TopLoadingAddress - TotalReservedMemorySize;\r
PrivateData->FreePhysicalMemoryTop = PrivateData->PhysicalMemoryBegin + PeiMemorySize;\r
}\r
+\r
+/**\r
+ This routine is invoked in switch stack as PeiCore Entry.\r
+\r
+ @param SecCoreData Points to a data structure containing information about the PEI core's operating\r
+ environment, such as the size and location of temporary RAM, the stack location and\r
+ the BFV location.\r
+ @param Private Pointer to old core data that is used to initialize the\r
+ core's data areas.\r
+**/\r
+VOID\r
+EFIAPI\r
+PeiCoreEntry (\r
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
+ IN PEI_CORE_INSTANCE *Private\r
+ )\r
+{\r
+ //\r
+ // Entry PEI Phase 2\r
+ //\r
+ PeiCore (SecCoreData, NULL, Private);\r
+}\r
+\r
/**\r
Conduct PEIM dispatch.\r
\r
PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData;\r
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;\r
UINT64 NewStackSize;\r
+ EFI_PHYSICAL_ADDRESS BaseOfNewHeap;\r
EFI_PHYSICAL_ADDRESS TopOfNewStack;\r
EFI_PHYSICAL_ADDRESS TopOfOldStack;\r
EFI_PHYSICAL_ADDRESS TemporaryRamBase;\r
UINTN TemporaryRamSize;\r
- EFI_PHYSICAL_ADDRESS TemporaryStackSize;\r
+ UINTN TemporaryStackSize;\r
+ VOID *TemporaryStackBase;\r
+ UINTN PeiTemporaryRamSize;\r
+ VOID *PeiTemporaryRamBase;\r
UINTN StackOffset;\r
BOOLEAN StackOffsetPositive;\r
+ EFI_PHYSICAL_ADDRESS HoleMemBase;\r
+ UINTN HoleMemSize;\r
EFI_FV_FILE_INFO FvFileInfo;\r
PEI_CORE_FV_HANDLE *CoreFvHandle;\r
VOID *LoadFixPeiCodeBegin;\r
-\r
+ EFI_PHYSICAL_ADDRESS TempBase1;\r
+ UINTN TempSize1;\r
+ EFI_PHYSICAL_ADDRESS TempBase2;\r
+ UINTN TempSize2;\r
+ UINTN Index;\r
+ \r
PeiServices = (CONST EFI_PEI_SERVICES **) &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
+ if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {\r
//\r
// Once real memory is available, shadow the RegisterForShadow modules. And meanwhile\r
// update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.\r
//\r
// For Fv type file, Produce new FV PPI and FV hob\r
//\r
- Status = ProcessFvFile (&Private->Fv[FvCount], PeimFileHandle);\r
- AuthenticationState = 0;\r
+ Status = ProcessFvFile (Private, &Private->Fv[FvCount], PeimFileHandle);\r
+ if (Status == EFI_SUCCESS) {\r
+ //\r
+ // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED\r
+ //\r
+ Private->Fv[FvCount].PeimState[PeimCount]++;\r
+ Private->PeimDispatchOnThisPass = TRUE;\r
+ }\r
} else {\r
//\r
// For PEIM driver, Load its entry point\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
- //\r
- PERF_START (PeimFileHandle, "PEIM", NULL, 0);\r
-\r
- ExtendedData.Handle = (EFI_HANDLE)PeimFileHandle;\r
-\r
- REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
- EFI_PROGRESS_CODE,\r
- (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN),\r
- (VOID *)(&ExtendedData),\r
- sizeof (ExtendedData)\r
- );\r
-\r
- Status = VerifyPeim (Private, CoreFvHandle->FvHandle, PeimFileHandle);\r
- if (Status != EFI_SECURITY_VIOLATION && (AuthenticationState == 0)) {\r
+ if (Status == EFI_SUCCESS) {\r
//\r
- // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED\r
+ // The PEIM has its dependencies satisfied, and its entry point\r
+ // has been found, so invoke it.\r
//\r
- Private->Fv[FvCount].PeimState[PeimCount]++;\r
+ PERF_START (PeimFileHandle, "PEIM", NULL, 0);\r
+\r
+ ExtendedData.Handle = (EFI_HANDLE)PeimFileHandle;\r
\r
- if (FvFileInfo.FileType != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {\r
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN),\r
+ (VOID *)(&ExtendedData),\r
+ sizeof (ExtendedData)\r
+ );\r
+\r
+ Status = VerifyPeim (Private, CoreFvHandle->FvHandle, PeimFileHandle, AuthenticationState);\r
+ if (Status != EFI_SECURITY_VIOLATION) {\r
+ //\r
+ // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED\r
+ //\r
+ Private->Fv[FvCount].PeimState[PeimCount]++;\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
+ Private->PeimDispatchOnThisPass = TRUE;\r
}\r
\r
- Private->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
- (VOID *)(&ExtendedData),\r
- sizeof (ExtendedData)\r
- );\r
- PERF_END (PeimFileHandle, "PEIM", NULL, 0);\r
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END),\r
+ (VOID *)(&ExtendedData),\r
+ sizeof (ExtendedData)\r
+ );\r
+ PERF_END (PeimFileHandle, "PEIM", NULL, 0);\r
\r
+ }\r
}\r
\r
if (Private->SwitchStackSignal) {\r
//\r
TopOfOldStack = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize;\r
TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize;\r
- if (TopOfNewStack >= (UINTN)SecCoreData->PeiTemporaryRamBase) {\r
- Private->HeapOffsetPositive = TRUE;\r
- Private->HeapOffset = (UINTN)(TopOfNewStack - (UINTN)SecCoreData->PeiTemporaryRamBase);\r
- } else {\r
- Private->HeapOffsetPositive = FALSE;\r
- Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - TopOfNewStack);\r
- }\r
if (TopOfNewStack >= TopOfOldStack) {\r
StackOffsetPositive = TRUE;\r
StackOffset = (UINTN)(TopOfNewStack - TopOfOldStack);\r
//\r
// Cache information from SecCoreData into locals before SecCoreData is converted to a permanent memory address\r
//\r
- TemporaryRamBase = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase;\r
- TemporaryRamSize = SecCoreData->TemporaryRamSize;\r
- TemporaryStackSize = SecCoreData->StackSize;\r
-\r
- //\r
- // Caculate new HandOffTable and PrivateData address in permanent memory's stack\r
- //\r
- if (StackOffsetPositive) {\r
- SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset);\r
- Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset);\r
- } else {\r
- SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset);\r
- Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset);\r
- }\r
-\r
+ TemporaryRamBase = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase;\r
+ TemporaryRamSize = SecCoreData->TemporaryRamSize;\r
+ TemporaryStackSize = SecCoreData->StackSize;\r
+ TemporaryStackBase = SecCoreData->StackBase;\r
+ PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize;\r
+ PeiTemporaryRamBase = SecCoreData->PeiTemporaryRamBase;\r
+ \r
//\r
// TemporaryRamSupportPpi is produced by platform's SEC\r
//\r
(VOID**)&TemporaryRamSupportPpi\r
);\r
if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Heap Offset\r
+ //\r
+ BaseOfNewHeap = TopOfNewStack;\r
+ if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) {\r
+ Private->HeapOffsetPositive = TRUE;\r
+ Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase);\r
+ } else {\r
+ Private->HeapOffsetPositive = FALSE;\r
+ Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);\r
+ }\r
+ \r
+ //\r
+ // Caculate new HandOffTable and PrivateData address in permanent memory's stack\r
+ //\r
+ if (StackOffsetPositive) {\r
+ SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset);\r
+ Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset);\r
+ } else {\r
+ SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset);\r
+ Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset);\r
+ }\r
+\r
//\r
// Temporary Ram Support PPI is provided by platform, it will copy \r
// temporary memory to permenent memory and do stack switching.\r
TemporaryRamSize\r
);\r
\r
+ //\r
+ // Entry PEI Phase 2\r
+ //\r
+ PeiCore (SecCoreData, NULL, Private);\r
} else {\r
//\r
- // In IA32/x64/Itanium architecture, we need platform provide\r
- // TEMPORARY_RAM_MIGRATION_PPI.\r
+ // Heap Offset\r
//\r
- ASSERT (FALSE);\r
- }\r
+ BaseOfNewHeap = TopOfNewStack;\r
+ HoleMemBase = TopOfNewStack;\r
+ HoleMemSize = TemporaryRamSize - PeiTemporaryRamSize - TemporaryStackSize;\r
+ if (HoleMemSize != 0) {\r
+ //\r
+ // Make sure HOB List start address is 8 byte alignment.\r
+ //\r
+ BaseOfNewHeap = ALIGN_VALUE (BaseOfNewHeap + HoleMemSize, 8);\r
+ }\r
+ if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) {\r
+ Private->HeapOffsetPositive = TRUE;\r
+ Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase);\r
+ } else {\r
+ Private->HeapOffsetPositive = FALSE;\r
+ Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);\r
+ }\r
\r
- //\r
- // Entry PEI Phase 2\r
- //\r
- PeiCore (SecCoreData, NULL, Private);\r
+ //\r
+ // Migrate Heap\r
+ //\r
+ CopyMem ((UINT8 *) (UINTN) BaseOfNewHeap, (UINT8 *) PeiTemporaryRamBase, PeiTemporaryRamSize);\r
+ \r
+ //\r
+ // Migrate Stack\r
+ //\r
+ CopyMem ((UINT8 *) (UINTN) (TopOfNewStack - TemporaryStackSize), TemporaryStackBase, TemporaryStackSize);\r
+ \r
+ //\r
+ // Copy Hole Range Data\r
+ // Convert PPI from Hole. \r
+ //\r
+ if (HoleMemSize != 0) {\r
+ //\r
+ // Prepare Hole\r
+ //\r
+ if (PeiTemporaryRamBase < TemporaryStackBase) {\r
+ TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase;\r
+ TempSize1 = PeiTemporaryRamSize;\r
+ TempBase2 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase;\r
+ TempSize2 = TemporaryStackSize;\r
+ } else {\r
+ TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase;\r
+ TempSize1 = TemporaryStackSize;\r
+ TempBase2 =(EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase;\r
+ TempSize2 = PeiTemporaryRamSize;\r
+ }\r
+ if (TemporaryRamBase < TempBase1) {\r
+ Private->HoleData[0].Base = TemporaryRamBase;\r
+ Private->HoleData[0].Size = (UINTN) (TempBase1 - TemporaryRamBase);\r
+ }\r
+ if (TempBase1 + TempSize1 < TempBase2) {\r
+ Private->HoleData[1].Base = TempBase1 + TempSize1;\r
+ Private->HoleData[1].Size = (UINTN) (TempBase2 - TempBase1 - TempSize1);\r
+ }\r
+ if (TempBase2 + TempSize2 < TemporaryRamBase + TemporaryRamSize) {\r
+ Private->HoleData[2].Base = TempBase2 + TempSize2;\r
+ Private->HoleData[2].Size = (UINTN) (TemporaryRamBase + TemporaryRamSize - TempBase2 - TempSize2);\r
+ }\r
+ \r
+ //\r
+ // Copy Hole Range data.\r
+ //\r
+ for (Index = 0; Index < HOLE_MAX_NUMBER; Index ++) {\r
+ if (Private->HoleData[Index].Size > 0) {\r
+ if (HoleMemBase > Private->HoleData[Index].Base) {\r
+ Private->HoleData[Index].OffsetPositive = TRUE;\r
+ Private->HoleData[Index].Offset = (UINTN) (HoleMemBase - Private->HoleData[Index].Base);\r
+ } else {\r
+ Private->HoleData[Index].OffsetPositive = FALSE;\r
+ Private->HoleData[Index].Offset = (UINTN) (Private->HoleData[Index].Base - HoleMemBase);\r
+ }\r
+ CopyMem ((VOID *) (UINTN) HoleMemBase, (VOID *) (UINTN) Private->HoleData[Index].Base, Private->HoleData[Index].Size);\r
+ HoleMemBase = HoleMemBase + Private->HoleData[Index].Size;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Switch new stack\r
+ //\r
+ SwitchStack (\r
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)PeiCoreEntry,\r
+ (VOID *) SecCoreData,\r
+ (VOID *) Private,\r
+ (VOID *) (UINTN) TopOfNewStack\r
+ );\r
+ }\r
\r
//\r
// Code should not come here\r
ProcessNotifyList (Private);\r
\r
if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \\r
- (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+ (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {\r
//\r
// If memory is availble we shadow images by default for performance reasons.\r
// We call the entry point a 2nd time so the module knows it's shadowed.\r