Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan <[email protected]>
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 143 +++++++++++++++++++++++++++++++++++++++++++++-
 UefiCpuPkg/CpuDxe/CpuMp.h |   9 +++
 2 files changed, 151 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 55a8573..9b57508 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -35,7 +35,7 @@ EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   NULL, // StartupAllAps,
   NULL, // StartupThisAP,
   NULL, // SwitchBSP,
-  NULL, // EnableDisableAP,
+  EnableDisableAP,
   WhoAmI
 };
 
@@ -53,6 +53,57 @@ IsBSP (
   return CpuData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT ? TRUE : FALSE;
 }
 
+CPU_STATE
+GetApState (
+  IN  CPU_DATA_BLOCK  *CpuData
+  )
+{
+  CPU_STATE State;
+
+  AcquireSpinLock (&CpuData->CpuDataLock);
+  State = CpuData->State;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+
+  return State;
+}
+
+BOOLEAN
+TestCpuStatusFlag (
+  IN  CPU_DATA_BLOCK  *CpuData,
+  IN  UINT32          Flags
+  )
+{
+  UINT32 Ret;
+
+  AcquireSpinLock (&CpuData->CpuDataLock);
+  Ret = CpuData->Info.StatusFlag & Flags;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+
+  return !!(Ret);
+}
+
+VOID
+CpuStatusFlagOr (
+  IN  CPU_DATA_BLOCK  *CpuData,
+  IN  UINT32          Flags
+  )
+{
+  AcquireSpinLock (&CpuData->CpuDataLock);
+  CpuData->Info.StatusFlag |= Flags;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+}
+
+VOID
+CpuStatusFlagAndNot (
+  IN  CPU_DATA_BLOCK  *CpuData,
+  IN  UINT32          Flags
+  )
+{
+  AcquireSpinLock (&CpuData->CpuDataLock);
+  CpuData->Info.StatusFlag &= ~Flags;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+}
+
 
 /**
   This service retrieves the number of logical processor in the platform
@@ -161,6 +212,95 @@ GetProcessorInfo (
   return EFI_SUCCESS;
 }
 
+/**
+  This service lets the caller enable or disable an AP from this point onward.
+  This service may only be called from the BSP.
+
+  This service allows the caller enable or disable an AP from this point 
onward.
+  The caller can optionally specify the health status of the AP by Health. If
+  an AP is being disabled, then the state of the disabled AP is implementation
+  dependent. If an AP is enabled, then the implementation must guarantee that a
+  complete initialization sequence is performed on the AP, so the AP is in a 
state
+  that is compatible with an MP operating system. This service may not be 
supported
+  after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
+
+  If the enable or disable AP operation cannot be completed prior to the return
+  from this service, then EFI_UNSUPPORTED must be returned.
+
+  @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL 
instance.
+  @param[in] ProcessorNumber   The handle number of AP that is to become the 
new
+                               BSP. The range is from 0 to the total number of
+                               logical processors minus 1. The total number of
+                               logical processors can be retrieved by
+                               
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+  @param[in] EnableAP          Specifies the new state for the processor for
+                               enabled, FALSE for disabled.
+  @param[in] HealthFlag        If not NULL, a pointer to a value that specifies
+                               the new health status of the AP. This flag
+                               corresponds to StatusFlag defined in
+                               EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). 
Only
+                               the PROCESSOR_HEALTH_STATUS_BIT is used. All 
other
+                               bits are ignored.  If it is NULL, this parameter
+                               is ignored.
+
+  @retval EFI_SUCCESS             The specified AP was enabled or disabled 
successfully.
+  @retval EFI_UNSUPPORTED         Enabling or disabling an AP cannot be 
completed
+                                  prior to this service returning.
+  @retval EFI_UNSUPPORTED         Enabling or disabling an AP is not supported.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_NOT_FOUND           Processor with the handle specified by 
ProcessorNumber
+                                  does not exist.
+  @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableDisableAP (
+  IN  EFI_MP_SERVICES_PROTOCOL  *This,
+  IN  UINTN                     ProcessorNumber,
+  IN  BOOLEAN                   EnableAP,
+  IN  UINT32                    *HealthFlag OPTIONAL
+  )
+{
+  CPU_DATA_BLOCK *CpuData;
+
+  if (!IsBSP ()) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
+    return EFI_NOT_FOUND;
+  }
+
+  CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
+  if (!TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (GetApState (CpuData) != CPU_STATE_IDLE) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (EnableAP) {
+    if (!(TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT))) {
+      mMpSystemData.NumberOfEnabledProcessors++;
+    }
+    CpuStatusFlagOr (CpuData, PROCESSOR_ENABLED_BIT);
+  } else {
+    if (TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
+      mMpSystemData.NumberOfEnabledProcessors--;
+    }
+    CpuStatusFlagAndNot (CpuData, PROCESSOR_ENABLED_BIT);
+  }
+
+  if (HealthFlag != NULL) {
+    CpuStatusFlagAndNot (CpuData, ~PROCESSOR_HEALTH_STATUS_BIT);
+    CpuStatusFlagOr (CpuData, (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT));
+  }
+
+  return EFI_SUCCESS;
+}
+
 
 /**
   This return the handle number for the calling processor.  This service may be
@@ -277,6 +417,7 @@ InitMpSystemData (
       CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;
       CpuData->Info.ProcessorId = GetApicId ();
     }
+    InitializeSpinLock (&CpuData->CpuDataLock);
   }
 
   return EFI_SUCCESS;
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index a395385..4c6d935 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -87,6 +87,15 @@ GetProcessorInfo (
 
 EFI_STATUS
 EFIAPI
+EnableDisableAP (
+  IN  EFI_MP_SERVICES_PROTOCOL  *This,
+  IN  UINTN                     ProcessorNumber,
+  IN  BOOLEAN                   EnableAP,
+  IN  UINT32                    *HealthFlag OPTIONAL
+  );
+
+EFI_STATUS
+EFIAPI
 WhoAmI (
   IN EFI_MP_SERVICES_PROTOCOL  *This,
   OUT UINTN                    *ProcessorNumber
-- 
1.9.3


------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to