From 94ce667781f20302b1db949e69f2585605e57366 Mon Sep 17 00:00:00 2001 From: deraadt Date: Sun, 25 Jul 2010 21:43:35 +0000 Subject: [PATCH] in the clock drivers, seperate the soft-state and hard-state which was all jumbled up in the same functions. the rtc (mc chip) and clock (i8243) startup was also mixed up. they the soft state and hardware state can be started in the right order, and it is easy to restart just the neccessary parts upon resume. tested in numerous cases: (apic, pic) * (GENERIC.MP, GENERIC) * (mp, non-mp) * (i386, amd64) ok kettenis --- sys/arch/amd64/amd64/acpi_machdep.c | 9 ++-- sys/arch/amd64/amd64/autoconf.c | 4 +- sys/arch/amd64/amd64/cpu.c | 4 +- sys/arch/amd64/amd64/lapic.c | 14 ++++-- sys/arch/amd64/amd64/machdep.c | 8 +--- sys/arch/amd64/include/cpu.h | 8 ++-- sys/arch/amd64/include/i82489var.h | 3 +- sys/arch/amd64/isa/clock.c | 74 +++++++++++------------------ sys/arch/i386/i386/acpi_machdep.c | 9 ++-- sys/arch/i386/i386/apm.c | 8 ++-- sys/arch/i386/i386/autoconf.c | 4 +- sys/arch/i386/i386/cpu.c | 4 +- sys/arch/i386/i386/lapic.c | 13 +++-- sys/arch/i386/i386/machdep.c | 11 ++--- sys/arch/i386/include/cpu.h | 9 ++-- sys/arch/i386/include/i82489var.h | 3 +- sys/arch/i386/isa/clock.c | 68 +++++++++++++------------- 17 files changed, 122 insertions(+), 131 deletions(-) diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c index 3beb4e5668f..58c48caafed 100644 --- a/sys/arch/amd64/amd64/acpi_machdep.c +++ b/sys/arch/amd64/amd64/acpi_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_machdep.c,v 1.40 2010/07/06 06:25:56 deraadt Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.41 2010/07/25 21:43:38 deraadt Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * @@ -255,7 +255,8 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state) #if NLAPIC > 0 lapic_enable(); - lapic_initclocks(); + if (initclock_func == lapic_initclocks) + lapic_startclock(); lapic_set_lvt(); #endif @@ -268,7 +269,9 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state) #if NIOAPIC > 0 ioapic_enable(); #endif - initrtclock(); + i8254_startclock(); + if (initclock_func == i8254_initclocks) + rtcstart(); /* in i8254 mode, rtc is profclock */ inittodr(time_second); return (0); diff --git a/sys/arch/amd64/amd64/autoconf.c b/sys/arch/amd64/amd64/autoconf.c index 3f2ab670cc3..5c8804ac56c 100644 --- a/sys/arch/amd64/amd64/autoconf.c +++ b/sys/arch/amd64/amd64/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.34 2010/07/01 00:24:27 thib Exp $ */ +/* $OpenBSD: autoconf.c,v 1.35 2010/07/25 21:43:38 deraadt Exp $ */ /* $NetBSD: autoconf.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -118,8 +118,6 @@ cpu_configure(void) x86_64_proc0_tss_ldt_init(); - startrtclock(); - if (config_rootfound("mainbus", NULL) == NULL) panic("configure: mainbus not configured"); diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index 40da9cf7743..a42691a6363 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.34 2010/06/26 23:24:43 guenther Exp $ */ +/* $OpenBSD: cpu.c,v 1.35 2010/07/25 21:43:38 deraadt Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -497,7 +497,7 @@ cpu_hatch(void *v) ci->ci_flags |= CPUF_PRESENT; lapic_enable(); - lapic_initclocks(); + lapic_startclock(); while ((ci->ci_flags & CPUF_GO) == 0) delay(10); diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c index c7507f41819..b51932e0a52 100644 --- a/sys/arch/amd64/amd64/lapic.c +++ b/sys/arch/amd64/amd64/lapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lapic.c,v 1.25 2010/07/23 07:21:02 matthew Exp $ */ +/* $OpenBSD: lapic.c,v 1.26 2010/07/25 21:43:38 deraadt Exp $ */ /* $NetBSD: lapic.c,v 1.2 2003/05/08 01:04:35 fvdl Exp $ */ /*- @@ -278,7 +278,7 @@ lapic_clockintr(void *arg, struct intrframe frame) } void -lapic_initclocks(void) +lapic_startclock(void) { /* * Start local apic countdown timer running, in repeated mode. @@ -293,9 +293,17 @@ lapic_initclocks(void) i82489_writereg(LAPIC_LVTT, LAPIC_LVTT_TM|LAPIC_TIMER_VECTOR); } +void +lapic_initclocks(void) +{ + lapic_startclock(); + + i8254_inittimecounter_simple(); +} + + extern int gettick(void); /* XXX put in header file */ extern u_long rtclock_tval; /* XXX put in header file */ -extern void (*initclock_func)(void); /* XXX put in header file */ /* * Calibrate the local apic count-down timer (which is running at diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 006753725d4..4c0701b40d6 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.117 2010/07/23 14:56:31 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.118 2010/07/25 21:43:38 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -315,6 +315,7 @@ cpu_startup(void) initmsgbuf((caddr_t)msgbuf_vaddr, round_page(MSGBUFSIZE)); printf("%s", version); + startclocks(); printf("real mem = %lu (%luMB)\n", ptoa((psize_t)physmem), ptoa((psize_t)physmem)/1024/1024); @@ -1697,11 +1698,6 @@ void cpu_initclocks(void) { (*initclock_func)(); - - if (initclock_func == i8254_initclocks) - i8254_inittimecounter(); - else - i8254_inittimecounter_simple(); } void diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index c9730702f2f..a3e5a30d11a 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.52 2010/07/21 14:08:09 kettenis Exp $ */ +/* $OpenBSD: cpu.h,v 1.53 2010/07/25 21:43:38 deraadt Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -290,10 +290,12 @@ void proc_trampoline(void); void child_trampoline(void); /* clock.c */ -void initrtclock(void); -void startrtclock(void); +extern void (*initclock_func)(void); +void startclocks(void); +void rtcstart(void); void i8254_delay(int); void i8254_initclocks(void); +void i8254_startclock(void); void i8254_inittimecounter(void); void i8254_inittimecounter_simple(void); diff --git a/sys/arch/amd64/include/i82489var.h b/sys/arch/amd64/include/i82489var.h index c3ceda14a91..565675b0192 100644 --- a/sys/arch/amd64/include/i82489var.h +++ b/sys/arch/amd64/include/i82489var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i82489var.h,v 1.10 2009/06/09 02:56:38 krw Exp $ */ +/* $OpenBSD: i82489var.h,v 1.11 2010/07/25 21:43:38 deraadt Exp $ */ /* $NetBSD: i82489var.h,v 1.1 2003/02/26 21:26:10 fvdl Exp $ */ /*- @@ -123,6 +123,7 @@ extern void lapic_boot_init(paddr_t); extern void lapic_set_lvt(void); extern void lapic_enable(void); extern void lapic_calibrate_timer(struct cpu_info *ci); +extern void lapic_startclock(void); extern void lapic_initclocks(void); #endif diff --git a/sys/arch/amd64/isa/clock.c b/sys/arch/amd64/isa/clock.c index 91b23087b03..96234b41bfe 100644 --- a/sys/arch/amd64/isa/clock.c +++ b/sys/arch/amd64/isa/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.13 2007/08/02 16:40:27 deraadt Exp $ */ +/* $OpenBSD: clock.c,v 1.14 2010/07/25 21:43:38 deraadt Exp $ */ /* $NetBSD: clock.c,v 1.1 2003/04/26 18:39:50 fvdl Exp $ */ /*- @@ -154,42 +154,16 @@ mc146818_write(void *sc, u_int reg, u_int datum) struct mutex timer_mutex = MUTEX_INITIALIZER(IPL_HIGH); u_long rtclock_tval; -int rtclock_init; -/* minimal initialization, enough for delay() */ void -initrtclock(void) +startclocks(void) { - u_long tval; - - /* - * Compute timer_count, the count-down count the timer will be - * set to. Also, correctly round - * this by carrying an extra bit through the division. - */ - tval = (TIMER_FREQ * 2) / (u_long) hz; - tval = (tval / 2) + (tval & 0x1); + int s; mtx_enter(&timer_mutex); - /* initialize 8253 clock */ - outb(IO_TIMER1+TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT); - - /* 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; - rtclock_init = 1; + rtclock_tval = TIMER_DIV(hz); + i8254_startclock(); mtx_leave(&timer_mutex); -} - -void -startrtclock(void) -{ - int s; - - if (!rtclock_init) - initrtclock(); /* Check diagnostic status */ if ((s = mc146818_read(NULL, NVRAM_DIAG)) != 0) /* XXX softc */ @@ -269,10 +243,6 @@ i8254_delay(int n) 24, 25, 27, 28, 29, 30, }; - /* allow DELAY() to be used before startrtclock() */ - if (!rtclock_init) - initrtclock(); - /* * Read the counter first, so that the rest of the setup overhead is * counted. @@ -340,14 +310,21 @@ rtcdrain(void *v) void i8254_initclocks(void) { - static struct timeout rtcdrain_timeout; - stathz = 128; profhz = 1024; isa_intr_establish(NULL, 0, IST_PULSE, IPL_CLOCK, clockintr, 0, "clock"); - isa_intr_establish(NULL, 8, IST_PULSE, IPL_CLOCK, rtcintr, 0, "rtc"); + isa_intr_establish(NULL, 8, IST_PULSE, IPL_CLOCK, rtcintr, + 0, "rtc"); + + rtcstart(); /* start the mc146818 clock */ +} + +void +rtcstart(void) +{ + static struct timeout rtcdrain_timeout; mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_128_Hz); mc146818_write(NULL, MC_REGB, MC_REGB_24HR | MC_REGB_PIE); @@ -637,25 +614,28 @@ i8254_inittimecounter(void) void i8254_inittimecounter_simple(void) { - u_long tval = 0x8000; - i8254_timecounter.tc_get_timecount = i8254_simple_get_timecount; i8254_timecounter.tc_counter_mask = 0x7fff; - i8254_timecounter.tc_frequency = TIMER_FREQ; mtx_enter(&timer_mutex); - outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); - outb(IO_TIMER1 + TIMER_CNTR0, tval & 0xff); - outb(IO_TIMER1 + TIMER_CNTR0, tval >> 8); - - rtclock_tval = tval; - rtclock_init = 1; + rtclock_tval = 0x8000; + i8254_startclock(); mtx_leave(&timer_mutex); tc_init(&i8254_timecounter); } +void +i8254_startclock(void) +{ + u_long tval = rtclock_tval; + + outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); + outb(IO_TIMER1 + TIMER_CNTR0, tval & 0xff); + outb(IO_TIMER1 + TIMER_CNTR0, tval >> 8); +} + u_int i8254_simple_get_timecount(struct timecounter *tc) { diff --git a/sys/arch/i386/i386/acpi_machdep.c b/sys/arch/i386/i386/acpi_machdep.c index 29cefc5a72b..671fe794171 100644 --- a/sys/arch/i386/i386/acpi_machdep.c +++ b/sys/arch/i386/i386/acpi_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_machdep.c,v 1.34 2010/07/06 06:25:55 deraadt Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.35 2010/07/25 21:43:35 deraadt Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * @@ -273,7 +273,8 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state) #if NLAPIC > 0 lapic_enable(); - lapic_initclocks(); + if (initclock_func == lapic_initclocks) + lapic_startclock(); lapic_set_lvt(); #endif @@ -286,7 +287,9 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state) #if NIOAPIC > 0 ioapic_enable(); #endif - initrtclock(); + i8254_startclock(); + if (initclock_func == i8254_initclocks) + rtcstart(); /* in i8254 mode, rtc is profclock */ inittodr(time_second); return (0); diff --git a/sys/arch/i386/i386/apm.c b/sys/arch/i386/i386/apm.c index 22243f7f573..830e998196f 100644 --- a/sys/arch/i386/i386/apm.c +++ b/sys/arch/i386/i386/apm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: apm.c,v 1.87 2010/07/20 12:23:00 deraadt Exp $ */ +/* $OpenBSD: apm.c,v 1.88 2010/07/25 21:43:35 deraadt Exp $ */ /*- * Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved. @@ -356,8 +356,10 @@ apm_resume(struct apm_softc *sc, struct apmregs *regs) apm_resumes = APM_RESUME_HOLDOFF; - /* they say that some machines may require reinitializing the clock */ - initrtclock(); + /* they say that some machines may require reinitializing the clocks */ + i8254_startclock(); + if (initclock_func == i8254_initclocks) + rtcstart(); /* in i8254 mode, rtc is profclock */ inittodr(time_second); /* lower bit in cx means pccard was powered down */ diff --git a/sys/arch/i386/i386/autoconf.c b/sys/arch/i386/i386/autoconf.c index 9d49b0988fb..7ded3b3a53f 100644 --- a/sys/arch/i386/i386/autoconf.c +++ b/sys/arch/i386/i386/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.84 2010/06/28 22:20:12 deraadt Exp $ */ +/* $OpenBSD: autoconf.c,v 1.85 2010/07/25 21:43:35 deraadt Exp $ */ /* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */ /*- @@ -105,8 +105,6 @@ cpu_configure(void) * architectures. This fact is used by the pcmcia irq line probing. */ - startrtclock(); - gdt_init(); /* XXX - pcibios uses gdt stuff */ /* Set up proc0's TSS and LDT */ diff --git a/sys/arch/i386/i386/cpu.c b/sys/arch/i386/i386/cpu.c index 751e2d05875..8a9898b08a8 100644 --- a/sys/arch/i386/i386/cpu.c +++ b/sys/arch/i386/i386/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.40 2010/06/26 23:24:43 guenther Exp $ */ +/* $OpenBSD: cpu.c,v 1.41 2010/07/25 21:43:35 deraadt Exp $ */ /* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */ /*- @@ -470,7 +470,7 @@ cpu_hatch(void *v) cpu_init_idt(); lapic_enable(); - lapic_initclocks(); + lapic_startclock(); lapic_set_lvt(); gdt_init_cpu(ci); cpu_init_ldt(ci); diff --git a/sys/arch/i386/i386/lapic.c b/sys/arch/i386/i386/lapic.c index b4675c19029..b0c6e5f01c1 100644 --- a/sys/arch/i386/i386/lapic.c +++ b/sys/arch/i386/i386/lapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lapic.c,v 1.29 2010/07/23 07:21:02 matthew Exp $ */ +/* $OpenBSD: lapic.c,v 1.30 2010/07/25 21:43:35 deraadt Exp $ */ /* $NetBSD: lapic.c,v 1.1.2.8 2000/02/23 06:10:50 sommerfeld Exp $ */ /*- @@ -247,7 +247,7 @@ lapic_clockintr(void *arg) } void -lapic_initclocks(void) +lapic_startclock(void) { /* * Start local apic countdown timer running, in repeated mode. @@ -262,8 +262,15 @@ lapic_initclocks(void) i82489_writereg(LAPIC_LVTT, LAPIC_LVTT_TM|LAPIC_TIMER_VECTOR); } +void +lapic_initclocks(void) +{ + lapic_startclock(); + + i8254_inittimecounter_simple(); +} + extern int gettick(void); /* XXX put in header file */ -extern void (*initclock_func)(void); /* XXX put in header file */ /* * Calibrate the local apic count-down timer (which is running at diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index af304a22335..73da8f7d959 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.479 2010/07/23 14:56:31 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.480 2010/07/25 21:43:35 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -401,7 +401,7 @@ cpu_startup() initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE)); printf("%s", version); - startrtclock(); + startclocks(); /* * We need to call identifycpu here early, so users have at least some @@ -3291,12 +3291,7 @@ cpu_reset() void cpu_initclocks(void) { - (*initclock_func)(); - - if (initclock_func == i8254_initclocks) - i8254_inittimecounter(); - else - i8254_inittimecounter_simple(); + (*initclock_func)(); /* lapic or i8254 */ } void diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index d6c0e6ef89d..04ee23d9986 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.111 2010/07/21 14:08:09 kettenis Exp $ */ +/* $OpenBSD: cpu.h,v 1.112 2010/07/25 21:43:37 deraadt Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -371,15 +371,16 @@ void switch_exit(struct proc *); void proc_trampoline(void); /* clock.c */ -void initrtclock(void); -void startrtclock(void); +extern void (*initclock_func)(void); +void startclocks(void); void rtcdrain(void *); +void rtcstart(void); void i8254_delay(int); void i8254_initclocks(void); +void i8254_startclock(void); void i8254_inittimecounter(void); void i8254_inittimecounter_simple(void); - #if !defined(SMALL_KERNEL) /* est.c */ void est_init(const char *, int); diff --git a/sys/arch/i386/include/i82489var.h b/sys/arch/i386/include/i82489var.h index 6af9d3ed971..6a81e1a9b05 100644 --- a/sys/arch/i386/include/i82489var.h +++ b/sys/arch/i386/include/i82489var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i82489var.h,v 1.10 2009/06/03 00:49:12 art Exp $ */ +/* $OpenBSD: i82489var.h,v 1.11 2010/07/25 21:43:37 deraadt Exp $ */ /* $NetBSD: i82489var.h,v 1.1.2.2 2000/02/21 18:46:14 sommerfeld Exp $ */ /*- @@ -119,6 +119,7 @@ extern void (*apichandler[])(void); struct cpu_info; extern void lapic_boot_init(paddr_t); +extern void lapic_startclock(void); extern void lapic_initclocks(void); extern void lapic_set_lvt(void); extern void lapic_set_softvectors(void); diff --git a/sys/arch/i386/isa/clock.c b/sys/arch/i386/isa/clock.c index dd2cc70c26a..da380bb9f7b 100644 --- a/sys/arch/i386/isa/clock.c +++ b/sys/arch/i386/isa/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.42 2009/01/29 13:36:17 kettenis Exp $ */ +/* $OpenBSD: clock.c,v 1.43 2010/07/25 21:43:37 deraadt Exp $ */ /* $NetBSD: clock.c,v 1.39 1996/05/12 23:11:54 mycroft Exp $ */ /*- @@ -167,11 +167,14 @@ mc146818_write(void *sc, u_int reg, u_int datum) } void -startrtclock(void) +startclocks(void) { int s; - initrtclock(); + mtx_enter(&timer_mutex); + rtclock_tval = TIMER_DIV(hz); + i8254_startclock(); + mtx_leave(&timer_mutex); /* Check diagnostic status */ if ((s = mc146818_read(NULL, NVRAM_DIAG)) != 0) /* XXX softc */ @@ -195,22 +198,6 @@ rtcdrain(void *v) ; /* Nothing. */ } -void -initrtclock(void) -{ - mtx_enter(&timer_mutex); - - /* initialize 8253 clock */ - outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT); - - /* Correct rounding will buy us a better precision in timekeeping */ - outb(IO_TIMER1, TIMER_DIV(hz) % 256); - outb(IO_TIMER1, TIMER_DIV(hz) / 256); - - rtclock_tval = TIMER_DIV(hz); - mtx_leave(&timer_mutex); -} - int clockintr(void *arg) { @@ -400,16 +387,21 @@ calibrate_cyclecounter(void) void i8254_initclocks(void) { - static struct timeout rtcdrain_timeout; + /* When using i8254 for clock, we also use the rtc for profclock */ + (void)isa_intr_establish(NULL, 0, IST_PULSE, IPL_CLOCK, + clockintr, 0, "clock"); + (void)isa_intr_establish(NULL, 8, IST_PULSE, IPL_CLOCK, + rtcintr, 0, "rtc"); - /* - * XXX If you're doing strange things with multiple clocks, you might - * want to keep track of clock handlers. - */ - (void)isa_intr_establish(NULL, 0, IST_PULSE, IPL_CLOCK, clockintr, - 0, "clock"); - (void)isa_intr_establish(NULL, 8, IST_PULSE, IPL_CLOCK, rtcintr, - 0, "rtc"); + rtcstart(); /* start the mc146818 clock */ + + i8254_inittimecounter(); /* hook the interrupt-based i8254 tc */ +} + +void +rtcstart(void) +{ + static struct timeout rtcdrain_timeout; mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | MC_RATE_128_Hz); mc146818_write(NULL, MC_REGB, MC_REGB_24HR | MC_REGB_PIE); @@ -691,24 +683,28 @@ i8254_inittimecounter(void) void i8254_inittimecounter_simple(void) { - u_long tval = 0x8000; - i8254_timecounter.tc_get_timecount = i8254_simple_get_timecount; i8254_timecounter.tc_counter_mask = 0x7fff; - i8254_timecounter.tc_frequency = TIMER_FREQ; mtx_enter(&timer_mutex); - outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); - outb(IO_TIMER1, tval & 0xff); - outb(IO_TIMER1, tval >> 8); - - rtclock_tval = tval; + rtclock_tval = 0x8000; + i8254_startclock(); mtx_leave(&timer_mutex); tc_init(&i8254_timecounter); } +void +i8254_startclock(void) +{ + u_long tval = rtclock_tval; + + outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); + outb(IO_TIMER1 + TIMER_CNTR0, tval & 0xff); + outb(IO_TIMER1 + TIMER_CNTR0, tval >> 8); +} + u_int i8254_simple_get_timecount(struct timecounter *tc) { -- 2.20.1