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
This commit is contained in:
Konstantin Belousov 2018-04-25 16:43:45 +00:00
parent bd509bdb85
commit 506a906c05
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333002

View File

@ -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);
}