SetApProcedure (&mMpSystemData.CpuDatas[NextNumber],\r
mMpSystemData.Procedure,\r
mMpSystemData.ProcedureArgument);\r
+ //\r
+ // If this AP previous state is blocked, we should\r
+ // wake up this AP by sent a SIPI. and avoid\r
+ // re-involve the sleeping state. we must call\r
+ // SetApProcedure() first.\r
+ //\r
+ ResetProcessorToIdleState (&mMpSystemData.CpuDatas[NextNumber]);\r
}\r
}\r
-\r
SetApState (CpuData, CpuStateIdle);\r
}\r
}\r
}\r
\r
CpuState = GetApState (CpuData);\r
- if (CpuState != CpuStateIdle) {\r
+ if (CpuState != CpuStateIdle &&\r
+ CpuState != CpuStateSleeping) {\r
if (mMpSystemData.FailedList != NULL) {\r
(*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex++] = Number;\r
}\r
CPU_DATA_BLOCK *CpuData;\r
UINTN Number;\r
CPU_STATE APInitialState;\r
+ CPU_STATE CpuState;\r
\r
CpuData = NULL;\r
\r
continue;\r
}\r
\r
- if (GetApState (CpuData) != CpuStateIdle) {\r
+ CpuState = GetApState (CpuData);\r
+ if (CpuState != CpuStateIdle &&\r
+ CpuState != CpuStateSleeping) {\r
return EFI_NOT_READY;\r
}\r
}\r
// state 1 by 1, until the previous 1 finished its task\r
// if not "SingleThread", all APs are put to ready state from the beginning\r
//\r
- if (GetApState (CpuData) == CpuStateIdle) {\r
+ CpuState = GetApState (CpuData);\r
+ if (CpuState == CpuStateIdle ||\r
+ CpuState == CpuStateSleeping) {\r
mMpSystemData.StartCount++;\r
\r
SetApState (CpuData, APInitialState);\r
\r
if (APInitialState == CpuStateReady) {\r
SetApProcedure (CpuData, Procedure, ProcedureArgument);\r
+ //\r
+ // If this AP previous state is Sleeping, we should\r
+ // wake up this AP by sent a SIPI. and avoid\r
+ // re-involve the sleeping state. we must call\r
+ // SetApProcedure() first.\r
+ //\r
+ if (CpuState == CpuStateSleeping) {\r
+ ResetProcessorToIdleState (CpuData);\r
+ }\r
}\r
\r
if (SingleThread) {\r
)\r
{\r
CPU_DATA_BLOCK *CpuData;\r
+ CPU_STATE CpuState;\r
\r
CpuData = NULL;\r
\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (GetApState (CpuData) != CpuStateIdle) {\r
+ CpuState = GetApState (CpuData);\r
+ if (CpuState != CpuStateIdle &&\r
+ CpuState != CpuStateSleeping) {\r
return EFI_NOT_READY;\r
}\r
\r
SetApState (CpuData, CpuStateReady);\r
\r
SetApProcedure (CpuData, Procedure, ProcedureArgument);\r
+ //\r
+ // If this AP previous state is Sleeping, we should\r
+ // wake up this AP by sent a SIPI. and avoid\r
+ // re-involve the sleeping state. we must call\r
+ // SetApProcedure() first.\r
+ //\r
+ if (CpuState == CpuStateSleeping) {\r
+ ResetProcessorToIdleState (CpuData);\r
+ }\r
\r
CpuData->Timeout = TimeoutInMicroseconds;\r
CpuData->WaitEvent = WaitEvent;\r
{\r
CPU_DATA_BLOCK *CpuData;\r
BOOLEAN TempStopCheckState;\r
+ CPU_STATE CpuState;\r
\r
CpuData = NULL;\r
TempStopCheckState = FALSE;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (GetApState (CpuData) != CpuStateIdle) {\r
+ CpuState = GetApState (CpuData);\r
+ if (CpuState != CpuStateIdle &&\r
+ CpuState != CpuStateSleeping) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
CpuData->Procedure = NULL;\r
CpuData->State = CpuStateFinished;\r
ReleaseMpSpinLock (CpuData);\r
+ } else {\r
+ //\r
+ // if no procedure to execution, we simply put AP\r
+ // into sleeping state, and waiting BSP sent SIPI.\r
+ //\r
+ GetMpSpinLock (CpuData);\r
+ if (CpuData->State == CpuStateIdle) {\r
+ CpuData->State = CpuStateSleeping;\r
+ }\r
+ ReleaseMpSpinLock (CpuData);\r
+ }\r
+\r
+ if (GetApState (CpuData) == CpuStateSleeping) {\r
+ CpuSleep ();\r
}\r
\r
CpuPause ();\r