diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c index d0b7bb072d..6198114bb1 100644 --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c @@ -183,56 +183,6 @@ DiscoverPeimsAndOrderWithApriori ( } -/** - Shadow PeiCore module from flash to installed memory. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param PrivateInMem PeiCore's private data structure - - @return PeiCore function address after shadowing. -**/ -VOID* -ShadowPeiCore( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN PEI_CORE_INSTANCE *PrivateInMem - ) -{ - EFI_PEI_FILE_HANDLE PeiCoreFileHandle; - EFI_PHYSICAL_ADDRESS EntryPoint; - EFI_STATUS Status; - UINT32 AuthenticationState; - - PeiCoreFileHandle = NULL; - - // - // Find the PEI Core in the BFV - // - Status = PrivateInMem->Fv[0].FvPpi->FindFileByType ( - PrivateInMem->Fv[0].FvPpi, - EFI_FV_FILETYPE_PEI_CORE, - PrivateInMem->Fv[0].FvHandle, - &PeiCoreFileHandle - ); - ASSERT_EFI_ERROR (Status); - - // - // Shadow PEI Core into memory so it will run faster - // - Status = PeiLoadImage ( - PeiServices, - *((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle), - PEIM_STATE_REGISITER_FOR_SHADOW, - &EntryPoint, - &AuthenticationState - ); - ASSERT_EFI_ERROR (Status); - - // - // Compute the PeiCore's function address after shaowed PeiCore. - // _ModuleEntryPoint is PeiCore main function entry - // - return (VOID*) ((UINTN) EntryPoint + (UINTN) PeiCore - (UINTN) _ModuleEntryPoint); -} // // This is the minimum memory required by DxeCore initialization. When LMFA feature enabled, // This part of memory still need reserved on the very top of memory so that the DXE Core could @@ -685,19 +635,16 @@ PeiDispatcher ( UINTN SaveCurrentFvCount; EFI_PEI_FILE_HANDLE SaveCurrentFileHandle; PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData; - EFI_PHYSICAL_ADDRESS NewPermenentMemoryBase; TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi; - EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffTable; - EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffTable; - INTN StackOffset; - INTN HeapOffset; - PEI_CORE_INSTANCE *PrivateInMem; - UINT64 NewPeiStackSize; - UINT64 OldPeiStackSize; - UINT64 StackGap; + UINT64 NewStackSize; + EFI_PHYSICAL_ADDRESS TopOfNewStack; + EFI_PHYSICAL_ADDRESS TopOfOldStack; + EFI_PHYSICAL_ADDRESS TemporaryRamBase; + UINTN TemporaryRamSize; + EFI_PHYSICAL_ADDRESS TemporaryStackSize; + UINTN StackOffset; + BOOLEAN StackOffsetPositive; EFI_FV_FILE_INFO FvFileInfo; - UINTN OldCheckingTop; - UINTN OldCheckingBottom; PEI_CORE_FV_HANDLE *CoreFvHandle; VOID *LoadFixPeiCodeBegin; @@ -889,13 +836,14 @@ PeiDispatcher ( && (*StackPointer == INIT_CAR_VALUE); StackPointer ++); + DEBUG ((EFI_D_INFO, "Temp Stack : BaseAddress=0x%p Length=0x%X\n", SecCoreData->StackBase, (UINT32)SecCoreData->StackSize)); + 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))); DEBUG ((EFI_D_INFO, "Total temporary memory: %d bytes.\n", (UINT32)SecCoreData->TemporaryRamSize)); DEBUG ((EFI_D_INFO, " temporary memory stack ever used: %d bytes.\n", - (SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN)SecCoreData->StackBase)) + (UINT32)(SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN)SecCoreData->StackBase)) )); DEBUG ((EFI_D_INFO, " temporary memory heap used: %d bytes.\n", - ((UINTN) Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - - (UINTN) Private->HobList.Raw) + (UINT32)((UINTN)Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN)Private->HobList.Raw) )); DEBUG_CODE_END (); @@ -903,9 +851,10 @@ PeiDispatcher ( // // Loading Module at Fixed Address is enabled // - PeiLoadFixAddressHook(Private); + PeiLoadFixAddressHook (Private); + // - // if Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range. + // If Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range. // LoadFixPeiCodeBegin = AllocatePages((UINTN)PcdGet32(PcdLoadFixAddressPeiCodePageNumber)); 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))); @@ -914,170 +863,104 @@ PeiDispatcher ( // // Reserve the size of new stack at bottom of physical memory // - OldPeiStackSize = (UINT64) SecCoreData->StackSize; - NewPeiStackSize = (RShiftU64 (Private->PhysicalMemoryLength, 1) + EFI_PAGE_MASK) & ~EFI_PAGE_MASK; - if (PcdGet32(PcdPeiCoreMaxPeiStackSize) > (UINT32) NewPeiStackSize) { - Private->StackSize = NewPeiStackSize; - } else { - Private->StackSize = PcdGet32(PcdPeiCoreMaxPeiStackSize); - } - - // - // In theory, the size of new stack in permenent memory should large than - // size of old stack in temporary memory. + // The size of new stack in permenent memory must be the same size + // or larger than the size of old stack in temporary memory. // But if new stack is smaller than the size of old stack, we also reserve // the size of old stack at bottom of permenent memory. // - DEBUG ((EFI_D_INFO, "Old Stack size %d, New stack size %d\n", (INT32) OldPeiStackSize, (INT32) Private->StackSize)); - ASSERT (Private->StackSize >= OldPeiStackSize); - StackGap = Private->StackSize - OldPeiStackSize; + NewStackSize = RShiftU64 (Private->PhysicalMemoryLength, 1); + NewStackSize = ALIGN_VALUE (NewStackSize, EFI_PAGE_SIZE); + NewStackSize = MIN (PcdGet32(PcdPeiCoreMaxPeiStackSize), NewStackSize); + DEBUG ((EFI_D_INFO, "Old Stack size %d, New stack size %d\n", (UINT32)SecCoreData->StackSize, (UINT32)NewStackSize)); + ASSERT (NewStackSize >= SecCoreData->StackSize); - // - // Update HandOffHob for new installed permenent memory - // - OldHandOffTable = Private->HobList.HandoffInformationTable; - OldCheckingBottom = (UINTN)(SecCoreData->TemporaryRamBase); - OldCheckingTop = (UINTN)(OldCheckingBottom + SecCoreData->TemporaryRamSize); - - // - // The whole temporary memory will be migrated to physical memory. - // CAUTION: The new base is computed accounding to gap of new stack. - // - NewPermenentMemoryBase = Private->PhysicalMemoryBegin + StackGap; - // // Caculate stack offset and heap offset between temporary memory and new permement // memory seperately. // - StackOffset = (UINTN) NewPermenentMemoryBase - (UINTN) SecCoreData->StackBase; - HeapOffset = (INTN) ((UINTN) Private->PhysicalMemoryBegin + Private->StackSize - \ - (UINTN) SecCoreData->PeiTemporaryRamBase); - DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (INT64)HeapOffset, (INT64)StackOffset)); - + TopOfOldStack = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize; + TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize; + if (TopOfNewStack >= (UINTN)SecCoreData->PeiTemporaryRamBase) { + Private->HeapOffsetPositive = TRUE; + Private->HeapOffset = (UINTN)(TopOfNewStack - (UINTN)SecCoreData->PeiTemporaryRamBase); + } else { + Private->HeapOffsetPositive = FALSE; + Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - TopOfNewStack); + } + if (TopOfNewStack >= TopOfOldStack) { + StackOffsetPositive = TRUE; + StackOffset = (UINTN)(TopOfNewStack - TopOfOldStack); + } else { + StackOffsetPositive = FALSE; + StackOffset = (UINTN)(TopOfOldStack - TopOfNewStack); + } + + DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64)Private->HeapOffset, (UINT64)(StackOffset))); + // - // Caculate new HandOffTable and PrivateData address in permenet memory's stack + // Build Stack HOB that describes the permanent memory stack // - NewHandOffTable = (EFI_HOB_HANDOFF_INFO_TABLE *)((UINTN)OldHandOffTable + HeapOffset); - PrivateInMem = (PEI_CORE_INSTANCE *)((UINTN) (VOID*) Private + StackOffset); + DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n", TopOfNewStack - NewStackSize, NewStackSize)); + BuildStackHob (TopOfNewStack - NewStackSize, NewStackSize); + + // + // Cache information from SecCoreData into locals before SecCoreData is converted to a permanent memory address + // + TemporaryRamBase = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase; + TemporaryRamSize = SecCoreData->TemporaryRamSize; + TemporaryStackSize = SecCoreData->StackSize; + + // + // Caculate new HandOffTable and PrivateData address in permanent memory's stack + // + if (StackOffsetPositive) { + SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset); + Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset); + } else { + SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset); + Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset); + } // // TemporaryRamSupportPpi is produced by platform's SEC // - Status = PeiLocatePpi ( - (CONST EFI_PEI_SERVICES **) PeiServices, + Status = PeiServicesLocatePpi ( &gEfiTemporaryRamSupportPpiGuid, 0, NULL, (VOID**)&TemporaryRamSupportPpi ); - - if (!EFI_ERROR (Status)) { // - // Temporary Ram support Ppi is provided by platform, it will copy + // Temporary Ram Support PPI is provided by platform, it will copy // temporary memory to permenent memory and do stack switching. - // After invoken temporary Ram support, following code's stack is in - // memory but not in temporary memory. + // After invoking Temporary Ram Support PPI, the following code's + // stack is in permanent memory. // TemporaryRamSupportPpi->TemporaryRamMigration ( - (CONST EFI_PEI_SERVICES **) PeiServices, - (EFI_PHYSICAL_ADDRESS)(UINTN) SecCoreData->TemporaryRamBase, - (EFI_PHYSICAL_ADDRESS)(UINTN) NewPermenentMemoryBase, - SecCoreData->TemporaryRamSize + PeiServices, + TemporaryRamBase, + (EFI_PHYSICAL_ADDRESS)(UINTN)(TopOfNewStack - TemporaryStackSize), + TemporaryRamSize ); } else { // // In IA32/x64/Itanium architecture, we need platform provide - // TEMPORAY_RAM_MIGRATION_PPI. + // TEMPORARY_RAM_MIGRATION_PPI. // ASSERT (FALSE); } - - // - // - // Fixup the PeiCore's private data - // - PrivateInMem->Ps = &PrivateInMem->ServiceTableShadow; - PrivateInMem->CpuIo = &PrivateInMem->ServiceTableShadow.CpuIo; - PrivateInMem->HobList.Raw = (VOID*) ((UINTN) PrivateInMem->HobList.Raw + HeapOffset); - PrivateInMem->StackBase = (EFI_PHYSICAL_ADDRESS)(((UINTN)PrivateInMem->PhysicalMemoryBegin + EFI_PAGE_MASK) & ~EFI_PAGE_MASK); - - PeiServices = (CONST EFI_PEI_SERVICES **) &PrivateInMem->Ps; - - // - // Fixup for PeiService's address - // - SetPeiServicesTablePointer(PeiServices); - - // - // Update HandOffHob for new installed permenent memory - // - NewHandOffTable->EfiEndOfHobList = - (EFI_PHYSICAL_ADDRESS)((UINTN) NewHandOffTable->EfiEndOfHobList + HeapOffset); - NewHandOffTable->EfiMemoryTop = PrivateInMem->PhysicalMemoryBegin + - PrivateInMem->PhysicalMemoryLength; - NewHandOffTable->EfiMemoryBottom = PrivateInMem->PhysicalMemoryBegin; - NewHandOffTable->EfiFreeMemoryTop = PrivateInMem->FreePhysicalMemoryTop; - NewHandOffTable->EfiFreeMemoryBottom = NewHandOffTable->EfiEndOfHobList + - sizeof (EFI_HOB_GENERIC_HEADER); - - // - // We need convert the PPI desciptor's pointer - // - ConvertPpiPointers (PrivateInMem, - OldCheckingBottom, - OldCheckingTop, - HeapOffset - ); - - DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n", - PrivateInMem->StackBase, - PrivateInMem->StackSize)); - BuildStackHob (PrivateInMem->StackBase, PrivateInMem->StackSize); - - // - // After the whole temporary memory is migrated, then we can allocate page in - // permenent memory. - // - PrivateInMem->PeiMemoryInstalled = TRUE; - - // - // Indicate that PeiCore reenter - // - PrivateInMem->PeimDispatcherReenter = TRUE; - - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (PrivateInMem->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { - // - // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array. - // Every bit in the array indicate the status of the corresponding memory page available or not - // - PrivateInMem->PeiCodeMemoryRangeUsageBitMap = AllocateZeroPool (((PcdGet32(PcdLoadFixAddressPeiCodePageNumber)>>6) + 1)*sizeof(UINT64)); - } - // - // Shadow PEI Core. When permanent memory is avaiable, shadow - // PEI Core and PEIMs to get high performance. - // - PrivateInMem->ShadowedPeiCore = ShadowPeiCore ( - PeiServices, - PrivateInMem - ); - // - // Process the Notify list and dispatch any notifies for - // newly installed PPIs. - // - ProcessNotifyList (PrivateInMem); - // // Entry PEI Phase 2 // - PeiCore (SecCoreData, NULL, PrivateInMem); + PeiCore (SecCoreData, NULL, Private); // // Code should not come here // - ASSERT_EFI_ERROR(FALSE); + ASSERT (FALSE); } // diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index 1bb1103b73..fbfe4f59da 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -128,13 +128,39 @@ typedef struct { UINTN SectionIndex; } CACHE_SECTION_DATA; +/// +/// Forward declaration for PEI_CORE_INSTANCE +/// +typedef struct _PEI_CORE_INSTANCE PEI_CORE_INSTANCE; + + +/** + Function Pointer type for PeiCore function. + @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size + and location of temporary RAM, the stack location and the BFV location. + @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core. + An empty PPI list consists of a single descriptor with the end-tag + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization + phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such + that both the PEI Foundation and any modules can leverage the associated service + calls and/or code in these early PPIs + @param OldCoreData Pointer to old core data that is used to initialize the + core's data areas. +**/ +typedef +EFI_STATUS +(EFIAPI *PEICORE_FUNCTION_POINTER)( + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, + IN PEI_CORE_INSTANCE *OldCoreData + ); #define PEI_CORE_HANDLE_SIGNATURE SIGNATURE_32('P','e','i','C') /// /// Pei Core private data structure instance /// -typedef struct{ +struct _PEI_CORE_INSTANCE { UINTN Signature; /// @@ -166,8 +192,6 @@ typedef struct{ EFI_PEI_HOB_POINTERS HobList; BOOLEAN SwitchStackSignal; BOOLEAN PeiMemoryInstalled; - EFI_PHYSICAL_ADDRESS StackBase; - UINT64 StackSize; VOID *CpuIo; EFI_PEI_SECURITY2_PPI *PrivateSecurityPpi; EFI_PEI_SERVICES ServiceTableShadow; @@ -175,7 +199,9 @@ typedef struct{ EFI_PHYSICAL_ADDRESS PhysicalMemoryBegin; UINT64 PhysicalMemoryLength; EFI_PHYSICAL_ADDRESS FreePhysicalMemoryTop; - VOID* ShadowedPeiCore; + UINTN HeapOffset; + BOOLEAN HeapOffsetPositive; + PEICORE_FUNCTION_POINTER ShadowedPeiCore; CACHE_SECTION_DATA CacheSection; // // For Loading modules at fixed address feature to cache the top address below which the @@ -193,7 +219,7 @@ typedef struct{ // This field points to the shadowed image read function // PE_COFF_LOADER_READ_FILE ShadowedImageRead; -} PEI_CORE_INSTANCE; +}; /// /// Pei Core Instance Data Macros @@ -201,27 +227,6 @@ typedef struct{ #define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \ CR(a, PEI_CORE_INSTANCE, Ps, PEI_CORE_HANDLE_SIGNATURE) -/** - Function Pointer type for PeiCore function. - @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size - and location of temporary RAM, the stack location and the BFV location. - @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core. - An empty PPI list consists of a single descriptor with the end-tag - EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization - phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such - that both the PEI Foundation and any modules can leverage the associated service - calls and/or code in these early PPIs - @param OldCoreData Pointer to old core data that is used to initialize the - core's data areas. -**/ -typedef -EFI_STATUS -(EFIAPI *PEICORE_FUNCTION_POINTER)( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, - IN PEI_CORE_INSTANCE *OldCoreData - ); - /// /// Union of temporarily used function pointers (to save stack space) /// @@ -380,6 +385,8 @@ InitializePpiServices ( will be fixup for PpiData and PpiDescriptor. @param Fixup The address difference between the new Hob list and old Hob list. + @param FixupPositive TRUE if new Hob list is above the old Hob list. + Otherwise FALSE. **/ VOID @@ -387,7 +394,8 @@ ConvertPpiPointers ( IN PEI_CORE_INSTANCE *PrivateData, IN UINTN OldCheckingBottom, IN UINTN OldCheckingTop, - IN INTN Fixup + IN UINTN Fixup, + IN BOOLEAN FixupPositive ); /** diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c index ba665ee57b..bf99e4bd4c 100644 --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c @@ -64,6 +64,55 @@ EFI_PEI_SERVICES gPs = { PeiRegisterForShadow }; +/** + Shadow PeiCore module from flash to installed memory. + + @param PrivateData PeiCore's private data structure + + @return PeiCore function address after shadowing. +**/ +PEICORE_FUNCTION_POINTER +ShadowPeiCore ( + IN PEI_CORE_INSTANCE *PrivateData + ) +{ + EFI_PEI_FILE_HANDLE PeiCoreFileHandle; + EFI_PHYSICAL_ADDRESS EntryPoint; + EFI_STATUS Status; + UINT32 AuthenticationState; + + PeiCoreFileHandle = NULL; + + // + // Find the PEI Core in the BFV + // + Status = PrivateData->Fv[0].FvPpi->FindFileByType ( + PrivateData->Fv[0].FvPpi, + EFI_FV_FILETYPE_PEI_CORE, + PrivateData->Fv[0].FvHandle, + &PeiCoreFileHandle + ); + ASSERT_EFI_ERROR (Status); + + // + // Shadow PEI Core into memory so it will run faster + // + Status = PeiLoadImage ( + GetPeiServicesTablePointer (), + *((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle), + PEIM_STATE_REGISITER_FOR_SHADOW, + &EntryPoint, + &AuthenticationState + ); + ASSERT_EFI_ERROR (Status); + + // + // Compute the PeiCore's function address after shaowed PeiCore. + // _ModuleEntryPoint is PeiCore main function entry + // + return (PEICORE_FUNCTION_POINTER)((UINTN) EntryPoint + (UINTN) PeiCore - (UINTN) _ModuleEntryPoint); +} + /** This routine is invoked by main entry of PeiMain module during transition from SEC to PEI. After switching stack in the PEI core, it will restart @@ -91,17 +140,17 @@ PeiCore ( IN VOID *Data ) { - PEI_CORE_INSTANCE PrivateData; - EFI_STATUS Status; - PEI_CORE_TEMP_POINTERS TempPtr; - UINT64 Tick; - PEI_CORE_INSTANCE *OldCoreData; - EFI_PEI_CPU_IO_PPI *CpuIo; - EFI_PEI_PCI_CFG2_PPI *PciCfg; - PEICORE_FUNCTION_POINTER ShadowedPeiCore; + PEI_CORE_INSTANCE PrivateData; + EFI_STATUS Status; + PEI_CORE_TEMP_POINTERS TempPtr; + UINT64 Tick; + PEI_CORE_INSTANCE *OldCoreData; + EFI_PEI_CPU_IO_PPI *CpuIo; + EFI_PEI_PCI_CFG2_PPI *PciCfg; + EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable; Tick = 0; - OldCoreData = (PEI_CORE_INSTANCE *) Data; + OldCoreData = (PEI_CORE_INSTANCE *)Data; // // Record the system tick for first entering PeiCore. @@ -114,22 +163,82 @@ PeiCore ( } if (OldCoreData != NULL) { - ShadowedPeiCore = (PEICORE_FUNCTION_POINTER) (UINTN) OldCoreData->ShadowedPeiCore; - - // - // PeiCore has been shadowed to memory for first entering, so - // just jump to PeiCore in memory here. - // - if (ShadowedPeiCore != NULL) { - OldCoreData->ShadowedPeiCore = NULL; - ShadowedPeiCore ( - SecCoreData, - PpiList, - OldCoreData - ); + if (OldCoreData->ShadowedPeiCore == NULL) { + // + // + // Fixup the PeiCore's private data + // + OldCoreData->Ps = &OldCoreData->ServiceTableShadow; + OldCoreData->CpuIo = &OldCoreData->ServiceTableShadow.CpuIo; + if (OldCoreData->HeapOffsetPositive) { + OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw + OldCoreData->HeapOffset); + } else { + OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw - OldCoreData->HeapOffset); + } + + // + // Fixup for PeiService's address + // + SetPeiServicesTablePointer ((CONST EFI_PEI_SERVICES **)&OldCoreData->Ps); + + // + // Update HandOffHob for new installed permenent memory + // + HandoffInformationTable = OldCoreData->HobList.HandoffInformationTable; + if (OldCoreData->HeapOffsetPositive) { + HandoffInformationTable->EfiEndOfHobList = HandoffInformationTable->EfiEndOfHobList + OldCoreData->HeapOffset; + } else { + HandoffInformationTable->EfiEndOfHobList = HandoffInformationTable->EfiEndOfHobList - OldCoreData->HeapOffset; + } + HandoffInformationTable->EfiMemoryTop = OldCoreData->PhysicalMemoryBegin + OldCoreData->PhysicalMemoryLength; + HandoffInformationTable->EfiMemoryBottom = OldCoreData->PhysicalMemoryBegin; + HandoffInformationTable->EfiFreeMemoryTop = OldCoreData->FreePhysicalMemoryTop; + HandoffInformationTable->EfiFreeMemoryBottom = HandoffInformationTable->EfiEndOfHobList + sizeof (EFI_HOB_GENERIC_HEADER); + + // + // We need convert the PPI desciptor's pointer + // + ConvertPpiPointers (OldCoreData, (UINTN)SecCoreData->TemporaryRamBase, (UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize, OldCoreData->HeapOffset, OldCoreData->HeapOffsetPositive); + + // + // After the whole temporary memory is migrated, then we can allocate page in + // permenent memory. + // + OldCoreData->PeiMemoryInstalled = TRUE; + + // + // Indicate that PeiCore reenter + // + OldCoreData->PeimDispatcherReenter = TRUE; + + if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (OldCoreData->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { + // + // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array. + // Every bit in the array indicate the status of the corresponding memory page available or not + // + OldCoreData->PeiCodeMemoryRangeUsageBitMap = AllocateZeroPool (((PcdGet32(PcdLoadFixAddressPeiCodePageNumber)>>6) + 1)*sizeof(UINT64)); + } + + // + // Process the Notify list and dispatch any notifies for + // newly installed PPIs. + // + ProcessNotifyList (OldCoreData); + + // + // Shadow PEI Core. When permanent memory is avaiable, shadow + // PEI Core and PEIMs to get high performance. + // + OldCoreData->ShadowedPeiCore = ShadowPeiCore (OldCoreData); + + // + // PeiCore has been shadowed to memory for first entering, so + // just jump to PeiCore in memory here. + // + OldCoreData->ShadowedPeiCore (SecCoreData, PpiList, OldCoreData); } - CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE)); + CopyMem (&PrivateData, OldCoreData, sizeof (PrivateData)); CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo; PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg; diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c index 8089796d7b..65dc5be9fc 100644 --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c @@ -47,6 +47,8 @@ InitializePpiServices ( will be fixup for PpiData and PpiDescriptor. @param Fixup The address difference between the new Hob list and old Hob list. + @param FixupPositive TRUE if new Hob list is above the old Hob list. + Otherwise FALSE. **/ VOID @@ -54,7 +56,8 @@ ConvertPpiPointers ( IN PEI_CORE_INSTANCE *PrivateData, IN UINTN OldCheckingBottom, IN UINTN OldCheckingTop, - IN INTN Fixup + IN UINTN Fixup, + IN BOOLEAN FixupPositive ) { UINT8 Index; @@ -71,7 +74,11 @@ ConvertPpiPointers ( // Convert the pointer to the PEIM descriptor from the old HOB heap // to the relocated HOB heap. // - PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup); + if (FixupPositive) { + PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup); + } else { + PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - Fixup); + } // // Only when the PEIM descriptor is in the old HOB should it be necessary @@ -84,7 +91,11 @@ ConvertPpiPointers ( // Convert the pointer to the GUID in the PPI or NOTIFY descriptor // from the old HOB heap to the relocated HOB heap. // - PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup); + if (FixupPositive) { + PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup); + } else { + PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - Fixup); + } } // @@ -98,7 +109,11 @@ ConvertPpiPointers ( // Convert the pointer to the PPI interface structure in the PPI descriptor // from the old HOB heap to the relocated HOB heap. // - PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup); + if (FixupPositive) { + PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + Fixup); + } else { + PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - Fixup); + } } } }