Module Name: src Committed By: matt Date: Fri Jun 17 23:36:18 UTC 2011
Modified Files: src/sys/arch/amigappc/include: intr.h src/sys/arch/bebox/include: intr.h src/sys/arch/evbppc/include: pmppc_intr.h src/sys/arch/ibmnws/include: intr.h src/sys/arch/macppc/include: intr.h src/sys/arch/mvmeppc/include: intr.h src/sys/arch/ofppc/include: intr.h src/sys/arch/powerpc/include: intr.h src/sys/arch/powerpc/pic: files.pic intr.c src/sys/arch/prep/include: intr.h src/sys/arch/prep/pnpbus: if_we_pnpbus.c src/sys/arch/rs6000/include: intr.h src/sys/arch/sandpoint/include: intr.h Removed Files: src/sys/arch/powerpc/pic: pic_subr.c Log Message: intr.h must not include cpu due to deadly embrace with SOFTINT_COUNT. Cleanup intr.h so MD definitions can overload common definitions. Rototill pic/intr.c. Virtual IRQs can now be reclaimed. separate virq from hwirq from picirq. Redo intr mask calculations. tested on pmppc and macppc (MP). To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.25 src/sys/arch/amigappc/include/intr.h cvs rdiff -u -r1.29 -r1.30 src/sys/arch/bebox/include/intr.h cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbppc/include/pmppc_intr.h cvs rdiff -u -r1.14 -r1.15 src/sys/arch/ibmnws/include/intr.h cvs rdiff -u -r1.29 -r1.30 src/sys/arch/macppc/include/intr.h cvs rdiff -u -r1.14 -r1.15 src/sys/arch/mvmeppc/include/intr.h cvs rdiff -u -r1.15 -r1.16 src/sys/arch/ofppc/include/intr.h cvs rdiff -u -r1.7 -r1.8 src/sys/arch/powerpc/include/intr.h cvs rdiff -u -r1.6 -r1.7 src/sys/arch/powerpc/pic/files.pic cvs rdiff -u -r1.14 -r1.15 src/sys/arch/powerpc/pic/intr.c cvs rdiff -u -r1.1 -r0 src/sys/arch/powerpc/pic/pic_subr.c cvs rdiff -u -r1.33 -r1.34 src/sys/arch/prep/include/intr.h cvs rdiff -u -r1.5 -r1.6 src/sys/arch/prep/pnpbus/if_we_pnpbus.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/rs6000/include/intr.h cvs rdiff -u -r1.18 -r1.19 src/sys/arch/sandpoint/include/intr.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amigappc/include/intr.h diff -u src/sys/arch/amigappc/include/intr.h:1.24 src/sys/arch/amigappc/include/intr.h:1.25 --- src/sys/arch/amigappc/include/intr.h:1.24 Sat Nov 13 13:34:00 2010 +++ src/sys/arch/amigappc/include/intr.h Fri Jun 17 23:36:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.24 2010/11/13 13:34:00 uebayasi Exp $ */ +/* $NetBSD: intr.h,v 1.25 2011/06/17 23:36:17 matt Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -44,8 +44,4 @@ #endif #include <powerpc/intr.h> -#ifndef _LOCORE -#include <machine/cpu.h> -#endif /* _LOCORE */ - #endif /* !_AMIGAPPC_INTR_H_ */ Index: src/sys/arch/bebox/include/intr.h diff -u src/sys/arch/bebox/include/intr.h:1.29 src/sys/arch/bebox/include/intr.h:1.30 --- src/sys/arch/bebox/include/intr.h:1.29 Sat Apr 24 09:39:56 2010 +++ src/sys/arch/bebox/include/intr.h Fri Jun 17 23:36:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.29 2010/04/24 09:39:56 kiyohara Exp $ */ +/* $NetBSD: intr.h,v 1.30 2011/06/17 23:36:17 matt Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -42,12 +42,12 @@ extern paddr_t bebox_mb_reg; -#define ICU_LEN 32 -#define IRQ_SLAVE 2 -#define LEGAL_IRQ(x) ((x) >= 0 && (x) < ICU_LEN && (x) != IRQ_SLAVE) +#define ICU_LEN 32 +#define IRQ_SLAVE 2 +#define LEGAL_HWIRQ_P(x) ((u_int)(x) < ICU_LEN && (x) != IRQ_SLAVE) -#define BEBOX_INTR_REG 0x7ffff000 -#define INTR_VECTOR_REG 0xff0 +#define BEBOX_INTR_REG 0x7ffff000 +#define INTR_VECTOR_REG 0xff0 #endif /* !_LOCORE */ Index: src/sys/arch/evbppc/include/pmppc_intr.h diff -u src/sys/arch/evbppc/include/pmppc_intr.h:1.3 src/sys/arch/evbppc/include/pmppc_intr.h:1.4 --- src/sys/arch/evbppc/include/pmppc_intr.h:1.3 Mon Apr 28 20:23:17 2008 +++ src/sys/arch/evbppc/include/pmppc_intr.h Fri Jun 17 23:36:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pmppc_intr.h,v 1.3 2008/04/28 20:23:17 martin Exp $ */ +/* $NetBSD: pmppc_intr.h,v 1.4 2011/06/17 23:36:17 matt Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -44,7 +44,7 @@ #define ICU_LEN 32 #define ICU_MASK 0x1f000fc0 -#define LEGAL_IRQ(x) ((x) >= 0 && (x) <= 31 && (ICU_MASK & (0x80000000 >> (x)))) +#define LEGAL_HWIRQ_P(x) ((u_int)(x) < ICU_LEN && (ICU_MASK & (0x80000000 >> (x)))) #endif /* !_LOCORE */ Index: src/sys/arch/ibmnws/include/intr.h diff -u src/sys/arch/ibmnws/include/intr.h:1.14 src/sys/arch/ibmnws/include/intr.h:1.15 --- src/sys/arch/ibmnws/include/intr.h:1.14 Sat Nov 13 14:07:07 2010 +++ src/sys/arch/ibmnws/include/intr.h Fri Jun 17 23:36:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.14 2010/11/13 14:07:07 uebayasi Exp $ */ +/* $NetBSD: intr.h,v 1.15 2011/06/17 23:36:17 matt Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -32,11 +32,7 @@ #ifndef _IBMNWS_INTR_H_ #define _IBMNWS_INTR_H_ -#include <powerpc/intr.h> - #ifndef _LOCORE -#include <machine/cpu.h> - void init_intr_ivr(void); void init_intr_openpic(void); void openpic_init(unsigned char *); @@ -49,7 +45,7 @@ #define ICU_LEN 32 #define IRQ_SLAVE 2 -#define LEGAL_IRQ(x) ((x) >= 0 && (x) < ICU_LEN && (x) != IRQ_SLAVE) +#define LEGAL_HWIRQ_P(x) ((u_int)(x) < ICU_LEN && (x) != IRQ_SLAVE) #define I8259_INTR_NUM 16 #define PREP_INTR_REG 0xbffff000 @@ -57,4 +53,6 @@ #endif /* !_LOCORE */ +#include <powerpc/intr.h> + #endif /* !_IBMNWS_INTR_H_ */ Index: src/sys/arch/macppc/include/intr.h diff -u src/sys/arch/macppc/include/intr.h:1.29 src/sys/arch/macppc/include/intr.h:1.30 --- src/sys/arch/macppc/include/intr.h:1.29 Fri Jun 17 05:18:10 2011 +++ src/sys/arch/macppc/include/intr.h Fri Jun 17 23:36:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.29 2011/06/17 05:18:10 matt Exp $ */ +/* $NetBSD: intr.h,v 1.30 2011/06/17 23:36:17 matt Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -32,8 +32,6 @@ #ifndef _MACPPC_INTR_H_ #define _MACPPC_INTR_H_ -#include <powerpc/intr.h> - #ifdef _KERNEL_OPT #include "opt_multiprocessor.h" #endif @@ -59,4 +57,6 @@ #endif #endif /* _LOCORE */ +#include <powerpc/intr.h> + #endif /* _MACPPC_INTR_H_ */ Index: src/sys/arch/mvmeppc/include/intr.h diff -u src/sys/arch/mvmeppc/include/intr.h:1.14 src/sys/arch/mvmeppc/include/intr.h:1.15 --- src/sys/arch/mvmeppc/include/intr.h:1.14 Sat Apr 24 09:39:57 2010 +++ src/sys/arch/mvmeppc/include/intr.h Fri Jun 17 23:36:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.14 2010/04/24 09:39:57 kiyohara Exp $ */ +/* $NetBSD: intr.h,v 1.15 2011/06/17 23:36:17 matt Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -32,8 +32,6 @@ #ifndef _MVMEPPC_INTR_H_ #define _MVMEPPC_INTR_H_ -#include <powerpc/intr.h> - #ifndef _LOCORE void enable_intr(void); @@ -41,13 +39,15 @@ extern vaddr_t mvmeppc_intr_reg; -#define ICU_LEN 32 -#define IRQ_SLAVE 2 -#define LEGAL_IRQ(x) ((x) >= 0 && (x) < ICU_LEN && (x) != IRQ_SLAVE) +#define ICU_LEN 32 +#define IRQ_SLAVE 2 +#define LEGAL_HWIRQ_P(x) ((u_int)(x) < ICU_LEN && (x) != IRQ_SLAVE) #define MVMEPPC_INTR_REG 0xbffff000 -#define INTR_VECTOR_REG 0xff0 +#define INTR_VECTOR_REG 0xff0 #endif /* !_LOCORE */ +#include <powerpc/intr.h> + #endif /* !_MVMEPPC_INTR_H_ */ Index: src/sys/arch/ofppc/include/intr.h diff -u src/sys/arch/ofppc/include/intr.h:1.15 src/sys/arch/ofppc/include/intr.h:1.16 --- src/sys/arch/ofppc/include/intr.h:1.15 Sun Jun 5 16:52:24 2011 +++ src/sys/arch/ofppc/include/intr.h Fri Jun 17 23:36:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.15 2011/06/05 16:52:24 matt Exp $ */ +/* $NetBSD: intr.h,v 1.16 2011/06/17 23:36:17 matt Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -32,21 +32,19 @@ #ifndef _OFPPC_INTR_H_ #define _OFPPC_INTR_H_ +#ifndef _LOCORE #ifdef _KERNEL_OPT #include "opt_multiprocessor.h" #endif - -#include <powerpc/intr.h> - -#ifndef _LOCORE #ifdef MULTIPROCESSOR #include <powerpc/pic/ipivar.h> #endif -#include <machine/cpu.h> #define ICU_LEN 32 #define IRQ_SLAVE 2 #endif +#include <powerpc/intr.h> + #endif /* _OFPPC_INTR_H_ */ Index: src/sys/arch/powerpc/include/intr.h diff -u src/sys/arch/powerpc/include/intr.h:1.7 src/sys/arch/powerpc/include/intr.h:1.8 --- src/sys/arch/powerpc/include/intr.h:1.7 Fri Jun 17 05:15:22 2011 +++ src/sys/arch/powerpc/include/intr.h Fri Jun 17 23:36:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.7 2011/06/17 05:15:22 matt Exp $ */ +/* $NetBSD: intr.h,v 1.8 2011/06/17 23:36:17 matt Exp $ */ /*- * Copyright (c) 2007 Michael Lorenz @@ -28,7 +28,7 @@ #ifndef _LOCORE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intr.h,v 1.7 2011/06/17 05:15:22 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.h,v 1.8 2011/06/17 23:36:17 matt Exp $"); #endif #ifndef POWERPC_INTR_MACHDEP_H @@ -60,10 +60,6 @@ #define IST_EDGE 2 /* edge-triggered */ #define IST_LEVEL 3 /* level-triggered */ -#ifdef _LOCORE -#define splhigh __splhigh -#endif - #ifndef _LOCORE /* * Interrupt handler chains. intr_establish() inserts a handler into @@ -74,7 +70,7 @@ void *ih_arg; struct intrhand *ih_next; int ih_ipl; - int ih_irq; + int ih_virq; }; int splraise(int); @@ -86,16 +82,24 @@ #define softint_init_md powerpc_softint_init_md #define softint_trigger powerpc_softint_trigger -typedef u_int imask_t; +#ifdef __IMASK_T +typedef __IMASK_T imask_t; +#else +typedef uint32_t imask_t; +#endif + extern imask_t imask[]; -#define NVIRQ 32 /* 32 virtual IRQs */ +#define NVIRQ (sizeof(imask_t)*8) /* 32 virtual IRQs */ +#ifndef NIRQ #define NIRQ 128 /* up to 128 HW IRQs */ +#endif -#define HWIRQ_MAX (NVIRQ - 5 - 1) -#define HWIRQ_MASK 0x07ffffff +#define HWIRQ_MAX (NVIRQ - 1) +#define HWIRQ_MASK (~(imask_t)0 >> 1) -#define MS_PENDING(p) (31 - cntlzw(p)) +#define PIC_VIRQ_TO_MASK(v) __BIT(HWIRQ_MAX - (v)) +#define PIC_VIRQ_MS_PENDING(p) __builtin_clz(p) #define spl0() spllower(0) Index: src/sys/arch/powerpc/pic/files.pic diff -u src/sys/arch/powerpc/pic/files.pic:1.6 src/sys/arch/powerpc/pic/files.pic:1.7 --- src/sys/arch/powerpc/pic/files.pic:1.6 Thu Jun 16 02:43:43 2011 +++ src/sys/arch/powerpc/pic/files.pic Fri Jun 17 23:36:18 2011 @@ -1,10 +1,9 @@ # -# $NetBSD: files.pic,v 1.6 2011/06/16 02:43:43 macallan Exp $ +# $NetBSD: files.pic,v 1.7 2011/06/17 23:36:18 matt Exp $ # # generic PIC abstraction file arch/powerpc/pic/intr.c -file arch/powerpc/pic/pic_subr.c defflag opt_pic.h PIC_DEBUG Index: src/sys/arch/powerpc/pic/intr.c diff -u src/sys/arch/powerpc/pic/intr.c:1.14 src/sys/arch/powerpc/pic/intr.c:1.15 --- src/sys/arch/powerpc/pic/intr.c:1.14 Fri Jun 17 05:15:23 2011 +++ src/sys/arch/powerpc/pic/intr.c Fri Jun 17 23:36:18 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.c,v 1.14 2011/06/17 05:15:23 matt Exp $ */ +/* $NetBSD: intr.c,v 1.15 2011/06/17 23:36:18 matt Exp $ */ /*- * Copyright (c) 2007 Michael Lorenz @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.14 2011/06/17 05:15:23 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.15 2011/06/17 23:36:18 matt Exp $"); #include "opt_multiprocessor.h" @@ -55,29 +55,27 @@ #define MAX_PICS 8 /* 8 PICs ought to be enough for everyone */ -#define LEGAL_VIRQ(x) ((x) >= 0 && (x) < NVIRQ) +#define PIC_VIRQ_LEGAL_P(x) ((u_int)(x) < NVIRQ) struct pic_ops *pics[MAX_PICS]; int num_pics = 0; int max_base = 0; -uint8_t virq[NIRQ]; -int virq_max = 0; +uint8_t virq_map[NIRQ]; +imask_t virq_mask = HWIRQ_MASK; imask_t imask[NIPL]; int primary_pic = 0; static int fakeintr(void *); -static int mapirq(uint32_t); +static int mapirq(int); static void intr_calculatemasks(void); -static struct pic_ops *find_pic_by_irq(int); +static struct pic_ops *find_pic_by_hwirq(int); static struct intr_source intrsources[NVIRQ]; void pic_init(void) { - for (u_int i = 0; i < NIRQ; i++) - virq[i] = 0; - memset(intrsources, 0, sizeof(intrsources)); + /* everything is in bss, no reason to zero it. */ } int @@ -98,23 +96,20 @@ void pic_finish_setup(void) { - struct pic_ops *pic; - int i; - - for (i = 0; i < num_pics; i++) { - pic = pics[i]; + for (size_t i = 0; i < num_pics; i++) { + struct pic_ops * const pic = pics[i]; if (pic->pic_finish_setup != NULL) pic->pic_finish_setup(pic); } } static struct pic_ops * -find_pic_by_irq(int irq) +find_pic_by_hwirq(int hwirq) { for (u_int base = 0; base < num_pics; base++) { struct pic_ops * const pic = pics[base]; - if (pic->pic_intrbase <= irq - && irq < pic->pic_intrbase + pic->pic_numintrs) { + if (pic->pic_intrbase <= hwirq + && hwirq < pic->pic_intrbase + pic->pic_numintrs) { return pic; } } @@ -136,37 +131,36 @@ void *ih_arg) { struct intrhand **p, *q, *ih; - struct intr_source *is; struct pic_ops *pic; static struct intrhand fakehand; - int irq, maxipl = ipl; + int maxipl = ipl; if (maxipl == IPL_NONE) maxipl = IPL_HIGH; if (hwirq >= max_base) { - panic("%s: bogus IRQ %d, max is %d", __func__, hwirq, max_base - 1); } - pic = find_pic_by_irq(hwirq); + pic = find_pic_by_hwirq(hwirq); if (pic == NULL) { panic("%s: cannot find a pic for IRQ %d", __func__, hwirq); } - irq = mapirq(hwirq); + const int virq = mapirq(hwirq); /* no point in sleeping unless someone can free memory. */ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK); if (ih == NULL) panic("intr_establish: can't malloc handler info"); - if (!LEGAL_VIRQ(irq) || type == IST_NONE) - panic("intr_establish: bogus irq (%d) or type (%d)", irq, type); + if (!PIC_VIRQ_LEGAL_P(virq) || type == IST_NONE) + panic("intr_establish: bogus irq (%d) or type (%d)", + hwirq, type); - is = &intrsources[irq]; + struct intr_source * const is = &intrsources[virq]; switch (is->is_type) { case IST_NONE: @@ -176,6 +170,7 @@ case IST_LEVEL: if (type == is->is_type) break; + /* FALLTHROUGH */ case IST_PULSE: if (type != IST_NONE) panic("intr_establish: can't share %s with %s", @@ -215,7 +210,7 @@ ih->ih_arg = ih_arg; ih->ih_next = NULL; ih->ih_ipl = ipl; - ih->ih_irq = irq; + ih->ih_virq = virq; *p = ih; if (pic->pic_establish_irq != NULL) @@ -249,13 +244,13 @@ intr_disestablish(void *arg) { struct intrhand * const ih = arg; - const int irq = ih->ih_irq; - struct intr_source * const is = &intrsources[irq]; + const int virq = ih->ih_virq; + struct intr_source * const is = &intrsources[virq]; struct intrhand **p, **q; int maxipl = IPL_NONE; - if (!LEGAL_VIRQ(irq)) - panic("intr_disestablish: bogus irq %d", irq); + if (!PIC_VIRQ_LEGAL_P(virq)) + panic("intr_disestablish: bogus virq %d", virq); /* * Remove the handler from the chain. @@ -285,6 +280,11 @@ if (is->is_hand == NULL) { is->is_type = IST_NONE; evcnt_detach(&is->is_ev); + /* + * Make the virutal IRQ available again. + */ + virq_map[virq] = 0; + virq_mask |= PIC_VIRQ_TO_MASK(virq); } } @@ -292,32 +292,34 @@ * Map max_base irqs into 32 (bits). */ static int -mapirq(uint32_t irq) +mapirq(int hwirq) { struct pic_ops *pic; - int v; - if (irq >= max_base) - panic("invalid irq %d", irq); + if (hwirq >= max_base) + panic("invalid irq %d", hwirq); - if ((pic = find_pic_by_irq(irq)) == NULL) - panic("%s: cannot find PIC for IRQ %d", __func__, irq); + if ((pic = find_pic_by_hwirq(hwirq)) == NULL) + panic("%s: cannot find PIC for HWIRQ %d", __func__, hwirq); - if (virq[irq]) - return virq[irq]; + if (virq_map[hwirq]) + return virq_map[hwirq]; - virq_max++; - v = virq_max; - if (v > HWIRQ_MAX) + if (virq_mask == 0) panic("virq overflow"); - intrsources[v].is_hwirq = irq; - intrsources[v].is_pic = pic; - virq[irq] = v; + const int virq = PIC_VIRQ_MS_PENDING(virq_mask); + struct intr_source * const is = intrsources + virq; + + virq_mask &= ~PIC_VIRQ_TO_MASK(virq); + + is->is_hwirq = hwirq; + is->is_pic = pic; + virq_map[hwirq] = virq; #ifdef PIC_DEBUG - printf("mapping irq %d to virq %d\n", irq, v); + printf("mapping hwirq %d to virq %d\n", irq, virq); #endif - return v; + return virq; } static const char * const intr_typenames[] = { @@ -354,7 +356,7 @@ /* First, figure out which ipl each IRQ uses. */ for (irq = 0, is = intrsources; irq < NVIRQ; irq++, is++) { - newmask[is->is_ipl] |= 1ULL << irq; + newmask[is->is_ipl] |= PIC_VIRQ_TO_MASK(irq); } /* @@ -404,150 +406,116 @@ } void -pic_enable_irq(int num) +pic_enable_irq(int hwirq) { - struct pic_ops *current; - int type; - - current = find_pic_by_irq(num); - if (current == NULL) - panic("%s: bogus IRQ %d", __func__, num); - type = intrsources[virq[num]].is_type; - current->pic_enable_irq(current, num - current->pic_intrbase, type); + struct pic_ops * const pic = find_pic_by_hwirq(hwirq); + if (pic == NULL) + panic("%s: bogus IRQ %d", __func__, hwirq); + const int type = intrsources[virq_map[hwirq]].is_type; + (*pic->pic_enable_irq)(pic, hwirq - pic->pic_intrbase, type); } void -pic_mark_pending(int irq) +pic_mark_pending(int hwirq) { struct cpu_info * const ci = curcpu(); - int v, msr; - v = virq[irq]; - if (v == 0) - printf("IRQ %d maps to 0\n", irq); + const int virq = virq_map[hwirq]; + if (virq == 0) + printf("IRQ %d maps to 0\n", hwirq); - msr = mfmsr(); + const register_t msr = mfmsr(); mtmsr(msr & ~PSL_EE); - ci->ci_ipending |= 1ULL << v; + ci->ci_ipending |= PIC_VIRQ_TO_MASK(virq); mtmsr(msr); } +static void +intr_deliver(struct intr_source *is, int virq) +{ + bool locked = false; + for (struct intrhand *ih = is->is_hand; ih != NULL; ih = ih->ih_next) { + KASSERTMSG(ih->ih_fun != NULL, + ("%s: irq %d, hwirq %d, is %p ih %p: " + "NULL interrupt handler!\n", __func__, + virq, is->is_hwirq, is, ih)); + if (ih->ih_ipl == IPL_VM) { + if (!locked) { + KERNEL_LOCK(1, NULL); + locked = true; + } + } else if (locked) { + KERNEL_UNLOCK_ONE(NULL); + locked = false; + } + (*ih->ih_fun)(ih->ih_arg); + } + if (locked) { + KERNEL_UNLOCK_ONE(NULL); + } + is->is_ev.ev_count++; +} + void pic_do_pending_int(void) { struct cpu_info * const ci = curcpu(); - struct intr_source *is; - struct intrhand *ih; - struct pic_ops *pic; - int irq; - int pcpl; - imask_t hwpend; - int emsr, dmsr; + imask_t vpend; if (ci->ci_iactive) return; ci->ci_iactive = 1; - emsr = mfmsr(); + + const register_t emsr = mfmsr(); + const register_t dmsr = emsr & ~PSL_EE; + KASSERT(emsr & PSL_EE); - dmsr = emsr & ~PSL_EE; mtmsr(dmsr); - pcpl = ci->ci_cpl; + const int pcpl = ci->ci_cpl; #ifdef __HAVE_FAST_SOFTINTS -#if 0 again: #endif -#endif /* Do now unmasked pendings */ - while ((hwpend = (ci->ci_ipending & ~imask[pcpl] & HWIRQ_MASK)) != 0) { + while ((vpend = (ci->ci_ipending & ~imask[pcpl])) != 0) { ci->ci_idepth++; + KASSERT((PIC_VIRQ_TO_MASK(0) & ci->ci_ipending) == 0); + /* Get most significant pending bit */ - irq = MS_PENDING(hwpend); - KASSERT(irq <= virq_max); - ci->ci_ipending &= ~(1ULL << irq); - if (irq == 0) { - printf("VIRQ0"); - continue; - } - is = &intrsources[irq]; - pic = is->is_pic; + const int virq = PIC_VIRQ_MS_PENDING(vpend); + ci->ci_ipending &= ~PIC_VIRQ_TO_MASK(virq); + + struct intr_source * const is = &intrsources[virq]; + struct pic_ops * const pic = is->is_pic; splraise(is->is_ipl); mtmsr(emsr); - ih = is->is_hand; - while (ih) { -#ifdef DIAGNOSTIC - if (!ih->ih_fun) { - printf("NULL interrupt handler!\n"); - panic("irq %02d, hwirq %02d, is %p\n", - irq, is->is_hwirq, is); - } -#endif - if (ih->ih_ipl == IPL_VM) { - KERNEL_LOCK(1, NULL); - } - (*ih->ih_fun)(ih->ih_arg); - if (ih->ih_ipl == IPL_VM) { - KERNEL_UNLOCK_ONE(NULL); - } - ih = ih->ih_next; - } + intr_deliver(is, virq); mtmsr(dmsr); - ci->ci_cpl = pcpl; + ci->ci_cpl = pcpl; /* Don't use splx... we are here already! */ - is->is_ev.ev_count++; pic->pic_reenable_irq(pic, is->is_hwirq - pic->pic_intrbase, is->is_type); ci->ci_idepth--; } #ifdef __HAVE_FAST_SOFTINTS -#if 0 - if ((ci->ci_ipending & ~pcpl) & (1ULL << SIR_SERIAL)) { - ci->ci_ipending &= ~(1ULL << SIR_SERIAL); - splsoftserial(); - mtmsr(emsr); - softintr__run(IPL_SOFTSERIAL); - mtmsr(dmsr); - ci->ci_cpl = pcpl; - ci->ci_ev_softserial.ev_count++; - goto again; - } - if ((ci->ci_ipending & ~pcpl) & (1ULL << SIR_NET)) { - ci->ci_ipending &= ~(1ULL << SIR_NET); - splsoftnet(); - mtmsr(emsr); - softintr__run(IPL_SOFTNET); - mtmsr(dmsr); - ci->ci_cpl = pcpl; - ci->ci_ev_softnet.ev_count++; - goto again; - } - if ((ci->ci_ipending & ~pcpl) & (1ULL << SIR_CLOCK)) { - ci->ci_ipending &= ~(1ULL << SIR_CLOCK); - splsoftclock(); - mtmsr(emsr); - softintr__run(IPL_SOFTCLOCK); - mtmsr(dmsr); - ci->ci_cpl = pcpl; - ci->ci_ev_softclock.ev_count++; - goto again; - } -#else const u_int softints = (ci->ci_data.cpu_softints << pcpl) & IPL_SOFTMASK; if (__predict_false(softints != 0)) { - splhigh(); + ci->ci_cpl = IPL_HIGH; + mtmsr(emsr); powerpc_softint(ci, pcpl, (vaddr_t)__builtin_return_address(0)); + mtmsr(dmsr); ci->ci_cpl = pcpl; + if (__predict_false(ci->ci_ipending & ~imask[pcpl])) + goto again; } #endif -#endif - ci->ci_cpl = pcpl; /* Don't use splx... we are here already! */ ci->ci_iactive = 0; mtmsr(emsr); } @@ -557,86 +525,52 @@ { struct pic_ops *pic = cookie; struct cpu_info *ci = curcpu(); - struct intr_source *is; - struct intrhand *ih; - int irq, realirq; - int pcpl, msr, bail; - imask_t r_imen; + int picirq; - realirq = pic->pic_get_irq(pic, PIC_GET_IRQ); - if (realirq == 255) + picirq = pic->pic_get_irq(pic, PIC_GET_IRQ); + if (picirq == 255) return 0; - msr = mfmsr(); - pcpl = ci->ci_cpl; - -start: + const register_t msr = mfmsr(); + const int pcpl = ci->ci_cpl; + do { #ifdef MULTIPROCESSOR - /* THIS IS WRONG XXX */ - while (realirq == ipiops.ppc_ipi_vector) { - ipi_intr(NULL); - pic->pic_ack_irq(pic, realirq); - realirq = pic->pic_get_irq(pic, PIC_GET_RECHECK); - } - if (realirq == 255) { - return 0; - } + /* THIS IS WRONG XXX */ + if (picirq == ipiops.ppc_ipi_vector) { + ci->ci_cpl = IPL_HIGH; + ipi_intr(NULL); + ci->ci_cpl = pcpl; + pic->pic_ack_irq(pic, picirq); + continue; + } #endif - irq = virq[realirq + pic->pic_intrbase]; -#ifdef PIC_DEBUG - if (irq == 0) { - printf("%s: %d virq 0\n", pic->pic_name, realirq); - goto boo; - } -#endif /* PIC_DEBUG */ - KASSERT(realirq < pic->pic_numintrs); - r_imen = 1ULL << irq; - is = &intrsources[irq]; - - if ((imask[pcpl] & r_imen) != 0) { - - ci->ci_ipending |= r_imen; /* Masked! Mark this as pending */ - pic->pic_disable_irq(pic, realirq); - } else { - - /* this interrupt is no longer pending */ - ci->ci_ipending &= ~r_imen; - ci->ci_idepth++; + const int virq = virq_map[picirq + pic->pic_intrbase]; + KASSERT(virq != 0); + KASSERT(picirq < pic->pic_numintrs); + imask_t v_imen = PIC_VIRQ_TO_MASK(virq); + struct intr_source * const is = &intrsources[virq]; + + if ((imask[pcpl] & v_imen) != 0) { + ci->ci_ipending |= v_imen; /* Masked! Mark this as pending */ + pic->pic_disable_irq(pic, picirq); + } else { + /* this interrupt is no longer pending */ + ci->ci_ipending &= ~v_imen; + ci->ci_idepth++; + + splraise(is->is_ipl); + mtmsr(msr | PSL_EE); + intr_deliver(is, virq); + mtmsr(msr); + ci->ci_cpl = pcpl; - splraise(is->is_ipl); - mtmsr(msr | PSL_EE); - ih = is->is_hand; - bail = 0; - while ((ih != NULL) && (bail < 10)) { - if (ih->ih_fun == NULL) - panic("bogus handler for IRQ %s %d", - pic->pic_name, realirq); - if (ih->ih_ipl == IPL_VM) { - KERNEL_LOCK(1, NULL); - } - (*ih->ih_fun)(ih->ih_arg); - if (ih->ih_ipl == IPL_VM) { - KERNEL_UNLOCK_ONE(NULL); - } - ih = ih->ih_next; - bail++; + ci->ci_data.cpu_nintr++; + ci->ci_idepth--; } - mtmsr(msr); - ci->ci_cpl = pcpl; - - ci->ci_data.cpu_nintr++; - is->is_ev.ev_count++; - ci->ci_idepth--; - } -#ifdef PIC_DEBUG -boo: -#endif /* PIC_DEBUG */ - pic->pic_ack_irq(pic, realirq); - realirq = pic->pic_get_irq(pic, PIC_GET_RECHECK); - if (realirq != 255) - goto start; + pic->pic_ack_irq(pic, picirq); + } while ((picirq = pic->pic_get_irq(pic, PIC_GET_RECHECK)) != 255); mtmsr(msr | PSL_EE); splx(pcpl); /* Process pendings. */ @@ -747,7 +681,7 @@ mask >>= 1, irq++) { if ((mask & 1) == 0) continue; - vi = virq[irq + pic->pic_intrbase]; + vi = virq_map[irq + pic->pic_intrbase]; if (!vi) { *irq_p = irq; return 0; Index: src/sys/arch/prep/include/intr.h diff -u src/sys/arch/prep/include/intr.h:1.33 src/sys/arch/prep/include/intr.h:1.34 --- src/sys/arch/prep/include/intr.h:1.33 Sat Nov 13 14:07:07 2010 +++ src/sys/arch/prep/include/intr.h Fri Jun 17 23:36:18 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.33 2010/11/13 14:07:07 uebayasi Exp $ */ +/* $NetBSD: intr.h,v 1.34 2011/06/17 23:36:18 matt Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -32,10 +32,7 @@ #ifndef _PREP_INTR_H_ #define _PREP_INTR_H_ -#include <powerpc/intr.h> - #ifndef _LOCORE -#include <machine/cpu.h> void init_intr_ivr(void); void init_intr_openpic(void); @@ -49,13 +46,15 @@ #define ICU_LEN 32 #define IRQ_SLAVE 2 -#define LEGAL_IRQ(x) ((x) >= 0 && (x) < ICU_LEN && (x) != IRQ_SLAVE) +#define LEGAL_HWIRQ_P(x) ((u_int)(x) < ICU_LEN && (x) != IRQ_SLAVE) #define I8259_INTR_NUM 16 #define OPENPIC_INTR_NUM ((ICU_LEN)-(I8259_INTR_NUM)) -#define PREP_INTR_REG 0xbffff000 -#define INTR_VECTOR_REG 0xff0 +#define PREP_INTR_REG 0xbffff000 +#define INTR_VECTOR_REG 0xff0 #endif /* !_LOCORE */ +#include <powerpc/intr.h> + #endif /* !_PREP_INTR_H_ */ Index: src/sys/arch/prep/pnpbus/if_we_pnpbus.c diff -u src/sys/arch/prep/pnpbus/if_we_pnpbus.c:1.5 src/sys/arch/prep/pnpbus/if_we_pnpbus.c:1.6 --- src/sys/arch/prep/pnpbus/if_we_pnpbus.c:1.5 Sat Mar 14 21:04:14 2009 +++ src/sys/arch/prep/pnpbus/if_we_pnpbus.c Fri Jun 17 23:36:18 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: if_we_pnpbus.c,v 1.5 2009/03/14 21:04:14 dsl Exp $ */ +/* $NetBSD: if_we_pnpbus.c,v 1.6 2011/06/17 23:36:18 matt Exp $ */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. @@ -49,7 +49,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_we_pnpbus.c,v 1.5 2009/03/14 21:04:14 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_we_pnpbus.c,v 1.6 2011/06/17 23:36:18 matt Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -238,7 +238,7 @@ /* some cards think they are level. force them to edge */ if (irq->flags & 0x0c) irq->flags = 0x01; - if (!LEGAL_IRQ(irqnum)) + if (!LEGAL_HWIRQ_P(irqnum)) continue; if (irqnum < 2) continue; Index: src/sys/arch/rs6000/include/intr.h diff -u src/sys/arch/rs6000/include/intr.h:1.4 src/sys/arch/rs6000/include/intr.h:1.5 --- src/sys/arch/rs6000/include/intr.h:1.4 Sat Nov 13 14:07:08 2010 +++ src/sys/arch/rs6000/include/intr.h Fri Jun 17 23:36:18 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.4 2010/11/13 14:07:08 uebayasi Exp $ */ +/* $NetBSD: intr.h,v 1.5 2011/06/17 23:36:18 matt Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -32,13 +32,12 @@ #ifndef _RS6000_INTR_H_ #define _RS6000_INTR_H_ -#include <powerpc/intr.h> - #ifndef _LOCORE -#include <machine/cpu.h> #define ICU_LEN 16 #endif /* _LOCORE */ +#include <powerpc/intr.h> + #endif /* _RS6000_INTR_H_ */ Index: src/sys/arch/sandpoint/include/intr.h diff -u src/sys/arch/sandpoint/include/intr.h:1.18 src/sys/arch/sandpoint/include/intr.h:1.19 --- src/sys/arch/sandpoint/include/intr.h:1.18 Sat Nov 13 14:07:08 2010 +++ src/sys/arch/sandpoint/include/intr.h Fri Jun 17 23:36:18 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.18 2010/11/13 14:07:08 uebayasi Exp $ */ +/* $NetBSD: intr.h,v 1.19 2011/06/17 23:36:18 matt Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -35,7 +35,6 @@ #include <powerpc/intr.h> #ifndef _LOCORE -#include <machine/cpu.h> void enable_intr(void); void disable_intr(void);