UefiCpuPkg/CpuDxe: Consume MpInitLib to produce CPU MP Protocol services
authorJeff Fan <jeff.fan@intel.com>
Fri, 22 Jul 2016 02:42:47 +0000 (10:42 +0800)
committerJeff Fan <jeff.fan@intel.com>
Wed, 17 Aug 2016 12:06:56 +0000 (20:06 +0800)
Consume MP Initialize library to produce CPU MP Protocol services to simply the
code.

v4:
  1. Update CpuDxe.c file header to mention it produces CPU Arch protocol.
  2. Update BistData type from UINT32 to EFI_HEALTH_FLAG.
  3. Move some header location from CpuMp.h to CpuDxe.h.

v3:
  1. Move the code Consume MpInitLib APIs to produce CPU MP Protocol from patch
     #40 to this patch.
  2. Add DxeMpInitLib.inf in DSC file

Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Michael Kinney <michael.d.kinney@intel.com>
UefiCpuPkg/CpuDxe/CpuDxe.c
UefiCpuPkg/CpuDxe/CpuDxe.h
UefiCpuPkg/CpuDxe/CpuDxe.inf
UefiCpuPkg/CpuDxe/CpuDxe.uni
UefiCpuPkg/CpuDxe/CpuDxeExtra.uni
UefiCpuPkg/CpuDxe/CpuMp.c
UefiCpuPkg/CpuDxe/CpuMp.h
UefiCpuPkg/UefiCpuPkg.dsc

index 78b2c880958f40e318893d00c9b56e49a062553b..1b94290dd50891006a3819528b84b680e817ecff 100644 (file)
@@ -1,5 +1,5 @@
 /** @file\r
-  CPU DXE Module.\r
+  CPU DXE Module to produce CPU ARCH Protocol.\r
 \r
   Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
index 2aef626cd51eb243507524fd1a81e27ec138b5d2..00d1a8f130c39b32c5c6cb3e7d8e7ee3425763cc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
-  CPU DXE Module.\r
+  CPU DXE Module to produce CPU ARCH Protocol and CPU MP Protocol.\r
 \r
-  Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2016, 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
 #include <PiDxe.h>\r
 \r
 #include <Protocol/Cpu.h>\r
+#include <Protocol/MpService.h>\r
+\r
+#include <Ppi/SecPlatformInformation.h>\r
+#include <Ppi/SecPlatformInformation2.h>\r
 \r
 #include <Library/UefiDriverEntryPoint.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiLib.h>\r
 #include <Library/CpuExceptionHandlerLib.h>\r
 #include <Library/TimerLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/MpInitLib.h>\r
+\r
 #include <Guid/IdleLoopEvent.h>\r
 #include <Guid/VectorHandoffTable.h>\r
 \r
index bdff548cc2728306ee0e9d653287075fa8e4c7cb..0643bec5d28a3c5b021a0a9d67c1c718cd416c46 100644 (file)
@@ -1,5 +1,5 @@
 ## @file\r
-#  Simple CPU driver installs CPU Architecture Protocol.\r
+#  CPU driver installs CPU Architecture Protocol and CPU MP protocol.\r
 #\r
 #  Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
 #  This program and the accompanying materials\r
   UefiCpuLib\r
   UefiLib\r
   CpuExceptionHandlerLib\r
-  TimerLib\r
-  SynchronizationLib\r
   HobLib\r
   ReportStatusCodeLib\r
+  MpInitLib\r
 \r
 [Sources]\r
   ApStartup.c\r
@@ -71,7 +70,7 @@
 \r
 [Protocols]\r
   gEfiCpuArchProtocolGuid                       ## PRODUCES\r
-  gEfiMpServiceProtocolGuid                     ## SOMETIMES_PRODUCES\r
+  gEfiMpServiceProtocolGuid                     ## PRODUCES\r
 \r
 [Guids]\r
   gIdleLoopEventGuid                            ## CONSUMES           ## Event\r
index 5ac78100fb0e1abf5903d6d642709cfe3734598d..caf01dcbf5fedbb99863c7d35bb2e43a7f974d66 100644 (file)
@@ -1,9 +1,9 @@
 // /** @file\r
-// Simple CPU driver installs CPU Architecture Protocol.\r
+// CPU driver installs CPU Architecture Protocol and CPU MP Protocol.\r
 //\r
-// Simple CPU driver installs CPU Architecture Protocol.\r
+// CPU driver installs CPU Architecture Protocol and CPU MP Protocol.\r
 //\r
-// Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
+// Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
 //\r
 // This program and the accompanying materials\r
 // are licensed and made available under the terms and conditions of the BSD License\r
@@ -16,7 +16,7 @@
 // **/\r
 \r
 \r
-#string STR_MODULE_ABSTRACT             #language en-US "Installs CPU Architecture Protocol"\r
+#string STR_MODULE_ABSTRACT             #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol."\r
 \r
