diff options
-rw-r--r-- | sys/amd64/amd64/tsc.c | 12 | ||||
-rw-r--r-- | sys/amd64/isa/clock.c | 12 | ||||
-rw-r--r-- | sys/amd64/isa/isa.c | 358 | ||||
-rw-r--r-- | sys/amd64/isa/vector.S | 238 | ||||
-rw-r--r-- | sys/amd64/isa/vector.s | 238 | ||||
-rw-r--r-- | sys/dev/sio/sio.c | 3 | ||||
-rw-r--r-- | sys/i386/i386/tsc.c | 12 | ||||
-rw-r--r-- | sys/i386/isa/clock.c | 12 | ||||
-rw-r--r-- | sys/i386/isa/icu.s | 20 | ||||
-rw-r--r-- | sys/i386/isa/isa.c | 358 | ||||
-rw-r--r-- | sys/i386/isa/isa_device.h | 65 | ||||
-rw-r--r-- | sys/i386/isa/sio.c | 3 | ||||
-rw-r--r-- | sys/i386/isa/vector.s | 238 | ||||
-rw-r--r-- | sys/isa/atrtc.c | 12 | ||||
-rw-r--r-- | sys/isa/sio.c | 3 |
15 files changed, 856 insertions, 728 deletions
diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index 35f2e42..e3f3f21 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $ + * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $ */ /* @@ -497,16 +497,14 @@ test_inittodr(time_t base) /* * Wire clock interrupt in. */ -#define V(s) __CONCAT(V, s) -extern void V(clk)(); -extern void V(rtc)(); - void enablertclock() { - setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr, + HWI_MASK | SWI_MASK, /* unit */ 0); INTREN(IRQ0); - setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr, + SWI_CLOCK_MASK, /* unit */ 0); INTREN(IRQ8); outb(IO_RTC, RTC_STATUSB); outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR); diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index 35f2e42..e3f3f21 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $ + * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $ */ /* @@ -497,16 +497,14 @@ test_inittodr(time_t base) /* * Wire clock interrupt in. */ -#define V(s) __CONCAT(V, s) -extern void V(clk)(); -extern void V(rtc)(); - void enablertclock() { - setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr, + HWI_MASK | SWI_MASK, /* unit */ 0); INTREN(IRQ0); - setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr, + SWI_CLOCK_MASK, /* unit */ 0); INTREN(IRQ8); outb(IO_RTC, RTC_STATUSB); outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR); diff --git a/sys/amd64/isa/isa.c b/sys/amd64/isa/isa.c index 80be9a5..5b5878e 100644 --- a/sys/amd64/isa/isa.c +++ b/sys/amd64/isa/isa.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: isa.c,v 1.19 1994/08/10 04:39:52 wollman Exp $ + * $Id: isa.c,v 1.20 1994/08/13 03:50:07 wollman Exp $ */ /* @@ -65,6 +65,7 @@ #include <i386/isa/icu.h> #include <i386/isa/ic/i8237.h> #include <i386/isa/ic/i8042.h> +#include "vector.h" /* ** Register definitions for DMA controller 1 (channels 0..3): @@ -82,20 +83,70 @@ #define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */ #define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */ -void config_isadev __P((struct isa_device *, u_int *)); +/* + * Bits to specify the type and amount of conflict checking. + */ +#define CC_ATTACH (1 << 0) +#define CC_DRQ (1 << 1) +#define CC_IOADDR (1 << 2) +#define CC_IRQ (1 << 3) +#define CC_MEMADDR (1 << 4) + +/* + * XXX these defines should be in a central place. + */ +#define read_eflags() ({u_long ef; \ + __asm("pushfl; popl %0" : "=a" (ef)); \ + ef; }) +#define write_eflags(ef) __asm("pushl %0; popfl" : : "a" ((u_long)(ef))) + +u_long *intr_countp[ICU_LEN]; +inthand2_t *intr_handler[ICU_LEN]; +u_int intr_mask[ICU_LEN]; +int intr_unit[ICU_LEN]; + +static inthand_t *fastintr[ICU_LEN] = { + &IDTVEC(fastintr0), &IDTVEC(fastintr1), + &IDTVEC(fastintr2), &IDTVEC(fastintr3), + &IDTVEC(fastintr4), &IDTVEC(fastintr5), + &IDTVEC(fastintr6), &IDTVEC(fastintr7), + &IDTVEC(fastintr8), &IDTVEC(fastintr9), + &IDTVEC(fastintr10), &IDTVEC(fastintr11), + &IDTVEC(fastintr12), &IDTVEC(fastintr13), + &IDTVEC(fastintr14), &IDTVEC(fastintr15) +}; + +static inthand_t *slowintr[ICU_LEN] = { + &IDTVEC(intr0), &IDTVEC(intr1), &IDTVEC(intr2), &IDTVEC(intr3), + &IDTVEC(intr4), &IDTVEC(intr5), &IDTVEC(intr6), &IDTVEC(intr7), + &IDTVEC(intr8), &IDTVEC(intr9), &IDTVEC(intr10), &IDTVEC(intr11), + &IDTVEC(intr12), &IDTVEC(intr13), &IDTVEC(intr14), &IDTVEC(intr15) +}; + +static void config_isadev __P((struct isa_device *isdp, u_int *mp)); +static void conflict __P((struct isa_device *dvp, struct isa_device *tmpdvp, + int item, char const *whatnot, char const *reason, + char const *format)); +static int haveseen __P((struct isa_device *dvp, struct isa_device *tmpdvp, + u_int checkbits)); +static int haveseen_isadev __P((struct isa_device *dvp, u_int checkbits)); +static inthand2_t isa_strayintr; +static void register_imask __P((struct isa_device *dvp, u_int mask)); /* * print a conflict message */ -void -conflict(dvp, tmpdvp, item, reason, format) - struct isa_device *dvp, *tmpdvp; +static void +conflict(dvp, tmpdvp, item, whatnot, reason, format) + struct isa_device *dvp; + struct isa_device *tmpdvp; int item; - char *reason; - char *format; + char const *whatnot; + char const *reason; + char const *format; { - printf("%s%d not probed due to %s conflict with %s%d at ", - dvp->id_driver->name, dvp->id_unit, reason, + printf("%s%d not %sed due to %s conflict with %s%d at ", + dvp->id_driver->name, dvp->id_unit, whatnot, reason, tmpdvp->id_driver->name, tmpdvp->id_unit); printf(format, item); printf("\n"); @@ -105,9 +156,11 @@ conflict(dvp, tmpdvp, item, reason, format) * Check to see if things are alread in use, like IRQ's, I/O addresses * and Memory addresses. */ -int -haveseen(dvp, tmpdvp) - struct isa_device *dvp, *tmpdvp; +static int +haveseen(dvp, tmpdvp, checkbits) + struct isa_device *dvp; + struct isa_device *tmpdvp; + u_int checkbits; { int status = 0; @@ -115,17 +168,20 @@ haveseen(dvp, tmpdvp) * Only check against devices that have already been found */ if (tmpdvp->id_alive) { + char const *whatnot; + + whatnot = checkbits & CC_ATTACH ? "attach" : "probe"; /* * Check for I/O address conflict. We can only check the * starting address of the device against the range of the * device that has already been probed since we do not * know how many I/O addresses this device uses. */ - if (tmpdvp->id_alive != -1) { + if (checkbits & CC_IOADDR && tmpdvp->id_alive != -1) { if ((dvp->id_iobase >= tmpdvp->id_iobase) && (dvp->id_iobase <= (tmpdvp->id_iobase + tmpdvp->id_alive - 1))) { - conflict(dvp, tmpdvp, dvp->id_iobase, + conflict(dvp, tmpdvp, dvp->id_iobase, whatnot, "I/O address", "0x%x"); status = 1; } @@ -140,34 +196,32 @@ haveseen(dvp, tmpdvp) * since at that time we would know the full range. * XXX KERNBASE is a hack, we should have vaddr in the table! */ - if(tmpdvp->id_maddr) { - if((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) && - (KERNBASE + dvp->id_maddr <= - (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) { - conflict(dvp, tmpdvp, dvp->id_maddr, "maddr", - "0x%x"); + if (checkbits & CC_MEMADDR && tmpdvp->id_maddr) { + if ((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) && + (KERNBASE + dvp->id_maddr <= + (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) { + conflict(dvp, tmpdvp, (int)dvp->id_maddr, + whatnot, "maddr", "0x%x"); status = 1; } } -#ifndef COM_MULTIPORT /* * Check for IRQ conflicts. */ - if(tmpdvp->id_irq) { + if (checkbits & CC_IRQ && tmpdvp->id_irq) { if (tmpdvp->id_irq == dvp->id_irq) { conflict(dvp, tmpdvp, ffs(dvp->id_irq) - 1, - "irq", "%d"); + whatnot, "irq", "%d"); status = 1; } } -#endif /* * Check for DRQ conflicts. */ - if(tmpdvp->id_drq != -1) { + if (checkbits & CC_DRQ && tmpdvp->id_drq != -1) { if (tmpdvp->id_drq == dvp->id_drq) { - conflict(dvp, tmpdvp, dvp->id_drq, - "drq", "%d"); + conflict(dvp, tmpdvp, dvp->id_drq, whatnot, + "drq", "%d"); status = 1; } } @@ -179,25 +233,22 @@ haveseen(dvp, tmpdvp) * Search through all the isa_devtab_* tables looking for anything that * conflicts with the current device. */ -int -haveseen_isadev(dvp) +static int +haveseen_isadev(dvp, checkbits) struct isa_device *dvp; + u_int checkbits; { struct isa_device *tmpdvp; int status = 0; - for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++) { - status |= haveseen(dvp, tmpdvp); - } - for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++) { - status |= haveseen(dvp, tmpdvp); - } - for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++) { - status |= haveseen(dvp, tmpdvp); - } - for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++) { - status |= haveseen(dvp, tmpdvp); - } + for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++) + status |= haveseen(dvp, tmpdvp, checkbits); + for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++) + status |= haveseen(dvp, tmpdvp, checkbits); + for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++) + status |= haveseen(dvp, tmpdvp, checkbits); + for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++) + status |= haveseen(dvp, tmpdvp, checkbits); return(status); } @@ -208,26 +259,18 @@ void isa_configure() { struct isa_device *dvp; - enable_intr(); splhigh(); + enable_intr(); INTREN(IRQ_SLAVE); printf("Probing for devices on the ISA bus:\n"); - for (dvp = isa_devtab_tty; dvp->id_driver; dvp++) { - if (!haveseen_isadev(dvp)) - config_isadev(dvp,&tty_imask); - } - for (dvp = isa_devtab_bio; dvp->id_driver; dvp++) { - if (!haveseen_isadev(dvp)) - config_isadev(dvp,&bio_imask); - } - for (dvp = isa_devtab_net; dvp->id_driver; dvp++) { - if (!haveseen_isadev(dvp)) - config_isadev(dvp,&net_imask); - } - for (dvp = isa_devtab_null; dvp->id_driver; dvp++) { - if (!haveseen_isadev(dvp)) - config_isadev(dvp,(u_int *) NULL); - } + for (dvp = isa_devtab_tty; dvp->id_driver; dvp++) + config_isadev(dvp, &tty_imask); + for (dvp = isa_devtab_bio; dvp->id_driver; dvp++) + config_isadev(dvp, &bio_imask); + for (dvp = isa_devtab_net; dvp->id_driver; dvp++) + config_isadev(dvp, &net_imask); + for (dvp = isa_devtab_null; dvp->id_driver; dvp++) + config_isadev(dvp, (u_int *)NULL); bio_imask |= SWI_CLOCK_MASK; net_imask |= SWI_NET_MASK; tty_imask |= SWI_TTY_MASK; @@ -253,27 +296,54 @@ isa_configure() { printf("bio_imask %x tty_imask %x net_imask %x\n", bio_imask, tty_imask, net_imask); #endif + /* + * Finish initializing intr_mask[]. Note that the partly + * constructed masks aren't actually used since we're at splhigh. + * For fully dynamic initialization, register_intr() and + * unregister_intr() will have to adjust the masks for _all_ + * interrupts and for tty_imask, etc. + */ + for (dvp = isa_devtab_tty; dvp->id_driver; dvp++) + register_imask(dvp, tty_imask); + for (dvp = isa_devtab_bio; dvp->id_driver; dvp++) + register_imask(dvp, bio_imask); + for (dvp = isa_devtab_net; dvp->id_driver; dvp++) + register_imask(dvp, net_imask); + for (dvp = isa_devtab_null; dvp->id_driver; dvp++) + register_imask(dvp, SWI_CLOCK_MASK); splnone(); } /* * Configure an ISA device. */ -void +static void config_isadev(isdp, mp) struct isa_device *isdp; u_int *mp; { + u_int checkbits; + int id_alive; struct isa_driver *dp = isdp->id_driver; + checkbits = 0; +#ifndef ALLOW_CONFLICT_DRQ + checkbits |= CC_DRQ; +#endif +#ifndef ALLOW_CONFLICT_IOADDR + checkbits |= CC_IOADDR; +#endif +#ifndef ALLOW_CONFLICT_MEMADDR + checkbits |= CC_MEMADDR; +#endif + if (haveseen_isadev(isdp, checkbits)) + return; if (isdp->id_maddr) { - extern u_int atdevbase; - isdp->id_maddr -= 0xa0000; /* XXX should be a define */ isdp->id_maddr += atdevbase; } - isdp->id_alive = (*dp->probe)(isdp); - if (isdp->id_alive) { + id_alive = (*dp->probe)(isdp); + if (id_alive) { /* * Only print the I/O address range if id_alive != -1 * Right now this is a temporary fix just for the new @@ -282,21 +352,20 @@ config_isadev(isdp, mp) * Rod Grimes 04/26/94 */ printf("%s%d", dp->name, isdp->id_unit); - if (isdp->id_alive != -1) { + if (id_alive != -1) { printf(" at 0x%x", isdp->id_iobase); - if ((isdp->id_iobase + isdp->id_alive - 1) != + if ((isdp->id_iobase + id_alive - 1) != isdp->id_iobase) { printf("-0x%x", - isdp->id_iobase + - isdp->id_alive - 1); + isdp->id_iobase + id_alive - 1); } } - if(isdp->id_irq) + if (isdp->id_irq) printf(" irq %d", ffs(isdp->id_irq) - 1); if (isdp->id_drq != -1) printf(" drq %d", isdp->id_drq); if (isdp->id_maddr) - printf(" maddr 0x%x", kvtop(isdp->id_maddr)); + printf(" maddr 0x%lx", kvtop(isdp->id_maddr)); if (isdp->id_msize) printf(" msize %d", isdp->id_msize); if (isdp->id_flags) @@ -312,18 +381,25 @@ config_isadev(isdp, mp) } } } - + /* + * Check for conflicts again. The driver may have changed + * *dvp. We should weaken the early check since the + * driver may have been able to change *dvp to avoid + * conflicts if given a chance. We already skip the early + * check for IRQs and force a check for IRQs in the next + * group of checks. + */ + checkbits |= CC_IRQ; + if (haveseen_isadev(isdp, checkbits)) + return; + isdp->id_alive = id_alive; (*dp->attach)(isdp); - - if(isdp->id_irq) { - int intrno; - - intrno = ffs(isdp->id_irq)-1; - setidt(ICU_OFFSET+intrno, isdp->id_intr, - SDT_SYS386IGT, SEL_KPL); - if(mp) { - INTRMASK(*mp,isdp->id_irq); - } + if (isdp->id_irq) { + if (mp) + INTRMASK(*mp, isdp->id_irq); + register_intr(ffs(isdp->id_irq) - 1, isdp->id_id, + isdp->id_ri_flags, isdp->id_intr, + mp ? *mp : 0, isdp->id_unit); INTREN(isdp->id_irq); } } else { @@ -335,22 +411,6 @@ config_isadev(isdp, mp) } } -#define IDTVEC(name) __CONCAT(X,name) -/* default interrupt vector table entries */ -typedef void inthand_t(); -typedef void (*inthand_func_t)(); -extern inthand_t - IDTVEC(intr0), IDTVEC(intr1), IDTVEC(intr2), IDTVEC(intr3), - IDTVEC(intr4), IDTVEC(intr5), IDTVEC(intr6), IDTVEC(intr7), - IDTVEC(intr8), IDTVEC(intr9), IDTVEC(intr10), IDTVEC(intr11), - IDTVEC(intr12), IDTVEC(intr13), IDTVEC(intr14), IDTVEC(intr15); - -static inthand_func_t defvec[ICU_LEN] = { - &IDTVEC(intr0), &IDTVEC(intr1), &IDTVEC(intr2), &IDTVEC(intr3), - &IDTVEC(intr4), &IDTVEC(intr5), &IDTVEC(intr6), &IDTVEC(intr7), - &IDTVEC(intr8), &IDTVEC(intr9), &IDTVEC(intr10), &IDTVEC(intr11), - &IDTVEC(intr12), &IDTVEC(intr13), &IDTVEC(intr14), &IDTVEC(intr15) }; - /* * Fill in default interrupt table (in case of spuruious interrupt * during configuration of kernel, setup interrupt control unit @@ -362,7 +422,7 @@ isa_defaultirq() /* icu vectors */ for (i = 0; i < ICU_LEN; i++) - setidt(ICU_OFFSET + i, defvec[i], SDT_SYS386IGT, SEL_KPL); + unregister_intr(i, (inthand2_t *)NULL); /* initialize 8259's */ outb(IO_ICU1, 0x11); /* reset; program device, four bytes */ @@ -418,6 +478,9 @@ void isa_dmacascade(unsigned chan) } } +static int +isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan); + /* * isa_dmastart(): program 8237 DMA controller channel, avoid page alignment * problems by using a bounce buffer. @@ -520,7 +583,7 @@ void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan) * Return true if special handling needed. */ -int +static int isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan) { vm_offset_t phys, priorpage = 0, endva; u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1); @@ -622,7 +685,7 @@ isa_nmi(cd) /* * Caught a stray interrupt, notify */ -void +static void isa_strayintr(d) int d; { @@ -637,13 +700,18 @@ isa_strayintr(d) * the first 5 get logged, then it quits logging them, and puts * out a special message. rgrimes 3/25/1993 */ - extern u_long intrcnt_stray; - - intrcnt_stray++; - if (intrcnt_stray <= 5) - log(LOG_ERR,"ISA strayintr %x\n", d); - if (intrcnt_stray == 5) - log(LOG_CRIT,"Too many ISA strayintr not logging any more\n"); + /* + * XXX TODO print a different message for #7 if it is for a + * glitch. Glitches can be distinguished from real #7's by + * testing that the in-service bit is _not_ set. The test + * must be done before sending an EOI so it can't be done if + * we are using AUTO_EOI_1. + */ + if (intrcnt[NR_DEVICES + d] <= 5) + log(LOG_ERR, "stray irq %d\n", d); + if (intrcnt[NR_DEVICES + d] == 5) + log(LOG_CRIT, + "too many stray irq %d's; not logging any more\n", d); } /* @@ -683,8 +751,84 @@ isa_irq_pending(dvp) { unsigned id_irq; - id_irq = (unsigned short) dvp->id_irq; /* XXX silly type in struct */ + id_irq = dvp->id_irq; if (id_irq & 0xff) return (inb(IO_ICU1) & id_irq); return (inb(IO_ICU2) & (id_irq >> 8)); } + +int +register_intr(intr, device_id, flags, handler, mask, unit) + int intr; + int device_id; + u_int flags; + inthand2_t *handler; + u_int mask; + int unit; +{ + char *cp; + u_long ef; + int id; + + if ((u_int)intr >= ICU_LEN || intr == 2 + || (u_int)device_id >= NR_DEVICES) + return (EINVAL); + if (intr_handler[intr] != isa_strayintr) + return (EBUSY); + ef = read_eflags(); + disable_intr(); + intr_countp[intr] = &intrcnt[device_id]; + intr_handler[intr] = handler; + intr_mask[intr] = mask | (1 << intr); + intr_unit[intr] = unit; + setidt(ICU_OFFSET + intr, + flags & RI_FAST ? fastintr[intr] : slowintr[intr], + SDT_SYS386IGT, SEL_KPL); + write_eflags(ef); + for (cp = intrnames, id = 0; id <= device_id; id++) + while (*cp++ != '\0') + ; + if (cp > eintrnames) + return (0); + if (intr < 10) { + cp[-3] = intr + '0'; + cp[-2] = ' '; + } else { + cp[-3] = '1'; + cp[-2] = intr - 10 + '0'; + } + return (0); +} + +static void +register_imask(dvp, mask) + struct isa_device *dvp; + u_int mask; +{ + if (dvp->id_alive && dvp->id_irq) { + int intr; + + intr = ffs(dvp->id_irq) - 1; + intr_mask[intr] = mask | (1 <<intr); + } +} + +int +unregister_intr(intr, handler) + int intr; + inthand2_t *handler; +{ + u_long ef; + + if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr]) + return (EINVAL); + ef = read_eflags(); + disable_intr(); + intr_countp[intr] = &intrcnt[NR_DEVICES + intr]; + intr_handler[intr] = isa_strayintr; + intr_mask[intr] = HWI_MASK | SWI_MASK; + intr_unit[intr] = intr; + setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL); + write_eflags(ef); + return (0); +} diff --git a/sys/amd64/isa/vector.S b/sys/amd64/isa/vector.S index 7135ae7..252bd95 100644 --- a/sys/amd64/isa/vector.S +++ b/sys/amd64/isa/vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: vector.s,v 1.6 1994/01/10 23:15:09 ache Exp $ + * $Id: vector.s,v 1.7 1994/04/02 07:00:50 davidg Exp $ */ #include "i386/isa/icu.h" @@ -97,7 +97,10 @@ * loading segregs. */ -#define FAST_INTR(unit, irq_num, id_num, handler, enable_icus) \ +#define FAST_INTR(irq_num, enable_icus) \ + .text ; \ + SUPERALIGN_TEXT ; \ +IDTVEC(fastintr/**/irq_num) ; \ pushl %eax ; /* save only call-used registers */ \ pushl %ecx ; \ pushl %edx ; \ @@ -107,12 +110,13 @@ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ - pushl $unit ; \ - call handler ; /* do the work ASAP */ \ + pushl _intr_unit + (irq_num) * 4 ; \ + call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \ addl $4,%esp ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ - incl _intrcnt_actv + (id_num) * 4 ; \ + movl _intr_countp + (irq_num) * 4,%eax ; \ + incl (%eax) ; \ movl _cpl,%eax ; /* are we unmasking pending HWIs or SWIs? */ \ notl %eax ; \ andl _ipending,%eax ; \ @@ -147,7 +151,10 @@ MEXITCOUNT ; \ jmp _doreti -#define INTR(unit, irq_num, id_num, mask, handler, icu, enable_icus, reg, stray) \ +#define INTR(irq_num, icu, enable_icus, reg) \ + .text ; \ + SUPERALIGN_TEXT ; \ +IDTVEC(intr/**/irq_num) ; \ pushl $0 ; /* dumby error code */ \ pushl $0 ; /* dumby trap type */ \ pushal ; \ @@ -167,15 +174,17 @@ testb $IRQ_BIT(irq_num),%reg ; \ jne 2f ; \ 1: ; \ +Xresume/**/irq_num: ; \ FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \ - incl _intrcnt_actv + (id_num) * 4 ; \ + movl _intr_countp + (irq_num) * 4,%eax ; \ + incl (%eax) ; \ movl _cpl,%eax ; \ pushl %eax ; \ - pushl $unit ; \ - orl mask,%eax ; \ + pushl _intr_unit + (irq_num) * 4 ; \ + orl _intr_mask + (irq_num) * 4,%eax ; \ movl %eax,_cpl ; \ sti ; \ - call handler ; \ + call *_intr_handler + (irq_num) * 4 ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ andb $~IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -189,9 +198,6 @@ ALIGN_TEXT ; \ 2: ; \ /* XXX skip mcounting here to avoid double count */ \ - movl $1b,%eax ; /* register resume address */ \ - /* XXX - someday do it at attach time */ \ - movl %eax,ihandlers + (irq_num) * 4 ; \ orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \ popl %es ; \ popl %ds ; \ @@ -199,118 +205,48 @@ addl $4+4,%esp ; \ iret -/* - * vector.h has defined a macro 'BUILD_VECTORS' containing a big list of info - * about vectors, including a submacro 'BUILD_VECTOR' that operates on the - * info about each vector. We redefine 'BUILD_VECTOR' to expand the info - * in different ways. Here we expand it to a list of interrupt handlers. - * This order is of course unimportant. Elsewhere we expand it to inline - * linear search code for which the order is a little more important and - * concatenating the code with no holes is very important. - * - * XXX - now there is BUILD_FAST_VECTOR as well as BUILD_VECTOR. - * - * The info consists of the following items for each vector: - * - * name (identifier): name of the vector; used to build labels - * unit (expression): unit number to call the device driver with - * irq_num (number): number of the IRQ to handled (0-15) - * id_num (number): uniq numeric id for handler (assigned by config) - * mask (blank-ident): priority mask used - * handler (blank-ident): interrupt handler to call - * icu_num (number): (1 + irq_num / 8) converted for label building - * icu_enables (number): 1 for icu_num == 1, 1_AND_2 for icu_num == 2 - * reg (blank-ident): al for icu_num == 1, ah for icu_num == 2 - * - * 'irq_num' is converted in several ways at config time to get around - * limitations in cpp. The macros have blanks after commas iff they would - * not mess up identifiers and numbers. - */ - -#undef BUILD_FAST_VECTOR -#define BUILD_FAST_VECTOR(name, unit, irq_num, id_num, mask, handler, \ - icu_num, icu_enables, reg) \ - .globl handler ; \ - .text ; \ - .globl _V/**/name ; \ - SUPERALIGN_TEXT ; \ -_V/**/name: ; \ - FAST_INTR(unit, irq_num,id_num, handler, ENABLE_ICU/**/icu_enables) - -#undef BUILD_VECTOR -#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \ - icu_num, icu_enables, reg) \ - .globl handler ; \ - .text ; \ - .globl _V/**/name ; \ - SUPERALIGN_TEXT ; \ -_V/**/name: ; \ - INTR(unit,irq_num, id_num, mask, handler, IO_ICU/**/icu_num, \ - ENABLE_ICU/**/icu_enables, reg,) - MCOUNT_LABEL(bintr) - BUILD_VECTORS - - /* hardware interrupt catcher (IDT 32 - 47) */ - .globl _isa_strayintr - -#define STRAYINTR(irq_num, icu_num, icu_enables, reg) \ -IDTVEC(intr/**/irq_num) ; \ - INTR(irq_num,irq_num,irq_num, _high_imask, _isa_strayintr, \ - IO_ICU/**/icu_num, ENABLE_ICU/**/icu_enables, reg,stray) - -/* - * XXX - the mask (1 << 2) == IRQ_SLAVE will be generated for IRQ 2, instead - * of the mask IRQ2 (defined as IRQ9 == (1 << 9)). But IRQ 2 "can't happen". - * In fact, all stray interrupts "can't happen" except for bugs. The - * "stray" IRQ 7 is documented behaviour of the 8259. It happens when there - * is a glitch on any of its interrupt inputs. Does it really interrupt when - * IRQ 7 is masked? - * - * XXX - unpend doesn't work for these, it sends them to the real handler. - * - * XXX - the race bug during initialization may be because I changed the - * order of switching from the stray to the real interrupt handler to before - * enabling interrupts. The old order looked unsafe but maybe it is OK with - * the stray interrupt handler installed. But these handlers only reduce - * the window of vulnerability - it is still open at the end of - * isa_configure(). - * - * XXX - many comments are stale. - */ - - STRAYINTR(0,1,1, al) - STRAYINTR(1,1,1, al) - STRAYINTR(2,1,1, al) - STRAYINTR(3,1,1, al) - STRAYINTR(4,1,1, al) - STRAYINTR(5,1,1, al) - STRAYINTR(6,1,1, al) - STRAYINTR(7,1,1, al) - STRAYINTR(8,2,1_AND_2, ah) - STRAYINTR(9,2,1_AND_2, ah) - STRAYINTR(10,2,1_AND_2, ah) - STRAYINTR(11,2,1_AND_2, ah) - STRAYINTR(12,2,1_AND_2, ah) - STRAYINTR(13,2,1_AND_2, ah) - STRAYINTR(14,2,1_AND_2, ah) - STRAYINTR(15,2,1_AND_2, ah) -#if 0 - INTRSTRAY(255, _highmask, 255) ; call _isa_strayintr ; INTREXIT2 -#endif + FAST_INTR(0, ENABLE_ICU1) + FAST_INTR(1, ENABLE_ICU1) + FAST_INTR(2, ENABLE_ICU1) + FAST_INTR(3, ENABLE_ICU1) + FAST_INTR(4, ENABLE_ICU1) + FAST_INTR(5, ENABLE_ICU1) + FAST_INTR(6, ENABLE_ICU1) + FAST_INTR(7, ENABLE_ICU1) + FAST_INTR(8, ENABLE_ICU1_AND_2) + FAST_INTR(9, ENABLE_ICU1_AND_2) + FAST_INTR(10, ENABLE_ICU1_AND_2) + FAST_INTR(11, ENABLE_ICU1_AND_2) + FAST_INTR(12, ENABLE_ICU1_AND_2) + FAST_INTR(13, ENABLE_ICU1_AND_2) + FAST_INTR(14, ENABLE_ICU1_AND_2) + FAST_INTR(15, ENABLE_ICU1_AND_2) + INTR(0, IO_ICU1, ENABLE_ICU1, al) + INTR(1, IO_ICU1, ENABLE_ICU1, al) + INTR(2, IO_ICU1, ENABLE_ICU1, al) + INTR(3, IO_ICU1, ENABLE_ICU1, al) + INTR(4, IO_ICU1, ENABLE_ICU1, al) + INTR(5, IO_ICU1, ENABLE_ICU1, al) + INTR(6, IO_ICU1, ENABLE_ICU1, al) + INTR(7, IO_ICU1, ENABLE_ICU1, al) + INTR(8, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(9, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(10, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(11, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(12, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(13, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(14, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(15, IO_ICU2, ENABLE_ICU1_AND_2, ah) MCOUNT_LABEL(eintr) -/* - * These are the interrupt counters, I moved them here from icu.s so that - * they are with the name table. rgrimes - * - * There are now lots of counters, this has been redone to work with - * Bruce Evans intr-0.1 code, which I modified some more to make it all - * work with vmstat. - */ .data ihandlers: /* addresses of interrupt handlers */ - .space NHWI*4 /* actually resumption addresses for HWI's */ + /* actually resumption addresses for HWI's */ + .long Xresume0, Xresume1, Xresume2, Xresume3 + .long Xresume4, Xresume5, Xresume6, Xresume7 + .long Xresume8, Xresume9, Xresume10, Xresume11 + .long Xresume12, Xresume13, Xresume14, Xresume15 .long swi_tty, swi_net, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, swi_clock, swi_ast imasks: /* masks for interrupt handlers */ @@ -318,43 +254,37 @@ imasks: /* masks for interrupt handlers */ .long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK - .globl _intrcnt -_intrcnt: /* used by vmstat to calc size of table */ - .globl _intrcnt_bad7 -_intrcnt_bad7: .space 4 /* glitches on irq 7 */ - .globl _intrcnt_bad15 -_intrcnt_bad15: .space 4 /* glitches on irq 15 */ - .globl _intrcnt_stray -_intrcnt_stray: .space 4 /* total count of stray interrupts */ - .globl _intrcnt_actv -_intrcnt_actv: .space NR_REAL_INT_HANDLERS * 4 /* active interrupts */ - .globl _eintrcnt -_eintrcnt: /* used by vmstat to calc size of table */ - -/* - * Build the interrupt name table for vmstat - */ - -#undef BUILD_FAST_VECTOR -#define BUILD_FAST_VECTOR BUILD_VECTOR - -#undef BUILD_VECTOR -#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \ - icu_num, icu_enables, reg) \ - .ascii "name irq" ; \ - .asciz "irq_num" /* - * XXX - use the __STRING and __CONCAT macros from <sys/cdefs.h> to stringize - * and concatenate names above and elsewhere. Note that __CONCAT doesn't - * work when nested. + * Interrupt counters and names. The format of these and the label names + * must agree with what vmstat expects. The tables are indexed by device + * ids so that we don't have to move the names around as devices are + * attached. */ +#include "vector.h" + .globl _intrcnt, _eintrcnt +_intrcnt: + .space (NR_DEVICES + ICU_LEN) * 4 +_eintrcnt: - .text .globl _intrnames, _eintrnames _intrnames: - BUILD_VECTOR(bad,,7,,,,,,) - BUILD_VECTOR(bad,,15,,,,,,) - BUILD_VECTOR(stray,,,,,,,,) - BUILD_VECTORS - + .ascii DEVICE_NAMES + .asciz "stray irq0" + .asciz "stray irq1" + .asciz "stray irq2" + .asciz "stray irq3" + .asciz "stray irq4" + .asciz "stray irq5" + .asciz "stray irq6" + .asciz "stray irq7" + .asciz "stray irq8" + .asciz "stray irq9" + .asciz "stray irq10" + .asciz "stray irq11" + .asciz "stray irq12" + .asciz "stray irq13" + .asciz "stray irq14" + .asciz "stray irq15" _eintrnames: + + .text diff --git a/sys/amd64/isa/vector.s b/sys/amd64/isa/vector.s index 7135ae7..252bd95 100644 --- a/sys/amd64/isa/vector.s +++ b/sys/amd64/isa/vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: vector.s,v 1.6 1994/01/10 23:15:09 ache Exp $ + * $Id: vector.s,v 1.7 1994/04/02 07:00:50 davidg Exp $ */ #include "i386/isa/icu.h" @@ -97,7 +97,10 @@ * loading segregs. */ -#define FAST_INTR(unit, irq_num, id_num, handler, enable_icus) \ +#define FAST_INTR(irq_num, enable_icus) \ + .text ; \ + SUPERALIGN_TEXT ; \ +IDTVEC(fastintr/**/irq_num) ; \ pushl %eax ; /* save only call-used registers */ \ pushl %ecx ; \ pushl %edx ; \ @@ -107,12 +110,13 @@ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ - pushl $unit ; \ - call handler ; /* do the work ASAP */ \ + pushl _intr_unit + (irq_num) * 4 ; \ + call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \ addl $4,%esp ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ - incl _intrcnt_actv + (id_num) * 4 ; \ + movl _intr_countp + (irq_num) * 4,%eax ; \ + incl (%eax) ; \ movl _cpl,%eax ; /* are we unmasking pending HWIs or SWIs? */ \ notl %eax ; \ andl _ipending,%eax ; \ @@ -147,7 +151,10 @@ MEXITCOUNT ; \ jmp _doreti -#define INTR(unit, irq_num, id_num, mask, handler, icu, enable_icus, reg, stray) \ +#define INTR(irq_num, icu, enable_icus, reg) \ + .text ; \ + SUPERALIGN_TEXT ; \ +IDTVEC(intr/**/irq_num) ; \ pushl $0 ; /* dumby error code */ \ pushl $0 ; /* dumby trap type */ \ pushal ; \ @@ -167,15 +174,17 @@ testb $IRQ_BIT(irq_num),%reg ; \ jne 2f ; \ 1: ; \ +Xresume/**/irq_num: ; \ FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \ - incl _intrcnt_actv + (id_num) * 4 ; \ + movl _intr_countp + (irq_num) * 4,%eax ; \ + incl (%eax) ; \ movl _cpl,%eax ; \ pushl %eax ; \ - pushl $unit ; \ - orl mask,%eax ; \ + pushl _intr_unit + (irq_num) * 4 ; \ + orl _intr_mask + (irq_num) * 4,%eax ; \ movl %eax,_cpl ; \ sti ; \ - call handler ; \ + call *_intr_handler + (irq_num) * 4 ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ andb $~IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -189,9 +198,6 @@ ALIGN_TEXT ; \ 2: ; \ /* XXX skip mcounting here to avoid double count */ \ - movl $1b,%eax ; /* register resume address */ \ - /* XXX - someday do it at attach time */ \ - movl %eax,ihandlers + (irq_num) * 4 ; \ orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \ popl %es ; \ popl %ds ; \ @@ -199,118 +205,48 @@ addl $4+4,%esp ; \ iret -/* - * vector.h has defined a macro 'BUILD_VECTORS' containing a big list of info - * about vectors, including a submacro 'BUILD_VECTOR' that operates on the - * info about each vector. We redefine 'BUILD_VECTOR' to expand the info - * in different ways. Here we expand it to a list of interrupt handlers. - * This order is of course unimportant. Elsewhere we expand it to inline - * linear search code for which the order is a little more important and - * concatenating the code with no holes is very important. - * - * XXX - now there is BUILD_FAST_VECTOR as well as BUILD_VECTOR. - * - * The info consists of the following items for each vector: - * - * name (identifier): name of the vector; used to build labels - * unit (expression): unit number to call the device driver with - * irq_num (number): number of the IRQ to handled (0-15) - * id_num (number): uniq numeric id for handler (assigned by config) - * mask (blank-ident): priority mask used - * handler (blank-ident): interrupt handler to call - * icu_num (number): (1 + irq_num / 8) converted for label building - * icu_enables (number): 1 for icu_num == 1, 1_AND_2 for icu_num == 2 - * reg (blank-ident): al for icu_num == 1, ah for icu_num == 2 - * - * 'irq_num' is converted in several ways at config time to get around - * limitations in cpp. The macros have blanks after commas iff they would - * not mess up identifiers and numbers. - */ - -#undef BUILD_FAST_VECTOR -#define BUILD_FAST_VECTOR(name, unit, irq_num, id_num, mask, handler, \ - icu_num, icu_enables, reg) \ - .globl handler ; \ - .text ; \ - .globl _V/**/name ; \ - SUPERALIGN_TEXT ; \ -_V/**/name: ; \ - FAST_INTR(unit, irq_num,id_num, handler, ENABLE_ICU/**/icu_enables) - -#undef BUILD_VECTOR -#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \ - icu_num, icu_enables, reg) \ - .globl handler ; \ - .text ; \ - .globl _V/**/name ; \ - SUPERALIGN_TEXT ; \ -_V/**/name: ; \ - INTR(unit,irq_num, id_num, mask, handler, IO_ICU/**/icu_num, \ - ENABLE_ICU/**/icu_enables, reg,) - MCOUNT_LABEL(bintr) - BUILD_VECTORS - - /* hardware interrupt catcher (IDT 32 - 47) */ - .globl _isa_strayintr - -#define STRAYINTR(irq_num, icu_num, icu_enables, reg) \ -IDTVEC(intr/**/irq_num) ; \ - INTR(irq_num,irq_num,irq_num, _high_imask, _isa_strayintr, \ - IO_ICU/**/icu_num, ENABLE_ICU/**/icu_enables, reg,stray) - -/* - * XXX - the mask (1 << 2) == IRQ_SLAVE will be generated for IRQ 2, instead - * of the mask IRQ2 (defined as IRQ9 == (1 << 9)). But IRQ 2 "can't happen". - * In fact, all stray interrupts "can't happen" except for bugs. The - * "stray" IRQ 7 is documented behaviour of the 8259. It happens when there - * is a glitch on any of its interrupt inputs. Does it really interrupt when - * IRQ 7 is masked? - * - * XXX - unpend doesn't work for these, it sends them to the real handler. - * - * XXX - the race bug during initialization may be because I changed the - * order of switching from the stray to the real interrupt handler to before - * enabling interrupts. The old order looked unsafe but maybe it is OK with - * the stray interrupt handler installed. But these handlers only reduce - * the window of vulnerability - it is still open at the end of - * isa_configure(). - * - * XXX - many comments are stale. - */ - - STRAYINTR(0,1,1, al) - STRAYINTR(1,1,1, al) - STRAYINTR(2,1,1, al) - STRAYINTR(3,1,1, al) - STRAYINTR(4,1,1, al) - STRAYINTR(5,1,1, al) - STRAYINTR(6,1,1, al) - STRAYINTR(7,1,1, al) - STRAYINTR(8,2,1_AND_2, ah) - STRAYINTR(9,2,1_AND_2, ah) - STRAYINTR(10,2,1_AND_2, ah) - STRAYINTR(11,2,1_AND_2, ah) - STRAYINTR(12,2,1_AND_2, ah) - STRAYINTR(13,2,1_AND_2, ah) - STRAYINTR(14,2,1_AND_2, ah) - STRAYINTR(15,2,1_AND_2, ah) -#if 0 - INTRSTRAY(255, _highmask, 255) ; call _isa_strayintr ; INTREXIT2 -#endif + FAST_INTR(0, ENABLE_ICU1) + FAST_INTR(1, ENABLE_ICU1) + FAST_INTR(2, ENABLE_ICU1) + FAST_INTR(3, ENABLE_ICU1) + FAST_INTR(4, ENABLE_ICU1) + FAST_INTR(5, ENABLE_ICU1) + FAST_INTR(6, ENABLE_ICU1) + FAST_INTR(7, ENABLE_ICU1) + FAST_INTR(8, ENABLE_ICU1_AND_2) + FAST_INTR(9, ENABLE_ICU1_AND_2) + FAST_INTR(10, ENABLE_ICU1_AND_2) + FAST_INTR(11, ENABLE_ICU1_AND_2) + FAST_INTR(12, ENABLE_ICU1_AND_2) + FAST_INTR(13, ENABLE_ICU1_AND_2) + FAST_INTR(14, ENABLE_ICU1_AND_2) + FAST_INTR(15, ENABLE_ICU1_AND_2) + INTR(0, IO_ICU1, ENABLE_ICU1, al) + INTR(1, IO_ICU1, ENABLE_ICU1, al) + INTR(2, IO_ICU1, ENABLE_ICU1, al) + INTR(3, IO_ICU1, ENABLE_ICU1, al) + INTR(4, IO_ICU1, ENABLE_ICU1, al) + INTR(5, IO_ICU1, ENABLE_ICU1, al) + INTR(6, IO_ICU1, ENABLE_ICU1, al) + INTR(7, IO_ICU1, ENABLE_ICU1, al) + INTR(8, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(9, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(10, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(11, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(12, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(13, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(14, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(15, IO_ICU2, ENABLE_ICU1_AND_2, ah) MCOUNT_LABEL(eintr) -/* - * These are the interrupt counters, I moved them here from icu.s so that - * they are with the name table. rgrimes - * - * There are now lots of counters, this has been redone to work with - * Bruce Evans intr-0.1 code, which I modified some more to make it all - * work with vmstat. - */ .data ihandlers: /* addresses of interrupt handlers */ - .space NHWI*4 /* actually resumption addresses for HWI's */ + /* actually resumption addresses for HWI's */ + .long Xresume0, Xresume1, Xresume2, Xresume3 + .long Xresume4, Xresume5, Xresume6, Xresume7 + .long Xresume8, Xresume9, Xresume10, Xresume11 + .long Xresume12, Xresume13, Xresume14, Xresume15 .long swi_tty, swi_net, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, swi_clock, swi_ast imasks: /* masks for interrupt handlers */ @@ -318,43 +254,37 @@ imasks: /* masks for interrupt handlers */ .long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK - .globl _intrcnt -_intrcnt: /* used by vmstat to calc size of table */ - .globl _intrcnt_bad7 -_intrcnt_bad7: .space 4 /* glitches on irq 7 */ - .globl _intrcnt_bad15 -_intrcnt_bad15: .space 4 /* glitches on irq 15 */ - .globl _intrcnt_stray -_intrcnt_stray: .space 4 /* total count of stray interrupts */ - .globl _intrcnt_actv -_intrcnt_actv: .space NR_REAL_INT_HANDLERS * 4 /* active interrupts */ - .globl _eintrcnt -_eintrcnt: /* used by vmstat to calc size of table */ - -/* - * Build the interrupt name table for vmstat - */ - -#undef BUILD_FAST_VECTOR -#define BUILD_FAST_VECTOR BUILD_VECTOR - -#undef BUILD_VECTOR -#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \ - icu_num, icu_enables, reg) \ - .ascii "name irq" ; \ - .asciz "irq_num" /* - * XXX - use the __STRING and __CONCAT macros from <sys/cdefs.h> to stringize - * and concatenate names above and elsewhere. Note that __CONCAT doesn't - * work when nested. + * Interrupt counters and names. The format of these and the label names + * must agree with what vmstat expects. The tables are indexed by device + * ids so that we don't have to move the names around as devices are + * attached. */ +#include "vector.h" + .globl _intrcnt, _eintrcnt +_intrcnt: + .space (NR_DEVICES + ICU_LEN) * 4 +_eintrcnt: - .text .globl _intrnames, _eintrnames _intrnames: - BUILD_VECTOR(bad,,7,,,,,,) - BUILD_VECTOR(bad,,15,,,,,,) - BUILD_VECTOR(stray,,,,,,,,) - BUILD_VECTORS - + .ascii DEVICE_NAMES + .asciz "stray irq0" + .asciz "stray irq1" + .asciz "stray irq2" + .asciz "stray irq3" + .asciz "stray irq4" + .asciz "stray irq5" + .asciz "stray irq6" + .asciz "stray irq7" + .asciz "stray irq8" + .asciz "stray irq9" + .asciz "stray irq10" + .asciz "stray irq11" + .asciz "stray irq12" + .asciz "stray irq13" + .asciz "stray irq14" + .asciz "stray irq15" _eintrnames: + + .text diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index de95e90..d505c4d 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.47 1994/05/26 13:31:40 rgrimes Exp $ + * $Id: sio.c,v 1.48 1994/08/13 03:50:13 wollman Exp $ */ #include "sio.h" @@ -427,6 +427,7 @@ sioattach(isdp) int s; int unit; + isdp->id_ri_flags |= RI_FAST; iobase = isdp->id_iobase; unit = isdp->id_unit; s = spltty(); diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c index 35f2e42..e3f3f21 100644 --- a/sys/i386/i386/tsc.c +++ b/sys/i386/i386/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $ + * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $ */ /* @@ -497,16 +497,14 @@ test_inittodr(time_t base) /* * Wire clock interrupt in. */ -#define V(s) __CONCAT(V, s) -extern void V(clk)(); -extern void V(rtc)(); - void enablertclock() { - setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr, + HWI_MASK | SWI_MASK, /* unit */ 0); INTREN(IRQ0); - setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr, + SWI_CLOCK_MASK, /* unit */ 0); INTREN(IRQ8); outb(IO_RTC, RTC_STATUSB); outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR); diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index 35f2e42..e3f3f21 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $ + * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $ */ /* @@ -497,16 +497,14 @@ test_inittodr(time_t base) /* * Wire clock interrupt in. */ -#define V(s) __CONCAT(V, s) -extern void V(clk)(); -extern void V(rtc)(); - void enablertclock() { - setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr, + HWI_MASK | SWI_MASK, /* unit */ 0); INTREN(IRQ0); - setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr, + SWI_CLOCK_MASK, /* unit */ 0); INTREN(IRQ8); outb(IO_RTC, RTC_STATUSB); outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR); diff --git a/sys/i386/isa/icu.s b/sys/i386/isa/icu.s index 735eeda..4956ab8 100644 --- a/sys/i386/isa/icu.s +++ b/sys/i386/isa/icu.s @@ -36,7 +36,7 @@ * * @(#)icu.s 7.2 (Berkeley) 5/21/91 * - * $Id: icu.s,v 1.10 1994/08/13 03:50:01 wollman Exp $ + * $Id: icu.s,v 1.11 1994/08/15 03:15:19 wollman Exp $ */ /* @@ -57,7 +57,6 @@ _cpl: .long HWI_MASK | SWI_MASK /* current priority (all off) */ .globl _imen _imen: .long HWI_MASK /* interrupt mask enable (all h/w off) */ -_high_imask: .long HWI_MASK | SWI_MASK .globl _stat_imask _stat_imask: .long (1 << 8) .globl _tty_imask @@ -236,8 +235,8 @@ splz_swi: jmp splz_next /* - * Fake clock IRQ so that it appears to come from our caller and not from - * vec0, so that kernel profiling works. + * Fake clock interrupt(s) so that they appear to come from our caller instead + * of from here, so that system profiling works. * XXX do this more generally (for all vectors; look up the C entry point). * XXX frame bogusness stops us from just jumping to the C entry point. */ @@ -250,7 +249,17 @@ vec0: pushl %eax cli MEXITCOUNT - jmp _Vclk + jmp _Xintr0 /* XXX might need _Xfastintr0 */ + + ALIGN_TEXT +vec8: + popl %eax + pushfl + pushl $KCSEL + pushl %eax + cli + MEXITCOUNT + jmp _Xintr8 /* XXX might need _Xfastintr8 */ #define BUILD_VEC(irq_num) \ ALIGN_TEXT ; \ @@ -265,7 +274,6 @@ vec/**/irq_num: ; \ BUILD_VEC(5) BUILD_VEC(6) BUILD_VEC(7) - BUILD_VEC(8) BUILD_VEC(9) BUILD_VEC(10) BUILD_VEC(11) diff --git a/sys/i386/isa/isa.c b/sys/i386/isa/isa.c index 80be9a5..5b5878e 100644 --- a/sys/i386/isa/isa.c +++ b/sys/i386/isa/isa.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: isa.c,v 1.19 1994/08/10 04:39:52 wollman Exp $ + * $Id: isa.c,v 1.20 1994/08/13 03:50:07 wollman Exp $ */ /* @@ -65,6 +65,7 @@ #include <i386/isa/icu.h> #include <i386/isa/ic/i8237.h> #include <i386/isa/ic/i8042.h> +#include "vector.h" /* ** Register definitions for DMA controller 1 (channels 0..3): @@ -82,20 +83,70 @@ #define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */ #define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */ -void config_isadev __P((struct isa_device *, u_int *)); +/* + * Bits to specify the type and amount of conflict checking. + */ +#define CC_ATTACH (1 << 0) +#define CC_DRQ (1 << 1) +#define CC_IOADDR (1 << 2) +#define CC_IRQ (1 << 3) +#define CC_MEMADDR (1 << 4) + +/* + * XXX these defines should be in a central place. + */ +#define read_eflags() ({u_long ef; \ + __asm("pushfl; popl %0" : "=a" (ef)); \ + ef; }) +#define write_eflags(ef) __asm("pushl %0; popfl" : : "a" ((u_long)(ef))) + +u_long *intr_countp[ICU_LEN]; +inthand2_t *intr_handler[ICU_LEN]; +u_int intr_mask[ICU_LEN]; +int intr_unit[ICU_LEN]; + +static inthand_t *fastintr[ICU_LEN] = { + &IDTVEC(fastintr0), &IDTVEC(fastintr1), + &IDTVEC(fastintr2), &IDTVEC(fastintr3), + &IDTVEC(fastintr4), &IDTVEC(fastintr5), + &IDTVEC(fastintr6), &IDTVEC(fastintr7), + &IDTVEC(fastintr8), &IDTVEC(fastintr9), + &IDTVEC(fastintr10), &IDTVEC(fastintr11), + &IDTVEC(fastintr12), &IDTVEC(fastintr13), + &IDTVEC(fastintr14), &IDTVEC(fastintr15) +}; + +static inthand_t *slowintr[ICU_LEN] = { + &IDTVEC(intr0), &IDTVEC(intr1), &IDTVEC(intr2), &IDTVEC(intr3), + &IDTVEC(intr4), &IDTVEC(intr5), &IDTVEC(intr6), &IDTVEC(intr7), + &IDTVEC(intr8), &IDTVEC(intr9), &IDTVEC(intr10), &IDTVEC(intr11), + &IDTVEC(intr12), &IDTVEC(intr13), &IDTVEC(intr14), &IDTVEC(intr15) +}; + +static void config_isadev __P((struct isa_device *isdp, u_int *mp)); +static void conflict __P((struct isa_device *dvp, struct isa_device *tmpdvp, + int item, char const *whatnot, char const *reason, + char const *format)); +static int haveseen __P((struct isa_device *dvp, struct isa_device *tmpdvp, + u_int checkbits)); +static int haveseen_isadev __P((struct isa_device *dvp, u_int checkbits)); +static inthand2_t isa_strayintr; +static void register_imask __P((struct isa_device *dvp, u_int mask)); /* * print a conflict message */ -void -conflict(dvp, tmpdvp, item, reason, format) - struct isa_device *dvp, *tmpdvp; +static void +conflict(dvp, tmpdvp, item, whatnot, reason, format) + struct isa_device *dvp; + struct isa_device *tmpdvp; int item; - char *reason; - char *format; + char const *whatnot; + char const *reason; + char const *format; { - printf("%s%d not probed due to %s conflict with %s%d at ", - dvp->id_driver->name, dvp->id_unit, reason, + printf("%s%d not %sed due to %s conflict with %s%d at ", + dvp->id_driver->name, dvp->id_unit, whatnot, reason, tmpdvp->id_driver->name, tmpdvp->id_unit); printf(format, item); printf("\n"); @@ -105,9 +156,11 @@ conflict(dvp, tmpdvp, item, reason, format) * Check to see if things are alread in use, like IRQ's, I/O addresses * and Memory addresses. */ -int -haveseen(dvp, tmpdvp) - struct isa_device *dvp, *tmpdvp; +static int +haveseen(dvp, tmpdvp, checkbits) + struct isa_device *dvp; + struct isa_device *tmpdvp; + u_int checkbits; { int status = 0; @@ -115,17 +168,20 @@ haveseen(dvp, tmpdvp) * Only check against devices that have already been found */ if (tmpdvp->id_alive) { + char const *whatnot; + + whatnot = checkbits & CC_ATTACH ? "attach" : "probe"; /* * Check for I/O address conflict. We can only check the * starting address of the device against the range of the * device that has already been probed since we do not * know how many I/O addresses this device uses. */ - if (tmpdvp->id_alive != -1) { + if (checkbits & CC_IOADDR && tmpdvp->id_alive != -1) { if ((dvp->id_iobase >= tmpdvp->id_iobase) && (dvp->id_iobase <= (tmpdvp->id_iobase + tmpdvp->id_alive - 1))) { - conflict(dvp, tmpdvp, dvp->id_iobase, + conflict(dvp, tmpdvp, dvp->id_iobase, whatnot, "I/O address", "0x%x"); status = 1; } @@ -140,34 +196,32 @@ haveseen(dvp, tmpdvp) * since at that time we would know the full range. * XXX KERNBASE is a hack, we should have vaddr in the table! */ - if(tmpdvp->id_maddr) { - if((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) && - (KERNBASE + dvp->id_maddr <= - (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) { - conflict(dvp, tmpdvp, dvp->id_maddr, "maddr", - "0x%x"); + if (checkbits & CC_MEMADDR && tmpdvp->id_maddr) { + if ((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) && + (KERNBASE + dvp->id_maddr <= + (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) { + conflict(dvp, tmpdvp, (int)dvp->id_maddr, + whatnot, "maddr", "0x%x"); status = 1; } } -#ifndef COM_MULTIPORT /* * Check for IRQ conflicts. */ - if(tmpdvp->id_irq) { + if (checkbits & CC_IRQ && tmpdvp->id_irq) { if (tmpdvp->id_irq == dvp->id_irq) { conflict(dvp, tmpdvp, ffs(dvp->id_irq) - 1, - "irq", "%d"); + whatnot, "irq", "%d"); status = 1; } } -#endif /* * Check for DRQ conflicts. */ - if(tmpdvp->id_drq != -1) { + if (checkbits & CC_DRQ && tmpdvp->id_drq != -1) { if (tmpdvp->id_drq == dvp->id_drq) { - conflict(dvp, tmpdvp, dvp->id_drq, - "drq", "%d"); + conflict(dvp, tmpdvp, dvp->id_drq, whatnot, + "drq", "%d"); status = 1; } } @@ -179,25 +233,22 @@ haveseen(dvp, tmpdvp) * Search through all the isa_devtab_* tables looking for anything that * conflicts with the current device. */ -int -haveseen_isadev(dvp) +static int +haveseen_isadev(dvp, checkbits) struct isa_device *dvp; + u_int checkbits; { struct isa_device *tmpdvp; int status = 0; - for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++) { - status |= haveseen(dvp, tmpdvp); - } - for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++) { - status |= haveseen(dvp, tmpdvp); - } - for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++) { - status |= haveseen(dvp, tmpdvp); - } - for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++) { - status |= haveseen(dvp, tmpdvp); - } + for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++) + status |= haveseen(dvp, tmpdvp, checkbits); + for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++) + status |= haveseen(dvp, tmpdvp, checkbits); + for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++) + status |= haveseen(dvp, tmpdvp, checkbits); + for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++) + status |= haveseen(dvp, tmpdvp, checkbits); return(status); } @@ -208,26 +259,18 @@ void isa_configure() { struct isa_device *dvp; - enable_intr(); splhigh(); + enable_intr(); INTREN(IRQ_SLAVE); printf("Probing for devices on the ISA bus:\n"); - for (dvp = isa_devtab_tty; dvp->id_driver; dvp++) { - if (!haveseen_isadev(dvp)) - config_isadev(dvp,&tty_imask); - } - for (dvp = isa_devtab_bio; dvp->id_driver; dvp++) { - if (!haveseen_isadev(dvp)) - config_isadev(dvp,&bio_imask); - } - for (dvp = isa_devtab_net; dvp->id_driver; dvp++) { - if (!haveseen_isadev(dvp)) - config_isadev(dvp,&net_imask); - } - for (dvp = isa_devtab_null; dvp->id_driver; dvp++) { - if (!haveseen_isadev(dvp)) - config_isadev(dvp,(u_int *) NULL); - } + for (dvp = isa_devtab_tty; dvp->id_driver; dvp++) + config_isadev(dvp, &tty_imask); + for (dvp = isa_devtab_bio; dvp->id_driver; dvp++) + config_isadev(dvp, &bio_imask); + for (dvp = isa_devtab_net; dvp->id_driver; dvp++) + config_isadev(dvp, &net_imask); + for (dvp = isa_devtab_null; dvp->id_driver; dvp++) + config_isadev(dvp, (u_int *)NULL); bio_imask |= SWI_CLOCK_MASK; net_imask |= SWI_NET_MASK; tty_imask |= SWI_TTY_MASK; @@ -253,27 +296,54 @@ isa_configure() { printf("bio_imask %x tty_imask %x net_imask %x\n", bio_imask, tty_imask, net_imask); #endif + /* + * Finish initializing intr_mask[]. Note that the partly + * constructed masks aren't actually used since we're at splhigh. + * For fully dynamic initialization, register_intr() and + * unregister_intr() will have to adjust the masks for _all_ + * interrupts and for tty_imask, etc. + */ + for (dvp = isa_devtab_tty; dvp->id_driver; dvp++) + register_imask(dvp, tty_imask); + for (dvp = isa_devtab_bio; dvp->id_driver; dvp++) + register_imask(dvp, bio_imask); + for (dvp = isa_devtab_net; dvp->id_driver; dvp++) + register_imask(dvp, net_imask); + for (dvp = isa_devtab_null; dvp->id_driver; dvp++) + register_imask(dvp, SWI_CLOCK_MASK); splnone(); } /* * Configure an ISA device. */ -void +static void config_isadev(isdp, mp) struct isa_device *isdp; u_int *mp; { + u_int checkbits; + int id_alive; struct isa_driver *dp = isdp->id_driver; + checkbits = 0; +#ifndef ALLOW_CONFLICT_DRQ + checkbits |= CC_DRQ; +#endif +#ifndef ALLOW_CONFLICT_IOADDR + checkbits |= CC_IOADDR; +#endif +#ifndef ALLOW_CONFLICT_MEMADDR + checkbits |= CC_MEMADDR; +#endif + if (haveseen_isadev(isdp, checkbits)) + return; if (isdp->id_maddr) { - extern u_int atdevbase; - isdp->id_maddr -= 0xa0000; /* XXX should be a define */ isdp->id_maddr += atdevbase; } - isdp->id_alive = (*dp->probe)(isdp); - if (isdp->id_alive) { + id_alive = (*dp->probe)(isdp); + if (id_alive) { /* * Only print the I/O address range if id_alive != -1 * Right now this is a temporary fix just for the new @@ -282,21 +352,20 @@ config_isadev(isdp, mp) * Rod Grimes 04/26/94 */ printf("%s%d", dp->name, isdp->id_unit); - if (isdp->id_alive != -1) { + if (id_alive != -1) { printf(" at 0x%x", isdp->id_iobase); - if ((isdp->id_iobase + isdp->id_alive - 1) != + if ((isdp->id_iobase + id_alive - 1) != isdp->id_iobase) { printf("-0x%x", - isdp->id_iobase + - isdp->id_alive - 1); + isdp->id_iobase + id_alive - 1); } } - if(isdp->id_irq) + if (isdp->id_irq) printf(" irq %d", ffs(isdp->id_irq) - 1); if (isdp->id_drq != -1) printf(" drq %d", isdp->id_drq); if (isdp->id_maddr) - printf(" maddr 0x%x", kvtop(isdp->id_maddr)); + printf(" maddr 0x%lx", kvtop(isdp->id_maddr)); if (isdp->id_msize) printf(" msize %d", isdp->id_msize); if (isdp->id_flags) @@ -312,18 +381,25 @@ config_isadev(isdp, mp) } } } - + /* + * Check for conflicts again. The driver may have changed + * *dvp. We should weaken the early check since the + * driver may have been able to change *dvp to avoid + * conflicts if given a chance. We already skip the early + * check for IRQs and force a check for IRQs in the next + * group of checks. + */ + checkbits |= CC_IRQ; + if (haveseen_isadev(isdp, checkbits)) + return; + isdp->id_alive = id_alive; (*dp->attach)(isdp); - - if(isdp->id_irq) { - int intrno; - - intrno = ffs(isdp->id_irq)-1; - setidt(ICU_OFFSET+intrno, isdp->id_intr, - SDT_SYS386IGT, SEL_KPL); - if(mp) { - INTRMASK(*mp,isdp->id_irq); - } + if (isdp->id_irq) { + if (mp) + INTRMASK(*mp, isdp->id_irq); + register_intr(ffs(isdp->id_irq) - 1, isdp->id_id, + isdp->id_ri_flags, isdp->id_intr, + mp ? *mp : 0, isdp->id_unit); INTREN(isdp->id_irq); } } else { @@ -335,22 +411,6 @@ config_isadev(isdp, mp) } } -#define IDTVEC(name) __CONCAT(X,name) -/* default interrupt vector table entries */ -typedef void inthand_t(); -typedef void (*inthand_func_t)(); -extern inthand_t - IDTVEC(intr0), IDTVEC(intr1), IDTVEC(intr2), IDTVEC(intr3), - IDTVEC(intr4), IDTVEC(intr5), IDTVEC(intr6), IDTVEC(intr7), - IDTVEC(intr8), IDTVEC(intr9), IDTVEC(intr10), IDTVEC(intr11), - IDTVEC(intr12), IDTVEC(intr13), IDTVEC(intr14), IDTVEC(intr15); - -static inthand_func_t defvec[ICU_LEN] = { - &IDTVEC(intr0), &IDTVEC(intr1), &IDTVEC(intr2), &IDTVEC(intr3), - &IDTVEC(intr4), &IDTVEC(intr5), &IDTVEC(intr6), &IDTVEC(intr7), - &IDTVEC(intr8), &IDTVEC(intr9), &IDTVEC(intr10), &IDTVEC(intr11), - &IDTVEC(intr12), &IDTVEC(intr13), &IDTVEC(intr14), &IDTVEC(intr15) }; - /* * Fill in default interrupt table (in case of spuruious interrupt * during configuration of kernel, setup interrupt control unit @@ -362,7 +422,7 @@ isa_defaultirq() /* icu vectors */ for (i = 0; i < ICU_LEN; i++) - setidt(ICU_OFFSET + i, defvec[i], SDT_SYS386IGT, SEL_KPL); + unregister_intr(i, (inthand2_t *)NULL); /* initialize 8259's */ outb(IO_ICU1, 0x11); /* reset; program device, four bytes */ @@ -418,6 +478,9 @@ void isa_dmacascade(unsigned chan) } } +static int +isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan); + /* * isa_dmastart(): program 8237 DMA controller channel, avoid page alignment * problems by using a bounce buffer. @@ -520,7 +583,7 @@ void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan) * Return true if special handling needed. */ -int +static int isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan) { vm_offset_t phys, priorpage = 0, endva; u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1); @@ -622,7 +685,7 @@ isa_nmi(cd) /* * Caught a stray interrupt, notify */ -void +static void isa_strayintr(d) int d; { @@ -637,13 +700,18 @@ isa_strayintr(d) * the first 5 get logged, then it quits logging them, and puts * out a special message. rgrimes 3/25/1993 */ - extern u_long intrcnt_stray; - - intrcnt_stray++; - if (intrcnt_stray <= 5) - log(LOG_ERR,"ISA strayintr %x\n", d); - if (intrcnt_stray == 5) - log(LOG_CRIT,"Too many ISA strayintr not logging any more\n"); + /* + * XXX TODO print a different message for #7 if it is for a + * glitch. Glitches can be distinguished from real #7's by + * testing that the in-service bit is _not_ set. The test + * must be done before sending an EOI so it can't be done if + * we are using AUTO_EOI_1. + */ + if (intrcnt[NR_DEVICES + d] <= 5) + log(LOG_ERR, "stray irq %d\n", d); + if (intrcnt[NR_DEVICES + d] == 5) + log(LOG_CRIT, + "too many stray irq %d's; not logging any more\n", d); } /* @@ -683,8 +751,84 @@ isa_irq_pending(dvp) { unsigned id_irq; - id_irq = (unsigned short) dvp->id_irq; /* XXX silly type in struct */ + id_irq = dvp->id_irq; if (id_irq & 0xff) return (inb(IO_ICU1) & id_irq); return (inb(IO_ICU2) & (id_irq >> 8)); } + +int +register_intr(intr, device_id, flags, handler, mask, unit) + int intr; + int device_id; + u_int flags; + inthand2_t *handler; + u_int mask; + int unit; +{ + char *cp; + u_long ef; + int id; + + if ((u_int)intr >= ICU_LEN || intr == 2 + || (u_int)device_id >= NR_DEVICES) + return (EINVAL); + if (intr_handler[intr] != isa_strayintr) + return (EBUSY); + ef = read_eflags(); + disable_intr(); + intr_countp[intr] = &intrcnt[device_id]; + intr_handler[intr] = handler; + intr_mask[intr] = mask | (1 << intr); + intr_unit[intr] = unit; + setidt(ICU_OFFSET + intr, + flags & RI_FAST ? fastintr[intr] : slowintr[intr], + SDT_SYS386IGT, SEL_KPL); + write_eflags(ef); + for (cp = intrnames, id = 0; id <= device_id; id++) + while (*cp++ != '\0') + ; + if (cp > eintrnames) + return (0); + if (intr < 10) { + cp[-3] = intr + '0'; + cp[-2] = ' '; + } else { + cp[-3] = '1'; + cp[-2] = intr - 10 + '0'; + } + return (0); +} + +static void +register_imask(dvp, mask) + struct isa_device *dvp; + u_int mask; +{ + if (dvp->id_alive && dvp->id_irq) { + int intr; + + intr = ffs(dvp->id_irq) - 1; + intr_mask[intr] = mask | (1 <<intr); + } +} + +int +unregister_intr(intr, handler) + int intr; + inthand2_t *handler; +{ + u_long ef; + + if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr]) + return (EINVAL); + ef = read_eflags(); + disable_intr(); + intr_countp[intr] = &intrcnt[NR_DEVICES + intr]; + intr_handler[intr] = isa_strayintr; + intr_mask[intr] = HWI_MASK | SWI_MASK; + intr_unit[intr] = intr; + setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL); + write_eflags(ef); + return (0); +} diff --git a/sys/i386/isa/isa_device.h b/sys/i386/isa/isa_device.h index 16fac9a..47dd12d 100644 --- a/sys/i386/isa/isa_device.h +++ b/sys/i386/isa/isa_device.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91 - * $Id: isa_device.h,v 1.4 1993/12/19 00:50:42 wollman Exp $ + * $Id: isa_device.h,v 1.5 1994/01/04 20:06:30 nate Exp $ */ #ifndef _I386_ISA_ISA_DEVICE_H_ @@ -41,21 +41,38 @@ * ISA Bus Autoconfiguration */ +#define IDTVEC(name) __CONCAT(X,name) + +/* + * Type of the first (asm) part of an interrupt handler. + */ +typedef void inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss)); + +/* + * Usual type of the second (C) part of an interrupt handler. Some bogus + * ones need the arg to be the interrupt frame (and not a copy of it, which + * is all that is possible in C). + */ +typedef void inthand2_t __P((int unit)); + /* * Per device structure. */ struct isa_device { + int id_id; /* device id */ struct isa_driver *id_driver; short id_iobase; /* base i/o address */ u_short id_irq; /* interrupt request */ short id_drq; /* DMA request */ caddr_t id_maddr; /* physical i/o memory address on bus (if any)*/ int id_msize; /* size of i/o memory */ - void (*id_intr)(); /* interrupt interface routine */ + inthand2_t *id_intr; /* interrupt interface routine */ int id_unit; /* unit number */ int id_flags; /* flags */ int id_scsiid; /* scsi id if needed */ int id_alive; /* device is present */ +#define RI_FAST 1 /* fast interrupt handler */ + u_int id_ri_flags; /* flags for register_intr() */ }; /* @@ -66,17 +83,49 @@ struct isa_device { * These are used at boot time by the configuration program. */ struct isa_driver { - int (*probe)(); /* test whether device is present */ - int (*attach)(); /* setup driver for a device */ + int (*probe) __P((struct isa_device *idp)); + /* test whether device is present */ + int (*attach) __P((struct isa_device *idp)); + /* setup driver for a device */ char *name; /* device name */ }; +extern char eintrnames[]; /* end of intrnames[] */ +extern u_long intrcnt[]; /* counts for for each device and stray */ +extern char intrnames[]; /* string table containing device names */ +u_long *intr_countp[]; /* indirectors into intrcnt[] */ +inthand2_t *intr_handler[]; /* C entry points of intr handlers */ +u_int intr_mask[]; /* sets of intrs masked during handling of 1 */ +int intr_unit[]; /* cookies to pass to intr handlers */ + extern struct isa_device isa_devtab_bio[], isa_devtab_tty[], isa_devtab_net[], isa_devtab_null[], isa_biotab_wdc[], isa_biotab_fdc[]; -extern struct isa_device *find_isadev(/* table, driver, unit*/); - -extern void isa_dmastart(int, caddr_t, unsigned, unsigned); -extern void isa_dmadone(int, caddr_t, int, int); +inthand_t + IDTVEC(fastintr0), IDTVEC(fastintr1), + IDTVEC(fastintr2), IDTVEC(fastintr3), + IDTVEC(fastintr4), IDTVEC(fastintr5), + IDTVEC(fastintr6), IDTVEC(fastintr7), + IDTVEC(fastintr8), IDTVEC(fastintr9), + IDTVEC(fastintr10), IDTVEC(fastintr11), + IDTVEC(fastintr12), IDTVEC(fastintr13), + IDTVEC(fastintr14), IDTVEC(fastintr15); +struct isa_device *find_isadev __P((struct isa_device *table, + struct isa_driver *driverp, int unit)); +inthand_t + IDTVEC(intr0), IDTVEC(intr1), IDTVEC(intr2), IDTVEC(intr3), + IDTVEC(intr4), IDTVEC(intr5), IDTVEC(intr6), IDTVEC(intr7), + IDTVEC(intr8), IDTVEC(intr9), IDTVEC(intr10), IDTVEC(intr11), + IDTVEC(intr12), IDTVEC(intr13), IDTVEC(intr14), IDTVEC(intr15); +void isa_configure __P((void)); +void isa_defaultirq __P((void)); +void isa_dmacascade __P((unsigned chan)); +void isa_dmadone __P((int, caddr_t, int, int)); +void isa_dmastart __P((int, caddr_t, unsigned, unsigned)); +int isa_irq_pending __P((struct isa_device *dvp)); +int isa_nmi __P((int cd)); +int register_intr __P((int intr, int device_id, u_int flags, + inthand2_t *handler, u_int mask, int unit)); +int unregister_intr __P((int intr, inthand2_t *handler)); #endif /* _I386_ISA_ISA_DEVICE_H_ */ diff --git a/sys/i386/isa/sio.c b/sys/i386/isa/sio.c index de95e90..d505c4d 100644 --- a/sys/i386/isa/sio.c +++ b/sys/i386/isa/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.47 1994/05/26 13:31:40 rgrimes Exp $ + * $Id: sio.c,v 1.48 1994/08/13 03:50:13 wollman Exp $ */ #include "sio.h" @@ -427,6 +427,7 @@ sioattach(isdp) int s; int unit; + isdp->id_ri_flags |= RI_FAST; iobase = isdp->id_iobase; unit = isdp->id_unit; s = spltty(); diff --git a/sys/i386/isa/vector.s b/sys/i386/isa/vector.s index 7135ae7..252bd95 100644 --- a/sys/i386/isa/vector.s +++ b/sys/i386/isa/vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: vector.s,v 1.6 1994/01/10 23:15:09 ache Exp $ + * $Id: vector.s,v 1.7 1994/04/02 07:00:50 davidg Exp $ */ #include "i386/isa/icu.h" @@ -97,7 +97,10 @@ * loading segregs. */ -#define FAST_INTR(unit, irq_num, id_num, handler, enable_icus) \ +#define FAST_INTR(irq_num, enable_icus) \ + .text ; \ + SUPERALIGN_TEXT ; \ +IDTVEC(fastintr/**/irq_num) ; \ pushl %eax ; /* save only call-used registers */ \ pushl %ecx ; \ pushl %edx ; \ @@ -107,12 +110,13 @@ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ - pushl $unit ; \ - call handler ; /* do the work ASAP */ \ + pushl _intr_unit + (irq_num) * 4 ; \ + call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \ addl $4,%esp ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ - incl _intrcnt_actv + (id_num) * 4 ; \ + movl _intr_countp + (irq_num) * 4,%eax ; \ + incl (%eax) ; \ movl _cpl,%eax ; /* are we unmasking pending HWIs or SWIs? */ \ notl %eax ; \ andl _ipending,%eax ; \ @@ -147,7 +151,10 @@ MEXITCOUNT ; \ jmp _doreti -#define INTR(unit, irq_num, id_num, mask, handler, icu, enable_icus, reg, stray) \ +#define INTR(irq_num, icu, enable_icus, reg) \ + .text ; \ + SUPERALIGN_TEXT ; \ +IDTVEC(intr/**/irq_num) ; \ pushl $0 ; /* dumby error code */ \ pushl $0 ; /* dumby trap type */ \ pushal ; \ @@ -167,15 +174,17 @@ testb $IRQ_BIT(irq_num),%reg ; \ jne 2f ; \ 1: ; \ +Xresume/**/irq_num: ; \ FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \ - incl _intrcnt_actv + (id_num) * 4 ; \ + movl _intr_countp + (irq_num) * 4,%eax ; \ + incl (%eax) ; \ movl _cpl,%eax ; \ pushl %eax ; \ - pushl $unit ; \ - orl mask,%eax ; \ + pushl _intr_unit + (irq_num) * 4 ; \ + orl _intr_mask + (irq_num) * 4,%eax ; \ movl %eax,_cpl ; \ sti ; \ - call handler ; \ + call *_intr_handler + (irq_num) * 4 ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ andb $~IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -189,9 +198,6 @@ ALIGN_TEXT ; \ 2: ; \ /* XXX skip mcounting here to avoid double count */ \ - movl $1b,%eax ; /* register resume address */ \ - /* XXX - someday do it at attach time */ \ - movl %eax,ihandlers + (irq_num) * 4 ; \ orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \ popl %es ; \ popl %ds ; \ @@ -199,118 +205,48 @@ addl $4+4,%esp ; \ iret -/* - * vector.h has defined a macro 'BUILD_VECTORS' containing a big list of info - * about vectors, including a submacro 'BUILD_VECTOR' that operates on the - * info about each vector. We redefine 'BUILD_VECTOR' to expand the info - * in different ways. Here we expand it to a list of interrupt handlers. - * This order is of course unimportant. Elsewhere we expand it to inline - * linear search code for which the order is a little more important and - * concatenating the code with no holes is very important. - * - * XXX - now there is BUILD_FAST_VECTOR as well as BUILD_VECTOR. - * - * The info consists of the following items for each vector: - * - * name (identifier): name of the vector; used to build labels - * unit (expression): unit number to call the device driver with - * irq_num (number): number of the IRQ to handled (0-15) - * id_num (number): uniq numeric id for handler (assigned by config) - * mask (blank-ident): priority mask used - * handler (blank-ident): interrupt handler to call - * icu_num (number): (1 + irq_num / 8) converted for label building - * icu_enables (number): 1 for icu_num == 1, 1_AND_2 for icu_num == 2 - * reg (blank-ident): al for icu_num == 1, ah for icu_num == 2 - * - * 'irq_num' is converted in several ways at config time to get around - * limitations in cpp. The macros have blanks after commas iff they would - * not mess up identifiers and numbers. - */ - -#undef BUILD_FAST_VECTOR -#define BUILD_FAST_VECTOR(name, unit, irq_num, id_num, mask, handler, \ - icu_num, icu_enables, reg) \ - .globl handler ; \ - .text ; \ - .globl _V/**/name ; \ - SUPERALIGN_TEXT ; \ -_V/**/name: ; \ - FAST_INTR(unit, irq_num,id_num, handler, ENABLE_ICU/**/icu_enables) - -#undef BUILD_VECTOR -#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \ - icu_num, icu_enables, reg) \ - .globl handler ; \ - .text ; \ - .globl _V/**/name ; \ - SUPERALIGN_TEXT ; \ -_V/**/name: ; \ - INTR(unit,irq_num, id_num, mask, handler, IO_ICU/**/icu_num, \ - ENABLE_ICU/**/icu_enables, reg,) - MCOUNT_LABEL(bintr) - BUILD_VECTORS - - /* hardware interrupt catcher (IDT 32 - 47) */ - .globl _isa_strayintr - -#define STRAYINTR(irq_num, icu_num, icu_enables, reg) \ -IDTVEC(intr/**/irq_num) ; \ - INTR(irq_num,irq_num,irq_num, _high_imask, _isa_strayintr, \ - IO_ICU/**/icu_num, ENABLE_ICU/**/icu_enables, reg,stray) - -/* - * XXX - the mask (1 << 2) == IRQ_SLAVE will be generated for IRQ 2, instead - * of the mask IRQ2 (defined as IRQ9 == (1 << 9)). But IRQ 2 "can't happen". - * In fact, all stray interrupts "can't happen" except for bugs. The - * "stray" IRQ 7 is documented behaviour of the 8259. It happens when there - * is a glitch on any of its interrupt inputs. Does it really interrupt when - * IRQ 7 is masked? - * - * XXX - unpend doesn't work for these, it sends them to the real handler. - * - * XXX - the race bug during initialization may be because I changed the - * order of switching from the stray to the real interrupt handler to before - * enabling interrupts. The old order looked unsafe but maybe it is OK with - * the stray interrupt handler installed. But these handlers only reduce - * the window of vulnerability - it is still open at the end of - * isa_configure(). - * - * XXX - many comments are stale. - */ - - STRAYINTR(0,1,1, al) - STRAYINTR(1,1,1, al) - STRAYINTR(2,1,1, al) - STRAYINTR(3,1,1, al) - STRAYINTR(4,1,1, al) - STRAYINTR(5,1,1, al) - STRAYINTR(6,1,1, al) - STRAYINTR(7,1,1, al) - STRAYINTR(8,2,1_AND_2, ah) - STRAYINTR(9,2,1_AND_2, ah) - STRAYINTR(10,2,1_AND_2, ah) - STRAYINTR(11,2,1_AND_2, ah) - STRAYINTR(12,2,1_AND_2, ah) - STRAYINTR(13,2,1_AND_2, ah) - STRAYINTR(14,2,1_AND_2, ah) - STRAYINTR(15,2,1_AND_2, ah) -#if 0 - INTRSTRAY(255, _highmask, 255) ; call _isa_strayintr ; INTREXIT2 -#endif + FAST_INTR(0, ENABLE_ICU1) + FAST_INTR(1, ENABLE_ICU1) + FAST_INTR(2, ENABLE_ICU1) + FAST_INTR(3, ENABLE_ICU1) + FAST_INTR(4, ENABLE_ICU1) + FAST_INTR(5, ENABLE_ICU1) + FAST_INTR(6, ENABLE_ICU1) + FAST_INTR(7, ENABLE_ICU1) + FAST_INTR(8, ENABLE_ICU1_AND_2) + FAST_INTR(9, ENABLE_ICU1_AND_2) + FAST_INTR(10, ENABLE_ICU1_AND_2) + FAST_INTR(11, ENABLE_ICU1_AND_2) + FAST_INTR(12, ENABLE_ICU1_AND_2) + FAST_INTR(13, ENABLE_ICU1_AND_2) + FAST_INTR(14, ENABLE_ICU1_AND_2) + FAST_INTR(15, ENABLE_ICU1_AND_2) + INTR(0, IO_ICU1, ENABLE_ICU1, al) + INTR(1, IO_ICU1, ENABLE_ICU1, al) + INTR(2, IO_ICU1, ENABLE_ICU1, al) + INTR(3, IO_ICU1, ENABLE_ICU1, al) + INTR(4, IO_ICU1, ENABLE_ICU1, al) + INTR(5, IO_ICU1, ENABLE_ICU1, al) + INTR(6, IO_ICU1, ENABLE_ICU1, al) + INTR(7, IO_ICU1, ENABLE_ICU1, al) + INTR(8, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(9, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(10, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(11, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(12, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(13, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(14, IO_ICU2, ENABLE_ICU1_AND_2, ah) + INTR(15, IO_ICU2, ENABLE_ICU1_AND_2, ah) MCOUNT_LABEL(eintr) -/* - * These are the interrupt counters, I moved them here from icu.s so that - * they are with the name table. rgrimes - * - * There are now lots of counters, this has been redone to work with - * Bruce Evans intr-0.1 code, which I modified some more to make it all - * work with vmstat. - */ .data ihandlers: /* addresses of interrupt handlers */ - .space NHWI*4 /* actually resumption addresses for HWI's */ + /* actually resumption addresses for HWI's */ + .long Xresume0, Xresume1, Xresume2, Xresume3 + .long Xresume4, Xresume5, Xresume6, Xresume7 + .long Xresume8, Xresume9, Xresume10, Xresume11 + .long Xresume12, Xresume13, Xresume14, Xresume15 .long swi_tty, swi_net, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, swi_clock, swi_ast imasks: /* masks for interrupt handlers */ @@ -318,43 +254,37 @@ imasks: /* masks for interrupt handlers */ .long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK - .globl _intrcnt -_intrcnt: /* used by vmstat to calc size of table */ - .globl _intrcnt_bad7 -_intrcnt_bad7: .space 4 /* glitches on irq 7 */ - .globl _intrcnt_bad15 -_intrcnt_bad15: .space 4 /* glitches on irq 15 */ - .globl _intrcnt_stray -_intrcnt_stray: .space 4 /* total count of stray interrupts */ - .globl _intrcnt_actv -_intrcnt_actv: .space NR_REAL_INT_HANDLERS * 4 /* active interrupts */ - .globl _eintrcnt -_eintrcnt: /* used by vmstat to calc size of table */ - -/* - * Build the interrupt name table for vmstat - */ - -#undef BUILD_FAST_VECTOR -#define BUILD_FAST_VECTOR BUILD_VECTOR - -#undef BUILD_VECTOR -#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \ - icu_num, icu_enables, reg) \ - .ascii "name irq" ; \ - .asciz "irq_num" /* - * XXX - use the __STRING and __CONCAT macros from <sys/cdefs.h> to stringize - * and concatenate names above and elsewhere. Note that __CONCAT doesn't - * work when nested. + * Interrupt counters and names. The format of these and the label names + * must agree with what vmstat expects. The tables are indexed by device + * ids so that we don't have to move the names around as devices are + * attached. */ +#include "vector.h" + .globl _intrcnt, _eintrcnt +_intrcnt: + .space (NR_DEVICES + ICU_LEN) * 4 +_eintrcnt: - .text .globl _intrnames, _eintrnames _intrnames: - BUILD_VECTOR(bad,,7,,,,,,) - BUILD_VECTOR(bad,,15,,,,,,) - BUILD_VECTOR(stray,,,,,,,,) - BUILD_VECTORS - + .ascii DEVICE_NAMES + .asciz "stray irq0" + .asciz "stray irq1" + .asciz "stray irq2" + .asciz "stray irq3" + .asciz "stray irq4" + .asciz "stray irq5" + .asciz "stray irq6" + .asciz "stray irq7" + .asciz "stray irq8" + .asciz "stray irq9" + .asciz "stray irq10" + .asciz "stray irq11" + .asciz "stray irq12" + .asciz "stray irq13" + .asciz "stray irq14" + .asciz "stray irq15" _eintrnames: + + .text diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index 35f2e42..e3f3f21 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $ + * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $ */ /* @@ -497,16 +497,14 @@ test_inittodr(time_t base) /* * Wire clock interrupt in. */ -#define V(s) __CONCAT(V, s) -extern void V(clk)(); -extern void V(rtc)(); - void enablertclock() { - setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr, + HWI_MASK | SWI_MASK, /* unit */ 0); INTREN(IRQ0); - setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL); + register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr, + SWI_CLOCK_MASK, /* unit */ 0); INTREN(IRQ8); outb(IO_RTC, RTC_STATUSB); outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR); diff --git a/sys/isa/sio.c b/sys/isa/sio.c index de95e90..d505c4d 100644 --- a/sys/isa/sio.c +++ b/sys/isa/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.47 1994/05/26 13:31:40 rgrimes Exp $ + * $Id: sio.c,v 1.48 1994/08/13 03:50:13 wollman Exp $ */ #include "sio.h" @@ -427,6 +427,7 @@ sioattach(isdp) int s; int unit; + isdp->id_ri_flags |= RI_FAST; iobase = isdp->id_iobase; unit = isdp->id_unit; s = spltty(); |