]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuMpPei/CpuMpPei.c
UefiCpuPkg/CpuMpPei: Add GetApLoopMode() to get AP loop mode
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / CpuMpPei.c
index 2e6e7611a2618ea1492d6debceb2f756bc2113bb..ac609a01f8cc4a4e2b3c0894f313eaed2d7f15c2 100644 (file)
@@ -117,6 +117,54 @@ ApFuncEnableX2Apic (
   SetApicMode (LOCAL_APIC_MODE_X2APIC);\r
 }\r
 \r
+/**\r
+  Get AP loop mode.\r
+\r
+  @param MonitorFilterSize  Returns the largest monitor-line size in bytes.\r
+\r
+  @return The AP loop mode.\r
+**/\r
+UINT8\r
+GetApLoopMode (\r
+  OUT UINT16     *MonitorFilterSize\r
+  )\r
+{\r
+  UINT8          ApLoopMode;\r
+  UINT32         RegEbx;\r
+  UINT32         RegEcx;\r
+  UINT32         RegEdx;\r
+\r
+  ASSERT (MonitorFilterSize != NULL);\r
+\r
+  ApLoopMode = PcdGet8 (PcdCpuApLoopMode);\r
+  ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop);\r
+  if (ApLoopMode == ApInMwaitLoop) {\r
+    AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &RegEcx, NULL);\r
+    if ((RegEcx & BIT3) == 0) {\r
+      //\r
+      // If processor does not support MONITOR/MWAIT feature\r
+      // by CPUID.[EAX=01H]:ECX.BIT3, force AP in Hlt-loop mode\r
+      //\r
+      ApLoopMode = ApInHltLoop;\r
+    }\r
+  }\r
+\r
+  if (ApLoopMode == ApInHltLoop) {\r
+    *MonitorFilterSize = 0;\r
+  } else if (ApLoopMode == ApInRunLoop) {\r
+    *MonitorFilterSize = sizeof (UINT32);\r
+  } else if (ApLoopMode == ApInMwaitLoop) {\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, &RegEbx, NULL, &RegEdx);\r
+    *MonitorFilterSize = RegEbx & 0xFFFF;\r
+  }\r
+\r
+  return ApLoopMode;\r
+}\r
+\r
 /**\r
   Get CPU MP Data pointer from the Guided HOB.\r
 \r