summaryrefslogtreecommitdiff
path: root/UefiCpuPkg
diff options
context:
space:
mode:
authorJeff Fan <jeff.fan@intel.com>2016-07-20 23:32:17 +0800
committerJeff Fan <jeff.fan@intel.com>2016-08-17 19:59:06 +0800
commit9ebcf0f4005239abcde5141414703e2676200550 (patch)
treebbe52c3a4669096b53e3ea284c55253e8d8c0ced /UefiCpuPkg
parentf7f85d83609842e7a3243f8cb15e3d4cb8345177 (diff)
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.c63
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.h10
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.