summaryrefslogtreecommitdiff
path: root/UefiCpuPkg
diff options
context:
space:
mode:
authorChen Fan <chen.fan.fnst@cn.fujitsu.com>2015-03-09 06:43:11 +0000
committervanjeff <vanjeff@Edk2>2015-03-09 06:43:11 +0000
commit68f06742379437e412f9699cc3c82421f4684b67 (patch)
treebc3463c7b76cf58494edb2e91ccc8c88f85816f5 /UefiCpuPkg
parente033a1a83e84effb893899d9272778be5d7f2e1f (diff)
downloadedk2-platforms-68f06742379437e412f9699cc3c82421f4684b67.tar.xz
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
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/CpuDxe/CpuMp.c62
-rw-r--r--UefiCpuPkg/CpuDxe/CpuMp.h3
2 files changed, 58 insertions, 7 deletions
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 25c909193e..e5d2f5f7e2 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -298,9 +298,15 @@ CheckAndUpdateAllAPsToIdleState (
SetApProcedure (&mMpSystemData.CpuDatas[NextNumber],
mMpSystemData.Procedure,
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);
}
}
@@ -343,7 +349,8 @@ ResetAllFailedAPs (
}
CpuState = GetApState (CpuData);
- if (CpuState != CpuStateIdle) {
+ if (CpuState != CpuStateIdle &&
+ CpuState != CpuStateSleeping) {
if (mMpSystemData.FailedList != NULL) {
(*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex++] = Number;
}
@@ -615,6 +622,7 @@ StartupAllAPs (
CPU_DATA_BLOCK *CpuData;
UINTN Number;
CPU_STATE APInitialState;
+ CPU_STATE CpuState;
CpuData = NULL;
@@ -655,7 +663,9 @@ StartupAllAPs (
continue;
}
- if (GetApState (CpuData) != CpuStateIdle) {
+ CpuState = GetApState (CpuData);
+ if (CpuState != CpuStateIdle &&
+ CpuState != CpuStateSleeping) {
return EFI_NOT_READY;
}
}
@@ -694,13 +704,24 @@ StartupAllAPs (
// 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 (GetApState (CpuData) == CpuStateIdle) {
+ CpuState = GetApState (CpuData);
+ if (CpuState == CpuStateIdle ||
+ CpuState == CpuStateSleeping) {
mMpSystemData.StartCount++;
SetApState (CpuData, APInitialState);
if (APInitialState == CpuStateReady) {
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) {
@@ -847,6 +868,7 @@ StartupThisAP (
)
{
CPU_DATA_BLOCK *CpuData;
+ CPU_STATE CpuState;
CpuData = NULL;
@@ -877,13 +899,24 @@ StartupThisAP (
return EFI_INVALID_PARAMETER;
}
- if (GetApState (CpuData) != CpuStateIdle) {
+ CpuState = GetApState (CpuData);
+ if (CpuState != CpuStateIdle &&
+ CpuState != CpuStateSleeping) {
return EFI_NOT_READY;
}
SetApState (CpuData, CpuStateReady);
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->WaitEvent = WaitEvent;
@@ -1021,6 +1054,7 @@ EnableDisableAP (
{
CPU_DATA_BLOCK *CpuData;
BOOLEAN TempStopCheckState;
+ CPU_STATE CpuState;
CpuData = NULL;
TempStopCheckState = FALSE;
@@ -1046,7 +1080,9 @@ EnableDisableAP (
return EFI_INVALID_PARAMETER;
}
- if (GetApState (CpuData) != CpuStateIdle) {
+ CpuState = GetApState (CpuData);
+ if (CpuState != CpuStateIdle &&
+ CpuState != CpuStateSleeping) {
return EFI_UNSUPPORTED;
}
@@ -1201,6 +1237,20 @@ ProcessorToIdleState (
CpuData->Procedure = NULL;
CpuData->State = CpuStateFinished;
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 ();
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index a6478c087c..cb3460f355 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -80,7 +80,8 @@ typedef enum {
CpuStateBlocked,
CpuStateReady,
CpuStateBusy,
- CpuStateFinished
+ CpuStateFinished,
+ CpuStateSleeping
} CPU_STATE;
/**