Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 May 2018 07:42:47 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r333161 - stable/11/sys/x86/x86
Message-ID:  <201805020742.w427glQ4075124@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed May  2 07:42:47 2018
New Revision: 333161
URL: https://svnweb.freebsd.org/changeset/base/333161

Log:
  MFC r333002:
  Use CPUID leaf 0x15 to get TSC frequency when the calibration is
  disabled.

Modified:
  stable/11/sys/x86/x86/tsc.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/x86/x86/tsc.c
==============================================================================
--- stable/11/sys/x86/x86/tsc.c	Wed May  2 07:40:04 2018	(r333160)
+++ stable/11/sys/x86/x86/tsc.c	Wed May  2 07:42:47 2018	(r333161)
@@ -128,6 +128,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)
 {
@@ -252,17 +272,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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805020742.w427glQ4075124>