diff options
author | bde <bde@FreeBSD.org> | 1998-02-13 06:33:16 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1998-02-13 06:33:16 +0000 |
commit | c0758a12df13db5ca34c99e7facb377ddf0fa69a (patch) | |
tree | 6c9b88dc5bd9c030811253123bcce20f1c0c3e82 /sys/i386/isa/clock.c | |
parent | 793b3fcc96da24432a08fc9c09fd7753c2f7a229 (diff) | |
download | FreeBSD-src-c0758a12df13db5ca34c99e7facb377ddf0fa69a.zip FreeBSD-src-c0758a12df13db5ca34c99e7facb377ddf0fa69a.tar.gz |
Update timer0_prescaler_count before calling hardclock() while timer0
is "acquired". This fixes a TSC biasing error of about 10 msec when
pcaudio is active.
Update `time' before calling hardclock() when timer0 is being released.
This is not known to be important.
Added some delays in writertc(). Efficiency is not critical here, unlike
in rtcin(), and we already use conservative delays there.
Don't touch the hardware when machdep.i8254_freq is being changed but
the maximum count wouldn't change. This fixes jitter of up to 10 msec
for most small adjustments to machdep.i8254_freq. When the maximum
count needs to change, the hardware should be adjusted more carefully.
Diffstat (limited to 'sys/i386/isa/clock.c')
-rw-r--r-- | sys/i386/isa/clock.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index 0732bd1..2fb46cb 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.108 1998/01/28 10:41:33 phk Exp $ + * $Id: clock.c,v 1.109 1998/02/09 06:08:26 eivind Exp $ */ /* @@ -176,9 +176,9 @@ clkintr(struct clockframe frame) case ACQUIRED: if ((timer0_prescaler_count += timer0_max_count) >= hardclock_max_count) { + timer0_prescaler_count -= hardclock_max_count; hardclock(&frame); setdelayed(); - timer0_prescaler_count -= hardclock_max_count; } break; @@ -200,6 +200,13 @@ clkintr(struct clockframe frame) case RELEASE_PENDING: if ((timer0_prescaler_count += timer0_max_count) >= hardclock_max_count) { + timer0_prescaler_count -= hardclock_max_count; + /* + * See microtime.s for this magic. + */ + time.tv_usec += (27465 * timer0_prescaler_count) >> 15; + if (time.tv_usec >= 1000000) + time.tv_usec -= 1000000; hardclock(&frame); setdelayed(); timer0_max_count = hardclock_max_count; @@ -211,14 +218,6 @@ clkintr(struct clockframe frame) outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); enable_intr(); - /* - * See microtime.s for this magic. - */ - time.tv_usec += (27465 * - (timer0_prescaler_count - hardclock_max_count)) - >> 15; - if (time.tv_usec >= 1000000) - time.tv_usec -= 1000000; timer0_prescaler_count = 0; timer_func = hardclock; timer0_state = RELEASED; @@ -519,8 +518,11 @@ rtcin(reg) static __inline void writertc(u_char reg, u_char val) { + inb(0x84); outb(IO_RTC, reg); + inb(0x84); outb(IO_RTC + 1, val); + inb(0x84); /* XXX work around wrong order in rtcin() */ } static __inline int @@ -625,15 +627,20 @@ static void set_timer_freq(u_int freq, int intr_freq) { u_long ef; + int new_timer0_max_count; ef = read_eflags(); disable_intr(); timer_freq = freq; - timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); - timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); - outb(TIMER_CNTR0, timer0_max_count & 0xff); - outb(TIMER_CNTR0, timer0_max_count >> 8); + new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); + if (new_timer0_max_count != timer0_max_count) { + timer0_max_count = new_timer0_max_count; + timer0_overflow_threshold = timer0_max_count - + TIMER0_LATCH_COUNT; + outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); + outb(TIMER_CNTR0, timer0_max_count & 0xff); + outb(TIMER_CNTR0, timer0_max_count >> 8); + } CLOCK_UNLOCK(); write_eflags(ef); } |