diff --git a/sys/arch/hpcmips/hpcmips/interrupt.c b/sys/arch/hpcmips/hpcmips/interrupt.c index 3796784cece8..88342b48d3e7 100644 --- a/sys/arch/hpcmips/hpcmips/interrupt.c +++ b/sys/arch/hpcmips/hpcmips/interrupt.c @@ -1,4 +1,4 @@ -/* $NetBSD: interrupt.c,v 1.3 2001/09/15 19:51:38 uch Exp $ */ +/* $NetBSD: interrupt.c,v 1.4 2001/09/23 14:32:52 uch Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -44,97 +44,10 @@ #include -#include /* mips3_cp0_*() */ #include -#ifdef DEBUG -#define STATIC -#else -#define STATIC static -#endif - -#if defined(VR41XX) && defined(TX39XX) -STATIC void (*__cpu_intr)(u_int32_t, u_int32_t, u_int32_t, u_int32_t); -#define VR_INTR vr_intr -#define TX_INTR tx_intr -#elif defined(VR41XX) -#define VR_INTR cpu_intr -#elif defined(TX39XX) -#define TX_INTR cpu_intr -#endif - -/* - * This is a mask of bits to clear in the SR when we go to a - * given interrupt priority level. - */ -#ifdef VR41XX -const u_int32_t __ipl_sr_bits_vr[_IPL_N] = { - 0, /* IPL_NONE */ - - MIPS_SOFT_INT_MASK_0, /* IPL_SOFT */ - - MIPS_SOFT_INT_MASK_0, /* IPL_SOFTCLOCK */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1, /* IPL_SOFTNET */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1, /* IPL_SOFTSERIAL */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1| - MIPS_INT_MASK_0, /* IPL_BIO */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1| - MIPS_INT_MASK_0, /* IPL_NET */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1| - MIPS_INT_MASK_0, /* IPL_{TTY,SERIAL} */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1| - MIPS_INT_MASK_0| - MIPS_INT_MASK_1, /* IPL_{CLOCK,HIGH} */ -}; -#endif /* VR41XX */ - -#ifdef TX39XX -const u_int32_t __ipl_sr_bits_tx[_IPL_N] = { - 0, /* IPL_NONE */ - - MIPS_SOFT_INT_MASK_0, /* IPL_SOFT */ - - MIPS_SOFT_INT_MASK_0, /* IPL_SOFTCLOCK */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1, /* IPL_SOFTNET */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1, /* IPL_SOFTSERIAL */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1| - MIPS_INT_MASK_2| - MIPS_INT_MASK_4, /* IPL_BIO */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1| - MIPS_INT_MASK_2| - MIPS_INT_MASK_4, /* IPL_NET */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1| - MIPS_INT_MASK_2| - MIPS_INT_MASK_4, /* IPL_{TTY,SERIAL} */ - - MIPS_SOFT_INT_MASK_0| - MIPS_SOFT_INT_MASK_1| - MIPS_INT_MASK_2| - MIPS_INT_MASK_4, /* IPL_{CLOCK,HIGH} */ -}; -#endif /* TX39XX */ +extern const u_int32_t __ipl_sr_bits_vr[]; +extern const u_int32_t __ipl_sr_bits_tx[]; const u_int32_t ipl_si_to_sr[_IPL_NSOFT] = { MIPS_SOFT_INT_MASK_0, /* IPL_SOFT */ @@ -146,7 +59,6 @@ const u_int32_t ipl_si_to_sr[_IPL_NSOFT] = { const u_int32_t *ipl_sr_bits; struct hpcmips_soft_intrhand *softnet_intrhand; struct hpcmips_soft_intr hpcmips_soft_intrs[_IPL_NSOFT]; -STATIC void softintr(u_int32_t); void intr_init() @@ -162,49 +74,22 @@ intr_init() } #if defined(VR41XX) && defined(TX39XX) +/* + * cpu_intr: + * + * handle MIPS CPU interrupt. + * if VR41XX only or TX39XX only kernel, directly jump to each handler + * (tx/tx39icu.c, vr/vr.c), don't use this dispather. + * + */ void cpu_intr(u_int32_t status, u_int32_t cause, u_int32_t pc, u_int32_t ipending) { - (*__cpu_intr)(status, caust, pc, ipending); + (*platform.cpu_intr)(status, cause, pc, ipending); } #endif /* VR41XX && TX39XX */ -#ifdef VR41XX -void -VR_INTR(u_int32_t status, u_int32_t cause, u_int32_t pc, u_int32_t ipending) -{ - uvmexp.intrs++; - - if (ipending & MIPS_INT_MASK_5) { - /* - * Writing a value to the Compare register, - * as a side effect, clears the timer - * interrupt request. - */ - mips3_cp0_compare_write(mips3_cp0_count_read()); - } - - if (ipending & MIPS3_HARD_INT_MASK) - _splset((*platform.iointr)(status, cause, pc, ipending)); - - softintr(ipending); -} -#endif /* VR41XX */ - -#ifdef TX39XX -void -TX_INTR(u_int32_t status, u_int32_t cause, u_int32_t pc, u_int32_t ipending) -{ - uvmexp.intrs++; - - if (ipending & MIPS_HARD_INT_MASK) - _splset((*platform.iointr)(status, cause, pc, ipending)); - - softintr(ipending); -} -#endif /* TX39XX */ - /* * softintr: * diff --git a/sys/arch/hpcmips/include/intr.h b/sys/arch/hpcmips/include/intr.h index 283069bc990c..9c7ffe82f8df 100644 --- a/sys/arch/hpcmips/include/intr.h +++ b/sys/arch/hpcmips/include/intr.h @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.14 2001/09/16 15:45:44 uch Exp $ */ +/* $NetBSD: intr.h,v 1.15 2001/09/23 14:32:52 uch Exp $ */ /* * Copyright (c) 1998 Jonathan Stone. All rights reserved. @@ -148,6 +148,7 @@ struct hpcmips_soft_intr { }; void softintr_init(void); +void softintr(u_int32_t); void *softintr_establish(int, void (*)(void *), void *); void softintr_disestablish(void *); void softintr_dispatch(void); diff --git a/sys/arch/hpcmips/include/sysconf.h b/sys/arch/hpcmips/include/sysconf.h index 82531da708c2..cddd4d365771 100644 --- a/sys/arch/hpcmips/include/sysconf.h +++ b/sys/arch/hpcmips/include/sysconf.h @@ -1,4 +1,4 @@ -/* $NetBSD: sysconf.h,v 1.10 2001/09/18 17:37:28 uch Exp $ */ +/* $NetBSD: sysconf.h,v 1.11 2001/09/23 14:32:52 uch Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -54,17 +54,17 @@ struct clock_ymdhms; extern struct platform { /* + * cpu_intr - interrupt handler * cpu_idle - CPU dependend idle routine. * cons_init - console initialization - * iointr - I/O interrupt handler * fb_init - frame buffer initialization * mem_init - Count available memory * reboot - reboot or powerdown * clock - */ + void (*cpu_intr)(u_int32_t, u_int32_t, u_int32_t, u_int32_t); void (*cpu_idle)(void); void (*cons_init)(void); - int (*iointr)(u_int32_t, u_int32_t, u_int32_t, u_int32_t); void (*fb_init)(caddr_t*); void (*mem_init)(paddr_t); void (*reboot)(int, char *); diff --git a/sys/arch/hpcmips/tx/tx39.c b/sys/arch/hpcmips/tx/tx39.c index 250d7e4ce907..09e70c2f23bb 100644 --- a/sys/arch/hpcmips/tx/tx39.c +++ b/sys/arch/hpcmips/tx/tx39.c @@ -1,4 +1,4 @@ -/* $NetBSD: tx39.c,v 1.26 2001/09/17 17:03:45 uch Exp $ */ +/* $NetBSD: tx39.c,v 1.27 2001/09/23 14:32:53 uch Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -36,6 +36,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "opt_vr41xx.h" +#include "opt_tx39xx.h" #include "opt_tx39_debug.h" #include "m38813c.h" #include "tc5165buf.h" @@ -83,7 +85,14 @@ u_int32_t tx39debugflag; #endif void tx_init(void); -int tx39icu_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t); +#if defined(VR41XX) && defined(TX39XX) +#define TX_INTR tx_intr +#else +#define TX_INTR cpu_intr /* locore_mips3 directly call this */ +#endif + +extern void TX_INTR(u_int32_t, u_int32_t, u_int32_t, u_int32_t); + void tx39clock_cpuspeed(int *, int *); /* TX39-specific initialization vector */ @@ -92,7 +101,6 @@ void tx_fb_init(caddr_t *); void tx_mem_init(paddr_t); void tx_find_dram(paddr_t, paddr_t); void tx_reboot(int, char *); -int tx_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t); void tx_init() @@ -105,12 +113,13 @@ tx_init() /* * Platform Specific Function Hooks */ + platform.cpu_intr = TX_INTR; platform.cpu_idle = NULL; /* not implemented yet */ platform.cons_init = tx_cons_init; platform.fb_init = tx_fb_init; platform.mem_init = tx_mem_init; platform.reboot = tx_reboot; - platform.iointr = tx39icu_intr; + model = MIPS_PRID_REV(cpu_id); diff --git a/sys/arch/hpcmips/tx/tx39icu.c b/sys/arch/hpcmips/tx/tx39icu.c index 7e6fda1e0715..6eb8f3ba9898 100644 --- a/sys/arch/hpcmips/tx/tx39icu.c +++ b/sys/arch/hpcmips/tx/tx39icu.c @@ -1,7 +1,7 @@ -/* $NetBSD: tx39icu.c,v 1.13 2001/09/18 17:37:28 uch Exp $ */ +/* $NetBSD: tx39icu.c,v 1.14 2001/09/23 14:32:53 uch Exp $ */ /*- - * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. + * Copyright (c) 1999-2001 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -36,6 +36,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "opt_vr41xx.h" +#include "opt_tx39xx.h" + #include "opt_tx39_debug.h" #include "opt_use_poll.h" #include "opt_tx39icudebug.h" @@ -47,6 +50,8 @@ #include #include +#include + #include #include @@ -59,6 +64,12 @@ #undef TX39ICUDEBUG_PRINT_PENDING_INTERRUPT /* For explorer. good luck! */ +#if defined(VR41XX) && defined(TX39XX) +#define TX_INTR tx_intr +#else +#define TX_INTR cpu_intr /* locore_mips3 directly call this */ +#endif + #ifdef TX39ICUDEBUG #define DPRINTF(arg) printf arg #else @@ -66,6 +77,44 @@ #endif u_int32_t tx39intrvec; +/* + * This is a mask of bits to clear in the SR when we go to a + * given interrupt priority level. + */ +const u_int32_t __ipl_sr_bits_tx[_IPL_N] = { + 0, /* IPL_NONE */ + + MIPS_SOFT_INT_MASK_0, /* IPL_SOFT */ + + MIPS_SOFT_INT_MASK_0, /* IPL_SOFTCLOCK */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1, /* IPL_SOFTNET */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1, /* IPL_SOFTSERIAL */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1| + MIPS_INT_MASK_2| + MIPS_INT_MASK_4, /* IPL_BIO */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1| + MIPS_INT_MASK_2| + MIPS_INT_MASK_4, /* IPL_NET */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1| + MIPS_INT_MASK_2| + MIPS_INT_MASK_4, /* IPL_{TTY,SERIAL} */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1| + MIPS_INT_MASK_2| + MIPS_INT_MASK_4, /* IPL_{CLOCK,HIGH} */ +}; + /* IRQHIGH lines list */ static const struct irqhigh_list { int qh_pri; /* IRQHIGH priority */ @@ -179,13 +228,14 @@ void tx39_irqhigh_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t); int tx39_irqhigh(int, int); struct cfattach tx39icu_ca = { -sizeof(struct tx39icu_softc), tx39icu_match, tx39icu_attach + sizeof(struct tx39icu_softc), tx39icu_match, tx39icu_attach }; int tx39icu_match(struct device *parent, struct cfdata *cf, void *aux) { -return (ATTACH_FIRST); + + return (ATTACH_FIRST); } void @@ -196,7 +246,7 @@ tx39icu_attach(struct device *parent, struct device *self, void *aux) tx_chipset_tag_t tc = ta->ta_tc; txreg_t reg, *regs; int i; - + printf("\n"); sc->sc_tc = ta->ta_tc; @@ -272,15 +322,19 @@ tx39icu_attach(struct device *parent, struct device *self, void *aux) tx_conf_register_intr(tc, self); } -int -tx39icu_intr(u_int32_t status, u_int32_t cause, u_int32_t pc, - u_int32_t ipending) +void +TX_INTR(u_int32_t status, u_int32_t cause, u_int32_t pc, u_int32_t ipending) { struct tx39icu_softc *sc; tx_chipset_tag_t tc; txreg_t reg, pend, *regs; int i, j; + uvmexp.intrs++; + + if ((ipending & MIPS_HARD_INT_MASK) == 0) + goto softintr; + tc = tx_conf_get_tag(); sc = tc->tc_intrt; /* @@ -314,7 +368,7 @@ tx39icu_intr(u_int32_t status, u_int32_t cause, u_int32_t pc, if (ipending & MIPS_INT_MASK_4) { tx39_irqhigh_intr(ipending, pc, status, cause); - return (0); + goto softintr; } /* IRQLOW */ @@ -371,7 +425,11 @@ tx39icu_intr(u_int32_t status, u_int32_t cause, u_int32_t pc, reg = TX39_INTRENABLE6_PRIORITYMASK_SET(reg, 0xffff); tx_conf_write(tc, TX39_INTRENABLE6_REG, reg); #endif - return (MIPS_SR_INT_IE | (status & ~cause & MIPS_HARD_INT_MASK)); + + softintr: + _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); + + softintr(ipending); } int diff --git a/sys/arch/hpcmips/vr/vr.c b/sys/arch/hpcmips/vr/vr.c index dad1cccc1c42..9607b3b66d80 100644 --- a/sys/arch/hpcmips/vr/vr.c +++ b/sys/arch/hpcmips/vr/vr.c @@ -1,7 +1,7 @@ -/* $NetBSD: vr.c,v 1.30 2001/09/17 17:03:46 uch Exp $ */ +/* $NetBSD: vr.c,v 1.31 2001/09/23 14:32:53 uch Exp $ */ /*- - * Copyright (c) 1999 + * Copyright (c) 1999-2001 * Shin Takemura and PocketBSD Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,12 +35,15 @@ */ #include "opt_vr41xx.h" +#include "opt_tx39xx.h" #include "opt_kgdb.h" #include #include #include +#include + #include #include #include @@ -99,27 +102,74 @@ #include #endif -void vr_init(void); -int vr_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t); -void vr_cons_init(void); -void vr_fb_init(caddr_t *); -void vr_mem_init(paddr_t); -void vr_find_dram(paddr_t, paddr_t); -void vr_reboot(int, char *); -void vr_idle(void); +#ifdef DEBUG +#define STATIC +#else +#define STATIC static +#endif + +/* + * This is a mask of bits to clear in the SR when we go to a + * given interrupt priority level. + */ +const u_int32_t __ipl_sr_bits_vr[_IPL_N] = { + 0, /* IPL_NONE */ + + MIPS_SOFT_INT_MASK_0, /* IPL_SOFT */ + + MIPS_SOFT_INT_MASK_0, /* IPL_SOFTCLOCK */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1, /* IPL_SOFTNET */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1, /* IPL_SOFTSERIAL */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1| + MIPS_INT_MASK_0, /* IPL_BIO */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1| + MIPS_INT_MASK_0, /* IPL_NET */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1| + MIPS_INT_MASK_0, /* IPL_{TTY,SERIAL} */ + + MIPS_SOFT_INT_MASK_0| + MIPS_SOFT_INT_MASK_1| + MIPS_INT_MASK_0| + MIPS_INT_MASK_1, /* IPL_{CLOCK,HIGH} */ +}; + +#if defined(VR41XX) && defined(TX39XX) +#define VR_INTR vr_intr +#else +#define VR_INTR cpu_intr /* locore_mips3 directly call this */ +#endif + +void vr_init(void); +void VR_INTR(u_int32_t, u_int32_t, u_int32_t, u_int32_t); +extern void vr_idle(void); +STATIC void vr_cons_init(void); +STATIC void vr_fb_init(caddr_t *); +STATIC void vr_mem_init(paddr_t); +STATIC void vr_find_dram(paddr_t, paddr_t); +STATIC void vr_reboot(int, char *); /* * CPU interrupt dispatch table (HwInt[0:3]) */ -int null_handler(void *, u_int32_t, u_int32_t); -static int (*intr_handler[4])(void*, u_int32_t, u_int32_t) = +STATIC int vr_null_handler(void *, u_int32_t, u_int32_t); +STATIC int (*vr_intr_handler[4])(void *, u_int32_t, u_int32_t) = { - null_handler, - null_handler, - null_handler, - null_handler + vr_null_handler, + vr_null_handler, + vr_null_handler, + vr_null_handler }; -static void *intr_arg[4]; +STATIC void *vr_intr_arg[4]; void vr_init() @@ -128,7 +178,7 @@ vr_init() * Platform Specific Function Hooks */ platform.cpu_idle = vr_idle; - platform.iointr = vr_intr; + platform.cpu_intr = VR_INTR; platform.cons_init = vr_cons_init; platform.fb_init = vr_fb_init; platform.mem_init = vr_mem_init; @@ -175,7 +225,7 @@ vr_find_dram(paddr_t addr, paddr_t end) #ifdef VR_FIND_DRAMLIM if (VR_FIND_DRAMLIM < end) end = VR_FIND_DRAMLIM; -#endif +#endif /* VR_FIND_DRAMLIM */ n = mem_cluster_cnt; for (; addr < end; addr += NBPG) { @@ -215,7 +265,7 @@ vr_find_dram(paddr_t addr, paddr_t end) for (i = 0; i < NBPG; i += 4) if (*(volatile int *)(page+i) != (x ^ i)) goto bad; -#endif +#endif /* NARLY_MEMORY_PROBE */ if (!mem_clusters[n].size) mem_clusters[n].start = addr; @@ -339,15 +389,38 @@ vr_reboot(int howto, char *bootstr) /* * Handle interrupts. */ -int -vr_intr(u_int32_t status, u_int32_t cause, u_int32_t pc, u_int32_t ipending) +void +VR_INTR(u_int32_t status, u_int32_t cause, u_int32_t pc, u_int32_t ipending) { - int hwintr; + uvmexp.intrs++; - hwintr = (ffs(ipending >> 10) -1) & 0x3; - (*intr_handler[hwintr])(intr_arg[hwintr], pc, status); - - return (MIPS_SR_INT_IE | (status & ~cause & MIPS_HARD_INT_MASK)); + if (ipending & MIPS_INT_MASK_5) { + /* + * spl* uses MIPS_INT_MASK not MIPS3_INT_MASK. it causes + * INT5 interrupt. + */ + mips3_cp0_compare_write(mips3_cp0_count_read()); + } + + /* for spllowersoftclock */ + _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); + + if (ipending & MIPS_INT_MASK_1) { + (*vr_intr_handler[1])(vr_intr_arg[1], pc, status); + + cause &= ~MIPS_INT_MASK_1; + _splset(((status & ~cause) & MIPS_HARD_INT_MASK) + | MIPS_SR_INT_IE); + } + + if (ipending & MIPS_INT_MASK_0) { + (*vr_intr_handler[0])(vr_intr_arg[0], pc, status); + + cause &= ~MIPS_INT_MASK_0; + } + _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); + + softintr(ipending); } void * @@ -355,30 +428,28 @@ vr_intr_establish(int line, int (*ih_fun)(void *, u_int32_t, u_int32_t), void *ih_arg) { - if (intr_handler[line] != null_handler) { - panic("vr_intr_establish:" - " can't establish duplicated intr handler."); - } - intr_handler[line] = ih_fun; - intr_arg[line] = ih_arg; + KDASSERT(vr_intr_handler[line] == vr_null_handler); - return ((void*)line); + vr_intr_handler[line] = ih_fun; + vr_intr_arg[line] = ih_arg; + + return ((void *)line); } - void vr_intr_disestablish(void *ih) { int line = (int)ih; - intr_handler[line] = null_handler; - intr_arg[line] = NULL; + vr_intr_handler[line] = vr_null_handler; + vr_intr_arg[line] = NULL; } int -null_handler(void *arg, u_int32_t pc, u_int32_t statusReg) +vr_null_handler(void *arg, u_int32_t pc, u_int32_t status) { - printf("null_handler\n"); + + printf("vr_null_handler\n"); return (0); }