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