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