aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBruce Evans <bde@FreeBSD.org>1996-10-25 13:01:56 +0000
committerBruce Evans <bde@FreeBSD.org>1996-10-25 13:01:56 +0000
commit835bd1ce62ebd0b706c83528cc57a9f4a005d617 (patch)
tree5968eb78feb617d966921606e10992b228f61554 /sys
parent22b9cd6f99c5bdb80b197cf30657b937861a39b0 (diff)
downloadsrc-835bd1ce62ebd0b706c83528cc57a9f4a005d617.tar.gz
src-835bd1ce62ebd0b706c83528cc57a9f4a005d617.zip
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/include/clock.h113
-rw-r--r--sys/i386/include/clock.h113
-rw-r--r--sys/kern/kern_clock.c3
-rw-r--r--sys/kern/kern_tc.c3
-rw-r--r--sys/kern/kern_timeout.c3
5 files changed, 130 insertions, 105 deletions
diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h
index 9c6646ebc965..f20902f59128 100644
--- a/sys/amd64/include/clock.h
+++ b/sys/amd64/include/clock.h
@@ -3,48 +3,24 @@
* Garrett Wollman, September 1994.
* This file is in the public domain.
*
- * $Id: clock.h,v 1.18 1996/10/10 10:25:26 bde Exp $
+ * $Id: clock.h,v 1.19 1996/10/17 17:31:25 bde Exp $
*/
#ifndef _MACHINE_CLOCK_H_
#define _MACHINE_CLOCK_H_
#if defined(I586_CPU) || defined(I686_CPU)
-
-/*
- * When we update the clock, we also update this bias value which is
- * automatically subtracted in microtime(). We assume that CPU_THISTICKLEN()
- * has been called at some point in the past, so that an appropriate value is
- * set up in i586_last_tick. (This works even if we are not being called
- * from hardclock because hardclock will have run before and will made the
- * call.)
- */
-#define CPU_CLOCKUPDATE(otime, ntime) \
- do { \
- if (i586_ctr_freq != 0) { \
- disable_intr(); \
- i586_ctr_bias = i586_last_tick; \
- *(otime) = *(ntime); \
- enable_intr(); \
- } else { \
- *(otime) = *(ntime); \
- } \
- } while(0)
-
-#define CPU_THISTICKLEN(dflt) cpu_thisticklen(dflt)
+#define CPU_CLOCKUPDATE(otime, ntime) cpu_clockupdate((otime), (ntime))
#else
-#define CPU_CLOCKUPDATE(otime, ntime) \
- (*(otime) = *(ntime))
-#define CPU_THISTICKLEN(dflt) dflt
+#define CPU_CLOCKUPDATE(otime, ntime) (*(otime) = *(ntime))
#endif
+#define CPU_THISTICKLEN(dflt) dflt
+
#define I586_CTR_COMULTIPLIER_SHIFT 20
#define I586_CTR_MULTIPLIER_SHIFT 32
-#if defined(KERNEL) && !defined(LOCORE)
-#include <sys/cdefs.h>
-#include <machine/frame.h>
-
+#ifdef KERNEL
/*
* i386 to clock driver interface.
* XXX almost all of it is misplaced. i586 stuff is done in isa/clock.c
@@ -57,8 +33,6 @@ extern u_int i586_ctr_bias;
extern u_int i586_ctr_comultiplier;
extern u_int i586_ctr_freq;
extern u_int i586_ctr_multiplier;
-extern long long i586_last_tick;
-extern unsigned long i586_avg_tick;
#endif
extern int statclock_disable;
extern u_int timer_freq;
@@ -67,27 +41,11 @@ extern u_int timer0_overflow_threshold;
extern u_int timer0_prescaler_count;
extern int wall_cmos_clock;
-#if defined(I586_CPU) || defined(I686_CPU)
-static __inline u_long
-cpu_thisticklen(u_long dflt)
-{
- long long old;
- long len;
-
- if (i586_ctr_freq != 0) {
- old = i586_last_tick;
- i586_last_tick = rdtsc();
- len = ((i586_last_tick - old) * i586_ctr_multiplier)
- >> I586_CTR_MULTIPLIER_SHIFT;
- i586_avg_tick = i586_avg_tick * 15 / 16 + len / 16;
- }
- return dflt;
-}
-#endif
-
/*
* Driver to clock driver interface.
*/
+struct clockframe;
+
void DELAY __P((int usec));
int acquire_timer0 __P((int rate,
void (*function)(struct clockframe *frame)));
@@ -105,6 +63,59 @@ void rtc_outb __P((int val));
#endif
int sysbeep __P((int pitch, int period));
-#endif /* KERNEL && !LOCORE */
+#ifdef CLOCK_HAIR
+
+#include <i386/isa/isa.h> /* XXX */
+#include <i386/isa/timerreg.h> /* XXX */
+
+static __inline u_int
+clock_latency(void)
+{
+ u_char high, low;
+
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
+ low = inb(TIMER_CNTR0);
+ high = inb(TIMER_CNTR0);
+ return (timer0_prescaler_count + timer0_max_count
+ - ((high << 8) | low));
+}
+
+#if defined(I586_CPU) || defined(I686_CPU)
+/*
+ * When we update `time', on i586's we also update `i586_ctr_bias'
+ * atomically. `i586_ctr_bias' is the best available approximation to
+ * the value of the i586 counter (mod 2^32) at the time of the i8254
+ * counter transition that caused the clock interrupt that caused the
+ * update. clock_latency() gives the time between the transition and
+ * the update to within a few usec provided another such transition
+ * hasn't occurred. We don't bother checking for counter overflow as
+ * in microtime(), since if it occurs then we're close to losing clock
+ * interrupts.
+ */
+static __inline void
+cpu_clockupdate(volatile struct timeval *otime, struct timeval *ntime)
+{
+ if (i586_ctr_freq != 0) {
+ u_int i586_count; /* truncated */
+ u_int i8254_count;
+
+ disable_intr();
+ i8254_count = clock_latency();
+ i586_count = rdtsc();
+ i586_ctr_bias = i586_count
+ - (u_int)
+ (((unsigned long long)i586_ctr_comultiplier
+ * i8254_count)
+ >> I586_CTR_COMULTIPLIER_SHIFT);
+ *otime = *ntime;
+ enable_intr();
+ } else
+ *otime = *ntime;
+}
+#endif /* I586_CPU || I686_CPU */
+
+#endif /* CLOCK_HAIR */
+
+#endif /* KERNEL */
#endif /* !_MACHINE_CLOCK_H_ */
diff --git a/sys/i386/include/clock.h b/sys/i386/include/clock.h
index 9c6646ebc965..f20902f59128 100644
--- a/sys/i386/include/clock.h
+++ b/sys/i386/include/clock.h
@@ -3,48 +3,24 @@
* Garrett Wollman, September 1994.
* This file is in the public domain.
*
- * $Id: clock.h,v 1.18 1996/10/10 10:25:26 bde Exp $
+ * $Id: clock.h,v 1.19 1996/10/17 17:31:25 bde Exp $
*/
#ifndef _MACHINE_CLOCK_H_
#define _MACHINE_CLOCK_H_
#if defined(I586_CPU) || defined(I686_CPU)
-
-/*
- * When we update the clock, we also update this bias value which is
- * automatically subtracted in microtime(). We assume that CPU_THISTICKLEN()
- * has been called at some point in the past, so that an appropriate value is
- * set up in i586_last_tick. (This works even if we are not being called
- * from hardclock because hardclock will have run before and will made the
- * call.)
- */
-#define CPU_CLOCKUPDATE(otime, ntime) \
- do { \
- if (i586_ctr_freq != 0) { \
- disable_intr(); \
- i586_ctr_bias = i586_last_tick; \
- *(otime) = *(ntime); \
- enable_intr(); \
- } else { \
- *(otime) = *(ntime); \
- } \
- } while(0)
-
-#define CPU_THISTICKLEN(dflt) cpu_thisticklen(dflt)
+#define CPU_CLOCKUPDATE(otime, ntime) cpu_clockupdate((otime), (ntime))
#else
-#define CPU_CLOCKUPDATE(otime, ntime) \
- (*(otime) = *(ntime))
-#define CPU_THISTICKLEN(dflt) dflt
+#define CPU_CLOCKUPDATE(otime, ntime) (*(otime) = *(ntime))
#endif
+#define CPU_THISTICKLEN(dflt) dflt
+
#define I586_CTR_COMULTIPLIER_SHIFT 20
#define I586_CTR_MULTIPLIER_SHIFT 32
-#if defined(KERNEL) && !defined(LOCORE)
-#include <sys/cdefs.h>
-#include <machine/frame.h>
-
+#ifdef KERNEL
/*
* i386 to clock driver interface.
* XXX almost all of it is misplaced. i586 stuff is done in isa/clock.c
@@ -57,8 +33,6 @@ extern u_int i586_ctr_bias;
extern u_int i586_ctr_comultiplier;
extern u_int i586_ctr_freq;
extern u_int i586_ctr_multiplier;
-extern long long i586_last_tick;
-extern unsigned long i586_avg_tick;
#endif
extern int statclock_disable;
extern u_int timer_freq;
@@ -67,27 +41,11 @@ extern u_int timer0_overflow_threshold;
extern u_int timer0_prescaler_count;
extern int wall_cmos_clock;
-#if defined(I586_CPU) || defined(I686_CPU)
-static __inline u_long
-cpu_thisticklen(u_long dflt)
-{
- long long old;
- long len;
-
- if (i586_ctr_freq != 0) {
- old = i586_last_tick;
- i586_last_tick = rdtsc();
- len = ((i586_last_tick - old) * i586_ctr_multiplier)
- >> I586_CTR_MULTIPLIER_SHIFT;
- i586_avg_tick = i586_avg_tick * 15 / 16 + len / 16;
- }
- return dflt;
-}
-#endif
-
/*
* Driver to clock driver interface.
*/
+struct clockframe;
+
void DELAY __P((int usec));
int acquire_timer0 __P((int rate,
void (*function)(struct clockframe *frame)));
@@ -105,6 +63,59 @@ void rtc_outb __P((int val));
#endif
int sysbeep __P((int pitch, int period));
-#endif /* KERNEL && !LOCORE */
+#ifdef CLOCK_HAIR
+
+#include <i386/isa/isa.h> /* XXX */
+#include <i386/isa/timerreg.h> /* XXX */
+
+static __inline u_int
+clock_latency(void)
+{
+ u_char high, low;
+
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
+ low = inb(TIMER_CNTR0);
+ high = inb(TIMER_CNTR0);
+ return (timer0_prescaler_count + timer0_max_count
+ - ((high << 8) | low));
+}
+
+#if defined(I586_CPU) || defined(I686_CPU)
+/*
+ * When we update `time', on i586's we also update `i586_ctr_bias'
+ * atomically. `i586_ctr_bias' is the best available approximation to
+ * the value of the i586 counter (mod 2^32) at the time of the i8254
+ * counter transition that caused the clock interrupt that caused the
+ * update. clock_latency() gives the time between the transition and
+ * the update to within a few usec provided another such transition
+ * hasn't occurred. We don't bother checking for counter overflow as
+ * in microtime(), since if it occurs then we're close to losing clock
+ * interrupts.
+ */
+static __inline void
+cpu_clockupdate(volatile struct timeval *otime, struct timeval *ntime)
+{
+ if (i586_ctr_freq != 0) {
+ u_int i586_count; /* truncated */
+ u_int i8254_count;
+
+ disable_intr();
+ i8254_count = clock_latency();
+ i586_count = rdtsc();
+ i586_ctr_bias = i586_count
+ - (u_int)
+ (((unsigned long long)i586_ctr_comultiplier
+ * i8254_count)
+ >> I586_CTR_COMULTIPLIER_SHIFT);
+ *otime = *ntime;
+ enable_intr();
+ } else
+ *otime = *ntime;
+}
+#endif /* I586_CPU || I686_CPU */
+
+#endif /* CLOCK_HAIR */
+
+#endif /* KERNEL */
#endif /* !_MACHINE_CLOCK_H_ */
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index d94d53ea6237..b1f3bb061552 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
- * $Id: kern_clock.c,v 1.26 1996/07/30 16:59:22 bde Exp $
+ * $Id: kern_clock.c,v 1.27 1996/10/10 10:25:03 bde Exp $
*/
/* Portions of this software are covered by the following: */
@@ -76,6 +76,7 @@
#include <sys/sysctl.h>
#include <machine/cpu.h>
+#define CLOCK_HAIR /* XXX */
#include <machine/clock.h>
#ifdef GPROF
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index d94d53ea6237..b1f3bb061552 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
- * $Id: kern_clock.c,v 1.26 1996/07/30 16:59:22 bde Exp $
+ * $Id: kern_clock.c,v 1.27 1996/10/10 10:25:03 bde Exp $
*/
/* Portions of this software are covered by the following: */
@@ -76,6 +76,7 @@
#include <sys/sysctl.h>
#include <machine/cpu.h>
+#define CLOCK_HAIR /* XXX */
#include <machine/clock.h>
#ifdef GPROF
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index d94d53ea6237..b1f3bb061552 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
- * $Id: kern_clock.c,v 1.26 1996/07/30 16:59:22 bde Exp $
+ * $Id: kern_clock.c,v 1.27 1996/10/10 10:25:03 bde Exp $
*/
/* Portions of this software are covered by the following: */
@@ -76,6 +76,7 @@
#include <sys/sysctl.h>
#include <machine/cpu.h>
+#define CLOCK_HAIR /* XXX */
#include <machine/clock.h>
#ifdef GPROF