-#string STR_MODULE_DESCRIPTION          #language en-US "Simple CPU driver installs CPU Architecture Protocol."\r
+#string STR_MODULE_DESCRIPTION          #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol."\r
 \r
index fbfc2e1fb257eb10362dbe1841b53fa030bb6d36..c1d201911c72ff5309d11ac92d3c861c7b3338cc 100644 (file)
@@ -1,7 +1,7 @@
 // /** @file\r
 // CpuDxe Localized Strings and Content\r
 //\r
-// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>\r
+// Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>\r
 //\r
 // This program and the accompanying materials\r
 // are licensed and made available under the terms and conditions of the BSD License\r
@@ -15,6 +15,6 @@
 \r
 #string STR_PROPERTIES_MODULE_NAME \r
 #language en-US \r
-"CPU Architectural DXE Driver"\r
+"CPU Architectural and CPU Multi-processor DXE Driver"\r
 \r
 \r
index 98fdfdf5e0e7b9bdc2c96cf47a9811bff44e53ce..38603f9867cebd635350ddfb7217691cf884589e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
-  CPU DXE Module.\r
+  CPU DXE Module to produce CPU MP Protocol.\r
 \r
-  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2016, 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
@@ -21,6 +21,7 @@ UINTN gPollInterval = 100; // 100 microseconds
 \r
 MP_SYSTEM_DATA mMpSystemData;\r
 EFI_HANDLE     mMpServiceHandle       = NULL;\r
+UINTN          mNumberOfProcessors    = 1;\r
 EFI_EVENT      mExitBootServicesEvent = (EFI_EVENT)NULL;\r
 \r
 VOID *mCommonStack = 0;\r
@@ -28,7 +29,6 @@ VOID *mTopOfApCommonStack = 0;
 VOID *mApStackStart = 0;\r
 \r
 volatile BOOLEAN mAPsAlreadyInitFinished = FALSE;\r
