PeiCore (SecCoreData, NULL, Private);\r
}\r
\r
+/**\r
+ Check SwitchStackSignal and switch stack if SwitchStackSignal is TRUE.\r
+\r
+ @param[in] 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[in] Private Pointer to the private data passed in from caller.\r
+\r
+**/\r
+VOID\r
+PeiCheckAndSwitchStack (\r
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
+ IN PEI_CORE_INSTANCE *Private\r
+ )\r
+{\r
+ VOID *LoadFixPeiCodeBegin;\r
+ EFI_STATUS Status;\r
+ CONST EFI_PEI_SERVICES **PeiServices;\r
+ UINT64 NewStackSize;\r
+ EFI_PHYSICAL_ADDRESS TopOfOldStack;\r
+ EFI_PHYSICAL_ADDRESS TopOfNewStack;\r
+ UINTN StackOffset;\r
+ BOOLEAN StackOffsetPositive;\r
+ EFI_PHYSICAL_ADDRESS TemporaryRamBase;\r
+ UINTN TemporaryRamSize;\r
+ UINTN TemporaryStackSize;\r
+ VOID *TemporaryStackBase;\r
+ UINTN PeiTemporaryRamSize;\r
+ VOID *PeiTemporaryRamBase;\r
+ EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;\r
+ EFI_PHYSICAL_ADDRESS BaseOfNewHeap;\r
+ EFI_PHYSICAL_ADDRESS HoleMemBase;\r
+ UINTN HoleMemSize;\r
+ UINTN HeapTemporaryRamSize;\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
+\r
+ if (Private->SwitchStackSignal) {\r
+ //\r
+ // Before switch stack from temporary memory to permenent memory, calculate the heap and stack\r
+ // usage in temporary memory for debuging.\r
+ //\r
+ DEBUG_CODE_BEGIN ();\r
+ UINT32 *StackPointer;\r
+\r
+ for (StackPointer = (UINT32*)SecCoreData->StackBase;\r
+ (StackPointer < (UINT32*)((UINTN)SecCoreData->StackBase + SecCoreData->StackSize)) \\r
+ && (*StackPointer == INIT_CAR_VALUE);\r
+ StackPointer ++);\r
+\r
+ DEBUG ((EFI_D_INFO, "Temp Stack : BaseAddress=0x%p Length=0x%X\n", SecCoreData->StackBase, (UINT32)SecCoreData->StackSize));\r
+ DEBUG ((EFI_D_INFO, "Temp Heap : BaseAddress=0x%p Length=0x%X\n", Private->HobList.Raw, (UINT32)((UINTN) Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN) Private->HobList.Raw)));\r
+ DEBUG ((EFI_D_INFO, "Total temporary memory: %d bytes.\n", (UINT32)SecCoreData->TemporaryRamSize));\r
+ DEBUG ((EFI_D_INFO, " temporary memory stack ever used: %d bytes.\n",\r
+ (UINT32)(SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN)SecCoreData->StackBase))\r
+ ));\r
+ DEBUG ((EFI_D_INFO, " temporary memory heap used: %d bytes.\n",\r
+ (UINT32)((UINTN)Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN)Private->HobList.Raw)\r
+ ));\r
+ DEBUG_CODE_END ();\r
+\r
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+ //\r
+ // Loading Module at Fixed Address is enabled\r
+ //\r
+ PeiLoadFixAddressHook (Private);\r
+\r
+ //\r
+ // If Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range.\r
+ //\r
+ LoadFixPeiCodeBegin = AllocatePages((UINTN)PcdGet32(PcdLoadFixAddressPeiCodePageNumber));\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PeiCodeBegin = 0x%lX, PeiCodeTop= 0x%lX\n", (UINT64)(UINTN)LoadFixPeiCodeBegin, (UINT64)((UINTN)LoadFixPeiCodeBegin + PcdGet32(PcdLoadFixAddressPeiCodePageNumber) * EFI_PAGE_SIZE)));\r
+ }\r
+\r
+ //\r
+ // Reserve the size of new stack at bottom of physical memory\r
+ //\r
+ // The size of new stack in permenent memory must be the same size \r
+ // or larger than the size of old stack in temporary memory.\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
+ NewStackSize = RShiftU64 (Private->PhysicalMemoryLength, 1);\r
+ NewStackSize = ALIGN_VALUE (NewStackSize, EFI_PAGE_SIZE);\r
+ NewStackSize = MIN (PcdGet32(PcdPeiCoreMaxPeiStackSize), NewStackSize);\r
+ DEBUG ((EFI_D_INFO, "Old Stack size %d, New stack size %d\n", (UINT32)SecCoreData->StackSize, (UINT32)NewStackSize));\r
+ ASSERT (NewStackSize >= SecCoreData->StackSize);\r
+\r
+ //\r
+ // Calculate stack offset and heap offset between temporary memory and new permement \r
+ // memory seperately.\r
+ //\r
+ TopOfOldStack = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize;\r
+ TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize;\r
+ if (TopOfNewStack >= TopOfOldStack) {\r
+ StackOffsetPositive = TRUE;\r
+ StackOffset = (UINTN)(TopOfNewStack - TopOfOldStack);\r
+ } else {\r
+ StackOffsetPositive = FALSE;\r
+ StackOffset = (UINTN)(TopOfOldStack - TopOfNewStack);\r
+ }\r
+ Private->StackOffsetPositive = StackOffsetPositive;\r
+ Private->StackOffset = StackOffset;\r
+\r
+ //\r
+ // Build Stack HOB that describes the permanent memory stack\r
+ //\r
+ DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n", TopOfNewStack - NewStackSize, NewStackSize));\r
+ BuildStackHob (TopOfNewStack - NewStackSize, NewStackSize);\r
+\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
+ TemporaryStackBase = SecCoreData->StackBase;\r
+ PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize;\r
+ PeiTemporaryRamBase = SecCoreData->PeiTemporaryRamBase;\r
+\r
+ //\r
+ // TemporaryRamSupportPpi is produced by platform's SEC\r
+ //\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiTemporaryRamSupportPpiGuid,\r
+ 0,\r
+ NULL,\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
+ DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64) Private->HeapOffset, (UINT64) Private->StackOffset));\r
+\r
+ //\r
+ // Calculate 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
+ // After invoking Temporary Ram Support PPI, the following code's \r
+ // stack is in permanent memory.\r
+ //\r
+ TemporaryRamSupportPpi->TemporaryRamMigration (\r
+ PeiServices,\r
+ TemporaryRamBase,\r
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(TopOfNewStack - TemporaryStackSize),\r
+ TemporaryRamSize\r
+ );\r
+\r
+ //\r
+ // Entry PEI Phase 2\r
+ //\r
+ PeiCore (SecCoreData, NULL, Private);\r
+ } else {\r
+ //\r
+ // Migrate the PEI Services Table pointer from temporary RAM to permanent RAM.\r
+ //\r
+ MigratePeiServicesTablePointer ();\r
+ \r
+ //\r
+ // Heap Offset\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
+ DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64) Private->HeapOffset, (UINT64) Private->StackOffset));\r
+\r
+ //\r
+ // Migrate Heap\r
+ //\r
+ HeapTemporaryRamSize = (UINTN) (Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - Private->HobList.HandoffInformationTable->EfiMemoryBottom);\r
+ ASSERT (BaseOfNewHeap + HeapTemporaryRamSize <= Private->FreePhysicalMemoryTop);\r
+ CopyMem ((UINT8 *) (UINTN) BaseOfNewHeap, (UINT8 *) PeiTemporaryRamBase, HeapTemporaryRamSize);\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
+ //\r
+ ASSERT (FALSE);\r
+ }\r
+}\r
+\r
/**\r
Conduct PEIM dispatch.\r
\r
UINTN SaveCurrentPeimCount;\r
UINTN SaveCurrentFvCount;\r
EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;\r
- EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;\r
- UINT64 NewStackSize;\r
- UINTN HeapTemporaryRamSize;\r
- EFI_PHYSICAL_ADDRESS BaseOfNewHeap;\r
- EFI_PHYSICAL_ADDRESS TopOfNewStack;\r
- EFI_PHYSICAL_ADDRESS TopOfOldStack;\r
- EFI_PHYSICAL_ADDRESS TemporaryRamBase;\r
- UINTN TemporaryRamSize;\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
- 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
for (Index2 = 0; (Index2 < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {\r
if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {\r
PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];\r
+ Private->CurrentFileHandle = PeimFileHandle;\r
+ Private->CurrentPeimFvCount = Index1;\r
+ Private->CurrentPeimCount = Index2;\r
Status = PeiLoadImage (\r
(CONST EFI_PEI_SERVICES **) &Private->Ps,\r
PeimFileHandle,\r
// PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE\r
//\r
Private->Fv[Index1].PeimState[Index2]++;\r
- Private->CurrentFileHandle = PeimFileHandle;\r
- Private->CurrentPeimFvCount = Index1;\r
- Private->CurrentPeimCount = Index2;\r
//\r
// Call the PEIM entry point\r
//\r
}\r
}\r
\r
- if (Private->SwitchStackSignal) {\r
- //\r
- // Before switch stack from temporary memory to permenent memory, calculate the heap and stack\r
- // usage in temporary memory for debuging.\r
- //\r
- DEBUG_CODE_BEGIN ();\r
- UINT32 *StackPointer;\r
- \r
- for (StackPointer = (UINT32*)SecCoreData->StackBase;\r
- (StackPointer < (UINT32*)((UINTN)SecCoreData->StackBase + SecCoreData->StackSize)) \\r
- && (*StackPointer == INIT_CAR_VALUE);\r
- StackPointer ++);\r
- \r
- DEBUG ((EFI_D_INFO, "Temp Stack : BaseAddress=0x%p Length=0x%X\n", SecCoreData->StackBase, (UINT32)SecCoreData->StackSize));\r
- DEBUG ((EFI_D_INFO, "Temp Heap : BaseAddress=0x%p Length=0x%X\n", Private->HobList.Raw, (UINT32)((UINTN) Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN) Private->HobList.Raw)));\r
- DEBUG ((EFI_D_INFO, "Total temporary memory: %d bytes.\n", (UINT32)SecCoreData->TemporaryRamSize));\r
- DEBUG ((EFI_D_INFO, " temporary memory stack ever used: %d bytes.\n",\r
- (UINT32)(SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN)SecCoreData->StackBase))\r
- ));\r
- DEBUG ((EFI_D_INFO, " temporary memory heap used: %d bytes.\n",\r
- (UINT32)((UINTN)Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN)Private->HobList.Raw)\r
- ));\r
- DEBUG_CODE_END ();\r
- \r
- if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
- //\r
- // Loading Module at Fixed Address is enabled\r
- //\r
- PeiLoadFixAddressHook (Private);\r
-\r
- //\r
- // If Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range.\r
- //\r
- LoadFixPeiCodeBegin = AllocatePages((UINTN)PcdGet32(PcdLoadFixAddressPeiCodePageNumber));\r
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PeiCodeBegin = 0x%lX, PeiCodeTop= 0x%lX\n", (UINT64)(UINTN)LoadFixPeiCodeBegin, (UINT64)((UINTN)LoadFixPeiCodeBegin + PcdGet32(PcdLoadFixAddressPeiCodePageNumber) * EFI_PAGE_SIZE)));\r
- }\r
- \r
- //\r
- // Reserve the size of new stack at bottom of physical memory\r
- //\r
- // The size of new stack in permenent memory must be the same size \r
- // or larger than the size of old stack in temporary memory.\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
- NewStackSize = RShiftU64 (Private->PhysicalMemoryLength, 1);\r
- NewStackSize = ALIGN_VALUE (NewStackSize, EFI_PAGE_SIZE);\r
- NewStackSize = MIN (PcdGet32(PcdPeiCoreMaxPeiStackSize), NewStackSize);\r
- DEBUG ((EFI_D_INFO, "Old Stack size %d, New stack size %d\n", (UINT32)SecCoreData->StackSize, (UINT32)NewStackSize));\r
- ASSERT (NewStackSize >= SecCoreData->StackSize);\r
-\r
- //\r
- // Calculate stack offset and heap offset between temporary memory and new permement \r
- // memory seperately.\r
- //\r
- TopOfOldStack = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize;\r
- TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize;\r
- if (TopOfNewStack >= TopOfOldStack) {\r
- StackOffsetPositive = TRUE;\r
- StackOffset = (UINTN)(TopOfNewStack - TopOfOldStack);\r
- } else {\r
- StackOffsetPositive = FALSE;\r
- StackOffset = (UINTN)(TopOfOldStack - TopOfNewStack);\r
- }\r
- Private->StackOffsetPositive = StackOffsetPositive;\r
- Private->StackOffset = StackOffset;\r
-\r
- //\r
- // Build Stack HOB that describes the permanent memory stack\r
- //\r
- DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n", TopOfNewStack - NewStackSize, NewStackSize));\r
- BuildStackHob (TopOfNewStack - NewStackSize, NewStackSize);\r
-\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
- TemporaryStackBase = SecCoreData->StackBase;\r
- PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize;\r
- PeiTemporaryRamBase = SecCoreData->PeiTemporaryRamBase;\r
- \r
- //\r
- // TemporaryRamSupportPpi is produced by platform's SEC\r
- //\r
- Status = PeiServicesLocatePpi (\r
- &gEfiTemporaryRamSupportPpiGuid,\r
- 0,\r
- NULL,\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
- DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64) Private->HeapOffset, (UINT64) Private->StackOffset));\r
-\r
- //\r
- // Calculate 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
- // After invoking Temporary Ram Support PPI, the following code's \r
- // stack is in permanent memory.\r
- //\r
- TemporaryRamSupportPpi->TemporaryRamMigration (\r
- PeiServices,\r
- TemporaryRamBase,\r
- (EFI_PHYSICAL_ADDRESS)(UINTN)(TopOfNewStack - TemporaryStackSize),\r
- TemporaryRamSize\r
- );\r
-\r
- //\r
- // Entry PEI Phase 2\r
- //\r
- PeiCore (SecCoreData, NULL, Private);\r
- } else {\r
- //\r
- // Migrate the PEI Services Table pointer from temporary RAM to permanent RAM.\r
- //\r
- MigratePeiServicesTablePointer ();\r
- \r
- //\r
- // Heap Offset\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
- DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64) Private->HeapOffset, (UINT64) Private->StackOffset));\r
-\r
- //\r
- // Migrate Heap\r
- //\r
- HeapTemporaryRamSize = (UINTN) (Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - Private->HobList.HandoffInformationTable->EfiMemoryBottom);\r
- ASSERT (BaseOfNewHeap + HeapTemporaryRamSize <= Private->FreePhysicalMemoryTop);\r
- CopyMem ((UINT8 *) (UINTN) BaseOfNewHeap, (UINT8 *) PeiTemporaryRamBase, HeapTemporaryRamSize);\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
- //\r
- ASSERT (FALSE);\r
- }\r
+ PeiCheckAndSwitchStack (SecCoreData, Private);\r
\r
//\r
// Process the Notify list and dispatch any notifies for\r
//\r
ProcessNotifyList (Private);\r
\r
+ //\r
+ // Recheck SwitchStackSignal after ProcessNotifyList()\r
+ // in case PeiInstallPeiMemory() is done in a callback with\r
+ // EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH.\r
+ //\r
+ PeiCheckAndSwitchStack (SecCoreData, 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 || PcdGetBool (PcdShadowPeimOnS3Boot))) {\r
//\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
+ if ((Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) && !PcdGetBool (PcdShadowPeimOnBoot)) {\r
+ //\r
+ // Load PEIM into Memory for Register for shadow PEIM.\r
+ //\r
+ Status = PeiLoadImage (\r
+ PeiServices,\r
+ PeimFileHandle,\r
+ PEIM_STATE_REGISITER_FOR_SHADOW,\r
+ &EntryPoint,\r
+ &AuthenticationState\r
+ );\r
+ if (Status == EFI_SUCCESS) {\r
+ PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;\r
+ }\r
+ }\r
ASSERT (PeimEntryPoint != NULL);\r
PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);\r
//PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);\r