MFi386: r1.221: use simple timecounter that is aware of irq0 being off.

Approved by:  re
This commit is contained in:
Peter Wemm 2005-07-01 20:13:19 +00:00
parent 2b0f687b5d
commit 27e11adbbb

View File

@ -127,6 +127,7 @@ static u_char rtc_statusb = RTCSB_24HR;
static u_char timer2_state;
static unsigned i8254_get_timecount(struct timecounter *tc);
static unsigned i8254_simple_get_timecount(struct timecounter *tc);
static void set_timer_freq(u_int freq, int intr_freq);
static struct timecounter i8254_timecounter = {
@ -518,10 +519,15 @@ set_timer_freq(u_int freq, int intr_freq)
{
int new_timer0_max_count;
i8254_timecounter.tc_frequency = freq;
mtx_lock_spin(&clock_lock);
timer_freq = freq;
new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (new_timer0_max_count != timer0_max_count) {
if (using_lapic_timer) {
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, 0);
outb(TIMER_CNTR0, 0);
} else if (new_timer0_max_count != timer0_max_count) {
timer0_max_count = new_timer0_max_count;
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
@ -575,7 +581,6 @@ startrtclock()
}
set_timer_freq(timer_freq, hz);
i8254_timecounter.tc_frequency = timer_freq;
tc_init(&i8254_timecounter);
init_TSC();
@ -728,15 +733,21 @@ cpu_initclocks()
/*
* If we aren't using the local APIC timer to drive the kernel
* clocks, setup the interrupt handler for the 8254 timer 0 so
* that it can drive hardclock().
* that it can drive hardclock(). Otherwise, change the 8254
* timecounter to user a simpler algorithm.
*/
if (!using_lapic_timer) {
if (!using_lapic_timer || 1) {
intr_add_handler("clk", 0, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
i8254_intsrc = intr_lookup_source(0);
if (i8254_intsrc != NULL)
i8254_pending =
i8254_intsrc->is_pic->pic_source_pending;
} else {
i8254_timecounter.tc_get_timecount =
i8254_simple_get_timecount;
i8254_timecounter.tc_counter_mask = 0xffff;
set_timer_freq(timer_freq, hz);
}
/* Initialize RTC. */
@ -804,16 +815,32 @@ sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
*/
freq = timer_freq;
error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
if (error == 0 && req->newptr != NULL) {
if (error == 0 && req->newptr != NULL)
set_timer_freq(freq, hz);
i8254_timecounter.tc_frequency = freq;
}
return (error);
}
SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i8254_freq, "IU", "");
static unsigned
i8254_simple_get_timecount(struct timecounter *tc)
{
u_int count;
u_int high, low;
mtx_lock_spin(&clock_lock);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
count = 0xffff - ((high << 8) | low);
mtx_unlock_spin(&clock_lock);
return (count);
}
static unsigned
i8254_get_timecount(struct timecounter *tc)
{