- Prepare common structures for interrupt handler and share them between
Hyper-bus and AP-bus. - Use LIST rather than static array for interrupt dispatcher.
This commit is contained in:
parent
a85b205894
commit
764da5a461
|
@ -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 <machine/autoconf.h>
|
||||
#define _NEWSMIPS_BUS_DMA_PRIVATE
|
||||
#include <machine/bus.h>
|
||||
#include <machine/intr.h>
|
||||
#include <newsmips/apbus/apbusvar.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -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 <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <newsmips/dev/hbvar.h>
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() ? */
|
||||
|
||||
|
|
|
@ -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 <sys/device.h>
|
||||
#include <mips/cpuregs.h>
|
||||
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue