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