From 0f12aa9ffd2c88f3ee8bc1a60d2e4878a6bc6945 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Sun, 28 Dec 1997 17:33:10 +0000 Subject: [PATCH] More cleanup relating to our use of the TSC. Look in the cpu_feature (CPUID output) to see if we have it. --- sys/amd64/amd64/tsc.c | 70 +++++++++++++++++---------------------- sys/amd64/include/clock.h | 14 +------- sys/amd64/isa/clock.c | 70 +++++++++++++++++---------------------- sys/i386/i386/microtime.s | 17 ++++------ sys/i386/i386/perfmon.c | 9 ++--- sys/i386/i386/tsc.c | 70 +++++++++++++++++---------------------- sys/i386/include/clock.h | 14 +------- sys/i386/isa/clock.c | 70 +++++++++++++++++---------------------- sys/isa/atrtc.c | 70 +++++++++++++++++---------------------- 9 files changed, 164 insertions(+), 240 deletions(-) diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index b7b12892f094..15a874c76c20 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.105 1997/12/26 20:42:05 phk Exp $ + * $Id: clock.c,v 1.106 1997/12/28 13:36:07 phk Exp $ */ /* @@ -67,12 +67,14 @@ #include #include #include +#include #ifdef APIC_IO #include #endif #if defined(SMP) || defined(APIC_IO) #include #endif /* SMP || APIC_IO */ +#include #include #include @@ -126,16 +128,11 @@ u_int timer_freq = 1193182; int timer0_max_count; u_int timer0_overflow_threshold; u_int timer0_prescaler_count; -#if defined(I586_CPU) || defined(I686_CPU) -#ifndef SMP u_int tsc_bias; u_int tsc_comultiplier; -#endif u_int tsc_freq; -#ifndef SMP u_int tsc_multiplier; -#endif -#endif +u_int tsc_present; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ static int beeping = 0; @@ -163,9 +160,7 @@ static u_char timer0_state; static u_char timer2_state; static void (*timer_func) __P((struct clockframe *frame)) = hardclock; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) -static void set_tsc_freq(u_int i586_freq, u_int i8254_freq); -#endif +static void set_tsc_freq(u_int tsc_count, u_int i8254_freq); static void set_timer_freq(u_int freq, int intr_freq); static void @@ -574,10 +569,8 @@ calibrate_clocks(void) goto fail; tot_count = 0; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) + if (tsc_present) wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */ -#endif /* * Wait for the mc146818A seconds counter to change. Read the i8254 @@ -607,17 +600,15 @@ calibrate_clocks(void) goto fail; } -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Read the cpu cycle counter. The timing considerations are * similar to those for the i8254 clock. */ - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { + if (tsc_present) { set_tsc_freq((u_int)rdtsc(), tot_count); if (bootverbose) printf("TSC clock: %u Hz, ", tsc_freq); } -#endif if (bootverbose) printf("i8254 clock: %u Hz\n", tot_count); @@ -656,6 +647,15 @@ startrtclock() { u_int delta, freq; + if (cpu_feature & CPUID_TSC) + tsc_present = 1; + else + tsc_present = 0; + +#ifdef SMP + tsc_present = 0; +#endif + writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, RTCSB_24HR); @@ -689,14 +689,11 @@ startrtclock() printf( "%d Hz differs from default of %d Hz by more than 1%%\n", freq, timer_freq); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) tsc_freq = 0; -#endif } set_timer_freq(timer_freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) #ifndef CLK_USE_TSC_CALIBRATION if (tsc_freq != 0) { if (bootverbose) @@ -705,8 +702,7 @@ startrtclock() tsc_freq = 0; } #endif - if (tsc_freq == 0 && - (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { + if (tsc_present && tsc_freq == 0) { /* * Calibration of the i586 clock relative to the mc146818A * clock failed. Do a less accurate calibration relative @@ -715,12 +711,11 @@ startrtclock() wrmsr(0x10, 0LL); /* XXX */ DELAY(1000000); set_tsc_freq((u_int)rdtsc(), timer_freq); -#ifdef CLK_USE_I586_CALIBRATION +#ifdef CLK_USE_TSC_CALIBRATION if (bootverbose) printf("TSC clock: %u Hz\n", tsc_freq); #endif } -#endif } /* @@ -925,13 +920,11 @@ cpu_initclocks() #endif /* APIC_IO */ -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Finish setting up anti-jitter measures. */ if (tsc_freq != 0) tsc_bias = rdtsc(); -#endif /* Initialize RTC. */ writertc(RTC_STATUSA, rtc_statusa); @@ -988,9 +981,8 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS if (timer0_state != 0) return (EBUSY); /* too much trouble to handle */ set_timer_freq(freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - set_tsc_freq(tsc_freq, timer_freq); -#endif + if (tsc_present) + set_tsc_freq(tsc_freq, timer_freq); } return (error); } @@ -998,23 +990,22 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) static void -set_tsc_freq(u_int i586_freq, u_int i8254_freq) +set_tsc_freq(u_int tsc_count, u_int i8254_freq) { u_int comultiplier, multiplier; u_long ef; - if (i586_freq == 0) { - tsc_freq = i586_freq; + if (tsc_count == 0) { + tsc_freq = tsc_count; return; } - comultiplier = ((unsigned long long)i586_freq + comultiplier = ((unsigned long long)tsc_count << TSC_COMULTIPLIER_SHIFT) / i8254_freq; - multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / i586_freq; + multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / tsc_count; ef = read_eflags(); disable_intr(); - tsc_freq = i586_freq; + tsc_freq = tsc_count; tsc_comultiplier = comultiplier; tsc_multiplier = multiplier; CLOCK_UNLOCK(); @@ -1022,12 +1013,12 @@ set_tsc_freq(u_int i586_freq, u_int i8254_freq) } static int -sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS +sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS { int error; u_int freq; - if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686) + if (!tsc_present) return (EOPNOTSUPP); freq = tsc_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); @@ -1036,6 +1027,5 @@ sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS return (error); } -SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW, - 0, sizeof(u_int), sysctl_machdep_i586_freq, "I", ""); -#endif /* (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) */ +SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW, + 0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", ""); diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h index 505ea4868fe8..a8f2d5a7efa3 100644 --- a/sys/amd64/include/clock.h +++ b/sys/amd64/include/clock.h @@ -3,17 +3,13 @@ * Garrett Wollman, September 1994. * This file is in the public domain. * - * $Id: clock.h,v 1.28 1997/12/26 20:42:01 phk Exp $ + * $Id: clock.h,v 1.29 1997/12/28 13:36:06 phk Exp $ */ #ifndef _MACHINE_CLOCK_H_ #define _MACHINE_CLOCK_H_ -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) #define CPU_CLOCKUPDATE(otime, ntime) cpu_clockupdate((otime), (ntime)) -#else -#define CPU_CLOCKUPDATE(otime, ntime) (*(otime) = *(ntime)) -#endif #define CPU_THISTICKLEN(dflt) dflt @@ -33,16 +29,10 @@ extern u_int timer_freq; extern int timer0_max_count; extern u_int timer0_overflow_threshold; extern u_int timer0_prescaler_count; -#if defined(I586_CPU) || defined(I686_CPU) -#ifndef SMP extern u_int tsc_bias; extern u_int tsc_comultiplier; -#endif extern u_int tsc_freq; -#ifndef SMP extern u_int tsc_multiplier; -#endif -#endif extern int wall_cmos_clock; /* @@ -85,7 +75,6 @@ clock_latency(void) - ((high << 8) | low)); } -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * When we update `time', on we also update `tsc_bias' * atomically. `tsc_bias' is the best available approximation to @@ -117,7 +106,6 @@ cpu_clockupdate(volatile struct timeval *otime, struct timeval *ntime) } else *otime = *ntime; } -#endif /* I586_CPU || I686_CPU */ #endif /* CLOCK_HAIR */ diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index b7b12892f094..15a874c76c20 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.105 1997/12/26 20:42:05 phk Exp $ + * $Id: clock.c,v 1.106 1997/12/28 13:36:07 phk Exp $ */ /* @@ -67,12 +67,14 @@ #include #include #include +#include #ifdef APIC_IO #include #endif #if defined(SMP) || defined(APIC_IO) #include #endif /* SMP || APIC_IO */ +#include #include #include @@ -126,16 +128,11 @@ u_int timer_freq = 1193182; int timer0_max_count; u_int timer0_overflow_threshold; u_int timer0_prescaler_count; -#if defined(I586_CPU) || defined(I686_CPU) -#ifndef SMP u_int tsc_bias; u_int tsc_comultiplier; -#endif u_int tsc_freq; -#ifndef SMP u_int tsc_multiplier; -#endif -#endif +u_int tsc_present; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ static int beeping = 0; @@ -163,9 +160,7 @@ static u_char timer0_state; static u_char timer2_state; static void (*timer_func) __P((struct clockframe *frame)) = hardclock; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) -static void set_tsc_freq(u_int i586_freq, u_int i8254_freq); -#endif +static void set_tsc_freq(u_int tsc_count, u_int i8254_freq); static void set_timer_freq(u_int freq, int intr_freq); static void @@ -574,10 +569,8 @@ calibrate_clocks(void) goto fail; tot_count = 0; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) + if (tsc_present) wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */ -#endif /* * Wait for the mc146818A seconds counter to change. Read the i8254 @@ -607,17 +600,15 @@ calibrate_clocks(void) goto fail; } -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Read the cpu cycle counter. The timing considerations are * similar to those for the i8254 clock. */ - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { + if (tsc_present) { set_tsc_freq((u_int)rdtsc(), tot_count); if (bootverbose) printf("TSC clock: %u Hz, ", tsc_freq); } -#endif if (bootverbose) printf("i8254 clock: %u Hz\n", tot_count); @@ -656,6 +647,15 @@ startrtclock() { u_int delta, freq; + if (cpu_feature & CPUID_TSC) + tsc_present = 1; + else + tsc_present = 0; + +#ifdef SMP + tsc_present = 0; +#endif + writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, RTCSB_24HR); @@ -689,14 +689,11 @@ startrtclock() printf( "%d Hz differs from default of %d Hz by more than 1%%\n", freq, timer_freq); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) tsc_freq = 0; -#endif } set_timer_freq(timer_freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) #ifndef CLK_USE_TSC_CALIBRATION if (tsc_freq != 0) { if (bootverbose) @@ -705,8 +702,7 @@ startrtclock() tsc_freq = 0; } #endif - if (tsc_freq == 0 && - (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { + if (tsc_present && tsc_freq == 0) { /* * Calibration of the i586 clock relative to the mc146818A * clock failed. Do a less accurate calibration relative @@ -715,12 +711,11 @@ startrtclock() wrmsr(0x10, 0LL); /* XXX */ DELAY(1000000); set_tsc_freq((u_int)rdtsc(), timer_freq); -#ifdef CLK_USE_I586_CALIBRATION +#ifdef CLK_USE_TSC_CALIBRATION if (bootverbose) printf("TSC clock: %u Hz\n", tsc_freq); #endif } -#endif } /* @@ -925,13 +920,11 @@ cpu_initclocks() #endif /* APIC_IO */ -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Finish setting up anti-jitter measures. */ if (tsc_freq != 0) tsc_bias = rdtsc(); -#endif /* Initialize RTC. */ writertc(RTC_STATUSA, rtc_statusa); @@ -988,9 +981,8 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS if (timer0_state != 0) return (EBUSY); /* too much trouble to handle */ set_timer_freq(freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - set_tsc_freq(tsc_freq, timer_freq); -#endif + if (tsc_present) + set_tsc_freq(tsc_freq, timer_freq); } return (error); } @@ -998,23 +990,22 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) static void -set_tsc_freq(u_int i586_freq, u_int i8254_freq) +set_tsc_freq(u_int tsc_count, u_int i8254_freq) { u_int comultiplier, multiplier; u_long ef; - if (i586_freq == 0) { - tsc_freq = i586_freq; + if (tsc_count == 0) { + tsc_freq = tsc_count; return; } - comultiplier = ((unsigned long long)i586_freq + comultiplier = ((unsigned long long)tsc_count << TSC_COMULTIPLIER_SHIFT) / i8254_freq; - multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / i586_freq; + multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / tsc_count; ef = read_eflags(); disable_intr(); - tsc_freq = i586_freq; + tsc_freq = tsc_count; tsc_comultiplier = comultiplier; tsc_multiplier = multiplier; CLOCK_UNLOCK(); @@ -1022,12 +1013,12 @@ set_tsc_freq(u_int i586_freq, u_int i8254_freq) } static int -sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS +sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS { int error; u_int freq; - if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686) + if (!tsc_present) return (EOPNOTSUPP); freq = tsc_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); @@ -1036,6 +1027,5 @@ sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS return (error); } -SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW, - 0, sizeof(u_int), sysctl_machdep_i586_freq, "I", ""); -#endif /* (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) */ +SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW, + 0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", ""); diff --git a/sys/i386/i386/microtime.s b/sys/i386/i386/microtime.s index 7544102d8e6d..df64698d327e 100644 --- a/sys/i386/i386/microtime.s +++ b/sys/i386/i386/microtime.s @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * from: Steve McCanne's microtime code - * $Id: microtime.s,v 1.37 1997/12/26 20:41:35 phk Exp $ + * $Id: microtime.s,v 1.38 1997/12/28 13:36:05 phk Exp $ */ #include @@ -47,7 +47,6 @@ ENTRY(microtime) -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) movl _tsc_freq, %ecx testl %ecx, %ecx je i8254_microtime @@ -57,11 +56,8 @@ ENTRY(microtime) subl _tsc_bias, %eax mull _tsc_multiplier movl %edx, %eax + popfl /* restore interrupt mask */ jmp common_microtime - ALIGN_TEXT -#else - xorl %ecx, %ecx /* clear ecx */ -#endif i8254_microtime: movb $TIMER_SEL0|TIMER_LATCH, %al /* prepare to latch */ @@ -205,10 +201,6 @@ overflow: #endif /* 0 */ shr $15, %eax -common_microtime: - addl _time+4, %eax /* usec += time.tv_sec */ - movl _time, %edx /* sec = time.tv_sec */ - #ifdef USE_CLOCKLOCK pushl %eax /* s_lock destroys %eax, %ecx */ pushl %edx /* during profiling, %edx is also destroyed */ @@ -220,6 +212,11 @@ common_microtime: #endif /* USE_CLOCKLOCK */ popfl /* restore interrupt mask */ +common_microtime: + + addl _time+4, %eax /* usec += time.tv_sec */ + movl _time, %edx /* sec = time.tv_sec */ + cmpl $1000000, %eax /* usec valid? */ jb 1f subl $1000000, %eax /* adjust usec */ diff --git a/sys/i386/i386/perfmon.c b/sys/i386/i386/perfmon.c index b8ad3e4e00ad..64acf7f3df15 100644 --- a/sys/i386/i386/perfmon.c +++ b/sys/i386/i386/perfmon.c @@ -26,7 +26,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: perfmon.c,v 1.12 1997/10/28 15:58:10 bde Exp $ + * $Id: perfmon.c,v 1.13 1997/12/26 20:41:37 phk Exp $ */ #include @@ -339,16 +339,17 @@ perfmon_ioctl(dev_t dev, int cmd, caddr_t param, int flags, struct proc *p) rv = perfmon_read(pmcd->pmcd_num, &pmcd->pmcd_value); break; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) case PMIOTSTAMP: + if (!tsc_freq) { + rv = ENOTTY; + break; + } pmct = (struct pmc_tstamp *)param; /* XXX interface loses precision. */ pmct->pmct_rate = tsc_freq / 1000000; pmct->pmct_value = rdtsc(); rv = 0; break; -#endif - default: rv = ENOTTY; } diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c index b7b12892f094..15a874c76c20 100644 --- a/sys/i386/i386/tsc.c +++ b/sys/i386/i386/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.105 1997/12/26 20:42:05 phk Exp $ + * $Id: clock.c,v 1.106 1997/12/28 13:36:07 phk Exp $ */ /* @@ -67,12 +67,14 @@ #include #include #include +#include #ifdef APIC_IO #include #endif #if defined(SMP) || defined(APIC_IO) #include #endif /* SMP || APIC_IO */ +#include #include #include @@ -126,16 +128,11 @@ u_int timer_freq = 1193182; int timer0_max_count; u_int timer0_overflow_threshold; u_int timer0_prescaler_count; -#if defined(I586_CPU) || defined(I686_CPU) -#ifndef SMP u_int tsc_bias; u_int tsc_comultiplier; -#endif u_int tsc_freq; -#ifndef SMP u_int tsc_multiplier; -#endif -#endif +u_int tsc_present; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ static int beeping = 0; @@ -163,9 +160,7 @@ static u_char timer0_state; static u_char timer2_state; static void (*timer_func) __P((struct clockframe *frame)) = hardclock; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) -static void set_tsc_freq(u_int i586_freq, u_int i8254_freq); -#endif +static void set_tsc_freq(u_int tsc_count, u_int i8254_freq); static void set_timer_freq(u_int freq, int intr_freq); static void @@ -574,10 +569,8 @@ calibrate_clocks(void) goto fail; tot_count = 0; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) + if (tsc_present) wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */ -#endif /* * Wait for the mc146818A seconds counter to change. Read the i8254 @@ -607,17 +600,15 @@ calibrate_clocks(void) goto fail; } -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Read the cpu cycle counter. The timing considerations are * similar to those for the i8254 clock. */ - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { + if (tsc_present) { set_tsc_freq((u_int)rdtsc(), tot_count); if (bootverbose) printf("TSC clock: %u Hz, ", tsc_freq); } -#endif if (bootverbose) printf("i8254 clock: %u Hz\n", tot_count); @@ -656,6 +647,15 @@ startrtclock() { u_int delta, freq; + if (cpu_feature & CPUID_TSC) + tsc_present = 1; + else + tsc_present = 0; + +#ifdef SMP + tsc_present = 0; +#endif + writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, RTCSB_24HR); @@ -689,14 +689,11 @@ startrtclock() printf( "%d Hz differs from default of %d Hz by more than 1%%\n", freq, timer_freq); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) tsc_freq = 0; -#endif } set_timer_freq(timer_freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) #ifndef CLK_USE_TSC_CALIBRATION if (tsc_freq != 0) { if (bootverbose) @@ -705,8 +702,7 @@ startrtclock() tsc_freq = 0; } #endif - if (tsc_freq == 0 && - (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { + if (tsc_present && tsc_freq == 0) { /* * Calibration of the i586 clock relative to the mc146818A * clock failed. Do a less accurate calibration relative @@ -715,12 +711,11 @@ startrtclock() wrmsr(0x10, 0LL); /* XXX */ DELAY(1000000); set_tsc_freq((u_int)rdtsc(), timer_freq); -#ifdef CLK_USE_I586_CALIBRATION +#ifdef CLK_USE_TSC_CALIBRATION if (bootverbose) printf("TSC clock: %u Hz\n", tsc_freq); #endif } -#endif } /* @@ -925,13 +920,11 @@ cpu_initclocks() #endif /* APIC_IO */ -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Finish setting up anti-jitter measures. */ if (tsc_freq != 0) tsc_bias = rdtsc(); -#endif /* Initialize RTC. */ writertc(RTC_STATUSA, rtc_statusa); @@ -988,9 +981,8 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS if (timer0_state != 0) return (EBUSY); /* too much trouble to handle */ set_timer_freq(freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - set_tsc_freq(tsc_freq, timer_freq); -#endif + if (tsc_present) + set_tsc_freq(tsc_freq, timer_freq); } return (error); } @@ -998,23 +990,22 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) static void -set_tsc_freq(u_int i586_freq, u_int i8254_freq) +set_tsc_freq(u_int tsc_count, u_int i8254_freq) { u_int comultiplier, multiplier; u_long ef; - if (i586_freq == 0) { - tsc_freq = i586_freq; + if (tsc_count == 0) { + tsc_freq = tsc_count; return; } - comultiplier = ((unsigned long long)i586_freq + comultiplier = ((unsigned long long)tsc_count << TSC_COMULTIPLIER_SHIFT) / i8254_freq; - multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / i586_freq; + multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / tsc_count; ef = read_eflags(); disable_intr(); - tsc_freq = i586_freq; + tsc_freq = tsc_count; tsc_comultiplier = comultiplier; tsc_multiplier = multiplier; CLOCK_UNLOCK(); @@ -1022,12 +1013,12 @@ set_tsc_freq(u_int i586_freq, u_int i8254_freq) } static int -sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS +sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS { int error; u_int freq; - if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686) + if (!tsc_present) return (EOPNOTSUPP); freq = tsc_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); @@ -1036,6 +1027,5 @@ sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS return (error); } -SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW, - 0, sizeof(u_int), sysctl_machdep_i586_freq, "I", ""); -#endif /* (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) */ +SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW, + 0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", ""); diff --git a/sys/i386/include/clock.h b/sys/i386/include/clock.h index 505ea4868fe8..a8f2d5a7efa3 100644 --- a/sys/i386/include/clock.h +++ b/sys/i386/include/clock.h @@ -3,17 +3,13 @@ * Garrett Wollman, September 1994. * This file is in the public domain. * - * $Id: clock.h,v 1.28 1997/12/26 20:42:01 phk Exp $ + * $Id: clock.h,v 1.29 1997/12/28 13:36:06 phk Exp $ */ #ifndef _MACHINE_CLOCK_H_ #define _MACHINE_CLOCK_H_ -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) #define CPU_CLOCKUPDATE(otime, ntime) cpu_clockupdate((otime), (ntime)) -#else -#define CPU_CLOCKUPDATE(otime, ntime) (*(otime) = *(ntime)) -#endif #define CPU_THISTICKLEN(dflt) dflt @@ -33,16 +29,10 @@ extern u_int timer_freq; extern int timer0_max_count; extern u_int timer0_overflow_threshold; extern u_int timer0_prescaler_count; -#if defined(I586_CPU) || defined(I686_CPU) -#ifndef SMP extern u_int tsc_bias; extern u_int tsc_comultiplier; -#endif extern u_int tsc_freq; -#ifndef SMP extern u_int tsc_multiplier; -#endif -#endif extern int wall_cmos_clock; /* @@ -85,7 +75,6 @@ clock_latency(void) - ((high << 8) | low)); } -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * When we update `time', on we also update `tsc_bias' * atomically. `tsc_bias' is the best available approximation to @@ -117,7 +106,6 @@ cpu_clockupdate(volatile struct timeval *otime, struct timeval *ntime) } else *otime = *ntime; } -#endif /* I586_CPU || I686_CPU */ #endif /* CLOCK_HAIR */ diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index b7b12892f094..15a874c76c20 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.105 1997/12/26 20:42:05 phk Exp $ + * $Id: clock.c,v 1.106 1997/12/28 13:36:07 phk Exp $ */ /* @@ -67,12 +67,14 @@ #include #include #include +#include #ifdef APIC_IO #include #endif #if defined(SMP) || defined(APIC_IO) #include #endif /* SMP || APIC_IO */ +#include #include #include @@ -126,16 +128,11 @@ u_int timer_freq = 1193182; int timer0_max_count; u_int timer0_overflow_threshold; u_int timer0_prescaler_count; -#if defined(I586_CPU) || defined(I686_CPU) -#ifndef SMP u_int tsc_bias; u_int tsc_comultiplier; -#endif u_int tsc_freq; -#ifndef SMP u_int tsc_multiplier; -#endif -#endif +u_int tsc_present; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ static int beeping = 0; @@ -163,9 +160,7 @@ static u_char timer0_state; static u_char timer2_state; static void (*timer_func) __P((struct clockframe *frame)) = hardclock; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) -static void set_tsc_freq(u_int i586_freq, u_int i8254_freq); -#endif +static void set_tsc_freq(u_int tsc_count, u_int i8254_freq); static void set_timer_freq(u_int freq, int intr_freq); static void @@ -574,10 +569,8 @@ calibrate_clocks(void) goto fail; tot_count = 0; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) + if (tsc_present) wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */ -#endif /* * Wait for the mc146818A seconds counter to change. Read the i8254 @@ -607,17 +600,15 @@ calibrate_clocks(void) goto fail; } -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Read the cpu cycle counter. The timing considerations are * similar to those for the i8254 clock. */ - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { + if (tsc_present) { set_tsc_freq((u_int)rdtsc(), tot_count); if (bootverbose) printf("TSC clock: %u Hz, ", tsc_freq); } -#endif if (bootverbose) printf("i8254 clock: %u Hz\n", tot_count); @@ -656,6 +647,15 @@ startrtclock() { u_int delta, freq; + if (cpu_feature & CPUID_TSC) + tsc_present = 1; + else + tsc_present = 0; + +#ifdef SMP + tsc_present = 0; +#endif + writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, RTCSB_24HR); @@ -689,14 +689,11 @@ startrtclock() printf( "%d Hz differs from default of %d Hz by more than 1%%\n", freq, timer_freq); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) tsc_freq = 0; -#endif } set_timer_freq(timer_freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) #ifndef CLK_USE_TSC_CALIBRATION if (tsc_freq != 0) { if (bootverbose) @@ -705,8 +702,7 @@ startrtclock() tsc_freq = 0; } #endif - if (tsc_freq == 0 && - (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { + if (tsc_present && tsc_freq == 0) { /* * Calibration of the i586 clock relative to the mc146818A * clock failed. Do a less accurate calibration relative @@ -715,12 +711,11 @@ startrtclock() wrmsr(0x10, 0LL); /* XXX */ DELAY(1000000); set_tsc_freq((u_int)rdtsc(), timer_freq); -#ifdef CLK_USE_I586_CALIBRATION +#ifdef CLK_USE_TSC_CALIBRATION if (bootverbose) printf("TSC clock: %u Hz\n", tsc_freq); #endif } -#endif } /* @@ -925,13 +920,11 @@ cpu_initclocks() #endif /* APIC_IO */ -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Finish setting up anti-jitter measures. */ if (tsc_freq != 0) tsc_bias = rdtsc(); -#endif /* Initialize RTC. */ writertc(RTC_STATUSA, rtc_statusa); @@ -988,9 +981,8 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS if (timer0_state != 0) return (EBUSY); /* too much trouble to handle */ set_timer_freq(freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - set_tsc_freq(tsc_freq, timer_freq); -#endif + if (tsc_present) + set_tsc_freq(tsc_freq, timer_freq); } return (error); } @@ -998,23 +990,22 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) static void -set_tsc_freq(u_int i586_freq, u_int i8254_freq) +set_tsc_freq(u_int tsc_count, u_int i8254_freq) { u_int comultiplier, multiplier; u_long ef; - if (i586_freq == 0) { - tsc_freq = i586_freq; + if (tsc_count == 0) { + tsc_freq = tsc_count; return; } - comultiplier = ((unsigned long long)i586_freq + comultiplier = ((unsigned long long)tsc_count << TSC_COMULTIPLIER_SHIFT) / i8254_freq; - multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / i586_freq; + multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / tsc_count; ef = read_eflags(); disable_intr(); - tsc_freq = i586_freq; + tsc_freq = tsc_count; tsc_comultiplier = comultiplier; tsc_multiplier = multiplier; CLOCK_UNLOCK(); @@ -1022,12 +1013,12 @@ set_tsc_freq(u_int i586_freq, u_int i8254_freq) } static int -sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS +sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS { int error; u_int freq; - if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686) + if (!tsc_present) return (EOPNOTSUPP); freq = tsc_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); @@ -1036,6 +1027,5 @@ sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS return (error); } -SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW, - 0, sizeof(u_int), sysctl_machdep_i586_freq, "I", ""); -#endif /* (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) */ +SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW, + 0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", ""); diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index b7b12892f094..15a874c76c20 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.105 1997/12/26 20:42:05 phk Exp $ + * $Id: clock.c,v 1.106 1997/12/28 13:36:07 phk Exp $ */ /* @@ -67,12 +67,14 @@ #include #include #include +#include #ifdef APIC_IO #include #endif #if defined(SMP) || defined(APIC_IO) #include #endif /* SMP || APIC_IO */ +#include #include #include @@ -126,16 +128,11 @@ u_int timer_freq = 1193182; int timer0_max_count; u_int timer0_overflow_threshold; u_int timer0_prescaler_count; -#if defined(I586_CPU) || defined(I686_CPU) -#ifndef SMP u_int tsc_bias; u_int tsc_comultiplier; -#endif u_int tsc_freq; -#ifndef SMP u_int tsc_multiplier; -#endif -#endif +u_int tsc_present; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ static int beeping = 0; @@ -163,9 +160,7 @@ static u_char timer0_state; static u_char timer2_state; static void (*timer_func) __P((struct clockframe *frame)) = hardclock; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) -static void set_tsc_freq(u_int i586_freq, u_int i8254_freq); -#endif +static void set_tsc_freq(u_int tsc_count, u_int i8254_freq); static void set_timer_freq(u_int freq, int intr_freq); static void @@ -574,10 +569,8 @@ calibrate_clocks(void) goto fail; tot_count = 0; -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) + if (tsc_present) wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */ -#endif /* * Wait for the mc146818A seconds counter to change. Read the i8254 @@ -607,17 +600,15 @@ calibrate_clocks(void) goto fail; } -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Read the cpu cycle counter. The timing considerations are * similar to those for the i8254 clock. */ - if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { + if (tsc_present) { set_tsc_freq((u_int)rdtsc(), tot_count); if (bootverbose) printf("TSC clock: %u Hz, ", tsc_freq); } -#endif if (bootverbose) printf("i8254 clock: %u Hz\n", tot_count); @@ -656,6 +647,15 @@ startrtclock() { u_int delta, freq; + if (cpu_feature & CPUID_TSC) + tsc_present = 1; + else + tsc_present = 0; + +#ifdef SMP + tsc_present = 0; +#endif + writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, RTCSB_24HR); @@ -689,14 +689,11 @@ startrtclock() printf( "%d Hz differs from default of %d Hz by more than 1%%\n", freq, timer_freq); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) tsc_freq = 0; -#endif } set_timer_freq(timer_freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) #ifndef CLK_USE_TSC_CALIBRATION if (tsc_freq != 0) { if (bootverbose) @@ -705,8 +702,7 @@ startrtclock() tsc_freq = 0; } #endif - if (tsc_freq == 0 && - (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { + if (tsc_present && tsc_freq == 0) { /* * Calibration of the i586 clock relative to the mc146818A * clock failed. Do a less accurate calibration relative @@ -715,12 +711,11 @@ startrtclock() wrmsr(0x10, 0LL); /* XXX */ DELAY(1000000); set_tsc_freq((u_int)rdtsc(), timer_freq); -#ifdef CLK_USE_I586_CALIBRATION +#ifdef CLK_USE_TSC_CALIBRATION if (bootverbose) printf("TSC clock: %u Hz\n", tsc_freq); #endif } -#endif } /* @@ -925,13 +920,11 @@ cpu_initclocks() #endif /* APIC_IO */ -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) /* * Finish setting up anti-jitter measures. */ if (tsc_freq != 0) tsc_bias = rdtsc(); -#endif /* Initialize RTC. */ writertc(RTC_STATUSA, rtc_statusa); @@ -988,9 +981,8 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS if (timer0_state != 0) return (EBUSY); /* too much trouble to handle */ set_timer_freq(freq, hz); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) - set_tsc_freq(tsc_freq, timer_freq); -#endif + if (tsc_present) + set_tsc_freq(tsc_freq, timer_freq); } return (error); } @@ -998,23 +990,22 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); -#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) static void -set_tsc_freq(u_int i586_freq, u_int i8254_freq) +set_tsc_freq(u_int tsc_count, u_int i8254_freq) { u_int comultiplier, multiplier; u_long ef; - if (i586_freq == 0) { - tsc_freq = i586_freq; + if (tsc_count == 0) { + tsc_freq = tsc_count; return; } - comultiplier = ((unsigned long long)i586_freq + comultiplier = ((unsigned long long)tsc_count << TSC_COMULTIPLIER_SHIFT) / i8254_freq; - multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / i586_freq; + multiplier = (1000000LL << TSC_MULTIPLIER_SHIFT) / tsc_count; ef = read_eflags(); disable_intr(); - tsc_freq = i586_freq; + tsc_freq = tsc_count; tsc_comultiplier = comultiplier; tsc_multiplier = multiplier; CLOCK_UNLOCK(); @@ -1022,12 +1013,12 @@ set_tsc_freq(u_int i586_freq, u_int i8254_freq) } static int -sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS +sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS { int error; u_int freq; - if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686) + if (!tsc_present) return (EOPNOTSUPP); freq = tsc_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); @@ -1036,6 +1027,5 @@ sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS return (error); } -SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW, - 0, sizeof(u_int), sysctl_machdep_i586_freq, "I", ""); -#endif /* (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) */ +SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW, + 0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", "");