]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmulatorPkg/CpuRuntimeDxe/MpService.c
EmulatorPkg/MpService: Check Processor State when Set Procedure
[mirror_edk2.git] / EmulatorPkg / CpuRuntimeDxe / MpService.c
index b5b1d156c011ccc83d3e4c97c4b0c2126fac4c43..5ddd4e761ec6cae6aaac9caaf8ee3b0449d3826f 100644 (file)
@@ -28,7 +28,7 @@
   APs to help test system memory in parallel with other device initialization.\r
   Diagnostics applications may also use this protocol for multi-processor.\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\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
@@ -59,7 +59,7 @@ IsBSP (
   EFI_STATUS  Status;\r
   UINTN       ProcessorNumber;\r
 \r
-  Status = CpuMpServicesWhoAmI (&mMpSercicesTemplate, &ProcessorNumber);\r
+  Status = CpuMpServicesWhoAmI (&mMpServicesTemplate, &ProcessorNumber);\r
   if (EFI_ERROR (Status)) {\r
     return FALSE;\r
   }\r
@@ -374,7 +374,6 @@ CpuMpServicesStartupAllAps (
 {\r
   EFI_STATUS            Status;\r
   PROCESSOR_DATA_BLOCK  *ProcessorData;\r
-  UINTN                 ListIndex;\r
   UINTN                 Number;\r
   UINTN                 NextNumber;\r
   PROCESSOR_STATE       APInitialState;\r
@@ -411,7 +410,6 @@ CpuMpServicesStartupAllAps (
 \r
   Timeout = TimeoutInMicroseconds;\r
 \r
-  ListIndex                   = 0;\r
   ProcessorData               = NULL;\r
 \r
   gMPSystem.FinishCount   = 0;\r
@@ -439,17 +437,17 @@ CpuMpServicesStartupAllAps (
     // 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
+    gThread->MutexLock(ProcessorData->StateLock);\r
     if (ProcessorData->State == CPU_STATE_IDLE) {\r
-      gMPSystem.StartCount++;\r
-\r
-      gThread->MutexLock (&ProcessorData->StateLock);\r
       ProcessorData->State = APInitialState;\r
-      gThread->MutexUnlock (&ProcessorData->StateLock);\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
     }\r
   }\r
@@ -467,7 +465,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
@@ -514,11 +518,16 @@ CpuMpServicesStartupAllAps (
         if (SingleThread) {\r
           Status = GetNextBlockedNumber (&NextNumber);\r
           if (!EFI_ERROR (Status)) {\r
+            gThread->MutexLock (gMPSystem.ProcessorData[NextNumber].StateLock);\r
             gMPSystem.ProcessorData[NextNumber].State = CPU_STATE_READY;\r
+            gThread->MutexUnlock (gMPSystem.ProcessorData[NextNumber].StateLock);\r
           }\r
         }\r
 \r
+        gThread->MutexLock (ProcessorData->StateLock);\r
         ProcessorData->State = CPU_STATE_IDLE;\r
+        gThread->MutexUnlock (ProcessorData->StateLock);\r
+\r
         break;\r
 \r
       default:\r
@@ -650,7 +659,6 @@ CpuMpServicesStartupThisAP (
   OUT BOOLEAN                   *Finished               OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS      Status;\r
   INTN            Timeout;\r
 \r
   if (!IsBSP ()) {\r
@@ -669,9 +677,12 @@ CpuMpServicesStartupThisAP (
     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
     return EFI_NOT_READY;\r
   }\r
+  gThread->MutexUnlock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
 \r
   if ((WaitEvent != NULL)  && gReadToBoot) {\r
     return EFI_UNSUPPORTED;\r
@@ -685,26 +696,26 @@ CpuMpServicesStartupThisAP (
   SetApProcedure (&gMPSystem.ProcessorData[ProcessorNumber], Procedure, ProcedureArgument);\r
 \r
   if (WaitEvent != NULL) {\r
-      // Non Blocking\r
-      gMPSystem.WaitEvent = WaitEvent;\r
-      Status = gBS->SetTimer (\r
-                      gMPSystem.ProcessorData[ProcessorNumber].CheckThisAPEvent,\r
-                      TimerPeriodic,\r
-                      gPollInterval\r
-                      );\r
+    // Non Blocking\r
+    gMPSystem.WaitEvent = WaitEvent;\r
+    gBS->SetTimer (\r
+           gMPSystem.ProcessorData[ProcessorNumber].CheckThisAPEvent,\r
+           TimerPeriodic,\r
+           gPollInterval\r
+           );\r
     return EFI_SUCCESS;\r
   }\r
 \r
   // Blocking\r
   while (TRUE) {\r
-    gThread->MutexLock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+    gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
     if (gMPSystem.ProcessorData[ProcessorNumber].State == CPU_STATE_FINISHED) {\r
       gMPSystem.ProcessorData[ProcessorNumber].State = CPU_STATE_IDLE;\r
-      gThread->MutexUnlock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+      gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
       break;\r
     }\r
 \r
-    gThread->MutexUnlock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+    gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
 \r
     if ((TimeoutInMicroseconds != 0) && (Timeout < 0)) {\r
       return EFI_TIMEOUT;\r
@@ -787,9 +798,12 @@ CpuMpServicesSwitchBSP (
   }\r
   ASSERT (Index != gMPSystem.NumberOfProcessors);\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
     return EFI_NOT_READY;\r
   }\r
+  gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
 \r
   // Skip for now as we need switch a bunch of stack stuff around and it's complex\r
   // May not be worth it?\r
@@ -859,11 +873,12 @@ CpuMpServicesEnableDisableAP (
     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
     return EFI_UNSUPPORTED;\r
   }\r
-\r
-  gThread->MutexLock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+  gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
 \r
   if (EnableAP) {\r
     if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0 ) {\r
@@ -882,8 +897,6 @@ CpuMpServicesEnableDisableAP (
     gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag |= (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT);\r
   }\r
 \r
-  gThread->MutexUnlock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -939,7 +952,7 @@ CpuMpServicesWhoAmI (
 \r
 \r
 \r
-EFI_MP_SERVICES_PROTOCOL  mMpSercicesTemplate = {\r
+EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {\r
   CpuMpServicesGetNumberOfProcessors,\r
   CpuMpServicesGetProcessorInfo,\r
   CpuMpServicesStartupAllAps,\r
@@ -977,10 +990,9 @@ CpuCheckAllAPsStatus (
     gMPSystem.Timeout -= gPollInterval;\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
@@ -995,12 +1007,12 @@ 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
@@ -1013,15 +1025,17 @@ CpuCheckAllAPsStatus (
         if (!EFI_ERROR (Status)) {\r
           NextData = &gMPSystem.ProcessorData[NextNumber];\r
 \r
-          gThread->MutexLock (&NextData->ProcedureLock);\r
+          gThread->MutexLock (NextData->StateLock);\r
           NextData->State = CPU_STATE_READY;\r
-          gThread->MutexUnlock (&NextData->ProcedureLock);\r
+          gThread->MutexUnlock (NextData->StateLock);\r
 \r
           SetApProcedure (NextData, gMPSystem.Procedure, gMPSystem.ProcedureArgument);\r
         }\r
       }\r
 \r
-      gMPSystem.ProcessorData[ProcessorNumber].State = CPU_STATE_IDLE;\r
+      gThread->MutexLock (ProcessorData->StateLock);\r
+      ProcessorData->State = CPU_STATE_IDLE;\r
+      gThread->MutexUnlock (ProcessorData->StateLock);\r
       gMPSystem.FinishCount++;\r
       break;\r
 \r
@@ -1036,7 +1050,8 @@ CpuCheckAllAPsStatus (
     //\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
@@ -1047,12 +1062,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
@@ -1155,17 +1170,13 @@ FillInProcessorInformation (
   IN     UINTN                ProcessorNumber\r
   )\r
 {\r
-  PROCESSOR_DATA_BLOCK            *ProcessorData;\r
-\r
-  ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];\r
-\r
   gMPSystem.ProcessorData[ProcessorNumber].Info.ProcessorId  = gThread->Self ();\r
   gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag   = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;\r
   if (BSP) {\r
     gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;\r
   }\r
 \r
-  gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Package = ProcessorNumber;\r
+  gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Package = (UINT32) ProcessorNumber;\r
   gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Core    = 0;\r
   gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Thread  = 0;\r
   gMPSystem.ProcessorData[ProcessorNumber].State = BSP ? CPU_STATE_BUSY : CPU_STATE_IDLE;\r
@@ -1315,35 +1326,33 @@ CpuReadToBootFunction (
 \r
 EFI_STATUS\r
 CpuMpServicesInit (\r
-  VOID\r
+  OUT UINTN *MaxCpus\r
   )\r
 {\r
   EFI_STATUS              Status;\r
   EFI_HANDLE              Handle;\r
   EMU_IO_THUNK_PROTOCOL   *IoThunk;\r
-  UINTN                   MaxCpus;\r
-\r
-  MaxCpus = 1; // BSP\r
 \r
+  *MaxCpus = 1; // BSP\r
   IoThunk = GetIoThunkInstance (&gEmuThreadThunkProtocolGuid, 0);\r
   if (IoThunk != NULL) {\r
     Status = IoThunk->Open (IoThunk);\r
     if (!EFI_ERROR (Status)) {\r
       if (IoThunk->ConfigString != NULL) {\r
-        MaxCpus += StrDecimalToUintn (IoThunk->ConfigString);\r
+        *MaxCpus += StrDecimalToUintn (IoThunk->ConfigString);\r
         gThread = IoThunk->Interface;\r
       }\r
     }\r
   }\r
 \r
-  if (MaxCpus == 1) {\r
+  if (*MaxCpus == 1) {\r
     // We are not MP so nothing to do\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  gPollInterval = PcdGet64 (PcdEmuMpServicesPollingInterval);\r
+  gPollInterval = (UINTN) PcdGet64 (PcdEmuMpServicesPollingInterval);\r
 \r
-  Status  = InitializeMpSystemData (MaxCpus);\r
+  Status  = InitializeMpSystemData (*MaxCpus);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -1357,7 +1366,7 @@ CpuMpServicesInit (
   Handle = NULL;\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Handle,\r
-                  &gEfiMpServiceProtocolGuid,   &mMpSercicesTemplate,\r
+                  &gEfiMpServiceProtocolGuid,   &mMpServicesTemplate,\r
                   NULL\r
                   );\r
   return Status;\r