]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
OptionRomPkg/AtapiPassThruDxe: rebase to ARRAY_SIZE()
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / MpService.c
index 185cb3d5935fe92ebf79a785487c392e080a0d69..12466ef5de1f633b20c24bcec75e1ffff0c1e586 100644 (file)
@@ -21,6 +21,9 @@ UINT64                                      gSmiMtrrs[MTRR_NUMBER_OF_FIXED_MTRR
 UINT64                                      gPhyMask;\r
 SMM_DISPATCHER_MP_SYNC_DATA                 *mSmmMpSyncData = NULL;\r
 UINTN                                       mSmmMpSyncDataSize;\r
+SMM_CPU_SEMAPHORES                          mSmmCpuSemaphores;\r
+UINTN                                       mSemaphoreSize;\r
+SPIN_LOCK                                   *mPFLock = NULL;\r
 \r
 /**\r
   Performs an atomic compare exchange operation to get semaphore.\r
@@ -120,7 +123,7 @@ WaitForAllAPs (
 \r
   BspIndex = mSmmMpSyncData->BspIndex;\r
   while (NumberOfAPs-- > 0) {\r
-    WaitForSemaphore (&mSmmMpSyncData->CpuData[BspIndex].Run);\r
+    WaitForSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);\r
   }\r
 }\r
 \r
@@ -139,8 +142,8 @@ ReleaseAllAPs (
 \r
   BspIndex = mSmmMpSyncData->BspIndex;\r
   for (Index = mMaxNumberOfCpus; Index-- > 0;) {\r
-    if (Index != BspIndex && mSmmMpSyncData->CpuData[Index].Present) {\r
-      ReleaseSemaphore (&mSmmMpSyncData->CpuData[Index].Run);\r
+    if (Index != BspIndex && *(mSmmMpSyncData->CpuData[Index].Present)) {\r
+      ReleaseSemaphore (mSmmMpSyncData->CpuData[Index].Run);\r
     }\r
   }\r
 }\r
@@ -163,16 +166,16 @@ AllCpusInSmmWithExceptions (
   SMM_CPU_DATA_BLOCK                *CpuData;\r
   EFI_PROCESSOR_INFORMATION         *ProcessorInfo;\r
 \r
-  ASSERT (mSmmMpSyncData->Counter <= mNumberOfCpus);\r
+  ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);\r
 \r
-  if (mSmmMpSyncData->Counter == mNumberOfCpus) {\r
+  if (*mSmmMpSyncData->Counter == mNumberOfCpus) {\r
     return TRUE;\r
   }\r
 \r
   CpuData = mSmmMpSyncData->CpuData;\r
   ProcessorInfo = gSmmCpuPrivate->ProcessorInfo;\r
   for (Index = mMaxNumberOfCpus; Index-- > 0;) {\r
-    if (!CpuData[Index].Present && ProcessorInfo[Index].ProcessorId != INVALID_APIC_ID) {\r
+    if (!(*(CpuData[Index].Present)) && ProcessorInfo[Index].ProcessorId != INVALID_APIC_ID) {\r
       if (((Exceptions & ARRIVAL_EXCEPTION_DELAYED) != 0) && SmmCpuFeaturesGetSmmRegister (Index, SmmRegSmmDelayed) != 0) {\r
         continue;\r
       }\r
@@ -204,7 +207,7 @@ SmmWaitForApArrival (
   UINT64                            Timer;\r
   UINTN                             Index;\r
 \r
-  ASSERT (mSmmMpSyncData->Counter <= mNumberOfCpus);\r
+  ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);\r
 \r
   //\r
   // Platform implementor should choose a timeout value appropriately:\r
@@ -243,12 +246,12 @@ SmmWaitForApArrival (
   //    - In relaxed flow, CheckApArrival() will check SMI disabling status before calling this function.\r
   //    In both cases, adding SMI-disabling checking code increases overhead.\r
   //\r
-  if (mSmmMpSyncData->Counter < mNumberOfCpus) {\r
+  if (*mSmmMpSyncData->Counter < mNumberOfCpus) {\r
     //\r
     // Send SMI IPIs to bring outside processors in\r
     //\r
     for (Index = mMaxNumberOfCpus; Index-- > 0;) {\r
-      if (!mSmmMpSyncData->CpuData[Index].Present && gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId != INVALID_APIC_ID) {\r
+      if (!(*(mSmmMpSyncData->CpuData[Index].Present)) && gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId != INVALID_APIC_ID) {\r
         SendSmiIpi ((UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId);\r
       }\r
     }\r
@@ -320,7 +323,7 @@ BSPHandler (
   //\r
   // Flag BSP's presence\r
   //\r
-  mSmmMpSyncData->InsideSmm = TRUE;\r
+  *mSmmMpSyncData->InsideSmm = TRUE;\r
 \r
   //\r
   // Initialize Debug Agent to start source level debug in BSP handler\r
@@ -330,7 +333,7 @@ BSPHandler (
   //\r
   // Mark this processor's presence\r
   //\r
-  mSmmMpSyncData->CpuData[CpuIndex].Present = TRUE;\r
+  *(mSmmMpSyncData->CpuData[CpuIndex].Present) = TRUE;\r
 \r
   //\r
   // Clear platform top level SMI status bit before calling SMI handlers. If\r
@@ -358,8 +361,8 @@ BSPHandler (
     //\r
     // Lock the counter down and retrieve the number of APs\r
     //\r
-    mSmmMpSyncData->AllCpusInSync = TRUE;\r
-    ApCount = LockdownSemaphore (&mSmmMpSyncData->Counter) - 1;\r
+    *mSmmMpSyncData->AllCpusInSync = TRUE;\r
+    ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1;\r
 \r
     //\r
     // Wait for all APs to get ready for programming MTRRs\r
@@ -409,7 +412,7 @@ BSPHandler (
   //\r
   // The BUSY lock is initialized to Acquired state\r
   //\r
-  AcquireSpinLockOrFail (&mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
+  AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
 \r
   //\r
   // Perform the pre tasks\r
@@ -425,9 +428,9 @@ BSPHandler (
   // Make sure all APs have completed their pending none-block tasks\r
   //\r
   for (Index = mMaxNumberOfCpus; Index-- > 0;) {\r
-    if (Index != CpuIndex && mSmmMpSyncData->CpuData[Index].Present) {\r
-      AcquireSpinLock (&mSmmMpSyncData->CpuData[Index].Busy);\r
-      ReleaseSpinLock (&mSmmMpSyncData->CpuData[Index].Busy);;\r
+    if (Index != CpuIndex && *(mSmmMpSyncData->CpuData[Index].Present)) {\r
+      AcquireSpinLock (mSmmMpSyncData->CpuData[Index].Busy);\r
+      ReleaseSpinLock (mSmmMpSyncData->CpuData[Index].Busy);\r
     }\r
   }\r
 \r
@@ -446,15 +449,15 @@ BSPHandler (
     //\r
     // Lock the counter down and retrieve the number of APs\r
     //\r
-    mSmmMpSyncData->AllCpusInSync = TRUE;\r
-    ApCount = LockdownSemaphore (&mSmmMpSyncData->Counter) - 1;\r
+    *mSmmMpSyncData->AllCpusInSync = TRUE;\r
+    ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1;\r
     //\r
     // Make sure all APs have their Present flag set\r
     //\r
     while (TRUE) {\r
       PresentCount = 0;\r
       for (Index = mMaxNumberOfCpus; Index-- > 0;) {\r
-        if (mSmmMpSyncData->CpuData[Index].Present) {\r
+        if (*(mSmmMpSyncData->CpuData[Index].Present)) {\r
           PresentCount ++;\r
         }\r
       }\r
@@ -467,7 +470,7 @@ BSPHandler (
   //\r
   // Notify all APs to exit\r
   //\r
-  mSmmMpSyncData->InsideSmm = FALSE;\r
+  *mSmmMpSyncData->InsideSmm = FALSE;\r
   ReleaseAllAPs ();\r
 \r
   //\r
@@ -512,7 +515,7 @@ BSPHandler (
   //\r
   // Clear the Present flag of BSP\r
   //\r
-  mSmmMpSyncData->CpuData[CpuIndex].Present = FALSE;\r
+  *(mSmmMpSyncData->CpuData[CpuIndex].Present) = FALSE;\r
 \r
   //\r
   // Gather APs to exit SMM synchronously. Note the Present flag is cleared by now but\r
@@ -530,8 +533,8 @@ BSPHandler (
   //\r
   // Allow APs to check in from this point on\r
   //\r
-  mSmmMpSyncData->Counter = 0;\r
-  mSmmMpSyncData->AllCpusInSync = FALSE;\r
+  *mSmmMpSyncData->Counter = 0;\r
+  *mSmmMpSyncData->AllCpusInSync = FALSE;\r
 }\r
 \r
 /**\r
@@ -558,12 +561,12 @@ APHandler (
   //\r
   for (Timer = StartSyncTimer ();\r
        !IsSyncTimerTimeout (Timer) &&\r
-       !mSmmMpSyncData->InsideSmm;\r
+       !(*mSmmMpSyncData->InsideSmm);\r
        ) {\r
     CpuPause ();\r
   }\r
 \r
-  if (!mSmmMpSyncData->InsideSmm) {\r
+  if (!(*mSmmMpSyncData->InsideSmm)) {\r
     //\r
     // BSP timeout in the first round\r
     //\r
@@ -584,23 +587,23 @@ APHandler (
       //\r
       for (Timer = StartSyncTimer ();\r
            !IsSyncTimerTimeout (Timer) &&\r
-           !mSmmMpSyncData->InsideSmm;\r
+           !(*mSmmMpSyncData->InsideSmm);\r
            ) {\r
         CpuPause ();\r
       }\r
 \r
-      if (!mSmmMpSyncData->InsideSmm) {\r
+      if (!(*mSmmMpSyncData->InsideSmm)) {\r
         //\r
         // Give up since BSP is unable to enter SMM\r
         // and signal the completion of this AP\r
-        WaitForSemaphore (&mSmmMpSyncData->Counter);\r
+        WaitForSemaphore (mSmmMpSyncData->Counter);\r
         return;\r
       }\r
     } else {\r
       //\r
       // Don't know BSP index. Give up without sending IPI to BSP.\r
       //\r
-      WaitForSemaphore (&mSmmMpSyncData->Counter);\r
+      WaitForSemaphore (mSmmMpSyncData->Counter);\r
       return;\r
     }\r
   }\r
@@ -614,20 +617,20 @@ APHandler (
   //\r
   // Mark this processor's presence\r
   //\r
-  mSmmMpSyncData->CpuData[CpuIndex].Present = TRUE;\r
+  *(mSmmMpSyncData->CpuData[CpuIndex].Present) = TRUE;\r
 \r
   if (SyncMode == SmmCpuSyncModeTradition || SmmCpuFeaturesNeedConfigureMtrrs()) {\r
     //\r
     // Notify BSP of arrival at this point\r
     //\r
-    ReleaseSemaphore (&mSmmMpSyncData->CpuData[BspIndex].Run);\r
+    ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);\r
   }\r
 \r
   if (SmmCpuFeaturesNeedConfigureMtrrs()) {\r
     //\r
     // Wait for the signal from BSP to backup MTRRs\r
     //\r
-    WaitForSemaphore (&mSmmMpSyncData->CpuData[CpuIndex].Run);\r
+    WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);\r
 \r
     //\r
     // Backup OS MTRRs\r
@@ -637,12 +640,12 @@ APHandler (
     //\r
     // Signal BSP the completion of this AP\r
     //\r
-    ReleaseSemaphore (&mSmmMpSyncData->CpuData[BspIndex].Run);\r
+    ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);\r
 \r
     //\r
     // Wait for BSP's signal to program MTRRs\r
     //\r
-    WaitForSemaphore (&mSmmMpSyncData->CpuData[CpuIndex].Run);\r
+    WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);\r
 \r
     //\r
     // Replace OS MTRRs with SMI MTRRs\r
@@ -652,19 +655,19 @@ APHandler (
     //\r
     // Signal BSP the completion of this AP\r
     //\r
-    ReleaseSemaphore (&mSmmMpSyncData->CpuData[BspIndex].Run);\r
+    ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);\r
   }\r
 \r
   while (TRUE) {\r
     //\r
     // Wait for something to happen\r
     //\r
-    WaitForSemaphore (&mSmmMpSyncData->CpuData[CpuIndex].Run);\r
+    WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);\r
 \r
     //\r
     // Check if BSP wants to exit SMM\r
     //\r
-    if (!mSmmMpSyncData->InsideSmm) {\r
+    if (!(*mSmmMpSyncData->InsideSmm)) {\r
       break;\r
     }\r
 \r
@@ -672,7 +675,7 @@ APHandler (
     // BUSY should be acquired by SmmStartupThisAp()\r
     //\r
     ASSERT (\r
-      !AcquireSpinLockOrFail (&mSmmMpSyncData->CpuData[CpuIndex].Busy)\r
+      !AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy)\r
       );\r
 \r
     //\r
@@ -685,19 +688,19 @@ APHandler (
     //\r
     // Release BUSY\r
     //\r
-    ReleaseSpinLock (&mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
+    ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
   }\r
 \r
   if (SmmCpuFeaturesNeedConfigureMtrrs()) {\r
     //\r
     // Notify BSP the readiness of this AP to program MTRRs\r
     //\r
-    ReleaseSemaphore (&mSmmMpSyncData->CpuData[BspIndex].Run);\r
+    ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);\r
 \r
     //\r
     // Wait for the signal from BSP to program MTRRs\r
     //\r
-    WaitForSemaphore (&mSmmMpSyncData->CpuData[CpuIndex].Run);\r
+    WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);\r
 \r
     //\r
     // Restore OS MTRRs\r
@@ -709,22 +712,22 @@ APHandler (
   //\r
   // Notify BSP the readiness of this AP to Reset states/semaphore for this processor\r
   //\r
-  ReleaseSemaphore (&mSmmMpSyncData->CpuData[BspIndex].Run);\r
+  ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);\r
 \r
   //\r
   // Wait for the signal from BSP to Reset states/semaphore for this processor\r
   //\r
-  WaitForSemaphore (&mSmmMpSyncData->CpuData[CpuIndex].Run);\r
+  WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);\r
 \r
   //\r
   // Reset states/semaphore for this processor\r
   //\r
-  mSmmMpSyncData->CpuData[CpuIndex].Present = FALSE;\r
+  *(mSmmMpSyncData->CpuData[CpuIndex].Present) = FALSE;\r
 \r
   //\r
   // Notify BSP the readiness of this AP to exit SMM\r
   //\r
-  ReleaseSemaphore (&mSmmMpSyncData->CpuData[BspIndex].Run);\r
+  ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);\r
 \r
 }\r
 \r
@@ -925,19 +928,19 @@ SmmStartupThisAp (
 {\r
   if (CpuIndex >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus ||\r
       CpuIndex == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu ||\r
-      !mSmmMpSyncData->CpuData[CpuIndex].Present ||\r
+      !(*(mSmmMpSyncData->CpuData[CpuIndex].Present)) ||\r
       gSmmCpuPrivate->Operation[CpuIndex] == SmmCpuRemove ||\r
-      !AcquireSpinLockOrFail (&mSmmMpSyncData->CpuData[CpuIndex].Busy)) {\r
+      !AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   mSmmMpSyncData->CpuData[CpuIndex].Procedure = Procedure;\r
   mSmmMpSyncData->CpuData[CpuIndex].Parameter = ProcArguments;\r
-  ReleaseSemaphore (&mSmmMpSyncData->CpuData[CpuIndex].Run);\r
+  ReleaseSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);\r
 \r
   if (FeaturePcdGet (PcdCpuSmmBlockStartupThisAp)) {\r
-    AcquireSpinLock (&mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
-    ReleaseSpinLock (&mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
+    AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
+    ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
   }\r
   return EFI_SUCCESS;\r
 }\r
@@ -1013,13 +1016,14 @@ SmiRendezvous (
   IN      UINTN                     CpuIndex\r
   )\r
 {\r
-  EFI_STATUS        Status;\r
-  BOOLEAN           ValidSmi;\r
-  BOOLEAN           IsBsp;\r
-  BOOLEAN           BspInProgress;\r
-  UINTN             Index;\r
-  UINTN             Cr2;\r
-  BOOLEAN           XdDisableFlag;\r
+  EFI_STATUS                     Status;\r
+  BOOLEAN                        ValidSmi;\r
+  BOOLEAN                        IsBsp;\r
+  BOOLEAN                        BspInProgress;\r
+  UINTN                          Index;\r
+  UINTN                          Cr2;\r
+  BOOLEAN                        XdDisableFlag;\r
+  MSR_IA32_MISC_ENABLE_REGISTER  MiscEnableMsr;\r
 \r
   //\r
   // Save Cr2 because Page Fault exception in SMM may override its value\r
@@ -1040,7 +1044,7 @@ SmiRendezvous (
   // Determine if BSP has been already in progress. Note this must be checked after\r
   // ValidSmi because BSP may clear a valid SMI source after checking in.\r
   //\r
-  BspInProgress = mSmmMpSyncData->InsideSmm;\r
+  BspInProgress = *mSmmMpSyncData->InsideSmm;\r
 \r
   if (!BspInProgress && !ValidSmi) {\r
     //\r
@@ -1055,7 +1059,7 @@ SmiRendezvous (
     //\r
     // Signal presence of this processor\r
     //\r
-    if (ReleaseSemaphore (&mSmmMpSyncData->Counter) == 0) {\r
+    if (ReleaseSemaphore (mSmmMpSyncData->Counter) == 0) {\r
       //\r
       // BSP has already ended the synchronization, so QUIT!!!\r
       //\r
@@ -1063,7 +1067,7 @@ SmiRendezvous (
       //\r
       // Wait for BSP's signal to finish SMI\r
       //\r
-      while (mSmmMpSyncData->AllCpusInSync) {\r
+      while (*mSmmMpSyncData->AllCpusInSync) {\r
         CpuPause ();\r
       }\r
       goto Exit;\r
@@ -1075,7 +1079,7 @@ SmiRendezvous (
       // E.g., with Relaxed AP flow, SmmStartupThisAp() may be called immediately\r
       // after AP's present flag is detected.\r
       //\r
-      InitializeSpinLock (&mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
+      InitializeSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
     }\r
 \r
     //\r
@@ -1083,9 +1087,11 @@ SmiRendezvous (
     //\r
     XdDisableFlag = FALSE;\r
     if (mXdSupported) {\r
-      if ((AsmReadMsr64 (MSR_IA32_MISC_ENABLE) & B_XD_DISABLE_BIT) != 0) {\r
+      MiscEnableMsr.Uint64 = AsmReadMsr64 (MSR_IA32_MISC_ENABLE);\r
+      if (MiscEnableMsr.Bits.XD == 1) {\r
         XdDisableFlag = TRUE;\r
-        AsmMsrAnd64 (MSR_IA32_MISC_ENABLE, ~B_XD_DISABLE_BIT);\r
+        MiscEnableMsr.Bits.XD = 0;\r
+        AsmWriteMsr64 (MSR_IA32_MISC_ENABLE, MiscEnableMsr.Uint64);\r
       }\r
       ActivateXd ();\r
     }\r
@@ -1163,12 +1169,12 @@ SmiRendezvous (
       }\r
     }\r
 \r
-    ASSERT (mSmmMpSyncData->CpuData[CpuIndex].Run == 0);\r
+    ASSERT (*mSmmMpSyncData->CpuData[CpuIndex].Run == 0);\r
 \r
     //\r
     // Wait for BSP's signal to exit SMI\r
     //\r
-    while (mSmmMpSyncData->AllCpusInSync) {\r
+    while (*mSmmMpSyncData->AllCpusInSync) {\r
       CpuPause ();\r
      }\r
 \r
@@ -1176,7 +1182,9 @@ SmiRendezvous (
     // Restore XD\r
     //\r
     if (XdDisableFlag) {\r
-      AsmMsrOr64 (MSR_IA32_MISC_ENABLE, B_XD_DISABLE_BIT);\r
+      MiscEnableMsr.Uint64 = AsmReadMsr64 (MSR_IA32_MISC_ENABLE);\r
+      MiscEnableMsr.Bits.XD = 1;\r
+      AsmWriteMsr64 (MSR_IA32_MISC_ENABLE, MiscEnableMsr.Uint64);\r
     }\r
   }\r
 \r
@@ -1188,6 +1196,72 @@ Exit:
   AsmWriteCr2 (Cr2);\r
 }\r
 \r
+/**\r
+  Allocate buffer for all semaphores and spin locks.\r
+\r
+**/\r
+VOID\r
+InitializeSmmCpuSemaphores (\r
+  VOID\r
+  )\r
+{\r
+  UINTN                      ProcessorCount;\r
+  UINTN                      TotalSize;\r
+  UINTN                      GlobalSemaphoresSize;\r
+  UINTN                      CpuSemaphoresSize;\r
+  UINTN                      MsrSemahporeSize;\r
+  UINTN                      SemaphoreSize;\r
+  UINTN                      Pages;\r
+  UINTN                      *SemaphoreBlock;\r
+  UINTN                      SemaphoreAddr;\r
+\r
+  SemaphoreSize   = GetSpinLockProperties ();\r
+  ProcessorCount = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;\r
+  GlobalSemaphoresSize = (sizeof (SMM_CPU_SEMAPHORE_GLOBAL) / sizeof (VOID *)) * SemaphoreSize;\r
+  CpuSemaphoresSize    = (sizeof (SMM_CPU_SEMAPHORE_CPU) / sizeof (VOID *)) * ProcessorCount * SemaphoreSize;\r
+  MsrSemahporeSize     = MSR_SPIN_LOCK_INIT_NUM * SemaphoreSize;\r
+  TotalSize = GlobalSemaphoresSize + CpuSemaphoresSize + MsrSemahporeSize;\r
+  DEBUG((EFI_D_INFO, "One Semaphore Size    = 0x%x\n", SemaphoreSize));\r
+  DEBUG((EFI_D_INFO, "Total Semaphores Size = 0x%x\n", TotalSize));\r
+  Pages = EFI_SIZE_TO_PAGES (TotalSize);\r
+  SemaphoreBlock = AllocatePages (Pages);\r
+  ASSERT (SemaphoreBlock != NULL);\r
+  ZeroMem (SemaphoreBlock, TotalSize);\r
+\r
+  SemaphoreAddr = (UINTN)SemaphoreBlock;\r
+  mSmmCpuSemaphores.SemaphoreGlobal.Counter       = (UINT32 *)SemaphoreAddr;\r
+  SemaphoreAddr += SemaphoreSize;\r
+  mSmmCpuSemaphores.SemaphoreGlobal.InsideSmm     = (BOOLEAN *)SemaphoreAddr;\r
+  SemaphoreAddr += SemaphoreSize;\r
+  mSmmCpuSemaphores.SemaphoreGlobal.AllCpusInSync = (BOOLEAN *)SemaphoreAddr;\r
+  SemaphoreAddr += SemaphoreSize;\r
+  mSmmCpuSemaphores.SemaphoreGlobal.PFLock        = (SPIN_LOCK *)SemaphoreAddr;\r
+  SemaphoreAddr += SemaphoreSize;\r
+  mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock\r
+                                                  = (SPIN_LOCK *)SemaphoreAddr;\r
+  SemaphoreAddr += SemaphoreSize;\r
+  mSmmCpuSemaphores.SemaphoreGlobal.MemoryMappedLock\r
+                                                  = (SPIN_LOCK *)SemaphoreAddr;\r
+\r
+  SemaphoreAddr = (UINTN)SemaphoreBlock + GlobalSemaphoresSize;\r
+  mSmmCpuSemaphores.SemaphoreCpu.Busy    = (SPIN_LOCK *)SemaphoreAddr;\r
+  SemaphoreAddr += ProcessorCount * SemaphoreSize;\r
+  mSmmCpuSemaphores.SemaphoreCpu.Run     = (UINT32 *)SemaphoreAddr;\r
+  SemaphoreAddr += ProcessorCount * SemaphoreSize;\r
+  mSmmCpuSemaphores.SemaphoreCpu.Present = (BOOLEAN *)SemaphoreAddr;\r
+\r
+  SemaphoreAddr = (UINTN)SemaphoreBlock + GlobalSemaphoresSize + CpuSemaphoresSize;\r
+  mSmmCpuSemaphores.SemaphoreMsr.Msr              = (SPIN_LOCK *)SemaphoreAddr;\r
+  mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter =\r
+        ((UINTN)SemaphoreBlock + Pages * SIZE_4KB - SemaphoreAddr) / SemaphoreSize;\r
+  ASSERT (mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter >= MSR_SPIN_LOCK_INIT_NUM);\r
+\r
+  mPFLock                       = mSmmCpuSemaphores.SemaphoreGlobal.PFLock;\r
+  mConfigSmmCodeAccessCheckLock = mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock;\r
+  mMemoryMappedLock             = mSmmCpuSemaphores.SemaphoreGlobal.MemoryMappedLock;\r
+\r
+  mSemaphoreSize = SemaphoreSize;\r
+}\r
 \r
 /**\r
   Initialize un-cacheable data.\r
@@ -1199,7 +1273,13 @@ InitializeMpSyncData (
   VOID\r
   )\r
 {\r
+  UINTN                      CpuIndex;\r
+\r
   if (mSmmMpSyncData != NULL) {\r
+    //\r
+    // mSmmMpSyncDataSize includes one structure of SMM_DISPATCHER_MP_SYNC_DATA, one\r
+    // CpuData array of SMM_CPU_DATA_BLOCK and one CandidateBsp array of BOOLEAN.\r
+    //\r
     ZeroMem (mSmmMpSyncData, mSmmMpSyncDataSize);\r
     mSmmMpSyncData->CpuData = (SMM_CPU_DATA_BLOCK *)((UINT8 *)mSmmMpSyncData + sizeof (SMM_DISPATCHER_MP_SYNC_DATA));\r
     mSmmMpSyncData->CandidateBsp = (BOOLEAN *)(mSmmMpSyncData->CpuData + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);\r
@@ -1210,6 +1290,24 @@ InitializeMpSyncData (
       mSmmMpSyncData->BspIndex = (UINT32)-1;\r
     }\r
     mSmmMpSyncData->EffectiveSyncMode = (SMM_CPU_SYNC_MODE) PcdGet8 (PcdCpuSmmSyncMode);\r
+\r
+    mSmmMpSyncData->Counter       = mSmmCpuSemaphores.SemaphoreGlobal.Counter;\r
+    mSmmMpSyncData->InsideSmm     = mSmmCpuSemaphores.SemaphoreGlobal.InsideSmm;\r
+    mSmmMpSyncData->AllCpusInSync = mSmmCpuSemaphores.SemaphoreGlobal.AllCpusInSync;\r
+    ASSERT (mSmmMpSyncData->Counter != NULL && mSmmMpSyncData->InsideSmm != NULL &&\r
+            mSmmMpSyncData->AllCpusInSync != NULL);\r
+    *mSmmMpSyncData->Counter       = 0;\r
+    *mSmmMpSyncData->InsideSmm     = FALSE;\r
+    *mSmmMpSyncData->AllCpusInSync = FALSE;\r
+\r
+    for (CpuIndex = 0; CpuIndex < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; CpuIndex ++) {\r
+      mSmmMpSyncData->CpuData[CpuIndex].Busy    =\r
+        (SPIN_LOCK *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Busy + mSemaphoreSize * CpuIndex);\r
+      mSmmMpSyncData->CpuData[CpuIndex].Run     =\r
+        (UINT32 *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Run + mSemaphoreSize * CpuIndex);\r
+      mSmmMpSyncData->CpuData[CpuIndex].Present =\r
+        (BOOLEAN *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Present + mSemaphoreSize * CpuIndex);\r
+    }\r
   }\r
 }\r
 \r
@@ -1233,6 +1331,20 @@ InitializeMpServiceData (
   UINT8                     *GdtTssTables;\r
   UINTN                     GdtTableStepSize;\r
 \r
+  //\r
+  // Allocate memory for all locks and semaphores\r
+  //\r
+  InitializeSmmCpuSemaphores ();\r
+\r
+  //\r
+  // Initialize mSmmMpSyncData\r
+  //\r
+  mSmmMpSyncDataSize = sizeof (SMM_DISPATCHER_MP_SYNC_DATA) +\r
+                       (sizeof (SMM_CPU_DATA_BLOCK) + sizeof (BOOLEAN)) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;\r
+  mSmmMpSyncData = (SMM_DISPATCHER_MP_SYNC_DATA*) AllocatePages (EFI_SIZE_TO_PAGES (mSmmMpSyncDataSize));\r
+  ASSERT (mSmmMpSyncData != NULL);\r
+  InitializeMpSyncData ();\r
+\r
   //\r
   // Initialize physical address mask\r
   // NOTE: Physical memory above virtual address limit is not supported !!!\r
@@ -1273,15 +1385,6 @@ InitializeMpServiceData (
       );\r
   }\r
 \r
-  //\r
-  // Initialize mSmmMpSyncData\r
-  //\r
-  mSmmMpSyncDataSize = sizeof (SMM_DISPATCHER_MP_SYNC_DATA) +\r
-                       (sizeof (SMM_CPU_DATA_BLOCK) + sizeof (BOOLEAN)) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;\r
-  mSmmMpSyncData = (SMM_DISPATCHER_MP_SYNC_DATA*) AllocatePages (EFI_SIZE_TO_PAGES (mSmmMpSyncDataSize));\r
-  ASSERT (mSmmMpSyncData != NULL);\r
-  InitializeMpSyncData ();\r
-\r
   //\r
   // Record current MTRR settings\r
   //\r