\r
}\r
\r
-/**\r
- Shadow PeiCore module from flash to installed memory.\r
- \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
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN PEI_CORE_INSTANCE *PrivateInMem\r
- )\r
-{\r
- EFI_PEI_FILE_HANDLE PeiCoreFileHandle;\r
- EFI_PHYSICAL_ADDRESS EntryPoint;\r
- EFI_STATUS Status;\r
- UINT32 AuthenticationState;\r
-\r
- PeiCoreFileHandle = NULL;\r
-\r
- //\r
- // Find the PEI Core in the BFV\r
- //\r
- Status = PrivateInMem->Fv[0].FvPpi->FindFileByType (\r
- PrivateInMem->Fv[0].FvPpi,\r
- EFI_FV_FILETYPE_PEI_CORE,\r
- PrivateInMem->Fv[0].FvHandle,\r
- &PeiCoreFileHandle\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Shadow PEI Core into memory so it will run faster\r
- //\r
- Status = PeiLoadImage (\r
- PeiServices,\r
- *((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle),\r
- PEIM_STATE_REGISITER_FOR_SHADOW,\r
- &EntryPoint,\r
- &AuthenticationState\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
// This is the minimum memory required by DxeCore initialization. When LMFA feature enabled,\r
// This part of memory still need reserved on the very top of memory so that the DXE Core could \r
UINTN SaveCurrentFvCount;\r
EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;\r
PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData;\r
- EFI_PHYSICAL_ADDRESS NewPermenentMemoryBase;\r
TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;\r
- EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffTable;\r
- EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffTable;\r
- INTN StackOffset;\r
- INTN HeapOffset;\r
- PEI_CORE_INSTANCE *PrivateInMem;\r
- UINT64 NewPeiStackSize;\r
- UINT64 OldPeiStackSize;\r
- UINT64 StackGap;\r
+ UINT64 NewStackSize;\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 StackOffset;\r
+ BOOLEAN StackOffsetPositive;\r
EFI_FV_FILE_INFO FvFileInfo;\r
- UINTN OldCheckingTop;\r
- UINTN OldCheckingBottom;\r
PEI_CORE_FV_HANDLE *CoreFvHandle;\r
VOID *LoadFixPeiCodeBegin;\r
\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
- (SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN)SecCoreData->StackBase))\r
+ (UINT32)(SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN)SecCoreData->StackBase))\r
));\r
DEBUG ((EFI_D_INFO, " temporary memory heap used: %d bytes.\n",\r
- ((UINTN) Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom -\r
- (UINTN) Private->HobList.Raw)\r
+ (UINT32)((UINTN)Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN)Private->HobList.Raw)\r
));\r
DEBUG_CODE_END ();\r
\r
//\r
// Loading Module at Fixed Address is enabled\r
//\r
- PeiLoadFixAddressHook(Private);\r
+ PeiLoadFixAddressHook (Private);\r
+\r
//\r
- // if Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range.\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
// Reserve the size of new stack at bottom of physical memory\r
//\r
- OldPeiStackSize = (UINT64) SecCoreData->StackSize;\r
- NewPeiStackSize = (RShiftU64 (Private->PhysicalMemoryLength, 1) + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;\r
- if (PcdGet32(PcdPeiCoreMaxPeiStackSize) > (UINT32) NewPeiStackSize) {\r
- Private->StackSize = NewPeiStackSize;\r
- } else {\r
- Private->StackSize = PcdGet32(PcdPeiCoreMaxPeiStackSize);\r
- }\r
-\r
- //\r
- // In theory, the size of new stack in permenent memory should large than\r
- // size of old stack in temporary memory.\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
- DEBUG ((EFI_D_INFO, "Old Stack size %d, New stack size %d\n", (INT32) OldPeiStackSize, (INT32) Private->StackSize));\r
- ASSERT (Private->StackSize >= OldPeiStackSize);\r
- StackGap = Private->StackSize - OldPeiStackSize;\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
- // Update HandOffHob for new installed permenent memory\r
+ // Caculate stack offset and heap offset between temporary memory and new permement \r
+ // memory seperately.\r
//\r
- OldHandOffTable = Private->HobList.HandoffInformationTable;\r
- OldCheckingBottom = (UINTN)(SecCoreData->TemporaryRamBase);\r
- OldCheckingTop = (UINTN)(OldCheckingBottom + SecCoreData->TemporaryRamSize);\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
+ } else {\r
+ StackOffsetPositive = FALSE;\r
+ StackOffset = (UINTN)(TopOfOldStack - TopOfNewStack);\r
+ }\r
+\r
+ DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64)Private->HeapOffset, (UINT64)(StackOffset)));\r
\r
//\r
- // The whole temporary memory will be migrated to physical memory.\r
- // CAUTION: The new base is computed accounding to gap of new stack.\r
+ // Build Stack HOB that describes the permanent memory stack\r
//\r
- NewPermenentMemoryBase = Private->PhysicalMemoryBegin + StackGap;\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
- // Caculate stack offset and heap offset between temporary memory and new permement \r
- // memory seperately.\r
+ // Cache information from SecCoreData into locals before SecCoreData is converted to a permanent memory address\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%lX Stack Offset = 0x%lX\n", (INT64)HeapOffset, (INT64)StackOffset));\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 permenet memory's stack\r
+ // Caculate new HandOffTable and PrivateData address in permanent memory's stack\r
//\r
- NewHandOffTable = (EFI_HOB_HANDOFF_INFO_TABLE *)((UINTN)OldHandOffTable + HeapOffset);\r
- PrivateInMem = (PEI_CORE_INSTANCE *)((UINTN) (VOID*) Private + StackOffset);\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
// TemporaryRamSupportPpi is produced by platform's SEC\r
//\r
- Status = PeiLocatePpi (\r
- (CONST EFI_PEI_SERVICES **) PeiServices,\r
+ Status = PeiServicesLocatePpi (\r
&gEfiTemporaryRamSupportPpiGuid,\r
0,\r
NULL,\r
(VOID**)&TemporaryRamSupportPpi\r
);\r
-\r
-\r
if (!EFI_ERROR (Status)) {\r
//\r
- // Temporary Ram support Ppi is provided by platform, it will copy \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 temporary memory.\r
+ // After invoking Temporary Ram Support PPI, the following code's \r
+ // stack is in permanent memory.\r
//\r
TemporaryRamSupportPpi->TemporaryRamMigration (\r
- (CONST EFI_PEI_SERVICES **) PeiServices,\r
- (EFI_PHYSICAL_ADDRESS)(UINTN) SecCoreData->TemporaryRamBase,\r
- (EFI_PHYSICAL_ADDRESS)(UINTN) NewPermenentMemoryBase,\r
- SecCoreData->TemporaryRamSize\r
+ PeiServices,\r
+ TemporaryRamBase,\r
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(TopOfNewStack - TemporaryStackSize),\r
+ TemporaryRamSize\r
);\r
\r
} else {\r
//\r
// In IA32/x64/Itanium architecture, we need platform provide\r
- // TEMPORAY_RAM_MIGRATION_PPI.\r
+ // TEMPORARY_RAM_MIGRATION_PPI.\r
//\r
ASSERT (FALSE);\r
}\r
\r
-\r
- //\r
- //\r
- // Fixup the PeiCore's private data\r
- //\r
- PrivateInMem->Ps = &PrivateInMem->ServiceTableShadow;\r
- PrivateInMem->CpuIo = &PrivateInMem->ServiceTableShadow.CpuIo;\r
- PrivateInMem->HobList.Raw = (VOID*) ((UINTN) PrivateInMem->HobList.Raw + HeapOffset);\r
- PrivateInMem->StackBase = (EFI_PHYSICAL_ADDRESS)(((UINTN)PrivateInMem->PhysicalMemoryBegin + EFI_PAGE_MASK) & ~EFI_PAGE_MASK);\r
-\r
- PeiServices = (CONST EFI_PEI_SERVICES **) &PrivateInMem->Ps;\r
-\r
- //\r
- // Fixup for PeiService's address\r
- //\r
- SetPeiServicesTablePointer(PeiServices);\r
-\r
- //\r
- // Update HandOffHob for new installed permenent memory\r
- //\r
- NewHandOffTable->EfiEndOfHobList =\r
- (EFI_PHYSICAL_ADDRESS)((UINTN) NewHandOffTable->EfiEndOfHobList + HeapOffset);\r
- NewHandOffTable->EfiMemoryTop = PrivateInMem->PhysicalMemoryBegin +\r
- PrivateInMem->PhysicalMemoryLength;\r
- NewHandOffTable->EfiMemoryBottom = PrivateInMem->PhysicalMemoryBegin;\r
- NewHandOffTable->EfiFreeMemoryTop = PrivateInMem->FreePhysicalMemoryTop;\r
- NewHandOffTable->EfiFreeMemoryBottom = NewHandOffTable->EfiEndOfHobList +\r
- sizeof (EFI_HOB_GENERIC_HEADER);\r
-\r
- //\r
- // We need convert the PPI desciptor's pointer\r
- //\r
- ConvertPpiPointers (PrivateInMem, \r
- OldCheckingBottom, \r
- OldCheckingTop, \r
- HeapOffset\r
- );\r
-\r
- DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n",\r
- PrivateInMem->StackBase,\r
- PrivateInMem->StackSize));\r
- BuildStackHob (PrivateInMem->StackBase, PrivateInMem->StackSize);\r
-\r
- //\r
- // After the whole temporary memory is migrated, then we can allocate page in\r
- // permenent memory.\r
- //\r
- PrivateInMem->PeiMemoryInstalled = TRUE;\r
-\r
- //\r
- // Indicate that PeiCore reenter\r
- //\r
- PrivateInMem->PeimDispatcherReenter = TRUE;\r
- \r
- if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (PrivateInMem->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
- //\r
- // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array.\r
- // Every bit in the array indicate the status of the corresponding memory page available or not\r
- //\r
- PrivateInMem->PeiCodeMemoryRangeUsageBitMap = AllocateZeroPool (((PcdGet32(PcdLoadFixAddressPeiCodePageNumber)>>6) + 1)*sizeof(UINT64));\r
- }\r
- //\r
- // Shadow PEI Core. When permanent memory is avaiable, shadow\r
- // PEI Core and PEIMs to get high performance.\r
- //\r
- PrivateInMem->ShadowedPeiCore = ShadowPeiCore (\r
- PeiServices,\r
- PrivateInMem\r
- );\r
- //\r
- // Process the Notify list and dispatch any notifies for\r
- // newly installed PPIs.\r
- //\r
- ProcessNotifyList (PrivateInMem);\r
-\r
//\r
// Entry PEI Phase 2\r
//\r
- PeiCore (SecCoreData, NULL, PrivateInMem);\r
+ PeiCore (SecCoreData, NULL, Private);\r
\r
//\r
// Code should not come here\r
//\r
- ASSERT_EFI_ERROR(FALSE);\r
+ ASSERT (FALSE);\r
}\r
\r
//\r
UINTN SectionIndex;\r
} CACHE_SECTION_DATA;\r
\r
+///\r
+/// Forward declaration for PEI_CORE_INSTANCE\r
+///\r
+typedef struct _PEI_CORE_INSTANCE PEI_CORE_INSTANCE;\r
+\r
+\r
+/**\r
+ Function Pointer type for PeiCore function.\r
+ @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size \r
+ and location of temporary RAM, the stack location and the BFV location.\r
+ @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core.\r
+ An empty PPI list consists of a single descriptor with the end-tag\r
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization\r
+ phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such\r
+ that both the PEI Foundation and any modules can leverage the associated service\r
+ calls and/or code in these early PPIs\r
+ @param OldCoreData Pointer to old core data that is used to initialize the\r
+ core's data areas.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PEICORE_FUNCTION_POINTER)(\r
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,\r
+ IN PEI_CORE_INSTANCE *OldCoreData\r
+ );\r
\r
#define PEI_CORE_HANDLE_SIGNATURE SIGNATURE_32('P','e','i','C')\r
\r
///\r
/// Pei Core private data structure instance\r
///\r
-typedef struct{\r
+struct _PEI_CORE_INSTANCE {\r
UINTN Signature;\r
\r
///\r
EFI_PEI_HOB_POINTERS HobList;\r
BOOLEAN SwitchStackSignal;\r
BOOLEAN PeiMemoryInstalled;\r
- EFI_PHYSICAL_ADDRESS StackBase;\r
- UINT64 StackSize;\r
VOID *CpuIo;\r
EFI_PEI_SECURITY2_PPI *PrivateSecurityPpi;\r
EFI_PEI_SERVICES ServiceTableShadow;\r
EFI_PHYSICAL_ADDRESS PhysicalMemoryBegin;\r
UINT64 PhysicalMemoryLength;\r
EFI_PHYSICAL_ADDRESS FreePhysicalMemoryTop;\r
- VOID* ShadowedPeiCore;\r
+ UINTN HeapOffset;\r
+ BOOLEAN HeapOffsetPositive;\r
+ PEICORE_FUNCTION_POINTER ShadowedPeiCore;\r
CACHE_SECTION_DATA CacheSection;\r
//\r
// For Loading modules at fixed address feature to cache the top address below which the \r
// This field points to the shadowed image read function\r
//\r
PE_COFF_LOADER_READ_FILE ShadowedImageRead;\r
-} PEI_CORE_INSTANCE;\r
+};\r
\r
///\r
/// Pei Core Instance Data Macros\r
#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \\r
CR(a, PEI_CORE_INSTANCE, Ps, PEI_CORE_HANDLE_SIGNATURE)\r
\r
-/**\r
- Function Pointer type for PeiCore function.\r
- @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size \r
- and location of temporary RAM, the stack location and the BFV location.\r
- @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core.\r
- An empty PPI list consists of a single descriptor with the end-tag\r
- EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization\r
- phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such\r
- that both the PEI Foundation and any modules can leverage the associated service\r
- calls and/or code in these early PPIs\r
- @param OldCoreData Pointer to old core data that is used to initialize the\r
- core's data areas.\r
-**/\r
-typedef\r
-EFI_STATUS\r
-(EFIAPI *PEICORE_FUNCTION_POINTER)(\r
- IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
- IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,\r
- IN PEI_CORE_INSTANCE *OldCoreData\r
- );\r
-\r
///\r
/// Union of temporarily used function pointers (to save stack space)\r
///\r
will be fixup for PpiData and PpiDescriptor.\r
@param Fixup The address difference between\r
the new Hob list and old Hob list.\r
+ @param FixupPositive TRUE if new Hob list is above the old Hob list. \r
+ Otherwise FALSE.\r
\r
**/\r
VOID\r
IN PEI_CORE_INSTANCE *PrivateData,\r
IN UINTN OldCheckingBottom,\r
IN UINTN OldCheckingTop,\r
- IN INTN Fixup\r
+ IN UINTN Fixup,\r
+ IN BOOLEAN FixupPositive\r
);\r
\r
/**\r
PeiRegisterForShadow\r
};\r
\r
+/**\r
+ Shadow PeiCore module from flash to installed memory.\r
+ \r
+ @param PrivateData PeiCore's private data structure\r
+\r
+ @return PeiCore function address after shadowing.\r
+**/\r
+PEICORE_FUNCTION_POINTER\r
+ShadowPeiCore (\r
+ IN PEI_CORE_INSTANCE *PrivateData\r
+ )\r
+{\r
+ EFI_PEI_FILE_HANDLE PeiCoreFileHandle;\r
+ EFI_PHYSICAL_ADDRESS EntryPoint;\r
+ EFI_STATUS Status;\r
+ UINT32 AuthenticationState;\r
+\r
+ PeiCoreFileHandle = NULL;\r
+\r
+ //\r
+ // Find the PEI Core in the BFV\r
+ //\r
+ Status = PrivateData->Fv[0].FvPpi->FindFileByType (\r
+ PrivateData->Fv[0].FvPpi,\r
+ EFI_FV_FILETYPE_PEI_CORE,\r
+ PrivateData->Fv[0].FvHandle,\r
+ &PeiCoreFileHandle\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Shadow PEI Core into memory so it will run faster\r
+ //\r
+ Status = PeiLoadImage (\r
+ GetPeiServicesTablePointer (),\r
+ *((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle),\r
+ PEIM_STATE_REGISITER_FOR_SHADOW,\r
+ &EntryPoint,\r
+ &AuthenticationState\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 (PEICORE_FUNCTION_POINTER)((UINTN) EntryPoint + (UINTN) PeiCore - (UINTN) _ModuleEntryPoint);\r
+}\r
+\r
/**\r
This routine is invoked by main entry of PeiMain module during transition\r
from SEC to PEI. After switching stack in the PEI core, it will restart\r
IN VOID *Data\r
)\r
{\r
- PEI_CORE_INSTANCE PrivateData;\r
- EFI_STATUS Status;\r
- PEI_CORE_TEMP_POINTERS TempPtr;\r
- UINT64 Tick;\r
- PEI_CORE_INSTANCE *OldCoreData;\r
- EFI_PEI_CPU_IO_PPI *CpuIo;\r
- EFI_PEI_PCI_CFG2_PPI *PciCfg;\r
- PEICORE_FUNCTION_POINTER ShadowedPeiCore;\r
+ PEI_CORE_INSTANCE PrivateData;\r
+ EFI_STATUS Status;\r
+ PEI_CORE_TEMP_POINTERS TempPtr;\r
+ UINT64 Tick;\r
+ PEI_CORE_INSTANCE *OldCoreData;\r
+ EFI_PEI_CPU_IO_PPI *CpuIo;\r
+ EFI_PEI_PCI_CFG2_PPI *PciCfg;\r
+ EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable;\r
\r
Tick = 0;\r
- OldCoreData = (PEI_CORE_INSTANCE *) Data;\r
+ OldCoreData = (PEI_CORE_INSTANCE *)Data;\r
\r
//\r
// Record the system tick for first entering PeiCore.\r
}\r
\r
if (OldCoreData != NULL) {\r
- ShadowedPeiCore = (PEICORE_FUNCTION_POINTER) (UINTN) OldCoreData->ShadowedPeiCore;\r
- \r
- //\r
- // PeiCore has been shadowed to memory for first entering, so\r
- // just jump to PeiCore in memory here.\r
- //\r
- if (ShadowedPeiCore != NULL) {\r
- OldCoreData->ShadowedPeiCore = NULL;\r
- ShadowedPeiCore (\r
- SecCoreData,\r
- PpiList,\r
- OldCoreData\r
- );\r
+ if (OldCoreData->ShadowedPeiCore == NULL) {\r
+ //\r
+ //\r
+ // Fixup the PeiCore's private data\r
+ //\r
+ OldCoreData->Ps = &OldCoreData->ServiceTableShadow;\r
+ OldCoreData->CpuIo = &OldCoreData->ServiceTableShadow.CpuIo;\r
+ if (OldCoreData->HeapOffsetPositive) {\r
+ OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw + OldCoreData->HeapOffset);\r
+ } else {\r
+ OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw - OldCoreData->HeapOffset);\r
+ }\r
+\r
+ //\r
+ // Fixup for PeiService's address\r
+ //\r
+ SetPeiServicesTablePointer ((CONST EFI_PEI_SERVICES **)&OldCoreData->Ps);\r
+\r
+ //\r
+ // Update HandOffHob for new installed permenent memory\r
+ //\r
+ HandoffInformationTable = OldCoreData->HobList.HandoffInformationTable;\r
+ if (OldCoreData->HeapOffsetPositive) {\r
+ HandoffInformationTable->EfiEndOfHobList = HandoffInformationTable->EfiEndOfHobList + OldCoreData->HeapOffset;\r
+ } else {\r
+ HandoffInformationTable->EfiEndOfHobList = HandoffInformationTable->EfiEndOfHobList - OldCoreData->HeapOffset;\r
+ }\r
+ HandoffInformationTable->EfiMemoryTop = OldCoreData->PhysicalMemoryBegin + OldCoreData->PhysicalMemoryLength;\r
+ HandoffInformationTable->EfiMemoryBottom = OldCoreData->PhysicalMemoryBegin;\r
+ HandoffInformationTable->EfiFreeMemoryTop = OldCoreData->FreePhysicalMemoryTop;\r
+ HandoffInformationTable->EfiFreeMemoryBottom = HandoffInformationTable->EfiEndOfHobList + sizeof (EFI_HOB_GENERIC_HEADER);\r
+\r
+ //\r
+ // We need convert the PPI desciptor's pointer\r
+ //\r
+ ConvertPpiPointers (OldCoreData, (UINTN)SecCoreData->TemporaryRamBase, (UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize, OldCoreData->HeapOffset, OldCoreData->HeapOffsetPositive);\r
+\r
+ //\r
+ // After the whole temporary memory is migrated, then we can allocate page in\r
+ // permenent memory.\r
+ //\r
+ OldCoreData->PeiMemoryInstalled = TRUE;\r
+\r
+ //\r
+ // Indicate that PeiCore reenter\r
+ //\r
+ OldCoreData->PeimDispatcherReenter = TRUE;\r
+ \r
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (OldCoreData->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+ //\r
+ // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array.\r
+ // Every bit in the array indicate the status of the corresponding memory page available or not\r
+ //\r
+ OldCoreData->PeiCodeMemoryRangeUsageBitMap = AllocateZeroPool (((PcdGet32(PcdLoadFixAddressPeiCodePageNumber)>>6) + 1)*sizeof(UINT64));\r
+ }\r
+\r
+ //\r
+ // Process the Notify list and dispatch any notifies for\r
+ // newly installed PPIs.\r
+ //\r
+ ProcessNotifyList (OldCoreData);\r
+\r
+ //\r
+ // Shadow PEI Core. When permanent memory is avaiable, shadow\r
+ // PEI Core and PEIMs to get high performance.\r
+ //\r
+ OldCoreData->ShadowedPeiCore = ShadowPeiCore (OldCoreData);\r
+ \r
+ //\r
+ // PeiCore has been shadowed to memory for first entering, so\r
+ // just jump to PeiCore in memory here.\r
+ //\r
+ OldCoreData->ShadowedPeiCore (SecCoreData, PpiList, OldCoreData);\r
}\r
\r
- CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));\r
+ CopyMem (&PrivateData, OldCoreData, sizeof (PrivateData));\r
\r
CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;\r
PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;\r