]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.c
index e5c701ddeb464d36a66321343f07931dd93e93bb..33374888922a85d80fbe4f4735f1f24446b03926 100644 (file)
@@ -2,13 +2,7 @@
   CPU MP Initialize Library common functions.\r
 \r
   Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -217,9 +211,9 @@ RestoreVolatileRegisters (
   CPUID_VERSION_INFO_EDX        VersionInfoEdx;\r
   IA32_TSS_DESCRIPTOR           *Tss;\r
 \r
-  AsmWriteCr0 (VolatileRegisters->Cr0);\r
   AsmWriteCr3 (VolatileRegisters->Cr3);\r
   AsmWriteCr4 (VolatileRegisters->Cr4);\r
+  AsmWriteCr0 (VolatileRegisters->Cr0);\r
 \r
   if (IsRestoreDr) {\r
     AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);\r
@@ -435,16 +429,19 @@ GetProcessorNumber (
   UINTN                   TotalProcessorNumber;\r
   UINTN                   Index;\r
   CPU_INFO_IN_HOB         *CpuInfoInHob;\r
+  UINT32                  CurrentApicId;\r
 \r
   CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;\r
 \r
   TotalProcessorNumber = CpuMpData->CpuCount;\r
+  CurrentApicId = GetApicId ();\r
   for (Index = 0; Index < TotalProcessorNumber; Index ++) {\r
-    if (CpuInfoInHob[Index].ApicId == GetApicId ()) {\r
+    if (CpuInfoInHob[Index].ApicId == CurrentApicId) {\r
       *ProcessorNumber = Index;\r
       return EFI_SUCCESS;\r
     }\r
   }\r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -467,7 +464,7 @@ CollectProcessorCount (
   //\r
   CpuMpData->InitFlag     = ApInitConfig;\r
   CpuMpData->X2ApicEnable = FALSE;\r
-  WakeUpAP (CpuMpData, TRUE, 0, NULL, NULL);\r
+  WakeUpAP (CpuMpData, TRUE, 0, NULL, NULL, TRUE);\r
   CpuMpData->InitFlag = ApInitDone;\r
   ASSERT (CpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));\r
   //\r
@@ -488,7 +485,7 @@ CollectProcessorCount (
     //\r
     // Wakeup all APs to enable x2APIC mode\r
     //\r
-    WakeUpAP (CpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL);\r
+    WakeUpAP (CpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL, TRUE);\r
     //\r
     // Wait for all known APs finished\r
     //\r
@@ -966,6 +963,7 @@ FreeResetVector (
   @param[in] ProcessorNumber    The handle number of specified processor\r
   @param[in] Procedure          The function to be invoked by AP\r
   @param[in] ProcedureArgument  The argument to be passed into AP function\r
+  @param[in] WakeUpDisabledAps  Whether need to wake up disabled APs in broadcast mode.\r
 **/\r
 VOID\r
 WakeUpAP (\r
@@ -973,7 +971,8 @@ WakeUpAP (
   IN BOOLEAN                   Broadcast,\r
   IN UINTN                     ProcessorNumber,\r
   IN EFI_AP_PROCEDURE          Procedure,              OPTIONAL\r
-  IN VOID                      *ProcedureArgument      OPTIONAL\r
+  IN VOID                      *ProcedureArgument,     OPTIONAL\r
+  IN BOOLEAN                   WakeUpDisabledAps\r
   )\r
 {\r
   volatile MP_CPU_EXCHANGE_INFO    *ExchangeInfo;\r
@@ -1007,6 +1006,15 @@ WakeUpAP (
     for (Index = 0; Index < CpuMpData->CpuCount; Index++) {\r
       if (Index != CpuMpData->BspNumber) {\r
         CpuData = &CpuMpData->CpuData[Index];\r
+        //\r
+        // All AP(include disabled AP) will be woke up by INIT-SIPI-SIPI, but\r
+        // the AP procedure will be skipped for disabled AP because AP state\r
+        // is not CpuStateReady.\r
+        //\r
+        if (GetApState (CpuData) == CpuStateDisabled && !WakeUpDisabledAps) {\r
+          continue;\r
+        }\r
+\r
         CpuData->ApFunction         = (UINTN) Procedure;\r
         CpuData->ApFunctionArgument = (UINTN) ProcedureArgument;\r
         SetApState (CpuData, CpuStateReady);\r
@@ -1286,7 +1294,7 @@ ResetProcessorToIdleState (
   CpuMpData = GetCpuMpData ();\r
 \r
   CpuMpData->InitFlag = ApInitReconfig;\r
-  WakeUpAP (CpuMpData, FALSE, ProcessorNumber, NULL, NULL);\r
+  WakeUpAP (CpuMpData, FALSE, ProcessorNumber, NULL, NULL, TRUE);\r
   while (CpuMpData->FinishedCount < 1) {\r
     CpuPause ();\r
   }\r
@@ -1349,9 +1357,9 @@ CheckThisAP (
   CpuData   = &CpuMpData->CpuData[ProcessorNumber];\r
 \r
   //\r
-  //  Check the CPU state of AP. If it is CpuStateFinished, then the AP has finished its task.\r
+  //  Check the CPU state of AP. If it is CpuStateIdle, then the AP has finished its task.\r
   //  Only BSP and corresponding AP access this unit of CPU Data. This means the AP will not modify the\r
-  //  value of state after setting the it to CpuStateFinished, so BSP can safely make use of its value.\r
+  //  value of state after setting the it to CpuStateIdle, so BSP can safely make use of its value.\r
   //\r
   //\r
   // If the AP finishes for StartupThisAP(), return EFI_SUCCESS.\r
@@ -1417,12 +1425,12 @@ CheckAllAPs (
 \r
     CpuData = &CpuMpData->CpuData[ProcessorNumber];\r
     //\r
-    // Check the CPU state of AP. If it is CpuStateFinished, then the AP has finished its task.\r
+    // Check the CPU state of AP. If it is CpuStateIdle, then the AP has finished its task.\r
     // Only BSP and corresponding AP access this unit of CPU Data. This means the AP will not modify the\r
-    // value of state after setting the it to CpuStateFinished, so BSP can safely make use of its value.\r
+    // value of state after setting the it to CpuStateIdle, so BSP can safely make use of its value.\r
     //\r
     if (GetApState(CpuData) == CpuStateFinished) {\r
-      CpuMpData->RunningCount ++;\r
+      CpuMpData->RunningCount --;\r
       CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;\r
       SetApState(CpuData, CpuStateIdle);\r
 \r
@@ -1438,7 +1446,8 @@ CheckAllAPs (
             FALSE,\r
             (UINT32) NextProcessorNumber,\r
             CpuMpData->Procedure,\r
-            CpuMpData->ProcArguments\r
+            CpuMpData->ProcArguments,\r
+            TRUE\r
             );\r
          }\r
       }\r
@@ -1448,7 +1457,7 @@ CheckAllAPs (
   //\r
   // If all APs finish, return EFI_SUCCESS.\r
   //\r
-  if (CpuMpData->RunningCount == CpuMpData->StartCount) {\r
+  if (CpuMpData->RunningCount == 0) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -1465,7 +1474,7 @@ CheckAllAPs (
     //\r
     if (CpuMpData->FailedCpuList != NULL) {\r
       *CpuMpData->FailedCpuList =\r
-         AllocatePool ((CpuMpData->StartCount - CpuMpData->FinishedCount + 1) * sizeof (UINTN));\r
+         AllocatePool ((CpuMpData->RunningCount + 1) * sizeof (UINTN));\r
       ASSERT (*CpuMpData->FailedCpuList != NULL);\r
     }\r
     ListIndex = 0;\r
@@ -1545,7 +1554,7 @@ MpInitLibInitialize (
   ApLoopMode  = GetApLoopMode (&MonitorFilterSize);\r
 \r
   //\r
-  // Save BSP's Control registers for APs\r
+  // Save BSP's Control registers for APs.\r
   //\r
   SaveVolatileRegisters (&VolatileRegisters);\r
 \r
@@ -1643,6 +1652,10 @@ MpInitLibInitialize (
   //\r
   CopyMem ((VOID *)ApIdtBase, (VOID *)VolatileRegisters.Idtr.Base, VolatileRegisters.Idtr.Limit + 1);\r
   VolatileRegisters.Idtr.Base = ApIdtBase;\r
+  //\r
+  // Don't pass BSP's TR to APs to avoid AP init failure.\r
+  //\r
+  VolatileRegisters.Tr = 0;\r
   CopyMem (&CpuMpData->CpuData[0].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters));\r
   //\r
   // Set BSP basic information\r
@@ -1710,7 +1723,7 @@ MpInitLibInitialize (
       //\r
       // Wakeup APs to do some AP initialize sync\r
       //\r
-      WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData);\r
+      WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData, TRUE);\r
       //\r
       // Wait for all APs finished initialization\r
       //\r
@@ -1905,7 +1918,7 @@ SwitchBSPWorker (
   //\r
   // Need to wakeUp AP (future BSP).\r
   //\r
-  WakeUpAP (CpuMpData, FALSE, ProcessorNumber, FutureBSPProc, CpuMpData);\r
+  WakeUpAP (CpuMpData, FALSE, ProcessorNumber, FutureBSPProc, CpuMpData, TRUE);\r
 \r
   AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo);\r
 \r
@@ -2211,7 +2224,7 @@ StartupAllAPsWorker (
     return EFI_NOT_STARTED;\r
   }\r
 \r
-  CpuMpData->StartCount = 0;\r
+  CpuMpData->RunningCount = 0;\r
   for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) {\r
     CpuData = &CpuMpData->CpuData[ProcessorNumber];\r
     CpuData->Waiting = FALSE;\r
@@ -2221,7 +2234,7 @@ StartupAllAPsWorker (
         // Mark this processor as responsible for current calling.\r
         //\r
         CpuData->Waiting = TRUE;\r
-        CpuMpData->StartCount++;\r
+        CpuMpData->RunningCount++;\r
       }\r
     }\r
   }\r
@@ -2230,7 +2243,6 @@ StartupAllAPsWorker (
   CpuMpData->ProcArguments = ProcedureArgument;\r
   CpuMpData->SingleThread  = SingleThread;\r
   CpuMpData->FinishedCount = 0;\r
-  CpuMpData->RunningCount  = 0;\r
   CpuMpData->FailedCpuList = FailedCpuList;\r
   CpuMpData->ExpectedTime  = CalculateTimeout (\r
                                TimeoutInMicroseconds,\r
@@ -2240,14 +2252,14 @@ StartupAllAPsWorker (
   CpuMpData->WaitEvent     = WaitEvent;\r
 \r
   if (!SingleThread) {\r
-    WakeUpAP (CpuMpData, TRUE, 0, Procedure, ProcedureArgument);\r
+    WakeUpAP (CpuMpData, TRUE, 0, Procedure, ProcedureArgument, FALSE);\r
   } else {\r
     for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) {\r
       if (ProcessorNumber == CallerNumber) {\r
         continue;\r
       }\r
       if (CpuMpData->CpuData[ProcessorNumber].Waiting) {\r
-        WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument);\r
+        WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument, TRUE);\r
         break;\r
       }\r
     }\r
@@ -2359,7 +2371,7 @@ StartupThisAPWorker (
   CpuData->ExpectedTime = CalculateTimeout (TimeoutInMicroseconds, &CpuData->CurrentTime);\r
   CpuData->TotalTime    = 0;\r
 \r
-  WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument);\r
+  WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument, TRUE);\r
 \r
   //\r
   // If WaitEvent is NULL, execute in blocking mode.\r