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.
This commit is contained in:
parent
9f449d2aa2
commit
1d804e7925
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=33309
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user