diff options
Diffstat (limited to 'sys/i386/isa')
-rw-r--r-- | sys/i386/isa/clock.c | 199 | ||||
-rw-r--r-- | sys/i386/isa/npx.c | 50 |
2 files changed, 30 insertions, 219 deletions
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index 0f8ac68..b389670 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.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; } diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c index fbd4643..9e5a7ee 100644 --- a/sys/i386/isa/npx.c +++ b/sys/i386/isa/npx.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include <sys/mutex.h> #include <sys/mutex.h> #include <sys/proc.h> +#include <sys/smp.h> #include <sys/sysctl.h> #include <machine/bus.h> #include <sys/rman.h> @@ -61,31 +62,25 @@ __FBSDID("$FreeBSD$"); #include <sys/signalvar.h> #include <sys/user.h> -#ifndef SMP #include <machine/asmacros.h> -#endif #include <machine/cputypes.h> #include <machine/frame.h> #include <machine/md_var.h> #include <machine/pcb.h> #include <machine/psl.h> -#ifndef SMP #include <machine/clock.h> -#endif #include <machine/resource.h> #include <machine/specialreg.h> #include <machine/segments.h> #include <machine/ucontext.h> -#ifndef SMP #include <i386/isa/icu.h> #ifdef PC98 #include <pc98/pc98/pc98.h> #else #include <i386/isa/isa.h> #endif -#endif -#include <i386/isa/intr_machdep.h> +#include <machine/intr_machdep.h> #ifdef DEV_ISA #include <isa/isavar.h> #endif @@ -165,9 +160,7 @@ static void fpusave(union savefpu *); static void fpurstor(union savefpu *); static int npx_attach(device_t dev); static void npx_identify(driver_t *driver, device_t parent); -#ifndef SMP static void npx_intr(void *); -#endif static int npx_probe(device_t dev); #ifdef I586_CPU_XXX static long timezero(const char *funcname, @@ -180,10 +173,8 @@ SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint, CTLFLAG_RD, &hw_float, 0, "Floatingpoint instructions executed in hardware"); -#ifndef SMP static volatile u_int npx_intrs_while_probing; static volatile u_int npx_traps_while_probing; -#endif static union savefpu npx_cleanstate; static bool_t npx_cleanstate_ready; @@ -191,7 +182,6 @@ static bool_t npx_ex16; static bool_t npx_exists; static bool_t npx_irq13; -#ifndef SMP alias_for_inthand_t probetrap; __asm(" \n\ .text \n\ @@ -203,7 +193,6 @@ __asm(" \n\ fnclex \n\ iret \n\ "); -#endif /* SMP */ /* * Identify routine. Create a connection point on our parent for probing. @@ -220,7 +209,6 @@ npx_identify(driver, parent) panic("npx_identify"); } -#ifndef SMP /* * Do minimal handling of npx interrupts to convert them to traps. */ @@ -230,9 +218,7 @@ npx_intr(dummy) { struct thread *td; -#ifndef SMP npx_intrs_while_probing++; -#endif /* * The BUSY# latch must be cleared in all cases so that the next @@ -264,7 +250,6 @@ npx_intr(dummy) mtx_unlock_spin(&sched_lock); } } -#endif /* !SMP */ /* * Probe routine. Initialize cr0 to give correct behaviour for [f]wait @@ -276,7 +261,6 @@ static int npx_probe(dev) device_t dev; { -#ifndef SMP struct gate_descriptor save_idt_npxtrap; struct resource *ioport_res, *irq_res; void *irq_cookie; @@ -307,7 +291,6 @@ npx_probe(dev) if (bus_setup_intr(dev, irq_res, INTR_TYPE_MISC | INTR_FAST, npx_intr, NULL, &irq_cookie) != 0) panic("npx: can't create intr"); -#endif /* !SMP */ /* * Partially reset the coprocessor, if any. Some BIOS's don't reset @@ -348,16 +331,6 @@ npx_probe(dev) device_set_desc(dev, "math processor"); -#ifdef SMP - - /* - * Exception 16 MUST work for SMP. - */ - npx_ex16 = hw_float = npx_exists = 1; - return (0); - -#else /* !SMP */ - /* * Don't use fwait here because it might hang. * Don't use fnop here because it usually hangs if there is no FPU. @@ -413,6 +386,10 @@ npx_probe(dev) */ npx_irq13 = 1; idt[IDT_MF] = save_idt_npxtrap; +#ifdef SMP + if (mp_ncpus > 1) + panic("npx0 cannot use IRQ 13 on an SMP system"); +#endif return (0); } /* @@ -425,6 +402,10 @@ npx_probe(dev) * emulator and say that it has been installed. XXX handle devices * that aren't really devices better. */ +#ifdef SMP + if (mp_ncpus > 1) + panic("npx0 cannot be emulated on an SMP system"); +#endif /* FALLTHROUGH */ no_irq13: idt[IDT_MF] = save_idt_npxtrap; @@ -435,20 +416,15 @@ no_irq13: * irq active then we would get it instead of exception 16. */ { - register_t crit; + struct intsrc *isrc; - crit = intr_disable(); - mtx_lock_spin(&icu_lock); - INTRDIS(1 << irq_num); - mtx_unlock_spin(&icu_lock); - intr_restore(crit); + isrc = intr_lookup_source(irq_num); + isrc->is_pic->pic_disable_source(isrc); } bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res); bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res); return (0); - -#endif /* SMP */ } /* |