-volatile BOOLEAN mStopCheckAllAPsStatus = TRUE;\r
 \r
 EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {\r
   GetNumberOfProcessors,\r
@@ -102,6 +102,7 @@ IsBSP (
   @retval  CPU_STATE  the AP status\r
 \r
 **/\r
+STATIC\r
 CPU_STATE\r
 GetApState (\r
   IN  CPU_DATA_BLOCK  *CpuData\r
@@ -123,6 +124,7 @@ GetApState (
   @param   State      The AP status\r
 \r
 **/\r
+STATIC\r
 VOID\r
 SetApState (\r
   IN  CPU_DATA_BLOCK   *CpuData,\r
@@ -452,13 +454,10 @@ GetNumberOfProcessors (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (!IsBSP ()) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  *NumberOfProcessors        = mMpSystemData.NumberOfProcessors;\r
-  *NumberOfEnabledProcessors = mMpSystemData.NumberOfEnabledProcessors;\r
-  return EFI_SUCCESS;\r
+  return MpInitLibGetNumberOfProcessors (\r
+           NumberOfProcessors,\r
+           NumberOfEnabledProcessors\r
+           );\r
 }\r
 \r
 /**\r
@@ -495,20 +494,7 @@ GetProcessorInfo (
   OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer\r
   )\r
 {\r
-  if (ProcessorInfoBuffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (!IsBSP ()) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  CopyMem (ProcessorInfoBuffer, &mMpSystemData.CpuDatas[ProcessorNumber], sizeof (EFI_PROCESSOR_INFORMATION));\r
-  return EFI_SUCCESS;\r
+  return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);\r
 }\r
 \r
 /**\r
@@ -659,155 +645,14 @@ StartupAllAPs (
   OUT UINTN                     **FailedCpuList         OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  CPU_DATA_BLOCK        *CpuData;\r
-  UINTN                 Number;\r
-  CPU_STATE             APInitialState;\r
-  CPU_STATE             CpuState;\r
-\r
-  CpuData = NULL;\r
-\r
-  if (FailedCpuList != NULL) {\r
-    *FailedCpuList = NULL;\r
-  }\r
-\r
-  if (!IsBSP ()) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (mMpSystemData.NumberOfProcessors == 1) {\r
-    return EFI_NOT_STARTED;\r
-  }\r
-\r
-  if (Procedure == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // temporarily stop checkAllAPsStatus for avoid resource dead-lock.\r
-  //\r
-  mStopCheckAllAPsStatus = TRUE;\r
-\r
-  for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {\r
-    CpuData = &mMpSystemData.CpuDatas[Number];\r
-    if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {\r
-      //\r
-      // Skip BSP\r
-      //\r
-      continue;\r
-    }\r
-\r
-    if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {\r
-      //\r
-      // Skip Disabled processors\r
-      //\r
-      continue;\r
-    }\r
-\r
-    CpuState = GetApState (CpuData);\r
-    if (CpuState != CpuStateIdle &&\r
-        CpuState != CpuStateSleeping) {\r
-      return EFI_NOT_READY;\r
-    }\r
-  }\r
-\r
-  mMpSystemData.Procedure         = Procedure;\r
-  mMpSystemData.ProcedureArgument = ProcedureArgument;\r
-  mMpSystemData.WaitEvent         = WaitEvent;\r
-  mMpSystemData.Timeout           = TimeoutInMicroseconds;\r
-  mMpSystemData.TimeoutActive     = (BOOLEAN) (TimeoutInMicroseconds != 0);\r
-  mMpSystemData.FinishCount       = 0;\r
-  mMpSystemData.StartCount        = 0;\r
-  mMpSystemData.SingleThread      = SingleThread;\r
-  mMpSystemData.FailedList        = FailedCpuList;\r
-  mMpSystemData.FailedListIndex   = 0;\r
-  APInitialState                  = CpuStateReady;\r
-\r
-  for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {\r
-    CpuData = &mMpSystemData.CpuDatas[Number];\r
-    if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {\r
-      //\r
-      // Skip BSP\r
-      //\r
-      continue;\r
-    }\r
-\r
-    if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {\r
-      //\r
-      // Skip Disabled processors\r
-      //\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Get APs prepared, and put failing APs into FailedCpuList\r
-    // if "SingleThread", only 1 AP will put to ready state, other AP will be put to ready\r
-    // 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
-    CpuState = GetApState (CpuData);\r
-    if (CpuState == CpuStateIdle ||\r
-        CpuState == CpuStateSleeping) {\r
-      mMpSystemData.StartCount++;\r
-\r
-      SetApState (CpuData, APInitialState);\r
-\r
-      if (APInitialState == CpuStateReady) {\r
-        SetApProcedure (CpuData, Procedure, ProcedureArgument);\r
-        //\r
-        // If this AP previous state is Sleeping, we should\r
-        // wake up this AP by sent a SIPI. and avoid\r
-        // re-involve the sleeping state. we must call\r
-        // SetApProcedure() first.\r
-        //\r
-        if (CpuState == CpuStateSleeping) {\r
-          ResetProcessorToIdleState (CpuData);\r
-        }\r
-      }\r
-\r
-      if (SingleThread) {\r
-        APInitialState = CpuStateBlocked;\r
-      }\r
-    }\r
-  }\r
-\r
-  mStopCheckAllAPsStatus = FALSE;\r
-\r
-  if (WaitEvent != NULL) {\r
-    //\r
-    // non blocking\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Blocking temporarily stop CheckAllAPsStatus()\r
-  //\r
-  mStopCheckAllAPsStatus = TRUE;\r
-\r
-  while (TRUE) {\r
-    CheckAndUpdateAllAPsToIdleState ();\r
-    if (mMpSystemData.FinishCount == mMpSystemData.StartCount) {\r
-      Status = EFI_SUCCESS;\r
-      goto Done;\r
-    }\r
-\r
-    //\r
-    // task timeout\r
-    //\r
-    if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {\r
-      ResetAllFailedAPs();\r
-      Status = EFI_TIMEOUT;\r
-      goto Done;\r
-    }\r
-\r
-    MicroSecondDelay (gPollInterval);\r
-    mMpSystemData.Timeout -= gPollInterval;\r
-  }\r
-\r
-Done:\r
-\r
-  return Status;\r
+  return MpInitLibStartupAllAPs (\r
+           Procedure,\r
+           SingleThread,\r
+           WaitEvent,\r
+           TimeoutInMicroseconds,\r
+           ProcedureArgument,\r
+           FailedCpuList\r
+           );\r
 }\r
 \r
 /**\r
@@ -908,90 +753,14 @@ StartupThisAP (
   OUT BOOLEAN                   *Finished               OPTIONAL\r
   )\r
 {\r
-  CPU_DATA_BLOCK        *CpuData;\r
-  CPU_STATE             CpuState;\r
-\r
-  CpuData = NULL;\r
-\r
-  if (Finished != NULL) {\r
-    *Finished = FALSE;\r
-  }\r
-\r
-  if (!IsBSP ()) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (Procedure == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // temporarily stop checkAllAPsStatus for avoid resource dead-lock.\r
-  //\r
-  mStopCheckAllAPsStatus = TRUE;\r
-\r
-  CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
-  if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT) ||\r
-      !TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  CpuState = GetApState (CpuData);\r
-  if (CpuState != CpuStateIdle &&\r
-      CpuState != CpuStateSleeping) {\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  SetApState (CpuData, CpuStateReady);\r
-\r
-  SetApProcedure (CpuData, Procedure, ProcedureArgument);\r
-  //\r
-  // If this AP previous state is Sleeping, we should\r
-  // wake up this AP by sent a SIPI. and avoid\r
-  // re-involve the sleeping state. we must call\r
-  // SetApProcedure() first.\r
-  //\r
-  if (CpuState == CpuStateSleeping) {\r
-    ResetProcessorToIdleState (CpuData);\r
-  }\r
-\r
-  CpuData->Timeout = TimeoutInMicroseconds;\r
-  CpuData->WaitEvent = WaitEvent;\r
-  CpuData->TimeoutActive = (BOOLEAN) (TimeoutInMicroseconds != 0);\r
-  CpuData->Finished = Finished;\r
-\r
-  mStopCheckAllAPsStatus = FALSE;\r
-\r
-  if (WaitEvent != NULL) {\r
-    //\r
-    // Non Blocking\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Blocking\r
-  //\r
-  while (TRUE) {\r
-    if (GetApState (CpuData) == CpuStateFinished) {\r
-      SetApState (CpuData, CpuStateIdle);\r
-      break;\r
-    }\r
-\r
-    if (CpuData->TimeoutActive && CpuData->Timeout < 0) {\r
-      ResetProcessorToIdleState (CpuData);\r
-      return EFI_TIMEOUT;\r
-    }\r
-\r
-    MicroSecondDelay (gPollInterval);\r
-    CpuData->Timeout -= gPollInterval;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
+  return MpInitLibStartupThisAP (\r
+           Procedure,\r
+           ProcessorNumber,\r
+           WaitEvent,\r
+           TimeoutInMicroseconds,\r
+           ProcedureArgument,\r
+           Finished\r
+           );\r
 }\r
 \r
 /**\r
@@ -1037,10 +806,7 @@ SwitchBSP (
   IN  BOOLEAN                  EnableOldBSP\r
   )\r
 {\r
-   //\r
-   // Current always return unsupported.\r
-   //\r
-   return EFI_UNSUPPORTED;\r
+  return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);\r
 }\r
 \r
 /**\r
@@ -1093,62 +859,7 @@ EnableDisableAP (
   IN  UINT32                    *HealthFlag OPTIONAL\r
   )\r
 {\r
-  CPU_DATA_BLOCK *CpuData;\r
-  BOOLEAN        TempStopCheckState;\r
-  CPU_STATE      CpuState;\r
-\r
-  CpuData = NULL;\r
-  TempStopCheckState = FALSE;\r
-\r
-  if (!IsBSP ()) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // temporarily stop checkAllAPsStatus for initialize parameters.\r
-  //\r
-  if (!mStopCheckAllAPsStatus) {\r
-    mStopCheckAllAPsStatus = TRUE;\r
-    TempStopCheckState = TRUE;\r
-  }\r
-\r
-  CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
-  if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  CpuState = GetApState (CpuData);\r
-  if (CpuState != CpuStateIdle &&\r
-      CpuState != CpuStateSleeping) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  if (EnableAP) {\r
-    if (!(TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT))) {\r
-      mMpSystemData.NumberOfEnabledProcessors++;\r
-    }\r
-    CpuStatusFlagOr (CpuData, PROCESSOR_ENABLED_BIT);\r
-  } else {\r
-    if (TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {\r
-      mMpSystemData.NumberOfEnabledProcessors--;\r
-    }\r
-    CpuStatusFlagAndNot (CpuData, PROCESSOR_ENABLED_BIT);\r
-  }\r
-\r
-  if (HealthFlag != NULL) {\r
-    CpuStatusFlagAndNot (CpuData, (UINT32)~PROCESSOR_HEALTH_STATUS_BIT);\r
-    CpuStatusFlagOr (CpuData, (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT));\r
-  }\r
-\r
-  if (TempStopCheckState) {\r
-    mStopCheckAllAPsStatus = FALSE;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
+  return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);\r
 }\r
 \r
 /**\r
@@ -1182,383 +893,7 @@ WhoAmI (
   OUT UINTN                    *ProcessorNumber\r
   )\r
 {\r
-  UINTN   Index;\r
-  UINT32  ProcessorId;\r
-\r
-  if (ProcessorNumber == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  ProcessorId = GetApicId ();\r
-  for (Index = 0; Index < mMpSystemData.NumberOfProcessors; Index++) {\r
-    if (mMpSystemData.CpuDatas[Index].Info.ProcessorId == ProcessorId) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  *ProcessorNumber = Index;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Terminate AP's task and set it to idle state.\r
-\r
-  This function terminates AP's task due to timeout by sending INIT-SIPI,\r
-  and sends it to idle state.\r
-\r
-  @param CpuData           the pointer to CPU_DATA_BLOCK of specified AP\r
-\r
-**/\r
-VOID\r
-ResetProcessorToIdleState (\r
-  IN CPU_DATA_BLOCK  *CpuData\r
-  )\r
-{\r
-  ResetApStackless ((UINT32)CpuData->Info.ProcessorId);\r
-}\r
-\r
-/**\r
-  Application Processors do loop routine\r
-  after switch to its own stack.\r
-\r
-  @param  Context1    A pointer to the context to pass into the function.\r
-  @param  Context2    A pointer to the context to pass into the function.\r
-\r
-**/\r
-VOID\r
-ProcessorToIdleState (\r
-  IN      VOID                      *Context1,  OPTIONAL\r
-  IN      VOID                      *Context2   OPTIONAL\r
-  )\r
-{\r
-  UINTN                 ProcessorNumber;\r
-  CPU_DATA_BLOCK        *CpuData;\r
-  EFI_AP_PROCEDURE      Procedure;\r
-  volatile VOID         *ProcedureArgument;\r
-\r
-  AsmApDoneWithCommonStack ();\r
-\r
-  while (!mAPsAlreadyInitFinished) {\r
-    CpuPause ();\r
-  }\r
-\r
-  WhoAmI (&mMpServicesTemplate, &ProcessorNumber);\r
-  CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
-\r
-  //\r
-  // Avoid forcibly reset AP caused the AP got lock not release.\r
-  //\r
-  if (CpuData->LockSelf == (INTN) GetApicId ()) {\r
-    ReleaseSpinLock (&CpuData->CpuDataLock);\r
-  }\r
-\r
-  //\r
-  // Avoid forcibly reset AP caused the timeout AP State is not\r
-  // updated.\r
-  //\r
-  GetMpSpinLock (CpuData);\r
-  if (CpuData->State == CpuStateBusy) {\r
-    CpuData->Procedure = NULL;\r
-  }\r
-  CpuData->State = CpuStateIdle;\r
-  ReleaseMpSpinLock (CpuData);\r
-\r
-  while (TRUE) {\r
-    GetMpSpinLock (CpuData);\r
-    ProcedureArgument = CpuData->Parameter;\r
-    Procedure = CpuData->Procedure;\r
-    ReleaseMpSpinLock (CpuData);\r
-\r
-    if (Procedure != NULL) {\r
-      SetApState (CpuData, CpuStateBusy);\r
-\r
-      Procedure ((VOID*) ProcedureArgument);\r
-\r
-      GetMpSpinLock (CpuData);\r
-      CpuData->Procedure = NULL;\r
-      CpuData->State = CpuStateFinished;\r
-      ReleaseMpSpinLock (CpuData);\r
-    } else {\r
-      //\r
-      // if no procedure to execution, we simply put AP\r
-      // into sleeping state, and waiting BSP sent SIPI.\r
-      //\r
-      GetMpSpinLock (CpuData);\r
-      if (CpuData->State == CpuStateIdle) {\r
-          CpuData->State = CpuStateSleeping;\r
-      }\r
-      ReleaseMpSpinLock (CpuData);\r
-    }\r
-\r
-    if (GetApState (CpuData) == CpuStateSleeping) {\r
-      CpuSleep ();\r
-    }\r
-\r
-    CpuPause ();\r
-  }\r
-\r
-  CpuSleep ();\r
-  CpuDeadLoop ();\r
-}\r
-\r
-/**\r
-  Checks AP' status periodically.\r
-\r
-  This function is triggerred by timer perodically to check the\r
-  state of AP forStartupThisAP() executed in non-blocking mode.\r
-\r
-  @param  Event    Event triggered.\r
-  @param  Context  Parameter passed with the event.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-CheckThisAPStatus (\r
-  IN  EFI_EVENT        Event,\r
-  IN  VOID             *Context\r
-  )\r
-{\r
-  CPU_DATA_BLOCK  *CpuData;\r
-  CPU_STATE       CpuState;\r
-\r
-  CpuData = (CPU_DATA_BLOCK *) Context;\r
-  if (CpuData->TimeoutActive) {\r
-    CpuData->Timeout -= gPollInterval;\r
-  }\r
-\r
-  CpuState = GetApState (CpuData);\r
-\r
-  if (CpuState == CpuStateFinished) {\r
-    if (CpuData->Finished) {\r
-      *CpuData->Finished = TRUE;\r
-    }\r
-    SetApState (CpuData, CpuStateIdle);\r
-    goto out;\r
-  }\r
-\r
-  if (CpuData->TimeoutActive && CpuData->Timeout < 0) {\r
-    if (CpuState != CpuStateIdle &&\r
-        CpuData->Finished) {\r
-      *CpuData->Finished = FALSE;\r
-    }\r
-    ResetProcessorToIdleState (CpuData);\r
-    goto out;\r
-  }\r
-\r
-  return;\r
-\r
-out:\r
-  CpuData->TimeoutActive = FALSE;\r
-  gBS->SignalEvent (CpuData->WaitEvent);\r
-  CpuData->WaitEvent = NULL;\r
-}\r
-\r
-/**\r
-  Checks APs' status periodically.\r
-\r
-  This function is triggerred by timer perodically to check the\r
-  state of APs for StartupAllAPs() executed in non-blocking mode.\r
-\r
-  @param  Event    Event triggered.\r
-  @param  Context  Parameter passed with the event.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-CheckAllAPsStatus (\r
-  IN  EFI_EVENT        Event,\r
-  IN  VOID             *Context\r
-  )\r
-{\r
-  CPU_DATA_BLOCK *CpuData;\r
-  UINTN          Number;\r
-  EFI_STATUS     Status;\r
-\r
-  if (mMpSystemData.TimeoutActive) {\r
-    mMpSystemData.Timeout -= gPollInterval;\r
-  }\r
-\r
-  if (mStopCheckAllAPsStatus) {\r
-    return;\r
-  }\r
-\r
-  //\r
-  // avoid next timer enter.\r
-  //\r
-  Status = gBS->SetTimer (\r
-                  mMpSystemData.CheckAllAPsEvent,\r
-                  TimerCancel,\r
-                  0\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  if (mMpSystemData.WaitEvent != NULL) {\r
-    CheckAndUpdateAllAPsToIdleState ();\r
-    //\r
-    // task timeout\r
-    //\r
-    if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {\r
-      ResetAllFailedAPs();\r
-      //\r
-      // force exit\r
-      //\r
-      mMpSystemData.FinishCount = mMpSystemData.StartCount;\r
-    }\r
-\r
-    if (mMpSystemData.FinishCount != mMpSystemData.StartCount) {\r
-      goto EXIT;\r
-    }\r
-\r
-    mMpSystemData.TimeoutActive = FALSE;\r
-    gBS->SignalEvent (mMpSystemData.WaitEvent);\r
-    mMpSystemData.WaitEvent = NULL;\r
-    mStopCheckAllAPsStatus = TRUE;\r
-\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // check each AP status for StartupThisAP\r
-  //\r
-  for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {\r
-    CpuData = &mMpSystemData.CpuDatas[Number];\r
-    if (CpuData->WaitEvent) {\r
-      CheckThisAPStatus (NULL, (VOID *)CpuData);\r
-    }\r
-  }\r
-\r
-EXIT:\r
-  Status = gBS->SetTimer (\r
-                  mMpSystemData.CheckAllAPsEvent,\r
-                  TimerPeriodic,\r
-                  EFI_TIMER_PERIOD_MICROSECONDS (100)\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-}\r
-\r
-/**\r
-  Application Processor C code entry point.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ApEntryPointInC (\r
-  VOID\r
-  )\r
-{\r
-  VOID*           TopOfApStack;\r
-  UINTN           ProcessorNumber;\r
-\r
-  if (!mAPsAlreadyInitFinished) {\r
-    FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);\r
-    TopOfApStack  = (UINT8*)mApStackStart + gApStackSize;\r
-    mApStackStart = TopOfApStack;\r
-\r
-    //\r
-    // Store the Stack address, when reset the AP, We can found the original address.\r
-    //\r
-    mMpSystemData.CpuDatas[mMpSystemData.NumberOfProcessors].TopOfStack = TopOfApStack;\r
-    mMpSystemData.NumberOfProcessors++;\r
-    mMpSystemData.NumberOfEnabledProcessors++;\r
-  } else {\r
-    WhoAmI (&mMpServicesTemplate, &ProcessorNumber);\r
-    //\r
-    // Get the original stack address.\r
-    //\r
-    TopOfApStack = mMpSystemData.CpuDatas[ProcessorNumber].TopOfStack;\r
-  }\r
-\r
-  SwitchStack (\r
-    (SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState,\r
-    NULL,\r
-    NULL,\r
-    TopOfApStack);\r
-}\r
-\r
-/**\r
-  This function is called by all processors (both BSP and AP) once and collects MP related data.\r
-\r
-  @param Bsp             TRUE if the CPU is BSP\r
-  @param ProcessorNumber The specific processor number\r
-\r
-  @retval EFI_SUCCESS    Data for the processor collected and filled in\r
-\r
-**/\r
-EFI_STATUS\r
-FillInProcessorInformation (\r
-  IN     BOOLEAN              Bsp,\r
-  IN     UINTN                ProcessorNumber\r
-  )\r
-{\r
-  CPU_DATA_BLOCK  *CpuData;\r
-  UINT32          ProcessorId;\r
-\r
-  CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
-  ProcessorId  = GetApicId ();\r
-  CpuData->Info.ProcessorId  = ProcessorId;\r
-  CpuData->Info.StatusFlag   = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;\r
-  if (Bsp) {\r
-    CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;\r
-  }\r
-  CpuData->Info.Location.Package = ProcessorId;\r
-  CpuData->Info.Location.Core    = 0;\r
-  CpuData->Info.Location.Thread  = 0;\r
-  CpuData->State = Bsp ? CpuStateBusy : CpuStateIdle;\r
-\r
-  CpuData->Procedure        = NULL;\r
-  CpuData->Parameter        = NULL;\r
-  InitializeSpinLock (&CpuData->CpuDataLock);\r
-  CpuData->LockSelf         = -1;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Prepare the System Data.\r
-\r
-  @retval EFI_SUCCESS     the System Data finished initilization.\r
-\r
-**/\r
-EFI_STATUS\r
-InitMpSystemData (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS     Status;\r
-\r
-  ZeroMem (&mMpSystemData, sizeof (MP_SYSTEM_DATA));\r
-\r
-  mMpSystemData.NumberOfProcessors = 1;\r
-  mMpSystemData.NumberOfEnabledProcessors = 1;\r
-\r
-  mMpSystemData.CpuDatas = AllocateZeroPool (sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber);\r
-  ASSERT(mMpSystemData.CpuDatas != NULL);\r
-\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  CheckAllAPsStatus,\r
-                  NULL,\r
-                  &mMpSystemData.CheckAllAPsEvent\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Set timer to check all APs status.\r
-  //\r
-  Status = gBS->SetTimer (\r
-                  mMpSystemData.CheckAllAPsEvent,\r
-                  TimerPeriodic,\r
-                  EFI_TIMER_PERIOD_MICROSECONDS (100)\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // BSP\r
-  //\r
-  FillInProcessorInformation (TRUE, 0);\r
-\r
-  return EFI_SUCCESS;\r
+  return MpInitLibWhoAmI (ProcessorNumber);;\r
 }\r
 \r
 /**\r
@@ -1580,8 +915,8 @@ CollectBistDataFromHob (
   EFI_SEC_PLATFORM_INFORMATION_CPU      *CpuInstance;\r
   EFI_SEC_PLATFORM_INFORMATION_CPU      BspCpuInstance;\r
   UINTN                                 ProcessorNumber;\r
-  UINT32                                InitialLocalApicId;\r
-  CPU_DATA_BLOCK                        *CpuData;\r
+  EFI_PROCESSOR_INFORMATION             ProcessorInfo;\r
+  EFI_HEALTH_FLAGS                      BistData;\r
 \r
   SecPlatformInformation2 = NULL;\r
   SecPlatformInformation  = NULL;\r
@@ -1622,23 +957,22 @@ CollectBistDataFromHob (
   }\r
 \r
   while ((NumberOfData--) > 0) {\r
-    for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) {\r
-      CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
-      InitialLocalApicId = (UINT32) CpuData->Info.ProcessorId;\r
-      if (InitialLocalApicId == CpuInstance[NumberOfData].CpuLocation) {\r
+    for (ProcessorNumber = 0; ProcessorNumber < mNumberOfProcessors; ProcessorNumber++) {\r
+      MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData);\r
+      if (ProcessorInfo.ProcessorId == CpuInstance[NumberOfData].CpuLocation) {\r
         //\r
         // Update CPU health status for MP Services Protocol according to BIST data.\r
         //\r
-        if (CpuInstance[NumberOfData].InfoRecord.IA32HealthFlags.Uint32 != 0) {\r
-          CpuData->Info.StatusFlag &= ~PROCESSOR_HEALTH_STATUS_BIT;\r
-          //\r
-          // Report Status Code that self test is failed\r
-          //\r
-          REPORT_STATUS_CODE (\r
-            EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
-            (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)\r
-            );\r
-        }\r
+        BistData = CpuInstance[NumberOfData].InfoRecord.IA32HealthFlags;\r
+      }\r
+      if (BistData.Uint32 != 0) {\r
+        //\r
+        // Report Status Code that self test is failed\r
+        //\r
+        REPORT_STATUS_CODE (\r
+          EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
+          (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)\r
+          );\r
       }\r
     }\r
   }\r
@@ -1692,115 +1026,37 @@ InitializeMpSupport (
   )\r
 {\r
   EFI_STATUS     Status;\r
-  MTRR_SETTINGS  MtrrSettings;\r
-  UINTN          Timeout;\r
+  UINTN          NumberOfProcessors;\r
+  UINTN          NumberOfEnabledProcessors;\r
 \r
-  gMaxLogicalProcessorNumber = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
-  if (gMaxLogicalProcessorNumber < 1) {\r
+  NumberOfProcessors = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
+  if (NumberOfProcessors < 1) {\r
     DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));\r
     return;\r
   }\r
 \r
-\r
-\r
-  InitMpSystemData ();\r
-\r
   //\r
   // Only perform AP detection if PcdCpuMaxLogicalProcessorNumber is greater than 1\r
   //\r
-  if (gMaxLogicalProcessorNumber > 1) {\r
-\r
-    gApStackSize = (UINTN) PcdGet32 (PcdCpuApStackSize);\r
-    ASSERT ((gApStackSize & (SIZE_4KB - 1)) == 0);\r
-\r
-    mApStackStart = AllocatePages (EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));\r
-    ASSERT (mApStackStart != NULL);\r
-\r
-    //\r
-    // the first buffer of stack size used for common stack, when the amount of AP\r
-    // more than 1, we should never free the common stack which maybe used for AP reset.\r
-    //\r
-    mCommonStack = mApStackStart;\r
-    mTopOfApCommonStack = (UINT8*) mApStackStart + gApStackSize;\r
-    mApStackStart = mTopOfApCommonStack;\r
-\r
-    PrepareAPStartupCode ();\r
+  if (NumberOfProcessors > 1) {\r
+    Status = MpInitLibInitialize ();\r
+    ASSERT_EFI_ERROR (Status);\r
 \r
-    StartApsStackless ();\r
-  }\r
-\r
-  DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", mMpSystemData.NumberOfProcessors));\r
-  if (mMpSystemData.NumberOfProcessors == 1) {\r
-    FreeApStartupCode ();\r
-    if (mCommonStack != NULL) {\r
-      FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));\r
-    }\r
+    MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors);\r
+    mNumberOfProcessors = NumberOfProcessors;\r
   }\r
-\r
-  mMpSystemData.CpuDatas = ReallocatePool (\r
-                             sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber,\r
-                             sizeof (CPU_DATA_BLOCK) * mMpSystemData.NumberOfProcessors,\r
-                             mMpSystemData.CpuDatas);\r
-\r
-  //\r
-  // Release all APs to complete initialization and enter idle loop\r
-  //\r
-  mAPsAlreadyInitFinished = TRUE;\r
-\r
-  //\r
-  // Wait for all APs to enter idle loop.\r
-  //\r
-  Timeout = 0;\r
-  do {\r
-    if (CheckAllAPsSleeping ()) {\r
-      break;\r
-    }\r
-    MicroSecondDelay (gPollInterval);\r
-    Timeout += gPollInterval;\r
-  } while (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));\r
-  ASSERT (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));\r
+  DEBUG ((EFI_D_ERROR, "Detect CPU count: %d\n", mNumberOfProcessors));\r
 \r
   //\r
   // Update CPU healthy information from Guided HOB\r
   //\r
   CollectBistDataFromHob ();\r
 \r
-  //\r
-  // Synchronize MTRR settings to APs.\r
-  //\r
-  MtrrGetAllMtrrs (&MtrrSettings);\r
-  Status = mMpServicesTemplate.StartupAllAPs (\r
-                                 &mMpServicesTemplate, // This\r
-                                 SetMtrrsFromBuffer,   // Procedure\r
-                                 TRUE,                 // SingleThread\r
-                                 NULL,                 // WaitEvent\r
-                                 0,                    // TimeoutInMicrosecsond\r
-                                 &MtrrSettings,        // ProcedureArgument\r
-                                 NULL                  // FailedCpuList\r
-                                 );\r
-  ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_STARTED);\r
-\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &mMpServiceHandle,\r
                   &gEfiMpServiceProtocolGuid,  &mMpServicesTemplate,\r
                   NULL\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
-\r
-  if (mMpSystemData.NumberOfProcessors > 1 && mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {\r
-    if (mApStackStart != NULL) {\r
-      FreePages (mApStackStart, EFI_SIZE_TO_PAGES (\r
-                                  (gMaxLogicalProcessorNumber - mMpSystemData.NumberOfProcessors) *\r
-                                  gApStackSize));\r
-    }\r
-  }\r
-\r
-  Status = gBS->CreateEvent (\r
-                  EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
-                  TPL_CALLBACK,\r
-                  ExitBootServicesCallback,\r
-                  NULL,\r
-                  &mExitBootServicesEvent\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
 }\r
+\r
index 503f3ae944fe850e1a2afeeb15aa6604ef2e0242..1e204f34565bbaa58b1084c4f5883979bf88038f 100644 (file)
@@ -19,8 +19,6 @@
 #include <Ppi/SecPlatformInformation2.h>\r
 #include <Protocol/MpService.h>\r
 #include <Library/SynchronizationLib.h>\r
-#include <Library/HobLib.h>\r
-#include <Library/ReportStatusCodeLib.h>\r
 \r
 /**\r
   Initialize Multi-processor support.\r
index 467aa869a5e5b1d3f6ef946308680ea21cc1d6b3..d4a6673770a193d5bc3e24a68d0c385b60fcddfc 100644 (file)
@@ -83,6 +83,7 @@
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf\r
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf\r
 \r
 [LibraryClasses.common.DXE_SMM_DRIVER]\r
   SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf\r