summaryrefslogtreecommitdiff
path: root/sys/arch/sparc
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-05-04 03:44:46 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-05-04 03:44:46 +0000
commitec952e9183677d6369513031c05b09bd06afbea5 (patch)
treec876489f480abe0543e72709f1f25e73f920e72a /sys/arch/sparc
parentaf9c38d3cda06154a0cbd5dbfa54d94871c5bd39 (diff)
setroot() was a ugly mix of MI and MD code, with different bugs on different
machines. Instead -- build one solid clean MI version, and thenchange all the architectures to use it. ok various people, tested on almost all cases. (it is a 10094 line diff..)
Diffstat (limited to 'sys/arch/sparc')
-rw-r--r--sys/arch/sparc/include/autoconf.h5
-rw-r--r--sys/arch/sparc/sparc/autoconf.c506
2 files changed, 75 insertions, 436 deletions
diff --git a/sys/arch/sparc/include/autoconf.h b/sys/arch/sparc/include/autoconf.h
index a7aefd81e28..7e2a690d1af 100644
--- a/sys/arch/sparc/include/autoconf.h
+++ b/sys/arch/sparc/include/autoconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.h,v 1.15 2005/07/08 12:42:57 miod Exp $ */
+/* $OpenBSD: autoconf.h,v 1.16 2007/05/04 03:44:44 deraadt Exp $ */
/* $NetBSD: autoconf.h,v 1.20 1997/05/24 20:03:03 pk Exp $ */
/*
@@ -190,9 +190,6 @@ struct bootpath {
struct bootpath *bootpath_store(int, struct bootpath *);
int sd_crazymap(int);
-/* Parse a disk string into a dev_t, return device struct pointer */
-struct device *parsedisk(char *, int, int, dev_t *);
-
void bootstrap(void);
int firstchild(int);
int nextsibling(int);
diff --git a/sys/arch/sparc/sparc/autoconf.c b/sys/arch/sparc/sparc/autoconf.c
index 5e1b2c5b2e8..f21afa87351 100644
--- a/sys/arch/sparc/sparc/autoconf.c
+++ b/sys/arch/sparc/sparc/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.76 2007/04/30 18:37:00 deraadt Exp $ */
+/* $OpenBSD: autoconf.c,v 1.77 2007/05/04 03:44:44 deraadt Exp $ */
/* $NetBSD: autoconf.c,v 1.73 1997/07/29 09:41:53 fair Exp $ */
/*
@@ -102,12 +102,7 @@ extern int kgdb_debug_panic;
#endif
static int rootnode;
-void setroot(void);
static char *str2hex(char *, int *);
-static int getstr(char *, int);
-int findblkmajor(struct device *);
-char *findblkname(int);
-static struct device *getdisk(char *, int, int, dev_t *);
static int mbprint(void *, const char *);
static void crazymap(char *, int *);
void sync_crash(void);
@@ -122,10 +117,6 @@ static void bootpath_print(struct bootpath *);
int search_prom(int, char *);
char mainbus_model[30];
-#ifdef RAMDISK_HOOKS
-static struct device fakerdrootdev = { DV_DISK, {}, NULL, 0, "rd0", NULL };
-#endif
-
/* Translate SBus interrupt level to processor IPL */
int intr_sbus2ipl_4c[] = {
0, 1, 2, 3, 5, 7, 8, 9
@@ -372,8 +363,6 @@ bootpath_build()
if (cp != NULL)
bootpath_fake(bp, cp);
- bootpath_print(bootpath);
-
/* Setup pointer to boot flags */
cp = (*promvec->pv_v0bootargs)->ba_argv[1];
if (cp == NULL || *cp != '-')
@@ -418,8 +407,6 @@ bootpath_build()
}
bp->name[0] = 0;
- bootpath_print(bootpath);
-
/* Setup pointer to boot flags */
cp = *promvec->pv_v2bootargs.v2_bootargs;
if (cp == NULL)
@@ -762,6 +749,8 @@ cpu_configure()
struct confargs oca;
register int node = 0;
register char *cp;
+ struct bootpath *bp;
+ struct device *bootdv;
int s;
extern struct user *proc0paddr;
@@ -852,7 +841,12 @@ cpu_configure()
* Configure swap area and related system
* parameter based on device(s) used.
*/
- setroot();
+ bootpath_print(bootpath);
+
+ bp = nbootpath == 0 ? NULL : &bootpath[nbootpath-1];
+ bootdv = (bp == NULL) ? NULL : bp->dev;
+
+ setroot(bootdv, bp->val[2], RB_USERREQ | RB_HALT);
dumpconf();
cold = 0;
@@ -1743,423 +1737,6 @@ callrom()
promvec->pv_abort();
}
-#if 0 /* Unused */
-dev_t bootdev;
-#endif
-
-struct nam2blk {
- char *name;
- int maj;
-} nam2blk[] = {
- { "xy", 3 },
- { "sd", 7 },
- { "xd", 10 },
- { "st", 11 },
- { "fd", 16 },
- { "rd", 17 },
- { "cd", 18 },
- { "raid", 25 },
-};
-
-int
-findblkmajor(dv)
- struct device *dv;
-{
- char *name = dv->dv_xname;
- int i;
-
- for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); ++i)
- if (strncmp(name, nam2blk[i].name, strlen(nam2blk[i].name)) == 0)
- return (nam2blk[i].maj);
- return (-1);
-}
-
-char *
-findblkname(maj)
- int maj;
-{
- int i;
-
- for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); ++i)
- if (nam2blk[i].maj == maj)
- return (nam2blk[i].name);
- return (NULL);
-}
-
-static struct device *
-getdisk(str, len, defpart, devp)
- char *str;
- int len, defpart;
- dev_t *devp;
-{
- register struct device *dv;
-
- if ((dv = parsedisk(str, len, defpart, devp)) == NULL) {
- printf("use one of: exit");
-#ifdef RAMDISK_HOOKS
- printf(" %s[a-p]", fakerdrootdev.dv_xname);
-#endif
- TAILQ_FOREACH(dv, &alldevs, dv_list) {
- if (dv->dv_class == DV_DISK)
- printf(" %s[a-p]", dv->dv_xname);
-#ifdef NFSCLIENT
- if (dv->dv_class == DV_IFNET)
- printf(" %s", dv->dv_xname);
-#endif
- }
- printf("\n");
- }
- return (dv);
-}
-
-struct device *
-parsedisk(str, len, defpart, devp)
- char *str;
- int len, defpart;
- dev_t *devp;
-{
- register struct device *dv;
- register char *cp, c;
- int majdev, unit, part;
-
- if (len == 0)
- return (NULL);
- cp = str + len - 1;
- c = *cp;
- if (c >= 'a' && (c - 'a') < MAXPARTITIONS) {
- part = c - 'a';
- *cp = '\0';
- } else
- part = defpart;
-
-#ifdef RAMDISK_HOOKS
- if (strcmp(str, fakerdrootdev.dv_xname) == 0) {
- dv = &fakerdrootdev;
- goto gotdisk;
- }
-#endif
-
- TAILQ_FOREACH(dv, &alldevs, dv_list) {
- if (dv->dv_class == DV_DISK &&
- strcmp(str, dv->dv_xname) == 0) {
-#ifdef RAMDISK_HOOKS
-gotdisk:
-#endif
- majdev = findblkmajor(dv);
- unit = dv->dv_unit;
- if (majdev < 0)
- panic("parsedisk");
- *devp = MAKEDISKDEV(majdev, unit, part);
- break;
- }
-#ifdef NFSCLIENT
- if (dv->dv_class == DV_IFNET &&
- strcmp(str, dv->dv_xname) == 0) {
- *devp = NODEV;
- break;
- }
-#endif
- }
-
- *cp = c;
- return (dv);
-}
-
-/*
- * Attempt to find the device from which we were booted.
- * If we can do so, and not instructed not to do so,
- * change rootdev to correspond to the load device.
- *
- * XXX Actually, swap and root must be on the same type of device,
- * (ie. DV_DISK or DV_IFNET) because of how (*mountroot) is written.
- * That should be fixed.
- */
-void
-setroot()
-{
- register struct swdevt *swp;
- register struct device *dv;
- register int len, majdev, unit, part;
- dev_t nrootdev, nswapdev = NODEV;
- char buf[128];
- dev_t temp;
- struct device *bootdv;
- struct bootpath *bp;
-#if defined(NFSCLIENT)
- extern char *nfsbootdevname;
-#endif
-
- bp = nbootpath == 0 ? NULL : &bootpath[nbootpath-1];
-#ifdef RAMDISK_HOOKS
- bootdv = &fakerdrootdev;
-#else
- bootdv = (bp == NULL) ? NULL : bp->dev;
-#endif
-
- /*
- * (raid) device auto-configuration could have returned
- * the root device's id in rootdev. Check this case.
- */
- if (rootdev != NODEV) {
- majdev = major(rootdev);
- unit = DISKUNIT(rootdev);
- part = DISKPART(rootdev);
-
- len = snprintf(buf, sizeof buf, "%s%d", findblkname(majdev),
- unit);
- if (len == -1 || len >= sizeof(buf))
- panic("setroot: device name too long");
-
- if (len == 4 && strncmp(buf, "exit", 4) == 0)
- boot(RB_USERREQ | RB_HALT);
- bootdv = getdisk(buf, len, part, &rootdev);
- }
-
- /*
- * If `swap generic' and we couldn't determine boot device,
- * ask the user.
- */
- if (mountroot == NULL && bootdv == NULL)
- boothowto |= RB_ASKNAME;
-
- if (boothowto & RB_ASKNAME) {
- for (;;) {
- printf("root device ");
- if (bootdv != NULL)
- printf("(default %s%c)",
- bootdv->dv_xname,
- bootdv->dv_class == DV_DISK
- ? bp->val[2]+'a' : ' ');
- printf(": ");
- len = getstr(buf, sizeof(buf));
- if (len == 0 && bootdv != NULL) {
- strlcpy(buf, bootdv->dv_xname, sizeof buf);
- len = strlen(buf);
- }
- if (len == 4 && strncmp(buf, "exit", 4) == 0)
- boot(RB_USERREQ | RB_HALT);
- if (len > 0 && buf[len - 1] == '*') {
- buf[--len] = '\0';
- dv = getdisk(buf, len, 1, &nrootdev);
- if (dv != NULL) {
- bootdv = dv;
- nswapdev = nrootdev;
- goto gotswap;
- }
- }
- dv = getdisk(buf, len, bp?bp->val[2]:0, &nrootdev);
- if (dv != NULL) {
- bootdv = dv;
- break;
- }
- }
-
- /*
- * because swap must be on same device as root, for
- * network devices this is easy.
- */
- if (bootdv->dv_class == DV_IFNET) {
- goto gotswap;
- }
- for (;;) {
- printf("swap device ");
- if (bootdv != NULL)
- printf("(default %s%c)",
- bootdv->dv_xname,
- bootdv->dv_class == DV_DISK?'b':' ');
- printf(": ");
- len = getstr(buf, sizeof(buf));
- if (len == 4 && strncmp(buf, "exit", 4) == 0)
- boot(RB_USERREQ | RB_HALT);
- if (len == 0 && bootdv != NULL) {
- switch (bootdv->dv_class) {
- case DV_IFNET:
- nswapdev = NODEV;
- break;
- case DV_DISK:
- nswapdev = MAKEDISKDEV(major(nrootdev),
- DISKUNIT(nrootdev), 1);
- break;
- case DV_TAPE:
- case DV_TTY:
- case DV_DULL:
- case DV_CPU:
- break;
- }
- break;
- }
- dv = getdisk(buf, len, 1, &nswapdev);
- if (dv) {
- if (dv->dv_class == DV_IFNET)
- nswapdev = NODEV;
- break;
- }
- }
-gotswap:
- rootdev = nrootdev;
- dumpdev = nswapdev;
- swdevt[0].sw_dev = nswapdev;
- /* swdevt[1].sw_dev = NODEV; */
-
- } else if (mountroot == NULL) {
-
- /*
- * `swap generic': Use the device the ROM told us to use.
- */
- majdev = findblkmajor(bootdv);
- if (majdev >= 0) {
- /*
- * Root and swap are on a disk.
- * val[2] of the boot device is the partition number.
- * Assume swap is on partition b.
- */
- part = bp->val[2];
- unit = bootdv->dv_unit;
- rootdev = MAKEDISKDEV(majdev, unit, part);
- nswapdev = dumpdev = MAKEDISKDEV(major(rootdev),
- DISKUNIT(rootdev), 1);
- } else {
- /*
- * Root and swap are on a net.
- */
- nswapdev = dumpdev = NODEV;
- }
- swdevt[0].sw_dev = nswapdev;
- /* swdevt[1].sw_dev = NODEV; */
-
- } else {
-
- /*
- * `root DEV swap DEV': honour rootdev/swdevt.
- * rootdev/swdevt/mountroot already properly set.
- */
- if (bootdv->dv_class == DV_DISK)
- printf("root on %s%c\n", bootdv->dv_xname,
- part + 'a');
- majdev = major(rootdev);
- unit = DISKUNIT(rootdev);
- part = DISKPART(rootdev);
- return;
- }
-
- switch (bootdv->dv_class) {
-#if defined(NFSCLIENT)
- case DV_IFNET:
- mountroot = nfs_mountroot;
- nfsbootdevname = bootdv->dv_xname;
- return;
-#endif
- case DV_DISK:
- mountroot = dk_mountroot;
- majdev = major(rootdev);
- unit = DISKUNIT(rootdev);
- part = DISKPART(rootdev);
- printf("root on %s%c\n", bootdv->dv_xname,
- part + 'a');
- break;
- default:
- printf("can't figure root, hope your kernel is right\n");
- return;
- }
-
- /*
- * Make the swap partition on the root drive the primary swap.
- */
- temp = NODEV;
- for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
- if (majdev == major(swp->sw_dev) &&
- unit == DISKUNIT(swp->sw_dev)) {
- temp = swdevt[0].sw_dev;
- swdevt[0].sw_dev = swp->sw_dev;
- swp->sw_dev = temp;
- break;
- }
- }
- if (swp->sw_dev != NODEV) {
- /*
- * If dumpdev was the same as the old primary swap device,
- * move it to the new primary swap device.
- */
- if (temp == dumpdev)
- dumpdev = swdevt[0].sw_dev;
- }
-}
-
-static int
-getstr(cp, size)
- register char *cp;
- register int size;
-{
- register char *lp;
- register int c;
- register int len;
-
- lp = cp;
- len = 0;
- for (;;) {
- c = cngetc();
- switch (c) {
- case '\n':
- case '\r':
- printf("\n");
- *lp++ = '\0';
- return (len);
- case '\b':
- case '\177':
- case '#':
- if (len) {
- --len;
- --lp;
- printf("\b \b");
- }
- continue;
- case '@':
- case 'u'&037:
- len = 0;
- lp = cp;
- printf("\n");
- continue;
- default:
- if (len + 1 >= size || c < ' ') {
- printf("\007");
- continue;
- }
- printf("%c", c);
- ++len;
- *lp++ = c;
- }
- }
-}
-
-
-/*
- * find a device matching "name" and unit number
- */
-struct device *
-getdevunit(name, unit)
- char *name;
- int unit;
-{
- struct device *dev = TAILQ_FIRST(&alldevs);
- char num[10], fullname[16];
- int lunit;
-
- /* compute length of name and decimal expansion of unit number */
- snprintf(num, sizeof num, "%d", unit);
- lunit = strlen(num);
- if (strlen(name) + lunit >= sizeof(fullname) - 1)
- panic("config_attach: device name too long");
-
- strlcpy(fullname, name, sizeof fullname);
- strlcat(fullname, num, sizeof fullname);
-
- while (strcmp(dev->dv_xname, fullname) != 0) {
- if ((dev = TAILQ_NEXT(dev, dv_list)) == NULL)
- return NULL;
- }
- return dev;
-}
-
/*
* find the boot device (if it was a disk). we must check to see if
* unit info in saved bootpath structure matches unit info in our softc.
@@ -2224,3 +1801,68 @@ device_register(struct device *dev, void *aux)
}
}
}
+
+/*
+ * find a device matching "name" and unit number
+ */
+struct device *
+getdevunit(name, unit)
+ char *name;
+ int unit;
+{
+ struct device *dev = TAILQ_FIRST(&alldevs);
+ char num[10], fullname[16];
+ int lunit;
+
+ /* compute length of name and decimal expansion of unit number */
+ snprintf(num, sizeof num, "%d", unit);
+ lunit = strlen(num);
+ if (strlen(name) + lunit >= sizeof(fullname) - 1)
+ panic("config_attach: device name too long");
+
+ strlcpy(fullname, name, sizeof fullname);
+ strlcat(fullname, num, sizeof fullname);
+
+ while (strcmp(dev->dv_xname, fullname) != 0) {
+ if ((dev = TAILQ_NEXT(dev, dv_list)) == NULL)
+ return NULL;
+ }
+ return dev;
+}
+
+static struct {
+ char *name;
+ int maj;
+} nam2blk[] = {
+ { "xy", 3 },
+ { "sd", 7 },
+ { "xd", 10 },
+ { "st", 11 },
+ { "fd", 16 },
+ { "rd", 17 },
+ { "cd", 18 },
+ { "raid", 25 }
+};
+
+int
+findblkmajor(struct device *dv)
+{
+ char *name = dv->dv_xname;
+ int i;
+
+ for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); i++)
+ if (!strncmp(name, nam2blk[i].name, strlen(nam2blk[i].name)))
+ return (nam2blk[i].maj);
+ return (-1);
+}
+
+char *
+findblkname(int maj)
+{
+ int i;
+
+ for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); i++)
+ if (nam2blk[i].maj == maj)
+ return (nam2blk[i].name);
+ return (NULL);
+}