Add CpuMpEndOfPeiCallback () to restore wakeup buffer data on S3 path and flag flag wakeup buffer to be un-used type on normal boot path. Set one EndOfPei flag save/restore wakeup buffer when wakeup APs every time.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff....@intel.com> CC: Feng Tian <feng.t...@intel.com> CC: Jiewen Yao <jiewen....@intel.com> CC: Michael Kinney <michael.d.kin...@intel.com> --- UefiCpuPkg/CpuMpPei/CpuMpPei.c | 90 +++++++++++++++++++++++++++++++++++++ UefiCpuPkg/CpuMpPei/CpuMpPei.h | 43 ++++++++++++++++++ UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 + UefiCpuPkg/CpuMpPei/PeiMpServices.c | 42 +++++++++++++++++ 4 files changed, 176 insertions(+) diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c index 40e62e0..c047804 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c @@ -38,6 +38,12 @@ GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = { (UINTN) mGdtEntries }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + CpuMpEndOfPeiCallback +}; + /** Sort the APIC ID of all processors. @@ -317,6 +323,20 @@ BackupAndPrepareWakeupBuffer( PeiCpuMpData->AddressMap.RendezvousFunnelSize ); } + +/** + Restore wakeup buffer data. + + @param PeiCpuMpData Pointer to PEI CPU MP Data +**/ +VOID +RestoreWakeupBuffer( + IN PEI_CPU_MP_DATA *PeiCpuMpData + ) +{ + CopyMem ((VOID *) PeiCpuMpData->WakeupBuffer, (VOID *) PeiCpuMpData->BackupBuffer, PeiCpuMpData->BackupBufferSize); +} + /** This function will get CPU count in the system. @@ -409,6 +429,7 @@ PrepareAPStartupVector ( PeiCpuMpData->CpuData = (PEI_CPU_DATA *) (PeiCpuMpData->MpCpuExchangeInfo + 1); PeiCpuMpData->CpuData[0].ApicId = GetInitialApicId (); PeiCpuMpData->CpuData[0].Health.Uint32 = 0; + PeiCpuMpData->EndOfPeiFlag = FALSE; CopyMem (&PeiCpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP)); // @@ -418,6 +439,70 @@ PrepareAPStartupVector ( return PeiCpuMpData; } + +/** + Notify function on End Of Pei PPI. + + On S3 boot, this function will restore wakeup buffer data. + On normal boot, this function will flag wakeup buffer to be un-used type. + + @param PeiServices The pointer to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS When everything is OK. + +**/ +EFI_STATUS +EFIAPI +CpuMpEndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + PEI_CPU_MP_DATA *PeiCpuMpData; + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_MEMORY_ALLOCATION *MemoryHob; + + DEBUG ((EFI_D_INFO, "CpuMpPei: CpuMpEndOfPeiCallback () invokded\n")); + + Status = PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + PeiCpuMpData = GetMpHobData (); + ASSERT (PeiCpuMpData != NULL); + + if (BootMode != BOOT_ON_S3_RESUME) { + // + // Get the HOB list for processing + // + Hob.Raw = GetHobList (); + // + // Collect memory ranges + // + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) { + MemoryHob = Hob.MemoryAllocation; + if(MemoryHob->AllocDescriptor.MemoryBaseAddress == PeiCpuMpData->WakeupBuffer) { + // + // Flag this HOB type to un-used + // + GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED; + break; + } + } + Hob.Raw = GET_NEXT_HOB (Hob); + } + } else { + RestoreWakeupBuffer (PeiCpuMpData); + PeiCpuMpData->EndOfPeiFlag = TRUE; + } + return EFI_SUCCESS; +} + /** The Entry point of the MP CPU PEIM. @@ -466,6 +551,11 @@ CpuMpPeimInit ( // CollectBistDataFromPpi (PeiServices, PeiCpuMpData); // + // register an event for EndOfPei + // + Status = PeiServicesNotifyPpi (&mNotifyList); + ASSERT_EFI_ERROR (Status); + // // Install CPU MP PPI // Status = PeiServicesInstallPpi(&mPeiCpuMpPpiDesc); diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h index c241349..8d01ac6 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h @@ -20,6 +20,7 @@ #include <Ppi/MpServices.h> #include <Ppi/SecPlatformInformation.h> #include <Ppi/SecPlatformInformation2.h> +#include <Ppi/EndOfPeiPhase.h> #include <Register/LocalApic.h> @@ -133,6 +134,7 @@ struct _PEI_CPU_MP_DATA { UINTN ApFunction; UINTN ApFunctionArgument; volatile UINT32 FinishedCount; + BOOLEAN EndOfPeiFlag; BOOLEAN InitFlag; CPU_EXCHANGE_ROLE_INFO BSPInfo; CPU_EXCHANGE_ROLE_INFO APInfo; @@ -177,6 +179,47 @@ AsmCliHltLoop ( ); /** + Get available system memory below 1MB by specified size. + + @param PeiCpuMpData Pointer to PEI CPU MP Data +**/ +VOID +BackupAndPrepareWakeupBuffer( + IN PEI_CPU_MP_DATA *PeiCpuMpData + ); + +/** + Restore wakeup buffer data. + + @param PeiCpuMpData Pointer to PEI CPU MP Data +**/ +VOID +RestoreWakeupBuffer( + IN PEI_CPU_MP_DATA *PeiCpuMpData + ); + +/** + Notify function on End Of Pei PPI. + + On S3 boot, this function will restore wakeup buffer data. + On normal boot, this function will flag wakeup buffer to be un-used type. + + @param PeiServices The pointer to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS When everything is OK. + +**/ +EFI_STATUS +EFIAPI +CpuMpEndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +/** This function will be called by BSP to wakeup AP. @param PeiCpuMpData Pointer to PEI CPU MP Data diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf index 7160c0e..92c64f9 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf @@ -69,6 +69,7 @@ [Ppis] gEfiPeiMpServicesPpiGuid ## PRODUCES + gEfiEndOfPeiSignalPpiGuid ## NOTIFY gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES ## SOMETIMES_CONSUMES ## SOMETIMES_PRODUCES diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.c b/UefiCpuPkg/CpuMpPei/PeiMpServices.c index bd77f58..6f8d662 100644 --- a/UefiCpuPkg/CpuMpPei/PeiMpServices.c +++ b/UefiCpuPkg/CpuMpPei/PeiMpServices.c @@ -489,6 +489,13 @@ PeiStartupAllAPs ( return EFI_NOT_READY; } + if (PeiCpuMpData->EndOfPeiFlag) { + // + // Backup original data and copy AP reset vector in it + // + BackupAndPrepareWakeupBuffer(PeiCpuMpData); + } + WaitCountNumber = TimeoutInMicroSeconds / CPU_CHECK_AP_INTERVAL + 1; WaitCountIndex = 0; FinishedCount = &PeiCpuMpData->FinishedCount; @@ -540,6 +547,13 @@ PeiStartupAllAPs ( } } + if (PeiCpuMpData->EndOfPeiFlag) { + // + // Restore original data + // + RestoreWakeupBuffer(PeiCpuMpData); + } + return Status; } @@ -640,6 +654,13 @@ PeiStartupThisAP ( return EFI_INVALID_PARAMETER; } + if (PeiCpuMpData->EndOfPeiFlag) { + // + // Backup original data and copy AP reset vector in it + // + BackupAndPrepareWakeupBuffer(PeiCpuMpData); + } + WaitCountNumber = TimeoutInMicroseconds / CPU_CHECK_AP_INTERVAL + 1; WaitCountIndex = 0; FinishedCount = &PeiCpuMpData->FinishedCount; @@ -665,6 +686,13 @@ PeiStartupThisAP ( } } + if (PeiCpuMpData->EndOfPeiFlag) { + // + // Backup original data and copy AP reset vector in it + // + RestoreWakeupBuffer(PeiCpuMpData); + } + return Status; } @@ -764,6 +792,13 @@ PeiSwitchBSP ( PeiCpuMpData->BSPInfo.State = CPU_SWITCH_STATE_IDLE; PeiCpuMpData->APInfo.State = CPU_SWITCH_STATE_IDLE; + if (PeiCpuMpData->EndOfPeiFlag) { + // + // Backup original data and copy AP reset vector in it + // + BackupAndPrepareWakeupBuffer(PeiCpuMpData); + } + // // Need to wakeUp AP (future BSP). // @@ -771,6 +806,13 @@ PeiSwitchBSP ( AsmExchangeRole (&PeiCpuMpData->BSPInfo, &PeiCpuMpData->APInfo); + if (PeiCpuMpData->EndOfPeiFlag) { + // + // Backup original data and copy AP reset vector in it + // + RestoreWakeupBuffer(PeiCpuMpData); + } + // // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP // -- 1.9.5.msysgit.0 ------------------------------------------------------------------------------ Don't Limit Your Business. Reach for the Cloud. GigeNET's Cloud Solutions provide you with the tools and support that you need to offload your IT needs and focus on growing your business. Configured For All Businesses. Start Your Cloud Today. https://www.gigenetcloud.com/ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel