]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmulatorPkg/CpuRuntimeDxe/MpService.c
EmulatorPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / EmulatorPkg / CpuRuntimeDxe / MpService.c
index 536a47f7ec02d192eebbf02fc77e0dce013cfdce..42f94ada27f483a670c81c486e3a224f76dd75f3 100644 (file)
 \r
 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 Portitions Copyright (c) 2011, Apple Inc. All rights reserved.\r
-This program and the accompanying materials are licensed and made available under\r
-the terms and conditions of the BSD License that accompanies this distribution.\r
-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
@@ -111,8 +105,31 @@ GetNextBlockedNumber (
   return EFI_NOT_FOUND;\r
 }\r
 \r
+/**\r
+ * Calculated and stalled the interval time by BSP to check whether\r
+ * the APs have finished.\r
+ *\r
+ * @param[in]  Timeout    The time limit in microseconds for\r
+ *                        APs to return from Procedure.\r
+ *\r
+ * @retval     StallTime  Time of execution stall.\r
+**/\r
+UINTN\r
+CalculateAndStallInterval (\r
+  IN UINTN                  Timeout\r
+  )\r
+{\r
+  UINTN                 StallTime;\r
 \r
+  if (Timeout < gPollInterval && Timeout != 0) {\r
+    StallTime = Timeout;\r
+  } else {\r
+    StallTime = gPollInterval;\r
+  }\r
+  gBS->Stall (StallTime);\r
 \r
+  return StallTime;\r
+}\r
 \r
 /**\r
   This service retrieves the number of logical processor in the platform\r
@@ -378,7 +395,7 @@ CpuMpServicesStartupAllAps (
   UINTN                 NextNumber;\r
   PROCESSOR_STATE       APInitialState;\r
   PROCESSOR_STATE       ProcessorState;\r
-  INTN                  Timeout;\r
+  UINTN                 Timeout;\r
 \r
 \r
   if (!IsBSP ()) {\r
@@ -397,6 +414,24 @@ CpuMpServicesStartupAllAps (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {\r
+    ProcessorData = &gMPSystem.ProcessorData[Number];\r
+    if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
+      // Skip BSP\r
+      continue;\r
+    }\r
+\r
+    if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {\r
+      // Skip Disabled processors\r
+      continue;\r
+    }\r
+    gThread->MutexLock(ProcessorData->StateLock);\r
+    if (ProcessorData->State != CPU_STATE_IDLE) {\r
+      gThread->MutexUnlock (ProcessorData->StateLock);\r
+      return EFI_NOT_READY;\r
+    }\r
+    gThread->MutexUnlock(ProcessorData->StateLock);\r
+  }\r
 \r
   if (FailedCpuList != NULL) {\r
     gMPSystem.FailedList = AllocatePool ((gMPSystem.NumberOfProcessors + 1) * sizeof (UINTN));\r
@@ -438,17 +473,13 @@ CpuMpServicesStartupAllAps (
     // if not "SingleThread", all APs are put to ready state from the beginning\r
     //\r
     gThread->MutexLock(ProcessorData->StateLock);\r
-    if (ProcessorData->State == CPU_STATE_IDLE) {\r
-      ProcessorData->State = APInitialState;\r
-      gThread->MutexUnlock (ProcessorData->StateLock);\r
+    ASSERT (ProcessorData->State == CPU_STATE_IDLE);\r
+    ProcessorData->State = APInitialState;\r
+    gThread->MutexUnlock (ProcessorData->StateLock);\r
 \r
-      gMPSystem.StartCount++;\r
-      if (SingleThread) {\r
-        APInitialState = CPU_STATE_BLOCKED;\r
-      }\r
-    } else {\r
-      gThread->MutexUnlock (ProcessorData->StateLock);\r
-      return EFI_NOT_READY;\r
+    gMPSystem.StartCount++;\r
+    if (SingleThread) {\r
+      APInitialState = CPU_STATE_BLOCKED;\r
     }\r
   }\r
 \r
@@ -465,7 +496,13 @@ CpuMpServicesStartupAllAps (
         continue;\r
       }\r
 \r
-      SetApProcedure (ProcessorData, Procedure, ProcedureArgument);\r
+      gThread->MutexLock (ProcessorData->StateLock);\r
+      ProcessorState = ProcessorData->State;\r
+      gThread->MutexUnlock (ProcessorData->StateLock);\r
+\r
+      if (ProcessorState == CPU_STATE_READY) {\r
+        SetApProcedure (ProcessorData, Procedure, ProcedureArgument);\r
+      }\r
     }\r
 \r
     //\r
@@ -534,13 +571,12 @@ CpuMpServicesStartupAllAps (
       goto Done;\r
     }\r
 \r
-    if ((TimeoutInMicroseconds != 0) && (Timeout < 0)) {\r
+    if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {\r
       Status = EFI_TIMEOUT;\r
       goto Done;\r
     }\r
 \r
-    gBS->Stall (gPollInterval);\r
-    Timeout -= gPollInterval;\r
+    Timeout -= CalculateAndStallInterval (Timeout);\r
   }\r
 \r
 Done:\r
@@ -653,7 +689,7 @@ CpuMpServicesStartupThisAP (
   OUT BOOLEAN                   *Finished               OPTIONAL\r
   )\r
 {\r
-  INTN            Timeout;\r
+  UINTN            Timeout;\r
 \r
   if (!IsBSP ()) {\r
     return EFI_DEVICE_ERROR;\r
@@ -671,6 +707,10 @@ CpuMpServicesStartupThisAP (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   gThread->MutexLock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
   if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {\r
     gThread->MutexUnlock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
@@ -711,12 +751,11 @@ CpuMpServicesStartupThisAP (
 \r
     gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
 \r
-    if ((TimeoutInMicroseconds != 0) && (Timeout < 0)) {\r
+    if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {\r
       return EFI_TIMEOUT;\r
     }\r
 \r
-    gBS->Stall (gPollInterval);\r
-    Timeout -= gPollInterval;\r
+    Timeout -= CalculateAndStallInterval (Timeout);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -981,13 +1020,12 @@ CpuCheckAllAPsStatus (
   BOOLEAN               Found;\r
 \r
   if (gMPSystem.TimeoutActive) {\r
-    gMPSystem.Timeout -= gPollInterval;\r
+    gMPSystem.Timeout -= CalculateAndStallInterval (gMPSystem.Timeout);\r
   }\r
 \r
-  ProcessorData = (PROCESSOR_DATA_BLOCK *) Context;\r
-\r
   for (ProcessorNumber = 0; ProcessorNumber < gMPSystem.NumberOfProcessors; ProcessorNumber++) {\r
-    if ((ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
+    ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];\r
+    if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
      // Skip BSP\r
       continue;\r
     }\r
@@ -1002,18 +1040,14 @@ CpuCheckAllAPsStatus (
     // context. Meaning deadlock. Which is a bad thing.\r
     // So, try lock it. If we can get it, cool, do our thing.\r
     // otherwise, just dump out & try again on the next iteration.\r
-    Status = gThread->MutexTryLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+    Status = gThread->MutexTryLock (ProcessorData->StateLock);\r
     if (EFI_ERROR(Status)) {\r
       return;\r
     }\r
-    ProcessorState = gMPSystem.ProcessorData[ProcessorNumber].State;\r
-    gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+    ProcessorState = ProcessorData->State;\r
+    gThread->MutexUnlock (ProcessorData->StateLock);\r
 \r
     switch (ProcessorState) {\r
-    case CPU_STATE_READY:\r
-      SetApProcedure (ProcessorData, gMPSystem.Procedure, gMPSystem.ProcedureArgument);\r
-      break;\r
-\r
     case CPU_STATE_FINISHED:\r
       if (gMPSystem.SingleThread) {\r
         Status = GetNextBlockedNumber (&NextNumber);\r
@@ -1028,9 +1062,9 @@ CpuCheckAllAPsStatus (
         }\r
       }\r
 \r
-      gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
-      gMPSystem.ProcessorData[ProcessorNumber].State = CPU_STATE_IDLE;\r
-      gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+      gThread->MutexLock (ProcessorData->StateLock);\r
+      ProcessorData->State = CPU_STATE_IDLE;\r
+      gThread->MutexUnlock (ProcessorData->StateLock);\r
       gMPSystem.FinishCount++;\r
       break;\r
 \r
@@ -1039,13 +1073,14 @@ CpuCheckAllAPsStatus (
     }\r
   }\r
 \r
-  if (gMPSystem.TimeoutActive && gMPSystem.Timeout < 0) {\r
+  if (gMPSystem.TimeoutActive && gMPSystem.Timeout == 0) {\r
     //\r
     // Timeout\r
     //\r
     if (gMPSystem.FailedList != NULL) {\r
       for (ProcessorNumber = 0; ProcessorNumber < gMPSystem.NumberOfProcessors; ProcessorNumber++) {\r
-        if ((ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
+        ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];\r
+        if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
          // Skip BSP\r
           continue;\r
         }\r
@@ -1056,12 +1091,12 @@ CpuCheckAllAPsStatus (
         }\r
 \r
         // Mark the\r
-        Status = gThread->MutexTryLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+        Status = gThread->MutexTryLock (ProcessorData->StateLock);\r
         if (EFI_ERROR(Status)) {\r
           return;\r
         }\r
-        ProcessorState = gMPSystem.ProcessorData[ProcessorNumber].State;\r
-        gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+        ProcessorState = ProcessorData->State;\r
+        gThread->MutexUnlock (ProcessorData->StateLock);\r
 \r
         if (ProcessorState != CPU_STATE_IDLE) {\r
           // If we are retrying make sure we don't double count\r