]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
UefiCpuPkg/PiSmmCpuDxeSmm: Remove dependence between APs
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / MpService.c
index 757f1056f78dd62fa3fb3b904ed7f212171f58a1..35951cc43e149815d96b5827d506b6bbe55ad39a 100644 (file)
@@ -402,38 +402,6 @@ IsPresentAp (
     *(mSmmMpSyncData->CpuData[CpuIndex].Present));\r
 }\r
 \r
-/**\r
-  Check whether execute in single AP or all APs.\r
-\r
-  Compare two Tokens used by different APs to know whether in StartAllAps call.\r
-\r
-  Whether is an valid AP base on AP's Present flag.\r
-\r
-  @retval  TRUE      IN StartAllAps call.\r
-  @retval  FALSE     Not in StartAllAps call.\r
-\r
-**/\r
-BOOLEAN\r
-InStartAllApsCall (\r
-  VOID\r
-  )\r
-{\r
-  UINTN      ApIndex;\r
-  UINTN      ApIndex2;\r
-\r
-  for (ApIndex = mMaxNumberOfCpus; ApIndex-- > 0;) {\r
-    if (IsPresentAp (ApIndex) && (mSmmMpSyncData->CpuData[ApIndex].Token != NULL)) {\r
-      for (ApIndex2 = ApIndex; ApIndex2-- > 0;) {\r
-        if (IsPresentAp (ApIndex2) && (mSmmMpSyncData->CpuData[ApIndex2].Token != NULL)) {\r
-          return mSmmMpSyncData->CpuData[ApIndex2].Token == mSmmMpSyncData->CpuData[ApIndex].Token;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
 /**\r
   Clean up the status flags used during executing the procedure.\r
 \r
@@ -445,40 +413,15 @@ ReleaseToken (
   IN UINTN                  CpuIndex\r
   )\r
 {\r
-  UINTN                             Index;\r
-  BOOLEAN                           Released;\r
+  PROCEDURE_TOKEN                         *Token;\r
 \r
-  if (InStartAllApsCall ()) {\r
-    //\r
-    // In Start All APs mode, make sure all APs have finished task.\r
-    //\r
-    if (WaitForAllAPsNotBusy (FALSE)) {\r
-      //\r
-      // Clean the flags update in the function call.\r
-      //\r
-      Released = FALSE;\r
-      for (Index = mMaxNumberOfCpus; Index-- > 0;) {\r
-        //\r
-        // Only In SMM APs need to be clean up.\r
-        //\r
-        if (mSmmMpSyncData->CpuData[Index].Present && mSmmMpSyncData->CpuData[Index].Token != NULL) {\r
-          if (!Released) {\r
-            ReleaseSpinLock (mSmmMpSyncData->CpuData[Index].Token);\r
-            Released = TRUE;\r
-          }\r
-          mSmmMpSyncData->CpuData[Index].Token = NULL;\r
-        }\r
-      }\r
-    }\r
-  } else {\r
-    //\r
-    // In single AP mode.\r
-    //\r
-    if (mSmmMpSyncData->CpuData[CpuIndex].Token != NULL) {\r
-      ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Token);\r
-      mSmmMpSyncData->CpuData[CpuIndex].Token = NULL;\r
-    }\r
+  Token = mSmmMpSyncData->CpuData[CpuIndex].Token;\r
+\r
+  if (InterlockedDecrement (&Token->RunningApCount) == 0) {\r
+    ReleaseSpinLock (Token->SpinLock);\r
   }\r
+\r
+  mSmmMpSyncData->CpuData[CpuIndex].Token = NULL;\r
 }\r
 \r
 /**\r
@@ -912,12 +855,14 @@ APHandler (
       *mSmmMpSyncData->CpuData[CpuIndex].Status = ProcedureStatus;\r
     }\r
 \r
+    if (mSmmMpSyncData->CpuData[CpuIndex].Token != NULL) {\r
+      ReleaseToken (CpuIndex);\r
+    }\r
+\r
     //\r
     // Release BUSY\r
     //\r
     ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
-\r
-    ReleaseToken (CpuIndex);\r
   }\r
 \r
   if (SmmCpuFeaturesNeedConfigureMtrrs()) {\r
@@ -1111,7 +1056,7 @@ IsTokenInUse (
   while (!IsNull (&gSmmCpuPrivate->TokenList, Link)) {\r
     ProcToken = PROCEDURE_TOKEN_FROM_LINK (Link);\r
 \r
-    if (ProcToken->ProcedureToken == Token) {\r
+    if (ProcToken->SpinLock == Token) {\r
       return TRUE;\r
     }\r
 \r
@@ -1124,16 +1069,18 @@ IsTokenInUse (
 /**\r
   create token and save it to the maintain list.\r
 \r
+  @param     RunningApCount   Input running AP count.\r
+\r
   @retval    return the spin lock used as token.\r
 \r
 **/\r
-SPIN_LOCK *\r
+PROCEDURE_TOKEN *\r
 CreateToken (\r
-  VOID\r
+  IN UINT32              RunningApCount\r
   )\r
 {\r
   PROCEDURE_TOKEN     *ProcToken;\r
-  SPIN_LOCK           *CpuToken;\r
+  SPIN_LOCK           *SpinLock;\r
   UINTN               SpinLockSize;\r
   TOKEN_BUFFER        *TokenBuf;\r
   UINT32              TokenCountPerChunk;\r
@@ -1160,20 +1107,21 @@ CreateToken (
     gSmmCpuPrivate->UsedTokenNum = 0;\r
   }\r
 \r
-  CpuToken = (SPIN_LOCK *)(gSmmCpuPrivate->CurrentTokenBuf + SpinLockSize * gSmmCpuPrivate->UsedTokenNum);\r
+  SpinLock = (SPIN_LOCK *)(gSmmCpuPrivate->CurrentTokenBuf + SpinLockSize * gSmmCpuPrivate->UsedTokenNum);\r
   gSmmCpuPrivate->UsedTokenNum++;\r
 \r
-  InitializeSpinLock (CpuToken);\r
-  AcquireSpinLock (CpuToken);\r
+  InitializeSpinLock (SpinLock);\r
+  AcquireSpinLock (SpinLock);\r
 \r
   ProcToken = AllocatePool (sizeof (PROCEDURE_TOKEN));\r
   ASSERT (ProcToken != NULL);\r
   ProcToken->Signature = PROCEDURE_TOKEN_SIGNATURE;\r
-  ProcToken->ProcedureToken = CpuToken;\r
+  ProcToken->SpinLock = SpinLock;\r
+  ProcToken->RunningApCount = RunningApCount;\r
 \r
   InsertTailList (&gSmmCpuPrivate->TokenList, &ProcToken->Link);\r
 \r
-  return CpuToken;\r
+  return ProcToken;\r
 }\r
 \r
 /**\r
@@ -1246,6 +1194,8 @@ InternalSmmStartupThisAp (
   IN OUT  EFI_STATUS                     *CpuStatus\r
   )\r
 {\r
+  PROCEDURE_TOKEN    *ProcToken;\r
+\r
   if (CpuIndex >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus) {\r
     DEBUG((DEBUG_ERROR, "CpuIndex(%d) >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus(%d)\n", CpuIndex, gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
     return EFI_INVALID_PARAMETER;\r
@@ -1278,14 +1228,12 @@ InternalSmmStartupThisAp (
 \r
   AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
 \r
-  if (Token != NULL) {\r
-    *Token = (MM_COMPLETION) CreateToken ();\r
-  }\r
-\r
   mSmmMpSyncData->CpuData[CpuIndex].Procedure = Procedure;\r
   mSmmMpSyncData->CpuData[CpuIndex].Parameter = ProcArguments;\r
   if (Token != NULL) {\r
-    mSmmMpSyncData->CpuData[CpuIndex].Token   = (SPIN_LOCK *)(*Token);\r
+    ProcToken= CreateToken (1);\r
+    mSmmMpSyncData->CpuData[CpuIndex].Token = ProcToken;\r
+    *Token = (MM_COMPLETION)ProcToken->SpinLock;\r
   }\r
   mSmmMpSyncData->CpuData[CpuIndex].Status    = CpuStatus;\r
   if (mSmmMpSyncData->CpuData[CpuIndex].Status != NULL) {\r
@@ -1343,6 +1291,7 @@ InternalSmmStartupAllAPs (
 {\r
   UINTN               Index;\r
   UINTN               CpuCount;\r
+  PROCEDURE_TOKEN     *ProcToken;\r
 \r
   if ((TimeoutInMicroseconds != 0) && ((mSmmMp.Attributes & EFI_MM_MP_TIMEOUT_SUPPORTED) == 0)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1371,7 +1320,10 @@ InternalSmmStartupAllAPs (
   }\r
 \r
   if (Token != NULL) {\r
-    *Token = (MM_COMPLETION) CreateToken ();\r
+    ProcToken = CreateToken ((UINT32)mMaxNumberOfCpus);\r
+    *Token = (MM_COMPLETION)ProcToken->SpinLock;\r
+  } else {\r
+    ProcToken = NULL;\r
   }\r
 \r
   //\r
@@ -1391,8 +1343,8 @@ InternalSmmStartupAllAPs (
     if (IsPresentAp (Index)) {\r
       mSmmMpSyncData->CpuData[Index].Procedure = (EFI_AP_PROCEDURE2) Procedure;\r
       mSmmMpSyncData->CpuData[Index].Parameter = ProcedureArguments;\r
-      if (Token != NULL) {\r
-        mSmmMpSyncData->CpuData[Index].Token   = (SPIN_LOCK *)(*Token);\r
+      if (ProcToken != NULL) {\r
+        mSmmMpSyncData->CpuData[Index].Token   = ProcToken;\r
       }\r
       if (CPUStatus != NULL) {\r
         mSmmMpSyncData->CpuData[Index].Status    = &CPUStatus[Index];\r
@@ -1408,6 +1360,13 @@ InternalSmmStartupAllAPs (
       if (CPUStatus != NULL) {\r
         CPUStatus[Index] = EFI_NOT_STARTED;\r
       }\r
+\r
+      //\r
+      // Decrease the count to mark this processor(AP or BSP) as finished.\r
+      //\r
+      if (ProcToken != NULL) {\r
+        WaitForSemaphore (&ProcToken->RunningApCount);\r
+      }\r
     }\r
   }\r
 \r