diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2004-03-09 23:05:14 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2004-03-09 23:05:14 +0000 |
commit | 39cb247af46536e5a7d0a097f52832fc60d9905f (patch) | |
tree | d6c28e376fbff53b3481581fc7b7e15255e6297c /sys/arch/amd64/isa | |
parent | f0ae6fb0bf466588839c30aa7f844383b0350d74 (diff) |
simplify the delay stuff
Diffstat (limited to 'sys/arch/amd64/isa')
-rw-r--r-- | sys/arch/amd64/isa/clock.c | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/sys/arch/amd64/isa/clock.c b/sys/arch/amd64/isa/clock.c index 524ad712ec3..8c2fc2dab1f 100644 --- a/sys/arch/amd64/isa/clock.c +++ b/sys/arch/amd64/isa/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.1 2004/01/28 01:39:39 mickey Exp $ */ +/* $OpenBSD: clock.c,v 1.2 2004/03/09 23:05:13 deraadt Exp $ */ /* $NetBSD: clock.c,v 1.1 2003/04/26 18:39:50 fvdl Exp $ */ /*- @@ -184,6 +184,8 @@ mc146818_write(sc, reg, datum) DELAY(1); } +static u_long rtclock_tval; + /* minimal initialization, enough for delay() */ void initrtclock() @@ -204,6 +206,8 @@ initrtclock() /* Correct rounding will buy us a better precision in timekeeping */ outb(IO_TIMER1+TIMER_CNTR0, tval % 256); outb(IO_TIMER1+TIMER_CNTR0, tval / 256); + + rtclock_tval = tval; } /* @@ -310,9 +314,18 @@ gettick() * wave' mode counts at 2:1). */ void -i8254_delay(int n) +delay(int n) { int limit, tick, otick; + static const int delaytab[26] = { + 0, 2, 3, 4, 5, 6, 7, 9, 10, 11, + 12, 13, 15, 16, 17, 18, 19, 21, 22, 23, + 24, 25, 27, 28, 29, 30, + }; + + /* allow DELAY() to be used before startrtclock() */ + if (!rtclock_tval) + initrtclock(); /* * Read the counter first, so that the rest of the setup overhead is @@ -320,34 +333,35 @@ i8254_delay(int n) */ otick = gettick(); + if (n <= 25) + n = delaytab[n]; + else { #ifdef __GNUC__ - /* - * Calculate ((n * TIMER_FREQ) / 1e6) using explicit assembler code so - * we can take advantage of the intermediate 64-bit quantity to prevent - * loss of significance. - */ - n -= 5; - if (n < 0) - return; - __asm __volatile("mul %2\n\tdiv %3" - : "=a" (n) - : "0" (n), "r" (TIMER_FREQ), "r" (1000000) - : "%edx", "cc"); + /* + * Calculate ((n * TIMER_FREQ) / 1e6) using explicit assembler + * code so we can take advantage of the intermediate 64-bit + * quantity to prevent loss of significance. + */ + int m; + __asm __volatile("mul %3" + : "=a" (n), "=d" (m) + : "0" (n), "r" (TIMER_FREQ)); + __asm __volatile("div %4" + : "=a" (n), "=d" (m) + : "0" (n), "1" (m), "r" (1000000)); #else - /* - * Calculate ((n * TIMER_FREQ) / 1e6) without using floating point and - * without any avoidable overflows. - */ - n -= 20; - { + /* + * Calculate ((n * TIMER_FREQ) / 1e6) without using floating + * point and without any avoidable overflows. + */ int sec = n / 1000000, usec = n % 1000000; n = sec * TIMER_FREQ + usec * (TIMER_FREQ / 1000000) + usec * ((TIMER_FREQ % 1000000) / 1000) / 1000 + usec * (TIMER_FREQ % 1000) / 1000000; - } #endif + } limit = TIMER_FREQ / hz; @@ -435,7 +449,7 @@ rtcdrain(void *v) } void -i8254_initclocks() +cpu_initclocks() { static struct timeout rtcdrain_timeout; |