From a09647f3fe74ebbff2c49f47b983478f75bdf045 Mon Sep 17 00:00:00 2001 From: Jeff Fan Date: Fri, 18 Dec 2015 03:26:03 +0000 Subject: [PATCH] UefiCpuPkg/CpuMpPei: Wake up APs by proper method If ApLoopMode is ApInHltLoop, BSP will send INIT-SIPI-SIPI to wake up APs. If ApLoopMode is ApInMwaitLoop or ApInRunLoop, BSP will write one semaphore to wake up APs. Contributed-under: TianoCore Contribution Agreement 1.0 Cc: Feng Tian Cc: Michael Kinney Cc: Jordan Justen Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan Tested-by: Michael Kinney Reviewed-by: Michael Kinney git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19346 6f19259b-4bc3-4df7-8a09-765794883524 --- UefiCpuPkg/CpuMpPei/CpuMpPei.c | 43 ++++++++++++++++++++++++----- UefiCpuPkg/CpuMpPei/CpuMpPei.h | 4 +-- UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 + UefiCpuPkg/CpuMpPei/PeiMpServices.c | 6 ++-- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c index ba82ba4218..950d61cc48 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c @@ -399,7 +399,7 @@ ApCFunction ( @param PeiCpuMpData Pointer to PEI CPU MP Data @param Broadcast TRUE: Send broadcast IPI to all APs FALSE: Send IPI to AP by ApicId - @param ApicId Apic ID for the processor to be waked + @param ProcessorNumber The handle number of specified processor @param Procedure The function to be invoked by AP @param ProcedureArgument The argument to be passed into AP function **/ @@ -407,12 +407,13 @@ VOID WakeUpAP ( IN PEI_CPU_MP_DATA *PeiCpuMpData, IN BOOLEAN Broadcast, - IN UINT32 ApicId, + IN UINTN ProcessorNumber, IN EFI_AP_PROCEDURE Procedure, OPTIONAL IN VOID *ProcedureArgument OPTIONAL ) { volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo; + UINTN Index; PeiCpuMpData->ApFunction = (UINTN) Procedure; PeiCpuMpData->ApFunctionArgument = (UINTN) ProcedureArgument; @@ -436,12 +437,40 @@ WakeUpAP ( CopyMem ((VOID *)&ExchangeInfo->GdtrProfile, &mGdt, sizeof(mGdt)); AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile); - if (Broadcast) { - SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart); - } else { - SendInitSipiSipi (ApicId, (UINT32) ExchangeInfo->BufferStart); + if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) { + // + // Get AP target C-state each time when waking up AP, + // for it maybe updated by platform again + // + PeiCpuMpData->ApTargetCState = PcdGet8 (PcdCpuApTargetCstate); } + // + // Wakeup APs per AP loop state + // + if (PeiCpuMpData->ApLoopMode == ApInHltLoop || PeiCpuMpData->InitFlag) { + if (Broadcast) { + SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart); + } else { + SendInitSipiSipi ( + PeiCpuMpData->CpuData[ProcessorNumber].ApicId, + (UINT32) ExchangeInfo->BufferStart + ); + } + } else if ((PeiCpuMpData->ApLoopMode == ApInMwaitLoop) || + (PeiCpuMpData->ApLoopMode == ApInRunLoop)) { + if (Broadcast) { + for (Index = 0; Index < PeiCpuMpData->CpuCount; Index++) { + if (Index != PeiCpuMpData->BspNumber) { + *(PeiCpuMpData->CpuData[Index].StartupApSignal) = WAKEUP_AP_SIGNAL; + } + } + } else { + *(PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal) = WAKEUP_AP_SIGNAL; + } + } else { + ASSERT (FALSE); + } return ; } @@ -600,7 +629,7 @@ CountProcessorNumber ( if (PeiCpuMpData->X2ApicEnable) { DEBUG ((EFI_D_INFO, "Force x2APIC mode!\n")); // - // Send 2nd broadcast IPI to all APs to enable x2APIC mode + // Wakeup all APs to enable x2APIC mode // WakeUpAP (PeiCpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL); // diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h index 47038c2825..6f508b420b 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h @@ -255,7 +255,7 @@ CpuMpEndOfPeiCallback ( @param PeiCpuMpData Pointer to PEI CPU MP Data @param Broadcast TRUE: Send broadcast IPI to all APs FALSE: Send IPI to AP by ApicId - @param ApicId Apic ID for the processor to be waked + @param ProcessorNumber The handle number of specified processor @param Procedure The function to be invoked by AP @param ProcedureArgument The argument to be passed into AP function **/ @@ -263,7 +263,7 @@ VOID WakeUpAP ( IN PEI_CPU_MP_DATA *PeiCpuMpData, IN BOOLEAN Broadcast, - IN UINT32 ApicId, + IN UINTN ProcessorNumber, IN EFI_AP_PROCEDURE Procedure, OPTIONAL IN VOID *ProcedureArgument OPTIONAL ); diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf index ec353aed7d..70b272e33b 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf @@ -83,6 +83,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES [Depex] gEfiPeiMemoryDiscoveredPpiGuid diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.c b/UefiCpuPkg/CpuMpPei/PeiMpServices.c index 5dd2c153f4..e784377d67 100644 --- a/UefiCpuPkg/CpuMpPei/PeiMpServices.c +++ b/UefiCpuPkg/CpuMpPei/PeiMpServices.c @@ -520,7 +520,7 @@ PeiStartupAllAPs ( if (Index == CallerNumber) { continue; } - WakeUpAP (PeiCpuMpData, FALSE, PeiCpuMpData->CpuData[Index].ApicId, Procedure, ProcedureArgument); + WakeUpAP (PeiCpuMpData, FALSE, Index, Procedure, ProcedureArgument); // // Wait to finish // @@ -655,7 +655,7 @@ PeiStartupThisAP ( WaitCountIndex = 0; FinishedCount = &PeiCpuMpData->FinishedCount; - WakeUpAP (PeiCpuMpData, FALSE, PeiCpuMpData->CpuData[ProcessorNumber].ApicId, Procedure, ProcedureArgument); + WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument); // // Wait to finish @@ -791,7 +791,7 @@ PeiSwitchBSP ( // // Need to wakeUp AP (future BSP). // - WakeUpAP (PeiCpuMpData, FALSE, PeiCpuMpData->CpuData[ProcessorNumber].ApicId, FutureBSPProc, PeiCpuMpData); + WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, FutureBSPProc, PeiCpuMpData); AsmExchangeRole (&PeiCpuMpData->BSPInfo, &PeiCpuMpData->APInfo); -- 2.39.2