diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2011-10-24 22:49:08 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2011-10-24 22:49:08 +0000 |
commit | 44d661c7e0a659eeaae1fdf2d7f038b78a694f03 (patch) | |
tree | 685aa13e05c5287dbb49da3351846ec500738a3e | |
parent | 900a7eff33959bbff285c9d314a8fe7ce0cc9d74 (diff) |
Introduce a pluggable interrupt controller infrastructure for beagle,
to allow panda to share the port.
-rw-r--r-- | sys/arch/arm/include/cpu.h | 5 | ||||
-rw-r--r-- | sys/arch/beagle/beagle/beagle_machdep.c | 14 | ||||
-rw-r--r-- | sys/arch/beagle/beagle/intr.c | 288 | ||||
-rw-r--r-- | sys/arch/beagle/beagle/uboot_tags.c | 12 | ||||
-rw-r--r-- | sys/arch/beagle/conf/files.beagle | 5 | ||||
-rw-r--r-- | sys/arch/beagle/dev/gptimer.c | 4 | ||||
-rw-r--r-- | sys/arch/beagle/dev/intc.c | 168 | ||||
-rw-r--r-- | sys/arch/beagle/dev/intc.h | 9 | ||||
-rw-r--r-- | sys/arch/beagle/dev/omap_com.c | 4 | ||||
-rw-r--r-- | sys/arch/beagle/dev/omdisplay.c | 4 | ||||
-rw-r--r-- | sys/arch/beagle/dev/omehci.c | 8 | ||||
-rw-r--r-- | sys/arch/beagle/dev/omgpio.c | 20 | ||||
-rw-r--r-- | sys/arch/beagle/dev/ommmc.c | 4 | ||||
-rw-r--r-- | sys/arch/beagle/dev/omohci.c | 38 | ||||
-rw-r--r-- | sys/arch/beagle/include/intr.h | 100 |
15 files changed, 481 insertions, 202 deletions
diff --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h index 0f197bedd67..28e06c5c0ac 100644 --- a/sys/arch/arm/include/cpu.h +++ b/sys/arch/arm/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.28 2011/09/20 22:02:13 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.29 2011/10/24 22:49:07 drahn Exp $ */ /* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */ /* @@ -194,6 +194,9 @@ struct cpu_info { u_int32_t ci_arm_cpurev; /* CPU revision */ u_int32_t ci_ctrl; /* The CPU control register */ u_int32_t ci_randseed; + + uint32_t ci_cpl; + uint32_t ci_ipending; }; #ifndef MULTIPROCESSOR diff --git a/sys/arch/beagle/beagle/beagle_machdep.c b/sys/arch/beagle/beagle/beagle_machdep.c index 65d099cf2e7..1712777de3e 100644 --- a/sys/arch/beagle/beagle/beagle_machdep.c +++ b/sys/arch/beagle/beagle/beagle_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: beagle_machdep.c,v 1.9 2011/10/21 22:55:01 drahn Exp $ */ +/* $OpenBSD: beagle_machdep.c,v 1.10 2011/10/24 22:49:07 drahn Exp $ */ /* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */ /* @@ -455,8 +455,6 @@ initarm(void *arg0, void *arg1, void *arg2) paddr_t memstart; psize_t memsize; - board_id = (uint32_t)arg1; - #if 0 int led_data = 0; #endif @@ -465,20 +463,18 @@ initarm(void *arg0, void *arg1, void *arg2) int (*map_func_save)(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *); + board_id = (uint32_t)arg1; + /* * Heads up ... Setup the CPU / MMU / TLB functions */ if (set_cpufuncs()) panic("cpu not recognized!"); - if (board_id == BOARD_ID_OMAP3_BEAGLE) - intc_intr_bootstrap(0x48200000); /* XXX - constant */ - #if 0 /* Calibrate the delay loop. */ #endif - /* * Temporarily replace bus_space_map() functions so that * console devices can get mapped. @@ -795,10 +791,6 @@ initarm(void *arg0, void *arg1, void *arg2) cpu_domains(0x55555555); /* Switch tables */ - /* set new intc register address so that splfoo() doesn't - touch illegal address. */ - intc_intr_bootstrap(0x48200000); /* XXX - constant */ - cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); setttb(kernel_l1pt.pv_pa); cpu_tlb_flushID(); diff --git a/sys/arch/beagle/beagle/intr.c b/sys/arch/beagle/beagle/intr.c new file mode 100644 index 00000000000..d9379d6c212 --- /dev/null +++ b/sys/arch/beagle/beagle/intr.c @@ -0,0 +1,288 @@ +/* $OpenBSD: intr.c,v 1.1 2011/10/24 22:49:07 drahn Exp $ */ +/* + * Copyright (c) 2011 Dale Rahn <drahn@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/param.h> + +#include <arm/cpufunc.h> +#include <machine/cpu.h> +#include <machine/intr.h> + +int arm_dflt_splraise(int); +int arm_dflt_spllower(int); +void arm_dflt_splx(int); +void arm_dflt_setipl(int); +void *arm_dflt_intr_establish(int irqno, int level, int (*func)(void *), + void *cookie, char *name); +void arm_dflt_intr_disestablish(void *cookie); +const char *arm_dflt_intr_string(void *cookie); + +void arm_dflt_intr(void *); +void arm_intr(void *); + + +#define SI_TO_IRQBIT(x) (1 << (x)) +uint32_t arm_smask[NIPL]; + +struct arm_intr_func arm_intr_func = { + arm_dflt_splraise, + arm_dflt_spllower, + arm_dflt_splx, + arm_dflt_setipl, + arm_dflt_intr_establish, + arm_dflt_intr_disestablish, + arm_dflt_intr_string +}; + +void (*arm_intr_dispatch)(void *) = arm_dflt_intr; + +void +arm_intr(void *frame) +{ + /* XXX - change this to have irq_dispatch use function pointer */ + (*arm_intr_dispatch)(frame); +} +void +arm_dflt_intr(void *frame) +{ + panic("arm_dflt_intr() called"); +} + + +void *arm_intr_establish(int irqno, int level, int (*func)(void *), + void *cookie, char *name) +{ + return arm_intr_func.intr_establish(irqno, level, func, cookie, name); +} +void arm_intr_disestablish(void *cookie) +{ + arm_intr_func.intr_disestablish(cookie); +} +const char *arm_intr_string(void *cookie) +{ + return arm_intr_func.intr_string(cookie); +} + +int +arm_dflt_splraise(int newcpl) +{ + struct cpu_info *ci = curcpu(); + int oldcpl; + + oldcpl = ci->ci_cpl; + + if (newcpl < oldcpl) + newcpl = oldcpl; + + ci->ci_cpl = newcpl; + + return oldcpl; +} + +int +arm_dflt_spllower(int newcpl) +{ + struct cpu_info *ci = curcpu(); + int oldcpl; + + oldcpl = ci->ci_cpl; + + splx(newcpl); + + return oldcpl; +} + +void +arm_dflt_splx(int newcpl) +{ + struct cpu_info *ci = curcpu(); + + if (ci->ci_ipending & arm_smask[newcpl]) + arm_do_pending_intr(newcpl); + ci->ci_cpl = newcpl; +} + +void +arm_dflt_setipl(int newcpl) +{ + struct cpu_info *ci = curcpu(); + + ci->ci_cpl = newcpl; +} + +void *arm_dflt_intr_establish(int irqno, int level, int (*func)(void *), + void *cookie, char *name) +{ + panic("arm_dflt_intr_establish called"); +} + +void arm_dflt_intr_disestablish(void *cookie) +{ + panic("arm_dflt_intr_disestablish called"); +} + +const char * +arm_dflt_intr_string(void *cookie) +{ + panic("arm_dflt_intr_string called"); +} + +void +arm_setsoftintr(int si) +{ + struct cpu_info *ci = curcpu(); + int oldirqstate; + + /* XXX atomic? */ + oldirqstate = disable_interrupts(I32_bit); + ci->ci_ipending |= SI_TO_IRQBIT(si); + + restore_interrupts(oldirqstate); + + /* Process unmasked pending soft interrupts. */ + if (ci->ci_ipending & arm_smask[ci->ci_cpl]) + arm_do_pending_intr(ci->ci_cpl); +} + +void +arm_do_pending_intr(int pcpl) +{ + struct cpu_info *ci = curcpu(); + static int processing = 0; + int oldirqstate; + + oldirqstate = disable_interrupts(I32_bit); + + if (processing == 1) { + /* Don't use splx... we are here already! */ + arm_intr_func.setipl(pcpl); + restore_interrupts(oldirqstate); + return; + } + +#define DO_SOFTINT(si, ipl) \ + if ((ci->ci_ipending & arm_smask[pcpl]) & \ + SI_TO_IRQBIT(si)) { \ + ci->ci_ipending &= ~SI_TO_IRQBIT(si); \ + arm_intr_func.setipl(ipl); \ + restore_interrupts(oldirqstate); \ + softintr_dispatch(si); \ + oldirqstate = disable_interrupts(I32_bit); \ + } + + do { + DO_SOFTINT(SI_SOFTTTY, IPL_SOFTTTY); + DO_SOFTINT(SI_SOFTNET, IPL_SOFTNET); + DO_SOFTINT(SI_SOFTCLOCK, IPL_SOFTCLOCK); + DO_SOFTINT(SI_SOFT, IPL_SOFT); + } while (ci->ci_ipending & arm_smask[pcpl]); + + /* Don't use splx... we are here already! */ + arm_intr_func.setipl(pcpl); + processing = 0; + restore_interrupts(oldirqstate); +} + +void arm_set_intr_handler(int (*raise)(int), int (*lower)(int), + void (*x)(int), void (*setipl)(int), + void *(*intr_establish)(int irqno, int level, int (*func)(void *), + void *cookie, char *name), + void (*intr_disestablish)(void *cookie), + const char *(intr_string)(void *cookie), + void (*intr_handle)(void *)) +{ + arm_intr_func.raise = raise; + arm_intr_func.lower = lower; + arm_intr_func.x = x; + arm_intr_func.setipl = setipl; + arm_intr_func.intr_establish = intr_establish; + arm_intr_func.intr_disestablish = intr_disestablish; + arm_intr_func.intr_string = intr_string; + arm_intr_dispatch = intr_handle; +} + +void +arm_init_smask(void) +{ + static int inited = 0; + int i; + + if (inited) + return; + inited = 1; + + for (i = IPL_NONE; i <= IPL_HIGH; i++) { + arm_smask[i] = 0; + if (i < IPL_SOFT) + arm_smask[i] |= SI_TO_IRQBIT(SI_SOFT); + if (i < IPL_SOFTCLOCK) + arm_smask[i] |= SI_TO_IRQBIT(SI_SOFTCLOCK); + if (i < IPL_SOFTNET) + arm_smask[i] |= SI_TO_IRQBIT(SI_SOFTNET); + if (i < IPL_SOFTTTY) + arm_smask[i] |= SI_TO_IRQBIT(SI_SOFTTTY); + } +} + +/* provide functions for asm */ +#undef splraise +#undef spllower +#undef splx + +int +splraise(int ipl) +{ + return arm_intr_func.raise(ipl); +} + +int _spllower(int ipl); /* XXX - called from asm? */ +int +_spllower(int ipl) +{ + return arm_intr_func.lower(ipl); +} +int +spllower(int ipl) +{ + return arm_intr_func.lower(ipl); +} + +void +splx(int ipl) +{ + arm_intr_func.x(ipl); +} + + +#ifdef DIAGNOSTIC +void +arm_splassert_check(int wantipl, const char *func) +{ + struct cpu_info *ci = curcpu(); + int oldipl = ci->ci_cpl; + + if (oldipl < wantipl) { + splassert_fail(wantipl, oldipl, func); + /* + * If the splassert_ctl is set to not panic, raise the ipl + * in a feeble attempt to reduce damage. + */ + arm_intr_func.setipl(wantipl); + } +} +#endif diff --git a/sys/arch/beagle/beagle/uboot_tags.c b/sys/arch/beagle/beagle/uboot_tags.c index e9f0d666711..f4041d1df46 100644 --- a/sys/arch/beagle/beagle/uboot_tags.c +++ b/sys/arch/beagle/beagle/uboot_tags.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uboot_tags.c,v 1.1 2011/10/21 22:55:01 drahn Exp $ */ +/* $OpenBSD: uboot_tags.c,v 1.2 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright (c) 2011 Dale Rahn <drahn@openbsd.org> * @@ -88,13 +88,17 @@ parse_uboot_tags(void *handle) tag->u.mem.size); i = bootconfig.dramblocks -1; - if (bootconfig.dramblocks != 0 && (tag->u.mem.start == bootconfig.dram[i].address + + if (bootconfig.dramblocks != 0 && + (tag->u.mem.start == bootconfig.dram[i].address + (bootconfig.dram[i].pages * PAGE_SIZE))) { - bootconfig.dram[i].pages = bootconfig.dram[i].pages + tag->u.mem.size / PAGE_SIZE; + bootconfig.dram[i].pages = + bootconfig.dram[i].pages + + tag->u.mem.size / PAGE_SIZE; } else { i = bootconfig.dramblocks; bootconfig.dram[i].address = tag->u.mem.start; - bootconfig.dram[i].pages = tag->u.mem.size / PAGE_SIZE; + bootconfig.dram[i].pages = tag->u.mem.size + / PAGE_SIZE; bootconfig.dramblocks = i + 1; } diff --git a/sys/arch/beagle/conf/files.beagle b/sys/arch/beagle/conf/files.beagle index 2539b08347f..19f22ae3a10 100644 --- a/sys/arch/beagle/conf/files.beagle +++ b/sys/arch/beagle/conf/files.beagle @@ -1,4 +1,4 @@ -# $OpenBSD: files.beagle,v 1.8 2011/10/21 22:55:01 drahn Exp $ +# $OpenBSD: files.beagle,v 1.9 2011/10/24 22:49:07 drahn Exp $ # # First try for arm-specific configuration info # @@ -25,6 +25,9 @@ file arch/arm/armv7/armv7_a4x_space.c ahb # XXX file arch/arm/armv7/armv7_a4x_io.S ahb # XXX file arch/arm/armv7/armv7_mutex.c +#interrupt API layer +file arch/beagle/beagle/intr.c + # u-boot argument support file arch/beagle/beagle/uboot_tags.c diff --git a/sys/arch/beagle/dev/gptimer.c b/sys/arch/beagle/dev/gptimer.c index 6c97cb593dd..9b1a92f0194 100644 --- a/sys/arch/beagle/dev/gptimer.c +++ b/sys/arch/beagle/dev/gptimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gptimer.c,v 1.6 2011/10/21 22:55:01 drahn Exp $ */ +/* $OpenBSD: gptimer.c,v 1.7 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org> * @@ -307,7 +307,7 @@ cpu_initclocks() prcm_setclock(1, PRCM_CLK_SPEED_32); prcm_setclock(2, PRCM_CLK_SPEED_32); /* establish interrupts */ - intc_intr_establish(gptimer_irq, IPL_CLOCK, gptimer_intr, + arm_intr_establish(gptimer_irq, IPL_CLOCK, gptimer_intr, NULL, "tick"); /* setup timer 0 (hardware timer 2) */ diff --git a/sys/arch/beagle/dev/intc.c b/sys/arch/beagle/dev/intc.c index 09786443695..5e1a14aba32 100644 --- a/sys/arch/beagle/dev/intc.c +++ b/sys/arch/beagle/dev/intc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intc.c,v 1.7 2011/10/21 22:55:01 drahn Exp $ */ +/* $OpenBSD: intc.c,v 1.8 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org> * @@ -23,6 +23,7 @@ #include <sys/evcount.h> #include <machine/bus.h> #include <arch/beagle/beagle/ahb.h> +#include "intc.h" /* registers */ #define INTC_REVISION 0x00 /* R */ @@ -109,7 +110,6 @@ struct intrq { int iq_ist; /* share type */ }; -volatile int current_ipl_level = IPL_HIGH; volatile int softint_pending; struct intrq intc_handler[NIRQ]; @@ -121,11 +121,10 @@ bus_space_handle_t intc_ioh; int intc_match(struct device *, void *, void *); void intc_attach(struct device *, struct device *, void *); -int _spllower(int new); -int _splraise(int new); +int intc_spllower(int new); +int intc_splraise(int new); void intc_setipl(int new); void intc_calc_mask(void); -void intc_do_pending(void); struct cfattach intc_ca = { sizeof (struct device), intc_match, intc_attach @@ -177,10 +176,8 @@ intc_attach(struct device *parent, struct device *self, void *args) INTC_PROTECTION_PROT); #endif - /* XXX - check power saving bit */ - /* mask all interrupts */ bus_space_write_4(intc_iot, intc_ioh, INTC_MIR0, 0xffffffff); bus_space_write_4(intc_iot, intc_ioh, INTC_MIR1, 0xffffffff); @@ -192,19 +189,27 @@ intc_attach(struct device *parent, struct device *self, void *args) TAILQ_INIT(&intc_handler[i].iq_list); } + intc_calc_mask(); bus_space_write_4(intc_iot, intc_ioh, INTC_CONTROL, INTC_CONTROL_NEWIRQ); intc_attached = 1; - _splraise(IPL_HIGH); + /* insert self as interrupt handler */ + arm_set_intr_handler(intc_splraise, intc_spllower, intc_splx, + intc_setipl, + intc_intr_establish, intc_intr_disestablish, intc_intr_string, + intc_irq_handler); + + intc_setipl(IPL_HIGH); /* XXX ??? */ enable_interrupts(I32_bit); } void intc_calc_mask(void) { + struct cpu_info *ci = curcpu(); int irq; struct intrhand *ih; int i; @@ -243,96 +248,35 @@ intc_calc_mask(void) bus_space_write_4(intc_iot, intc_ioh, INTC_ILRn(irq), INTC_ILR_PRIs(NIPL-max)|INTC_ILR_IRQ); } - for (i = IPL_NONE; i <= IPL_HIGH; i++) { -#if 0 - printf("calc_mask lvl %d val %x %x %x\n", i, - intc_imask[0][i], intc_imask[1][i], intc_imask[2][i] ); -#endif - intc_smask[i] = 0; - if (i < IPL_SOFT) - intc_smask[i] |= SI_TO_IRQBIT(SI_SOFT); - if (i < IPL_SOFTCLOCK) - intc_smask[i] |= SI_TO_IRQBIT(SI_SOFTCLOCK); - if (i < IPL_SOFTNET) - intc_smask[i] |= SI_TO_IRQBIT(SI_SOFTNET); - if (i < IPL_SOFTTTY) - intc_smask[i] |= SI_TO_IRQBIT(SI_SOFTTTY); - } - intc_setipl(current_ipl_level); -} - -/* - * XXX - is it possible to do the soft interrupts with actual interrupt - * instead of emulating them? - */ -void -intc_do_pending(void) -{ - static int processing = 0; - int oldirqstate, spl_save; - - oldirqstate = disable_interrupts(I32_bit); - - spl_save = current_ipl_level; - - if (processing == 1) { - restore_interrupts(oldirqstate); - return; - } -// printf("softint_pending %x\n", softint_pending); - -#define DO_SOFTINT(si, ipl) \ - if ((softint_pending & intc_smask[current_ipl_level]) & \ - SI_TO_IRQBIT(si)) { \ - softint_pending &= ~SI_TO_IRQBIT(si); \ - if (current_ipl_level < ipl) \ - intc_setipl(ipl); \ - restore_interrupts(oldirqstate); \ - softintr_dispatch(si); \ - oldirqstate = disable_interrupts(I32_bit); \ - intc_setipl(spl_save); \ - } - - do { - DO_SOFTINT(SI_SOFTTTY, IPL_SOFTTTY); - DO_SOFTINT(SI_SOFTNET, IPL_SOFTNET); - DO_SOFTINT(SI_SOFTCLOCK, IPL_SOFTCLOCK); - DO_SOFTINT(SI_SOFT, IPL_SOFT); - } while (softint_pending & intc_smask[current_ipl_level]); - - -#if 0 - printf("exit softint_pending %x pri %x mask %x\n", softint_pending, - current_ipl_level, intc_smask[current_ipl_level]); -#endif - - processing = 0; - restore_interrupts(oldirqstate); + arm_init_smask(); + intc_setipl(ci->ci_cpl); } void -splx(int new) +intc_splx(int new) { - + struct cpu_info *ci = curcpu(); intc_setipl(new); - if (softint_pending & intc_smask[current_ipl_level]) - intc_do_pending(); + if (ci->ci_ipending & arm_smask[ci->ci_cpl]) + arm_do_pending_intr(ci->ci_cpl); } int -_spllower(int new) +intc_spllower(int new) { - int old = current_ipl_level; - splx(new); + struct cpu_info *ci = curcpu(); + int old = ci->ci_cpl; + intc_splx(new); return (old); } int -_splraise(int new) +intc_splraise(int new) { + struct cpu_info *ci = curcpu(); int old; - old = current_ipl_level; + old = ci->ci_cpl; /* * setipl must always be called because there is a race window @@ -350,31 +294,27 @@ _splraise(int new) } void -_setsoftintr(int si) -{ - int oldirqstate; - - oldirqstate = disable_interrupts(I32_bit); - softint_pending |= SI_TO_IRQBIT(si); - restore_interrupts(oldirqstate); - - /* Process unmasked pending soft interrupts. */ - if (softint_pending & intc_smask[current_ipl_level]) - intc_do_pending(); -} - - - -void intc_setipl(int new) { + struct cpu_info *ci = curcpu(); int i; int psw; if (intc_attached == 0) return; psw = disable_interrupts(I32_bit); - current_ipl_level = new; +#if 0 + { + volatile static int recursed = 0; + if (recursed == 0) { + recursed = 1; + if (new != 12) + printf("setipl %d\n", new); + recursed = 0; + } + } +#endif + ci->ci_cpl = new; for (i = 0; i < 3; i++) bus_space_write_4(intc_iot, intc_ioh, INTC_MIRn(i), intc_imask[i][new]); @@ -408,7 +348,7 @@ intc_irq_handler(void *frame) #endif pri = intc_handler[irq].iq_irq; - s = _splraise(pri); + s = intc_splraise(pri); TAILQ_FOREACH(ih, &intc_handler[irq].iq_list, ih_list) { if (ih->ih_arg != 0) arg = ih->ih_arg; @@ -421,7 +361,8 @@ intc_irq_handler(void *frame) } bus_space_write_4(intc_iot, intc_ioh, INTC_CONTROL, INTC_CONTROL_NEWIRQ); - splx(s); /* XXX - handles pending */ + + intc_splx(s); } void * @@ -476,6 +417,13 @@ intc_intr_disestablish(void *cookie) restore_interrupts(psw); } +const char * +intc_intr_string(void *cookie) +{ + return "huh?"; +} + + #if 0 int intc_tst(void *a); @@ -506,21 +454,3 @@ void intc_test(void) printf("done\n"); } #endif - -#ifdef DIAGNOSTIC -void -intc_splassert_check(int wantipl, const char *func) -{ - int oldipl = current_ipl_level; - - if (oldipl < wantipl) { - splassert_fail(wantipl, oldipl, func); - /* - * If the splassert_ctl is set to not panic, raise the ipl - * in a feeble attempt to reduce damage. - */ - intc_setipl(wantipl); - } -} -#endif - diff --git a/sys/arch/beagle/dev/intc.h b/sys/arch/beagle/dev/intc.h index 44617cf8347..ffb307bb8b9 100644 --- a/sys/arch/beagle/dev/intc.h +++ b/sys/arch/beagle/dev/intc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intc.h,v 1.1 2009/05/08 03:13:26 drahn Exp $ */ +/* $OpenBSD: intc.h,v 1.2 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org> * @@ -18,8 +18,6 @@ #ifndef _OMAPINTC_INTR_H_ #define _OMAPINTC_INTR_H_ -#define ARM_IRQ_HANDLER _C_LABEL(intc_irq_handler) - #ifndef _LOCORE #include <arm/armreg.h> @@ -57,11 +55,6 @@ find_first_bit( uint32_t bits ) } -int _splraise(int); -int _spllower(int); -void splx(int); -void _setsoftintr(int); - /* * This function *MUST* be called very early on in a port's * initarm() function, before ANY spl*() functions are called. diff --git a/sys/arch/beagle/dev/omap_com.c b/sys/arch/beagle/dev/omap_com.c index 28309abdec2..858fc483c1d 100644 --- a/sys/arch/beagle/dev/omap_com.c +++ b/sys/arch/beagle/dev/omap_com.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omap_com.c,v 1.6 2011/10/21 22:55:01 drahn Exp $ */ +/* $OpenBSD: omap_com.c,v 1.7 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright 2003 Wasabi Systems, Inc. * All rights reserved. @@ -127,7 +127,7 @@ omapuart_attach(struct device *parent, struct device *self, void *aux) com_attach_subr(sc); - (void)intc_intr_establish(aa->aa_intr, IPL_TTY, comintr, + (void)arm_intr_establish(aa->aa_intr, IPL_TTY, comintr, sc, sc->sc_dev.dv_xname); } diff --git a/sys/arch/beagle/dev/omdisplay.c b/sys/arch/beagle/dev/omdisplay.c index bf321881a60..46754eddbcf 100644 --- a/sys/arch/beagle/dev/omdisplay.c +++ b/sys/arch/beagle/dev/omdisplay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omdisplay.c,v 1.5 2010/09/07 16:21:37 deraadt Exp $ */ +/* $OpenBSD: omdisplay.c,v 1.6 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright (c) 2007 Dale Rahn <drahn@openbsd.org> * @@ -540,7 +540,7 @@ omdisplay_attach(struct device *parent, struct device *self, void *args) sc->sc_dma_tag = aa->aa_dmat; - sc->sc_ih = intc_intr_establish(aa->aa_intr, IPL_BIO /* XXX */, + sc->sc_ih = arm_intr_establish(aa->aa_intr, IPL_BIO /* XXX */, omdisplay_intr, sc, sc->sc_dev.dv_xname); printf ("\n"); diff --git a/sys/arch/beagle/dev/omehci.c b/sys/arch/beagle/dev/omehci.c index ed602089a22..ccb99848d3a 100644 --- a/sys/arch/beagle/dev/omehci.c +++ b/sys/arch/beagle/dev/omehci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omehci.c,v 1.6 2011/10/21 22:55:01 drahn Exp $ */ +/* $OpenBSD: omehci.c,v 1.7 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright (c) 2005 David Gwynne <dlg@openbsd.org> @@ -111,7 +111,7 @@ omehci_attach(struct device *parent, struct device *self, void *aux) sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); EOWRITE2(&sc->sc, EHCI_USBINTR, 0); - sc->sc_ih = intc_intr_establish(aa->aa_intr, IPL_USB, + sc->sc_ih = arm_intr_establish(aa->aa_intr, IPL_USB, ehci_intr, &sc->sc, devname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); @@ -133,7 +133,7 @@ omehci_attach(struct device *parent, struct device *self, void *aux) if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname); - intc_intr_disestablish(sc->sc_ih); + arm_intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); @@ -162,7 +162,7 @@ omehci_detach(struct device *self, int flags) return (rv); if (sc->sc_ih != NULL) { - intc_intr_disestablish(sc->sc_ih); + arm_intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; } diff --git a/sys/arch/beagle/dev/omgpio.c b/sys/arch/beagle/dev/omgpio.c index 14623fcb09a..8d4dfd5702c 100644 --- a/sys/arch/beagle/dev/omgpio.c +++ b/sys/arch/beagle/dev/omgpio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omgpio.c,v 1.5 2011/10/21 22:55:01 drahn Exp $ */ +/* $OpenBSD: omgpio.c,v 1.6 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org> * @@ -21,8 +21,12 @@ #include <sys/device.h> #include <sys/malloc.h> #include <sys/evcount.h> + +#include <arm/cpufunc.h> + #include <machine/bus.h> #include <machine/intr.h> + #include <arch/beagle/beagle/ahb.h> #include <arch/beagle/dev/omgpiovar.h> #include "omgpio.h" @@ -335,7 +339,7 @@ omgpio_intr_establish(unsigned int gpio, int level, int spl, ih->ih_arg = arg; ih->ih_ipl = level; ih->ih_gpio = gpio; - ih->ih_irq = gpio + INTC_NUM_IRQ; + ih->ih_irq = gpio + 512; ih->ih_name = name; sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] = ih; @@ -436,18 +440,18 @@ omgpio_recalc_interrupts(struct omgpio_softc *sc) #if 0 if ((max == IPL_NONE || max != sc->sc_max_il) && sc->sc_ih_h != NULL) - intc_intr_disestablish(sc->sc_ih_h); + arm_intr_disestablish(sc->sc_ih_h); if (max != IPL_NONE && max != sc->sc_max_il) { - sc->sc_ih_h = intc_intr_establish(sc->sc_irq, max, omgpio_irq, + sc->sc_ih_h = arm_intr_establish(sc->sc_irq, max, omgpio_irq, sc, NULL); } #else if (sc->sc_ih_h != NULL) - intc_intr_disestablish(sc->sc_ih_h); + arm_intr_disestablish(sc->sc_ih_h); if (max != IPL_NONE) { - sc->sc_ih_h = intc_intr_establish(sc->sc_irq, max, omgpio_irq, + sc->sc_ih_h = arm_intr_establish(sc->sc_irq, max, omgpio_irq, sc, NULL); } #endif @@ -455,10 +459,10 @@ omgpio_recalc_interrupts(struct omgpio_softc *sc) sc->sc_max_il = max; if (sc->sc_ih_l != NULL) - intc_intr_disestablish(sc->sc_ih_l); + arm_intr_disestablish(sc->sc_ih_l); if (max != min) { - sc->sc_ih_h = intc_intr_establish(sc->sc_irq, min, + sc->sc_ih_h = arm_intr_establish(sc->sc_irq, min, omgpio_irq_dummy, sc, NULL); } sc->sc_min_il = min; diff --git a/sys/arch/beagle/dev/ommmc.c b/sys/arch/beagle/dev/ommmc.c index 3b1a8696b8e..370e4a7c05f 100644 --- a/sys/arch/beagle/dev/ommmc.c +++ b/sys/arch/beagle/dev/ommmc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ommmc.c,v 1.9 2011/10/21 22:55:01 drahn Exp $ */ +/* $OpenBSD: ommmc.c,v 1.10 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright (c) 2009 Dale Rahn <drahn@openbsd.org> @@ -400,7 +400,7 @@ ommmc_attach(struct device *parent, struct device *self, void *args) /* XXX DMA channels? */ prcm_enableclock(sc->clockbit); - sc->sc_ih = intc_intr_establish(sc->sc_irq, IPL_SDMMC, ommmc_intr, + sc->sc_ih = arm_intr_establish(sc->sc_irq, IPL_SDMMC, ommmc_intr, sc, sc->sc_dev.dv_xname); #if 0 diff --git a/sys/arch/beagle/dev/omohci.c b/sys/arch/beagle/dev/omohci.c index 94f0ce998e4..482042f4f6c 100644 --- a/sys/arch/beagle/dev/omohci.c +++ b/sys/arch/beagle/dev/omohci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omohci.c,v 1.4 2010/09/07 16:21:37 deraadt Exp $ */ +/* $OpenBSD: omohci.c,v 1.5 2011/10/24 22:49:07 drahn Exp $ */ /* * Copyright (c) 2005 David Gwynne <dlg@openbsd.org> @@ -165,17 +165,17 @@ omohci_attach(struct device *parent, struct device *self, void *aux) bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, OHCI_MIE); - sc->sc_ihc0 = intc_intr_establish(aa->aa_intr, IPL_USB, + sc->sc_ihc0 = arm_intr_establish(aa->aa_intr, IPL_USB, ohci_intr, &sc->sc, sc->sc.sc_bus.bdev.dv_xname); - sc->sc_ihc1 = intc_intr_establish(aa->aa_intr+1, IPL_USB, + sc->sc_ihc1 = arm_intr_establish(aa->aa_intr+1, IPL_USB, ohci_intr, &sc->sc, sc->sc.sc_bus.bdev.dv_xname); - sc->sc_ihc2 = intc_intr_establish(aa->aa_intr+2, IPL_USB, + sc->sc_ihc2 = arm_intr_establish(aa->aa_intr+2, IPL_USB, ohci_intr, &sc->sc, sc->sc.sc_bus.bdev.dv_xname); - sc->sc_ih0 = intc_intr_establish(aa->aa_intr+3, IPL_USB, + sc->sc_ih0 = arm_intr_establish(aa->aa_intr+3, IPL_USB, ohci_intr, &sc->sc, sc->sc.sc_bus.bdev.dv_xname); - sc->sc_ih1 = intc_intr_establish(aa->aa_intr+4, IPL_USB, + sc->sc_ih1 = arm_intr_establish(aa->aa_intr+4, IPL_USB, ohci_intr, &sc->sc, sc->sc.sc_bus.bdev.dv_xname); - sc->sc_ihotg = intc_intr_establish(aa->aa_intr+5, IPL_USB, + sc->sc_ihotg = arm_intr_establish(aa->aa_intr+5, IPL_USB, ohci_intr, &sc->sc, sc->sc.sc_bus.bdev.dv_xname); if (sc->sc_ih0 == NULL || sc->sc_ih1 == NULL || @@ -203,12 +203,12 @@ omohci_attach(struct device *parent, struct device *self, void *aux) if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", sc->sc.sc_bus.bdev.dv_xname, r); - intc_intr_disestablish(sc->sc_ih0); - intc_intr_disestablish(sc->sc_ih1); - intc_intr_disestablish(sc->sc_ihc0); - intc_intr_disestablish(sc->sc_ihc1); - intc_intr_disestablish(sc->sc_ihc2); - intc_intr_disestablish(sc->sc_ihotg); + arm_intr_disestablish(sc->sc_ih0); + arm_intr_disestablish(sc->sc_ih1); + arm_intr_disestablish(sc->sc_ihc0); + arm_intr_disestablish(sc->sc_ihc1); + arm_intr_disestablish(sc->sc_ihc2); + arm_intr_disestablish(sc->sc_ihotg); sc->sc_ih0 = NULL; sc->sc_ih1 = NULL; sc->sc_ihc0 = NULL; @@ -239,12 +239,12 @@ omohci_detach(struct device *self, int flags) return (rv); if (sc->sc_ih0 != NULL) { - intc_intr_disestablish(sc->sc_ih0); - intc_intr_disestablish(sc->sc_ih1); - intc_intr_disestablish(sc->sc_ihc0); - intc_intr_disestablish(sc->sc_ihc1); - intc_intr_disestablish(sc->sc_ihc2); - intc_intr_disestablish(sc->sc_ihotg); + arm_intr_disestablish(sc->sc_ih0); + arm_intr_disestablish(sc->sc_ih1); + arm_intr_disestablish(sc->sc_ihc0); + arm_intr_disestablish(sc->sc_ihc1); + arm_intr_disestablish(sc->sc_ihc2); + arm_intr_disestablish(sc->sc_ihotg); sc->sc_ih0 = NULL; sc->sc_ih1 = NULL; sc->sc_ihc0 = NULL; diff --git a/sys/arch/beagle/include/intr.h b/sys/arch/beagle/include/intr.h index 80a43d88a7a..e1fd6cfee5e 100644 --- a/sys/arch/beagle/include/intr.h +++ b/sys/arch/beagle/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.3 2011/03/23 16:54:34 pirofti Exp $ */ +/* $OpenBSD: intr.h,v 1.4 2011/10/24 22:49:07 drahn Exp $ */ /* $NetBSD: intr.h,v 1.12 2003/06/16 20:00:59 thorpej Exp $ */ /* @@ -47,9 +47,9 @@ #define IPL_SOFT 1 /* generic software interrupts */ #define IPL_SOFTCLOCK 2 /* software clock interrupt */ #define IPL_SOFTNET 3 /* software network interrupt */ -#define IPL_BIO 4 /* block I/O */ -#define IPL_NET 5 /* network */ -#define IPL_SOFTTTY 6 /* software serial interrupt */ +#define IPL_SOFTTTY 4 /* software serial interrupt */ +#define IPL_BIO 5 /* block I/O */ +#define IPL_NET 6 /* network */ #define IPL_TTY 7 /* terminals */ #define IPL_VM 8 /* memory allocation */ #define IPL_AUDIO 9 /* audio device */ @@ -73,30 +73,92 @@ #define IST_EDGE_BOTH 6 #ifndef _LOCORE - #include <sys/device.h> #include <sys/queue.h> -#define splhigh() _splraise(IPL_HIGH) -#define splsoft() _splraise(IPL_SOFT) -#define splsoftclock() _splraise(IPL_SOFTCLOCK) -#define splsoftnet() _splraise(IPL_SOFTNET) -#define splbio() _splraise(IPL_BIO) -#define splnet() _splraise(IPL_NET) -#define spltty() _splraise(IPL_TTY) -#define splvm() _splraise(IPL_VM) -#define splaudio() _splraise(IPL_AUDIO) -#define splclock() _splraise(IPL_CLOCK) -#define splstatclock() _splraise(IPL_STATCLOCK) - -#define spl0() _spllower(IPL_NONE) +int splraise(int); +int spllower(int); +void splx(int); + +void arm_do_pending_intr(int); +void arm_set_intr_handler(int (*raise)(int), int (*lower)(int), + void (*x)(int), void (*setipl)(int), + void *(*intr_establish)(int irqno, int level, int (*func)(void *), + void *cookie, char *name), + void (*intr_disestablish)(void *cookie), + const char *(*intr_string)(void *cookie), + void (*intr_handle)(void *)); + +struct arm_intr_func { + int (*raise)(int); + int (*lower)(int); + void (*x)(int); + void (*setipl)(int); + void *(*intr_establish)(int irqno, int level, int (*func)(void *), + void *cookie, char *name); + void (*intr_disestablish)(void *cookie); + const char *(*intr_string)(void *cookie); +}; + +extern struct arm_intr_func arm_intr_func; + +#define splraise(cpl) (arm_intr_func.raise(cpl)) +#define _splraise(cpl) (arm_intr_func.raise(cpl)) +#define spllower(cpl) (arm_intr_func.lower(cpl)) +#define splx(cpl) (arm_intr_func.x(cpl)) + +#define splhigh() splraise(IPL_HIGH) +#define splsoft() splraise(IPL_SOFT) +#define splsoftclock() splraise(IPL_SOFTCLOCK) +#define splsoftnet() splraise(IPL_SOFTNET) +#define splbio() splraise(IPL_BIO) +#define splnet() splraise(IPL_NET) +#define spltty() splraise(IPL_TTY) +#define splvm() splraise(IPL_VM) +#define splaudio() splraise(IPL_AUDIO) +#define splclock() splraise(IPL_CLOCK) +#define splstatclock() splraise(IPL_STATCLOCK) + +#define spl0() spllower(IPL_NONE) #define splsched() splhigh() #define spllock() splhigh() +void arm_init_smask(void); /* XXX */ +extern uint32_t arm_smask[NIPL]; +void arm_setsoftintr(int si); + +#define _setsoftintr arm_setsoftintr + +#include <arm/softintr.h> + +void *arm_intr_establish(int irqno, int level, int (*func)(void *), + void *cookie, char *name); +void arm_intr_disestablish(void *cookie); +const char *arm_intr_string(void *cookie); + +#ifdef DIAGNOSTIC +/* + * Although this function is implemented in MI code, it must be in this MD + * header because we don't want this header to include MI includes. + */ +void splassert_fail(int, int, const char *); +extern int splassert_ctl; +void arm_splassert_check(int, const char *); +#define splassert(__wantipl) do { \ + if (splassert_ctl > 0) { \ + arm_splassert_check(__wantipl, __func__); \ + } \ +} while (0) +#define splsoftassert(wantipl) splassert(wantipl) +#else +#define splassert(wantipl) do { /* nothing */ } while (0) +#define splsoftassert(wantipl) do { /* nothing */ } while (0) +#endif + #endif /* ! _LOCORE */ -#include "machine/beagle_intr.h" +#define ARM_IRQ_HANDLER arm_intr #endif /* _KERNEL */ |