#include "MpLib.h"\r
\r
\r
+/**\r
+ Detect whether Mwait-monitor feature is supported.\r
+\r
+ @retval TRUE Mwait-monitor feature is supported.\r
+ @retval FALSE Mwait-monitor feature is not supported.\r
+**/\r
+BOOLEAN\r
+IsMwaitSupport (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_VERSION_INFO_ECX VersionInfoEcx;\r
+\r
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &VersionInfoEcx.Uint32, NULL);\r
+ return (VersionInfoEcx.Bits.MONITOR == 1) ? TRUE : FALSE;\r
+}\r
+\r
+/**\r
+ Get AP loop mode.\r
+\r
+ @param[out] MonitorFilterSize Returns the largest monitor-line size in bytes.\r
+\r
+ @return The AP loop mode.\r
+**/\r
+UINT8\r
+GetApLoopMode (\r
+ OUT UINT32 *MonitorFilterSize\r
+ )\r
+{\r
+ UINT8 ApLoopMode;\r
+ CPUID_MONITOR_MWAIT_EBX MonitorMwaitEbx;\r
+\r
+ ASSERT (MonitorFilterSize != NULL);\r
+\r
+ ApLoopMode = PcdGet8 (PcdCpuApLoopMode);\r
+ ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop);\r
+ if (ApLoopMode == ApInMwaitLoop) {\r
+ if (!IsMwaitSupport ()) {\r
+ //\r
+ // If processor does not support MONITOR/MWAIT feature,\r
+ // force AP in Hlt-loop mode\r
+ //\r
+ ApLoopMode = ApInHltLoop;\r
+ }\r
+ }\r
+\r
+ if (ApLoopMode != ApInMwaitLoop) {\r
+ *MonitorFilterSize = sizeof (UINT32);\r
+ } else {\r
+ //\r
+ // CPUID.[EAX=05H]:EBX.BIT0-15: Largest monitor-line size in bytes\r
+ // CPUID.[EAX=05H].EDX: C-states supported using MWAIT\r
+ //\r
+ AsmCpuid (CPUID_MONITOR_MWAIT, NULL, &MonitorMwaitEbx.Uint32, NULL, NULL);\r
+ *MonitorFilterSize = MonitorMwaitEbx.Bits.LargestMonitorLineSize;\r
+ }\r
+\r
+ return ApLoopMode;\r
+}\r
/**\r
MP Initialize Library initialization.\r
\r
)\r
{\r
MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
+ UINT32 MonitorFilterSize;\r
+ UINT8 ApLoopMode;\r
UINTN ApResetVectorSize;\r
\r
AsmGetAddressMap (&AddressMap);\r
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);\r
+ ApLoopMode = GetApLoopMode (&MonitorFilterSize);\r
+\r
return EFI_SUCCESS;\r
}\r
\r