From 764da5a4611ca4142c8444b379fad5882328c7f6 Mon Sep 17 00:00:00 2001 From: tsutsui Date: Sat, 10 May 2003 09:46:24 +0000 Subject: [PATCH] - Prepare common structures for interrupt handler and share them between Hyper-bus and AP-bus. - Use LIST rather than static array for interrupt dispatcher. --- sys/arch/newsmips/apbus/apbus.c | 91 +++++++++++++++------------ sys/arch/newsmips/dev/hb.c | 89 +++++++++++++++----------- sys/arch/newsmips/dev/hbvar.h | 6 +- sys/arch/newsmips/dev/if_le.c | 9 ++- sys/arch/newsmips/dev/kb_hb.c | 4 +- sys/arch/newsmips/dev/ms_hb.c | 4 +- sys/arch/newsmips/dev/sc_wrap.c | 4 +- sys/arch/newsmips/dev/zs_hb.c | 5 +- sys/arch/newsmips/include/intr.h | 17 ++++- sys/arch/newsmips/newsmips/news3400.c | 8 +-- 10 files changed, 140 insertions(+), 97 deletions(-) diff --git a/sys/arch/newsmips/apbus/apbus.c b/sys/arch/newsmips/apbus/apbus.c index 6d9d17bc75ed..937491903fde 100644 --- a/sys/arch/newsmips/apbus/apbus.c +++ b/sys/arch/newsmips/apbus/apbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: apbus.c,v 1.14 2003/05/03 18:10:53 wiz Exp $ */ +/* $NetBSD: apbus.c,v 1.15 2003/05/10 09:46:24 tsutsui Exp $ */ /*- * Copyright (C) 1999 SHIMIZU Ryo. All rights reserved. @@ -38,6 +38,7 @@ #include #define _NEWSMIPS_BUS_DMA_PRIVATE #include +#include #include static int apbusmatch (struct device *, struct cfdata *, void *); @@ -71,21 +72,8 @@ struct apbus_softc { CFATTACH_DECL(ap, sizeof(struct apbus_softc), apbusmatch, apbusattach, NULL, NULL); -#define APBUS_DEVNAMELEN 16 - -struct ap_intrhand { - struct ap_intrhand *ai_next; - int ai_mask; - int ai_priority; - int (*ai_func) (void*); /* function */ - void *ai_aux; /* softc */ - char ai_name[APBUS_DEVNAMELEN]; - int ai_ctlno; -}; - #define NLEVEL 2 - -static struct ap_intrhand *apintr[NLEVEL]; +static struct newsmips_intr apintr_tab[NLEVEL]; static int apbusmatch(parent, cfdata, aux) @@ -111,6 +99,8 @@ apbusattach(parent, self, aux) struct apbus_attach_args child; struct apbus_dev *apdev; struct apbus_ctl *apctl; + struct newsmips_intr *ip; + int i; *(volatile u_int *)(NEWS5000_APBUS_INTST) = 0xffffffff; *(volatile u_int *)(NEWS5000_APBUS_INTMSK) = 0xffffffff; @@ -119,6 +109,11 @@ apbusattach(parent, self, aux) printf("\n"); + for (i = 0; i < NLEVEL; i++) { + ip = &apintr_tab[i]; + LIST_INIT(&ip->intr_q); + } + /* * get first ap-device */ @@ -202,13 +197,16 @@ apbus_intr_call(level, stat) int level; int stat; { - int nintr = 0; - struct ap_intrhand *ai; + struct newsmips_intr *ip; + struct newsmips_intrhand *ih; + int nintr; - for (ai = apintr[level]; ai != NULL; ai = ai->ai_next) { - if (ai->ai_mask & stat) { - nintr += (*ai->ai_func)(ai->ai_aux); - } + ip = &apintr_tab[level]; + + nintr = 0; + LIST_FOREACH(ih, &ip->intr_q, ih_q) { + if (ih->ih_mask & stat) + nintr += (*ih->ih_func)(ih->ih_arg); } return nintr; } @@ -217,45 +215,58 @@ apbus_intr_call(level, stat) * register device interrupt routine */ void * -apbus_intr_establish(level, mask, priority, func, aux, name, ctlno) +apbus_intr_establish(level, mask, priority, func, arg, name, ctlno) int level; int mask; int priority; int (*func) (void *); - void *aux; + void *arg; char *name; int ctlno; { - struct ap_intrhand *ai, **aip; - volatile unsigned int *inten0 = (volatile unsigned int *)NEWS5000_INTEN0; - volatile unsigned int *inten1 = (volatile unsigned int *)NEWS5000_INTEN1; + struct newsmips_intr *ip; + struct newsmips_intrhand *ih, *curih; + volatile u_int32_t *inten0, *inten1; - ai = malloc(sizeof(*ai), M_DEVBUF, M_NOWAIT); - if (ai == NULL) + ip = &apintr_tab[level]; + + ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT); + if (ih == NULL) panic("apbus_intr_establish: can't malloc handler info"); - ai->ai_mask = mask; - ai->ai_priority = priority; - ai->ai_func = func; - ai->ai_aux = aux; - strncpy(ai->ai_name, name, APBUS_DEVNAMELEN-1); - ai->ai_ctlno = ctlno; + ih->ih_mask = mask; + ih->ih_priority = priority; + ih->ih_func = func; + ih->ih_arg = arg; - for (aip = &apintr[level]; *aip != NULL; aip = &(*aip)->ai_next) { - if ((*aip)->ai_priority < priority) - break; + if (LIST_EMPTY(&ip->intr_q)) { + LIST_INSERT_HEAD(&ip->intr_q, ih, ih_q); + goto done; } - ai->ai_next = *aip; - *aip = ai; + + for (curih = LIST_FIRST(&ip->intr_q); + LIST_NEXT(curih, ih_q) != NULL; + curih = LIST_NEXT(curih, ih_q)) { + if (ih->ih_priority > curih->ih_priority) { + LIST_INSERT_BEFORE(curih, ih, ih_q); + goto done; + } + } + + LIST_INSERT_AFTER(curih, ih, ih_q); + + done: switch (level) { case 0: + inten0 = (volatile u_int32_t *)NEWS5000_INTEN0; *inten0 |= mask; break; case 1: + inten1 = (volatile u_int32_t *)NEWS5000_INTEN1; *inten1 |= mask; break; } - return (void *)ai; + return (void *)ih; } static void diff --git a/sys/arch/newsmips/dev/hb.c b/sys/arch/newsmips/dev/hb.c index 0b4043c6edb4..925e43c9d844 100644 --- a/sys/arch/newsmips/dev/hb.c +++ b/sys/arch/newsmips/dev/hb.c @@ -1,10 +1,12 @@ -/* $NetBSD: hb.c,v 1.11 2003/05/09 13:36:40 tsutsui Exp $ */ +/* $NetBSD: hb.c,v 1.12 2003/05/10 09:46:25 tsutsui Exp $ */ #include #include #include +#include #include +#include #include @@ -18,13 +20,8 @@ CFATTACH_DECL(hb, sizeof(struct device), extern struct cfdriver hb_cd; -struct intrhand { - int (*func) __P((void *)); - void *arg; -}; - -#define NHBINTR 4 -struct intrhand hb_intrhand[6][NHBINTR]; +#define NLEVEL 4 +static struct newsmips_intr hbintr_tab[NLEVEL]; static int hb_match(parent, cf, aux) @@ -47,9 +44,17 @@ hb_attach(parent, self, aux) void *aux; { struct hb_attach_args ha; + struct newsmips_intr *ip; + int i; printf("\n"); + memset(&ha, 0, sizeof(ha)); + for (i = 0; i < NLEVEL; i++) { + ip = &hbintr_tab[i]; + LIST_INIT(&ip->intr_q); + } + config_search(hb_search, self, &ha); } @@ -93,50 +98,58 @@ hb_print(args, name) } void * -hb_intr_establish(irq, level, func, arg) - int irq, level; +hb_intr_establish(level, mask, priority, func, arg) + int level, mask, priority; int (*func) __P((void *)); void *arg; { - struct intrhand *ih = hb_intrhand[irq]; - int i; + struct newsmips_intr *ip; + struct newsmips_intrhand *ih, *curih; - for (i = NHBINTR; i > 0; i--) { - if (ih->func == NULL) - goto found; - ih++; + ip = &hbintr_tab[level]; + + ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT); + if (ih == NULL) + panic("hb_intr_establish: malloc failed"); + + ih->ih_func = func; + ih->ih_arg = arg; + ih->ih_level = level; + ih->ih_mask = mask; + ih->ih_priority = priority; + + if (LIST_EMPTY(&ip->intr_q)) { + LIST_INSERT_HEAD(&ip->intr_q, ih, ih_q); + goto done; } - panic("hb_intr_establish: no room"); -found: - ih->func = func; - ih->arg = arg; - -#ifdef HB_DEBUG - for (irq = 0; irq <= 2; irq++) { - for (i = 0; i < NHBINTR; i++) { - printf("%p(%p) ", - hb_intrhand[irq][i].func, - hb_intrhand[irq][i].arg); + for (curih = LIST_FIRST(&ip->intr_q); + LIST_NEXT(curih, ih_q) != NULL; + curih = LIST_NEXT(curih, ih_q)) { + if (ih->ih_priority > curih->ih_priority) { + LIST_INSERT_BEFORE(curih, ih, ih_q); + goto done; } - printf("\n"); } -#endif + LIST_INSERT_AFTER(curih, ih, ih_q); + + done: return ih; } void -hb_intr_dispatch(irq) - int irq; +hb_intr_dispatch(level, stat) + int level; + int stat; { - struct intrhand *ih; - int i; + struct newsmips_intr *ip; + struct newsmips_intrhand *ih; - ih = hb_intrhand[irq]; - for (i = NHBINTR; i > 0; i--) { - if (ih->func) - (*ih->func)(ih->arg); - ih++; + ip = &hbintr_tab[level]; + + LIST_FOREACH(ih, &ip->intr_q, ih_q) { + if (ih->ih_mask & stat) + (*ih->ih_func)(ih->ih_arg); } } diff --git a/sys/arch/newsmips/dev/hbvar.h b/sys/arch/newsmips/dev/hbvar.h index 990e8549095e..faba87a14707 100644 --- a/sys/arch/newsmips/dev/hbvar.h +++ b/sys/arch/newsmips/dev/hbvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: hbvar.h,v 1.1 2003/05/09 13:36:40 tsutsui Exp $ */ +/* $NetBSD: hbvar.h,v 1.2 2003/05/10 09:46:25 tsutsui Exp $ */ /* * Copyright (C) 2003 Izumi Tsutsui. All rights reserved. @@ -42,5 +42,5 @@ struct hb_attach_args { #define hb_badaddr news3400_badaddr -void *hb_intr_establish(int, int, int (*)(void *), void *); -void hb_intr_dispatch(int); +void *hb_intr_establish(int, int, int, int (*)(void *), void *); +void hb_intr_dispatch(int, int); diff --git a/sys/arch/newsmips/dev/if_le.c b/sys/arch/newsmips/dev/if_le.c index f70a889aa8e0..6826c9996f94 100644 --- a/sys/arch/newsmips/dev/if_le.c +++ b/sys/arch/newsmips/dev/if_le.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_le.c,v 1.10 2003/05/09 13:36:40 tsutsui Exp $ */ +/* $NetBSD: if_le.c,v 1.11 2003/05/10 09:46:25 tsutsui Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -154,7 +154,7 @@ le_attach(parent, self, aux) struct le_softc *lesc = (struct le_softc *)self; struct lance_softc *sc = &lesc->sc_am7990.lsc; struct hb_attach_args *ha = aux; - int intlevel; + int intlevel, intmask; u_char *p; intlevel = ha->ha_level; @@ -169,14 +169,17 @@ le_attach(parent, self, aux) case LANCE_PORT: sc->sc_mem = (void *)LANCE_MEMORY; p = (u_char *)(ETHER_ID+16); + intmask = INTST1_LANCE; break; case LANCE_PORT1: sc->sc_mem = (void *)LANCE_MEMORY1; p = (u_char *)(ETHER_ID1+16); + intmask = INTST1_SLOT3; /* XXX not tested */ break; case LANCE_PORT2: sc->sc_mem = (void *)LANCE_MEMORY2; p = (u_char *)(ETHER_ID2+16); + intmask = INTST1_SLOT3; /* XXX not tested */ break; default: @@ -214,5 +217,5 @@ le_attach(parent, self, aux) sc->sc_hwinit = NULL; am7990_config(&lesc->sc_am7990); - hb_intr_establish(intlevel, IPL_NET, am7990_intr, sc); + hb_intr_establish(intlevel, intmask, IPL_NET, am7990_intr, sc); } diff --git a/sys/arch/newsmips/dev/kb_hb.c b/sys/arch/newsmips/dev/kb_hb.c index 80c8af2c0912..4d109c02c241 100644 --- a/sys/arch/newsmips/dev/kb_hb.c +++ b/sys/arch/newsmips/dev/kb_hb.c @@ -1,4 +1,4 @@ -/* $NetBSD: kb_hb.c,v 1.5 2003/05/09 13:36:40 tsutsui Exp $ */ +/* $NetBSD: kb_hb.c,v 1.6 2003/05/10 09:46:25 tsutsui Exp $ */ /*- * Copyright (c) 2000 Tsubai Masanari. All rights reserved. @@ -129,7 +129,7 @@ kb_hb_attach(parent, self, aux) } printf("\n"); - hb_intr_establish(intr, IPL_TTY, kb_hb_intr, sc); + hb_intr_establish(intr, INTEN0_KBDINT, IPL_TTY, kb_hb_intr, sc); aa.console = cons; aa.keymap = &kb_hb_keymapdata; diff --git a/sys/arch/newsmips/dev/ms_hb.c b/sys/arch/newsmips/dev/ms_hb.c index 498e40999cd1..f9c97a7f0054 100644 --- a/sys/arch/newsmips/dev/ms_hb.c +++ b/sys/arch/newsmips/dev/ms_hb.c @@ -1,4 +1,4 @@ -/* $NetBSD: ms_hb.c,v 1.6 2003/05/10 03:57:28 tsutsui Exp $ */ +/* $NetBSD: ms_hb.c,v 1.7 2003/05/10 09:46:25 tsutsui Exp $ */ /*- * Copyright (c) 2000 Tsubai Masanari. All rights reserved. @@ -107,7 +107,7 @@ ms_hb_attach(parent, self, aux) printf(" level %d\n", intr); - hb_intr_establish(intr, IPL_TTY, ms_hb_intr, sc); + hb_intr_establish(intr, INTEN0_MSINT, IPL_TTY, ms_hb_intr, sc); aa.accessops = &ms_hb_accessops; aa.accesscookie = sc; diff --git a/sys/arch/newsmips/dev/sc_wrap.c b/sys/arch/newsmips/dev/sc_wrap.c index 491788974850..6c77ac5c4e36 100644 --- a/sys/arch/newsmips/dev/sc_wrap.c +++ b/sys/arch/newsmips/dev/sc_wrap.c @@ -1,4 +1,4 @@ -/* $NetBSD: sc_wrap.c,v 1.23 2003/05/09 13:36:40 tsutsui Exp $ */ +/* $NetBSD: sc_wrap.c,v 1.24 2003/05/10 09:46:25 tsutsui Exp $ */ /* * This driver is slow! Need to rewrite. @@ -125,7 +125,7 @@ cxd1185_attach(parent, self, aux) cxd1185_init(sc); DELAY(100000); - hb_intr_establish(intlevel, IPL_BIO, sc_intr, sc); + hb_intr_establish(intlevel, INTEN1_DMA, IPL_BIO, sc_intr, sc); config_found(&sc->sc_dev, &sc->sc_channel, scsiprint); } diff --git a/sys/arch/newsmips/dev/zs_hb.c b/sys/arch/newsmips/dev/zs_hb.c index 0d144429ff74..47ffbc89510b 100644 --- a/sys/arch/newsmips/dev/zs_hb.c +++ b/sys/arch/newsmips/dev/zs_hb.c @@ -1,4 +1,4 @@ -/* $NetBSD: zs_hb.c,v 1.14 2003/05/10 03:27:33 tsutsui Exp $ */ +/* $NetBSD: zs_hb.c,v 1.15 2003/05/10 09:46:25 tsutsui Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -296,7 +296,8 @@ zs_hb_attach(parent, self, aux) if (!didintr) { didintr = 1; - hb_intr_establish(intlevel, IPL_SERIAL, zshard_hb, NULL); + hb_intr_establish(intlevel, INTST1_SCC, IPL_SERIAL, + zshard_hb, NULL); } /* XXX; evcnt_attach() ? */ diff --git a/sys/arch/newsmips/include/intr.h b/sys/arch/newsmips/include/intr.h index be57264c1938..9691258d1b98 100644 --- a/sys/arch/newsmips/include/intr.h +++ b/sys/arch/newsmips/include/intr.h @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.11 2001/04/13 23:30:02 thorpej Exp $ */ +/* $NetBSD: intr.h,v 1.12 2003/05/10 09:46:25 tsutsui Exp $ */ /* * Copyright (c) 1998 Jonathan Stone. All rights reserved. @@ -44,6 +44,7 @@ #ifdef _KERNEL #ifndef _LOCORE +#include #include extern int _splraise __P((int)); @@ -102,6 +103,20 @@ extern void _clrsoftintr __P((int)); #define splsoftnet() _splraise(MIPS_INT_MASK_SPL_SOFT1) #define spllowersoftclock() _spllower(MIPS_INT_MASK_SPL_SOFT0) +struct newsmips_intrhand { + LIST_ENTRY(newsmips_intrhand) ih_q; + struct evcnt intr_count; + int (*ih_func)(void *); + void *ih_arg; + u_int ih_level; + u_int ih_mask; + u_int ih_priority; +}; + +struct newsmips_intr { + LIST_HEAD(,newsmips_intrhand) intr_q; +}; + /* * Index into intrcnt[], which is defined in locore */ diff --git a/sys/arch/newsmips/newsmips/news3400.c b/sys/arch/newsmips/newsmips/news3400.c index c32aeab5d6ab..46f87bca4430 100644 --- a/sys/arch/newsmips/newsmips/news3400.c +++ b/sys/arch/newsmips/newsmips/news3400.c @@ -1,4 +1,4 @@ -/* $NetBSD: news3400.c,v 1.10 2003/05/09 13:36:42 tsutsui Exp $ */ +/* $NetBSD: news3400.c,v 1.11 2003/05/10 09:46:26 tsutsui Exp $ */ /*- * Copyright (C) 1999 Tsubai Masanari. All rights reserved. @@ -84,7 +84,7 @@ news3400_intr(status, cause, pc, ipending) } if (stat) - hb_intr_dispatch(2); + hb_intr_dispatch(2, stat); cause &= ~MIPS_INT_MASK_2; } @@ -142,7 +142,7 @@ news3400_level0_intr() stat = *intst1 & LEVEL0_MASK; *intclr1 = stat; - hb_intr_dispatch(0); + hb_intr_dispatch(0, stat); if (stat & INTST1_SLOT1) intrcnt[SLOT1_INTR]++; @@ -170,7 +170,7 @@ news3400_level1_intr() stat1 &= saved_inten1; - hb_intr_dispatch(1); + hb_intr_dispatch(1, stat1); *inten1 = saved_inten1;