summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2007-08-11 19:25:32 +0000
committermarcel <marcel@FreeBSD.org>2007-08-11 19:25:32 +0000
commitb031fef0fe7eeba046a2b3d41301aceb44002829 (patch)
tree5173256f6143a83fb0650d3f3d3b059f81b0c1b3 /sys/powerpc
parent3a4b5d55d8c4fb5dafe3d58b83572ed5575bc2d6 (diff)
downloadFreeBSD-src-b031fef0fe7eeba046a2b3d41301aceb44002829.zip
FreeBSD-src-b031fef0fe7eeba046a2b3d41301aceb44002829.tar.gz
Revamp the interrupt handling in support of INTR_FILTER. This includes:
o Revamp the PIC I/F to only abstract the PIC hardware. The resource handling has been moved to nexus, where it belongs. o Include EOI and MASK+EOI methods to the PIC I/F in support of INTR_FILTER. o With the allocation of interrupt resources and setup of interrupt handlers in the common platform code we can delay talking to the PIC hardware after enumeration of all devices. Introduce a call to powerpc_intr_enable() in configure_final() to achieve that and have powerpc_setup_intr() only program the PIC when !cold. o As a consequence of the above, remove all early_attach() glue from the OpenPIC and Heathrow PIC drivers and have them register themselves when they're found during enumeration. o Decouple the interrupt vector from the interrupt request line. Allocate vectors increasingly so that they can be used for the intrcnt index as well. Extend the Heathrow PIC driver to translate between IRQ and vector. The OpenPIC driver already has the support for vectors in hardware. Approved by: re (blanket)
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/aim/interrupt.c19
-rw-r--r--sys/powerpc/aim/nexus.c95
-rw-r--r--sys/powerpc/include/intr_machdep.h29
-rw-r--r--sys/powerpc/include/md_var.h9
-rw-r--r--sys/powerpc/include/openpicvar.h33
-rw-r--r--sys/powerpc/powermac/hrowpic.c436
-rw-r--r--sys/powerpc/powermac/hrowpicvar.h12
-rw-r--r--sys/powerpc/powermac/openpic_macio.c156
-rw-r--r--sys/powerpc/powerpc/autoconf.c9
-rw-r--r--sys/powerpc/powerpc/interrupt.c19
-rw-r--r--sys/powerpc/powerpc/intr_machdep.c187
-rw-r--r--sys/powerpc/powerpc/nexus.c95
-rw-r--r--sys/powerpc/powerpc/openpic.c316
-rw-r--r--sys/powerpc/powerpc/pic_if.m36
-rw-r--r--sys/powerpc/psim/openpic_iobus.c142
15 files changed, 495 insertions, 1098 deletions
diff --git a/sys/powerpc/aim/interrupt.c b/sys/powerpc/aim/interrupt.c
index bb27675..ff77fc8 100644
--- a/sys/powerpc/aim/interrupt.c
+++ b/sys/powerpc/aim/interrupt.c
@@ -49,30 +49,19 @@
#include <sys/vmmeter.h>
#include <machine/cpu.h>
+#include <machine/clock.h>
#include <machine/db_machdep.h>
#include <machine/fpu.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
+#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/psl.h>
#include <machine/trap.h>
#include <machine/spr.h>
#include <machine/sr.h>
-void powerpc_interrupt(struct trapframe *);
-
-/*
- * External interrupt install routines
- */
-static void (*powerpc_extintr_handler)(void);
-
-void
-ext_intr_install(void (*new_extint)(void))
-{
- powerpc_extintr_handler = new_extint;
-}
-
-extern void decr_intr(struct trapframe *);
+#include "pic_if.h"
/*
* A very short dispatch, to try and maximise assembler code use
@@ -90,7 +79,7 @@ powerpc_interrupt(struct trapframe *framep)
switch (framep->exc) {
case EXC_EXI:
atomic_add_int(&td->td_intr_nesting_level, 1);
- (*powerpc_extintr_handler)();
+ PIC_DISPATCH(pic, framep);
atomic_subtract_int(&td->td_intr_nesting_level, 1);
break;
diff --git a/sys/powerpc/aim/nexus.c b/sys/powerpc/aim/nexus.c
index c2b754a..e31ef61 100644
--- a/sys/powerpc/aim/nexus.c
+++ b/sys/powerpc/aim/nexus.c
@@ -97,7 +97,7 @@ struct nexus_devinfo {
};
struct nexus_softc {
- device_t sc_pic;
+ struct rman sc_rman;
};
/*
@@ -182,12 +182,24 @@ nexus_probe(device_t dev)
phandle_t root;
phandle_t child;
struct nexus_softc *sc;
+ u_long start, end;
if ((root = OF_peer(0)) == -1)
panic("nexus_probe: OF_peer failed.");
sc = device_get_softc(dev);
+ start = 0;
+ end = INTR_VECTORS - 1;
+
+ sc->sc_rman.rm_start = start;
+ sc->sc_rman.rm_end = end;
+ sc->sc_rman.rm_type = RMAN_ARRAY;
+ sc->sc_rman.rm_descr = "Interrupt request lines";
+ if (rman_init(&sc->sc_rman) ||
+ rman_manage_region(&sc->sc_rman, start, end))
+ panic("nexus_probe IRQ rman");
+
/*
* Allow devices to identify
*/
@@ -302,31 +314,40 @@ nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
- driver_filter_t *filter, driver_intr_t *intr, void *arg, void **cookiep)
+ driver_filter_t *filter, driver_intr_t *ihand, void *arg, void **cookiep)
{
- struct nexus_softc *sc;
+ driver_t *driver;
+ int error;
- sc = device_get_softc(dev);
+ /* somebody tried to setup an irq that failed to allocate! */
+ if (res == NULL)
+ panic("nexus_setup_intr: NULL irq resource!");
+
+ *cookiep = 0;
+ if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
+ flags |= INTR_EXCL;
+
+ driver = device_get_driver(child);
+
+ /*
+ * We depend here on rman_activate_resource() being idempotent.
+ */
+ error = rman_activate_resource(res);
+ if (error)
+ return (error);
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_setup_intr: no pic attached\n");
+ error = powerpc_setup_intr(device_get_nameunit(child),
+ rman_get_start(res), filter, ihand, arg, flags, cookiep);
- return (PIC_SETUP_INTR(sc->sc_pic, child, res, flags, filter, intr,
- arg, cookiep));
+ return (error);
}
static int
nexus_teardown_intr(device_t dev, device_t child, struct resource *res,
- void *ih)
+ void *cookie)
{
- struct nexus_softc *sc;
- sc = device_get_softc(dev);
-
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_teardown_intr: no pic attached\n");
-
- return (PIC_TEARDOWN_INTR(sc->sc_pic, child, res, ih));
+ return (powerpc_teardown_intr(cookie));
}
/*
@@ -337,10 +358,8 @@ static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
- struct nexus_softc *sc;
- struct resource *rv;
-
- sc = device_get_softc(bus);
+ struct nexus_softc *sc;
+ struct resource *rv;
if (type != SYS_RES_IRQ) {
device_printf(bus, "unknown resource request from %s\n",
@@ -348,10 +367,21 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
return (NULL);
}
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_alloc_resource: no pic attached\n");
+ if (count == 0 || start + count - 1 != end) {
+ device_printf(bus, "invalid IRQ allocation from %s\n",
+ device_get_nameunit(child));
+ return (NULL);
+ }
- rv = PIC_ALLOCATE_INTR(sc->sc_pic, child, rid, start, flags);
+ sc = device_get_softc(bus);
+
+ rv = rman_reserve_resource(&sc->sc_rman, start, end, count,
+ flags, child);
+ if (rv == NULL) {
+ device_printf(bus, "IRQ allocation failed for %s\n",
+ device_get_nameunit(child));
+ } else
+ rman_set_rid(rv, *rid);
return (rv);
}
@@ -378,9 +408,6 @@ static int
nexus_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)
{
- struct nexus_softc *sc;
-
- sc = device_get_softc(bus);
if (type != SYS_RES_IRQ) {
device_printf(bus, "unknown resource request from %s\n",
@@ -388,10 +415,7 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
return (EINVAL);
}
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_release_resource: no pic attached\n");
-
- return (PIC_RELEASE_INTR(sc->sc_pic, child, rid, res));
+ return (rman_release_resource(res));
}
static device_t
@@ -418,17 +442,6 @@ nexus_device_from_node(device_t parent, phandle_t node)
return (cdev);
}
-int
-nexus_install_intcntlr(device_t dev)
-{
- struct nexus_softc *sc;
-
- sc = device_get_softc(device_get_parent(dev));
- sc->sc_pic = dev;
-
- return (0);
-}
-
static const char *
nexus_ofw_get_name(device_t bus, device_t dev)
{
diff --git a/sys/powerpc/include/intr_machdep.h b/sys/powerpc/include/intr_machdep.h
index 9914965..25f47f0 100644
--- a/sys/powerpc/include/intr_machdep.h
+++ b/sys/powerpc/include/intr_machdep.h
@@ -28,29 +28,18 @@
#ifndef _MACHINE_INTR_MACHDEP_H_
#define _MACHINE_INTR_MACHDEP_H_
-typedef void ih_func_t(void *);
+#define INTR_VECTORS 256
-struct intr_event;
+extern device_t pic;
-struct ppc_intr_handler {
- ih_func_t *ih_func;
- void *ih_arg;
- struct intr_event *ih_event;
- u_int ih_irq;
- u_int ih_flags;
- u_int ih_index;
- u_long *ih_count;
- u_long *ih_straycount;
-};
+struct trapframe;
-/* XXX temporary. */
-void ext_intr_install(void (*new_extint)(void));
+void powerpc_register_pic(device_t);
-void intr_init(void (*)(void), int, void (*)(uintptr_t), void (*)(uintptr_t));
-void intr_setup(u_int, ih_func_t *, void *, u_int);
-int inthand_add(const char *, u_int, driver_filter_t *filter,
- void (*)(void *), void *, int, void **);
-int inthand_remove(u_int, void *);
-void intr_handle(u_int);
+void powerpc_dispatch_intr(u_int, struct trapframe *);
+int powerpc_enable_intr(void);
+int powerpc_setup_intr(const char *, u_int, driver_filter_t,
+ driver_intr_t, void *, enum intr_type, void **);
+int powerpc_teardown_intr(void *);
#endif /* _MACHINE_INTR_MACHDEP_H_ */
diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h
index 7248e4b..73249ad 100644
--- a/sys/powerpc/include/md_var.h
+++ b/sys/powerpc/include/md_var.h
@@ -44,12 +44,6 @@ extern vm_offset_t kstack0_phys;
extern u_long ns_per_tick;
-struct fpreg;
-struct proc;
-struct reg;
-struct cam_sim;
-struct pcicfg;
-
#if defined(_KERNEL) || defined(_STANDALONE)
#define CACHELINESIZE 32
#endif
@@ -64,4 +58,7 @@ void decr_init(void);
void cpu_setup(u_int);
+struct trapframe;
+void powerpc_interrupt(struct trapframe *);
+
#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/powerpc/include/openpicvar.h b/sys/powerpc/include/openpicvar.h
index 5095036..081cf7a 100644
--- a/sys/powerpc/include/openpicvar.h
+++ b/sys/powerpc/include/openpicvar.h
@@ -33,36 +33,31 @@
#define OPENPIC_IRQMAX 256 /* h/w allows more */
struct openpic_softc {
+ device_t sc_dev;
+ struct resource *sc_memr;
+ bus_space_tag_t sc_bt;
+ bus_space_handle_t sc_bh;
char *sc_version;
+ int sc_rid;
u_int sc_ncpu;
u_int sc_nirq;
- int sc_psim;
- struct rman sc_rman;
- bus_space_tag_t sc_bt;
- bus_space_handle_t sc_bh;
- u_int sc_hwprobed;
- u_int sc_early_done;
- device_t sc_altdev;
- u_char sc_irqrsv[OPENPIC_IRQMAX]; /* pre-h/w reservation */
+ int sc_psim;
};
+extern devclass_t openpic_devclass;
+
/*
* Bus-independent attach i/f
*/
-int openpic_early_attach(device_t);
-int openpic_attach(device_t);
+int openpic_attach(device_t);
/*
* PIC interface.
*/
-struct resource *openpic_allocate_intr(device_t, device_t, int *,
- u_long, u_int);
-int openpic_setup_intr(device_t, device_t,
- struct resource *, int, driver_filter_t,
- driver_intr_t, void *, void **);
-int openpic_teardown_intr(device_t, device_t,
- struct resource *, void *);
-int openpic_release_intr(device_t dev, device_t, int,
- struct resource *res);
+void openpic_dispatch(device_t, struct trapframe *);
+void openpic_enable(device_t, u_int, u_int);
+void openpic_eoi(device_t, u_int);
+void openpic_mask(device_t, u_int);
+void openpic_unmask(device_t, u_int);
#endif /* _POWERPC_OPENPICVAR_H_ */
diff --git a/sys/powerpc/powermac/hrowpic.c b/sys/powerpc/powermac/hrowpic.c
index d6e5e25..cf8a462 100644
--- a/sys/powerpc/powermac/hrowpic.c
+++ b/sys/powerpc/powermac/hrowpic.c
@@ -28,15 +28,9 @@
*/
/*
- * A driver for the PIC found in the Heathrow/Paddington MacIO chips.
+ * A driver for the PIC found in the Heathrow/Paddington MacIO chips.
* This was superseded by an OpenPIC in the Keylargo and beyond
* MacIO versions.
- *
- * The device is initially located in the Open Firmware device tree
- * in the earliest stage of the nexus probe. However, no device registers
- * are touched until the actual h/w is probed later on during the
- * MacIO probe. At that point, any interrupt sources that were allocated
- * prior to this are activated.
*/
#include <sys/param.h>
@@ -45,6 +39,7 @@
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <sys/rman.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/openfirm.h>
@@ -60,67 +55,35 @@
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <sys/rman.h>
-
#include <powerpc/powermac/hrowpicvar.h>
#include "pic_if.h"
/*
- * Device interface.
- */
-static void hrowpic_identify(driver_t *, device_t);
-static int hrowpic_probe(device_t);
-static int hrowpic_attach(device_t);
-
-/*
- * PIC interface.
- */
-static struct resource *hrowpic_allocate_intr(device_t, device_t, int *,
- u_long, u_int);
-static int hrowpic_setup_intr(device_t, device_t,
- struct resource *, int, driver_filter_t,
- driver_intr_t, void *, void **);
-static int hrowpic_teardown_intr(device_t, device_t,
- struct resource *, void *);
-static int hrowpic_release_intr(device_t dev, device_t, int,
- struct resource *res);
-
-/*
* MacIO interface
*/
-static int hrowpic_macio_probe(device_t);
-static int hrowpic_macio_attach(device_t);
-
-/*
- * Local routines
- */
-static void hrowpic_intr(void);
-static void hrowpic_ext_enable_irq(uintptr_t);
-static void hrowpic_ext_disable_irq(uintptr_t);
-static void hrowpic_toggle_irq(struct hrowpic_softc *sc, int, int);
+static int hrowpic_probe(device_t);
+static int hrowpic_attach(device_t);
-/*
- * Interrupt controller softc. There should only be one.
- */
-static struct hrowpic_softc *hpicsoftc;
+static void hrowpic_dispatch(device_t, struct trapframe *);
+static void hrowpic_enable(device_t, u_int, u_int);
+static void hrowpic_eoi(device_t, u_int);
+static void hrowpic_mask(device_t, u_int);
+static void hrowpic_unmask(device_t, u_int);
-/*
- * Driver methods.
- */
static device_method_t hrowpic_methods[] = {
/* Device interface */
- DEVMETHOD(device_identify, hrowpic_identify),
DEVMETHOD(device_probe, hrowpic_probe),
DEVMETHOD(device_attach, hrowpic_attach),
/* PIC interface */
- DEVMETHOD(pic_allocate_intr, hrowpic_allocate_intr),
- DEVMETHOD(pic_setup_intr, hrowpic_setup_intr),
- DEVMETHOD(pic_teardown_intr, hrowpic_teardown_intr),
- DEVMETHOD(pic_release_intr, hrowpic_release_intr),
+ DEVMETHOD(pic_dispatch, hrowpic_dispatch),
+ DEVMETHOD(pic_enable, hrowpic_enable),
+ DEVMETHOD(pic_eoi, hrowpic_eoi),
+ DEVMETHOD(pic_mask, hrowpic_mask),
+ DEVMETHOD(pic_unmask, hrowpic_unmask),
- { 0, 0 }
+ { 0, 0 },
};
static driver_t hrowpic_driver = {
@@ -131,39 +94,48 @@ static driver_t hrowpic_driver = {
static devclass_t hrowpic_devclass;
-DRIVER_MODULE(hrowpic, nexus, hrowpic_driver, hrowpic_devclass, 0, 0);
+DRIVER_MODULE(hrowpic, macio, hrowpic_driver, hrowpic_devclass, 0, 0);
-static void
-hrowpic_identify(driver_t *driver, device_t parent)
+static uint32_t
+hrowpic_read_reg(struct hrowpic_softc *sc, u_int reg, u_int bank)
{
- phandle_t chosen, pic;
- char type[40];
+ if (bank == HPIC_PRIMARY)
+ reg += HPIC_1ST_OFFSET;
- chosen = OF_finddevice("/chosen");
- if (chosen == -1)
- return;
+ return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg));
+}
- if (OF_getprop(chosen, "interrupt-controller", &pic, 4) != 4)
- return;
+static void
+hrowpic_write_reg(struct hrowpic_softc *sc, u_int reg, u_int bank,
+ uint32_t val)
+{
- OF_getprop(pic, "compatible", type, sizeof(type));
- if (strcmp(type, "heathrow"))
- return;
+ if (bank == HPIC_PRIMARY)
+ reg += HPIC_1ST_OFFSET;
+
+ bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
- BUS_ADD_CHILD(parent, 0, "hrowpic", 0);
+ /* XXX Issue a read to force the write to complete. */
+ bus_space_read_4(sc->sc_bt, sc->sc_bh, reg);
}
static int
hrowpic_probe(device_t dev)
{
- char *name;
-
- name = nexus_get_name(dev);
+ const char *type = ofw_bus_get_type(dev);
- if (strcmp(name, "hrowpic"))
+ /*
+ * OpenPIC cells have a type of "open-pic", so this
+ * is sufficient to identify a Heathrow cell
+ */
+ if (strcmp(type, "interrupt-controller") != 0)
return (ENXIO);
-
- device_set_desc(dev, "Heathrow interrupt controller");
+
+ /*
+ * The description was already printed out in the nexus
+ * probe, so don't do it again here
+ */
+ device_set_desc(dev, "Heathrow MacIO interrupt controller");
return (0);
}
@@ -173,159 +145,36 @@ hrowpic_attach(device_t dev)
struct hrowpic_softc *sc;
sc = device_get_softc(dev);
+ sc->sc_dev = dev;
- sc->sc_rman.rm_type = RMAN_ARRAY;
- sc->sc_rman.rm_descr = device_get_nameunit(dev);
+ sc->sc_rrid = 0;
+ sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid,
+ RF_ACTIVE);
- if (rman_init(&sc->sc_rman) != 0 ||
- rman_manage_region(&sc->sc_rman, 0, HROWPIC_IRQMAX-1) != 0) {
- device_printf(dev, "could not set up resource management");
+ if (sc->sc_rres == NULL) {
+ device_printf(dev, "Could not alloc mem resource!\n");
return (ENXIO);
- }
-
- nexus_install_intcntlr(dev);
- intr_init(hrowpic_intr, HROWPIC_IRQMAX, hrowpic_ext_enable_irq,
- hrowpic_ext_disable_irq);
-
- KASSERT(hpicsoftc == NULL, ("hrowpic: h/w already probed"));
- hpicsoftc = sc;
-
- return (0);
-}
-
-/*
- * PIC interface
- */
-static struct resource *
-hrowpic_allocate_intr(device_t picdev, device_t child, int *rid, u_long intr,
- u_int flags)
-{
- struct hrowpic_softc *sc;
- struct resource *rv;
- int needactivate;
-
- sc = device_get_softc(picdev);
- needactivate = flags & RF_ACTIVE;
- flags &= ~RF_ACTIVE;
-
- rv = rman_reserve_resource(&sc->sc_rman, intr, intr, 1, flags, child);
- if (rv == NULL) {
- device_printf(picdev, "interrupt reservation failed for %s\n",
- device_get_nameunit(child));
- return (NULL);
}
- rman_set_rid(rv, *rid);
-
- return (rv);
-}
-static int
-hrowpic_setup_intr(device_t picdev, device_t child, struct resource *res,
- int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
- void **cookiep)
-{
- struct hrowpic_softc *sc;
- u_long start;
- int error;
-
- sc = device_get_softc(picdev);
- start = rman_get_start(res);
-
- if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
- flags |= INTR_EXCL;
+ sc->sc_bt = rman_get_bustag(sc->sc_rres);
+ sc->sc_bh = rman_get_bushandle(sc->sc_rres);
/*
- * We depend here on rman_activate_resource() being idempotent.
- */
- error = rman_activate_resource(res);
- if (error)
- return (error);
-
- error = inthand_add(device_get_nameunit(child), start, filt, intr, arg,
- flags, cookiep);
-
- if (!error) {
- /*
- * Record irq request, and enable if h/w has been probed
- */
- sc->sc_irq[start] = 1;
- if (sc->sc_memr) {
- hrowpic_toggle_irq(sc, start, 1);
- }
- }
-
- return (error);
-}
-
-static int
-hrowpic_teardown_intr(device_t picdev, device_t child, struct resource *res,
- void *ih)
-{
- int error;
-
- error = rman_deactivate_resource(res);
- if (error)
- return (error);
-
- error = inthand_remove(rman_get_start(res), ih);
-
- return (error);
-}
-
-static int
-hrowpic_release_intr(device_t picdev, device_t child, int rid,
- struct resource *res)
-{
- int error;
-
- if (rman_get_flags(res) & RF_ACTIVE) {
- error = bus_deactivate_resource(child, SYS_RES_IRQ, rid, res);
- if (error)
- return (error);
- }
-
- return (rman_release_resource(res));
-}
-
-/*
- * Interrupt interface
- */
-static void
-hrowpic_write_reg(struct hrowpic_softc *sc, u_int reg, u_int bank,
- u_int32_t val)
-{
- if (bank == HPIC_PRIMARY)
- reg += HPIC_1ST_OFFSET;
-
- bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
-
- /*
- * XXX Issue a read to force the write to complete
- */
- bus_space_read_4(sc->sc_bt, sc->sc_bh, reg);
-}
-
-static u_int32_t
-hrowpic_read_reg(struct hrowpic_softc *sc, u_int reg, u_int bank)
-{
- if (bank == HPIC_PRIMARY)
- reg += HPIC_1ST_OFFSET;
-
- return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg));
-}
-
-static void
-hrowpic_clear_all(struct hrowpic_softc *sc)
-{
- /*
* Disable all interrupt sources and clear outstanding interrupts
*/
hrowpic_write_reg(sc, HPIC_ENABLE, HPIC_PRIMARY, 0);
hrowpic_write_reg(sc, HPIC_CLEAR, HPIC_PRIMARY, 0xffffffff);
hrowpic_write_reg(sc, HPIC_ENABLE, HPIC_SECONDARY, 0);
hrowpic_write_reg(sc, HPIC_CLEAR, HPIC_SECONDARY, 0xffffffff);
+
+ powerpc_register_pic(dev);
+ return (0);
}
+/*
+ * Local routines
+ */
+
static void
hrowpic_toggle_irq(struct hrowpic_softc *sc, int irq, int enable)
{
@@ -349,143 +198,74 @@ hrowpic_toggle_irq(struct hrowpic_softc *sc, int irq, int enable)
hrowpic_write_reg(sc, HPIC_ENABLE, roffset, sc->sc_softreg[roffset]);
}
+/*
+ * PIC I/F methods.
+ */
+
static void
-hrowpic_intr(void)
+hrowpic_dispatch(device_t dev, struct trapframe *tf)
{
- int irq_lo, irq_hi;
- int i;
struct hrowpic_softc *sc;
+ uint64_t mask;
+ uint32_t reg;
+ u_int irq;
- sc = hpicsoftc;
-
- /*
- * Loop through both interrupt sources until they are empty.
- * XXX simplistic code, far from optimal.
- */
- do {
- irq_lo = hrowpic_read_reg(sc, HPIC_STATUS, HPIC_PRIMARY);
- if (irq_lo) {
- hrowpic_write_reg(sc, HPIC_CLEAR, HPIC_PRIMARY,
- irq_lo);
- for (i = 0; i < HROWPIC_IRQ_REGNUM; i++) {
- if (irq_lo & (1 << i)) {
- /*
- * Disable IRQ and call handler
- */
- hrowpic_toggle_irq(sc, i, 0);
- intr_handle(i);
- }
- }
-
- }
-
- irq_hi = hrowpic_read_reg(sc, HPIC_STATUS, HPIC_SECONDARY);
- if (irq_hi) {
- hrowpic_write_reg(sc, HPIC_CLEAR, HPIC_SECONDARY,
- irq_hi);
- for (i = 0; i < HROWPIC_IRQ_REGNUM; i++) {
- if (irq_hi & (1 << i)) {
- /*
- * Disable IRQ and call handler
- */
- hrowpic_toggle_irq(sc,
- i + HROWPIC_IRQ_REGNUM, 0);
- intr_handle(i + HROWPIC_IRQ_REGNUM);
- }
- }
+ sc = device_get_softc(dev);
+ while (1) {
+ mask = hrowpic_read_reg(sc, HPIC_STATUS, HPIC_SECONDARY);
+ reg = hrowpic_read_reg(sc, HPIC_STATUS, HPIC_PRIMARY);
+ mask = (mask << 32) | reg;
+ if (mask == 0)
+ break;
+
+ irq = 0;
+ while (irq < HROWPIC_IRQMAX) {
+ if (mask & 1)
+ powerpc_dispatch_intr(sc->sc_vector[irq], tf);
+ mask >>= 1;
+ irq++;
}
- } while (irq_lo && irq_hi);
+ }
}
static void
-hrowpic_ext_enable_irq(uintptr_t irq)
+hrowpic_enable(device_t dev, u_int irq, u_int vector)
{
- hrowpic_toggle_irq(hpicsoftc, irq, 1);
+ struct hrowpic_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->sc_vector[irq] = vector;
+ hrowpic_toggle_irq(sc, irq, 1);
}
static void
-hrowpic_ext_disable_irq(uintptr_t irq)
+hrowpic_eoi(device_t dev __unused, u_int irq __unused)
{
- hrowpic_toggle_irq(hpicsoftc, irq, 0);
-}
-
-
-/*
- * MacIO interface
- */
-
-static device_method_t hrowpic_macio_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, hrowpic_macio_probe),
- DEVMETHOD(device_attach, hrowpic_macio_attach),
-
- { 0, 0 },
-};
-
-static driver_t hrowpic_macio_driver = {
- "hrowpicmacio",
- hrowpic_macio_methods,
- 0
-};
-
-static devclass_t hrowpic_macio_devclass;
+ struct hrowpic_softc *sc;
+ int bank;
-DRIVER_MODULE(hrowpicmacio, macio, hrowpic_macio_driver,
- hrowpic_macio_devclass, 0, 0);
+ sc = device_get_softc(dev);
+ bank = (irq >= 32) ? HPIC_SECONDARY : HPIC_PRIMARY ;
+ hrowpic_write_reg(sc, HPIC_CLEAR, bank, 1U << (irq & 0x1f));
+}
-static int
-hrowpic_macio_probe(device_t dev)
+static void
+hrowpic_mask(device_t dev, u_int irq)
{
- const char *type = ofw_bus_get_type(dev);
-
- /*
- * OpenPIC cells have a type of "open-pic", so this
- * is sufficient to identify a Heathrow cell
- */
- if (strcmp(type, "interrupt-controller") != 0)
- return (ENXIO);
+ struct hrowpic_softc *sc;
+ int bank;
- /*
- * The description was already printed out in the nexus
- * probe, so don't do it again here
- */
- device_set_desc(dev, "Heathrow MacIO interrupt cell");
- device_quiet(dev);
- return (0);
+ sc = device_get_softc(dev);
+ hrowpic_toggle_irq(sc, irq, 0);
+ bank = (irq >= 32) ? HPIC_SECONDARY : HPIC_PRIMARY ;
+ hrowpic_write_reg(sc, HPIC_CLEAR, bank, 1U << (irq & 0x1f));
}
-static int
-hrowpic_macio_attach(device_t dev)
+static void
+hrowpic_unmask(device_t dev, u_int irq)
{
- struct hrowpic_softc *sc = hpicsoftc;
- int rid;
- int i;
-
- KASSERT(sc != NULL, ("pic not nexus-probed\n"));
- sc->sc_maciodev = dev;
-
- rid = 0;
- sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
-
- if (sc->sc_memr == NULL) {
- device_printf(dev, "Could not alloc mem resource!\n");
- return (ENXIO);
- }
-
- sc->sc_bt = rman_get_bustag(sc->sc_memr);
- sc->sc_bh = rman_get_bushandle(sc->sc_memr);
-
- hrowpic_clear_all(sc);
-
- /*
- * Enable all IRQs that were requested before the h/w
- * was probed
- */
- for (i = 0; i < HROWPIC_IRQMAX; i++)
- if (sc->sc_irq[i]) {
- hrowpic_toggle_irq(sc, i, 1);
- }
+ struct hrowpic_softc *sc;
- return (0);
+ sc = device_get_softc(dev);
+ hrowpic_toggle_irq(sc, irq, 1);
}
diff --git a/sys/powerpc/powermac/hrowpicvar.h b/sys/powerpc/powermac/hrowpicvar.h
index 6a536cc..ac643f5 100644
--- a/sys/powerpc/powermac/hrowpicvar.h
+++ b/sys/powerpc/powermac/hrowpicvar.h
@@ -62,16 +62,14 @@
#define HPIC_1ST_OFFSET 0x10 /* offset to primary reg bank */
-
struct hrowpic_softc {
- struct rman sc_rman; /* resource mgr for IRQs */
- u_int32_t sc_irq[HROWPIC_IRQMAX]; /* allocated IRQ flags */
- u_int32_t sc_softreg[2]; /* ENABLE reg copy */
- device_t sc_maciodev; /* macio device */
- struct resource *sc_memr; /* macio bus resource */
+ device_t sc_dev; /* macio device */
+ struct resource *sc_rres; /* macio bus resource */
bus_space_tag_t sc_bt; /* macio bus tag/handle */
bus_space_handle_t sc_bh;
+ int sc_rrid;
+ uint32_t sc_softreg[2]; /* ENABLE reg copy */
+ u_int sc_vector[HROWPIC_IRQMAX];
};
-
#endif /* _POWERPC_POWERMAC_HROWPICVAR_H_ */
diff --git a/sys/powerpc/powermac/openpic_macio.c b/sys/powerpc/powermac/openpic_macio.c
index c04c373..822804e 100644
--- a/sys/powerpc/powermac/openpic_macio.c
+++ b/sys/powerpc/powermac/openpic_macio.c
@@ -26,15 +26,6 @@
*
*/
-/*
- * The macio attachment for the OpenPIC interrupt controller.
- * A nexus driver is defined so the number of interrupts can be
- * determined early in the boot sequence before the hardware
- * is accessed - the interrupt i/f is installed at this time,
- * and when h/w is finally accessed, interrupt sources allocated
- * prior to this are activated
- */
-
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -65,123 +56,33 @@ __FBSDID("$FreeBSD$");
#include "pic_if.h"
-struct openpic_ofw_softc {
- struct openpic_softc osc;
- struct resource *sc_memr; /* macio bus resource */
- device_t sc_ndev; /* nexus device */
-};
-
-static struct openpic_ofw_softc *ofwpicsoftc;
-
/*
* MacIO interface
*/
-static void openpic_ofw_identify(driver_t *, device_t);
-static int openpic_ofw_probe(device_t);
-static int openpic_ofw_attach(device_t);
static int openpic_macio_probe(device_t);
-static int openpic_macio_attach(device_t);
-
-/*
- * Nexus attachment
- */
-static device_method_t openpic_ofw_methods[] = {
- /* Device interface */
- DEVMETHOD(device_identify, openpic_ofw_identify),
- DEVMETHOD(device_probe, openpic_ofw_probe),
- DEVMETHOD(device_attach, openpic_ofw_attach),
-
- /* PIC interface */
- DEVMETHOD(pic_allocate_intr, openpic_allocate_intr),
- DEVMETHOD(pic_setup_intr, openpic_setup_intr),
- DEVMETHOD(pic_teardown_intr, openpic_teardown_intr),
- DEVMETHOD(pic_release_intr, openpic_release_intr),
-
- { 0, 0 }
-};
-
-static driver_t openpic_ofw_driver = {
- "openpic",
- openpic_ofw_methods,
- sizeof(struct openpic_ofw_softc)
-};
-
-static devclass_t openpic_ofw_devclass;
-
-DRIVER_MODULE(openpic_ofw, nexus, openpic_ofw_driver, openpic_ofw_devclass,
- 0, 0);
-
-static void
-openpic_ofw_identify(driver_t *driver, device_t parent)
-{
- device_t child;
- phandle_t pic;
- char type[40];
-
- pic = OF_finddevice("mpic");
- if (pic == -1)
- return;
-
- OF_getprop(pic, "device_type", type, sizeof(type));
-
- if (strcmp(type, "open-pic") != 0)
- return;
-
- child = BUS_ADD_CHILD(parent, 0, "openpic", 0);
- if (child != NULL)
- nexus_set_device_type(child, "macio");
-}
-
-static int
-openpic_ofw_probe(device_t dev)
-{
- char *name;
- char *type;
- name = nexus_get_name(dev);
- type = nexus_get_device_type(dev);
-
- if (strcmp(name, "openpic") != 0 ||
- strcmp(type, "macio") != 0)
- return (ENXIO);
-
- device_set_desc(dev, OPENPIC_DEVSTR);
- return (0);
-}
-
-static int
-openpic_ofw_attach(device_t dev)
-{
- KASSERT(ofwpicsoftc == NULL, ("ofw openpic: already probed"));
- ofwpicsoftc = device_get_softc(dev);
- ofwpicsoftc->sc_ndev = dev;
-
- nexus_install_intcntlr(dev);
- openpic_early_attach(dev);
- return (0);
-}
-
-/*
- * MacIO attachment
- */
static device_method_t openpic_macio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpic_macio_probe),
- DEVMETHOD(device_attach, openpic_macio_attach),
+ DEVMETHOD(device_attach, openpic_attach),
+
+ /* PIC interface */
+ DEVMETHOD(pic_dispatch, openpic_dispatch),
+ DEVMETHOD(pic_enable, openpic_enable),
+ DEVMETHOD(pic_eoi, openpic_eoi),
+ DEVMETHOD(pic_mask, openpic_mask),
+ DEVMETHOD(pic_unmask, openpic_unmask),
{ 0, 0 },
};
static driver_t openpic_macio_driver = {
- "openpicmacio",
+ "openpic",
openpic_macio_methods,
- 0
+ sizeof(struct openpic_softc),
};
-static devclass_t openpic_macio_devclass;
-
-DRIVER_MODULE(openpicmacio, macio, openpic_macio_driver,
- openpic_macio_devclass, 0, 0);
+DRIVER_MODULE(openpic, macio, openpic_macio_driver, openpic_devclass, 0, 0);
static int
openpic_macio_probe(device_t dev)
@@ -191,39 +92,6 @@ openpic_macio_probe(device_t dev)
if (strcmp(type, "open-pic") != 0)
return (ENXIO);
- /*
- * The description was already printed out in the nexus
- * probe, so don't do it again here
- */
- device_set_desc(dev, "OpenPIC MacIO interrupt cell");
- if (!bootverbose)
- device_quiet(dev);
+ device_set_desc(dev, OPENPIC_DEVSTR);
return (0);
}
-
-static int
-openpic_macio_attach(device_t dev)
-{
- struct openpic_ofw_softc *sc;
- int rid;
-
- sc = ofwpicsoftc;
- KASSERT(sc != NULL, ("pic not nexus-probed\n"));
-
- rid = 0;
- sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
-
- if (sc->sc_memr == NULL) {
- device_printf(dev, "Could not alloc mem resource!\n");
- return (ENXIO);
- }
-
- sc->osc.sc_bt = rman_get_bustag(sc->sc_memr);
- sc->osc.sc_bh = rman_get_bushandle(sc->sc_memr);
- sc->osc.sc_altdev = dev;
-
- return (openpic_attach(sc->sc_ndev));
-}
-
-
diff --git a/sys/powerpc/powerpc/autoconf.c b/sys/powerpc/powerpc/autoconf.c
index aa21ddc..6449323 100644
--- a/sys/powerpc/powerpc/autoconf.c
+++ b/sys/powerpc/powerpc/autoconf.c
@@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$");
#include <sys/cons.h>
#include <sys/kernel.h>
+#include <machine/intr_machdep.h>
+
static device_t nexusdev;
static void configure_first(void *);
@@ -65,9 +67,14 @@ configure(void *dummy)
static void
configure_final(void *dummy)
{
+
/*
- * Enable device interrupts
+ * Now that we're guaranteed to have a PIC driver (or we'll never
+ * have one), program it with all the previously setup interrupts.
*/
+ powerpc_enable_intr();
+
+ /* Enable external interrupts. */
mtmsr(mfmsr() | PSL_EE | PSL_RI);
cninit_finish();
diff --git a/sys/powerpc/powerpc/interrupt.c b/sys/powerpc/powerpc/interrupt.c
index bb27675..ff77fc8 100644
--- a/sys/powerpc/powerpc/interrupt.c
+++ b/sys/powerpc/powerpc/interrupt.c
@@ -49,30 +49,19 @@
#include <sys/vmmeter.h>
#include <machine/cpu.h>
+#include <machine/clock.h>
#include <machine/db_machdep.h>
#include <machine/fpu.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
+#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/psl.h>
#include <machine/trap.h>
#include <machine/spr.h>
#include <machine/sr.h>
-void powerpc_interrupt(struct trapframe *);
-
-/*
- * External interrupt install routines
- */
-static void (*powerpc_extintr_handler)(void);
-
-void
-ext_intr_install(void (*new_extint)(void))
-{
- powerpc_extintr_handler = new_extint;
-}
-
-extern void decr_intr(struct trapframe *);
+#include "pic_if.h"
/*
* A very short dispatch, to try and maximise assembler code use
@@ -90,7 +79,7 @@ powerpc_interrupt(struct trapframe *framep)
switch (framep->exc) {
case EXC_EXI:
atomic_add_int(&td->td_intr_nesting_level, 1);
- (*powerpc_extintr_handler)();
+ PIC_DISPATCH(pic, framep);
atomic_subtract_int(&td->td_intr_nesting_level, 1);
break;
diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c
index 1b0ff94..7daaf23 100644
--- a/sys/powerpc/powerpc/intr_machdep.c
+++ b/sys/powerpc/powerpc/intr_machdep.c
@@ -71,30 +71,32 @@
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
+#include <sys/syslog.h>
#include <sys/vmmeter.h>
#include <sys/proc.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
+#include <machine/md_var.h>
#include <machine/trap.h>
+#include "pic_if.h"
+
#define MAX_STRAY_LOG 5
MALLOC_DEFINE(M_INTR, "intr", "interrupt handler data");
-struct ppc_intr {
+struct powerpc_intr {
struct intr_event *event;
long *cntp;
- int cntidx;
+ u_int irq;
};
-static struct mtx ppc_intrs_lock;
-static struct ppc_intr **ppc_intrs;
-static u_int ppc_nintrs;
-
-static int intrcnt_index;
+static struct powerpc_intr *powerpc_intrs[INTR_VECTORS];
+static u_int nvectors; /* Allocated vectors */
+static u_int stray_count;
-static void (*irq_enable)(uintptr_t);
+device_t pic;
static void
intrcnt_setname(const char *name, int index)
@@ -103,111 +105,154 @@ intrcnt_setname(const char *name, int index)
MAXCOMLEN, name);
}
-void
-intr_init(void (*handler)(void), int nirq, void (*irq_e)(uintptr_t),
- void (*irq_d)(uintptr_t))
+#ifdef INTR_FILTER
+static void
+powerpc_intr_eoi(void *arg)
+{
+ u_int irq = (uintptr_t)arg;
+
+ PIC_EOI(pic, irq);
+}
+
+static void
+powerpc_intr_mask(void *arg)
+{
+ u_int irq = (uintptr_t)arg;
+
+ PIC_MASK(pic, irq);
+}
+#endif
+
+static void
+powerpc_intr_unmask(void *arg)
{
- uint32_t msr;
+ u_int irq = (uintptr_t)arg;
+
+ PIC_UNMASK(pic, irq);
+}
- if (ppc_intrs != NULL)
- panic("intr_init: interrupts initialized twice\n");
+void
+powerpc_register_pic(device_t dev)
+{
- ppc_nintrs = nirq;
- ppc_intrs = malloc(nirq * sizeof(struct ppc_intr *), M_INTR,
- M_NOWAIT|M_ZERO);
- if (ppc_intrs == NULL)
- panic("intr_init: unable to allocate interrupt handler array");
+ pic = dev;
+}
- mtx_init(&ppc_intrs_lock, "intr table", NULL, MTX_SPIN);
+int
+powerpc_enable_intr(void)
+{
+ struct powerpc_intr *i;
+ int vector;
- irq_enable = irq_e;
+ for (vector = 0; vector < nvectors; vector++) {
+ i = powerpc_intrs[vector];
+ if (i == NULL)
+ continue;
- intrcnt_setname("???", 0);
- intrcnt_index = 1;
+ PIC_ENABLE(pic, i->irq, vector);
+ }
- msr = mfmsr();
- mtmsr(msr & ~PSL_EE);
- ext_intr_install(handler);
- mtmsr(msr);
+ return (0);
}
int
-inthand_add(const char *name, u_int irq, driver_filter_t *filter,
- void (*handler)(void *), void *arg, int flags, void **cookiep)
+powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter,
+ driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep)
{
- struct ppc_intr *i, *orphan;
- u_int idx;
+ struct powerpc_intr *i;
+ u_int vector;
int error;
- /*
- * Work around a race where more than one CPU may be registering
- * handlers on the same IRQ at the same time.
- */
- mtx_lock_spin(&ppc_intrs_lock);
- i = ppc_intrs[irq];
- mtx_unlock_spin(&ppc_intrs_lock);
+ /* XXX lock */
+
+ i = NULL;
+ for (vector = 0; vector < nvectors; vector++) {
+ i = powerpc_intrs[vector];
+ if (i == NULL)
+ continue;
+ if (i->irq == irq)
+ break;
+ i = NULL;
+ }
if (i == NULL) {
+ if (nvectors >= INTR_VECTORS) {
+ /* XXX unlock */
+ return (ENOENT);
+ }
+
i = malloc(sizeof(*i), M_INTR, M_NOWAIT);
- if (i == NULL)
+ if (i == NULL) {
+ /* XXX unlock */
return (ENOMEM);
+ }
error = intr_event_create(&i->event, (void *)irq, 0,
- (void (*)(void *))irq_enable, "irq%d:", irq);
+ powerpc_intr_unmask,
+#ifdef INTR_FILTER
+ powerpc_intr_eoi, powerpc_intr_mask,
+#endif
+ "irq%u:", irq);
if (error) {
+ /* XXX unlock */
free(i, M_INTR);
return (error);
}
- mtx_lock_spin(&ppc_intrs_lock);
- if (ppc_intrs[irq] != NULL) {
- orphan = i;
- i = ppc_intrs[irq];
- mtx_unlock_spin(&ppc_intrs_lock);
-
- intr_event_destroy(orphan->event);
- free(orphan, M_INTR);
- } else {
- ppc_intrs[irq] = i;
- idx = intrcnt_index++;
- mtx_unlock_spin(&ppc_intrs_lock);
-
- i->cntidx = idx;
- i->cntp = &intrcnt[idx];
- intrcnt_setname(i->event->ie_fullname, idx);
- }
+ vector = nvectors++;
+ powerpc_intrs[vector] = i;
+
+ i->irq = irq;
+
+ /* XXX unlock */
+
+ i->cntp = &intrcnt[vector];
+ intrcnt_setname(i->event->ie_fullname, vector);
+
+ if (!cold)
+ PIC_ENABLE(pic, i->irq, vector);
+ } else {
+ /* XXX unlock */
}
error = intr_event_add_handler(i->event, name, filter, handler, arg,
intr_priority(flags), flags, cookiep);
if (!error)
- intrcnt_setname(i->event->ie_fullname, i->cntidx);
+ intrcnt_setname(i->event->ie_fullname, vector);
return (error);
}
int
-inthand_remove(u_int irq, void *cookie)
+powerpc_teardown_intr(void *cookie)
{
return (intr_event_remove_handler(cookie));
}
void
-intr_handle(u_int irq)
+powerpc_dispatch_intr(u_int vector, struct trapframe *tf)
{
- struct ppc_intr *i;
+ struct powerpc_intr *i;
struct intr_event *ie;
+#ifndef INTR_FILTER
struct intr_handler *ih;
int error, sched, ret;
+#endif
- i = ppc_intrs[irq];
+ i = powerpc_intrs[vector];
if (i == NULL)
goto stray;
- atomic_add_long(i->cntp, 1);
+ (*i->cntp)++;
ie = i->event;
KASSERT(ie != NULL, ("%s: interrupt without an event", __func__));
+#ifdef INTR_FILTER
+ if (intr_event_handle(ie, tf) != 0) {
+ PIC_MASK(pic, i->irq);
+ log(LOG_ERR, "stray irq%u\n", i->irq);
+ }
+#else
if (TAILQ_EMPTY(&ie->ie_handlers))
goto stray;
@@ -238,20 +283,24 @@ intr_handle(u_int irq)
critical_exit();
if (sched) {
+ PIC_MASK(pic, i->irq);
error = intr_event_schedule_thread(ie);
KASSERT(error == 0, ("%s: impossible stray interrupt",
__func__));
} else
- irq_enable(irq);
+ PIC_EOI(pic, i->irq);
+#endif
return;
stray:
- atomic_add_long(&intrcnt[0], 1);
- if (intrcnt[0] <= MAX_STRAY_LOG) {
- printf("stray irq %d\n", irq);
- if (intrcnt[0] >= MAX_STRAY_LOG) {
+ stray_count++;
+ if (stray_count <= MAX_STRAY_LOG) {
+ printf("stray irq %d\n", i->irq);
+ if (stray_count >= MAX_STRAY_LOG) {
printf("got %d stray interrupts, not logging anymore\n",
- MAX_STRAY_LOG);
+ MAX_STRAY_LOG);
}
}
+ if (i != NULL)
+ PIC_MASK(pic, i->irq);
}
diff --git a/sys/powerpc/powerpc/nexus.c b/sys/powerpc/powerpc/nexus.c
index c2b754a..e31ef61 100644
--- a/sys/powerpc/powerpc/nexus.c
+++ b/sys/powerpc/powerpc/nexus.c
@@ -97,7 +97,7 @@ struct nexus_devinfo {
};
struct nexus_softc {
- device_t sc_pic;
+ struct rman sc_rman;
};
/*
@@ -182,12 +182,24 @@ nexus_probe(device_t dev)
phandle_t root;
phandle_t child;
struct nexus_softc *sc;
+ u_long start, end;
if ((root = OF_peer(0)) == -1)
panic("nexus_probe: OF_peer failed.");
sc = device_get_softc(dev);
+ start = 0;
+ end = INTR_VECTORS - 1;
+
+ sc->sc_rman.rm_start = start;
+ sc->sc_rman.rm_end = end;
+ sc->sc_rman.rm_type = RMAN_ARRAY;
+ sc->sc_rman.rm_descr = "Interrupt request lines";
+ if (rman_init(&sc->sc_rman) ||
+ rman_manage_region(&sc->sc_rman, start, end))
+ panic("nexus_probe IRQ rman");
+
/*
* Allow devices to identify
*/
@@ -302,31 +314,40 @@ nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
- driver_filter_t *filter, driver_intr_t *intr, void *arg, void **cookiep)
+ driver_filter_t *filter, driver_intr_t *ihand, void *arg, void **cookiep)
{
- struct nexus_softc *sc;
+ driver_t *driver;
+ int error;
- sc = device_get_softc(dev);
+ /* somebody tried to setup an irq that failed to allocate! */
+ if (res == NULL)
+ panic("nexus_setup_intr: NULL irq resource!");
+
+ *cookiep = 0;
+ if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
+ flags |= INTR_EXCL;
+
+ driver = device_get_driver(child);
+
+ /*
+ * We depend here on rman_activate_resource() being idempotent.
+ */
+ error = rman_activate_resource(res);
+ if (error)
+ return (error);
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_setup_intr: no pic attached\n");
+ error = powerpc_setup_intr(device_get_nameunit(child),
+ rman_get_start(res), filter, ihand, arg, flags, cookiep);
- return (PIC_SETUP_INTR(sc->sc_pic, child, res, flags, filter, intr,
- arg, cookiep));
+ return (error);
}
static int
nexus_teardown_intr(device_t dev, device_t child, struct resource *res,
- void *ih)
+ void *cookie)
{
- struct nexus_softc *sc;
- sc = device_get_softc(dev);
-
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_teardown_intr: no pic attached\n");
-
- return (PIC_TEARDOWN_INTR(sc->sc_pic, child, res, ih));
+ return (powerpc_teardown_intr(cookie));
}
/*
@@ -337,10 +358,8 @@ static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
- struct nexus_softc *sc;
- struct resource *rv;
-
- sc = device_get_softc(bus);
+ struct nexus_softc *sc;
+ struct resource *rv;
if (type != SYS_RES_IRQ) {
device_printf(bus, "unknown resource request from %s\n",
@@ -348,10 +367,21 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
return (NULL);
}
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_alloc_resource: no pic attached\n");
+ if (count == 0 || start + count - 1 != end) {
+ device_printf(bus, "invalid IRQ allocation from %s\n",
+ device_get_nameunit(child));
+ return (NULL);
+ }
- rv = PIC_ALLOCATE_INTR(sc->sc_pic, child, rid, start, flags);
+ sc = device_get_softc(bus);
+
+ rv = rman_reserve_resource(&sc->sc_rman, start, end, count,
+ flags, child);
+ if (rv == NULL) {
+ device_printf(bus, "IRQ allocation failed for %s\n",
+ device_get_nameunit(child));
+ } else
+ rman_set_rid(rv, *rid);
return (rv);
}
@@ -378,9 +408,6 @@ static int
nexus_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)
{
- struct nexus_softc *sc;
-
- sc = device_get_softc(bus);
if (type != SYS_RES_IRQ) {
device_printf(bus, "unknown resource request from %s\n",
@@ -388,10 +415,7 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
return (EINVAL);
}
- if (device_get_state(sc->sc_pic) != DS_ATTACHED)
- panic("nexus_release_resource: no pic attached\n");
-
- return (PIC_RELEASE_INTR(sc->sc_pic, child, rid, res));
+ return (rman_release_resource(res));
}
static device_t
@@ -418,17 +442,6 @@ nexus_device_from_node(device_t parent, phandle_t node)
return (cdev);
}
-int
-nexus_install_intcntlr(device_t dev)
-{
- struct nexus_softc *sc;
-
- sc = device_get_softc(device_get_parent(dev));
- sc->sc_pic = dev;
-
- return (0);
-}
-
static const char *
nexus_ofw_get_name(device_t bus, device_t dev)
{
diff --git a/sys/powerpc/powerpc/openpic.c b/sys/powerpc/powerpc/openpic.c
index 3afc5b9..c6a0863 100644
--- a/sys/powerpc/powerpc/openpic.c
+++ b/sys/powerpc/powerpc/openpic.c
@@ -30,6 +30,7 @@
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <sys/rman.h>
#include <machine/bus.h>
#include <machine/intr.h>
@@ -41,57 +42,38 @@
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <sys/rman.h>
-
#include <machine/openpicreg.h>
#include <machine/openpicvar.h>
#include "pic_if.h"
+devclass_t openpic_devclass;
+
/*
* Local routines
*/
-static u_int openpic_read(struct openpic_softc *, int);
-static void openpic_write(struct openpic_softc *, int, u_int);
-static int openpic_read_irq(struct openpic_softc *, int);
-static void openpic_eoi(struct openpic_softc *, int);
-static void openpic_enable_irq(struct openpic_softc *, int, int);
-static void openpic_disable_irq(struct openpic_softc *, int);
-static void openpic_set_priority(struct openpic_softc *, int, int);
-static void openpic_intr(void);
-static void openpic_ext_enable_irq(uintptr_t);
-static void openpic_ext_disable_irq(uintptr_t);
-
-/* XXX This limits us to one openpic */
-static struct openpic_softc *openpic_softc;
-/*
- * Called at nexus-probe time to allow interrupts to be enabled by
- * devices that are probed before the OpenPIC h/w is probed.
- */
-int
-openpic_early_attach(device_t dev)
+static __inline uint32_t
+openpic_read(struct openpic_softc *sc, u_int reg)
{
- struct openpic_softc *sc;
-
- sc = device_get_softc(dev);
- openpic_softc = sc;
-
- sc->sc_rman.rm_type = RMAN_ARRAY;
- sc->sc_rman.rm_descr = device_get_nameunit(dev);
-
- if (rman_init(&sc->sc_rman) != 0 ||
- rman_manage_region(&sc->sc_rman, 0, OPENPIC_IRQMAX-1) != 0) {
- device_printf(dev, "could not set up resource management");
- return (ENXIO);
- }
+ return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg));
+}
- intr_init(openpic_intr, OPENPIC_IRQMAX, openpic_ext_enable_irq,
- openpic_ext_disable_irq);
+static __inline void
+openpic_write(struct openpic_softc *sc, u_int reg, uint32_t val)
+{
+ bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
+}
- sc->sc_early_done = 1;
+static __inline void
+openpic_set_priority(struct openpic_softc *sc, int cpu, int pri)
+{
+ uint32_t x;
- return (0);
+ x = openpic_read(sc, OPENPIC_CPU_PRIORITY(cpu));
+ x &= ~OPENPIC_CPU_PRIORITY_MASK;
+ x |= pri;
+ openpic_write(sc, OPENPIC_CPU_PRIORITY(cpu), x);
}
int
@@ -102,10 +84,19 @@ openpic_attach(device_t dev)
u_int32_t x;
sc = device_get_softc(dev);
- sc->sc_hwprobed = 1;
+ sc->sc_dev = dev;
- if (!sc->sc_early_done)
- openpic_early_attach(dev);
+ sc->sc_rid = 0;
+ sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
+ RF_ACTIVE);
+
+ if (sc->sc_memr == NULL) {
+ device_printf(dev, "Could not alloc mem resource!\n");
+ return (ENXIO);
+ }
+
+ sc->sc_bt = rman_get_bustag(sc->sc_memr);
+ sc->sc_bh = rman_get_bushandle(sc->sc_memr);
x = openpic_read(sc, OPENPIC_FEATURE);
switch (x & OPENPIC_FEATURE_VERSION_MASK) {
@@ -155,7 +146,7 @@ openpic_attach(device_t dev)
openpic_write(sc, OPENPIC_IDEST(irq), 1 << 0);
for (irq = 0; irq < sc->sc_nirq; irq++) {
- x = irq;
+ x = irq; /* irq == vector. */
x |= OPENPIC_IMASK;
x |= OPENPIC_POLARITY_POSITIVE;
x |= OPENPIC_SENSE_LEVEL;
@@ -170,239 +161,78 @@ openpic_attach(device_t dev)
/* clear all pending interrupts */
for (irq = 0; irq < sc->sc_nirq; irq++) {
- openpic_read_irq(sc, 0);
- openpic_eoi(sc, 0);
+ (void)openpic_read(sc, OPENPIC_IACK(0));
+ openpic_write(sc, OPENPIC_EOI(0), 0);
}
- /* enable pre-h/w reserved irqs, disable all others */
- for (irq = 0; irq < sc->sc_nirq; irq++)
- if (sc->sc_irqrsv[irq])
- openpic_enable_irq(sc, irq, IST_LEVEL);
- else
- openpic_disable_irq(sc, irq);
+ powerpc_register_pic(dev);
return (0);
}
/*
- * PIC interface
+ * PIC I/F methods
*/
-struct resource *
-openpic_allocate_intr(device_t dev, device_t child, int *rid, u_long intr,
- u_int flags)
+void
+openpic_dispatch(device_t dev, struct trapframe *tf)
{
- struct openpic_softc *sc;
- struct resource *rv;
- int needactivate;
+ struct openpic_softc *sc;
+ u_int vector;
sc = device_get_softc(dev);
- needactivate = flags & RF_ACTIVE;
- flags &= ~RF_ACTIVE;
-
- if (sc->sc_hwprobed && (intr > sc->sc_nirq)) {
- device_printf(dev, "interrupt reservation %ld out of range\n",
- intr);
- return (NULL);
- }
-
- rv = rman_reserve_resource(&sc->sc_rman, intr, intr, 1, flags, child);
- if (rv == NULL) {
- device_printf(dev, "interrupt reservation failed for %s\n",
- device_get_nameunit(child));
- return (NULL);
+ while (1) {
+ vector = openpic_read(sc, OPENPIC_IACK(0));
+ vector &= OPENPIC_VECTOR_MASK;
+ if (vector == 255)
+ break;
+ powerpc_dispatch_intr(vector, tf);
}
- rman_set_rid(rv, *rid);
- if (needactivate) {
- if (bus_activate_resource(child, SYS_RES_IRQ, *rid, rv) != 0) {
- device_printf(dev,
- "resource activation failed for %s\n",
- device_get_nameunit(child));
- rman_release_resource(rv);
- return (NULL);
- }
- }
-
- return (rv);
}
-int
-openpic_setup_intr(device_t dev, device_t child, struct resource *res,
- int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
- void **cookiep)
+void
+openpic_enable(device_t dev, u_int irq, u_int vector)
{
- struct openpic_softc *sc;
- u_long start;
- int error;
+ struct openpic_softc *sc;
+ uint32_t x;
sc = device_get_softc(dev);
- start = rman_get_start(res);
-
- if (res == NULL) {
- device_printf(dev, "null interrupt resource from %s\n",
- device_get_nameunit(child));
- return (EINVAL);
- }
-
- if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
- flags |= INTR_EXCL;
-
- /*
- * We depend here on rman_activate_resource() being idempotent.
- */
- error = rman_activate_resource(res);
- if (error)
- return (error);
-
- error = inthand_add(device_get_nameunit(child), start, filt, intr, arg,
- flags, cookiep);
-
- if (sc->sc_hwprobed)
- openpic_enable_irq(sc, start, IST_LEVEL);
- else
- sc->sc_irqrsv[start] = 1;
-
- return (error);
-}
-
-int
-openpic_teardown_intr(device_t dev, device_t child, struct resource *res,
- void *ih)
-{
- int error;
-
- error = rman_deactivate_resource(res);
- if (error)
- return (error);
-
- error = inthand_remove(rman_get_start(res), ih);
-
- return (error);
-}
-
-int
-openpic_release_intr(device_t dev, device_t child, int rid,
- struct resource *res)
-{
- int error;
-
- if (rman_get_flags(res) & RF_ACTIVE) {
- error = bus_deactivate_resource(child, SYS_RES_IRQ, rid, res);
- if (error)
- return (error);
- }
-
- return (rman_release_resource(res));
-}
-
-/*
- * Local routines
- */
-
-static u_int
-openpic_read(struct openpic_softc *sc, int reg)
-{
- return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg));
-}
-
-static void
-openpic_write(struct openpic_softc *sc, int reg, u_int val)
-{
- bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
-}
-
-static int
-openpic_read_irq(struct openpic_softc *sc, int cpu)
-{
- return openpic_read(sc, OPENPIC_IACK(cpu)) & OPENPIC_VECTOR_MASK;
-}
-
-static void
-openpic_eoi(struct openpic_softc *sc, int cpu)
-{
- openpic_write(sc, OPENPIC_EOI(cpu), 0);
+ x = openpic_read(sc, OPENPIC_SRC_VECTOR(irq));
+ x &= ~(OPENPIC_IMASK | OPENPIC_VECTOR_MASK);
+ x |= vector;
+ openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
}
-static void
-openpic_enable_irq(struct openpic_softc *sc, int irq, int type)
+void
+openpic_eoi(device_t dev, u_int irq __unused)
{
- u_int x;
+ struct openpic_softc *sc;
- x = openpic_read(sc, OPENPIC_SRC_VECTOR(irq));
- x &= ~(OPENPIC_IMASK | OPENPIC_SENSE_LEVEL | OPENPIC_SENSE_EDGE);
- if (type == IST_LEVEL)
- x |= OPENPIC_SENSE_LEVEL;
- else
- x |= OPENPIC_SENSE_EDGE;
- openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
+ sc = device_get_softc(dev);
+ openpic_write(sc, OPENPIC_EOI(0), 0);
}
-static void
-openpic_disable_irq(struct openpic_softc *sc, int irq)
+void
+openpic_mask(device_t dev, u_int irq)
{
- u_int x;
+ struct openpic_softc *sc;
+ uint32_t x;
+ sc = device_get_softc(dev);
x = openpic_read(sc, OPENPIC_SRC_VECTOR(irq));
x |= OPENPIC_IMASK;
openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
+ openpic_write(sc, OPENPIC_EOI(0), 0);
}
-static void
-openpic_set_priority(struct openpic_softc *sc, int cpu, int pri)
-{
- u_int x;
-
- x = openpic_read(sc, OPENPIC_CPU_PRIORITY(cpu));
- x &= ~OPENPIC_CPU_PRIORITY_MASK;
- x |= pri;
- openpic_write(sc, OPENPIC_CPU_PRIORITY(cpu), x);
-}
-
-static void
-openpic_intr(void)
+void
+openpic_unmask(device_t dev, u_int irq)
{
struct openpic_softc *sc;
- int irq;
- u_int32_t msr;
-
- sc = openpic_softc;
- msr = mfmsr();
-
- irq = openpic_read_irq(sc, 0);
- if (irq == 255) {
- return;
- }
-
-start:
- openpic_disable_irq(sc, irq);
- /*mtmsr(msr | PSL_EE);*/
+ uint32_t x;
- /* do the interrupt thang */
- intr_handle(irq);
-
- mtmsr(msr);
-
- openpic_eoi(sc, 0);
-
- irq = openpic_read_irq(sc, 0);
- if (irq != 255)
- goto start;
-}
-
-static void
-openpic_ext_enable_irq(uintptr_t irq)
-{
- if (!openpic_softc->sc_hwprobed)
- return;
-
- openpic_enable_irq(openpic_softc, irq, IST_LEVEL);
-}
-
-static void
-openpic_ext_disable_irq(uintptr_t irq)
-{
- if (!openpic_softc->sc_hwprobed)
- return;
-
- openpic_disable_irq(openpic_softc, irq);
+ sc = device_get_softc(dev);
+ x = openpic_read(sc, OPENPIC_SRC_VECTOR(irq));
+ x &= ~OPENPIC_IMASK;
+ openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
}
diff --git a/sys/powerpc/powerpc/pic_if.m b/sys/powerpc/powerpc/pic_if.m
index 2b22b0f..9db9c16 100644
--- a/sys/powerpc/powerpc/pic_if.m
+++ b/sys/powerpc/powerpc/pic_if.m
@@ -28,38 +28,32 @@
#
#include <sys/bus.h>
+#include <machine/frame.h>
INTERFACE pic;
-METHOD struct resource * allocate_intr {
+METHOD void dispatch {
device_t dev;
- device_t child;
- int *rid;
- u_long intr;
- u_int flags;
+ struct trapframe *tf;
};
-METHOD int setup_intr {
+METHOD void enable {
device_t dev;
- device_t child;
- struct resource *res;
- int flags;
- driver_filter_t *filter;
- driver_intr_t *intr;
- void *arg;
- void **cookiep;
+ u_int irq;
+ u_int vector;
};
-METHOD int teardown_intr {
+METHOD void eoi {
device_t dev;
- device_t child;
- struct resource *res;
- void *ih;
+ u_int irq;
};
-METHOD int release_intr {
+METHOD void mask {
device_t dev;
- device_t child;
- int rid;
- struct resource *res;
+ u_int irq;
+};
+
+METHOD void unmask {
+ device_t dev;
+ u_int irq;
};
diff --git a/sys/powerpc/psim/openpic_iobus.c b/sys/powerpc/psim/openpic_iobus.c
index 9be65a8..a3a69d3 100644
--- a/sys/powerpc/psim/openpic_iobus.c
+++ b/sys/powerpc/psim/openpic_iobus.c
@@ -60,117 +60,33 @@ __FBSDID("$FreeBSD$");
#include "pic_if.h"
-struct openpic_iobus_softc {
- struct openpic_softc osc;
- struct resource *sc_memr; /* iobus mem resource */
- device_t sc_ndev; /* nexus device */
-};
-
-static struct openpic_iobus_softc *ppicsoftc;
-
/*
- * MacIO interface
+ * PSIM IOBus interface
*/
-static void openpic_psim_identify(driver_t *, device_t);
-static int openpic_psim_probe(device_t);
-static int openpic_psim_attach(device_t);
static int openpic_iobus_probe(device_t);
-static int openpic_iobus_attach(device_t);
-/*
- * Nexus attachment
- */
-static device_method_t openpic_psim_methods[] = {
+static device_method_t openpic_iobus_methods[] = {
/* Device interface */
- DEVMETHOD(device_identify, openpic_psim_identify),
- DEVMETHOD(device_probe, openpic_psim_probe),
- DEVMETHOD(device_attach, openpic_psim_attach),
+ DEVMETHOD(device_probe, openpic_iobus_probe),
+ DEVMETHOD(device_attach, openpic_attach),
/* PIC interface */
- DEVMETHOD(pic_allocate_intr, openpic_allocate_intr),
- DEVMETHOD(pic_setup_intr, openpic_setup_intr),
- DEVMETHOD(pic_teardown_intr, openpic_teardown_intr),
- DEVMETHOD(pic_release_intr, openpic_release_intr),
+ DEVMETHOD(pic_dispatch, openpic_dispatch),
+ DEVMETHOD(pic_enable, openpic_enable),
+ DEVMETHOD(pic_eoi, openpic_eoi),
+ DEVMETHOD(pic_mask, openpic_mask),
+ DEVMETHOD(pic_unmask, openpic_unmask),
{ 0, 0 }
};
-static driver_t openpic_psim_driver = {
- "openpic",
- openpic_psim_methods,
- sizeof(struct openpic_iobus_softc)
-};
-
-static devclass_t openpic_psim_devclass;
-
-DRIVER_MODULE(openpic_psim, nexus, openpic_psim_driver, openpic_psim_devclass,
- 0, 0);
-
-static void
-openpic_psim_identify(driver_t *driver, device_t parent)
-{
- device_t child;
- phandle_t pic;
-
- pic = OF_finddevice("/iobus/opic");
- if (pic == -1)
- return;
-
- child = BUS_ADD_CHILD(parent, 0, "openpic", 0);
- if (child != NULL)
- nexus_set_device_type(child, "psim");
-}
-
-static int
-openpic_psim_probe(device_t dev)
-{
- char *name;
- char *type;
-
- name = nexus_get_name(dev);
- type = nexus_get_device_type(dev);
-
- if (strcmp(name, "openpic") != 0 ||
- strcmp(type, "psim") != 0)
- return (ENXIO);
-
- device_set_desc(dev, OPENPIC_DEVSTR);
- return (0);
-}
-
-static int
-openpic_psim_attach(device_t dev)
-{
- KASSERT(ppicsoftc == NULL, ("iobus openpic: already probed"));
- ppicsoftc = device_get_softc(dev);
- ppicsoftc->sc_ndev = dev;
-
- nexus_install_intcntlr(dev);
- openpic_early_attach(dev);
- return (0);
-}
-
-/*
- * PSIM IOBus attachment
- */
-static device_method_t openpic_iobus_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, openpic_iobus_probe),
- DEVMETHOD(device_attach, openpic_iobus_attach),
-
- { 0, 0 },
-};
-
static driver_t openpic_iobus_driver = {
- "openpiciobus",
+ "openpic",
openpic_iobus_methods,
- 0
+ sizeof(struct openpic_softc)
};
-static devclass_t openpic_iobus_devclass;
-
-DRIVER_MODULE(openpiciobus, iobus, openpic_iobus_driver,
- openpic_iobus_devclass, 0, 0);
+DRIVER_MODULE(openpic, iobus, openpic_iobus_driver, openpic_devclass, 0, 0);
static int
openpic_iobus_probe(device_t dev)
@@ -179,42 +95,12 @@ openpic_iobus_probe(device_t dev)
name = iobus_get_name(dev);
if (strcmp(name, "interrupt-controller") != 0)
- return (ENXIO);
+ return (ENXIO);
/*
* The description was already printed out in the nexus
* probe, so don't do it again here
*/
- device_set_desc(dev, "OpenPIC IOBus interrupt cell");
- if (!bootverbose)
- device_quiet(dev);
+ device_set_desc(dev, OPENPIC_DEVSTR);
return (0);
}
-
-static int
-openpic_iobus_attach(device_t dev)
-{
- struct openpic_iobus_softc *sc;
- int rid;
-
- sc = ppicsoftc;
- KASSERT(sc != NULL, ("pic not nexus-probed\n"));
-
- rid = 0;
- sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
-
- if (sc->sc_memr == NULL) {
- device_printf(dev, "Could not alloc mem resource!\n");
- return (ENXIO);
- }
-
- sc->osc.sc_psim = 1;
- sc->osc.sc_bt = rman_get_bustag(sc->sc_memr);
- sc->osc.sc_bh = rman_get_bushandle(sc->sc_memr);
- sc->osc.sc_altdev = dev;
-
- return (openpic_attach(sc->sc_ndev));
-}
-
-
OpenPOWER on IntegriCloud