]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/MpService: Put APs to sleep when not busy.
authorChen Fan <chen.fan.fnst@cn.fujitsu.com>
Mon, 9 Mar 2015 06:43:11 +0000 (06:43 +0000)
committervanjeff <vanjeff@Edk2>
Mon, 9 Mar 2015 06:43:11 +0000 (06:43 +0000)
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

UefiCpuPkg/CpuDxe/CpuMp.c
UefiCpuPkg/CpuDxe/CpuMp.h

index 25c909193e41062f6615f8c11356ed26c86bdc71..e5d2f5f7e28ece9b0796dd759830c1bd77c6dc43 100644 (file)
@@ -298,9 +298,15 @@ CheckAndUpdateAllAPsToIdleState (
           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
@@ -343,7 +349,8 @@ ResetAllFailedAPs (
     }\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
@@ -615,6 +622,7 @@ StartupAllAPs (
   CPU_DATA_BLOCK        *CpuData;\r
   UINTN                 Number;\r
   CPU_STATE             APInitialState;\r
+  CPU_STATE             CpuState;\r
 \r
   CpuData = NULL;\r
 \r
@@ -655,7 +663,9 @@ StartupAllAPs (
       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
@@ -694,13 +704,24 @@ StartupAllAPs (
     // 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
@@ -847,6 +868,7 @@ StartupThisAP (
   )\r
 {\r
   CPU_DATA_BLOCK        *CpuData;\r
+  CPU_STATE             CpuState;\r
 \r
   CpuData = NULL;\r
 \r
@@ -877,13 +899,24 @@ StartupThisAP (
     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
@@ -1021,6 +1054,7 @@ EnableDisableAP (
 {\r
   CPU_DATA_BLOCK *CpuData;\r
   BOOLEAN        TempStopCheckState;\r
+  CPU_STATE      CpuState;\r
 \r
   CpuData = NULL;\r
   TempStopCheckState = FALSE;\r
@@ -1046,7 +1080,9 @@ EnableDisableAP (
     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
@@ -1201,6 +1237,20 @@ ProcessorToIdleState (
       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
index a6478c087c607752f4a25e325c3949fe0c020250..cb3460f355e7fee693f0f48de12ce6150e67f501 100644 (file)
@@ -80,7 +80,8 @@ typedef enum {
   CpuStateBlocked,\r
   CpuStateReady,\r
   CpuStateBusy,\r
-  CpuStateFinished\r
+  CpuStateFinished,\r
+  CpuStateSleeping\r
 } CPU_STATE;\r
 \r
 /**\r