Date: Thu, 12 Apr 2007 12:28:03 GMT From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 117957 for review Message-ID: <200704121228.l3CCS3XW081420@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=117957 Change 117957 by gonzo@gonzo_jeeves on 2007/04/12 12:27:08 o Migrate on new inetrrupt filtering API. o Replace "magic numbers" with named constants and export them through genassym.c. Affected files ... .. //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#3 edit .. //depot/projects/mips2/src/sys/mips/mips/cpu.c#18 edit .. //depot/projects/mips2/src/sys/mips/mips/genassym.c#7 edit .. //depot/projects/mips2/src/sys/mips/mips/intr_machdep.c#3 edit .. //depot/projects/mips2/src/sys/mips/mips/nexus.c#4 edit .. //depot/projects/mips2/src/sys/mips/mips/tick.c#5 edit .. //depot/projects/mips2/src/sys/mips/mips4k/malta/gt_pci.c#5 edit Differences ... ==== //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#3 (text+ko) ==== @@ -23,26 +23,21 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#2 $ + * $P4: //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#3 $ */ #ifndef _MACHINE_INTR_H_ #define _MACHINE_INTR_H_ +#define NHARD_IRQS 6 +#define NSOFT_IRQS 2 + struct trapframe; -/* - * Include the platform-specific MD interrupt header. - */ -/* - * XXXMIPS: We don't have this file. - */ -#if 0 -#include <platform/intr.h> -#endif - -void cpu_establish_hardintr(int, void (*)(void *), void *); -void cpu_establish_softintr(int, void (*)(void *), void *); +void cpu_establish_hardintr(const char *, int (*)(void*), void (*)(void*), + void *, int, int, void **); +void cpu_establish_softintr(const char *, int (*)(void*), void (*)(void*), + void *, int, int, void **); void cpu_intr(struct trapframe *); #endif /* !_MACHINE_INTR_H_ */ ==== //depot/projects/mips2/src/sys/mips/mips/cpu.c#18 (text+ko) ==== @@ -83,6 +83,9 @@ size_t len, max; max = 0x80; + if(bootverbose) + printf("Installing exception vector:\n\t[%p..%p] <- [%p..%p]\n", + (void *)addr, (void *)(addr+max), begin, end); len = end - begin; if (len > max) panic("exception code too big for vector %jx", (intmax_t) addr); @@ -263,7 +266,8 @@ static struct resource *cpu_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int cpu_setup_intr(device_t, device_t, struct resource *, int, - driver_intr_t *, void *, void **); + driver_filter_t *f, driver_intr_t *, void *, + void **); static device_method_t cpu_methods[] = { /* Device interface */ @@ -345,7 +349,8 @@ static int cpu_setup_intr(device_t dev, device_t child, struct resource *res, int flags, - driver_intr_t *handler, void *arg, void **cookiep) + driver_filter_t *filt, driver_intr_t *handler, void *arg, + void **cookiep) { int error; int intr; @@ -358,7 +363,8 @@ intr = rman_get_start(res); - cpu_establish_hardintr(intr, handler, arg); + cpu_establish_hardintr(device_get_nameunit(child), filt, handler, arg, + intr, flags, cookiep); device_printf(child, "established CPU interrupt %d\n", intr); return (0); } ==== //depot/projects/mips2/src/sys/mips/mips/genassym.c#7 (text+ko) ==== @@ -60,6 +60,7 @@ #include <net/if.h> #include <netinet/in.h> +#include <machine/intr_machdep.h> #include <machine/locore.h> #include <machine/pcb.h> #include <machine/reg.h> @@ -67,6 +68,7 @@ ASSYM(MIPS_KSEG0_START, MIPS_KSEG0_START); ASSYM(MIPS_KSSEG_START, MIPS_KSSEG_START); ASSYM(MIPS_PG_G, PG_G); + ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread)); ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb)); @@ -76,7 +78,6 @@ ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); - ASSYM(TD_FRAME, offsetof(struct thread, td_frame)); ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack)); ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); @@ -191,3 +192,6 @@ ASSYM(VM_MIN_KERNEL_ADDRESS, VM_MIN_KERNEL_ADDRESS); ASSYM(VM_MAX_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS); +ASSYM(NHARD_IRQS, NHARD_IRQS); +ASSYM(NSOFT_IRQS, NSOFT_IRQS); +ASSYM(MAXCOMLEN, MAXCOMLEN); ==== //depot/projects/mips2/src/sys/mips/mips/intr_machdep.c#3 (text+ko) ==== @@ -32,6 +32,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/bus.h> +#include <sys/interrupt.h> #include <machine/cpu.h> #include <machine/cpufunc.h> @@ -42,53 +43,87 @@ #include <machine/md_var.h> #include <machine/trap.h> -struct intrhand { - void (*handler)(void *); - void *arg; -}; -static struct intrhand intrhard[6]; -static struct intrhand intrsoft[2]; +static struct intr_event *hardintr_events[NHARD_IRQS]; +static struct intr_event *softintr_events[NSOFT_IRQS]; + +#ifdef notyet +static int intrcnt_tab[NHARD_IRQS + NSOFT_IRQS]; +static int intrcnt_index = 0; +static int last_printed = 0; +#endif void -cpu_establish_hardintr(int intr, void (*handler)(void *), void *arg) +cpu_establish_hardintr(const char *name, driver_filter_t *filt, + void (*handler)(void*), void *arg, int irq, int flags, + void **cookiep) { - struct intrhand *ih; + struct intr_event *event; + int error; + + if (irq < 0 || irq > NHARD_IRQS) + panic("%s called for unknown hard intr %d", __func__, irq); + + event = hardintr_events[irq]; + if (event == NULL) { + error = intr_event_create(&event, (void *)irq, 0, + (void (*)(void *))NULL, "hard intr%d:", irq); + if (error) + return; + hardintr_events[irq] = event; +#ifdef notyet + last_printed += + snprintf(intrnames + last_printed, + MAXCOMLEN + 1, + "hard irq%d: %s", irq, name); + last_printed++; + intrcnt_tab[irq] = intrcnt_index; + intrcnt_index++; +#endif + + } - if (intr < 0 || intr > 5) - panic("%s called for unknown hard intr %d", __func__, intr); - ih = &intrhard[intr]; - if (ih->handler != NULL && ih->handler != handler) - panic("%s cannot share hard intr %d", __func__, intr); - ih->handler = handler; - ih->arg = arg; + intr_event_add_handler(event, name, filt, handler, arg, + intr_priority(flags), flags, cookiep); - mips_wr_status(mips_rd_status() | (((1<< intr) << 8) << 2)); + mips_wr_status(mips_rd_status() | (((1<< irq) << 8) << 2)); } void -cpu_establish_softintr(int intr, void (*handler)(void *), void *arg) +cpu_establish_softintr(const char *name, driver_filter_t *filt, + void (*handler)(void*), void *arg, int irq, int flags, + void **cookiep) { - struct intrhand *ih; + struct intr_event *event; + int error; + + if (irq < 0 || irq > NSOFT_IRQS) + panic("%s called for unknown hard intr %d", __func__, irq); + + event = softintr_events[irq]; + if (event == NULL) { + error = intr_event_create(&event, (void *)irq, 0, + (void (*)(void *))NULL, "intr%d:", irq); + if (error) + return; + softintr_events[irq] = event; + } - if (intr < 0 || intr > 1) - panic("%s called for unknown soft intr %d", __func__, intr); - ih = &intrsoft[intr]; - if (ih->handler != NULL && ih->handler != handler) - panic("%s cannot share soft intr %d", __func__, intr); - ih->handler = handler; - ih->arg = arg; + intr_event_add_handler(event, name, filt, handler, arg, + intr_priority(flags), flags, cookiep); - mips_wr_status(mips_rd_status() | ((1 << intr) << 8)); + mips_wr_status(mips_rd_status() | (((1<< irq) << 8))); } void cpu_intr(struct trapframe *tf) { - struct intrhand *ih; + struct intr_handler *ih; + struct intr_event *event; register_t cause; int hard; int intr; int i; + int thread; critical_enter(); @@ -104,25 +139,39 @@ /* Software interrupt. */ i--; /* Get a 0-offset interrupt. */ hard = 0; - ih = &intrsoft[i]; + event = softintr_events[i]; break; default: /* Hardware interrupt. */ i -= 2; /* Trim software interrupt bits. */ i--; /* Get a 0-offset interrupt. */ hard = 1; - ih = &intrhard[i]; + event = hardintr_events[i]; break; } - if (ih->handler != NULL) { - if (ih->arg == NULL) - (*ih->handler)(tf); + + if (!event || TAILQ_EMPTY(&event->ie_handlers)) + { + printf("stray %s interrupt %d\n", + hard ? "hard" : "soft", i); + continue; + } + + /* Execute fast handlers. */ + thread = 0; + TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) { + if (ih->ih_filter == NULL) + thread = 1; else - (*ih->handler)(ih->arg); - } else - printf("stray %s interrupt %d\n", - hard ? "hard" : "soft", i); + ih->ih_filter(ih->ih_argument ? + ih->ih_argument : tf); + } + + /* Schedule thread if needed. */ + if (thread) + intr_event_schedule_thread(event); } + KASSERT(i == 0, ("all interrupts handled")); critical_exit(); ==== //depot/projects/mips2/src/sys/mips/mips/nexus.c#4 (text+ko) ==== @@ -80,7 +80,7 @@ struct resource *); static int nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, - driver_intr_t *intr, void *arg, void **cookiep); + driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep); static int nexus_teardown_intr(device_t, device_t, struct resource *, void *); @@ -124,7 +124,7 @@ static int nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, - driver_intr_t *intr, void *arg, void **cookiep) + driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { int irq; @@ -132,7 +132,9 @@ irq = rman_get_start(res); if(irq > 5) return(0); - cpu_establish_hardintr(irq, intr, arg); + + cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg, + irq, flags, cookiep); intr_restore(sr); return (0); } ==== //depot/projects/mips2/src/sys/mips/mips/tick.c#5 (text+ko) ==== @@ -203,7 +203,6 @@ /* * Set next clock edge. */ - mips_wr_compare(mips_rd_count() + counter_freq / hz); /* @@ -218,7 +217,7 @@ hardclock(usermode, pc); } - return (FILTER_HANDLED); + return FILTER_HANDLED; } static int @@ -250,9 +249,10 @@ device_printf(dev, "failed to allocate irq\n"); return (ENXIO); } - error = bus_setup_intr(dev, irq, - INTR_TYPE_CLK | INTR_MPSAFE | INTR_FAST, - clock_intr, NULL, NULL, NULL); + + error = bus_setup_intr(dev, irq, INTR_TYPE_CLK, clock_intr, NULL, + NULL, NULL); + if (error != 0) { device_printf(dev, "bus_setup_intr returned %d\n", error); return (error); ==== //depot/projects/mips2/src/sys/mips/mips4k/malta/gt_pci.c#5 (text+ko) ==== @@ -46,6 +46,7 @@ #include <sys/systm.h> #include <sys/bus.h> +#include <sys/interrupt.h> #include <sys/malloc.h> #include <sys/kernel.h> #include <sys/module.h> @@ -90,17 +91,6 @@ #define OCW3_POLL_IRQ(x) ((x) & 0x7f) #define OCW3_POLL_PENDING (1U << 7) -struct intrhand { - LIST_ENTRY(intrhand) ih_list; - driver_intr_t *ih_func; - void *ih_arg; - int ih_irq; -}; - -struct pci_intrhead { - LIST_HEAD(, intrhand) intr_list; -}; - struct gt_pci_softc { device_t sc_dev; bus_space_tag_t sc_st; @@ -118,7 +108,7 @@ uint32_t sc_io; struct resource *sc_irq; - struct pci_intrhead sc_intrtab[ICU_LEN]; + struct intr_event *sc_eventstab[ICU_LEN]; uint16_t sc_imask; uint16_t sc_elcr; @@ -151,8 +141,9 @@ gt_pci_intr(void *v) { struct gt_pci_softc *sc = v; - struct intrhand *ih; - int irq; + struct intr_event *event; + struct intr_handler *ih; + int irq, thread; for (;;) { bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW3, @@ -176,8 +167,23 @@ irq = 2; } - LIST_FOREACH(ih, &sc->sc_intrtab[irq].intr_list, ih_list) - (*ih->ih_func)(ih->ih_arg); + event = sc->sc_eventstab[irq]; + thread = 0; + + if (event && !TAILQ_EMPTY(&event->ie_handlers)) + { + /* Execute fast handlers. */ + TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) { + if (ih->ih_filter == NULL) + thread = 1; + else + ih->ih_filter(ih->ih_argument); + } + } + + /* Schedule thread if needed. */ + if (thread) + intr_event_schedule_thread(event); /* Send a specific EOI to the 8259. */ if (irq > 7) { @@ -192,8 +198,6 @@ } } - - static int gt_pci_probe(device_t dev) { @@ -205,9 +209,9 @@ gt_pci_attach(device_t dev) { - uint32_t busno; + uint32_t busno; struct gt_pci_softc *sc = device_get_softc(dev); - int rid, i; + int rid; busno = 0; sc->sc_dev = dev; @@ -270,7 +274,7 @@ ICW1_RESET | ICW1_IC4); /* * XXX: values from NetBSD's <dev/ic/i8259reg.h> - */ + */ bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1, 0/*XXX*/); bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1, @@ -338,30 +342,20 @@ (1U << 14) | /* IDE primary */ (1U << 15); /* IDE secondary */ - /* Initialize our interrupt table. */ - for (i = 0; i < ICU_LEN; i++) { - LIST_INIT(&sc->sc_intrtab[i].intr_list); - } - /* Hook up our interrupt handler. */ - if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, + if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, MALTA_SOUTHBRIDGE_INTR, MALTA_SOUTHBRIDGE_INTR, 1, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "unable to allocate IRQ resource\n"); return ENXIO; - } + } - if ((bus_setup_intr(dev, sc->sc_irq, INTR_FAST | INTR_MPSAFE, - NULL, gt_pci_intr, sc, &sc->sc_ih))) { + if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, + NULL, gt_pci_intr, sc, &sc->sc_ih))) { device_printf(dev, "WARNING: unable to register interrupt handler\n"); return ENXIO; - } - - if (sc->sc_ih == NULL) - - - + } /* Initialize memory and i/o rmans. */ device_add_child(dev, "pci", busno); @@ -392,8 +386,8 @@ uint32_t addr; uint32_t shift, mask; - if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr)) - return (uint32_t)(-1); + if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr)) + return (uint32_t)(-1); /* Clear cause register bits. */ GT_REGVAL(GT_INTR_CAUSE) = 0; @@ -644,37 +638,36 @@ } static int -gt_pci_setup_intr(device_t dev, device_t child, - struct resource *ires, int flags, driver_intr_t *intr, void *arg, - void **cookiep) +gt_pci_setup_intr(device_t dev, device_t child, struct resource *ires, + int flags, driver_filter_t *filt, driver_intr_t *handler, + void *arg, void **cookiep) { struct gt_pci_softc *sc = device_get_softc(dev); - struct intrhand *ih; - int irq; + struct intr_event *event; + int irq, error; irq = rman_get_start(ires); if (irq >= ICU_LEN || irq == 2) panic("%s: bad irq or type", __func__); - ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT); - if (ih == NULL) - return ENOMEM; + event = sc->sc_eventstab[irq]; + if (event == NULL) { + error = intr_event_create(&event, (void *)irq, 0, + (void (*)(void *))NULL, "gt_pci intr%d:", irq); + if (error) + return 0; + sc->sc_eventstab[irq] = event; + } - ih->ih_func = intr; - ih->ih_arg = arg; - ih->ih_irq = irq; + intr_event_add_handler(event, device_get_nameunit(child), filt, + handler, arg, intr_priority(flags), flags, cookiep); - /* Insert the handler into the table. */ - LIST_INSERT_HEAD(&sc->sc_intrtab[irq].intr_list, ih, ih_list); - /* Enable it, set trigger mode. */ sc->sc_imask &= ~(1 << irq); sc->sc_elcr &= ~(1 << irq); gt_pci_set_icus(sc); - *cookiep = (void *)ih; - return 0; } @@ -682,19 +675,7 @@ gt_pci_teardown_intr(device_t dev, device_t child, struct resource *res, void *cookie) { - struct gt_pci_softc *sc = device_get_softc(dev); - struct intrhand *ih = cookie; - LIST_REMOVE(ih, ih_list); - - /* If there are no more handlers on this IRQ, disable it. */ - if (LIST_FIRST(&sc->sc_intrtab[ih->ih_irq].intr_list) == NULL) { - sc->sc_imask |= (1 << ih->ih_irq); - gt_pci_set_icus(sc); - } - - free(ih, M_DEVBUF); - - return 0; + return (intr_event_remove_handler(cookie)); } static device_method_t gt_pci_methods[] = {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200704121228.l3CCS3XW081420>