mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/CpuMpPei: Fix potential AP mwait wakeup issue
If ApLoopMode is set to ApInMwaitLoop, AP will be placed into C-State by mwait instruction. BSP will wakeup AP by write start-up signal in monitor address. However, AP maybe waken by SMI/NMI/MCE and other condition. On this case, AP will check if BSP wants to wakeup itself really. If not, AP will continue to execute mwait to C-State. One potential issue: BSP may not recognize AP was wakeup from C-State by other event and BSP still writes start-up signal to wakeup AP. But AP does not aware it and still execute mwait instruction to C-State. So, AP cannot be wakeup on this case. This fix is let AP to clear start-up signal when it really is wakeup to execute AP function. And BSP will write start-up signal till AP clears it. Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Feng Tian <feng.tian@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com>
This commit is contained in:
parent
587d204ccd
commit
4da1ebf3b3
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
CPU PEI Module installs CPU Multiple Processor PPI.
|
CPU PEI Module installs CPU Multiple Processor PPI.
|
||||||
|
|
||||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -355,10 +355,6 @@ ApCFunction (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ApStartupSignalBuffer = PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal;
|
ApStartupSignalBuffer = PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal;
|
||||||
//
|
|
||||||
// Clear AP start-up signal
|
|
||||||
//
|
|
||||||
*ApStartupSignalBuffer = 0;
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
DisableInterrupts ();
|
DisableInterrupts ();
|
||||||
if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) {
|
if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) {
|
||||||
|
@ -387,12 +383,44 @@ ApCFunction (
|
||||||
// otherwise place AP in loop again
|
// otherwise place AP in loop again
|
||||||
//
|
//
|
||||||
if (*ApStartupSignalBuffer == WAKEUP_AP_SIGNAL) {
|
if (*ApStartupSignalBuffer == WAKEUP_AP_SIGNAL) {
|
||||||
|
//
|
||||||
|
// Clear AP start-up signal when AP waken up
|
||||||
|
//
|
||||||
|
InterlockedCompareExchange32 (
|
||||||
|
(UINT32 *)ApStartupSignalBuffer,
|
||||||
|
WAKEUP_AP_SIGNAL,
|
||||||
|
0
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write AP start-up signal to wakeup AP.
|
||||||
|
|
||||||
|
@param ApStartupSignalBuffer Pointer to AP wakeup signal
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
WriteStartupSignal (
|
||||||
|
IN volatile UINT32 *ApStartupSignalBuffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*ApStartupSignalBuffer = WAKEUP_AP_SIGNAL;
|
||||||
|
//
|
||||||
|
// If AP is waken up, StartupApSignal should be cleared.
|
||||||
|
// Otherwise, write StartupApSignal again till AP waken up.
|
||||||
|
//
|
||||||
|
while (InterlockedCompareExchange32 (
|
||||||
|
(UINT32 *)ApStartupSignalBuffer,
|
||||||
|
WAKEUP_AP_SIGNAL,
|
||||||
|
WAKEUP_AP_SIGNAL
|
||||||
|
) != 0) {
|
||||||
|
CpuPause ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function will be called by BSP to wakeup AP.
|
This function will be called by BSP to wakeup AP.
|
||||||
|
|
||||||
|
@ -462,11 +490,11 @@ WakeUpAP (
|
||||||
if (Broadcast) {
|
if (Broadcast) {
|
||||||
for (Index = 0; Index < PeiCpuMpData->CpuCount; Index++) {
|
for (Index = 0; Index < PeiCpuMpData->CpuCount; Index++) {
|
||||||
if (Index != PeiCpuMpData->BspNumber) {
|
if (Index != PeiCpuMpData->BspNumber) {
|
||||||
*(PeiCpuMpData->CpuData[Index].StartupApSignal) = WAKEUP_AP_SIGNAL;
|
WriteStartupSignal (PeiCpuMpData->CpuData[Index].StartupApSignal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*(PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal) = WAKEUP_AP_SIGNAL;
|
WriteStartupSignal (PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ASSERT (FALSE);
|
ASSERT (FALSE);
|
||||||
|
|
Loading…
Reference in New Issue