Add GetApLoopMode() that will get PCD PcdCpuApLoopMode firstly. If it is ApInMwaitLoop, we will check if MONITOR/MWAIT feature supported by CPUID. If MONITOR/MWAIT feature is not supported, force AP loop mode to ApInHltLoop.
GetApLoopMode() also return the largest line size required. Contributed-under: TianoCore Contribution Agreement 1.0 Cc: Feng Tian <feng.t...@intel.com> Cc: Michael Kinney <michael.d.kin...@intel.com> Cc: Jordan Justen <jordan.l.jus...@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff....@intel.com> Signed-off-by: Michael Kinney <michael.d.kin...@intel.com> Tested-by: Michael Kinney <michael.d.kin...@intel.com> --- UefiCpuPkg/CpuMpPei/CpuMpPei.c | 48 +++++++++++++++++++++++++++++++++++++ UefiCpuPkg/CpuMpPei/CpuMpPei.h | 6 +++++ UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 + UefiCpuPkg/Include/Register/Cpuid.h | 2 ++ 4 files changed, 57 insertions(+) diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c index 2e6e761..ac609a0 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c @@ -118,6 +118,54 @@ ApFuncEnableX2Apic ( } /** + Get AP loop mode. + + @param MonitorFilterSize Returns the largest monitor-line size in bytes. + + @return The AP loop mode. +**/ +UINT8 +GetApLoopMode ( + OUT UINT16 *MonitorFilterSize + ) +{ + UINT8 ApLoopMode; + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + + ASSERT (MonitorFilterSize != NULL); + + ApLoopMode = PcdGet8 (PcdCpuApLoopMode); + ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop); + if (ApLoopMode == ApInMwaitLoop) { + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &RegEcx, NULL); + if ((RegEcx & BIT3) == 0) { + // + // If processor does not support MONITOR/MWAIT feature + // by CPUID.[EAX=01H]:ECX.BIT3, force AP in Hlt-loop mode + // + ApLoopMode = ApInHltLoop; + } + } + + if (ApLoopMode == ApInHltLoop) { + *MonitorFilterSize = 0; + } else if (ApLoopMode == ApInRunLoop) { + *MonitorFilterSize = sizeof (UINT32); + } else if (ApLoopMode == ApInMwaitLoop) { + // + // CPUID.[EAX=05H]:EBX.BIT0-15: Largest monitor-line size in bytes + // CPUID.[EAX=05H].EDX: C-states supported using MWAIT + // + AsmCpuid (CPUID_MONITOR_MWAIT, NULL, &RegEbx, NULL, &RegEdx); + *MonitorFilterSize = RegEbx & 0xFFFF; + } + + return ApLoopMode; +} + +/** Get CPU MP Data pointer from the Guided HOB. @return Pointer to Pointer to PEI CPU MP Data diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h index 2460f4a..4be8234 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h @@ -50,6 +50,12 @@ typedef enum { CpuStateDisabled } CPU_STATE; +typedef enum { + ApInHltLoop = 1, + ApInMwaitLoop = 2, + ApInRunLoop = 3 +} AP_LOOP_MODE; + // // AP reset code information // diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf index 423f7f1..4a5cfe7 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf @@ -81,6 +81,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES [Depex] gEfiPeiMemoryDiscoveredPpiGuid diff --git a/UefiCpuPkg/Include/Register/Cpuid.h b/UefiCpuPkg/Include/Register/Cpuid.h index 6730551..f8ff247 100644 --- a/UefiCpuPkg/Include/Register/Cpuid.h +++ b/UefiCpuPkg/Include/Register/Cpuid.h @@ -31,6 +31,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define CPUID_CACHE_PARAMS 0x4 +#define CPUID_MONITOR_MWAIT 0x5 + #define CPUID_EXTENDED_TOPOLOGY 0xB #define CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID 0x0 #define CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT 0x1 -- 1.9.5.msysgit.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel