Allow discovering MSR-based CPU/TSC frequency early in boot. This method works only for some Intel CPUs.
Signed-off-by: Pavel Tatashin <[email protected]> --- arch/x86/include/asm/tsc.h | 1 + arch/x86/kernel/tsc_msr.c | 38 +++++++++++++++++++++++++------------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index f5e6f1c..893de0c 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h @@ -61,6 +61,7 @@ static inline void check_tsc_sync_target(void) { } extern void tsc_save_sched_clock_state(void); extern void tsc_restore_sched_clock_state(void); +unsigned long cpu_khz_from_msr_early(int vendor, int family, int model); unsigned long cpu_khz_from_msr(void); #endif /* _ASM_X86_TSC_H */ diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c index 19afdbd..6f5f617 100644 --- a/arch/x86/kernel/tsc_msr.c +++ b/arch/x86/kernel/tsc_msr.c @@ -62,22 +62,20 @@ static int match_cpu(u8 family, u8 model) #define id_to_freq(cpu_index, freq_id) \ (freq_desc_tables[cpu_index].freqs[freq_id]) -/* - * MSR-based CPU/TSC frequency discovery for certain CPUs. - * - * Set global "lapic_timer_frequency" to bus_clock_cycles/jiffy - * Return processor base frequency in KHz, or 0 on failure. - */ -unsigned long cpu_khz_from_msr(void) + /* + * Get CPU/TSC frequency early in boot. + * Set global "lapic_timer_frequency" to bus_clock_cycles/jiffy + * Return processor base frequency in KHz, or 0 on failure. + */ +unsigned long cpu_khz_from_msr_early(int vendor, int family, int model) { u32 lo, hi, ratio, freq_id, freq; - unsigned long res; int cpu_index; - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + if (vendor != X86_VENDOR_INTEL) return 0; - cpu_index = match_cpu(boot_cpu_data.x86, boot_cpu_data.x86_model); + cpu_index = match_cpu(family, model); if (cpu_index < 0) return 0; @@ -94,13 +92,27 @@ unsigned long cpu_khz_from_msr(void) freq_id = lo & 0x7; freq = id_to_freq(cpu_index, freq_id); - /* TSC frequency = maximum resolved freq * maximum resolved bus ratio */ - res = freq * ratio; - #ifdef CONFIG_X86_LOCAL_APIC lapic_timer_frequency = (freq * 1000) / HZ; #endif + /* TSC frequency = maximum resolved freq * maximum resolved bus ratio */ + return freq * ratio; +} + +/* + * MSR-based CPU/TSC frequency discovery for certain CPUs. + */ +unsigned long cpu_khz_from_msr(void) +{ + unsigned long res; + + res = cpu_khz_from_msr_early(boot_cpu_data.x86_vendor, + boot_cpu_data.x86, + boot_cpu_data.x86_model); + if (res == 0) + return 0; + /* * TSC frequency determined by MSR is always considered "known" * because it is reported by HW. -- 1.7.1

