diff options
-rw-r--r-- | sys/conf/files.powerpc | 2 | ||||
-rw-r--r-- | sys/dev/powermac_nvram/powermac_nvram.c | 12 | ||||
-rw-r--r-- | sys/powerpc/aim/nexus.c | 8 | ||||
-rw-r--r-- | sys/powerpc/aim/ofw_machdep.c | 4 | ||||
-rw-r--r-- | sys/powerpc/include/nexusvar.h | 58 | ||||
-rw-r--r-- | sys/powerpc/ofw/ofw_pci.c | 229 | ||||
-rw-r--r-- | sys/powerpc/ofw/ofw_pci.h | 34 | ||||
-rw-r--r-- | sys/powerpc/ofw/ofw_pcib_pci.c | 33 | ||||
-rw-r--r-- | sys/powerpc/ofw/ofw_pcibus.c | 359 | ||||
-rw-r--r-- | sys/powerpc/ofw/ofw_syscons.c | 9 | ||||
-rw-r--r-- | sys/powerpc/powermac/ata_kauai.c | 60 | ||||
-rw-r--r-- | sys/powerpc/powermac/grackle.c | 36 | ||||
-rw-r--r-- | sys/powerpc/powermac/hrowpic.c | 1 | ||||
-rw-r--r-- | sys/powerpc/powermac/macio.c | 4 | ||||
-rw-r--r-- | sys/powerpc/powermac/openpic_macio.c | 1 | ||||
-rw-r--r-- | sys/powerpc/powermac/uninorth.c | 101 | ||||
-rw-r--r-- | sys/powerpc/powermac/uninorthvar.h | 12 | ||||
-rw-r--r-- | sys/powerpc/psim/iobus.c | 6 | ||||
-rw-r--r-- | sys/powerpc/psim/openpic_iobus.c | 1 |
19 files changed, 520 insertions, 450 deletions
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index bc9e950..c6bd57c 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -104,7 +104,7 @@ powerpc/mpc85xx/nexus.c optional mpc85xx powerpc/mpc85xx/ocpbus.c optional mpc85xx powerpc/mpc85xx/opic.c optional mpc85xx powerpc/mpc85xx/pci_ocp.c optional pci mpc85xx -powerpc/ofw/ofw_pci.c optional pci aim +powerpc/ofw/ofw_pcibus.c optional pci aim powerpc/ofw/ofw_pcib_pci.c optional pci aim powerpc/ofw/ofw_syscons.c optional sc aim powerpc/powermac/ata_kauai.c optional powermac ata diff --git a/sys/dev/powermac_nvram/powermac_nvram.c b/sys/dev/powermac_nvram/powermac_nvram.c index a22c7ab..a55fcae 100644 --- a/sys/dev/powermac_nvram/powermac_nvram.c +++ b/sys/dev/powermac_nvram/powermac_nvram.c @@ -35,17 +35,15 @@ #include <sys/uio.h> #include <dev/ofw/openfirm.h> -#include <dev/ofw/ofw_pci.h> +#include <dev/ofw/ofw_bus.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 <dev/powermac_nvram/powermac_nvramvar.h> #include <vm/vm.h> @@ -113,10 +111,10 @@ static struct cdevsw powermac_nvram_cdevsw = { static int powermac_nvram_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; @@ -136,7 +134,7 @@ powermac_nvram_attach(device_t dev) u_int32_t reg[2]; int gen0, gen1; - 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) 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> |