Index: sys/x86/include/x86_var.h =================================================================== --- sys/x86/include/x86_var.h +++ sys/x86/include/x86_var.h @@ -116,6 +116,7 @@ #endif } +bool acpi_get_fadt_bootflags(uint16_t *flagsp); void *alloc_fpusave(int flags); void busdma_swi(void); bool cpu_mwait_usable(void); Index: sys/x86/isa/atrtc.c =================================================================== --- sys/x86/isa/atrtc.c +++ sys/x86/isa/atrtc.c @@ -32,7 +32,6 @@ #include __FBSDID("$FreeBSD$"); -#include "opt_acpi.h" #include "opt_isa.h" #include @@ -55,10 +54,8 @@ #endif #include #include "clock_if.h" - -#ifdef DEV_ACPI #include -#endif +#include /* * atrtc_lock protects low-level access to individual hardware registers. @@ -261,29 +258,12 @@ static bool atrtc_acpi_disabled(void) { -#ifdef DEV_ACPI - ACPI_TABLE_FADT *fadt; - vm_paddr_t physaddr; uint16_t flags; - physaddr = acpi_find_table(ACPI_SIG_FADT); - if (physaddr == 0) + if (!acpi_get_fadt_bootflags(&flags)) return (false); - - fadt = acpi_map_table(physaddr, ACPI_SIG_FADT); - if (fadt == NULL) { - printf("at_rtc: unable to map FADT ACPI table\n"); - return (false); - } - - flags = fadt->BootFlags; - acpi_unmap_table(fadt); - - if (flags & ACPI_FADT_NO_CMOS_RTC) + return ((flags & ACPI_FADT_NO_CMOS_RTC) != 0); return (true); -#endif - - return (false); } static int Index: sys/x86/x86/cpu_machdep.c =================================================================== --- sys/x86/x86/cpu_machdep.c +++ sys/x86/x86/cpu_machdep.c @@ -41,6 +41,7 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_acpi.h" #include "opt_atpic.h" #include "opt_cpu.h" #include "opt_ddb.h" @@ -98,6 +99,8 @@ #include +#include + #define STATE_RUNNING 0x0 #define STATE_MWAIT 0x1 #define STATE_SLEEPING 0x2 @@ -930,3 +933,23 @@ load_cr0(rcr0() | CR0_WP); } +bool +acpi_get_fadt_bootflags(uint16_t *flagsp) +{ +#ifdef DEV_ACPI + ACPI_TABLE_FADT *fadt; + vm_paddr_t physaddr; + + physaddr = acpi_find_table(ACPI_SIG_FADT); + if (physaddr == 0) + return (false); + fadt = acpi_map_table(physaddr, ACPI_SIG_FADT); + if (fadt == NULL) + return (false); + *flagsp = fadt->BootFlags; + acpi_unmap_table(fadt); + return (true); +#else + return (false); +#endif +} Index: sys/x86/x86/tsc.c =================================================================== --- sys/x86/x86/tsc.c +++ sys/x86/x86/tsc.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "cpufreq_if.h" @@ -81,8 +82,9 @@ "Disable x86 Time Stamp Counter"); static int tsc_skip_calibration; -SYSCTL_INT(_machdep, OID_AUTO, disable_tsc_calibration, CTLFLAG_RDTUN, - &tsc_skip_calibration, 0, "Disable TSC frequency calibration"); +SYSCTL_INT(_machdep, OID_AUTO, disable_tsc_calibration, CTLFLAG_RDTUN | + CTLFLAG_NOFETCH, &tsc_skip_calibration, 0, + "Disable TSC frequency calibration"); static void tsc_freq_changed(void *arg, const struct cf_level *level, int status); @@ -213,6 +215,7 @@ { u_int regs[4]; uint64_t tsc1, tsc2; + uint16_t bootflags; if (cpu_high >= 6) { do_cpuid(6, regs); @@ -272,6 +275,25 @@ break; } + if (!TUNABLE_INT_FETCH("machdep.disable_tsc_calibration", + &tsc_skip_calibration)) { + /* + * User did not give the order about calibration. + * If he did, we do not try to guess. + * + * Otherwise, if ACPI FADT reports that the platform + * is legacy-free and CPUID provides TSC frequency, + * use it. The calibration could fail anyway since + * ISA timer can be absent or power gated. + */ + if (acpi_get_fadt_bootflags(&bootflags) && + (bootflags & ACPI_FADT_LEGACY_DEVICES) == 0 && + tsc_freq_cpuid()) { + printf("Skipping TSC calibration since no legacy " + "devices reported by FADT and CPUID works\n"); + tsc_skip_calibration = 1; + } + } if (tsc_skip_calibration) { if (tsc_freq_cpuid()) ;