diff --git a/sys/arch/macppc/include/pci_machdep.h b/sys/arch/macppc/include/pci_machdep.h index 28b511479e86..e1d2f109ae6d 100644 --- a/sys/arch/macppc/include/pci_machdep.h +++ b/sys/arch/macppc/include/pci_machdep.h @@ -1,4 +1,4 @@ -/* $NetBSD: pci_machdep.h,v 1.8 1999/05/06 19:16:44 thorpej Exp $ */ +/* $NetBSD: pci_machdep.h,v 1.9 2000/02/01 04:04:17 danw Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -58,6 +58,7 @@ struct pci_bridge { bus_space_tag_t iot; bus_space_tag_t memt; pci_chipset_tag_t pc; + u_int reg[2]; int present; }; struct pci_bridge pci_bridges[2]; diff --git a/sys/arch/macppc/include/types.h b/sys/arch/macppc/include/types.h index 57345147a120..df1b67764561 100644 --- a/sys/arch/macppc/include/types.h +++ b/sys/arch/macppc/include/types.h @@ -1,3 +1,5 @@ -/* $NetBSD: types.h,v 1.2 1998/05/29 10:32:55 tsubai Exp $ */ +/* $NetBSD: types.h,v 1.3 2000/02/01 04:04:17 danw Exp $ */ #include + +#define __HAVE_DEVICE_REGISTER diff --git a/sys/arch/macppc/macppc/autoconf.c b/sys/arch/macppc/macppc/autoconf.c index bfe92ba170fc..f6e4c3fd071d 100644 --- a/sys/arch/macppc/macppc/autoconf.c +++ b/sys/arch/macppc/macppc/autoconf.c @@ -1,4 +1,4 @@ -/* $NetBSD: autoconf.c,v 1.15 1999/09/17 20:04:37 thorpej Exp $ */ +/* $NetBSD: autoconf.c,v 1.16 2000/02/01 04:04:19 danw Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -53,6 +53,8 @@ void findroot __P((void)); int OF_interpret __P((char *cmd, int nreturns, ...)); +extern char bootpath[256]; +char cbootpath[256]; struct device *booted_device; /* boot device */ int booted_partition; /* ...and partition on that device */ @@ -71,6 +73,8 @@ cpu_configure() { int node, reg[5]; int msr; + int phandle; + char *p; node = OF_finddevice("mac-io"); if (node == -1) @@ -87,6 +91,15 @@ cpu_configure() calc_delayconst(); + /* Canonicalize bootpath. */ + strcpy(cbootpath, bootpath); + p = strchr(cbootpath, ':'); + if (p) + *p = '\0'; + phandle = OF_finddevice(cbootpath); + if (phandle != -1) + OF_package_to_path(phandle, cbootpath, sizeof(cbootpath) - 1); + if (config_rootfound("mainbus", NULL) == NULL) panic("configure: mainbus not configured"); @@ -99,6 +112,123 @@ cpu_configure() : "=r"(msr) : "K"((u_short)(PSL_EE|PSL_RI))); } +#define DEVICE_IS(dev, name) \ + (!strncmp(dev->dv_xname, name, sizeof(name) - 1) && \ + dev->dv_xname[sizeof(name) - 1] >= '0' && \ + dev->dv_xname[sizeof(name) - 1] <= '9') + +/* + * device_register is called from config_attach as each device is + * attached. We use it to find the NetBSD device corresponding to the + * known OF boot device. + */ +void +device_register(dev, aux) + struct device *dev; + void *aux; +{ + static struct device *parent = NULL; + static char *bp = bootpath + 1, *cp = cbootpath; + unsigned long addr; + char *p; + + if (booted_device || dev->dv_parent != parent) + return; + + /* Skip over devices not represented in the OF tree. */ + if (DEVICE_IS(dev, "mainbus") || DEVICE_IS(dev, "scsibus") || + DEVICE_IS(dev, "atapibus") || DEVICE_IS(parent, "ppb")) { + parent = dev; + return; + } + + /* Get the address part of the current path component. The + * last component of the canonical bootpath may have no + * address (eg, "disk"), in which case we need to get the + * address from the original bootpath instead. + */ + p = strchr(cp, '@'); + if (!p) { + if (bp) + p = strchr(bp, '@'); + if (!p) + addr = 0; + else { + addr = strtoul(p + 1, NULL, 16); + p = NULL; + } + } else + addr = strtoul(p + 1, &p, 16); + + if (DEVICE_IS(parent, "mainbus") && DEVICE_IS(dev, "pci")) { + struct pcibus_attach_args *pba = aux; + int n; + + for (n = 0; n < 2; n++) { + if (pci_bridges[n].present && + pci_bridges[n].bus == pba->pba_bus) + break; + } + if (n == 2 || addr != pci_bridges[n].reg[0]) + return; + } else if (DEVICE_IS(parent, "pci")) { + struct pci_attach_args *pa = aux; + + if (addr != pa->pa_device) + return; + } else if (DEVICE_IS(parent, "obio")) { + struct confargs *ca = aux; + + if (addr != ca->ca_reg[0]) + return; + } else if (DEVICE_IS(parent, "scsibus") || + DEVICE_IS(parent, "atapibus")) { + struct scsipibus_attach_args *sa = aux; + + if (parent->dv_xname[0] == 's') { + if (addr != sa->sa_sc_link->scsipi_scsi.target) + return; + } else { + if (addr != sa->sa_sc_link->scsipi_atapi.drive) + return; + } + } else if (DEVICE_IS(parent, "pciide")) { + struct ata_atapi_attach *aa = aux; + + if (addr != aa->aa_channel) + return; + + /* + * OF splits channel and drive into separate path + * components, so check the addr part of the next + * component. (Ignore bp, because the canonical path + * will be complete in the pciide case.) + */ + p = strchr(p, '@'); + if (!p++) + return; + if (strtoul(p, &p, 16) != aa->aa_drv_data->drive) + return; + } else + return; + + /* If we reach this point, then dev is a match for the current + * path component. + */ + + if (p && *p) { + parent = dev; + cp = p; + bp = strchr(bp, '/'); + if (bp) + bp++; + return; + } else { + booted_device = dev; + return; + } +} + /* * Setup root device. * Configure swap area. @@ -106,133 +236,12 @@ cpu_configure() void cpu_rootconf() { - findroot(); - printf("boot device: %s\n", booted_device ? booted_device->dv_xname : ""); setroot(booted_device, booted_partition); } -/* - * Try to find the device we were booted from to set rootdev. - */ -void -findroot() -{ - int chosen, node, pnode; - u_int targ, lun = 0; /* XXX lun */ - struct device *dv; - char *p, *controller = "nodev"; - char path[64], type[16], name[16], compat[16]; - - booted_device = NULL; - - /* Cut off filename from "boot/devi/ce/file". */ - path[0] = 0; - p = bootpath; - while ((p = strchr(p + 1, '/')) != NULL) { - char new[64]; - - strcpy(new, bootpath); - new[p - bootpath] = 0; - if (OF_finddevice(new) == -1) - break; - strcpy(path, new); - } - if ((node = OF_finddevice(path)) == -1) - goto out; - - bzero(type, sizeof(type)); - bzero(name, sizeof(name)); - bzero(compat, sizeof(compat)); - if (OF_getprop(node, "device_type", type, 16) == -1) - goto out; - if (OF_getprop(node, "name", name, 16) == -1) - goto out; - OF_getprop(node, "compatible", compat, 16); /* ignore error */ - - if (strcmp(type, "block") == 0) { - char *addr; - - if ((addr = strrchr(path, '@')) == NULL) /* XXX fd:0 */ - goto out; - - targ = addr[1] - '0'; /* XXX > '9' */ - booted_partition = 0; /* = addr[3] - '0'; */ - - if ((pnode = OF_parent(node)) == -1) - goto out; - - bzero(name, sizeof(name)); - if (OF_getprop(pnode, "name", name, sizeof(name)) == -1) - goto out; - bzero(compat, sizeof(compat)); - OF_getprop(pnode, "compatible", compat, 16); - } - - if (strcmp(compat, "heathrow-ata") == 0) controller = "wdc"; - if (strcmp(name, "mace") == 0) controller = "mc"; - if (strcmp(name, "bmac") == 0) controller = "bm"; - if (strcmp(name, "ethernet") == 0) controller = "bm"; - if (strcmp(name, "53c94") == 0) controller = "esp"; - if (strcmp(name, "mesh") == 0) controller = "mesh"; - if (strcmp(name, "ide") == 0) controller = "wdc"; - if (strcmp(name, "ata") == 0) controller = "wdc"; - if (strcmp(name, "ata0") == 0) controller = "wdc"; - if (strcmp(name, "ATA") == 0) controller = "wdc"; - - for (dv = alldevs.tqh_first; dv; dv=dv->dv_list.tqe_next) { - if (dv->dv_class != DV_DISK && dv->dv_class != DV_IFNET) - continue; - - /* XXX ATAPI */ - if (strncmp(dv->dv_xname, "sd", 2) == 0) { - struct scsibus_softc *sdv = (void *)dv->dv_parent; - - /* sd? at scsibus at esp/mesh */ - if (strncmp(dv->dv_parent->dv_parent->dv_xname, - controller, strlen(controller)) != 0) - continue; - if (targ > 7 || lun > 7) - goto out; - if (sdv->sc_link[targ][lun]->device_softc != dv) - continue; - booted_device = dv; - break; - } - - if (strncmp(dv->dv_xname, "wd", 2) == 0) { - struct wdc_softc *wdv = (void *)dv->dv_parent; - - if (strncmp(dv->dv_parent->dv_xname, - controller, strlen(controller)) != 0) - continue; - if (targ >= 2 - || wdv->channels == NULL - || wdv->channels[0]->ch_drive[targ].drv_softc != dv) - continue; - booted_device = dv; - break; - } - - if (strncmp(dv->dv_xname, "mc", 2) == 0) - if (strcmp(controller, "mc") == 0) { - booted_device = dv; - break; - } - - if (strncmp(dv->dv_xname, "bm", 2) == 0) - if (strcmp(controller, "bm") == 0) { - booted_device = dv; - break; - } - } - -out: - dk_cleanup(); -} - int #ifdef __STDC__ OF_interpret(char *cmd, int nreturns, ...) diff --git a/sys/arch/macppc/pci/bandit.c b/sys/arch/macppc/pci/bandit.c index 7f9f7449dfbc..6c26a2db3d66 100644 --- a/sys/arch/macppc/pci/bandit.c +++ b/sys/arch/macppc/pci/bandit.c @@ -1,4 +1,4 @@ -/* $NetBSD: bandit.c,v 1.11 1999/05/06 19:16:45 thorpej Exp $ */ +/* $NetBSD: bandit.c,v 1.12 2000/02/01 04:04:18 danw Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -231,17 +231,19 @@ scan_pci_devs(canmap) * Map the PCI configuration space access registers, * and perform any PCI-Host bridge initialization. */ + if (OF_getprop(node, "reg", pci_bridges[n].reg, + sizeof(pci_bridges[n].reg)) != 8) + continue; if (is_bandit) { /* XXX magic numbers */ pci_bridges[n].pc = n; if (canmap) { - if (OF_getprop(node, "reg", reg, - sizeof(reg)) != 8) - continue; pci_bridges[n].addr = - mapiodev(reg[0] + 0x800000, 4); + mapiodev(pci_bridges[n].reg[0] + 0x800000, + 4); pci_bridges[n].data = - mapiodev(reg[0] + 0xc00000, 4); + mapiodev(pci_bridges[n].reg[0] + 0xc00000, + 4); bandit_init(n); } } else if (is_mpc106) {