diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2006-06-15 20:08:30 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2006-06-15 20:08:30 +0000 |
commit | 3c18738eebc3ab152ffb51145446e53abd3236d3 (patch) | |
tree | 65edf799ed5992b4b991b8ce6eeff4ef74f2e0b7 /sys | |
parent | fd293392db098cbdef234cf36ac226873023a403 (diff) |
Rework the interrupt code, shaving some cycles off in the process.
Rather than an "iointr" routine that decomposes a vector into an
IRQ, we maintain a vector table directly, hooking up each "iointr"
routine at the correct vector. This also allows us to hook device
interrupts up to specific vectors.
From thorpej NetBSD
Tested by myself and a number of end-users.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/alpha/alpha/interrupt.c | 120 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/machdep.c | 5 | ||||
-rw-r--r-- | sys/arch/alpha/dev/shared_intr.c | 10 | ||||
-rw-r--r-- | sys/arch/alpha/include/cpuconf.h | 4 | ||||
-rw-r--r-- | sys/arch/alpha/include/intr.h | 41 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_1000.c | 43 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_1000a.c | 38 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_2100_a50.c | 3 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_550.c | 46 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_6600.c | 45 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_axppci_33.c | 3 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_eb164.c | 46 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_eb64plus.c | 44 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_kn20aa.c | 49 | ||||
-rw-r--r-- | sys/arch/alpha/pci/pci_up1000.c | 3 | ||||
-rw-r--r-- | sys/arch/alpha/pci/sio_pic.c | 20 | ||||
-rw-r--r-- | sys/arch/alpha/tc/tcasic.c | 6 |
17 files changed, 301 insertions, 225 deletions
diff --git a/sys/arch/alpha/alpha/interrupt.c b/sys/arch/alpha/alpha/interrupt.c index a37a1984b3d..6dc85203c96 100644 --- a/sys/arch/alpha/alpha/interrupt.c +++ b/sys/arch/alpha/alpha/interrupt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: interrupt.c,v 1.19 2006/02/23 20:14:13 miod Exp $ */ +/* $OpenBSD: interrupt.c,v 1.20 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: interrupt.c,v 1.46 2000/06/03 20:47:36 thorpej Exp $ */ /*- @@ -124,8 +124,105 @@ static u_int schedclk2; extern struct evcount clk_count; +struct scbvec scb_iovectab[SCB_VECTOIDX(SCB_SIZE - SCB_IOVECBASE)]; + void netintr(void); +void scb_stray(void *, u_long); + +void +scb_init(void) +{ + u_long i; + + for (i = 0; i < SCB_NIOVECS; i++) { + scb_iovectab[i].scb_func = scb_stray; + scb_iovectab[i].scb_arg = NULL; + } +} + +void +scb_stray(void *arg, u_long vec) +{ + + printf("WARNING: stray interrupt, vector 0x%lx\n", vec); +} + +void +scb_set(u_long vec, void (*func)(void *, u_long), void *arg) +{ + u_long idx; + int s; + + s = splhigh(); + + if (vec < SCB_IOVECBASE || vec >= SCB_SIZE || + (vec & (SCB_VECSIZE - 1)) != 0) + panic("scb_set: bad vector 0x%lx", vec); + + idx = SCB_VECTOIDX(vec - SCB_IOVECBASE); + + if (scb_iovectab[idx].scb_func != scb_stray) + panic("scb_set: vector 0x%lx already occupied", vec); + + scb_iovectab[idx].scb_func = func; + scb_iovectab[idx].scb_arg = arg; + + splx(s); +} + +u_long +scb_alloc(void (*func)(void *, u_long), void *arg) +{ + u_long vec, idx; + int s; + + s = splhigh(); + + /* + * Allocate "downwards", to avoid bumping into + * interrupts which are likely to be at the lower + * vector numbers. + */ + for (vec = SCB_SIZE - SCB_VECSIZE; + vec >= SCB_IOVECBASE; vec -= SCB_VECSIZE) { + idx = SCB_VECTOIDX(vec - SCB_IOVECBASE); + if (scb_iovectab[idx].scb_func == scb_stray) { + scb_iovectab[idx].scb_func = func; + scb_iovectab[idx].scb_arg = arg; + splx(s); + return (vec); + } + } + + splx(s); + + return (SCB_ALLOC_FAILED); +} + +void +scb_free(u_long vec) +{ + u_long idx; + int s; + + s = splhigh(); + + if (vec < SCB_IOVECBASE || vec >= SCB_SIZE || + (vec & (SCB_VECSIZE - 1)) != 0) + panic("scb_free: bad vector 0x%lx", vec); + + idx = SCB_VECTOIDX(vec - SCB_IOVECBASE); + + if (scb_iovectab[idx].scb_func == scb_stray) + panic("scb_free: vector 0x%lx is empty", vec); + + scb_iovectab[idx].scb_func = scb_stray; + scb_iovectab[idx].scb_arg = (void *) vec; + + splx(s); +} + void interrupt(unsigned long a0, unsigned long a1, unsigned long a2, struct trapframe *framep) @@ -205,15 +302,22 @@ interrupt(unsigned long a0, unsigned long a1, unsigned long a2, break; case ALPHA_INTR_DEVICE: /* I/O device interrupt */ + { + struct scbvec *scb; + + KDASSERT(a1 >= SCB_IOVECBASE && a1 < SCB_SIZE); + #if defined(MULTIPROCESSOR) /* XXX XXX XXX */ if (CPU_IS_PRIMARY(ci) == 0) return; #endif uvmexp.intrs++; - if (platform.iointr) - (*platform.iointr)(framep, a1); + + scb = &scb_iovectab[SCB_VECTOIDX(a1 - SCB_IOVECBASE)]; + (*scb->scb_func)(scb->scb_arg, a1); break; + } case ALPHA_INTR_PERF: /* performance counter interrupt */ printf("WARNING: received performance counter interrupt!\n"); @@ -243,16 +347,6 @@ interrupt(unsigned long a0, unsigned long a1, unsigned long a2, } void -set_iointr(void (*niointr)(void *, unsigned long)) -{ - - if (platform.iointr) - panic("set iointr twice"); - platform.iointr = niointr; -} - - -void machine_check(unsigned long mces, struct trapframe *framep, unsigned long vector, unsigned long param) { diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index 2f9cfb65729..26ef3141f1f 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.100 2006/06/07 21:50:52 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.101 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */ /*- @@ -250,6 +250,9 @@ alpha_init(pfn, ptb, bim, bip, biv) ALPHA_TBIA(); alpha_pal_imb(); + /* Initialize the SCB. */ + scb_init(); + cpu_id = cpu_number(); #if defined(MULTIPROCESSOR) diff --git a/sys/arch/alpha/dev/shared_intr.c b/sys/arch/alpha/dev/shared_intr.c index 685e3e92f28..b5d8f8c9480 100644 --- a/sys/arch/alpha/dev/shared_intr.c +++ b/sys/arch/alpha/dev/shared_intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: shared_intr.c,v 1.14 2006/01/29 10:47:35 martin Exp $ */ +/* $OpenBSD: shared_intr.c,v 1.15 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: shared_intr.c,v 1.13 2000/03/19 01:46:18 thorpej Exp $ */ /* @@ -215,6 +215,14 @@ alpha_shared_intr_isactive(intr, num) return (!TAILQ_EMPTY(&intr[num].intr_q)); } +int +alpha_shared_intr_firstactive(struct alpha_shared_intr *intr, unsigned int num) +{ + + return (!TAILQ_EMPTY(&intr[num].intr_q) && + TAILQ_NEXT(intr[num].intr_q.tqh_first, ih_q) == NULL); +} + void alpha_shared_intr_set_dfltsharetype(intr, num, newdfltsharetype) struct alpha_shared_intr *intr; diff --git a/sys/arch/alpha/include/cpuconf.h b/sys/arch/alpha/include/cpuconf.h index 565f03dcd0a..cd3e9f5103a 100644 --- a/sys/arch/alpha/include/cpuconf.h +++ b/sys/arch/alpha/include/cpuconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpuconf.h,v 1.4 2000/11/08 21:27:18 ericj Exp $ */ +/* $OpenBSD: cpuconf.h,v 1.5 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: cpuconf.h,v 1.12 2000/06/08 03:10:06 thorpej Exp $ */ /* @@ -62,13 +62,11 @@ struct platform { * Platform Specific Function Hooks * cons_init - console initialization * device_register - boot configuration aid - * iointr - I/O interrupt handler * clockintr - Clock Interrupt Handler * mcheck_handler - Platform Specific Machine Check Handler */ void (*cons_init)(void); void (*device_register)(struct device *, void *); - void (*iointr)(void *, unsigned long); void (*clockintr)(struct clockframe *); void (*mcheck_handler)(unsigned long, struct trapframe *, unsigned long, unsigned long); diff --git a/sys/arch/alpha/include/intr.h b/sys/arch/alpha/include/intr.h index 5576f4bcc6e..5fb16d23e34 100644 --- a/sys/arch/alpha/include/intr.h +++ b/sys/arch/alpha/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.22 2006/03/12 03:14:36 brad Exp $ */ +/* $OpenBSD: intr.h,v 1.23 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: intr.h,v 1.26 2000/06/03 20:47:41 thorpej Exp $ */ /*- @@ -74,6 +74,34 @@ #include <machine/atomic.h> /* + * The Alpha System Control Block. This is 8k long, and you get + * 16 bytes per vector (i.e. the vector numbers are spaced 16 + * apart). + * + * This is sort of a "shadow" SCB -- rather than the CPU jumping + * to (SCBaddr + (16 * vector)), like it does on the VAX, we get + * a vector number in a1. We use the SCB to look up a routine/arg + * and jump to it. + * + * Since we use the SCB only for I/O interrupts, we make it shorter + * than normal, starting it at vector 0x800 (the start of the I/O + * interrupt vectors). + */ +#define SCB_IOVECBASE 0x0800 +#define SCB_VECSIZE 0x0010 +#define SCB_SIZE 0x2000 + +#define SCB_VECTOIDX(x) ((x) >> 4) +#define SCB_IDXTOVEC(x) ((x) << 4) + +#define SCB_NIOVECS SCB_VECTOIDX(SCB_SIZE - SCB_IOVECBASE) + +struct scbvec { + void (*scb_func)(void *, u_long); + void *scb_arg; +}; + +/* * Alpha interrupts come in at one of 4 levels: * * software interrupt level @@ -237,6 +265,8 @@ int alpha_shared_intr_get_sharetype(struct alpha_shared_intr *, unsigned int); int alpha_shared_intr_isactive(struct alpha_shared_intr *, unsigned int); +int alpha_shared_intr_firstactive(struct alpha_shared_intr *, + unsigned int); void alpha_shared_intr_set_dfltsharetype(struct alpha_shared_intr *, unsigned int, int); void alpha_shared_intr_set_maxstrays(struct alpha_shared_intr *, @@ -250,7 +280,14 @@ void alpha_shared_intr_set_private(struct alpha_shared_intr *, void *alpha_shared_intr_get_private(struct alpha_shared_intr *, unsigned int); -void set_iointr(void (*)(void *, unsigned long)); +extern struct scbvec scb_iovectab[]; + +void scb_init(void); +void scb_set(u_long, void (*)(void *, u_long), void *); +u_long scb_alloc(void (*)(void *, u_long), void *); +void scb_free(u_long); + +#define SCB_ALLOC_FAILED ((u_long) -1) #endif /* _KERNEL */ #endif /* ! _ALPHA_INTR_H_ */ diff --git a/sys/arch/alpha/pci/pci_1000.c b/sys/arch/alpha/pci/pci_1000.c index ce33786300e..b61b0c75c0e 100644 --- a/sys/arch/alpha/pci/pci_1000.c +++ b/sys/arch/alpha/pci/pci_1000.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_1000.c,v 1.4 2006/03/26 20:23:08 brad Exp $ */ +/* $OpenBSD: pci_1000.c,v 1.5 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_1000.c,v 1.12 2001/07/27 00:25:20 thorpej Exp $ */ /* @@ -103,7 +103,7 @@ void dec_1000_intr_disestablish(void *, void *); struct alpha_shared_intr *dec_1000_pci_intr; -void dec_1000_iointr(void *framep, unsigned long vec); +void dec_1000_iointr(void *arg, unsigned long vec); void dec_1000_enable_intr(int irq); void dec_1000_disable_intr(int irq); void pci_1000_imi(void); @@ -146,7 +146,6 @@ pci_1000_pickintr(core, iot, memt, pc) #if NSIO > 0 || NPCEB > 0 sio_intr_setup(pc, iot); #endif - set_iointr(dec_1000_iointr); } int @@ -227,7 +226,8 @@ dec_1000_intr_establish(ccv, ih, level, func, arg, name) level, func, arg, name); if (cookie != NULL && - alpha_shared_intr_isactive(dec_1000_pci_intr, ih)) { + alpha_shared_intr_firstactive(dec_1000_pci_intr, ih)) { + scb_set(0x900 + SCB_IDXTOVEC(ih), dec_1000_iointr, NULL); dec_1000_enable_intr(ih); } return (cookie); @@ -249,39 +249,28 @@ dec_1000_intr_disestablish(ccv, cookie) dec_1000_disable_intr(irq); alpha_shared_intr_set_dfltsharetype(dec_1000_pci_intr, irq, IST_NONE); + scb_free(0x900 + SCB_IDXTOVEC(irq)); } splx(s); } void -dec_1000_iointr(framep, vec) - void *framep; +dec_1000_iointr(arg, vec) + void *arg; unsigned long vec; { int irq; - if (vec >= 0x900) { - if (vec >= 0x900 + (PCI_NIRQ << 4)) - panic("dec_1000_iointr: vec 0x%lx out of range", vec); - irq = (vec - 0x900) >> 4; - - if (!alpha_shared_intr_dispatch(dec_1000_pci_intr, irq)) { - alpha_shared_intr_stray(dec_1000_pci_intr, irq, - "dec_1000 irq"); - if (ALPHA_SHARED_INTR_DISABLE(dec_1000_pci_intr, irq)) - dec_1000_disable_intr(irq); - } else - alpha_shared_intr_reset_strays(dec_1000_pci_intr, irq); - return; - } -#if NSIO > 0 || NPCEB > 0 - if (vec >= 0x800) { - sio_iointr(framep, vec); - return; - } -#endif - panic("dec_1000_intr: weird vec 0x%lx", vec); + irq = SCB_VECTOIDX(vec - 0x900); + + if (!alpha_shared_intr_dispatch(dec_1000_pci_intr, irq)) { + alpha_shared_intr_stray(dec_1000_pci_intr, irq, + "dec_1000 irq"); + if (ALPHA_SHARED_INTR_DISABLE(dec_1000_pci_intr, irq)) + dec_1000_disable_intr(irq); + } else + alpha_shared_intr_reset_strays(dec_1000_pci_intr, irq); } /* diff --git a/sys/arch/alpha/pci/pci_1000a.c b/sys/arch/alpha/pci/pci_1000a.c index 41ee3118968..fb3cbd72d21 100644 --- a/sys/arch/alpha/pci/pci_1000a.c +++ b/sys/arch/alpha/pci/pci_1000a.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_1000a.c,v 1.4 2006/03/26 20:23:08 brad Exp $ */ +/* $OpenBSD: pci_1000a.c,v 1.5 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_1000a.c,v 1.14 2001/07/27 00:25:20 thorpej Exp $ */ /* @@ -150,7 +150,6 @@ pci_1000a_pickintr(core, iot, memt, pc) #if NSIO > 0 || NPCEB > 0 sio_intr_setup(pc, iot); #endif - set_iointr(dec_1000a_iointr); } int @@ -248,8 +247,10 @@ dec_1000a_intr_establish(ccv, ih, level, func, arg, name) level, func, arg, name); if (cookie != NULL && - alpha_shared_intr_isactive(dec_1000a_pci_intr, ih)) { + alpha_shared_intr_firstactive(dec_1000a_pci_intr, ih)) { + scb_set(0x900 + SCB_IDXTOVEC(ih), dec_1000a_iointr, NULL); dec_1000a_enable_intr(ih); + } return (cookie); } @@ -270,6 +271,7 @@ dec_1000a_intr_disestablish(ccv, cookie) dec_1000a_disable_intr(irq); alpha_shared_intr_set_dfltsharetype(dec_1000a_pci_intr, irq, IST_NONE); + scb_free(0x900 + SCB_IDXTOVEC(irq)); } splx(s); @@ -282,27 +284,15 @@ dec_1000a_iointr(framep, vec) { int irq; - if (vec >= 0x900) { - if (vec >= 0x900 + (PCI_NIRQ << 4)) - panic("dec_1000_iointr: vec 0x%lx out of range", vec); - irq = (vec - 0x900) >> 4; - - if (!alpha_shared_intr_dispatch(dec_1000a_pci_intr, irq)) { - alpha_shared_intr_stray(dec_1000a_pci_intr, irq, - "dec_1000a irq"); - if (ALPHA_SHARED_INTR_DISABLE(dec_1000a_pci_intr, irq)) - dec_1000a_disable_intr(irq); - } else - alpha_shared_intr_reset_strays(dec_1000a_pci_intr, irq); - return; - } -#if NSIO > 0 || NPCEB > 0 - if (vec >= 0x800) { - sio_iointr(framep, vec); - return; - } -#endif - panic("dec_1000a_intr: weird vec 0x%lx", vec); + irq = SCB_VECTOIDX(vec - 0x900); + + if (!alpha_shared_intr_dispatch(dec_1000a_pci_intr, irq)) { + alpha_shared_intr_stray(dec_1000a_pci_intr, irq, + "dec_1000a irq"); + if (ALPHA_SHARED_INTR_DISABLE(dec_1000a_pci_intr, irq)) + dec_1000a_disable_intr(irq); + } else + alpha_shared_intr_reset_strays(dec_1000a_pci_intr, irq); } /* diff --git a/sys/arch/alpha/pci/pci_2100_a50.c b/sys/arch/alpha/pci/pci_2100_a50.c index 7183e73e66f..fdeaa46396a 100644 --- a/sys/arch/alpha/pci/pci_2100_a50.c +++ b/sys/arch/alpha/pci/pci_2100_a50.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_2100_a50.c,v 1.19 2002/03/14 03:15:50 millert Exp $ */ +/* $OpenBSD: pci_2100_a50.c,v 1.20 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_2100_a50.c,v 1.12 1996/11/13 21:13:29 cgd Exp $ */ /* @@ -91,7 +91,6 @@ pci_2100_a50_pickintr(acp) #if NSIO sio_intr_setup(pc, iot); - set_iointr(&sio_iointr); #else panic("pci_2100_a50_pickintr: no I/O interrupt handler (no sio)"); #endif diff --git a/sys/arch/alpha/pci/pci_550.c b/sys/arch/alpha/pci/pci_550.c index afecb9d760e..b7c712a9f30 100644 --- a/sys/arch/alpha/pci/pci_550.c +++ b/sys/arch/alpha/pci/pci_550.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_550.c,v 1.15 2006/03/26 20:23:08 brad Exp $ */ +/* $OpenBSD: pci_550.c,v 1.16 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_550.c,v 1.18 2000/06/29 08:58:48 mrg Exp $ */ /*- @@ -126,7 +126,7 @@ void dec_550_pciide_compat_intr_disestablish(void *, void *); struct alpha_shared_intr *dec_550_pci_intr; -void dec_550_iointr(void *framep, unsigned long vec); +void dec_550_iointr(void *arg, unsigned long vec); void dec_550_intr_enable(int irq); void dec_550_intr_disable(int irq); @@ -171,8 +171,6 @@ pci_550_pickintr(ccp) #if NSIO sio_intr_setup(pc, iot); #endif - - set_iointr(dec_550_iointr); } int @@ -319,8 +317,11 @@ dec_550_intr_establish(ccv, ih, level, func, arg, name) cookie = alpha_shared_intr_establish(dec_550_pci_intr, ih, IST_LEVEL, level, func, arg, name); - if (cookie != NULL && alpha_shared_intr_isactive(dec_550_pci_intr, ih)) + if (cookie != NULL && + alpha_shared_intr_firstactive(dec_550_pci_intr, ih)) { + scb_set(0x900 + SCB_IDXTOVEC(ih), dec_550_iointr, NULL); dec_550_intr_enable(ih); + } return (cookie); } @@ -354,6 +355,7 @@ dec_550_intr_disestablish(ccv, cookie) dec_550_intr_disable(irq); alpha_shared_intr_set_dfltsharetype(dec_550_pci_intr, irq, IST_NONE); + scb_free(0x900 + SCB_IDXTOVEC(irq)); } splx(s); @@ -397,34 +399,24 @@ dec_550_pciide_compat_intr_disestablish(v, cookie) } void -dec_550_iointr(framep, vec) - void *framep; +dec_550_iointr(arg, vec) + void *arg; unsigned long vec; { int irq; - if (vec >= 0x900) { - irq = ((vec - 0x900) >> 4); + irq = SCB_VECTOIDX(vec - 0x900); - if (irq >= DEC_550_MAX_IRQ) - panic("550_iointr: vec 0x%lx out of range", vec); + if (irq >= DEC_550_MAX_IRQ) + panic("550_iointr: vec 0x%lx out of range\n", vec); - if (!alpha_shared_intr_dispatch(dec_550_pci_intr, irq)) { - alpha_shared_intr_stray(dec_550_pci_intr, irq, - "dec 550 irq"); - if (ALPHA_SHARED_INTR_DISABLE(dec_550_pci_intr, irq)) - dec_550_intr_disable(irq); - } else - alpha_shared_intr_reset_strays(dec_550_pci_intr, irq); - return; - } -#if NSIO - if (vec >= 0x800) { - sio_iointr(framep, vec); - return; - } -#endif - panic("dec_550_iointr: weird vec 0x%lx", vec); + if (!alpha_shared_intr_dispatch(dec_550_pci_intr, irq)) { + alpha_shared_intr_stray(dec_550_pci_intr, irq, + "dec 550 irq"); + if (ALPHA_SHARED_INTR_DISABLE(dec_550_pci_intr, irq)) + dec_550_intr_disable(irq); + } else + alpha_shared_intr_reset_strays(dec_550_pci_intr, irq); } void diff --git a/sys/arch/alpha/pci/pci_6600.c b/sys/arch/alpha/pci/pci_6600.c index 50d1366ad08..6fd5fd8849a 100644 --- a/sys/arch/alpha/pci/pci_6600.c +++ b/sys/arch/alpha/pci/pci_6600.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_6600.c,v 1.14 2006/03/26 20:23:08 brad Exp $ */ +/* $OpenBSD: pci_6600.c,v 1.15 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_6600.c,v 1.5 2000/06/06 00:50:15 thorpej Exp $ */ /*- @@ -88,7 +88,7 @@ void dec_6600_pciide_compat_intr_disestablish(void *, void *); struct alpha_shared_intr *dec_6600_pci_intr; -void dec_6600_iointr(void *framep, unsigned long vec); +void dec_6600_iointr(void *arg, unsigned long vec); extern void dec_6600_intr_enable(int irq); extern void dec_6600_intr_disable(int irq); @@ -129,7 +129,6 @@ pci_6600_pickintr(pcp) sio_intr_setup(pc, iot); dec_6600_intr_enable(55); /* irq line for sio */ #endif - set_iointr(dec_6600_iointr); } } @@ -239,8 +238,11 @@ dec_6600_intr_establish(acv, ih, level, func, arg, name) cookie = alpha_shared_intr_establish(dec_6600_pci_intr, ih, IST_LEVEL, level, func, arg, name); - if (cookie != NULL && alpha_shared_intr_isactive(dec_6600_pci_intr, ih)) + if (cookie != NULL && + alpha_shared_intr_firstactive(dec_6600_pci_intr, ih)) { + scb_set(0x900 + SCB_IDXTOVEC(ih), dec_6600_iointr, NULL); dec_6600_intr_enable(ih); + } return (cookie); } @@ -272,40 +274,31 @@ dec_6600_intr_disestablish(acv, cookie) dec_6600_intr_disable(irq); alpha_shared_intr_set_dfltsharetype(dec_6600_pci_intr, irq, IST_NONE); + scb_free(0x900 + SCB_IDXTOVEC(irq)); } splx(s); } void -dec_6600_iointr(framep, vec) - void *framep; +dec_6600_iointr(arg, vec) + void *arg; unsigned long vec; { int irq; - if (vec >= 0x900) { - irq = (vec - 0x900) >> 4; + irq = SCB_VECTOIDX(vec - 0x900); - if (irq >= PCI_NIRQ) - panic("iointr: irq %d is too high", irq); + if (irq >= PCI_NIRQ) + panic("iointr: irq %d is too high", irq); - if (!alpha_shared_intr_dispatch(dec_6600_pci_intr, irq)) { - alpha_shared_intr_stray(dec_6600_pci_intr, irq, - irqtype); - if (ALPHA_SHARED_INTR_DISABLE(dec_6600_pci_intr, irq)) - dec_6600_intr_disable(irq); - } else - alpha_shared_intr_reset_strays(dec_6600_pci_intr, irq); - return; - } -#if NSIO - if (vec >= 0x800) { - sio_iointr(framep, vec); - return; - } -#endif - panic("iointr: weird vec 0x%lx", vec); + if (!alpha_shared_intr_dispatch(dec_6600_pci_intr, irq)) { + alpha_shared_intr_stray(dec_6600_pci_intr, irq, + irqtype); + if (ALPHA_SHARED_INTR_DISABLE(dec_6600_pci_intr, irq)) + dec_6600_intr_disable(irq); + } else + alpha_shared_intr_reset_strays(dec_6600_pci_intr, irq); } void diff --git a/sys/arch/alpha/pci/pci_axppci_33.c b/sys/arch/alpha/pci/pci_axppci_33.c index dd129f525f1..17a506fbdaa 100644 --- a/sys/arch/alpha/pci/pci_axppci_33.c +++ b/sys/arch/alpha/pci/pci_axppci_33.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_axppci_33.c,v 1.17 2002/03/14 03:15:50 millert Exp $ */ +/* $OpenBSD: pci_axppci_33.c,v 1.18 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_axppci_33.c,v 1.10 1996/11/13 21:13:29 cgd Exp $ */ /* @@ -92,7 +92,6 @@ pci_axppci_33_pickintr(lcp) #if NSIO sio_intr_setup(pc, iot); - set_iointr(&sio_iointr); #else panic("pci_axppci_33_pickintr: no I/O interrupt handler (no sio)"); #endif diff --git a/sys/arch/alpha/pci/pci_eb164.c b/sys/arch/alpha/pci/pci_eb164.c index 2920fcffb0b..2d1f3345e06 100644 --- a/sys/arch/alpha/pci/pci_eb164.c +++ b/sys/arch/alpha/pci/pci_eb164.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_eb164.c,v 1.18 2006/03/26 20:23:08 brad Exp $ */ +/* $OpenBSD: pci_eb164.c,v 1.19 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_eb164.c,v 1.27 2000/06/06 00:50:15 thorpej Exp $ */ /*- @@ -115,7 +115,7 @@ struct alpha_shared_intr *eb164_pci_intr; bus_space_tag_t eb164_intrgate_iot; bus_space_handle_t eb164_intrgate_ioh; -void eb164_iointr(void *framep, unsigned long vec); +void eb164_iointr(void *arg, unsigned long vec); extern void eb164_intr_enable(int irq); /* pci_eb164_intr.S */ extern void eb164_intr_disable(int irq); /* pci_eb164_intr.S */ @@ -161,8 +161,6 @@ pci_eb164_pickintr(ccp) sio_intr_setup(pc, iot); eb164_intr_enable(EB164_SIO_IRQ); #endif - - set_iointr(eb164_iointr); } int @@ -283,8 +281,11 @@ dec_eb164_intr_establish(ccv, ih, level, func, arg, name) cookie = alpha_shared_intr_establish(eb164_pci_intr, ih, IST_LEVEL, level, func, arg, name); - if (cookie != NULL && alpha_shared_intr_isactive(eb164_pci_intr, ih)) + if (cookie != NULL && + alpha_shared_intr_firstactive(eb164_pci_intr, ih)) { + scb_set(0x900 + SCB_IDXTOVEC(ih), eb164_iointr, NULL); eb164_intr_enable(ih); + } return (cookie); } @@ -307,6 +308,7 @@ dec_eb164_intr_disestablish(ccv, cookie) eb164_intr_disable(irq); alpha_shared_intr_set_dfltsharetype(eb164_pci_intr, irq, IST_NONE); + scb_free(0x900 + SCB_IDXTOVEC(irq)); } splx(s); @@ -350,33 +352,21 @@ dec_eb164_pciide_compat_intr_disestablish(void *v, void *cookie) } void -eb164_iointr(framep, vec) - void *framep; +eb164_iointr(arg, vec) + void *arg; unsigned long vec; { int irq; - if (vec >= 0x900) { - if (vec >= 0x900 + (EB164_MAX_IRQ << 4)) - panic("eb164_iointr: vec 0x%lx out of range", vec); - irq = (vec - 0x900) >> 4; - - if (!alpha_shared_intr_dispatch(eb164_pci_intr, irq)) { - alpha_shared_intr_stray(eb164_pci_intr, irq, - "eb164 irq"); - if (ALPHA_SHARED_INTR_DISABLE(eb164_pci_intr, irq)) - eb164_intr_disable(irq); - } else - alpha_shared_intr_reset_strays(eb164_pci_intr, irq); - return; - } -#if NSIO - if (vec >= 0x800) { - sio_iointr(framep, vec); - return; - } -#endif - panic("eb164_iointr: weird vec 0x%lx", vec); + irq = SCB_VECTOIDX(vec - 0x900); + + if (!alpha_shared_intr_dispatch(eb164_pci_intr, irq)) { + alpha_shared_intr_stray(eb164_pci_intr, irq, + "eb164 irq"); + if (ALPHA_SHARED_INTR_DISABLE(eb164_pci_intr, irq)) + eb164_intr_disable(irq); + } else + alpha_shared_intr_reset_strays(eb164_pci_intr, irq); } #if 0 /* THIS DOES NOT WORK! see pci_eb164_intr.S. */ diff --git a/sys/arch/alpha/pci/pci_eb64plus.c b/sys/arch/alpha/pci/pci_eb64plus.c index 32a080055f4..6ad999ef7c5 100644 --- a/sys/arch/alpha/pci/pci_eb64plus.c +++ b/sys/arch/alpha/pci/pci_eb64plus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_eb64plus.c,v 1.8 2006/03/26 20:23:08 brad Exp $ */ +/* $OpenBSD: pci_eb64plus.c,v 1.9 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_eb64plus.c,v 1.10 2001/07/27 00:25:20 thorpej Exp $ */ /*- @@ -143,7 +143,6 @@ pci_eb64plus_pickintr(acp) #if NSIO sio_intr_setup(pc, iot); #endif - set_iointr(eb64plus_iointr); } int @@ -217,9 +216,11 @@ dec_eb64plus_intr_establish(acv, ih, level, func, arg, name) cookie = alpha_shared_intr_establish(eb64plus_pci_intr, ih, IST_LEVEL, level, func, arg, name); - if (cookie != NULL && alpha_shared_intr_isactive(eb64plus_pci_intr, ih)) + if (cookie != NULL && + alpha_shared_intr_firstactive(eb64plus_pci_intr, ih)) { + scb_set(0x900 + SCB_IDXTOVEC(ih), eb64plus_iointr, NULL); eb64plus_intr_enable(ih); - + } return (cookie); } @@ -239,39 +240,28 @@ dec_eb64plus_intr_disestablish(acv, cookie) eb64plus_intr_disable(irq); alpha_shared_intr_set_dfltsharetype(eb64plus_pci_intr, irq, IST_NONE); + scb_free(0x900 + SCB_IDXTOVEC(irq)); } splx(s); } void -eb64plus_iointr(framep, vec) - void *framep; +eb64plus_iointr(arg, vec) + void *arg; unsigned long vec; { int irq; - if (vec >= 0x900) { - if (vec >= 0x900 + (EB64PLUS_MAX_IRQ << 4)) - panic("eb64plus_iointr: vec 0x%lx out of range", vec); - irq = (vec - 0x900) >> 4; - - if (!alpha_shared_intr_dispatch(eb64plus_pci_intr, irq)) { - alpha_shared_intr_stray(eb64plus_pci_intr, irq, - "eb64+ irq"); - if (ALPHA_SHARED_INTR_DISABLE(eb64plus_pci_intr, irq)) - eb64plus_intr_disable(irq); - } else - alpha_shared_intr_reset_strays(eb64plus_pci_intr, irq); - return; - } -#if NSIO - if (vec >= 0x800) { - sio_iointr(framep, vec); - return; - } -#endif - panic("eb64plus_iointr: weird vec 0x%lx", vec); + irq = SCB_VECTOIDX(vec - 0x900); + + if (!alpha_shared_intr_dispatch(eb64plus_pci_intr, irq)) { + alpha_shared_intr_stray(eb64plus_pci_intr, irq, + "eb64+ irq"); + if (ALPHA_SHARED_INTR_DISABLE(eb64plus_pci_intr, irq)) + eb64plus_intr_disable(irq); + } else + alpha_shared_intr_reset_strays(eb64plus_pci_intr, irq); } #if 0 /* THIS DOES NOT WORK! see pci_eb64plus_intr.S. */ diff --git a/sys/arch/alpha/pci/pci_kn20aa.c b/sys/arch/alpha/pci/pci_kn20aa.c index e9b39642e39..c9678760ade 100644 --- a/sys/arch/alpha/pci/pci_kn20aa.c +++ b/sys/arch/alpha/pci/pci_kn20aa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_kn20aa.c,v 1.21 2006/01/29 10:47:35 martin Exp $ */ +/* $OpenBSD: pci_kn20aa.c,v 1.22 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_kn20aa.c,v 1.21 1996/11/17 02:05:27 cgd Exp $ */ /* @@ -69,7 +69,7 @@ void dec_kn20aa_intr_disestablish(void *, void *); struct alpha_shared_intr *kn20aa_pci_intr; struct evcount kn20aa_intr_count; -void kn20aa_iointr(void *framep, unsigned long vec); +void kn20aa_iointr(void *arg, unsigned long vec); void kn20aa_enable_intr(int irq); void kn20aa_disable_intr(int irq); @@ -101,8 +101,6 @@ pci_kn20aa_pickintr(ccp) sio_intr_setup(pc, iot); kn20aa_enable_intr(KN20AA_PCEB_IRQ); #endif - - set_iointr(kn20aa_iointr); } int @@ -211,8 +209,10 @@ dec_kn20aa_intr_establish(ccv, ih, level, func, arg, name) level, func, arg, name); if (cookie != NULL && - alpha_shared_intr_isactive(kn20aa_pci_intr, ih)) + alpha_shared_intr_firstactive(kn20aa_pci_intr, ih)) { + scb_set(0x900 + SCB_IDXTOVEC(ih), kn20aa_iointr, NULL); kn20aa_enable_intr(ih); + } return (cookie); } @@ -232,42 +232,27 @@ dec_kn20aa_intr_disestablish(ccv, cookie) kn20aa_disable_intr(irq); alpha_shared_intr_set_dfltsharetype(kn20aa_pci_intr, irq, IST_NONE); - /* scb_free(0x900 + SCB_IDXTOVEC(irq)); */ + scb_free(0x900 + SCB_IDXTOVEC(irq)); } splx(s); } void -kn20aa_iointr(framep, vec) - void *framep; +kn20aa_iointr(arg, vec) + void *arg; unsigned long vec; { int irq; - if (vec >= 0x900) { - if (vec >= 0x900 + (KN20AA_MAX_IRQ << 4)) - panic("kn20aa_iointr: vec 0x%x out of range", vec); - irq = (vec - 0x900) >> 4; - - kn20aa_intr_count.ec_count++; - - if (!alpha_shared_intr_dispatch(kn20aa_pci_intr, irq)) { - alpha_shared_intr_stray(kn20aa_pci_intr, irq, - "kn20aa irq"); - if (kn20aa_pci_intr[irq].intr_nstrays == - kn20aa_pci_intr[irq].intr_maxstrays) - kn20aa_disable_intr(irq); - } else - alpha_shared_intr_reset_strays(kn20aa_pci_intr, irq); - return; - } -#if NSIO - if (vec >= 0x800) { - sio_iointr(framep, vec); - return; - } -#endif - panic("kn20aa_iointr: weird vec 0x%x", vec); + irq = SCB_VECTOIDX(vec - 0x900); + + if (!alpha_shared_intr_dispatch(kn20aa_pci_intr, irq)) { + alpha_shared_intr_stray(kn20aa_pci_intr, irq, + "kn20aa irq"); + if (ALPHA_SHARED_INTR_DISABLE(kn20aa_pci_intr, irq)) + kn20aa_disable_intr(irq); + } else + alpha_shared_intr_reset_strays(kn20aa_pci_intr, irq); } void diff --git a/sys/arch/alpha/pci/pci_up1000.c b/sys/arch/alpha/pci/pci_up1000.c index 3173cd91672..35fea1fff73 100644 --- a/sys/arch/alpha/pci/pci_up1000.c +++ b/sys/arch/alpha/pci/pci_up1000.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_up1000.c,v 1.10 2006/03/26 20:23:08 brad Exp $ */ +/* $OpenBSD: pci_up1000.c,v 1.11 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: pci_up1000.c,v 1.6 2000/12/28 22:59:07 sommerfeld Exp $ */ /*- @@ -96,7 +96,6 @@ pci_up1000_pickintr(struct irongate_config *icp) #if NSIO sio_intr_setup(pc, iot); - set_iointr(&sio_iointr); #else panic("pci_up1000_pickintr: no I/O interrupt handler (no sio)"); #endif diff --git a/sys/arch/alpha/pci/sio_pic.c b/sys/arch/alpha/pci/sio_pic.c index afa3299560c..a0a3f32eabc 100644 --- a/sys/arch/alpha/pci/sio_pic.c +++ b/sys/arch/alpha/pci/sio_pic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sio_pic.c,v 1.25 2006/01/29 10:47:35 martin Exp $ */ +/* $OpenBSD: sio_pic.c,v 1.26 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: sio_pic.c,v 1.28 2000/06/06 03:10:13 thorpej Exp $ */ /*- @@ -67,6 +67,7 @@ #include <sys/param.h> #include <sys/systm.h> + #include <sys/device.h> #include <sys/malloc.h> #include <sys/syslog.h> @@ -463,9 +464,12 @@ sio_intr_establish(v, irq, type, level, fn, arg, name) cookie = alpha_shared_intr_establish(sio_intr, irq, type, level, fn, arg, name); - if (cookie) - sio_setirqstat(irq, alpha_shared_intr_isactive(sio_intr, irq), + if (cookie != NULL && + alpha_shared_intr_firstactive(sio_intr, irq)) { + scb_set(0x800 + SCB_IDXTOVEC(irq), sio_iointr, NULL); + sio_setirqstat(irq, 1, alpha_shared_intr_get_sharetype(sio_intr, irq)); + } return (cookie); } @@ -513,19 +517,23 @@ sio_intr_disestablish(v, cookie) } sio_setirqstat(irq, 0, ist); alpha_shared_intr_set_dfltsharetype(sio_intr, irq, ist); + + /* Release our SCB vector. */ + scb_free(0x800 + SCB_IDXTOVEC(irq)); } splx(s); } void -sio_iointr(framep, vec) - void *framep; +sio_iointr(arg, vec) + void *arg; unsigned long vec; { int irq; - irq = (vec - 0x800) >> 4; + irq = SCB_VECTOIDX(vec - 0x800); + #ifdef DIAGNOSTIC if (irq >= ICU_LEN || irq < 0) panic("sio_iointr: irq out of range (%d)", irq); diff --git a/sys/arch/alpha/tc/tcasic.c b/sys/arch/alpha/tc/tcasic.c index 4662dabcd59..76aab2da124 100644 --- a/sys/arch/alpha/tc/tcasic.c +++ b/sys/arch/alpha/tc/tcasic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcasic.c,v 1.14 2006/03/16 22:32:01 miod Exp $ */ +/* $OpenBSD: tcasic.c,v 1.15 2006/06/15 20:08:29 brad Exp $ */ /* $NetBSD: tcasic.c,v 1.36 2001/08/23 01:16:52 nisimura Exp $ */ /* @@ -140,7 +140,9 @@ tcasicattach(parent, self, aux) tc_dma_init(); (*intr_setup)(); - set_iointr(iointr); + + /* They all come in at 0x800. */ + scb_set(0x800, iointr, NULL); config_found(self, &tba, tcasicprint); } |