summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/clock.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1997-12-28 17:33:10 +0000
committerphk <phk@FreeBSD.org>1997-12-28 17:33:10 +0000
commit87f11cf19320871fea90474134dca49de7749362 (patch)
tree6567ea6c3ae751ee6e0cae4b8ffab4e5187cb408 /sys/i386/isa/clock.c
parentca105236ff16f62ac2fdcdd9591281b1a4d2995f (diff)
downloadFreeBSD-src-87f11cf19320871fea90474134dca49de7749362.zip
FreeBSD-src-87f11cf19320871fea90474134dca49de7749362.tar.gz
More cleanup relating to our use of the TSC.
Look in the cpu_feature (CPUID output) to see if we have it.
Diffstat (limited to 'sys/i386/isa/clock.c')
-rw-r--r--sys/i386/isa/clock.c70
1 files changed, 30 insertions, 40 deletions
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
index b7b1289..15a874c 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 <machine/frame.h>
#include <machine/ipl.h>
#include <machine/limits.h>
+#include <machine/md_var.h>
#ifdef APIC_IO
#include <machine/segments.h>
#endif
#if defined(SMP) || defined(APIC_IO)
#include <machine/smp.h>
#endif /* SMP || APIC_IO */
+#include <machine/specialreg.h>
#include <i386/isa/icu.h>
#include <i386/isa/isa.h>
@@ -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", "");
OpenPOWER on IntegriCloud