diff options
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r-- | UefiCpuPkg/CpuDxe/CpuMp.c | 62 | ||||
-rw-r--r-- | UefiCpuPkg/CpuDxe/CpuMp.h | 3 |
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;
/**
|