svn commit: r353006 - stable/12/sys/x86/x86
Konstantin Belousov
kib at FreeBSD.org
Wed Oct 2 13:43:24 UTC 2019
Author: kib
Date: Wed Oct 2 13:43:24 2019
New Revision: 353006
URL: https://svnweb.freebsd.org/changeset/base/353006
Log:
MFC r352684:
x86: Fall back to leaf 0x16 if TSC frequency is obtained by CPUID and
leaf 0x15 is not functional.
Modified:
stable/12/sys/x86/x86/tsc.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/x86/x86/tsc.c
==============================================================================
--- stable/12/sys/x86/x86/tsc.c Wed Oct 2 13:36:54 2019 (r353005)
+++ stable/12/sys/x86/x86/tsc.c Wed Oct 2 13:43:24 2019 (r353006)
@@ -133,7 +133,11 @@ tsc_freq_vmware(void)
/*
* Calculate TSC frequency using information from the CPUID leaf 0x15
- * 'Time Stamp Counter and Nominal Core Crystal Clock'. It should be
+ * 'Time Stamp Counter and Nominal Core Crystal Clock'. If leaf 0x15
+ * is not functional, as it is on Skylake/Kabylake, try 0x16 'Processor
+ * Frequency Information'. Leaf 0x16 is described in the SDM as
+ * informational only, but if 0x15 did not work, and TSC calibration
+ * is disabled, it is the best we can get at all. It should still be
* an improvement over the parsing of the CPU model name in
* tsc_freq_intel(), when available.
*/
@@ -145,10 +149,20 @@ tsc_freq_cpuid(void)
if (cpu_high < 0x15)
return (false);
do_cpuid(0x15, regs);
- if (regs[0] == 0 || regs[1] == 0 || regs[2] == 0)
+ if (regs[0] != 0 && regs[1] != 0 && regs[2] != 0) {
+ tsc_freq = (uint64_t)regs[2] * regs[1] / regs[0];
+ return (true);
+ }
+
+ if (cpu_high < 0x16)
return (false);
- tsc_freq = (uint64_t)regs[2] * regs[1] / regs[0];
- return (true);
+ do_cpuid(0x16, regs);
+ if (regs[0] != 0) {
+ tsc_freq = (uint64_t)regs[0] * 1000000;
+ return (true);
+ }
+
+ return (false);
}
static void
More information about the svn-src-all
mailing list