diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-11-12 17:13:36 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-11-12 17:13:36 +0000 |
commit | 3e6bb87ef52ee34c4bf6a59f04b7d95d62f6fe60 (patch) | |
tree | cc5d0f3560fc1a843cc0ae7226493bde6d78160f /sys/arch/sgi | |
parent | 6bba85ed4998d233ca4e11ae026c036abaa16f43 (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.c | 52 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/intr_template.c | 59 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip27_machdep.c | 83 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/xheart.c | 55 |
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> |