summaryrefslogtreecommitdiff
path: root/sys/arch/sun3
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/sun3')
-rw-r--r--sys/arch/sun3/conf/files.sun34
-rw-r--r--sys/arch/sun3/sun3/autoconf.c557
-rw-r--r--sys/arch/sun3/sun3/stub.c9
-rw-r--r--sys/arch/sun3/sun3/swapgeneric.c355
4 files changed, 536 insertions, 389 deletions
diff --git a/sys/arch/sun3/conf/files.sun3 b/sys/arch/sun3/conf/files.sun3
index 111807ed987..0feef1d2547 100644
--- a/sys/arch/sun3/conf/files.sun3
+++ b/sys/arch/sun3/conf/files.sun3
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sun3,v 1.17 2001/05/11 07:13:16 deraadt Exp $
+# $OpenBSD: files.sun3,v 1.18 2001/05/30 20:37:51 miod Exp $
# $NetBSD: files.sun3,v 1.26 1996/10/29 19:58:14 gwr Exp $
#
@@ -27,7 +27,7 @@ file arch/sun3/sun3/leds.c
file arch/sun3/sun3/machdep.c
file arch/sun3/sun3/mem.c
file arch/sun3/sun3/pmap.c
-file arch/sun3/sun3/stub.c
+file arch/sun3/sun3/stub.c !ddb
file arch/sun3/sun3/sun3_startup.c
file arch/sun3/sun3/sys_machdep.c
file arch/sun3/sun3/trap.c
diff --git a/sys/arch/sun3/sun3/autoconf.c b/sys/arch/sun3/sun3/autoconf.c
index 538fe404ca3..740e67237df 100644
--- a/sys/arch/sun3/sun3/autoconf.c
+++ b/sys/arch/sun3/sun3/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.10 2001/05/05 22:34:24 art Exp $ */
+/* $OpenBSD: autoconf.c,v 1.11 2001/05/30 20:37:54 miod Exp $ */
/* $NetBSD: autoconf.c,v 1.37 1996/11/20 18:57:22 gwr Exp $ */
/*-
@@ -47,26 +47,46 @@
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/device.h>
-#include <sys/map.h>
#include <sys/buf.h>
-#include <sys/dkstat.h>
#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/dkstat.h>
#include <sys/dmap.h>
+#include <sys/map.h>
#include <sys/reboot.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_map.h>
+#ifdef UVM
+#include <uvm/uvm_extern.h>
+#endif
+
#include <machine/autoconf.h>
#include <machine/control.h>
+#include <machine/disklabel.h>
#include <machine/cpu.h>
#include <machine/machdep.h>
+#include <machine/mon.h>
#include <machine/pte.h>
#include <machine/pmap.h>
-int cold;
+#include <dev/cons.h>
+
+/* Want compile-time initialization here. */
+int cold = 1;
+
+void setroot __P((void));
+void swapconf __P((void));
+int findblkmajor __P((struct device *));
+struct device *getdisk __P((char *, int, int, dev_t *));
+struct device *parsedisk __P((char *, int, int, dev_t *));
+int getstr __P((char *, int));
void
cpu_configure()
@@ -78,44 +98,21 @@ cpu_configure()
if (mainbus == NULL)
panic("cpu_configure: mainbus not found");
- /* Choose root and swap devices. */
- swapgeneric();
- swapconf();
- dumpconf();
-
/*
* Now that device autoconfiguration is finished,
* we can safely enable interrupts.
*/
printf("enabling interrupts\n");
(void)spl0();
- cold = 0;
-}
-
-/*
- * Configure swap space and related parameters.
- */
-void
-swapconf()
-{
- struct swdevt *swp;
- u_int maj;
- int nblks;
-
- for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
-
- maj = major(swp->sw_dev);
- if (maj > nblkdev) /* paranoid? */
- break;
- if (bdevsw[maj].d_psize) {
- nblks = (*bdevsw[maj].d_psize)(swp->sw_dev);
- if (nblks > 0 &&
- (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
- swp->sw_nblks = nblks;
- swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
- }
- }
+ /*
+ * Configure swap area and related system
+ * parameters based on device(s) used.
+ */
+ setroot();
+ swapconf();
+
+ cold = 0;
}
/*
@@ -213,7 +210,8 @@ static const int bustype_to_ptetype[4] = {
* Try the access using peek_*
* Clean up temp. mapping
*/
-int bus_peek(bustype, paddr, sz)
+int
+bus_peek(bustype, paddr, sz)
int bustype, paddr, sz;
{
int off, pte, rv;
@@ -283,7 +281,11 @@ bus_mapin(bustype, paddr, sz)
pmt |= PMAP_NC; /* non-cached */
/* Get some kernel virtual address space. */
+#ifdef UVM
+ va = uvm_km_valloc_wait(kernel_map, sz);
+#else
va = kmem_alloc_wait(kernel_map, sz);
+#endif
if (va == 0)
panic("bus_mapin");
retval = va + off;
@@ -338,3 +340,484 @@ peek_byte(addr)
nofault = NULL;
return(x);
}
+
+/****************************************************************/
+
+/*
+ * Configure swap space and related parameters.
+ */
+void
+swapconf()
+{
+ register struct swdevt *swp;
+ register int nblks;
+
+ for (swp = swdevt; swp->sw_dev != NODEV; swp++)
+ if (bdevsw[major(swp->sw_dev)].d_psize) {
+ nblks =
+ (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
+ if (nblks != -1 &&
+ (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
+ swp->sw_nblks = nblks;
+ swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
+ }
+ dumpconf();
+}
+
+struct nam2blk {
+ char *name;
+ int maj;
+} nam2blk[] = {
+ { "xy", 3 },
+ { "sd", 7 },
+ { "xd", 10 },
+ { "st", 11 },
+ { "rd", 17 },
+ { "cd", 18 },
+};
+
+/* This takes the args: name, ctlr, unit */
+typedef struct device *(*findfunc_t) __P((char *, int, int));
+
+struct device *find_dev_byname __P((char *));
+struct device *net_find __P((char *, int, int));
+struct device *scsi_find __P((char *, int, int));
+struct device *xx_find __P((char *, int, int));
+
+struct prom_n2f {
+ char name[4];
+ findfunc_t func;
+} prom_dev_table[] = {
+ { "ie", net_find },
+ { "le", net_find },
+ { "sd", scsi_find },
+ { "xy", xx_find },
+ { "xd", xx_find },
+};
+
+int
+findblkmajor(dv)
+ struct device *dv;
+{
+ char *name = dv->dv_xname;
+ register int i;
+
+ for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); ++i)
+ if (strncmp(name, nam2blk[i].name, strlen(nam2blk[0].name)) == 0)
+ return (nam2blk[i].maj);
+ return (-1);
+}
+
+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:");
+ for (dv = alldevs.tqh_first; dv != NULL;
+ dv = dv->dv_list.tqe_next) {
+ if (dv->dv_class == DV_DISK)
+ printf(" %s[a-%c]", dv->dv_xname,
+ 'a' + MAXPARTITIONS - 1);
+#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;
+
+ for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
+ if (dv->dv_class == DV_DISK &&
+ strcmp(str, dv->dv_xname) == 0) {
+ 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()
+{
+ MachMonBootParam *bp;
+ struct prom_n2f *nf;
+ char promname[3];
+ findfunc_t find;
+ struct swdevt *swp;
+ struct device *bootdv;
+ int len, majdev, unit, part;
+ dev_t nrootdev, nswapdev = NODEV;
+ char buf[128];
+ dev_t temp;
+#if defined(NFSCLIENT)
+ extern char *nfsbootdevname;
+#endif
+
+ /* PROM boot parameters. */
+ bp = *romp->bootParam;
+
+ /*
+ * Copy PROM boot device name (two letters)
+ * to a normal, null terminated string.
+ * (No terminating null in bp->devName)
+ */
+ promname[0] = bp->devName[0];
+ promname[1] = bp->devName[1];
+ promname[2] = '\0';
+
+ /* Default to "unknown" */
+ bootdv = NULL;
+ part = 0;
+ find = NULL;
+
+ /* Do we know anything about the PROM boot device? */
+ for (nf = prom_dev_table; nf->func; nf++)
+ if (strcmp(nf->name, promname) == 0) {
+ find = nf->func;
+ break;
+ }
+ if (find != NULL)
+ bootdv = (*find)(promname, bp->ctlrNum, bp->unitNum);
+ if (bootdv != NULL) {
+ if (bootdv->dv_class == DV_DISK)
+ part = bp->partNum;
+ }
+
+ /*
+ * 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
+ ? part + 'a' : ' ');
+ printf(": ");
+ len = getstr(buf, sizeof(buf));
+ if (len == 0 && bootdv != NULL) {
+ strcpy(buf, bootdv->dv_xname);
+ len = strlen(buf);
+ }
+ if (len > 0 && buf[len - 1] == '*') {
+ buf[--len] = '\0';
+ bootdv = getdisk(buf, len, 1, &nrootdev);
+ if (bootdv != NULL) {
+ nswapdev = nrootdev;
+ goto gotswap;
+ }
+ }
+ bootdv = getdisk(buf, len, part, &nrootdev);
+ if (bootdv != NULL) {
+ 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 == 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;
+ }
+ bootdv = getdisk(buf, len, 1, &nswapdev);
+ if (bootdv != NULL) {
+ if (bootdv->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 PROM told us to use.
+ */
+ majdev = findblkmajor(bootdv);
+ if (majdev >= 0) {
+ /*
+ * Root and swap are on a disk.
+ * part is the partition number.
+ * Assume swap is on partition b.
+ */
+ 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.
+ */
+ 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;
+ }
+}
+
+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;
+ }
+ }
+}
+
+/*
+ * Functions to find devices using PROM boot parameters.
+ */
+
+/*
+ * Network device: Just use controller number.
+ */
+struct device *
+net_find(name, ctlr, unit)
+ char *name;
+ int ctlr, unit;
+{
+ char tname[16];
+
+ sprintf(tname, "%s%d", name, ctlr);
+ return (find_dev_byname(tname));
+}
+
+/*
+ * SCSI device: The controller number corresponds to the
+ * scsibus number, and the unit number is (targ*8 + LUN).
+ */
+struct device *
+scsi_find(name, ctlr, unit)
+ char *name;
+ int ctlr, unit;
+{
+ struct device *scsibus;
+ struct scsibus_softc *sbsc;
+ struct scsi_link *sc_link;
+ int target, lun;
+ char tname[16];
+
+ sprintf(tname, "scsibus%d", ctlr);
+ scsibus = find_dev_byname(tname);
+ if (scsibus == NULL)
+ return (NULL);
+
+ /* Compute SCSI target/LUN from PROM unit. */
+ target = (unit >> 3) & 7;
+ lun = unit & 7;
+
+ /* Find the device at this target/LUN */
+ sbsc = (struct scsibus_softc *)scsibus;
+ sc_link = sbsc->sc_link[target][lun];
+ if (sc_link == NULL)
+ return (NULL);
+
+ return (sc_link->device_softc);
+}
+
+/*
+ * Xylogics SMD disk: (xy, xd)
+ * Assume wired-in unit numbers for now...
+ */
+struct device *
+xx_find(name, ctlr, unit)
+ char *name;
+ int ctlr, unit;
+{
+ int diskunit;
+ char tname[16];
+
+ diskunit = (ctlr * 2) + unit;
+ sprintf(tname, "%s%d", name, diskunit);
+ return (find_dev_byname(tname));
+}
+
+/*
+ * Given a device name, find its struct device
+ * XXX - Move this to some common file?
+ */
+struct device *
+find_dev_byname(name)
+ char *name;
+{
+ struct device *dv;
+
+ for (dv = alldevs.tqh_first; dv != NULL;
+ dv = dv->dv_list.tqe_next) {
+ if (strcmp(dv->dv_xname, name) == 0) {
+ return(dv);
+ }
+ }
+ return (NULL);
+}
diff --git a/sys/arch/sun3/sun3/stub.c b/sys/arch/sun3/sun3/stub.c
index 9c0adcee5c8..c79cfbd0785 100644
--- a/sys/arch/sun3/sun3/stub.c
+++ b/sys/arch/sun3/sun3/stub.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: stub.c,v 1.7 2001/01/03 01:49:09 miod Exp $ */
+/* $OpenBSD: stub.c,v 1.8 2001/05/30 20:37:54 miod Exp $ */
/* $NetBSD: stub.c,v 1.13 1996/11/20 18:57:37 gwr Exp $ */
/*-
@@ -48,18 +48,11 @@
#ifndef DDB
void Debugger __P((void));
-#endif
-
-/* Called by autoconf.c */
-#ifdef RAMDISK_HOOKS
-void swapgeneric() {}
-#endif
/*
* When DDB is included, Debugger() comes from db_interface.c
* otherwise we get the one compiled here.
*/
-#ifndef DDB
void
Debugger()
{
diff --git a/sys/arch/sun3/sun3/swapgeneric.c b/sys/arch/sun3/sun3/swapgeneric.c
index a7bc52873f2..238606cadf5 100644
--- a/sys/arch/sun3/sun3/swapgeneric.c
+++ b/sys/arch/sun3/sun3/swapgeneric.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: swapgeneric.c,v 1.5 1997/01/16 04:04:33 kstailey Exp $ */
+/* $OpenBSD: swapgeneric.c,v 1.6 2001/05/30 20:37:54 miod Exp $ */
/* $NetBSD: swapgeneric.c,v 1.14 1995/04/26 23:30:08 gwr Exp $ */
/*
@@ -32,356 +32,27 @@
*/
/*
- * Generic configuration (one kernel fits all 8-)
- * Some ideas taken from i386 port but no code.
- *
- * Allow root/swap on any of: le,sd
- * Eventually, allow: ie,st,xd,xy
+ * Generic swap locations
*/
#include <sys/param.h>
#include <sys/conf.h>
-#include <sys/buf.h>
#include <sys/systm.h>
-#include <sys/reboot.h>
-
-#include <dev/cons.h>
-
-#include <machine/machdep.h>
-#include <machine/mon.h>
-#ifdef NFSCLIENT
-extern char *nfsbootdevname; /* nfs_boot.c */
-#endif /* NFSCLIENT */
-
-int (*mountroot) __P((void)) = NULL;
+int (*mountroot) __P((void)) = NULL; /* tells autoconf.c that we are "generic" */
dev_t rootdev = NODEV;
dev_t dumpdev = NODEV;
struct swdevt swdevt[] = {
- { NODEV, 0, 0 },
- { NODEV, 0, 0 },
+ { makedev(7, 1), 0, 0 }, /* sd0b */
+ { makedev(7, 17), 0, 0 }, /* sd1b */
+ { makedev(7, 33), 0, 0 }, /* sd2b */
+ { makedev(7, 49), 0, 0 }, /* sd3b */
+ { makedev(3, 1), 0, 0 }, /* xy0b */
+ { makedev(3, 17), 0, 0 }, /* xy1b */
+ { makedev(10, 1), 0, 0 }, /* xd0b */
+ { makedev(10, 17), 0, 0 }, /* xd1b */
+ { NODEV, 0, 0 },
+ { NODEV, 0, 0 }
};
-
-
-struct devspec {
- int major;
- int unit;
- int part;
- char name[4];
-};
-
-#define NAMESZ 16
-char boot_ifname[NAMESZ];
-
-
-static int net_mkunit __P((int, int));
-static int sd_mkunit __P((int, int));
-static int xx_mkunit __P((int, int));
-static struct genconf *gc_lookup __P((char *));
-static void gc_print_all __P((void));
-static int ds_parse __P((struct devspec *, char *));
-static int ds_tostr __P((struct devspec *, char *));
-static void ds_from_boot __P((struct devspec *));
-static void ds_query __P((struct devspec *, char *));
-static dev_t ds_todev __P((struct devspec *));
-
-/*
- * Devices which MIGHT be available.
- * If gc_root is NODEV, use NFS root.
- */
-static struct genconf {
- char gc_name[4];
- int gc_major;
- int (*gc_mkunit)__P((int, int));
-} genconf[] = {
- { {"ie"}, -1, net_mkunit },
- { {"le"}, -1, net_mkunit },
- { {"sd"}, 7, sd_mkunit },
- { {"xy"}, 3, xx_mkunit },
- { {"xd"}, 10, xx_mkunit },
- { {0}, },
-};
-
-/*
- * Functions to convert PROM ctlr/unit into our unit numbers
- */
-static int
-net_mkunit(ctlr, unit)
- int ctlr, unit;
-{
-
- /* XXX - Not sure which is set. */
- return (ctlr + unit);
-}
-
-static int
-sd_mkunit(ctlr, unit)
- int ctlr, unit;
-{
- int target, lun;
-
- /* This only supports LUNs 0, 1 */
- target = unit >> 3;
- lun = unit & 1;
- return (target * 2 + lun);
-}
-
-static int
-xx_mkunit(ctlr, unit)
- int ctlr, unit;
-{
-
- return (ctlr * 2 + unit);
-}
-
-static struct genconf *
-gc_lookup(name)
- char *name;
-{
- struct genconf *gc;
-
- gc = genconf;
- while (gc->gc_major) {
- if ((gc->gc_name[0] == name[0]) &&
- (gc->gc_name[1] == name[1]))
- return gc;
- gc++;
- }
- return NULL;
-}
-
-static void
-gc_print_all()
-{
- struct genconf *gc;
-
- gc = genconf;
- for (;;) {
- printf("%s", gc->gc_name);
- gc++;
- if (gc->gc_major == 0)
- break;
- printf(", ");
- }
- printf("\n");
-}
-
-/*
- * Set devspec from a string like: "sd0a"
- * Return length of recognized part.
- */
-static int
-ds_parse(ds, str)
- struct devspec *ds;
- char *str;
-{
- struct genconf *gc;
- int unit, part;
- char *p;
-
- bzero((caddr_t)ds, sizeof(*ds));
- while (*str == ' ')
- str++;
- p = str;
-
- gc = gc_lookup(p);
- if (!gc) return 0;
-
- /* Major number from the genconf table. */
- ds->major = gc->gc_major;
-
- /* Device name (always two letters on Suns) */
- ds->name[0] = *p++;
- ds->name[1] = *p++;
-
- /* Unit number */
- unit = 0;
- while ('0' <= *p && *p <= '9') {
- unit *= 10;
- unit += (*p++ - '0');
- }
- ds->unit = unit & 0x1F;
-
- /* Partition letter */
- part = 0;
- if ('a' <= *p && *p <= 'h')
- part = *p++ - 'a';
- ds->part = part;
-
- return (p - str);
-}
-
-/*
- * Format a devspec into a string like: "sd0a"
- * Returns length of string.
- */
-static int
-ds_tostr(ds, str)
- struct devspec *ds;
- char *str;
-{
- int unit, part;
- char *p;
-
- p = str;
-
- /* Device name (always two letters on Suns) */
- *p++ = ds->name[0];
- *p++ = ds->name[1];
-
- /* Unit number */
- unit = ds->unit & 0x1f;
- if (unit >= 10) {
- *p++ = '0' + (unit / 10);
- unit = unit % 10;
- }
- *p++ = '0' + unit;
-
- /* Partition letter (only for disks). */
- if (ds->major >= 0) {
- part = ds->part & 7;
- *p++ = 'a' + part;
- }
-
- *p = '\0';
- return (p - str);
-}
-
-/*
- * Set the devspec to the device we booted from.
- * (Just converts PROM boot parameters.)
- */
-static void
-ds_from_boot(ds)
- struct devspec *ds;
-{
- MachMonBootParam *bpp;
- struct genconf *gc;
-
- bpp = *romp->bootParam;
-
- bzero((caddr_t)ds, sizeof(*ds));
-
- /* Device name (always two letters) */
- ds->name[0] = bpp->devName[0];
- ds->name[1] = bpp->devName[1];
-
- /* Is this device known? */
- gc = gc_lookup(ds->name);
- if (gc == NULL) {
- /* Boot device not in genconf, so ask. */
- boothowto |= RB_ASKNAME;
- return;
- }
-
- /* Compute our equivalents of the prom info. */
- ds->major = gc->gc_major;
- ds->unit = gc->gc_mkunit(bpp->ctlrNum, bpp->unitNum);
- ds->part = bpp->partNum;
-}
-
-/*
- * Fill in the devspec by asking the operator.
- * The ds passed may hold a default value.
- */
-static void
-ds_query(ds, what)
- struct devspec *ds;
- char *what;
-{
- int len;
- char buf[64];
-
- for (;;) {
- len = ds_tostr(ds, buf);
- printf("%s device? [%s] ", what, buf);
-
- getsn(buf, 64);
- if (buf[0] == '\0')
- return;
-
- len = ds_parse(ds, buf);
- if (len > 2)
- break;
-
- printf("Invalid name. Use one of: ");
- gc_print_all();
- }
-}
-
-static dev_t
-ds_todev(ds)
- struct devspec *ds;
-{
- int minor;
- if (ds->major < 0)
- return NODEV;
- minor = (ds->unit << 3) + (ds->part & 7);
- return (makedev(ds->major, minor));
-}
-
-/*
- * Choose the root and swap device, either by asking,
- * (if RB_ASKNAME) or from the PROM boot parameters.
- */
-void
-swapgeneric()
-{
- struct devspec ds;
- char buf[NAMESZ];
-
- /*
- * Choose the root device.
- * Default is boot device.
- */
- ds_from_boot(&ds);
- if (boothowto & RB_ASKNAME)
- ds_query(&ds, "root");
- else {
- ds_tostr(&ds, buf);
- printf("root on %s\n", buf);
- }
- rootdev = ds_todev(&ds);
-
- /*
- * Choose the root fstype.
- * XXX - Hard coded for now.
- */
-#ifdef NFSCLIENT
- if (rootdev == NODEV) {
- /* Set boot interface name for nfs_mountroot. */
- nfsbootdevname = boot_ifname;
- ds_tostr(&ds, boot_ifname);
- mountroot = nfs_mountroot;
- } else
-#endif /* NFSCLIENT */
- {
- /* XXX - Should ask for the root fstype here. -gwr */
- mountroot = dk_mountroot;
- }
-
- /*
- * Choose the swap device. (Default from root)
- */
- ds.part = 1;
- if (boothowto & RB_ASKNAME)
- ds_query(&ds, "swap");
- else {
- ds_tostr(&ds, buf);
- printf("swap on %s\n", buf);
- }
- swdevt[0].sw_dev = ds_todev(&ds);
-
- /*
- * Choose the dump device. (Default from swap)
- */
- if (boothowto & RB_ASKNAME)
- ds_query(&ds, "dump");
- else {
- ds_tostr(&ds, buf);
- printf("dump on %s\n", buf);
- }
- dumpdev = ds_todev(&ds);
-}