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