]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/CpuDxe: implement Mp Protocol:EnableDisableAP()
authorChen Fan <chen.fan.fnst@cn.fujitsu.com>
Thu, 13 Nov 2014 18:27:09 +0000 (18:27 +0000)
committerjljusten <jljusten@Edk2>
Thu, 13 Nov 2014 18:27:09 +0000 (18:27 +0000)
Due to the implementation of  AcquireSpinLock() is not MP safe,
so we should use AcquireSpinLockOrFail directly instead.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16357 6f19259b-4bc3-4df7-8a09-765794883524

UefiCpuPkg/CpuDxe/CpuMp.c
UefiCpuPkg/CpuDxe/CpuMp.h

index 4fae3f2f0d9a0057328d1f4aab4bb184a14c1615..1d3d16bcc06bfa776e1df2f45699dad51aaa205d 100644 (file)
@@ -30,7 +30,7 @@ EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   NULL, // StartupAllAPs,\r
   NULL, // StartupThisAP,\r
   NULL, // SwitchBSP,\r
-  NULL, // EnableDisableAP,\r
+  EnableDisableAP,\r
   WhoAmI\r
 };\r
 \r
@@ -57,6 +57,101 @@ IsBSP (
   return CpuData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT ? TRUE : FALSE;\r
 }\r
 \r
