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.
This commit is contained in:
parent
aedaba9bc9
commit
33051e5117
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 : "<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;
|
||||
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, ...)
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue