summaryrefslogtreecommitdiff
path: root/sys/arch/sgi
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-11-12 17:13:36 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-11-12 17:13:36 +0000
commit3e6bb87ef52ee34c4bf6a59f04b7d95d62f6fe60 (patch)
treecc5d0f3560fc1a843cc0ae7226493bde6d78160f /sys/arch/sgi
parent6bba85ed4998d233ca4e11ae026c036abaa16f43 (diff)
Move the interrupt makemasks() code to the interrupt template; no functional
change.
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r--sys/arch/sgi/localbus/macebus.c52
-rw-r--r--sys/arch/sgi/sgi/intr_template.c59
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c83
-rw-r--r--sys/arch/sgi/xbow/xheart.c55
4 files changed, 80 insertions, 169 deletions
diff --git a/sys/arch/sgi/localbus/macebus.c b/sys/arch/sgi/localbus/macebus.c
index 1ffba232f99..5a742a6979c 100644
--- a/sys/arch/sgi/localbus/macebus.c
+++ b/sys/arch/sgi/localbus/macebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: macebus.c,v 1.52 2009/10/26 18:00:06 miod Exp $ */
+/* $OpenBSD: macebus.c,v 1.53 2009/11/12 17:13:31 miod Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -535,53 +535,6 @@ macebus_intr_disestablish(void *ih)
panic("%s not implemented", __func__);
}
-/*
- * Regenerate interrupt masks to reflect reality.
- */
-void
-macebus_intr_makemasks(void)
-{
- int irq, level;
- struct intrhand *q;
- uint intrlevel[CRIME_NINTS];
-
- /* First, figure out which levels each IRQ uses. */
- for (irq = 0; irq < CRIME_NINTS; irq++) {
- uint levels = 0;
- for (q = (struct intrhand *)crime_intrhand[irq];
- q != NULL; q = q->ih_next)
- levels |= 1 << q->ih_level;
- intrlevel[irq] = levels;
- }
-
- /* Then figure out which IRQs use each level. */
- for (level = IPL_NONE; level < IPL_HIGH; level++) {
- uint64_t irqs = 0;
- for (irq = 0; irq < CRIME_NINTS; irq++)
- if (intrlevel[irq] & (1 << level))
- irqs |= 1UL << irq;
- crime_imask[level] = irqs;
- }
-
- /*
- * There are tty, network and disk drivers that use free() at interrupt
- * time, so vm > (tty | net | bio).
- *
- * Enforce a hierarchy that gives slow devices a better chance at not
- * dropping data.
- */
- crime_imask[IPL_NET] |= crime_imask[IPL_BIO];
- crime_imask[IPL_TTY] |= crime_imask[IPL_NET];
- crime_imask[IPL_VM] |= crime_imask[IPL_TTY];
- crime_imask[IPL_CLOCK] |= crime_imask[IPL_VM];
-
- /*
- * These are pseudo-levels.
- */
- crime_imask[IPL_NONE] = 0;
- crime_imask[IPL_HIGH] = -1UL;
-}
-
void
macebus_splx(int newipl)
{
@@ -602,6 +555,8 @@ macebus_splx(int newipl)
*/
#define INTR_FUNCTIONNAME macebus_iointr
+#define MASK_FUNCTIONNAME macebus_intr_makemasks
+
#define INTR_LOCAL_DECLS
#define INTR_GETMASKS \
do { \
@@ -626,6 +581,7 @@ do { \
} while (0)
#define INTR_MASKRESTORE \
bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_MASK, imr)
+#define INTR_MASKSIZE CRIME_NINTS
#define INTR_HANDLER_SKIP(ih) macebus_iointr_skip((void *)ih)
diff --git a/sys/arch/sgi/sgi/intr_template.c b/sys/arch/sgi/sgi/intr_template.c
index 3c59ce25cd8..0be0bbc7052 100644
--- a/sys/arch/sgi/sgi/intr_template.c
+++ b/sys/arch/sgi/sgi/intr_template.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr_template.c,v 1.4 2009/10/26 20:14:15 miod Exp $ */
+/* $OpenBSD: intr_template.c,v 1.5 2009/11/12 17:13:33 miod Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -23,18 +23,74 @@
* macros and #include <sgi/sgi/intr_template.c>:
*
* INTR_FUNCTIONNAME interrupt handler function name
+ * MASK_FUNCTIONNAME interrupt mask computation function name
* INTR_GETMASKS logic to get `imr', `isr', and initialize `bit'
* INTR_HANDLER(bit) logic to access intrhand array head for `bit'
* INTR_IMASK(ipl) logic to access imask array for `ipl'
* INTR_LOCAL_DECLS local declarations (may be empty)
* INTR_MASKPENDING logic to mask `isr'
* INTR_MASKRESTORE logic to reset `imr'
+ * INTR_MASKSIZE size of interrupt mask in bits
* INTR_SPURIOUS(bit) print a spurious interrupt message for `bit'
*
* The following macros are optional:
* INTR_HANDLER_SKIP(ih) nonzero to skip intrhand invocation
*/
+/*
+ * Recompute interrupt masks.
+ */
+void
+MASK_FUNCTIONNAME()
+{
+ int irq, level;
+ struct intrhand *q;
+ uint intrlevel[INTR_MASKSIZE];
+
+ /* First, figure out which levels each IRQ uses. */
+ for (irq = 0; irq < INTR_MASKSIZE; irq++) {
+ uint levels = 0;
+ for (q = INTR_HANDLER(irq); q != NULL; q = q->ih_next)
+ levels |= 1 << q->ih_level;
+ intrlevel[irq] = levels;
+ }
+
+ /*
+ * Then figure out which IRQs use each level.
+ * Note that we make sure never to overwrite imask[IPL_HIGH], in
+ * case an interrupt occurs during intr_disestablish() and causes
+ * an unfortunate splx() while we are here recomputing the masks.
+ */
+ for (level = IPL_NONE; level < IPL_HIGH; level++) {
+ uint64_t irqs = 0;
+ for (irq = 0; irq < INTR_MASKSIZE; irq++)
+ if (intrlevel[irq] & (1 << level))
+ irqs |= 1UL << irq;
+ INTR_IMASK(level) = irqs;
+ }
+
+ /*
+ * There are tty, network and disk drivers that use free() at interrupt
+ * time, so vm > (tty | net | bio).
+ *
+ * Enforce a hierarchy that gives slow devices a better chance at not
+ * dropping data.
+ */
+ INTR_IMASK(IPL_NET) |= INTR_IMASK(IPL_BIO);
+ INTR_IMASK(IPL_TTY) |= INTR_IMASK(IPL_NET);
+ INTR_IMASK(IPL_VM) |= INTR_IMASK(IPL_TTY);
+ INTR_IMASK(IPL_CLOCK) |= INTR_IMASK(IPL_VM);
+
+ /*
+ * These are pseudo-levels.
+ */
+ INTR_IMASK(IPL_NONE) = 0;
+ INTR_IMASK(IPL_HIGH) = -1UL;
+}
+
+/*
+ * Interrupt dispatcher.
+ */
uint32_t
INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame)
{
@@ -122,6 +178,7 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame)
}
#undef INTR_FUNCTIONNAME
+#undef MASK_FUNCTIONNAME
#undef INTR_GETMASKS
#undef INTR_HANDLER
#undef INTR_HANDLER_SKIP
diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c
index fc964679ade..6b6204afefe 100644
--- a/sys/arch/sgi/sgi/ip27_machdep.c
+++ b/sys/arch/sgi/sgi/ip27_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip27_machdep.c,v 1.34 2009/11/07 22:48:37 miod Exp $ */
+/* $OpenBSD: ip27_machdep.c,v 1.35 2009/11/12 17:13:33 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -74,7 +74,8 @@ void ip27_hub_intr_clear(int);
void ip27_hub_intr_set(int);
uint32_t hubpi_intr0(uint32_t, struct trap_frame *);
uint32_t hubpi_intr1(uint32_t, struct trap_frame *);
-void ip27_hub_intr_makemasks(void);
+void ip27_hub_intr_makemasks0(void);
+void ip27_hub_intr_makemasks1(void);
void ip27_hub_setintrmask(int);
void ip27_hub_splx(int);
@@ -668,7 +669,10 @@ ip27_hub_intr_establish(int (*func)(void *), void *arg, int intrbit,
*anchor = ih;
hubpi_intem.hw[intrbit / HUBPI_NINTS] |= 1UL << (intrbit % HUBPI_NINTS);
- ip27_hub_intr_makemasks();
+ if (intrbit / HUBPI_NINTS != 0)
+ ip27_hub_intr_makemasks1();
+ else
+ ip27_hub_intr_makemasks0();
splx(s); /* causes hw mask update */
@@ -702,7 +706,10 @@ ip27_hub_intr_disestablish(int intrbit)
hubpi_intem.hw[intrbit / HUBPI_NINTS] &=
~(1UL << (intrbit % HUBPI_NINTS));
- ip27_hub_intr_makemasks();
+ if (intrbit / HUBPI_NINTS != 0)
+ ip27_hub_intr_makemasks1();
+ else
+ ip27_hub_intr_makemasks0();
splx(s);
@@ -721,70 +728,6 @@ ip27_hub_intr_set(int intrbit)
IP27_RHUB_PI_S(masternasid, 0, HUBPI_IR_CHANGE, PI_IR_SET | intrbit);
}
-/*
- * Recompute interrupt masks.
- */
-void
-ip27_hub_intr_makemasks()
-{
- int irq, level, i;
- struct intrhand *q;
- uint intrlevel[HUBPI_NINTS + HUBPI_NINTS];
-
- /* First, figure out which levels each IRQ uses. */
- for (irq = 0; irq < HUBPI_NINTS; irq++) {
- uint levels = 0;
- for (q = hubpi_intrhand0[irq]; q; q = q->ih_next)
- levels |= 1 << q->ih_level;
- intrlevel[irq] = levels;
-
- levels = 0;
- for (q = hubpi_intrhand1[irq]; q; q = q->ih_next)
- levels |= 1 << q->ih_level;
- intrlevel[HUBPI_NINTS + irq] = levels;
- }
-
- /*
- * Then figure out which IRQs use each level.
- * Note that we make sure never to overwrite imask[IPL_HIGH], in
- * case an interrupt occurs during intr_disestablish() and causes
- * an unfortunate splx() while we are here recomputing the masks.
- */
- for (level = IPL_NONE; level < IPL_HIGH; level++) {
- uint64_t irqs = 0;
- for (irq = 0; irq < HUBPI_NINTS; irq++)
- if (intrlevel[irq] & (1 << level))
- irqs |= 1UL << irq;
- hubpi_imask[level].hw[0] = irqs;
-
- irqs = 0;
- for (irq = 0; irq < HUBPI_NINTS; irq++)
- if (intrlevel[HUBPI_NINTS + irq] & (1 << level))
- irqs |= 1UL << irq;
- hubpi_imask[level].hw[1] = irqs;
- }
-
- /*
- * There are tty, network and disk drivers that use free() at interrupt
- * time, so vm > (tty | net | bio).
- *
- * Enforce a hierarchy that gives slow devices a better chance at not
- * dropping data.
- */
- for (i = 0; i < 2; i++) {
- hubpi_imask[IPL_NET].hw[i] |= hubpi_imask[IPL_BIO].hw[i];
- hubpi_imask[IPL_TTY].hw[i] |= hubpi_imask[IPL_NET].hw[i];
- hubpi_imask[IPL_VM].hw[i] |= hubpi_imask[IPL_TTY].hw[i];
- hubpi_imask[IPL_CLOCK].hw[i] |= hubpi_imask[IPL_VM].hw[i];
-
- /*
- * These are pseudo-levels.
- */
- hubpi_imask[IPL_NONE].hw[i] = 0;
- hubpi_imask[IPL_HIGH].hw[i] = -1;
- }
-}
-
void
ip27_hub_splx(int newipl)
{
@@ -806,6 +749,7 @@ ip27_hub_splx(int newipl)
*/
#define INTR_FUNCTIONNAME hubpi_intr0
+#define MASK_FUNCTIONNAME ip27_hub_intr_makemasks0
#define INTR_LOCAL_DECLS
#define INTR_GETMASKS \
do { \
@@ -830,10 +774,12 @@ do { \
IP27_LHUB_S(HUBPI_CPU0_IMR0, imr); \
(void)IP27_LHUB_L(HUBPI_IR0); \
} while (0)
+#define INTR_MASKSIZE HUBPI_NINTS
#include <sgi/sgi/intr_template.c>
#define INTR_FUNCTIONNAME hubpi_intr1
+#define MASK_FUNCTIONNAME ip27_hub_intr_makemasks1
#define INTR_LOCAL_DECLS
#define INTR_GETMASKS \
do { \
@@ -858,6 +804,7 @@ do { \
IP27_LHUB_S(HUBPI_CPU0_IMR1, imr); \
(void)IP27_LHUB_L(HUBPI_IR1); \
} while (0)
+#define INTR_MASKSIZE HUBPI_NINTS
#include <sgi/sgi/intr_template.c>
diff --git a/sys/arch/sgi/xbow/xheart.c b/sys/arch/sgi/xbow/xheart.c
index 07a11015b31..100a2211df6 100644
--- a/sys/arch/sgi/xbow/xheart.c
+++ b/sys/arch/sgi/xbow/xheart.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xheart.c,v 1.15 2009/10/31 00:20:47 miod Exp $ */
+/* $OpenBSD: xheart.c,v 1.16 2009/11/12 17:13:35 miod Exp $ */
/*
* Copyright (c) 2008 Miodrag Vallat.
@@ -375,57 +375,6 @@ xheart_intr_set(int intrbit)
CCA_NC) = 1UL << intrbit;
}
-/*
- * Recompute interrupt masks.
- */
-void
-xheart_intr_makemasks()
-{
- int irq, level;
- struct intrhand *q;
- uint intrlevel[HEART_NINTS];
-
- /* First, figure out which levels each IRQ uses. */
- for (irq = 0; irq < HEART_NINTS; irq++) {
- uint levels = 0;
- for (q = xheart_intrhand[irq]; q; q = q->ih_next)
- levels |= 1 << q->ih_level;
- intrlevel[irq] = levels;
- }
-
- /*
- * Then figure out which IRQs use each level.
- * Note that we make sure never to overwrite imask[IPL_HIGH], in
- * case an interrupt occurs during intr_disestablish() and causes
- * an unfortunate splx() while we are here recomputing the masks.
- */
- for (level = IPL_NONE; level < IPL_HIGH; level++) {
- uint64_t irqs = 0;
- for (irq = 0; irq < HEART_NINTS; irq++)
- if (intrlevel[irq] & (1 << level))
- irqs |= 1UL << irq;
- xheart_imask[level] = irqs;
- }
-
- /*
- * There are tty, network and disk drivers that use free() at interrupt
- * time, so vm > (tty | net | bio).
- *
- * Enforce a hierarchy that gives slow devices a better chance at not
- * dropping data.
- */
- xheart_imask[IPL_NET] |= xheart_imask[IPL_BIO];
- xheart_imask[IPL_TTY] |= xheart_imask[IPL_NET];
- xheart_imask[IPL_VM] |= xheart_imask[IPL_TTY];
- xheart_imask[IPL_CLOCK] |= xheart_imask[IPL_VM];
-
- /*
- * These are pseudo-levels.
- */
- xheart_imask[IPL_NONE] = 0;
- xheart_imask[IPL_HIGH] = -1UL;
-}
-
void
xheart_splx(int newipl)
{
@@ -447,6 +396,7 @@ xheart_splx(int newipl)
*/
#define INTR_FUNCTIONNAME xheart_intr_handler
+#define MASK_FUNCTIONNAME xheart_intr_makemasks
#define INTR_LOCAL_DECLS \
paddr_t heart = PHYS_TO_XKPHYS(HEART_PIU_BASE, CCA_NC);
#define INTR_GETMASKS \
@@ -488,6 +438,7 @@ do { \
} while (0)
#define INTR_MASKRESTORE \
*(volatile uint64_t *)(heart + HEART_IMR(0)) = imr
+#define INTR_MASKSIZE HEART_NINTS
#include <sgi/sgi/intr_template.c>