summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2011-10-24 22:49:08 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2011-10-24 22:49:08 +0000
commit44d661c7e0a659eeaae1fdf2d7f038b78a694f03 (patch)
tree685aa13e05c5287dbb49da3351846ec500738a3e
parent900a7eff33959bbff285c9d314a8fe7ce0cc9d74 (diff)
Introduce a pluggable interrupt controller infrastructure for beagle,
to allow panda to share the port.
-rw-r--r--sys/arch/arm/include/cpu.h5
-rw-r--r--sys/arch/beagle/beagle/beagle_machdep.c14
-rw-r--r--sys/arch/beagle/beagle/intr.c288
-rw-r--r--sys/arch/beagle/beagle/uboot_tags.c12
-rw-r--r--sys/arch/beagle/conf/files.beagle5
-rw-r--r--sys/arch/beagle/dev/gptimer.c4
-rw-r--r--sys/arch/beagle/dev/intc.c168
-rw-r--r--sys/arch/beagle/dev/intc.h9
-rw-r--r--sys/arch/beagle/dev/omap_com.c4
-rw-r--r--sys/arch/beagle/dev/omdisplay.c4
-rw-r--r--sys/arch/beagle/dev/omehci.c8
-rw-r--r--sys/arch/beagle/dev/omgpio.c20
-rw-r--r--sys/arch/beagle/dev/ommmc.c4
-rw-r--r--sys/arch/beagle/dev/omohci.c38
-rw-r--r--sys/arch/beagle/include/intr.h100
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 */