svn commit: r333002 - head/sys/x86/x86
Konstantin Belousov
kib at FreeBSD.org
Wed Apr 25 16:43:46 UTC 2018
Author: kib
Date: Wed Apr 25 16:43:45 2018
New Revision: 333002
URL: https://svnweb.freebsd.org/changeset/base/333002
Log:
Use CPUID leaf 0x15 to get TSC frequency when the calibration is
disabled.
Intel finally added this information, which allows us to not parse CPU
identification string looking for the nominal frequency. The leaf is
present e.g. on Appolo Lake Atom CPUs. It is only used if the TSC
calibration is disabled by user.
Also, report the TSC frequency in bootverbose mode always, regardless
of the way it was obtained.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Modified:
head/sys/x86/x86/tsc.c
Modified: head/sys/x86/x86/tsc.c
==============================================================================
--- head/sys/x86/x86/tsc.c Wed Apr 25 16:28:51 2018 (r333001)
+++ head/sys/x86/x86/tsc.c Wed Apr 25 16:43:45 2018 (r333002)
@@ -129,6 +129,26 @@ tsc_freq_vmware(void)
tsc_is_invariant = 1;
}
+/*
+ * Calculate TSC frequency using information from the CPUID leaf 0x15
+ * 'Time Stamp Counter and Nominal Core Crystal Clock'. It should be
+ * an improvement over the parsing of the CPU model name in
+ * tsc_freq_intel(), when available.
+ */
+static bool
+tsc_freq_cpuid(void)
+{
+ u_int regs[4];
+
+ if (cpu_high < 0x15)
+ return (false);
+ do_cpuid(0x15, regs);
+ if (regs[0] == 0 || regs[1] == 0 || regs[2] == 0)
+ return (false);
+ tsc_freq = (uint64_t)regs[2] * regs[1] / regs[0];
+ return (true);
+}
+
static void
tsc_freq_intel(void)
{
@@ -253,17 +273,18 @@ probe_tsc_freq(void)
}
if (tsc_skip_calibration) {
- if (cpu_vendor_id == CPU_VENDOR_INTEL)
+ if (tsc_freq_cpuid())
+ ;
+ else if (cpu_vendor_id == CPU_VENDOR_INTEL)
tsc_freq_intel();
- return;
+ } else {
+ if (bootverbose)
+ printf("Calibrating TSC clock ... ");
+ tsc1 = rdtsc();
+ DELAY(1000000);
+ tsc2 = rdtsc();
+ tsc_freq = tsc2 - tsc1;
}
-
- if (bootverbose)
- printf("Calibrating TSC clock ... ");
- tsc1 = rdtsc();
- DELAY(1000000);
- tsc2 = rdtsc();
- tsc_freq = tsc2 - tsc1;
if (bootverbose)
printf("TSC clock: %ju Hz\n", (intmax_t)tsc_freq);
}
More information about the svn-src-all
mailing list