Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/macppc Use device_register to find the boot device ...



details:   https://anonhg.NetBSD.org/src/rev/976403a74e80
branches:  trunk
changeset: 481509:976403a74e80
user:      danw <danw%NetBSD.org@localhost>
date:      Tue Feb 01 04:04:17 2000 +0000

description:
Use device_register to find the boot device more reliably. Should now work
on anything it's possible to boot from that we have a driver for.

diffstat:

 sys/arch/macppc/include/pci_machdep.h |    3 +-
 sys/arch/macppc/include/types.h       |    4 +-
 sys/arch/macppc/macppc/autoconf.c     |  253 +++++++++++++++++----------------
 sys/arch/macppc/pci/bandit.c          |   14 +-
 4 files changed, 144 insertions(+), 130 deletions(-)

diffs (truncated from 362 to 300 lines):

diff -r f88488c79b0d -r 976403a74e80 sys/arch/macppc/include/pci_machdep.h
--- a/sys/arch/macppc/include/pci_machdep.h     Tue Feb 01 04:02:59 2000 +0000
+++ b/sys/arch/macppc/include/pci_machdep.h     Tue Feb 01 04:04:17 2000 +0000
@@ -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 @@
        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 -r f88488c79b0d -r 976403a74e80 sys/arch/macppc/include/types.h
--- a/sys/arch/macppc/include/types.h   Tue Feb 01 04:02:59 2000 +0000
+++ b/sys/arch/macppc/include/types.h   Tue Feb 01 04:04:17 2000 +0000
@@ -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 <powerpc/types.h>
+
+#define __HAVE_DEVICE_REGISTER
diff -r f88488c79b0d -r 976403a74e80 sys/arch/macppc/macppc/autoconf.c
--- a/sys/arch/macppc/macppc/autoconf.c Tue Feb 01 04:02:59 2000 +0000
+++ b/sys/arch/macppc/macppc/autoconf.c Tue Feb 01 04:04:17 2000 +0000
@@ -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 @@
 {
        int node, reg[5];
        int msr;
+       int phandle;
+       char *p;
 
        node = OF_finddevice("mac-io");
        if (node == -1)
@@ -87,6 +91,15 @@
 
        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 @@
                      : "=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 @@
 void
 cpu_rootconf()
 {
-       findroot();
-
        printf("boot device: %s\n",
            booted_device ? booted_device->dv_xname : "<unknown>");
 
        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;



Home | Main Index | Thread Index | Old Index