Module Name: src Committed By: bouyer Date: Wed Feb 2 12:26:43 UTC 2011
Modified Files: src/sys/arch/x86/include: cpu_counter.h src/sys/arch/x86/x86: cpu.c tsc.c Log Message: Some CPU have cpu counter (CPUID_TSC is there) but don't handle the rdmsr instruction (CPUID_MSR is not there). Introduce a cpu_counter_serializing() function to remplace rdmsr(MSR_TSC) calls, which does a rdmsr(MSR_TSC) if available and cpu_counter() otherwise. This makes the cpu counter useable on vortex86 CPUs. OK ad@ To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/arch/x86/include/cpu_counter.h cvs rdiff -u -r1.79 -r1.80 src/sys/arch/x86/x86/cpu.c cvs rdiff -u -r1.27 -r1.28 src/sys/arch/x86/x86/tsc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/include/cpu_counter.h diff -u src/sys/arch/x86/include/cpu_counter.h:1.4 src/sys/arch/x86/include/cpu_counter.h:1.5 --- src/sys/arch/x86/include/cpu_counter.h:1.4 Sat May 10 16:12:32 2008 +++ src/sys/arch/x86/include/cpu_counter.h Wed Feb 2 12:26:42 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu_counter.h,v 1.4 2008/05/10 16:12:32 ad Exp $ */ +/* $NetBSD: cpu_counter.h,v 1.5 2011/02/02 12:26:42 bouyer Exp $ */ /*- * Copyright (c) 2000, 2008 The NetBSD Foundation, Inc. @@ -35,6 +35,7 @@ #ifdef _KERNEL uint64_t cpu_counter(void); +uint64_t cpu_counter_serializing(void); uint32_t cpu_counter32(void); uint64_t cpu_frequency(struct cpu_info *); int cpu_hascounter(void); Index: src/sys/arch/x86/x86/cpu.c diff -u src/sys/arch/x86/x86/cpu.c:1.79 src/sys/arch/x86/x86/cpu.c:1.80 --- src/sys/arch/x86/x86/cpu.c:1.79 Tue Jan 11 18:25:25 2011 +++ src/sys/arch/x86/x86/cpu.c Wed Feb 2 12:26:42 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.79 2011/01/11 18:25:25 jruoho Exp $ */ +/* $NetBSD: cpu.c,v 1.80 2011/02/02 12:26:42 bouyer Exp $ */ /*- * Copyright (c) 2000, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.79 2011/01/11 18:25:25 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.80 2011/02/02 12:26:42 bouyer Exp $"); #include "opt_ddb.h" #include "opt_mpbios.h" /* for MPDEBUG */ @@ -1080,9 +1080,10 @@ uint64_t last_tsc; if (cpu_hascounter()) { - last_tsc = rdmsr(MSR_TSC); + last_tsc = cpu_counter_serializing(); i8254_delay(100000); - ci->ci_data.cpu_cc_freq = (rdmsr(MSR_TSC) - last_tsc) * 10; + ci->ci_data.cpu_cc_freq = + (cpu_counter_serializing() - last_tsc) * 10; } } Index: src/sys/arch/x86/x86/tsc.c diff -u src/sys/arch/x86/x86/tsc.c:1.27 src/sys/arch/x86/x86/tsc.c:1.28 --- src/sys/arch/x86/x86/tsc.c:1.27 Sat Aug 21 01:57:34 2010 +++ src/sys/arch/x86/x86/tsc.c Wed Feb 2 12:26:42 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: tsc.c,v 1.27 2010/08/21 01:57:34 jruoho Exp $ */ +/* $NetBSD: tsc.c,v 1.28 2011/02/02 12:26:42 bouyer Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.27 2010/08/21 01:57:34 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.28 2011/02/02 12:26:42 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -177,13 +177,13 @@ /* Flag it and read our TSC. */ atomic_or_uint(&ci->ci_flags, CPUF_SYNCTSC); - bptsc = rdmsr(MSR_TSC) >> 1; + bptsc = cpu_counter_serializing() >> 1; /* Wait for remote to complete, and read ours again. */ while ((ci->ci_flags & CPUF_SYNCTSC) != 0) { __insn_barrier(); } - bptsc += (rdmsr(MSR_TSC) >> 1); + bptsc += (cpu_counter_serializing() >> 1); /* Wait for the results to come in. */ while (tsc_sync_cpu == ci) { @@ -222,11 +222,11 @@ while ((ci->ci_flags & CPUF_SYNCTSC) == 0) { __insn_barrier(); } - tsc = (rdmsr(MSR_TSC) >> 1); + tsc = (cpu_counter_serializing() >> 1); /* Instruct primary to read its counter. */ atomic_and_uint(&ci->ci_flags, ~CPUF_SYNCTSC); - tsc += (rdmsr(MSR_TSC) >> 1); + tsc += (cpu_counter_serializing() >> 1); /* Post result. Ensure the whole value goes out atomically. */ (void)atomic_swap_64(&tsc_sync_val, tsc); @@ -257,3 +257,12 @@ return cpu_feature[0] & CPUID_TSC; } + +uint64_t +cpu_counter_serializing(void) +{ + if (cpu_feature[0] & CPUID_MSR) + return rdmsr(MSR_TSC); + else + return cpu_counter(); +}