+/**\r
+  Get the Application Processors state.\r
+\r
+  @param   CpuData    the pointer to CPU_DATA_BLOCK of specified AP\r
+\r
+  @retval  CPU_STATE  the AP status\r
+\r
+**/\r
+CPU_STATE\r
+GetApState (\r
+  IN  CPU_DATA_BLOCK  *CpuData\r
+  )\r
+{\r
+  CPU_STATE State;\r
+\r
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
+    CpuPause ();\r
+  }\r
+\r
+  State = CpuData->State;\r
+  ReleaseSpinLock (&CpuData->CpuDataLock);\r
+\r
+  return State;\r
+}\r
+\r
+/**\r
+  Check the Application Processors Status whether contains the Flags.\r
+\r
+  @param     CpuData  the pointer to CPU_DATA_BLOCK of specified AP\r
+  @param     Flags    the StatusFlag describing in EFI_PROCESSOR_INFORMATION\r
+\r
+  @retval    TRUE     the AP status includes the StatusFlag\r
+  @retval    FALSE    the AP status excludes the StatusFlag\r
+\r
+**/\r
+BOOLEAN\r
+TestCpuStatusFlag (\r
+  IN  CPU_DATA_BLOCK  *CpuData,\r
+  IN  UINT32          Flags\r
+  )\r
+{\r
+  UINT32 Ret;\r
+\r
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
+    CpuPause ();\r
+  }\r
+\r
+  Ret = CpuData->Info.StatusFlag & Flags;\r
+  ReleaseSpinLock (&CpuData->CpuDataLock);\r
+\r
+  return !!(Ret);\r
+}\r
+\r
+/**\r
+  Bitwise-Or of the Application Processors Status with the Flags.\r
+\r
+  @param     CpuData  the pointer to CPU_DATA_BLOCK of specified AP\r
+  @param     Flags    the StatusFlag describing in EFI_PROCESSOR_INFORMATION\r
+\r
+**/\r
+VOID\r
+CpuStatusFlagOr (\r
+  IN  CPU_DATA_BLOCK  *CpuData,\r
+  IN  UINT32          Flags\r
+  )\r
+{\r
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
+    CpuPause ();\r
+  }\r
+\r
+  CpuData->Info.StatusFlag |= Flags;\r
+  ReleaseSpinLock (&CpuData->CpuDataLock);\r
+}\r
+\r
+/**\r
+  Bitwise-AndNot of the Application Processors Status with the Flags.\r
+\r
+  @param     CpuData  the pointer to CPU_DATA_BLOCK of specified AP\r
+  @param     Flags    the StatusFlag describing in EFI_PROCESSOR_INFORMATION\r
+\r
+**/\r
+VOID\r
+CpuStatusFlagAndNot (\r
+  IN  CPU_DATA_BLOCK  *CpuData,\r
+  IN  UINT32          Flags\r
+  )\r
+{\r
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
+    CpuPause ();\r
+  }\r
+\r
+  CpuData->Info.StatusFlag &= ~Flags;\r
+  ReleaseSpinLock (&CpuData->CpuDataLock);\r
+}\r
+\r
 /**\r
   This service retrieves the number of logical processor in the platform\r
   and the number of those logical processors that are enabled on this boot.\r
@@ -164,6 +259,95 @@ GetProcessorInfo (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  This service lets the caller enable or disable an AP from this point onward.\r
+  This service may only be called from the BSP.\r
+\r
+  This service allows the caller enable or disable an AP from this point onward.\r
+  The caller can optionally specify the health status of the AP by Health. If\r
+  an AP is being disabled, then the state of the disabled AP is implementation\r
+  dependent. If an AP is enabled, then the implementation must guarantee that a\r
+  complete initialization sequence is performed on the AP, so the AP is in a state\r
+  that is compatible with an MP operating system. This service may not be supported\r
+  after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.\r
+\r
+  If the enable or disable AP operation cannot be completed prior to the return\r
+  from this service, then EFI_UNSUPPORTED must be returned.\r
+\r
+  @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.\r
+  @param[in] ProcessorNumber   The handle number of AP that is to become the new\r
+                               BSP. The range is from 0 to the total number of\r
+                               logical processors minus 1. The total number of\r
+                               logical processors can be retrieved by\r
+                               EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().\r
+  @param[in] EnableAP          Specifies the new state for the processor for\r
+                               enabled, FALSE for disabled.\r
+  @param[in] HealthFlag        If not NULL, a pointer to a value that specifies\r
+                               the new health status of the AP. This flag\r
+                               corresponds to StatusFlag defined in\r
+                               EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only\r
+                               the PROCESSOR_HEALTH_STATUS_BIT is used. All other\r
+                               bits are ignored.  If it is NULL, this parameter\r
+                               is ignored.\r
+\r
+  @retval EFI_SUCCESS             The specified AP was enabled or disabled successfully.\r
+  @retval EFI_UNSUPPORTED         Enabling or disabling an AP cannot be completed\r
+                                  prior to this service returning.\r
+  @retval EFI_UNSUPPORTED         Enabling or disabling an AP is not supported.\r
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.\r
+  @retval EFI_NOT_FOUND           Processor with the handle specified by ProcessorNumber\r
+                                  does not exist.\r
+  @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EnableDisableAP (\r
+  IN  EFI_MP_SERVICES_PROTOCOL  *This,\r
+  IN  UINTN                     ProcessorNumber,\r
+  IN  BOOLEAN                   EnableAP,\r
+  IN  UINT32                    *HealthFlag OPTIONAL\r
+  )\r
+{\r
+  CPU_DATA_BLOCK *CpuData;\r
+\r
+  if (!IsBSP ()) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
+  if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (GetApState (CpuData) != CpuStateIdle) {\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
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   This return the handle number for the calling processor.  This service may be\r
   called from the BSP and APs.\r
index d061bc4a61379c474ab1c36998bb6d225734989d..e4adb3f0e164f3b1ed86f60910100421dd2eae44 100644 (file)
@@ -202,6 +202,56 @@ GetProcessorInfo (
   OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer\r
   );\r
 \r
+/**\r
+  This service lets the caller enable or disable an AP from this point onward.\r
+  This service may only be called from the BSP.\r
+\r
+  This service allows the caller enable or disable an AP from this point onward.\r
+  The caller can optionally specify the health status of the AP by Health. If\r
+  an AP is being disabled, then the state of the disabled AP is implementation\r
+  dependent. If an AP is enabled, then the implementation must guarantee that a\r
+  complete initialization sequence is performed on the AP, so the AP is in a state\r
+  that is compatible with an MP operating system. This service may not be supported\r
+  after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.\r
+\r
+  If the enable or disable AP operation cannot be completed prior to the return\r
+  from this service, then EFI_UNSUPPORTED must be returned.\r
+\r
+  @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.\r
+  @param[in] ProcessorNumber   The handle number of AP that is to become the new\r
+                               BSP. The range is from 0 to the total number of\r
+                               logical processors minus 1. The total number of\r
+                               logical processors can be retrieved by\r
+                               EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().\r
+  @param[in] EnableAP          Specifies the new state for the processor for\r
+                               enabled, FALSE for disabled.\r
+  @param[in] HealthFlag        If not NULL, a pointer to a value that specifies\r
+                               the new health status of the AP. This flag\r
+                               corresponds to StatusFlag defined in\r
+                               EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only\r
+                               the PROCESSOR_HEALTH_STATUS_BIT is used. All other\r
+                               bits are ignored.  If it is NULL, this parameter\r
+                               is ignored.\r
+\r
+  @retval EFI_SUCCESS             The specified AP was enabled or disabled successfully.\r
+  @retval EFI_UNSUPPORTED         Enabling or disabling an AP cannot be completed\r
+                                  prior to this service returning.\r
+  @retval EFI_UNSUPPORTED         Enabling or disabling an AP is not supported.\r
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.\r
+  @retval EFI_NOT_FOUND           Processor with the handle specified by ProcessorNumber\r
+                                  does not exist.\r
+  @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EnableDisableAP (\r
+  IN  EFI_MP_SERVICES_PROTOCOL  *This,\r
+  IN  UINTN                     ProcessorNumber,\r
+  IN  BOOLEAN                   EnableAP,\r
+  IN  UINT32                    *HealthFlag OPTIONAL\r
+  );\r
+\r
 /**\r
   This return the handle number for the calling processor.  This service may be\r
   called from the BSP and APs.\r