summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/aim/nexus.c8
-rw-r--r--sys/powerpc/aim/ofw_machdep.c4
-rw-r--r--sys/powerpc/include/nexusvar.h58
-rw-r--r--sys/powerpc/ofw/ofw_pci.c229
-rw-r--r--sys/powerpc/ofw/ofw_pci.h34
-rw-r--r--sys/powerpc/ofw/ofw_pcib_pci.c33
-rw-r--r--sys/powerpc/ofw/ofw_pcibus.c359
-rw-r--r--sys/powerpc/ofw/ofw_syscons.c9
-rw-r--r--sys/powerpc/powermac/ata_kauai.c60
-rw-r--r--sys/powerpc/powermac/grackle.c36
-rw-r--r--sys/powerpc/powermac/hrowpic.c1
-rw-r--r--sys/powerpc/powermac/macio.c4
-rw-r--r--sys/powerpc/powermac/openpic_macio.c1
-rw-r--r--sys/powerpc/powermac/uninorth.c101
-rw-r--r--sys/powerpc/powermac/uninorthvar.h12
-rw-r--r--sys/powerpc/psim/iobus.c6
-rw-r--r--sys/powerpc/psim/openpic_iobus.c1
17 files changed, 514 insertions, 442 deletions
diff --git a/sys/powerpc/aim/nexus.c b/sys/powerpc/aim/nexus.c
index 0d9d0b6..d92090b 100644
--- a/sys/powerpc/aim/nexus.c
+++ b/sys/powerpc/aim/nexus.c
@@ -70,7 +70,6 @@
#include <machine/bus.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
-#include <machine/nexusvar.h>
#include <machine/resource.h>
#include <sys/rman.h>
@@ -90,6 +89,13 @@
static MALLOC_DEFINE(M_NEXUS, "nexus", "nexus device information");
+enum nexus_ivars {
+ NEXUS_IVAR_NODE,
+ NEXUS_IVAR_NAME,
+ NEXUS_IVAR_DEVICE_TYPE,
+ NEXUS_IVAR_COMPATIBLE,
+};
+
struct nexus_devinfo {
phandle_t ndi_node;
/* Some common properties. */
diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c
index d6ec2f3..2755819 100644
--- a/sys/powerpc/aim/ofw_machdep.c
+++ b/sys/powerpc/aim/ofw_machdep.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/ofw_bus.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -56,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <machine/powerpc.h>
#include <machine/ofw_machdep.h>
-#include <powerpc/ofw/ofw_pci.h>
#define OFMEM_REGIONS 32
static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3];
@@ -282,7 +282,7 @@ OF_getetheraddr(device_t dev, u_char *addr)
{
phandle_t node;
- node = ofw_pci_find_node(dev);
+ node = ofw_bus_get_node(dev);
OF_getprop(node, "local-mac-address", addr, ETHER_ADDR_LEN);
}
diff --git a/sys/powerpc/include/nexusvar.h b/sys/powerpc/include/nexusvar.h
deleted file mode 100644
index df8a0f6..0000000
--- a/sys/powerpc/include/nexusvar.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 2001 by Thomas Moestl <tmm@FreeBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _MACHINE_NEXUSVAR_H_
-#define _MACHINE_NEXUSVAR_H_
-
-enum nexus_ivars {
- NEXUS_IVAR_NODE,
- NEXUS_IVAR_NAME,
- NEXUS_IVAR_DEVICE_TYPE,
- NEXUS_IVAR_COMPATIBLE,
-};
-
-/*
- * Simplified accessors for nexus devices
- * XXX: These should be made specializations of generic bus accessor macros
- * instead of having multiple implementations around.
- */
-#define NEXUS_ACCESSOR(var, ivar, type) \
- __BUS_ACCESSOR(nexus, var, NEXUS, ivar, type)
-
-NEXUS_ACCESSOR(node, NODE, phandle_t)
-NEXUS_ACCESSOR(name, NAME, char *)
-NEXUS_ACCESSOR(device_type, DEVICE_TYPE, char *)
-NEXUS_ACCESSOR(compatible, COMPATIBLE, char *)
-
-#undef NEXUS_ACCESSOR
-
-/*
- * Install the interrupt controller device
- */
-int nexus_install_intcntlr(device_t);
-
-#endif /* _MACHINE_NEXUSVAR_H_ */
diff --git a/sys/powerpc/ofw/ofw_pci.c b/sys/powerpc/ofw/ofw_pci.c
deleted file mode 100644
index ca4b36e..0000000
--- a/sys/powerpc/ofw/ofw_pci.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*-
- * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
- * Copyright (c) 1994 Charles M. Hannum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles M. Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * from NetBSD: pci_machdep.c,v 1.18 2001/07/22 11:29:48 wiz Exp
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_pci.h>
-
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-
-#include <powerpc/ofw/ofw_pci.h>
-
-#include "pcib_if.h"
-
-static void fixup_node(device_t, phandle_t);
-static int find_node_intr(phandle_t, u_int32_t *, u_int32_t *);
-
-phandle_t
-ofw_pci_find_node(device_t dev)
-{
- phandle_t node, nextnode;
- struct ofw_pci_register pcir;
- int l, b, s, f;
-
- for (node = OF_peer(0); node; node = nextnode) {
- l = OF_getprop(node, "reg", &pcir, sizeof(pcir));
- if (l > 4) {
- b = OFW_PCI_PHYS_HI_BUS(pcir.phys_hi);
- s = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi);
- f = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi);
-
- if (b == pci_get_bus(dev) && s == pci_get_slot(dev) &&
- f == pci_get_function(dev))
- return (node);
- }
-
- if ((nextnode = OF_child(node)))
- continue;
- while (node) {
- if ((nextnode = OF_peer(node)) != 0)
- break;
- node = OF_parent(node);
- }
- }
-
- return (0);
-}
-
-void
-ofw_pci_fixup(device_t dev, u_int bus, phandle_t parentnode)
-{
- phandle_t node;
-
- for (node = OF_child(parentnode); node; node = OF_peer(node)) {
- fixup_node(dev, node);
- }
-}
-
-static void
-fixup_node(device_t dev, phandle_t node)
-{
- u_int32_t csr, intr, irqs[4], npintr, paddr[4];
- struct ofw_pci_register addr[8];
- int len, i;
-
- len = OF_getprop(node, "assigned-addresses", addr, sizeof(addr));
- if (len < (int)sizeof(struct ofw_pci_register)) {
- return;
- }
-
- csr = PCIB_READ_CONFIG(dev, OFW_PCI_PHYS_HI_BUS(addr[0].phys_hi),
- OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
- OFW_PCI_PHYS_HI_FUNCTION(addr[0].phys_hi), PCIR_COMMAND, 4);
- csr &= ~(PCIM_CMD_PORTEN | PCIM_CMD_MEMEN);
-
- for (i = 0; i < len / sizeof(struct ofw_pci_register); i++) {
- switch (addr[i].phys_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
- case OFW_PCI_PHYS_HI_SPACE_IO:
- csr |= PCIM_CMD_PORTEN;
- break;
- case OFW_PCI_PHYS_HI_SPACE_MEM32:
- csr |= PCIM_CMD_MEMEN;
- break;
- }
- }
-
- PCIB_WRITE_CONFIG(dev, OFW_PCI_PHYS_HI_BUS(addr[0].phys_hi),
- OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
- OFW_PCI_PHYS_HI_FUNCTION(addr[0].phys_hi), PCIR_COMMAND, csr, 4);
-
- /*
- * Create PCI interrupt-map array element. pci-mid/pci-lo
- * aren't required, but the 'interrupts' property needs
- * to be appended
- */
- npintr = 0;
- OF_getprop(node, "interrupts", &npintr, 4);
- paddr[0] = addr[0].phys_hi;
- paddr[1] = 0;
- paddr[2] = 0;
- paddr[3] = npintr;
-
- if (find_node_intr(node, paddr, irqs) != -1) {
- intr = PCIB_READ_CONFIG(dev,
- OFW_PCI_PHYS_HI_BUS(addr[0].phys_hi),
- OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
- OFW_PCI_PHYS_HI_FUNCTION(addr[0].phys_hi), PCIR_INTLINE, 2);
- intr &= ~(0xff);
- intr |= irqs[0] & 0xff;
- PCIB_WRITE_CONFIG(dev,
- OFW_PCI_PHYS_HI_BUS(addr[0].phys_hi),
- OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
- OFW_PCI_PHYS_HI_FUNCTION(addr[0].phys_hi), PCIR_INTLINE,
- intr, 2);
- }
-
-}
-
-static int
-find_node_intr(phandle_t node, u_int32_t *addr, u_int32_t *intr)
-{
- phandle_t parent, iparent;
- int len, mlen, match, i;
- u_int32_t map[160], *mp, imask[8], maskedaddr[8], icells;
- char name[32];
-
- len = OF_getprop(node, "AAPL,interrupts", intr, 4);
- if (len == 4) {
- return (len);
- }
-
- parent = OF_parent(node);
- len = OF_getprop(parent, "interrupt-map", map, sizeof(map));
- mlen = OF_getprop(parent, "interrupt-map-mask", imask, sizeof(imask));
-
- if (len == -1 || mlen == -1)
- goto nomap;
-
- memcpy(maskedaddr, addr, mlen);
- for (i = 0; i < mlen/4; i++)
- maskedaddr[i] &= imask[i];
-
- mp = map;
- while (len > mlen) {
- match = bcmp(maskedaddr, mp, mlen);
- mp += mlen / 4;
- len -= mlen;
-
- /*
- * We must read "#interrupt-cells" for each time because
- * interrupt-parent may be different.
- */
- iparent = *mp++;
- len -= 4;
- if (OF_getprop(iparent, "#interrupt-cells", &icells, 4) != 4)
- goto nomap;
-
- /* Found. */
- if (match == 0) {
- bcopy(mp, intr, icells * 4);
- return (icells * 4);
- }
-
- mp += icells;
- len -= icells * 4;
- }
-
-nomap:
- /*
- * If the node has no interrupt property and the parent is a PCI
- * bridge, use the parent's interrupt. This occurs on a PCI slot.
- */
- bzero(name, sizeof(name));
- OF_getprop(parent, "name", name, sizeof(name));
- if (strcmp(name, "pci-bridge") == 0) {
- len = OF_getprop(parent, "AAPL,interrupts", intr, 4);
- if (len == 4) {
- return (len);
- }
-
- /*
- * XXX I don't know what is the correct local address.
- * XXX Use the first entry for now.
- */
- len = OF_getprop(parent, "interrupt-map", map, sizeof(map));
- if (len >= 36) {
- addr = &map[5];
- /* XXX Use 0 for 'interrupts' for compat */
- return (find_node_intr(parent, addr, intr));
- }
- }
-
- return (-1);
-}
diff --git a/sys/powerpc/ofw/ofw_pci.h b/sys/powerpc/ofw/ofw_pci.h
deleted file mode 100644
index 8d78f91..0000000
--- a/sys/powerpc/ofw/ofw_pci.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*-
- * Copyright (C) 2002 Benno Rice.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _POWERPC_OFW_PCI_H_
-#define _POWERPC_OFW_PCI_H_
-
-phandle_t ofw_pci_find_node(device_t);
-void ofw_pci_fixup(device_t, u_int, phandle_t);
-
-#endif /* _POWERPC_OFW_PCI_H_ */
diff --git a/sys/powerpc/ofw/ofw_pcib_pci.c b/sys/powerpc/ofw/ofw_pcib_pci.c
index 4cc73c4..5d6fba6 100644
--- a/sys/powerpc/ofw/ofw_pcib_pci.c
+++ b/sys/powerpc/ofw/ofw_pcib_pci.c
@@ -35,8 +35,7 @@
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_pci.h>
-
-#include <powerpc/ofw/ofw_pci.h>
+#include <dev/ofw/ofw_bus.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@@ -46,6 +45,7 @@
static int ofw_pcib_pci_probe(device_t bus);
static int ofw_pcib_pci_attach(device_t bus);
+static phandle_t ofw_pcib_pci_get_node(device_t bus, device_t dev);
static device_method_t ofw_pcib_pci_methods[] = {
/* Device interface */
@@ -72,6 +72,9 @@ static device_method_t ofw_pcib_pci_methods[] = {
DEVMETHOD(pcib_write_config, pcib_write_config),
DEVMETHOD(pcib_route_interrupt, pcib_route_interrupt),
+ /* ofw_bus interface */
+ DEVMETHOD(ofw_bus_get_node, ofw_pcib_pci_get_node),
+
{0, 0}
};
@@ -89,29 +92,29 @@ ofw_pcib_pci_probe(device_t dev)
(pci_get_subclass(dev) != PCIS_BRIDGE_PCI)) {
return (ENXIO);
}
- if (ofw_pci_find_node(dev) == 0) {
+
+ if (ofw_bus_get_node(dev) == 0)
return (ENXIO);
- }
- device_set_desc(dev, "Open Firmware PCI-PCI bridge");
- return (-1000);
+ device_set_desc(dev, "OFW PCI-PCI bridge");
+ return (0);
}
static int
ofw_pcib_pci_attach(device_t dev)
{
- phandle_t node;
- uint32_t busrange[2];
-
- node = ofw_pci_find_node(dev);
- if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8)
- return (ENXIO);
-
pcib_attach_common(dev);
- ofw_pci_fixup(dev, busrange[0], node);
-
device_add_child(dev, "pci", -1);
return (bus_generic_attach(dev));
}
+
+phandle_t
+ofw_pcib_pci_get_node(device_t bridge, device_t dev)
+{
+ /* We have only one child, the PCI bus, so pass it our node */
+
+ return (ofw_bus_get_node(bridge));
+}
+
diff --git a/sys/powerpc/ofw/ofw_pcibus.c b/sys/powerpc/ofw/ofw_pcibus.c
new file mode 100644
index 0000000..916d98b
--- /dev/null
+++ b/sys/powerpc/ofw/ofw_pcibus.c
@@ -0,0 +1,359 @@
+/*-
+ * Copyright (c) 1994 Charles M. Hannum. All rights reserved.
+ * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
+ * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
+ * Copyright (c) 2000, Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2000, BSDi
+ * Copyright (c) 2003, Thomas Moestl <tmm@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/module.h>
+#include <sys/pciio.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pci_private.h>
+
+#include "pcib_if.h"
+#include "pci_if.h"
+
+/* Helper functions */
+static int find_node_intr(phandle_t, u_int32_t *, u_int32_t *);
+static int ofw_pci_find_intline(phandle_t node, uint32_t *irqs);
+static void ofw_pci_fixup_node(device_t dev, phandle_t node);
+
+/* Methods */
+static device_probe_t ofw_pcibus_probe;
+static device_attach_t ofw_pcibus_attach;
+static pci_assign_interrupt_t ofw_pcibus_assign_interrupt;
+static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo;
+
+static device_method_t ofw_pcibus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ofw_pcibus_probe),
+ DEVMETHOD(device_attach, ofw_pcibus_attach),
+
+ /* PCI interface */
+ DEVMETHOD(pci_assign_interrupt, ofw_pcibus_assign_interrupt),
+
+ /* ofw_bus interface */
+ DEVMETHOD(ofw_bus_get_devinfo, ofw_pcibus_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
+
+ { 0, 0 }
+};
+
+struct ofw_pcibus_devinfo {
+ struct pci_devinfo opd_dinfo;
+ struct ofw_bus_devinfo opd_obdinfo;
+};
+
+static devclass_t pci_devclass;
+
+DEFINE_CLASS_1(pci, ofw_pcibus_driver, ofw_pcibus_methods, 1 /* no softc */,
+ pci_driver);
+DRIVER_MODULE(ofw_pcibus, pcib, ofw_pcibus_driver, pci_devclass, 0, 0);
+MODULE_VERSION(ofw_pcibus, 1);
+MODULE_DEPEND(ofw_pcibus, pci, 1, 1, 1);
+
+static int
+ofw_pcibus_probe(device_t dev)
+{
+ if (ofw_bus_get_node(dev) == 0)
+ return (ENXIO);
+ device_set_desc(dev, "OFW PCI bus");
+
+ return (0);
+}
+
+static int
+ofw_pcibus_attach(device_t dev)
+{
+ device_t pcib;
+ struct ofw_pci_register pcir;
+ struct ofw_pcibus_devinfo *dinfo;
+ phandle_t node, child;
+ u_int busno, domain, func, slot;
+
+ pcib = device_get_parent(dev);
+ domain = pcib_get_domain(dev);
+ busno = pcib_get_bus(dev);
+ if (bootverbose)
+ device_printf(dev, "domain=%d, physical bus=%d\n",
+ domain, busno);
+ node = ofw_bus_get_node(dev);
+
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ if (OF_getprop(child, "reg", &pcir, sizeof(pcir)) == -1)
+ continue;
+ slot = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi);
+ func = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi);
+
+ /* Some OFW device trees contain dupes. */
+ if (pci_find_dbsf(domain, busno, slot, func) != NULL)
+ continue;
+
+ ofw_pci_fixup_node(pcib, child);
+
+ dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
+ domain, busno, slot, func, sizeof(*dinfo));
+
+ if (dinfo == NULL)
+ continue;
+
+ /* Set up OFW devinfo */
+ if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
+ 0) {
+ pci_freecfg((struct pci_devinfo *)dinfo);
+ continue;
+ }
+
+ pci_add_child(dev, (struct pci_devinfo *)dinfo);
+
+ /*
+ * Some devices don't have an intpin set, but do have
+ * interrupts. Add them to the appropriate resource list.
+ */
+ if (dinfo->opd_dinfo.cfg.intpin == 0) {
+ uint32_t irqs[4];
+
+ if (ofw_pci_find_intline(child, irqs) > 0)
+ resource_list_add(&dinfo->opd_dinfo.resources,
+ SYS_RES_IRQ, 0, irqs[0], irqs[0], 1);
+ }
+ }
+
+ return (bus_generic_attach(dev));
+}
+
+static int
+ofw_pcibus_assign_interrupt(device_t dev, device_t child)
+{
+ uint32_t irqs[4];
+
+ device_printf(child,"Assigning interrupt\n");
+
+ if (ofw_pci_find_intline(ofw_bus_get_node(child), irqs) < 0)
+ return PCI_INVALID_IRQ;
+
+ device_printf(child,"IRQ %d\n",irqs[0]);
+
+ return irqs[0];
+
+// return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, intr));
+}
+
+static const struct ofw_bus_devinfo *
+ofw_pcibus_get_devinfo(device_t bus, device_t dev)
+{
+ struct ofw_pcibus_devinfo *dinfo;
+
+ dinfo = device_get_ivars(dev);
+ return (&dinfo->opd_obdinfo);
+}
+
+static void
+ofw_pci_fixup_node(device_t dev, phandle_t node)
+{
+ uint32_t csr, intr, irqs[4];
+ struct ofw_pci_register addr[8];
+ int len, i;
+
+ len = OF_getprop(node, "assigned-addresses", addr, sizeof(addr));
+ if (len < (int)sizeof(struct ofw_pci_register)) {
+ return;
+ }
+
+ csr = PCIB_READ_CONFIG(dev, OFW_PCI_PHYS_HI_BUS(addr[0].phys_hi),
+ OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
+ OFW_PCI_PHYS_HI_FUNCTION(addr[0].phys_hi), PCIR_COMMAND, 4);
+ csr &= ~(PCIM_CMD_PORTEN | PCIM_CMD_MEMEN);
+
+ for (i = 0; i < len / sizeof(struct ofw_pci_register); i++) {
+ switch (addr[i].phys_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
+ case OFW_PCI_PHYS_HI_SPACE_IO:
+ csr |= PCIM_CMD_PORTEN;
+ break;
+ case OFW_PCI_PHYS_HI_SPACE_MEM32:
+ csr |= PCIM_CMD_MEMEN;
+ break;
+ }
+ }
+
+ PCIB_WRITE_CONFIG(dev, OFW_PCI_PHYS_HI_BUS(addr[0].phys_hi),
+ OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
+ OFW_PCI_PHYS_HI_FUNCTION(addr[0].phys_hi), PCIR_COMMAND, csr, 4);
+
+ if (ofw_pci_find_intline(node, irqs) != -1) {
+ intr = PCIB_READ_CONFIG(dev,
+ OFW_PCI_PHYS_HI_BUS(addr[0].phys_hi),
+ OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
+ OFW_PCI_PHYS_HI_FUNCTION(addr[0].phys_hi), PCIR_INTLINE, 2);
+ intr &= ~(0xff);
+ intr |= irqs[0] & 0xff;
+ PCIB_WRITE_CONFIG(dev,
+ OFW_PCI_PHYS_HI_BUS(addr[0].phys_hi),
+ OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
+ OFW_PCI_PHYS_HI_FUNCTION(addr[0].phys_hi), PCIR_INTLINE,
+ intr, 2);
+ }
+}
+
+static int
+ofw_pci_find_intline(phandle_t node, uint32_t *irqs)
+{
+ uint32_t npintr, paddr[4];
+ struct ofw_pci_register addr[8];
+ int len;
+
+ len = OF_getprop(node, "assigned-addresses", addr, sizeof(addr));
+ if (len < (int)sizeof(struct ofw_pci_register))
+ return -1;
+ /*
+ * Create PCI interrupt-map array element. pci-mid/pci-lo
+ * aren't required, but the 'interrupts' property needs
+ * to be appended
+ */
+ npintr = 0;
+ OF_getprop(node, "interrupts", &npintr, 4);
+ paddr[0] = addr[0].phys_hi;
+ paddr[1] = 0;
+ paddr[2] = 0;
+ paddr[3] = npintr;
+
+ return find_node_intr(node, paddr, irqs);
+}
+
+static int
+find_node_intr(phandle_t node, u_int32_t *addr, u_int32_t *intr)
+{
+ phandle_t parent, iparent;
+ int len, mlen, match, i;
+ u_int32_t map[160], *mp, imask[8], maskedaddr[8], icells;
+ char name[32];
+
+ len = OF_getprop(node, "AAPL,interrupts", intr, 4);
+ if (len == 4) {
+ return (len);
+ }
+
+ parent = OF_parent(node);
+ len = OF_getprop(parent, "interrupt-map", map, sizeof(map));
+ mlen = OF_getprop(parent, "interrupt-map-mask", imask, sizeof(imask));
+
+ if (len == -1 || mlen == -1)
+ goto nomap;
+
+ memcpy(maskedaddr, addr, mlen);
+ for (i = 0; i < mlen/4; i++)
+ maskedaddr[i] &= imask[i];
+
+ mp = map;
+ while (len > mlen) {
+ match = bcmp(maskedaddr, mp, mlen);
+ mp += mlen / 4;
+ len -= mlen;
+
+ /*
+ * We must read "#interrupt-cells" for each time because
+ * interrupt-parent may be different.
+ */
+ iparent = *mp++;
+ len -= 4;
+ if (OF_getprop(iparent, "#interrupt-cells", &icells, 4) != 4)
+ goto nomap;
+
+ /* Found. */
+ if (match == 0) {
+ bcopy(mp, intr, icells * 4);
+ return (icells * 4);
+ }
+
+ mp += icells;
+ len -= icells * 4;
+ }
+
+nomap:
+ /*
+ * Check for local properties indicating interrupts
+ */
+
+ len = OF_getprop(node, "interrupts", intr, 16);
+ if (OF_getprop(node, "interrupt-parent", &iparent, sizeof(iparent)) ==
+ sizeof(iparent)) {
+ OF_getprop(iparent, "#interrupt-cells", &icells, sizeof(icells));
+ for (i = 0; i < len/icells/4; i++)
+ intr[i] = intr[i*icells];
+
+ return (len);
+ }
+
+
+ /*
+ * If the node has no interrupt property and the parent is a PCI
+ * bridge, use the parent's interrupt. This occurs on a PCI slot.
+ */
+ bzero(name, sizeof(name));
+ OF_getprop(parent, "name", name, sizeof(name));
+ if (strcmp(name, "pci-bridge") == 0) {
+ len = OF_getprop(parent, "AAPL,interrupts", intr, 4);
+ if (len == 4) {
+ return (len);
+ }
+
+ /*
+ * XXX I don't know what is the correct local address.
+ * XXX Use the first entry for now.
+ */
+ len = OF_getprop(parent, "interrupt-map", map, sizeof(map));
+ if (len >= 36) {
+ addr = &map[5];
+ /* XXX Use 0 for 'interrupts' for compat */
+ return (find_node_intr(parent, addr, intr));
+ }
+ }
+
+ return (-1);
+}
+
diff --git a/sys/powerpc/ofw/ofw_syscons.c b/sys/powerpc/ofw/ofw_syscons.c
index 7ea8497..99c5119 100644
--- a/sys/powerpc/ofw/ofw_syscons.c
+++ b/sys/powerpc/ofw/ofw_syscons.c
@@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_pci.h>
#include <powerpc/ofw/ofw_syscons.h>
-#include <machine/nexusvar.h>
static int ofwfb_ignore_mmap_checks;
SYSCTL_NODE(_hw, OID_AUTO, ofwfb, CTLFLAG_RD, 0, "ofwfb");
@@ -841,19 +840,11 @@ ofwfb_scidentify(driver_t *driver, device_t parent)
* the device list
*/
child = BUS_ADD_CHILD(parent, INT_MAX, SC_DRIVER_NAME, 0);
- if (child != NULL)
- nexus_set_device_type(child, "syscons");
}
static int
ofwfb_scprobe(device_t dev)
{
- char *name;
-
- name = nexus_get_name(dev);
- if (strcmp(SC_DRIVER_NAME, name) != 0)
- return (ENXIO);
-
device_set_desc(dev, "System console");
return (sc_probe_unit(device_get_unit(dev),
device_get_flags(dev) | SC_AUTODETECT_KBD));
diff --git a/sys/powerpc/powermac/ata_kauai.c b/sys/powerpc/powermac/ata_kauai.c
index 0582251..53fc676 100644
--- a/sys/powerpc/powermac/ata_kauai.c
+++ b/sys/powerpc/powermac/ata_kauai.c
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
#include <ata_if.h>
#include <dev/ofw/openfirm.h>
-#include <powerpc/ofw/ofw_pci.h>
+#include <dev/ofw/ofw_bus.h>
#include <machine/intr_machdep.h>
#include <dev/pci/pcivar.h>
@@ -194,11 +194,10 @@ ata_kauai_probe(device_t dev)
{
struct ata_channel *ch;
struct ata_kauai_softc *sc;
- u_long startp, countp;
u_int32_t devid;
phandle_t node;
- char *compatstring = NULL;
- int i, found, rid, status;
+ const char *compatstring = NULL;
+ int i, found, rid;
found = 0;
devid = pci_get_devid(dev);
@@ -212,59 +211,18 @@ ata_kauai_probe(device_t dev)
if (!found)
return (ENXIO);
- node = ofw_pci_find_node(dev);
+ node = ofw_bus_get_node(dev);
sc = device_get_softc(dev);
bzero(sc, sizeof(struct ata_kauai_softc));
ch = &sc->sc_ch.sc_ch;
- OF_getprop_alloc(node, "compatible", 1, (void **)&compatstring);
- if (strcmp(compatstring,"shasta-ata") == 0)
+ compatstring = ofw_bus_get_compat(dev);
+ if (compatstring != NULL && strcmp(compatstring,"shasta-ata") == 0)
sc->shasta = 1;
- free(compatstring, M_OFWPROP);
-
-
- /*
- * This device seems to ignore writes to the interrupt
- * config register, resulting in interrupt resources
- * not being attached. If this is the case, use
- * Open Firmware to determine the irq, and then attach
- * the resource. This allows the ATA common code to
- * allocate the irq.
- */
- status = bus_get_resource(dev, SYS_RES_IRQ, 0, &startp, &countp);
- if (status == ENOENT) {
- int *irq;
- phandle_t iparent;
- int icells, nintr, i;
-
- /*
- * Horrible hack to handle Kauai devices that have their IRQs
- * set up in an utterly wrong way
- */
- if (!sc->shasta)
- bus_set_resource(dev, SYS_RES_IRQ, 0, 39, 1);
-
- /*
- * For the rest of the interrupts, and the main Shasta
- * interrupt, get the IRQs from firmware.
- */
- if (OF_getprop(node, "interrupt-parent", &iparent,
- sizeof(iparent)) == sizeof(iparent)) {
- OF_getprop(iparent, "#interrupt-cells", &icells,
- sizeof(icells)) ;
- }
-
- nintr = OF_getprop_alloc(node, "interrupts", sizeof(*irq),
- (void **)&irq);
-
- for (i = 0; i < nintr; i += icells)
- bus_set_resource(dev, SYS_RES_IRQ,
- i/icells + !sc->shasta, irq[i], 1);
-
- free(irq, M_OFWPROP);
- }
-
+ /* Regular Kauai controllers apparently need this hack */
+ if (!sc->shasta)
+ bus_set_resource(dev, SYS_RES_IRQ, 0, 39, 1);
rid = PCIR_BARS;
sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
diff --git a/sys/powerpc/powermac/grackle.c b/sys/powerpc/powermac/grackle.c
index b40b77e..08e14ac 100644
--- a/sys/powerpc/powermac/grackle.c
+++ b/sys/powerpc/powermac/grackle.c
@@ -36,19 +36,18 @@
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/ofw_bus.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <machine/bus.h>
#include <machine/md_var.h>
-#include <machine/nexusvar.h>
#include <machine/pio.h>
#include <machine/resource.h>
#include <sys/rman.h>
-#include <powerpc/ofw/ofw_pci.h>
#include <powerpc/powermac/gracklevar.h>
#include <vm/vm.h>
@@ -92,6 +91,11 @@ static void grackle_write_config(device_t, u_int, u_int, u_int,
static int grackle_route_interrupt(device_t, device_t, int);
/*
+ * ofw_bus interface
+ */
+static phandle_t grackle_get_node(device_t bus, device_t dev);
+
+/*
* Local routines.
*/
static int grackle_enable_config(struct grackle_softc *, u_int,
@@ -122,6 +126,9 @@ static device_method_t grackle_methods[] = {
DEVMETHOD(pcib_write_config, grackle_write_config),
DEVMETHOD(pcib_route_interrupt, grackle_route_interrupt),
+ /* ofw_bus interface */
+ DEVMETHOD(ofw_bus_get_node, grackle_get_node),
+
{ 0, 0 }
};
@@ -138,10 +145,10 @@ DRIVER_MODULE(grackle, nexus, grackle_driver, grackle_devclass, 0, 0);
static int
grackle_probe(device_t dev)
{
- char *type, *compatible;
+ const char *type, *compatible;
- type = nexus_get_device_type(dev);
- compatible = nexus_get_compatible(dev);
+ type = ofw_bus_get_type(dev);
+ compatible = ofw_bus_get_compat(dev);
if (type == NULL || compatible == NULL)
return (ENXIO);
@@ -162,7 +169,7 @@ grackle_attach(device_t dev)
struct grackle_range *rp, *io, *mem[2];
int nmem, i, error;
- node = nexus_get_node(dev);
+ node = ofw_bus_get_node(dev);
sc = device_get_softc(dev);
if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8)
@@ -244,12 +251,6 @@ grackle_attach(device_t dev)
}
}
- /*
- * Write out the correct PIC interrupt values to config space
- * of all devices on the bus.
- */
- ofw_pci_fixup(dev, sc->sc_bus, sc->sc_node);
-
device_add_child(dev, "pci", device_get_unit(dev));
return (bus_generic_attach(dev));
}
@@ -511,6 +512,17 @@ grackle_disable_config(struct grackle_softc *sc)
out32rb(sc->sc_addr, 0);
}
+static phandle_t
+grackle_get_node(device_t bus, device_t dev)
+{
+ struct grackle_softc *sc;
+
+ sc = device_get_softc(bus);
+ /* We only have one child, the PCI bus, which needs our own node. */
+
+ return sc->sc_node;
+}
+
/*
* Driver to swallow Grackle host bridges from the PCI bus side.
*/
diff --git a/sys/powerpc/powermac/hrowpic.c b/sys/powerpc/powermac/hrowpic.c
index 59bb82b..2ed0aa3 100644
--- a/sys/powerpc/powermac/hrowpic.c
+++ b/sys/powerpc/powermac/hrowpic.c
@@ -48,7 +48,6 @@
#include <machine/intr.h>
#include <machine/intr_machdep.h>
#include <machine/md_var.h>
-#include <machine/nexusvar.h>
#include <machine/pio.h>
#include <machine/resource.h>
diff --git a/sys/powerpc/powermac/macio.c b/sys/powerpc/powermac/macio.c
index 9618234..b0f04e0 100644
--- a/sys/powerpc/powermac/macio.c
+++ b/sys/powerpc/powermac/macio.c
@@ -139,6 +139,8 @@ static struct macio_pci_dev {
{ 0x0022106b, "KeyLargo I/O Controller" },
{ 0x0025106b, "Pangea I/O Controller" },
{ 0x003e106b, "Intrepid I/O Controller" },
+ { 0x0041106b, "K2 KeyLargo I/O Controller" },
+ { 0x004f106b, "Shasta I/O Controller" },
{ 0, NULL }
};
@@ -270,7 +272,7 @@ macio_attach(device_t dev)
int error, quirks;
sc = device_get_softc(dev);
- root = sc->sc_node = OF_finddevice("mac-io");
+ root = sc->sc_node = ofw_bus_get_node(dev);
/*
* Locate the device node and it's base address
diff --git a/sys/powerpc/powermac/openpic_macio.c b/sys/powerpc/powermac/openpic_macio.c
index 49d935a..ca7f113 100644
--- a/sys/powerpc/powermac/openpic_macio.c
+++ b/sys/powerpc/powermac/openpic_macio.c
@@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#include <machine/intr_machdep.h>
#include <machine/md_var.h>
-#include <machine/nexusvar.h>
#include <machine/pio.h>
#include <machine/resource.h>
diff --git a/sys/powerpc/powermac/uninorth.c b/sys/powerpc/powermac/uninorth.c
index fc5105b..097532c 100644
--- a/sys/powerpc/powermac/uninorth.c
+++ b/sys/powerpc/powermac/uninorth.c
@@ -34,19 +34,18 @@
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/ofw_bus.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <machine/bus.h>
#include <machine/md_var.h>
-#include <machine/nexusvar.h>
#include <machine/pio.h>
#include <machine/resource.h>
#include <sys/rman.h>
-#include <powerpc/ofw/ofw_pci.h>
#include <powerpc/powermac/uninorthvar.h>
#include <vm/vm.h>
@@ -84,6 +83,12 @@ static void uninorth_write_config(device_t, u_int, u_int, u_int,
static int uninorth_route_interrupt(device_t, device_t, int);
/*
+ * OFW Bus interface
+ */
+
+static phandle_t uninorth_get_node(device_t bus, device_t dev);
+
+/*
* Local routines.
*/
static int uninorth_enable_config(struct uninorth_softc *, u_int,
@@ -112,6 +117,9 @@ static device_method_t uninorth_methods[] = {
DEVMETHOD(pcib_write_config, uninorth_write_config),
DEVMETHOD(pcib_route_interrupt, uninorth_route_interrupt),
+ /* ofw_bus interface */
+ DEVMETHOD(ofw_bus_get_node, uninorth_get_node),
+
{ 0, 0 }
};
@@ -128,32 +136,40 @@ DRIVER_MODULE(uninorth, nexus, uninorth_driver, uninorth_devclass, 0, 0);
static int
uninorth_probe(device_t dev)
{
- char *type, *compatible;
+ const char *type, *compatible;
- type = nexus_get_device_type(dev);
- compatible = nexus_get_compatible(dev);
+ type = ofw_bus_get_type(dev);
+ compatible = ofw_bus_get_compat(dev);
if (type == NULL || compatible == NULL)
return (ENXIO);
- if (strcmp(type, "pci") != 0 || strcmp(compatible, "uni-north") != 0)
+ if (strcmp(type, "pci") != 0)
return (ENXIO);
- device_set_desc(dev, "Apple UniNorth Host-PCI bridge");
- return (0);
+ if (strcmp(compatible, "uni-north") == 0) {
+ device_set_desc(dev, "Apple UniNorth Host-PCI bridge");
+ return (0);
+ } else if (strcmp(compatible,"u3-agp") == 0) {
+ device_set_desc(dev, "Apple U3 Host-AGP bridge");
+ return (0);
+ }
+
+ return (ENXIO);
}
static int
uninorth_attach(device_t dev)
{
struct uninorth_softc *sc;
+ const char *compatible;
phandle_t node;
phandle_t child;
u_int32_t reg[2], busrange[2];
struct uninorth_range *rp, *io, *mem[2];
int nmem, i, error;
- node = nexus_get_node(dev);
+ node = ofw_bus_get_node(dev);
sc = device_get_softc(dev);
if (OF_getprop(node, "reg", reg, sizeof(reg)) < 8)
@@ -162,15 +178,48 @@ uninorth_attach(device_t dev)
if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8)
return (ENXIO);
+ sc->sc_u3 = 0;
+ compatible = ofw_bus_get_compat(dev);
+ if (strcmp(compatible,"u3-agp") == 0)
+ sc->sc_u3 = 1;
+
sc->sc_dev = dev;
sc->sc_node = node;
- sc->sc_addr = (vm_offset_t)pmap_mapdev(reg[0] + 0x800000, PAGE_SIZE);
- sc->sc_data = (vm_offset_t)pmap_mapdev(reg[0] + 0xc00000, PAGE_SIZE);
+ if (sc->sc_u3) {
+ sc->sc_addr = (vm_offset_t)pmap_mapdev(reg[1] + 0x800000, PAGE_SIZE);
+ sc->sc_data = (vm_offset_t)pmap_mapdev(reg[1] + 0xc00000, PAGE_SIZE);
+ } else {
+ sc->sc_addr = (vm_offset_t)pmap_mapdev(reg[0] + 0x800000, PAGE_SIZE);
+ sc->sc_data = (vm_offset_t)pmap_mapdev(reg[0] + 0xc00000, PAGE_SIZE);
+ }
sc->sc_bus = busrange[0];
bzero(sc->sc_range, sizeof(sc->sc_range));
- sc->sc_nrange = OF_getprop(node, "ranges", sc->sc_range,
- sizeof(sc->sc_range));
+ if (sc->sc_u3) {
+ /*
+ * On Apple U3 systems, we have an otherwise standard
+ * Uninorth controller driving AGP. The one difference
+ * is that it uses a new PCI ranges format, so do the
+ * translation.
+ */
+
+ struct uninorth_range64 range64[6];
+ bzero(range64, sizeof(range64));
+
+ sc->sc_nrange = OF_getprop(node, "ranges", range64,
+ sizeof(range64));
+ for (i = 0; range64[i].pci_hi != 0; i++) {
+ sc->sc_range[i].pci_hi = range64[i].pci_hi;
+ sc->sc_range[i].pci_mid = range64[i].pci_mid;
+ sc->sc_range[i].pci_lo = range64[i].pci_lo;
+ sc->sc_range[i].host = range64[i].host_lo;
+ sc->sc_range[i].size_hi = range64[i].size_hi;
+ sc->sc_range[i].size_lo = range64[i].size_lo;
+ }
+ } else {
+ sc->sc_nrange = OF_getprop(node, "ranges", sc->sc_range,
+ sizeof(sc->sc_range));
+ }
if (sc->sc_nrange == -1) {
device_printf(dev, "could not get ranges\n");
@@ -245,13 +294,6 @@ uninorth_attach(device_t dev)
}
}
- /*
- * Write out the correct PIC interrupt values to config space
- * of all devices on the bus. This has to be done after the GEM
- * cell is enabled above.
- */
- ofw_pci_fixup(dev, sc->sc_bus, node);
-
device_add_child(dev, "pci", device_get_unit(dev));
return (bus_generic_attach(dev));
}
@@ -275,7 +317,7 @@ uninorth_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
if (uninorth_enable_config(sc, bus, slot, func, reg) != 0) {
switch (width) {
- case 1:
+ case 1:
return (in8rb(caoff));
break;
case 2:
@@ -467,6 +509,17 @@ uninorth_enable_config(struct uninorth_softc *sc, u_int bus, u_int slot,
return (1);
}
+static phandle_t
+uninorth_get_node(device_t bus, device_t dev)
+{
+ struct uninorth_softc *sc;
+
+ sc = device_get_softc(bus);
+ /* We only have one child, the PCI bus, which needs our own node. */
+
+ return sc->sc_node;
+}
+
/*
* Driver to swallow UniNorth host bridges from the PCI bus side.
*/
@@ -533,9 +586,9 @@ unin_enable_gmac(void)
static int
unin_chip_probe(device_t dev)
{
- char *name;
+ const char *name;
- name = nexus_get_name(dev);
+ name = ofw_bus_get_name(dev);
if (name == NULL)
return (ENXIO);
@@ -554,7 +607,7 @@ unin_chip_attach(device_t dev)
u_int reg[2];
uncsc = device_get_softc(dev);
- node = nexus_get_node(dev);
+ node = ofw_bus_get_node(dev);
if (OF_getprop(node, "reg", reg, sizeof(reg)) < 8)
return (ENXIO);
diff --git a/sys/powerpc/powermac/uninorthvar.h b/sys/powerpc/powermac/uninorthvar.h
index d2ee8d7..ff789ac 100644
--- a/sys/powerpc/powermac/uninorthvar.h
+++ b/sys/powerpc/powermac/uninorthvar.h
@@ -37,6 +37,16 @@ struct uninorth_range {
u_int32_t size_lo;
};
+struct uninorth_range64 {
+ u_int32_t pci_hi;
+ u_int32_t pci_mid;
+ u_int32_t pci_lo;
+ u_int32_t host_hi;
+ u_int32_t host_lo;
+ u_int32_t size_hi;
+ u_int32_t size_lo;
+};
+
struct uninorth_softc {
device_t sc_dev;
phandle_t sc_node;
@@ -51,6 +61,8 @@ struct uninorth_softc {
bus_space_tag_t sc_iot;
bus_space_tag_t sc_memt;
bus_dma_tag_t sc_dmat;
+
+ int sc_u3;
};
struct unin_chip_softc {
diff --git a/sys/powerpc/psim/iobus.c b/sys/powerpc/psim/iobus.c
index 7c51f8c..6ed8cd3 100644
--- a/sys/powerpc/psim/iobus.c
+++ b/sys/powerpc/psim/iobus.c
@@ -44,6 +44,7 @@
#include <machine/bus.h>
#include <sys/rman.h>
+#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/openfirm.h>
#include <machine/vmparam.h>
@@ -52,7 +53,6 @@
#include <machine/pmap.h>
#include <machine/resource.h>
-#include <machine/nexusvar.h>
#include <powerpc/psim/iobusvar.h>
@@ -121,7 +121,7 @@ DRIVER_MODULE(iobus, nexus, iobus_driver, iobus_devclass, 0, 0);
static int
iobus_probe(device_t dev)
{
- char *type = nexus_get_name(dev);
+ const char *type = ofw_bus_get_name(dev);
if (strcmp(type, "psim-iobus") != 0)
return (ENXIO);
@@ -190,7 +190,7 @@ iobus_attach(device_t dev)
int size;
sc = device_get_softc(dev);
- sc->sc_node = nexus_get_node(dev);
+ sc->sc_node = ofw_bus_get_node(dev);
/*
* Find the base addr/size of the iobus, and initialize the
diff --git a/sys/powerpc/psim/openpic_iobus.c b/sys/powerpc/psim/openpic_iobus.c
index 0a1574e..7a95b1b 100644
--- a/sys/powerpc/psim/openpic_iobus.c
+++ b/sys/powerpc/psim/openpic_iobus.c
@@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#include <machine/intr_machdep.h>
#include <machine/md_var.h>
-#include <machine/nexusvar.h>
#include <machine/pio.h>
#include <machine/resource.h>
OpenPOWER on IntegriCloud