Module Name: src Committed By: cliff Date: Sat Dec 12 00:18:34 UTC 2009
Modified Files: src/sys/arch/mips/rmi [matt-nb5-mips64]: rmixl_intr.c Log Message: - in ipl_sr_bits[], ensure ints for unused vectors are always disabled and ensure that MIPS_INT_MASK_5 (clock) is enabled as needed - break IRT entry management out into routines; this allows e.g. setup of IRT entry for clock without all the rest of rmixl_intr_irt_establish() - evbmips_intr_init() now creates IRT entry for mips3 clock interrupt To generate a diff of this commit: cvs rdiff -u -r1.1.2.5 -r1.1.2.6 src/sys/arch/mips/rmi/rmixl_intr.c 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/mips/rmi/rmixl_intr.c diff -u src/sys/arch/mips/rmi/rmixl_intr.c:1.1.2.5 src/sys/arch/mips/rmi/rmixl_intr.c:1.1.2.6 --- src/sys/arch/mips/rmi/rmixl_intr.c:1.1.2.5 Fri Nov 13 05:27:09 2009 +++ src/sys/arch/mips/rmi/rmixl_intr.c Sat Dec 12 00:18:34 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: rmixl_intr.c,v 1.1.2.5 2009/11/13 05:27:09 cliff Exp $ */ +/* $NetBSD: rmixl_intr.c,v 1.1.2.6 2009/12/12 00:18:34 cliff Exp $ */ /*- * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko. @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rmixl_intr.c,v 1.1.2.5 2009/11/13 05:27:09 cliff Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rmixl_intr.c,v 1.1.2.6 2009/12/12 00:18:34 cliff Exp $"); #include "opt_ddb.h" @@ -101,16 +101,21 @@ /* * This is a mask of bits to clear in the SR when we go to a * given hardware interrupt priority level. + * _SR_BITS_DFLT bits are to be always clear (disabled) */ +#define _SR_BITS_DFLT (MIPS_INT_MASK_2|MIPS_INT_MASK_3|MIPS_INT_MASK_4) const uint32_t ipl_sr_bits[_IPL_N] = { - [IPL_NONE] = 0, + [IPL_NONE] = _SR_BITS_DFLT, [IPL_SOFTCLOCK] = - MIPS_SOFT_INT_MASK_0, + _SR_BITS_DFLT + | MIPS_SOFT_INT_MASK_0, [IPL_SOFTNET] = - MIPS_SOFT_INT_MASK_0 + _SR_BITS_DFLT + | MIPS_SOFT_INT_MASK_0 | MIPS_SOFT_INT_MASK_1, [IPL_VM] = - MIPS_SOFT_INT_MASK_0 + _SR_BITS_DFLT + | MIPS_SOFT_INT_MASK_0 | MIPS_SOFT_INT_MASK_1 | MIPS_INT_MASK_0, [IPL_SCHED] = @@ -298,6 +303,13 @@ static int evbmips_intr_init_done; #endif + +static void rmixl_intr_irt_init(int); +static void rmixl_intr_irt_disestablish(int); +static void rmixl_intr_irt_establish(int, int, rmixl_intr_trigger_t, + rmixl_intr_polarity_t, int); + + static inline void pic_irt_print(const char *s, const int n, u_int irq) { @@ -348,14 +360,16 @@ RMIXL_PICREG_WRITE(RMIXL_PIC_CONTROL, r); /* - * invalidate all IRT Entries - * permanently unmask Thread#0 in low word - * (assume we only have 1 thread) + * initialize all IRT Entries */ - for (i=0; i < NIRQS; i++) { - RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC1(i), 0); /* high word */ - RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC0(i), 1); /* low word */ - } + for (i=0; i < NIRQS; i++) + rmixl_intr_irt_init(i); + + /* + * establish IRT entry for mips3 clock interrupt + */ + rmixl_intr_irt_establish(7, IPL_CLOCK, RMIXL_INTR_LEVEL, + RMIXL_INTR_HIGH, rmixl_iplvec[IPL_CLOCK]); #ifdef DIAGNOSTIC evbmips_intr_init_done = 1; @@ -395,13 +409,65 @@ return name; } +/* + * rmixl_intr_irt_init + * - invalidate IRT Entry for irq + * - unmask Thread#0 in low word (assume we only have 1 thread) + */ +static void +rmixl_intr_irt_init(int irq) +{ + RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC1(irq), 0); /* high word */ + RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC0(irq), 1); /* low word */ +} + +/* + * rmixl_intr_irt_disestablish + * - invalidate IRT Entry for irq + * - writes to IRTENTRYC1 only; leave IRTENTRYC0 as-is + */ +static void +rmixl_intr_irt_disestablish(int irq) +{ + DPRINTF(("%s: irq %d, irtc1 %#x\n", __func__, irq, 0)); + RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC1(irq), 0); /* high word */ +} + +/* + * rmixl_intr_irt_establish + * - construct and IRT Entry for irq and write to PIC + * - writes to IRTENTRYC1 only; assumes IRTENTRYC0 has been initialized + */ +static void +rmixl_intr_irt_establish(int irq, int ipl, rmixl_intr_trigger_t trigger, + rmixl_intr_polarity_t polarity, int vec) +{ + uint32_t irtc1; + + irtc1 = RMIXL_PIC_IRTENTRYC1_VALID; + irtc1 |= RMIXL_PIC_IRTENTRYC1_GL; /* local */ + + if (trigger == RMIXL_INTR_LEVEL) + irtc1 |= RMIXL_PIC_IRTENTRYC1_TRG; + + if ((polarity == RMIXL_INTR_FALLING) || (polarity == RMIXL_INTR_LOW)) + irtc1 |= RMIXL_PIC_IRTENTRYC1_P; + + irtc1 |= vec; + + /* + * write IRT Entry to PIC (high word only) + */ + DPRINTF(("%s: irq %d, irtc1 %#x\n", __func__, irq, irtc1)); + RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC1(irq), irtc1); +} + void * rmixl_intr_establish(int irq, int ipl, rmixl_intr_trigger_t trigger, rmixl_intr_polarity_t polarity, int (*func)(void *), void *arg) { struct evbmips_intrhand *ih; struct rmixl_intrvec *ivp; - uint32_t irtc1; int vec; int s; @@ -422,14 +488,9 @@ if (rmixl_irqtab[irq].irq_ih != NULL) panic("%s: irq %d busy", __func__, irq); - irtc1 = RMIXL_PIC_IRTENTRYC1_VALID; - irtc1 |= RMIXL_PIC_IRTENTRYC1_GL; /* local */ - switch (trigger) { case RMIXL_INTR_EDGE: - break; case RMIXL_INTR_LEVEL: - irtc1 |= RMIXL_PIC_IRTENTRYC1_TRG; break; default: panic("%s: bad trigger %d\n", __func__, trigger); @@ -438,10 +499,8 @@ switch (polarity) { case RMIXL_INTR_RISING: case RMIXL_INTR_HIGH: - break; case RMIXL_INTR_FALLING: case RMIXL_INTR_LOW: - irtc1 |= RMIXL_PIC_IRTENTRYC1_P; break; default: panic("%s: bad polarity %d\n", __func__, polarity); @@ -453,7 +512,6 @@ vec = rmixl_iplvec[ipl]; DPRINTF(("%s: irq %d, ipl %d, vec %d\n", __func__, irq, ipl, vec)); KASSERT((vec & ~RMIXL_PIC_IRTENTRYC1_INTVEC) == 0); - irtc1 |= vec; s = splhigh(); @@ -513,10 +571,9 @@ ivp->iv_refcnt++; /* - * establish IRT Entry (high word only) + * establish IRT Entry */ - DPRINTF(("%s: irq %d, irtc1 %#x\n", __func__, irq, irtc1)); - RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC1(irq), irtc1); + rmixl_intr_irt_establish(irq, ipl, trigger, polarity, vec); splx(s); @@ -541,7 +598,7 @@ /* * disable the IRT Entry (high word only) */ - RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC1(irq), 0); + rmixl_intr_irt_disestablish(irq); /* * remove from the table and adjust the reference count