mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/MpService: Put APs to sleep when not busy.
Add a new sleeping state for APs, when no procedure execution, put AP to sleep. when need to execute procedure, only need to wake up this AP by sent SIPI. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com> Reviewed-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17023 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
e033a1a83e
commit
68f0674237
|
@ -298,9 +298,15 @@ CheckAndUpdateAllAPsToIdleState (
|
||||||
SetApProcedure (&mMpSystemData.CpuDatas[NextNumber],
|
SetApProcedure (&mMpSystemData.CpuDatas[NextNumber],
|
||||||
mMpSystemData.Procedure,
|
mMpSystemData.Procedure,
|
||||||
mMpSystemData.ProcedureArgument);
|
mMpSystemData.ProcedureArgument);
|
||||||
|
//
|
||||||
|
// If this AP previous state is blocked, we should
|
||||||
|
// wake up this AP by sent a SIPI. and avoid
|
||||||
|
// re-involve the sleeping state. we must call
|
||||||
|
// SetApProcedure() first.
|
||||||
|
//
|
||||||
|
ResetProcessorToIdleState (&mMpSystemData.CpuDatas[NextNumber]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetApState (CpuData, CpuStateIdle);
|
SetApState (CpuData, CpuStateIdle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,7 +349,8 @@ ResetAllFailedAPs (
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuState = GetApState (CpuData);
|
CpuState = GetApState (CpuData);
|
||||||
if (CpuState != CpuStateIdle) {
|
if (CpuState != CpuStateIdle &&
|
||||||
|
CpuState != CpuStateSleeping) {
|
||||||
if (mMpSystemData.FailedList != NULL) {
|
if (mMpSystemData.FailedList != NULL) {
|
||||||
(*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex++] = Number;
|
(*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex++] = Number;
|
||||||
}
|
}
|
||||||
|
@ -615,6 +622,7 @@ StartupAllAPs (
|
||||||
CPU_DATA_BLOCK *CpuData;
|
CPU_DATA_BLOCK *CpuData;
|
||||||
UINTN Number;
|
UINTN Number;
|
||||||
CPU_STATE APInitialState;
|
CPU_STATE APInitialState;
|
||||||
|
CPU_STATE CpuState;
|
||||||
|
|
||||||
CpuData = NULL;
|
CpuData = NULL;
|
||||||
|
|
||||||
|
@ -655,7 +663,9 @@ StartupAllAPs (
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetApState (CpuData) != CpuStateIdle) {
|
CpuState = GetApState (CpuData);
|
||||||
|
if (CpuState != CpuStateIdle &&
|
||||||
|
CpuState != CpuStateSleeping) {
|
||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -694,13 +704,24 @@ StartupAllAPs (
|
||||||
// state 1 by 1, until the previous 1 finished its task
|
// state 1 by 1, until the previous 1 finished its task
|
||||||
// if not "SingleThread", all APs are put to ready state from the beginning
|
// if not "SingleThread", all APs are put to ready state from the beginning
|
||||||
//
|
//
|
||||||
if (GetApState (CpuData) == CpuStateIdle) {
|
CpuState = GetApState (CpuData);
|
||||||
|
if (CpuState == CpuStateIdle ||
|
||||||
|
CpuState == CpuStateSleeping) {
|
||||||
mMpSystemData.StartCount++;
|
mMpSystemData.StartCount++;
|
||||||
|
|
||||||
SetApState (CpuData, APInitialState);
|
SetApState (CpuData, APInitialState);
|
||||||
|
|
||||||
if (APInitialState == CpuStateReady) {
|
if (APInitialState == CpuStateReady) {
|
||||||
SetApProcedure (CpuData, Procedure, ProcedureArgument);
|
SetApProcedure (CpuData, Procedure, ProcedureArgument);
|
||||||
|
//
|
||||||
|
// If this AP previous state is Sleeping, we should
|
||||||
|
// wake up this AP by sent a SIPI. and avoid
|
||||||
|
// re-involve the sleeping state. we must call
|
||||||
|
// SetApProcedure() first.
|
||||||
|
//
|
||||||
|
if (CpuState == CpuStateSleeping) {
|
||||||
|
ResetProcessorToIdleState (CpuData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SingleThread) {
|
if (SingleThread) {
|
||||||
|
@ -847,6 +868,7 @@ StartupThisAP (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
CPU_DATA_BLOCK *CpuData;
|
CPU_DATA_BLOCK *CpuData;
|
||||||
|
CPU_STATE CpuState;
|
||||||
|
|
||||||
CpuData = NULL;
|
CpuData = NULL;
|
||||||
|
|
||||||
|
@ -877,13 +899,24 @@ StartupThisAP (
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetApState (CpuData) != CpuStateIdle) {
|
CpuState = GetApState (CpuData);
|
||||||
|
if (CpuState != CpuStateIdle &&
|
||||||
|
CpuState != CpuStateSleeping) {
|
||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetApState (CpuData, CpuStateReady);
|
SetApState (CpuData, CpuStateReady);
|
||||||
|
|
||||||
SetApProcedure (CpuData, Procedure, ProcedureArgument);
|
SetApProcedure (CpuData, Procedure, ProcedureArgument);
|
||||||
|
//
|
||||||
|
// If this AP previous state is Sleeping, we should
|
||||||
|
// wake up this AP by sent a SIPI. and avoid
|
||||||
|
// re-involve the sleeping state. we must call
|
||||||
|
// SetApProcedure() first.
|
||||||
|
//
|
||||||
|
if (CpuState == CpuStateSleeping) {
|
||||||
|
ResetProcessorToIdleState (CpuData);
|
||||||
|
}
|
||||||
|
|
||||||
CpuData->Timeout = TimeoutInMicroseconds;
|
CpuData->Timeout = TimeoutInMicroseconds;
|
||||||
CpuData->WaitEvent = WaitEvent;
|
CpuData->WaitEvent = WaitEvent;
|
||||||
|
@ -1021,6 +1054,7 @@ EnableDisableAP (
|
||||||
{
|
{
|
||||||
CPU_DATA_BLOCK *CpuData;
|
CPU_DATA_BLOCK *CpuData;
|
||||||
BOOLEAN TempStopCheckState;
|
BOOLEAN TempStopCheckState;
|
||||||
|
CPU_STATE CpuState;
|
||||||
|
|
||||||
CpuData = NULL;
|
CpuData = NULL;
|
||||||
TempStopCheckState = FALSE;
|
TempStopCheckState = FALSE;
|
||||||
|
@ -1046,7 +1080,9 @@ EnableDisableAP (
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetApState (CpuData) != CpuStateIdle) {
|
CpuState = GetApState (CpuData);
|
||||||
|
if (CpuState != CpuStateIdle &&
|
||||||
|
CpuState != CpuStateSleeping) {
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1201,6 +1237,20 @@ ProcessorToIdleState (
|
||||||
CpuData->Procedure = NULL;
|
CpuData->Procedure = NULL;
|
||||||
CpuData->State = CpuStateFinished;
|
CpuData->State = CpuStateFinished;
|
||||||
ReleaseMpSpinLock (CpuData);
|
ReleaseMpSpinLock (CpuData);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// if no procedure to execution, we simply put AP
|
||||||
|
// into sleeping state, and waiting BSP sent SIPI.
|
||||||
|
//
|
||||||
|
GetMpSpinLock (CpuData);
|
||||||
|
if (CpuData->State == CpuStateIdle) {
|
||||||
|
CpuData->State = CpuStateSleeping;
|
||||||
|
}
|
||||||
|
ReleaseMpSpinLock (CpuData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetApState (CpuData) == CpuStateSleeping) {
|
||||||
|
CpuSleep ();
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuPause ();
|
CpuPause ();
|
||||||
|
|
|
@ -80,7 +80,8 @@ typedef enum {
|
||||||
CpuStateBlocked,
|
CpuStateBlocked,
|
||||||
CpuStateReady,
|
CpuStateReady,
|
||||||
CpuStateBusy,
|
CpuStateBusy,
|
||||||
CpuStateFinished
|
CpuStateFinished,
|
||||||
|
CpuStateSleeping
|
||||||
} CPU_STATE;
|
} CPU_STATE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue