summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/CpuMpPei/CpuMpPei.c
diff options
context:
space:
mode:
authorJeff Fan <jeff.fan@intel.com>2015-12-18 03:26:03 +0000
committervanjeff <vanjeff@Edk2>2015-12-18 03:26:03 +0000
commita09647f3fe74ebbff2c49f47b983478f75bdf045 (patch)
tree707925b716399e16596476589b5d41f878837abc /UefiCpuPkg/CpuMpPei/CpuMpPei.c
parentc87e41b4452f0b5f8f14505b2ca5238f2598ea23 (diff)
downloadedk2-a09647f3fe74ebbff2c49f47b983478f75bdf045.tar.gz
edk2-a09647f3fe74ebbff2c49f47b983478f75bdf045.tar.bz2
edk2-a09647f3fe74ebbff2c49f47b983478f75bdf045.zip
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 <feng.tian@intel.com> Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> Tested-by: Michael Kinney <michael.d.kinney@intel.com> Reviewed-by: Michael Kinney <michael.d.kinney@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19346 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'UefiCpuPkg/CpuMpPei/CpuMpPei.c')
-rw-r--r--UefiCpuPkg/CpuMpPei/CpuMpPei.c43
1 files changed, 36 insertions, 7 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);
//