summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/powerpc/include/intr_machdep.h12
-rw-r--r--sys/powerpc/include/openpicvar.h2
-rw-r--r--sys/powerpc/mambo/mambo_openpic.c21
-rw-r--r--sys/powerpc/mpc85xx/atpic.c15
-rw-r--r--sys/powerpc/mpc85xx/isa.c8
-rw-r--r--sys/powerpc/mpc85xx/openpic_fdt.c11
-rw-r--r--sys/powerpc/mpc85xx/pci_fdt.c109
-rw-r--r--sys/powerpc/powermac/cpcht.c16
-rw-r--r--sys/powerpc/powermac/hrowpic.c13
-rw-r--r--sys/powerpc/powermac/openpic_macio.c13
-rw-r--r--sys/powerpc/powerpc/intr_machdep.c112
-rw-r--r--sys/powerpc/powerpc/openpic.c5
-rw-r--r--sys/powerpc/powerpc/pic_if.m4
-rw-r--r--sys/powerpc/ps3/ps3pic.c13
-rw-r--r--sys/powerpc/psim/openpic_iobus.c10
15 files changed, 162 insertions, 202 deletions
diff --git a/sys/powerpc/include/intr_machdep.h b/sys/powerpc/include/intr_machdep.h
index 67d7e79..d0c6c1b 100644
--- a/sys/powerpc/include/intr_machdep.h
+++ b/sys/powerpc/include/intr_machdep.h
@@ -29,13 +29,9 @@
#define _MACHINE_INTR_MACHDEP_H_
#define INTR_VECTORS 256
-#define MAX_PICS 5
-#define IGN_SHIFT 8
-#define INTR_INTLINE(irq) (irq & ((1 << IGN_SHIFT) - 1))
-#define INTR_IGN(irq) (irq >> IGN_SHIFT)
-
-#define INTR_VEC(pic_id, irq) ((powerpc_ign_lookup(pic_id) << IGN_SHIFT) | (irq))
+#define MAX_PICS 5
+#define INTR_VEC(node, pin) powerpc_get_irq(node, pin)
/*
* Default base address for MSI messages on PowerPC
@@ -50,8 +46,8 @@ driver_filter_t powerpc_ipi_handler;
void intrcnt_add(const char *name, u_long **countp);
-void powerpc_register_pic(device_t, u_int);
-int powerpc_ign_lookup(uint32_t pic_id);
+void powerpc_register_pic(device_t, uint32_t, u_int, u_int, u_int);
+u_int powerpc_get_irq(uint32_t, u_int);
void powerpc_dispatch_intr(u_int, struct trapframe *);
int powerpc_enable_intr(void);
diff --git a/sys/powerpc/include/openpicvar.h b/sys/powerpc/include/openpicvar.h
index 5468542..4fb9aa7 100644
--- a/sys/powerpc/include/openpicvar.h
+++ b/sys/powerpc/include/openpicvar.h
@@ -52,7 +52,7 @@ extern devclass_t openpic_devclass;
/*
* Bus-independent attach i/f
*/
-int openpic_attach(device_t);
+int openpic_common_attach(device_t, uint32_t);
/*
* PIC interface.
diff --git a/sys/powerpc/mambo/mambo_openpic.c b/sys/powerpc/mambo/mambo_openpic.c
index 3edb027..883c9d7 100644
--- a/sys/powerpc/mambo/mambo_openpic.c
+++ b/sys/powerpc/mambo/mambo_openpic.c
@@ -56,12 +56,11 @@ __FBSDID("$FreeBSD$");
* Mambo interface
*/
static int openpic_mambo_probe(device_t);
-static uint32_t openpic_mambo_id(device_t dev);
+static int openpic_mambo_attach(device_t);
static int openpicbus_mambo_probe(device_t dev);
static int openpicbus_mambo_attach(device_t dev);
-static struct resource *openpicbus_alloc_resource(device_t bus, device_t dev,
- int type, int *rid, u_long start, u_long end, u_long count,
- u_int flags);
+static struct resource *openpicbus_alloc_resource(device_t bus, device_t dev,
+ int type, int *rid, u_long start, u_long end, u_long count, u_int flags);
static device_method_t openpicbus_mambo_methods[] = {
/* Device interface */
@@ -87,7 +86,7 @@ static driver_t openpicbus_mambo_driver = {
static device_method_t openpic_mambo_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpic_mambo_probe),
- DEVMETHOD(device_attach, openpic_attach),
+ DEVMETHOD(device_attach, openpic_mambo_attach),
/* PIC interface */
DEVMETHOD(pic_config, openpic_config),
@@ -97,7 +96,6 @@ static device_method_t openpic_mambo_methods[] = {
DEVMETHOD(pic_ipi, openpic_ipi),
DEVMETHOD(pic_mask, openpic_mask),
DEVMETHOD(pic_unmask, openpic_unmask),
- DEVMETHOD(pic_id, openpic_mambo_id),
{ 0, 0 },
};
@@ -167,14 +165,15 @@ openpicbus_alloc_resource(device_t bus, device_t dev, int type, int *rid,
static int
openpic_mambo_probe(device_t dev)
{
+
device_set_desc(dev, OPENPIC_DEVSTR);
-
return (0);
}
-static uint32_t
-openpic_mambo_id(device_t dev)
+static int
+openpic_mambo_attach(device_t dev)
{
- return (ofw_bus_get_node(device_get_parent(dev)));
+
+ return (openpic_common_attach(dev,
+ ofw_bus_get_node(device_get_parent(dev))));
}
-
diff --git a/sys/powerpc/mpc85xx/atpic.c b/sys/powerpc/mpc85xx/atpic.c
index e903dbc..e1d0b39 100644
--- a/sys/powerpc/mpc85xx/atpic.c
+++ b/sys/powerpc/mpc85xx/atpic.c
@@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/intr_machdep.h>
-#include <machine/ocpbus.h>
#include <machine/pio.h>
#include <powerpc/mpc85xx/mpc85xx.h>
@@ -79,7 +78,6 @@ static void atpic_eoi(device_t, u_int);
static void atpic_ipi(device_t, u_int);
static void atpic_mask(device_t, u_int);
static void atpic_unmask(device_t, u_int);
-static uint32_t atpic_id (device_t dev);
static device_method_t atpic_isa_methods[] = {
/* Device interface */
@@ -95,7 +93,6 @@ static device_method_t atpic_isa_methods[] = {
DEVMETHOD(pic_ipi, atpic_ipi),
DEVMETHOD(pic_mask, atpic_mask),
DEVMETHOD(pic_unmask, atpic_unmask),
- DEVMETHOD(pic_id, atpic_id),
{ 0, 0 },
};
@@ -154,7 +151,7 @@ atpic_isa_identify(driver_t *drv, device_t parent)
bus_set_resource(child, SYS_RES_IOPORT, ATPIC_SLAVE, IO_ICU2, 2);
/* ISA interrupts are routed through external interrupt 0. */
- bus_set_resource(child, SYS_RES_IRQ, 0, PIC_IRQ_EXT(0), 1);
+ bus_set_resource(child, SYS_RES_IRQ, 0, 16, 1);
}
static int
@@ -221,7 +218,7 @@ atpic_isa_attach(device_t dev)
atpic_init(sc, ATPIC_SLAVE);
atpic_init(sc, ATPIC_MASTER);
- powerpc_register_pic(dev, 0x10);
+ powerpc_register_pic(dev, 0, 16, 0, TRUE);
return (0);
fail:
@@ -328,11 +325,3 @@ atpic_unmask(device_t dev, u_int irq)
atpic_write(sc, ATPIC_MASTER, 1, sc->sc_mask[ATPIC_MASTER]);
}
}
-
-static uint32_t
-atpic_id (device_t dev)
-{
-
- return (ATPIC_ID);
-}
-
diff --git a/sys/powerpc/mpc85xx/isa.c b/sys/powerpc/mpc85xx/isa.c
index eeffbfd..a1715ef 100644
--- a/sys/powerpc/mpc85xx/isa.c
+++ b/sys/powerpc/mpc85xx/isa.c
@@ -33,15 +33,12 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/intr_machdep.h>
-#include <machine/ocpbus.h>
#include <machine/resource.h>
#include <isa/isareg.h>
#include <isa/isavar.h>
#include <isa/isa_common.h>
-#include "ocpbus.h"
-
void
isa_init(device_t dev)
{
@@ -62,10 +59,7 @@ isa_alloc_resource(device_t bus, device_t child, int type, int *rid,
resource_list_find(rl, type, *rid) == NULL) {
switch (type) {
case SYS_RES_IOPORT: rids = ISA_PNP_NPORT; break;
- case SYS_RES_IRQ:
- rids = ISA_PNP_NIRQ;
- start = ISA_IRQ(start);
- break;
+ case SYS_RES_IRQ: rids = ISA_PNP_NIRQ; break;
case SYS_RES_MEMORY: rids = ISA_PNP_NMEM; break;
default: rids = 0; break;
}
diff --git a/sys/powerpc/mpc85xx/openpic_fdt.c b/sys/powerpc/mpc85xx/openpic_fdt.c
index da70542..7cf18ea 100644
--- a/sys/powerpc/mpc85xx/openpic_fdt.c
+++ b/sys/powerpc/mpc85xx/openpic_fdt.c
@@ -45,12 +45,12 @@ __FBSDID("$FreeBSD$");
#include "pic_if.h"
static int openpic_fdt_probe(device_t);
-static uint32_t openpic_fdt_id(device_t);
+static int openpic_fdt_attach(device_t);
static device_method_t openpic_fdt_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpic_fdt_probe),
- DEVMETHOD(device_attach, openpic_attach),
+ DEVMETHOD(device_attach, openpic_fdt_attach),
/* PIC interface */
DEVMETHOD(pic_bind, openpic_bind),
@@ -61,7 +61,6 @@ static device_method_t openpic_fdt_methods[] = {
DEVMETHOD(pic_ipi, openpic_ipi),
DEVMETHOD(pic_mask, openpic_mask),
DEVMETHOD(pic_unmask, openpic_unmask),
- DEVMETHOD(pic_id, openpic_fdt_id),
{ 0, 0 },
};
@@ -85,9 +84,9 @@ openpic_fdt_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}
-static uint32_t
-openpic_fdt_id(device_t dev)
+static int
+openpic_fdt_attach(device_t dev)
{
- return (ofw_bus_get_node(dev));
+ return (openpic_common_attach(dev, ofw_bus_get_node(dev)));
}
diff --git a/sys/powerpc/mpc85xx/pci_fdt.c b/sys/powerpc/mpc85xx/pci_fdt.c
index 9d67aae..7965167 100644
--- a/sys/powerpc/mpc85xx/pci_fdt.c
+++ b/sys/powerpc/mpc85xx/pci_fdt.c
@@ -136,7 +136,7 @@ static int fsl_pcib_decode_win(phandle_t, struct fsl_pcib_softc *);
static void fsl_pcib_err_init(device_t);
static void fsl_pcib_inbound(struct fsl_pcib_softc *, int, int, u_long,
u_long, u_long);
-static int fsl_pcib_init(struct fsl_pcib_softc *, int, int, int);
+static int fsl_pcib_init(struct fsl_pcib_softc *, int, int);
static int fsl_pcib_intr_info(phandle_t, struct fsl_pcib_softc *);
static int fsl_pcib_set_range(struct fsl_pcib_softc *, int, int, u_long,
u_long);
@@ -160,8 +160,6 @@ static uint32_t fsl_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int);
static void fsl_pcib_write_config(device_t, u_int, u_int, u_int, u_int,
uint32_t, int);
-static int next_busnr = 0;
-
/* Configuration r/w mutex. */
struct mtx pcicfg_mtx;
static int mtx_initialized = 0;
@@ -215,23 +213,17 @@ DRIVER_MODULE(pcib, fdtbus, fsl_pcib_driver, pcib_devclass, 0, 0);
static int
fsl_pcib_probe(device_t dev)
{
- phandle_t parnode;
+ phandle_t node;
- /*
- * The PCI subnode does not have the 'compatible' property, so we need
- * to check in the parent PCI node. However the parent is not
- * represented by a separate ofw_bus child, and therefore
- * ofw_bus_is_compatible() cannot be used, but direct fdt equivalent.
- */
- parnode = OF_parent(ofw_bus_get_node(dev));
- if (parnode == 0)
+ node = ofw_bus_get_node(dev);
+ if (!fdt_is_type(node, "pci"))
return (ENXIO);
- if (!(fdt_is_compatible(parnode, "fsl,mpc8548-pcie") ||
- fdt_is_compatible(parnode, "fsl,mpc8548-pcie")))
+
+ if (!(fdt_is_compatible(node, "fsl,mpc8540-pci") ||
+ fdt_is_compatible(node, "fsl,mpc8548-pcie")))
return (ENXIO);
device_set_desc(dev, "Freescale Integrated PCI/PCI-E Controller");
-
return (BUS_PROBE_DEFAULT);
}
@@ -241,7 +233,7 @@ fsl_pcib_attach(device_t dev)
struct fsl_pcib_softc *sc;
phandle_t node;
uint32_t cfgreg;
- int maxslot, subbus;
+ int maxslot;
uint8_t ltssm, capptr;
sc = device_get_softc(dev);
@@ -304,23 +296,13 @@ fsl_pcib_attach(device_t dev)
sc->sc_devfn_tundra = -1;
sc->sc_devfn_via_ide = -1;
- maxslot = (sc->sc_pcie) ? 1 : 31;
/*
- * Scan bus using firmware configured, 0 based bus numbering,
- * let fsl_pcib_init() shift bus number by next_busnr offset.
+ * Scan bus using firmware configured, 0 based bus numbering.
*/
- sc->sc_busnr = 1;
- subbus = fsl_pcib_init(sc, 0, next_busnr, maxslot);
-
- if (bootverbose)
- printf("PCI: domain %d, busnr = %d, next_busnr = %d\n",
- device_get_unit(dev), next_busnr + 1,
- next_busnr + subbus + 1);
-
- /* Set final busnr */
- sc->sc_busnr = next_busnr + 1;
- next_busnr += subbus + 1;
+ sc->sc_busnr = 0;
+ maxslot = (sc->sc_pcie) ? 0 : PCI_SLOTMAX;
+ fsl_pcib_init(sc, sc->sc_busnr, maxslot);
if (sc->sc_pcie) {
ltssm = fsl_pcib_cfgread(sc, 0, 0, 0, PCIR_LTSSM, 1);
@@ -455,7 +437,7 @@ fsl_pcib_maxslots(device_t dev)
{
struct fsl_pcib_softc *sc = device_get_softc(dev);
- return ((sc->sc_pcie) ? 1 : 31);
+ return ((sc->sc_pcie) ? 0 : PCI_SLOTMAX);
}
static uint32_t
@@ -572,14 +554,11 @@ fsl_pcib_route_int(struct fsl_pcib_softc *sc, u_int bus, u_int slot, u_int func,
devfn = DEVFN(bus, slot, func);
if (devfn == sc->sc_devfn_via_ide)
-#if 0
- intline = INTR_VEC(ATPIC_ID, 14);
+ intline = INTR_VEC(0, 14);
else if (devfn == sc->sc_devfn_via_ide + 1)
- intline = INTR_VEC(ATPIC_ID, 10);
+ intline = INTR_VEC(0, 10);
else if (devfn == sc->sc_devfn_via_ide + 2)
- intline = INTR_VEC(ATPIC_ID, 10);
-#endif
- ;
+ intline = INTR_VEC(0, 10);
else {
if (intpin != 0)
err = fdt_pci_route_intr(bus, slot, func, intpin,
@@ -596,10 +575,9 @@ fsl_pcib_route_int(struct fsl_pcib_softc *sc, u_int bus, u_int slot, u_int func,
}
static int
-fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int busnr_offset,
- int maxslot)
+fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int maxslot)
{
- int secbus, subbus;
+ int secbus;
int old_pribus, old_secbus, old_subbus;
int new_pribus, new_secbus, new_subbus;
int slot, func, maxfunc;
@@ -608,11 +586,10 @@ fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int busnr_offset,
uint8_t command, hdrtype, class, subclass;
uint8_t intline, intpin;
- subbus = bus;
+ secbus = bus;
for (slot = 0; slot <= maxslot; slot++) {
maxfunc = 0;
for (func = 0; func <= maxfunc; func++) {
-
hdrtype = fsl_pcib_read_config(sc->sc_dev, bus, slot,
func, PCIR_HDRTYPE, 1);
@@ -667,19 +644,14 @@ fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int busnr_offset,
func, PCIR_CLASS, 1);
subclass = fsl_pcib_read_config(sc->sc_dev, bus, slot,
func, PCIR_SUBCLASS, 1);
-#if 0
+
/* Allow only proper PCI-PCI briges */
if (class != PCIC_BRIDGE)
continue;
if (subclass != PCIS_BRIDGE_PCI)
continue;
-#endif
- /* Allow all DEVTYPE 1 devices */
- if (hdrtype != PCIM_HDRTYPE_BRIDGE)
- continue;
- subbus++;
- secbus = subbus;
+ secbus++;
/* Program I/O decoder. */
fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
@@ -718,31 +690,20 @@ fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int busnr_offset,
if (bootverbose)
printf("PCI: reading firmware bus numbers for "
"secbus = %d (bus/sec/sub) = (%d/%d/%d)\n",
- secbus + busnr_offset, old_pribus,
- old_secbus, old_subbus);
+ secbus, old_pribus, old_secbus, old_subbus);
- /* Skip unconfigured devices */
- if ((old_pribus == 0) &&
- (old_secbus == 0) && (old_subbus == 0))
- continue;
-
- subbus += fsl_pcib_init(sc, secbus, busnr_offset,
- (subclass == PCIS_BRIDGE_PCI) ? 31 : 1);
+ new_pribus = bus;
+ new_secbus = secbus;
- new_pribus = bus + busnr_offset;
- new_secbus = secbus + busnr_offset;
- new_subbus = subbus + busnr_offset;
+ secbus = fsl_pcib_init(sc, secbus,
+ (subclass == PCIS_BRIDGE_PCI) ? PCI_SLOTMAX : 0);
- /* Fixup pribus for MPC8572 PCIE controller */
- if ((vendor == 0x1957) && ((device = 0x0040) ||
- (device == 0x0041)))
- new_pribus = 0;
+ new_subbus = secbus;
if (bootverbose)
- printf("PCI: translate firmware bus numbers for "
- "secbus %d (%d/%d/%d) -> (%d/%d/%d)\n",
- secbus + busnr_offset,
- old_pribus, old_secbus, old_subbus,
+ printf("PCI: translate firmware bus numbers "
+ "for secbus %d (%d/%d/%d) -> (%d/%d/%d)\n",
+ secbus, old_pribus, old_secbus, old_subbus,
new_pribus, new_secbus, new_subbus);
fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
@@ -754,11 +715,7 @@ fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int busnr_offset,
}
}
- if (bootverbose)
- printf("PCI: bus %d, #subbus = %d\n",
- bus + busnr_offset, subbus - bus);
-
- return (subbus - bus);
+ return (secbus);
}
static void
@@ -938,12 +895,10 @@ fsl_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
va = sc->sc_iomem_va;
break;
case SYS_RES_IRQ:
-#if 0
- if (INTR_IGN(start) == powerpc_ign_lookup(ATPIC_ID)) {
+ if (start < 16) {
device_printf(dev, "%s requested ISA interrupt %lu\n",
device_get_nameunit(child), start);
}
-#endif
flags |= RF_SHAREABLE;
return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
type, rid, start, end, count, flags));
diff --git a/sys/powerpc/powermac/cpcht.c b/sys/powerpc/powermac/cpcht.c
index 4ee6aee..9359cd8 100644
--- a/sys/powerpc/powermac/cpcht.c
+++ b/sys/powerpc/powermac/cpcht.c
@@ -757,7 +757,6 @@ static void openpic_cpcht_config(device_t, u_int irq,
static void openpic_cpcht_enable(device_t, u_int irq, u_int vector);
static void openpic_cpcht_unmask(device_t, u_int irq);
static void openpic_cpcht_eoi(device_t, u_int irq);
-static uint32_t openpic_cpcht_id(device_t);
static device_method_t openpic_cpcht_methods[] = {
/* Device interface */
@@ -773,7 +772,6 @@ static device_method_t openpic_cpcht_methods[] = {
DEVMETHOD(pic_ipi, openpic_ipi),
DEVMETHOD(pic_mask, openpic_mask),
DEVMETHOD(pic_unmask, openpic_cpcht_unmask),
- DEVMETHOD(pic_id, openpic_cpcht_id),
{ 0, 0 },
};
@@ -808,9 +806,11 @@ static int
openpic_cpcht_attach(device_t dev)
{
struct openpic_cpcht_softc *sc;
+ phandle_t node;
int err, irq;
- err = openpic_attach(dev);
+ node = ofw_bus_get_node(dev);
+ err = openpic_common_attach(dev, node);
if (err != 0)
return (err);
@@ -839,9 +839,8 @@ openpic_cpcht_attach(device_t dev)
* be necessary, but Linux does it, and I cannot find any U3 machines
* with MSI devices to test.
*/
-
if (dev == root_pic)
- cpcht_msipic = PIC_ID(dev);
+ cpcht_msipic = node;
return (0);
}
@@ -981,10 +980,3 @@ openpic_cpcht_eoi(device_t dev, u_int irq)
openpic_eoi(dev, irq);
}
-
-static uint32_t
-openpic_cpcht_id(device_t dev)
-{
- return (ofw_bus_get_node(dev));
-}
-
diff --git a/sys/powerpc/powermac/hrowpic.c b/sys/powerpc/powermac/hrowpic.c
index 0e839d9..0142173 100644
--- a/sys/powerpc/powermac/hrowpic.c
+++ b/sys/powerpc/powermac/hrowpic.c
@@ -69,7 +69,6 @@ static void hrowpic_eoi(device_t, u_int);
static void hrowpic_ipi(device_t, u_int);
static void hrowpic_mask(device_t, u_int);
static void hrowpic_unmask(device_t, u_int);
-static uint32_t hrowpic_id(device_t dev);
static device_method_t hrowpic_methods[] = {
/* Device interface */
@@ -80,7 +79,6 @@ static device_method_t hrowpic_methods[] = {
DEVMETHOD(pic_dispatch, hrowpic_dispatch),
DEVMETHOD(pic_enable, hrowpic_enable),
DEVMETHOD(pic_eoi, hrowpic_eoi),
- DEVMETHOD(pic_id, hrowpic_id),
DEVMETHOD(pic_ipi, hrowpic_ipi),
DEVMETHOD(pic_mask, hrowpic_mask),
DEVMETHOD(pic_unmask, hrowpic_unmask),
@@ -169,9 +167,7 @@ hrowpic_attach(device_t dev)
hrowpic_write_reg(sc, HPIC_ENABLE, HPIC_SECONDARY, 0);
hrowpic_write_reg(sc, HPIC_CLEAR, HPIC_SECONDARY, 0xffffffff);
- powerpc_register_pic(dev, 64);
- root_pic = dev; /* Heathrow systems have only one PIC */
-
+ powerpc_register_pic(dev, ofw_bus_get_node(dev), 64, 0, FALSE);
return (0);
}
@@ -282,10 +278,3 @@ hrowpic_unmask(device_t dev, u_int irq)
sc = device_get_softc(dev);
hrowpic_toggle_irq(sc, irq, 1);
}
-
-static uint32_t
-hrowpic_id(device_t dev)
-{
- return (ofw_bus_get_node(dev));
-}
-
diff --git a/sys/powerpc/powermac/openpic_macio.c b/sys/powerpc/powermac/openpic_macio.c
index 880b8f7..e542ae3 100644
--- a/sys/powerpc/powermac/openpic_macio.c
+++ b/sys/powerpc/powermac/openpic_macio.c
@@ -58,12 +58,12 @@ __FBSDID("$FreeBSD$");
* MacIO interface
*/
static int openpic_macio_probe(device_t);
-static uint32_t openpic_macio_id(device_t);
+static int openpic_macio_attach(device_t);
static device_method_t openpic_macio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpic_macio_probe),
- DEVMETHOD(device_attach, openpic_attach),
+ DEVMETHOD(device_attach, openpic_macio_attach),
/* PIC interface */
DEVMETHOD(pic_bind, openpic_bind),
@@ -74,7 +74,6 @@ static device_method_t openpic_macio_methods[] = {
DEVMETHOD(pic_ipi, openpic_ipi),
DEVMETHOD(pic_mask, openpic_mask),
DEVMETHOD(pic_unmask, openpic_unmask),
- DEVMETHOD(pic_id, openpic_macio_id),
{ 0, 0 },
};
@@ -99,9 +98,9 @@ openpic_macio_probe(device_t dev)
return (0);
}
-static uint32_t
-openpic_macio_id(device_t dev)
+static int
+openpic_macio_attach(device_t dev)
{
- return (ofw_bus_get_node(dev));
+
+ return (openpic_common_attach(dev, ofw_bus_get_node(dev)));
}
-
diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c
index a33bddb..b8b703d 100644
--- a/sys/powerpc/powerpc/intr_machdep.c
+++ b/sys/powerpc/powerpc/intr_machdep.c
@@ -60,6 +60,8 @@
* $FreeBSD$
*/
+#include "opt_isa.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -102,9 +104,11 @@ struct powerpc_intr {
};
struct pic {
- device_t pic;
- uint32_t pic_id;
- int ipi_irq;
+ device_t dev;
+ uint32_t node;
+ u_int irqs;
+ u_int ipis;
+ int base;
};
static u_int intrcnt_index = 0;
@@ -113,6 +117,11 @@ static struct powerpc_intr *powerpc_intrs[INTR_VECTORS];
static struct pic piclist[MAX_PICS];
static u_int nvectors; /* Allocated vectors */
static u_int npics; /* PICs registered */
+#ifdef DEV_ISA
+static u_int nirqs = 16; /* Allocated IRQS (ISA pre-allocated). */
+#else
+static u_int nirqs = 0; /* Allocated IRQs. */
+#endif
static u_int stray_count;
device_t root_pic;
@@ -142,7 +151,6 @@ smp_intr_init(void *dummy __unused)
PIC_BIND(i->pic, i->intline, i->cpu);
}
}
-
SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL);
#endif
@@ -231,9 +239,21 @@ intr_lookup(u_int irq)
static int
powerpc_map_irq(struct powerpc_intr *i)
{
+ struct pic *p;
+ u_int cnt;
+ int idx;
- i->intline = INTR_INTLINE(i->irq);
- i->pic = piclist[INTR_IGN(i->irq)].pic;
+ for (idx = 0; idx < npics; idx++) {
+ p = &piclist[idx];
+ cnt = p->irqs + p->ipis;
+ if (i->irq >= p->base && i->irq < p->base + cnt)
+ break;
+ }
+ if (idx == npics)
+ return (EINVAL);
+
+ i->intline = i->irq - p->base;
+ i->pic = p->dev;
/* Try a best guess if that failed */
if (i->pic == NULL)
@@ -288,46 +308,76 @@ powerpc_assign_intr_cpu(void *arg, u_char cpu)
}
void
-powerpc_register_pic(device_t dev, u_int ipi)
+powerpc_register_pic(device_t dev, uint32_t node, u_int irqs, u_int ipis,
+ u_int atpic)
{
- int i;
+ struct pic *p;
+ u_int irq;
+ int idx;
mtx_lock(&intr_table_lock);
- for (i = 0; i < npics; i++) {
- if (piclist[i].pic_id == PIC_ID(dev))
+ /* XXX see powerpc_get_irq(). */
+ for (idx = 0; idx < npics; idx++) {
+ p = &piclist[idx];
+ if (p->node != node)
+ continue;
+ if (node != 0 || p->dev == dev)
break;
}
- piclist[i].pic = dev;
- piclist[i].pic_id = PIC_ID(dev);
- piclist[i].ipi_irq = ipi;
- if (i == npics)
+ p = &piclist[idx];
+
+ p->dev = dev;
+ p->node = node;
+ p->irqs = irqs;
+ p->ipis = ipis;
+ if (idx == npics) {
+#ifdef DEV_ISA
+ p->base = (atpic) ? 0 : nirqs;
+#else
+ p->base = nirqs;
+#endif
+ irq = p->base + irqs + ipis;
+ nirqs = MAX(nirqs, irq);
npics++;
+ }
mtx_unlock(&intr_table_lock);
}
-int
-powerpc_ign_lookup(uint32_t pic_id)
+u_int
+powerpc_get_irq(uint32_t node, u_int pin)
{
- int i;
+ int idx;
- mtx_lock(&intr_table_lock);
+ if (node == 0)
+ return (pin);
- for (i = 0; i < npics; i++) {
- if (piclist[i].pic_id == pic_id) {
+ mtx_lock(&intr_table_lock);
+ for (idx = 0; idx < npics; idx++) {
+ if (piclist[idx].node == node) {
mtx_unlock(&intr_table_lock);
- return (i);
+ return (piclist[idx].base + pin);
}
}
- piclist[i].pic = NULL;
- piclist[i].pic_id = pic_id;
- piclist[i].ipi_irq = 0;
+
+ /*
+ * XXX we should never encounter an unregistered PIC, but that
+ * can only be done when we properly support bus enumeration
+ * using multiple passes. Until then, fake an entry and give it
+ * some adhoc maximum number of IRQs and IPIs.
+ */
+ piclist[idx].dev = NULL;
+ piclist[idx].node = node;
+ piclist[idx].irqs = 124;
+ piclist[idx].ipis = 4;
+ piclist[idx].base = nirqs;
+ nirqs += 128;
npics++;
mtx_unlock(&intr_table_lock);
- return (i);
+ return (piclist[idx].base + pin);
}
int
@@ -342,15 +392,18 @@ powerpc_enable_intr(void)
if (npics == 0)
panic("no PIC detected\n");
+ if (root_pic == NULL)
+ root_pic = piclist[0].dev;
+
#ifdef SMP
/* Install an IPI handler. */
-
for (n = 0; n < npics; n++) {
- if (piclist[n].pic != root_pic)
+ if (piclist[n].dev != root_pic)
continue;
+ KASSERT(piclist[n].ipis != 0, ("%s", __func__));
error = powerpc_setup_intr("IPI",
- INTR_VEC(piclist[n].pic_id, piclist[n].ipi_irq),
+ INTR_VEC(piclist[n].node, piclist[n].irqs),
powerpc_ipi_handler, NULL, NULL,
INTR_TYPE_MISC | INTR_EXCL, &ipi_cookie);
if (error) {
@@ -373,6 +426,9 @@ powerpc_enable_intr(void)
i->pol != INTR_POLARITY_CONFORM)
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
+ if (i != NULL && i->pic == root_pic)
+ PIC_BIND(i->pic, i->intline, i->cpu);
+
if (i->event != NULL)
PIC_ENABLE(i->pic, i->intline, vector);
}
diff --git a/sys/powerpc/powerpc/openpic.c b/sys/powerpc/powerpc/openpic.c
index 7668f77..042f8b8 100644
--- a/sys/powerpc/powerpc/openpic.c
+++ b/sys/powerpc/powerpc/openpic.c
@@ -83,7 +83,7 @@ openpic_set_priority(struct openpic_softc *sc, int pri)
}
int
-openpic_attach(device_t dev)
+openpic_common_attach(device_t dev, uint32_t node)
{
struct openpic_softc *sc;
u_int cpu, ipi, irq;
@@ -217,7 +217,7 @@ openpic_attach(device_t dev)
for (cpu = 0; cpu < sc->sc_ncpu; cpu++)
openpic_write(sc, OPENPIC_PCPU_TPR(cpu), 0);
- powerpc_register_pic(dev, sc->sc_nirq);
+ powerpc_register_pic(dev, node, sc->sc_nirq, 4, FALSE);
/* If this is not a cascaded PIC, it must be the root PIC */
if (sc->sc_intr == NULL)
@@ -285,7 +285,6 @@ openpic_dispatch(device_t dev, struct trapframe *tf)
cpuid = (dev == root_pic) ? PCPU_GET(cpuid) : 0;
sc = device_get_softc(dev);
-
while (1) {
vector = openpic_read(sc, OPENPIC_PCPU_IACK(cpuid));
vector &= OPENPIC_VECTOR_MASK;
diff --git a/sys/powerpc/powerpc/pic_if.m b/sys/powerpc/powerpc/pic_if.m
index 04f1c1e..185cc08 100644
--- a/sys/powerpc/powerpc/pic_if.m
+++ b/sys/powerpc/powerpc/pic_if.m
@@ -66,10 +66,6 @@ METHOD void ipi {
u_int cpu;
};
-METHOD uint32_t id {
- device_t dev;
-};
-
METHOD void mask {
device_t dev;
u_int irq;
diff --git a/sys/powerpc/ps3/ps3pic.c b/sys/powerpc/ps3/ps3pic.c
index 5d56d3e..c00585b 100644
--- a/sys/powerpc/ps3/ps3pic.c
+++ b/sys/powerpc/ps3/ps3pic.c
@@ -54,7 +54,6 @@ static void ps3pic_eoi(device_t, u_int);
static void ps3pic_ipi(device_t, u_int);
static void ps3pic_mask(device_t, u_int);
static void ps3pic_unmask(device_t, u_int);
-static uint32_t ps3pic_id(device_t dev);
struct ps3pic_softc {
uint64_t *bitmap_thread0;
@@ -76,7 +75,6 @@ static device_method_t ps3pic_methods[] = {
DEVMETHOD(pic_dispatch, ps3pic_dispatch),
DEVMETHOD(pic_enable, ps3pic_enable),
DEVMETHOD(pic_eoi, ps3pic_eoi),
- DEVMETHOD(pic_id, ps3pic_id),
DEVMETHOD(pic_ipi, ps3pic_ipi),
DEVMETHOD(pic_mask, ps3pic_mask),
DEVMETHOD(pic_unmask, ps3pic_unmask),
@@ -146,9 +144,7 @@ ps3pic_attach(device_t dev)
sc->sc_ipi_outlet[1], 0);
#endif
- powerpc_register_pic(dev, sc->sc_ipi_outlet[0]);
- root_pic = dev; /* PS3s have only one PIC */
-
+ powerpc_register_pic(dev, 0, sc->sc_ipi_outlet[0], 1, FALSE);
return (0);
}
@@ -245,10 +241,3 @@ ps3pic_unmask(device_t dev, u_int irq)
lv1_did_update_interrupt_mask(ppe, 0);
lv1_did_update_interrupt_mask(ppe, 1);
}
-
-static uint32_t
-ps3pic_id(device_t dev)
-{
- return (0);
-}
-
diff --git a/sys/powerpc/psim/openpic_iobus.c b/sys/powerpc/psim/openpic_iobus.c
index 6522985..f2e7cdb 100644
--- a/sys/powerpc/psim/openpic_iobus.c
+++ b/sys/powerpc/psim/openpic_iobus.c
@@ -62,11 +62,12 @@ __FBSDID("$FreeBSD$");
* PSIM IOBus interface
*/
static int openpic_iobus_probe(device_t);
+static int openpic_iobus_attach(device_t);
static device_method_t openpic_iobus_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpic_iobus_probe),
- DEVMETHOD(device_attach, openpic_attach),
+ DEVMETHOD(device_attach, openpic_iobus_attach),
/* PIC interface */
DEVMETHOD(pic_config, openpic_config),
@@ -109,3 +110,10 @@ openpic_iobus_probe(device_t dev)
return (0);
}
+
+static int
+openpic_iobus_attach(device_t dev)
+{
+
+ return (openpic_common_attach(dev, 0));
+}
OpenPOWER on IntegriCloud