diff options
Diffstat (limited to 'sys/isa/atrtc.c')
-rw-r--r-- | sys/isa/atrtc.c | 199 |
1 files changed, 17 insertions, 182 deletions
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index 0f8ac68..b389670 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -71,14 +71,12 @@ __FBSDID("$FreeBSD$"); #include <machine/clock.h> #include <machine/cputypes.h> #include <machine/frame.h> +#include <machine/intr_machdep.h> #include <machine/md_var.h> #include <machine/psl.h> -#ifdef APIC_IO -#include <machine/segments.h> -#endif -#if defined(SMP) || defined(APIC_IO) +#if defined(SMP) #include <machine/smp.h> -#endif /* SMP || APIC_IO */ +#endif #include <machine/specialreg.h> #include <i386/isa/icu.h> @@ -89,20 +87,10 @@ __FBSDID("$FreeBSD$"); #endif #include <i386/isa/timerreg.h> -#include <i386/isa/intr_machdep.h> - #ifdef DEV_MCA #include <i386/bios/mca_machdep.h> #endif -#ifdef APIC_IO -#include <i386/isa/intr_machdep.h> -/* The interrupt triggered by the 8254 (timer) chip */ -int apic_8254_intr; -static u_long read_intr_count(int vec); -static void setup_8254_mixed_mode(void); -#endif - /* * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we * can use a simple formula for leap years. @@ -150,6 +138,7 @@ static u_int hardclock_max_count; static u_int32_t i8254_lastcount; static u_int32_t i8254_offset; static int i8254_ticked; +static struct intsrc *i8254_intsrc; #ifndef BURN_BRIDGES /* * XXX new_function and timer_func should not handle clockframes, but @@ -187,7 +176,7 @@ static struct timecounter i8254_timecounter = { }; static void -clkintr(struct clockframe frame) +clkintr(struct clockframe *frame) { if (timecounter->tc_get_timecount == i8254_get_timecount) { @@ -201,7 +190,7 @@ clkintr(struct clockframe frame) clkintr_pending = 0; mtx_unlock_spin(&clock_lock); } - timer_func(&frame); + timer_func(frame); #ifdef SMP if (timer_func == hardclock) forward_hardclock(); @@ -216,7 +205,7 @@ clkintr(struct clockframe frame) if ((timer0_prescaler_count += timer0_max_count) >= hardclock_max_count) { timer0_prescaler_count -= hardclock_max_count; - hardclock(&frame); + hardclock(frame); #ifdef SMP forward_hardclock(); #endif @@ -251,7 +240,7 @@ clkintr(struct clockframe frame) timer0_prescaler_count = 0; timer_func = hardclock; timer0_state = RELEASED; - hardclock(&frame); + hardclock(frame); #ifdef SMP forward_hardclock(); #endif @@ -379,16 +368,16 @@ release_timer2() * in the statistics, but the stat clock will no longer stop. */ static void -rtcintr(struct clockframe frame) +rtcintr(struct clockframe *frame) { while (rtcin(RTC_INTR) & RTCIR_PERIOD) { if (profprocs != 0) { if (--pscnt == 0) pscnt = psdiv; - profclock(&frame); + profclock(frame); } if (pscnt == psdiv) - statclock(&frame); + statclock(frame); #ifdef SMP forward_statclock(); #endif @@ -931,11 +920,6 @@ void cpu_initclocks() { int diag; -#ifdef APIC_IO - int apic_8254_trial; - void *clkdesc; -#endif /* APIC_IO */ - register_t crit; if (statclock_disable) { /* @@ -951,47 +935,9 @@ cpu_initclocks() profhz = RTC_PROFRATE; } - /* Finish initializing 8253 timer 0. */ -#ifdef APIC_IO - - apic_8254_intr = isa_apic_irq(0); - apic_8254_trial = 0; - if (apic_8254_intr >= 0 ) { - if (apic_int_type(0, 0) == 3) - apic_8254_trial = 1; - } else { - /* look for ExtInt on pin 0 */ - if (apic_int_type(0, 0) == 3) { - apic_8254_intr = apic_irq(0, 0); - setup_8254_mixed_mode(); - } else - panic("APIC_IO: Cannot route 8254 interrupt to CPU"); - } - - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, - INTR_TYPE_CLK | INTR_FAST, &clkdesc); - crit = intr_disable(); - mtx_lock_spin(&icu_lock); - INTREN(1 << apic_8254_intr); - mtx_unlock_spin(&icu_lock); - intr_restore(crit); - -#else /* APIC_IO */ - - /* - * XXX Check the priority of this interrupt handler. I - * couldn't find anything suitable in the BSD/OS code (grog, - * 19 July 2000). - */ - inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, + /* Finish initializing 8254 timer 0. */ + intr_add_handler("clk", 0, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); - crit = intr_disable(); - mtx_lock_spin(&icu_lock); - INTREN(IRQ0); - mtx_unlock_spin(&icu_lock); - intr_restore(crit); - -#endif /* APIC_IO */ /* Initialize RTC. */ writertc(RTC_STATUSA, rtc_statusa); @@ -1004,120 +950,15 @@ cpu_initclocks() if (diag != 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); -#ifdef APIC_IO - if (isa_apic_irq(8) != 8) - panic("APIC RTC != 8"); -#endif /* APIC_IO */ - - inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, + intr_add_handler("rtc", 8, (driver_intr_t *)rtcintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); - - crit = intr_disable(); - mtx_lock_spin(&icu_lock); -#ifdef APIC_IO - INTREN(APIC_IRQ8); -#else - INTREN(IRQ8); -#endif /* APIC_IO */ - mtx_unlock_spin(&icu_lock); - intr_restore(crit); + i8254_intsrc = intr_lookup_source(8); writertc(RTC_STATUSB, rtc_statusb); -#ifdef APIC_IO - if (apic_8254_trial) { - - printf("APIC_IO: Testing 8254 interrupt delivery\n"); - while (read_intr_count(8) < 6) - ; /* nothing */ - if (read_intr_count(apic_8254_intr) < 3) { - /* - * The MP table is broken. - * The 8254 was not connected to the specified pin - * on the IO APIC. - * Workaround: Limited variant of mixed mode. - */ - - crit = intr_disable(); - mtx_lock_spin(&icu_lock); - INTRDIS(1 << apic_8254_intr); - mtx_unlock_spin(&icu_lock); - intr_restore(crit); - inthand_remove(clkdesc); - printf("APIC_IO: Broken MP table detected: " - "8254 is not connected to " - "IOAPIC #%d intpin %d\n", - int_to_apicintpin[apic_8254_intr].ioapic, - int_to_apicintpin[apic_8254_intr].int_pin); - /* - * Revoke current ISA IRQ 0 assignment and - * configure a fallback interrupt routing from - * the 8254 Timer via the 8259 PIC to the - * an ExtInt interrupt line on IOAPIC #0 intpin 0. - * We reuse the low level interrupt handler number. - */ - if (apic_irq(0, 0) < 0) { - revoke_apic_irq(apic_8254_intr); - assign_apic_irq(0, 0, apic_8254_intr); - } - apic_8254_intr = apic_irq(0, 0); - setup_8254_mixed_mode(); - inthand_add("clk", apic_8254_intr, - (driver_intr_t *)clkintr, NULL, - INTR_TYPE_CLK | INTR_FAST, NULL); - crit = intr_disable(); - mtx_lock_spin(&icu_lock); - INTREN(1 << apic_8254_intr); - mtx_unlock_spin(&icu_lock); - intr_restore(crit); - } - - } - if (apic_int_type(0, 0) != 3 || - int_to_apicintpin[apic_8254_intr].ioapic != 0 || - int_to_apicintpin[apic_8254_intr].int_pin != 0) - printf("APIC_IO: routing 8254 via IOAPIC #%d intpin %d\n", - int_to_apicintpin[apic_8254_intr].ioapic, - int_to_apicintpin[apic_8254_intr].int_pin); - else - printf("APIC_IO: " - "routing 8254 via 8259 and IOAPIC #0 intpin 0\n"); -#endif - init_TSC_tc(); } -#ifdef APIC_IO -static u_long -read_intr_count(int vec) -{ - u_long *up; - up = intr_countp[vec]; - if (up) - return *up; - return 0UL; -} - -static void -setup_8254_mixed_mode() -{ - /* - * Allow 8254 timer to INTerrupt 8259: - * re-initialize master 8259: - * reset; prog 4 bytes, single ICU, edge triggered - */ - outb(IO_ICU1, 0x13); - outb(IO_ICU1 + 1, NRSVIDT); /* start vector (unused) */ - outb(IO_ICU1 + 1, 0x00); /* ignore slave */ - outb(IO_ICU1 + 1, 0x03); /* auto EOI, 8086 */ - outb(IO_ICU1 + 1, 0xfe); /* unmask INT0 */ - - /* program IO APIC for type 3 INT on INT0 */ - if (ext_int_setup(0, 0) < 0) - panic("8254 redirect via APIC pin0 impossible!"); -} -#endif - void cpu_startprofclock(void) { @@ -1181,14 +1022,8 @@ i8254_get_timecount(struct timecounter *tc) if (count < i8254_lastcount || (!i8254_ticked && (clkintr_pending || ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) && -#ifdef APIC_IO -#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ - /* XXX this assumes that apic_8254_intr is < 24. */ - (lapic_irr1 & (1 << apic_8254_intr)))) -#else - (inb(IO_ICU1) & 1))) -#endif - )) { + i8254_intsrc != NULL && + i8254_intsrc->is_pic->pic_source_pending(i8254_intsrc))))) { i8254_ticked = 1; i8254_offset += timer0_max_count; } |