mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-29 08:34:07 +02:00
UefiCpuPkg/CpuMpPei: Place APs in proper loop mode after AP execution
After AP function is executed, we will place AP in proper loop mode. Because AP maybe waken up by SMI or other reasons. We need to read signature in monitor buffer to check if APs is waken up by BSP. If it is not waken up by BSP, we will continue to place them into proper loop mode. 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@19345 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
e001e11f90
commit
c87e41b445
@ -273,8 +273,10 @@ ApCFunction (
|
||||
UINTN ProcessorNumber;
|
||||
EFI_AP_PROCEDURE Procedure;
|
||||
UINTN BistData;
|
||||
volatile UINT32 *ApStartupSignalBuffer;
|
||||
|
||||
PeiCpuMpData = ExchangeInfo->PeiCpuMpData;
|
||||
while (TRUE) {
|
||||
if (PeiCpuMpData->InitFlag) {
|
||||
ProcessorNumber = NumApsExecuting;
|
||||
//
|
||||
@ -307,10 +309,12 @@ ApCFunction (
|
||||
// Execute AP function if AP is not disabled
|
||||
//
|
||||
GetProcessorNumber (PeiCpuMpData, &ProcessorNumber);
|
||||
if (PeiCpuMpData->ApLoopMode == ApInHltLoop) {
|
||||
//
|
||||
// Restore AP's volatile registers saved
|
||||
//
|
||||
RestoreVolatileRegisters (&PeiCpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);
|
||||
}
|
||||
|
||||
if ((PeiCpuMpData->CpuData[ProcessorNumber].State != CpuStateDisabled) &&
|
||||
(PeiCpuMpData->ApFunction != 0)) {
|
||||
@ -320,6 +324,10 @@ ApCFunction (
|
||||
// Invoke AP function here
|
||||
//
|
||||
Procedure ((VOID *)(UINTN)PeiCpuMpData->ApFunctionArgument);
|
||||
//
|
||||
// Re-get the processor number due to BSP/AP maybe exchange in AP function
|
||||
//
|
||||
GetProcessorNumber (PeiCpuMpData, &ProcessorNumber);
|
||||
PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;
|
||||
}
|
||||
}
|
||||
@ -329,12 +337,60 @@ ApCFunction (
|
||||
//
|
||||
InterlockedIncrement ((UINT32 *)&PeiCpuMpData->FinishedCount);
|
||||
|
||||
//
|
||||
// Place AP is specified loop mode
|
||||
//
|
||||
if (PeiCpuMpData->ApLoopMode == ApInHltLoop) {
|
||||
//
|
||||
// Save AP volatile registers
|
||||
//
|
||||
SaveVolatileRegisters (&PeiCpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
|
||||
//
|
||||
// Place AP in Hlt-loop
|
||||
//
|
||||
while (TRUE) {
|
||||
DisableInterrupts ();
|
||||
CpuSleep ();
|
||||
CpuPause ();
|
||||
}
|
||||
}
|
||||
ApStartupSignalBuffer = PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal;
|
||||
//
|
||||
// Clear AP start-up signal
|
||||
//
|
||||
*ApStartupSignalBuffer = 0;
|
||||
while (TRUE) {
|
||||
DisableInterrupts ();
|
||||
if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) {
|
||||
//
|
||||
// Place AP in Mwait-loop
|
||||
//
|
||||
AsmMonitor ((UINTN)ApStartupSignalBuffer, 0, 0);
|
||||
if (*ApStartupSignalBuffer != WAKEUP_AP_SIGNAL) {
|
||||
//
|
||||
// If AP start-up signal is not set, place AP into
|
||||
// the maximum C-state
|
||||
//
|
||||
AsmMwait (PeiCpuMpData->ApTargetCState << 4, 0);
|
||||
}
|
||||
} else if (PeiCpuMpData->ApLoopMode == ApInRunLoop) {
|
||||
//
|
||||
// Place AP in Run-loop
|
||||
//
|
||||
CpuPause ();
|
||||
} else {
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
AsmCliHltLoop ();
|
||||
//
|
||||
// If AP start-up signal is written, AP is waken up
|
||||
// otherwise place AP in loop again
|
||||
//
|
||||
if (*ApStartupSignalBuffer == WAKEUP_AP_SIGNAL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <Library/SynchronizationLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/UefiCpuLib.h>
|
||||
#include <Library/CpuLib.h>
|
||||
|
||||
#include "Microcode.h"
|
||||
|
||||
@ -50,6 +51,8 @@ typedef enum {
|
||||
CpuStateDisabled
|
||||
} CPU_STATE;
|
||||
|
||||
#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
|
||||
|
||||
typedef enum {
|
||||
ApInHltLoop = 1,
|
||||
ApInMwaitLoop = 2,
|
||||
|
@ -66,6 +66,7 @@
|
||||
SynchronizationLib
|
||||
TimerLib
|
||||
UefiCpuLib
|
||||
CpuLib
|
||||
|
||||
[Ppis]
|
||||
gEfiPeiMpServicesPpiGuid ## PRODUCES
|
||||
|
Loading…
x
Reference in New Issue
Block a user