]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg/MpInitLib: Get ApLoopMode and MointorFilter size
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.c
index 3ac79b6a9031b9bbf8e8f7569dbc952d59fc0687..32bbaee5cce0e43bc654e2eff161bf1da2fe75b4 100644 (file)
 #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
@@ -35,10 +94,14 @@ MpInitLibInitialize (
   )\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