diff options
author | Jeff Fan <jeff.fan@intel.com> | 2016-07-20 23:32:17 +0800 |
---|---|---|
committer | Jeff Fan <jeff.fan@intel.com> | 2016-08-17 19:59:06 +0800 |
commit | 9ebcf0f4005239abcde5141414703e2676200550 (patch) | |
tree | bbe52c3a4669096b53e3ea284c55253e8d8c0ced /UefiCpuPkg | |
parent | f7f85d83609842e7a3243f8cb15e3d4cb8345177 (diff) | |
download | edk2-9ebcf0f4005239abcde5141414703e2676200550.tar.gz edk2-9ebcf0f4005239abcde5141414703e2676200550.tar.bz2 edk2-9ebcf0f4005239abcde5141414703e2676200550.zip |
UefiCpuPkg/MpInitLib: Get ApLoopMode and MointorFilter size
Firstly, get ApLoopMode from PcdCpuApLoopMode. If MonitorMwait feature is not
supported, update ApLoopMode to ApHltLoop. If MonitorMwait feature is supported,
get MointorFilter size by CPUID.[EAX=05H]:EBX.BIT0-15.
v5:
1. Add comment block for enum AP_LOOP_MODE.
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>
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r-- | UefiCpuPkg/Library/MpInitLib/MpLib.c | 63 | ||||
-rw-r--r-- | UefiCpuPkg/Library/MpInitLib/MpLib.h | 10 |
2 files changed, 73 insertions, 0 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 3ac79b6a90..32bbaee5cc 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -16,6 +16,65 @@ /**
+ Detect whether Mwait-monitor feature is supported.
+
+ @retval TRUE Mwait-monitor feature is supported.
+ @retval FALSE Mwait-monitor feature is not supported.
+**/
+BOOLEAN
+IsMwaitSupport (
+ VOID
+ )
+{
+ CPUID_VERSION_INFO_ECX VersionInfoEcx;
+
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &VersionInfoEcx.Uint32, NULL);
+ return (VersionInfoEcx.Bits.MONITOR == 1) ? TRUE : FALSE;
+}
+
+/**
+ Get AP loop mode.
+
+ @param[out] MonitorFilterSize Returns the largest monitor-line size in bytes.
+
+ @return The AP loop mode.
+**/
+UINT8
+GetApLoopMode (
+ OUT UINT32 *MonitorFilterSize
+ )
+{
+ UINT8 ApLoopMode;
+ CPUID_MONITOR_MWAIT_EBX MonitorMwaitEbx;
+
+ ASSERT (MonitorFilterSize != NULL);
+
+ ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
+ ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop);
+ if (ApLoopMode == ApInMwaitLoop) {
+ if (!IsMwaitSupport ()) {
+ //
+ // If processor does not support MONITOR/MWAIT feature,
+ // force AP in Hlt-loop mode
+ //
+ ApLoopMode = ApInHltLoop;
+ }
+ }
+
+ if (ApLoopMode != ApInMwaitLoop) {
+ *MonitorFilterSize = sizeof (UINT32);
+ } else {
+ //
+ // 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, &MonitorMwaitEbx.Uint32, NULL, NULL);
+ *MonitorFilterSize = MonitorMwaitEbx.Bits.LargestMonitorLineSize;
+ }
+
+ return ApLoopMode;
+}
+/**
MP Initialize Library initialization.
This service will allocate AP reset vector and wakeup all APs to do APs
@@ -35,10 +94,14 @@ MpInitLibInitialize ( )
{
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
+ UINT32 MonitorFilterSize;
+ UINT8 ApLoopMode;
UINTN ApResetVectorSize;
AsmGetAddressMap (&AddressMap);
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
+ ApLoopMode = GetApLoopMode (&MonitorFilterSize);
+
return EFI_SUCCESS;
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index 2be13516aa..317facc80c 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -36,6 +36,16 @@ #include <Library/HobLib.h>
//
+// AP loop state when APs are in idle state
+// It's value is the same with PcdCpuApLoopMode
+//
+typedef enum {
+ ApInHltLoop = 1,
+ ApInMwaitLoop = 2,
+ ApInRunLoop = 3
+} AP_LOOP_MODE;
+
+//
// AP reset code information including code address and size,
// this structure will be shared be C code and assembly code.
// It is natural aligned by design.
|