X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FCpuMpPei%2FCpuMpPei.c;fp=UefiCpuPkg%2FCpuMpPei%2FCpuMpPei.c;h=ac609a01f8cc4a4e2b3c0894f313eaed2d7f15c2;hp=2e6e7611a2618ea1492d6debceb2f756bc2113bb;hb=4de216c01641fe4362cabfa0687378a973490832;hpb=9d39ed931bf59b8d5afdccf7e1c30ece817b7a04 diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c index 2e6e7611a2..ac609a01f8 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c @@ -117,6 +117,54 @@ ApFuncEnableX2Apic ( SetApicMode (LOCAL_APIC_MODE_X2APIC); } +/** + Get AP loop mode. + + @param MonitorFilterSize Returns the largest monitor-line size in bytes. + + @return The AP loop mode. +**/ +UINT8 +GetApLoopMode ( + OUT UINT16 *MonitorFilterSize + ) +{ + UINT8 ApLoopMode; + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + + ASSERT (MonitorFilterSize != NULL); + + ApLoopMode = PcdGet8 (PcdCpuApLoopMode); + ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop); + if (ApLoopMode == ApInMwaitLoop) { + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &RegEcx, NULL); + if ((RegEcx & BIT3) == 0) { + // + // If processor does not support MONITOR/MWAIT feature + // by CPUID.[EAX=01H]:ECX.BIT3, force AP in Hlt-loop mode + // + ApLoopMode = ApInHltLoop; + } + } + + if (ApLoopMode == ApInHltLoop) { + *MonitorFilterSize = 0; + } else if (ApLoopMode == ApInRunLoop) { + *MonitorFilterSize = sizeof (UINT32); + } else if (ApLoopMode == ApInMwaitLoop) { + // + // 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, &RegEbx, NULL, &RegEdx); + *MonitorFilterSize = RegEbx & 0xFFFF; + } + + return ApLoopMode; +} + /** Get CPU MP Data pointer from the Guided HOB.