diff options
author | chuck <chuck@cvs.openbsd.org> | 1996-05-29 16:37:18 +0000 |
---|---|---|
committer | chuck <chuck@cvs.openbsd.org> | 1996-05-29 16:37:18 +0000 |
commit | ef8cd5454d010b6164eee47f280096ab43424bc7 (patch) | |
tree | c8a8ca3af44c161752783c38c9089e129a0854dc /sys | |
parent | 0a25818ac3349e6f2aa96c3a178f074a7c66ea97 (diff) |
new generic boot
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/mvme68k/mvme68k/autoconf.c | 343 | ||||
-rw-r--r-- | sys/arch/mvme68k/mvme68k/disksubr.c | 42 | ||||
-rw-r--r-- | sys/arch/mvme68k/mvme68k/locore.s | 58 |
3 files changed, 321 insertions, 122 deletions
diff --git a/sys/arch/mvme68k/mvme68k/autoconf.c b/sys/arch/mvme68k/mvme68k/autoconf.c index 0ecb0720ebc..cadb124da60 100644 --- a/sys/arch/mvme68k/mvme68k/autoconf.c +++ b/sys/arch/mvme68k/mvme68k/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.5 1996/04/28 10:58:38 deraadt Exp $ */ +/* $OpenBSD: autoconf.c,v 1.6 1996/05/29 16:37:16 chuck Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -92,6 +92,7 @@ #include <machine/vmparam.h> #include <machine/autoconf.h> +#include <machine/disklabel.h> #include <machine/cpu.h> #include <machine/pte.h> @@ -102,6 +103,10 @@ */ extern int cold; /* if 1, still working on cold-start */ +static int getstr __P((char *, int)); +struct device *parsedisk __P((char *, int, int, dev_t *)); +void setroot __P((void)); + /* XXX must be allocated statically because of early console init */ struct map extiomap[EIOMAPSIZE/16]; extern char *extiobase; @@ -179,6 +184,8 @@ mainbus_attach(parent, self, args) */ configure() { + bootdv = NULL; /* set by device drivers (if found) */ + init_sir(); rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16); @@ -257,82 +264,140 @@ swapconf() dumpconf(); } -u_long bootdev; - -#define PARTITIONMASK (MAXPARTITIONS-1) +/* + * the rest of this file was adapted from Theo de Raadt's code in the + * sparc port to nuke the "options GENERIC" stuff. + */ -struct bdevnam { +struct nam2blk { char *name; int maj; -} bdevnam[] = { - { "sd", 4 }, - { "cd", 6 }, - { "xd", 10 }, +} nam2blk[] = { + { "sd", 4 }, + { "st", 6 }, }; -char * -blktonam(blk) - int blk; +static int +findblkmajor(dv) + struct device *dv; { - int i; + char *name = dv->dv_xname; + register int i; - for (i = 0; i < sizeof(bdevnam)/sizeof(bdevnam[0]); i++) - if (bdevnam[i].maj == blk) - return (bdevnam[i].name); - return ("??"); + 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); +} + +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:"); + for (dv = alldevs.tqh_first; dv != NULL; + dv = dv->dv_list.tqe_next) { + if (dv->dv_class == DV_DISK) + printf(" %s[a-h]", 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, mindev, part; + + if (len == 0) + return (NULL); + cp = str + len - 1; + c = *cp; + if (c >= 'a' && c <= 'h') { + 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); + if (majdev < 0) + panic("parsedisk"); + mindev = (dv->dv_unit << PARTITIONSHIFT) + part; + *devp = makedev(majdev, mindev); + 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() { - int majdev, mindev, nswapdev; - extern int (*mountroot)(); + register struct swdevt *swp; + register struct device *dv; + register int len, majdev, mindev; + dev_t nrootdev, nswapdev = NODEV; + char buf[128]; + extern int (*mountroot) __P((void *)); + dev_t temp; #if defined(NFSCLIENT) extern char *nfsbootdevname; - extern int nfs_mountroot(); + extern int nfs_mountroot __P((void *)); #endif #if defined(FFS) - extern int ffs_mountroot(); -#endif - int boottype = DV_DISK; - int tmp; - -#ifdef DEBUG - printf("bootdev 0x%08x boothowto 0x%08x\n", bootdev, boothowto); + extern int ffs_mountroot __P((void *)); #endif - /* - * ignore DFLTROOT in the `swap generic' case. - */ - if (boothowto & RB_DFLTROOT || - (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) - if (mountroot) - return; + printf("boot device: %s\n", + (bootdv) ? bootdv->dv_xname : "<unknown>"); if (boothowto & RB_ASKNAME) { -#if 0 - char *devname; - - majdev = B_TYPE(bootdev); - mindev = B_UNIT(bootdev); - name = searchname(majdev); - while (mindev == 0 - if (bootdv && bootdv->dv_class == DV_DISK) - printf("root device (default %sa)? ", - name); - else if (bootdv) - printf("root device (default %s)? ", - name); - else - printf("root device ? "); + for (;;) { + printf("root device "); + if (bootdv != NULL) + printf("(default %s%c)", + bootdv->dv_xname, + bootdv->dv_class == DV_DISK + ? 'a' : ' '); + printf(": "); len = getstr(buf, sizeof(buf)); - if (len == 0) { - if (!bootdv) - continue; + if (len == 0 && bootdv != NULL) { strcpy(buf, bootdv->dv_xname); len = strlen(buf); } @@ -351,29 +416,23 @@ setroot() break; } } - /*XXXX remember to set boottype if we are a network device!! */ /* * because swap must be on same device as root, for * network devices this is easy. - * XXX: IS THIS STILL TRUE? */ if (bootdv->dv_class == DV_IFNET) { goto gotswap; } for (;;) { - if (bootdv && bootdv->dv_class == DV_DISK) - printf("swap device (default %sb)? ", - bootdv->dv_xname); - else if (bootdv) - printf("swap device (default %s)? ", - bootdv->dv_xname); - else - printf("swap device ? "); + 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) { - if (!bootdv) - continue; + if (len == 0 && bootdv != NULL) { switch (bootdv->dv_class) { case DV_IFNET: nswapdev = NODEV; @@ -382,6 +441,11 @@ setroot() nswapdev = makedev(major(nrootdev), (minor(nrootdev) & ~ PARTITIONMASK) | 1); break; + case DV_TAPE: + case DV_TTY: + case DV_DULL: + case DV_CPU: + break; } break; } @@ -396,46 +460,39 @@ gotswap: rootdev = nrootdev; dumpdev = nswapdev; swdevt[0].sw_dev = nswapdev; - /* swdevt[1].sw_dev = NODEV; */ - /* XXX should ask for devices to boot from */ -#else - panic("RB_ASKNAME not implimented"); -#endif + swdevt[1].sw_dev = NODEV; + } else if (mountroot == NULL) { + /* - * `swap generic': Use the device the boot program - * told us to use. This is a bit messy, since the ROM - * doesn't give us a standard dev_t. - * B_TYPE: 0 = disk, 1 = net - * B_ADAPTER: major # of disk device driver XXX - * B_UNIT: disk unit number + * `swap generic': Use the device the ROM told us to use. */ - if (B_TYPE(bootdev) == 0) { + if (bootdv == NULL) + panic("boot device not known"); + + majdev = findblkmajor(bootdv); + if (majdev >= 0) { /* * Root and swap are on a disk. - * Assume that we are supposed to put root on - * partition a, and swap on partition b. + * val[2] of the boot device is the partition number. + * Assume swap is on partition b. */ - switch (B_ADAPTOR(bootdev)) { - case 0: - majdev = 4; - break; - } - mindev = B_UNIT(bootdev) << PARTITIONSHIFT; + int part = bootpart; + mindev = (bootdv->dv_unit << PARTITIONSHIFT) + part; rootdev = makedev(majdev, mindev); nswapdev = dumpdev = makedev(major(rootdev), (minor(rootdev) & ~ PARTITIONMASK) | 1); } else { /* * Root and swap are on a net. - * XXX we don't know which network device... */ nswapdev = dumpdev = NODEV; - boottype = DV_IFNET; } swdevt[0].sw_dev = nswapdev; - /* swdevt[1].sw_dev = NODEV; */ + swdevt[1].sw_dev = NODEV; + } else { + /* * `root DEV swap DEV': honour rootdev/swdevt. * rootdev/swdevt/mountroot already properly set. @@ -443,25 +500,123 @@ gotswap: return; } - switch (boottype) { + switch (bootdv->dv_class) { #if defined(NFSCLIENT) case DV_IFNET: mountroot = nfs_mountroot; - nfsbootdevname = NULL; /* XXX don't know it */ - break; + nfsbootdevname = bootdv->dv_xname; + return; #endif #if defined(FFS) case DV_DISK: mountroot = ffs_mountroot; majdev = major(rootdev); mindev = minor(rootdev); - printf("root on %s%d%c\n", blktonam(majdev), - mindev >> PARTITIONSHIFT, + printf("root on %s%c\n", bootdv->dv_xname, (mindev & PARTITIONMASK) + 'a'); break; #endif default: printf("can't figure root, hope your kernel is right\n"); - break; + return; + } + + /* + * XXX: What is this doing? + */ + mindev &= ~PARTITIONMASK; + temp = NODEV; + for (swp = swdevt; swp->sw_dev != NODEV; swp++) { + if (majdev == major(swp->sw_dev) && + mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { + temp = swdevt[0].sw_dev; + swdevt[0].sw_dev = swp->sw_dev; + swp->sw_dev = temp; + break; + } + } + if (swp->sw_dev == NODEV) + return; + + /* + * 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 = alldevs.tqh_first; + char num[10], fullname[16]; + int lunit; + + /* compute length of name and decimal expansion of unit number */ + sprintf(num, "%d", unit); + lunit = strlen(num); + if (strlen(name) + lunit >= sizeof(fullname) - 1) + panic("config_attach: device name too long"); + + strcpy(fullname, name); + strcat(fullname, num); + + while (strcmp(dev->dv_xname, fullname) != 0) { + if ((dev = dev->dv_list.tqe_next) == NULL) + return NULL; } + return dev; } diff --git a/sys/arch/mvme68k/mvme68k/disksubr.c b/sys/arch/mvme68k/mvme68k/disksubr.c index 8a738197dd4..66a0e2e7938 100644 --- a/sys/arch/mvme68k/mvme68k/disksubr.c +++ b/sys/arch/mvme68k/mvme68k/disksubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disksubr.c,v 1.6 1996/05/10 03:15:15 chuck Exp $ */ +/* $OpenBSD: disksubr.c,v 1.7 1996/05/29 16:37:17 chuck Exp $ */ /* * Copyright (c) 1995 Dale Rahn. @@ -32,10 +32,16 @@ #include <sys/param.h> #include <sys/buf.h> +#include <sys/device.h> #define DKTYPENAMES #include <sys/disklabel.h> #include <sys/disk.h> +#include <scsi/scsi_all.h> +#include <scsi/scsiconf.h> + +#include <machine/autoconf.h> + #define b_cylin b_resid #ifdef DEBUG @@ -57,6 +63,40 @@ dk_establish(dk, dev) struct disk *dk; struct device *dev; { + struct scsibus_softc *sbsc; + int target, lun; + + if (bootpart == -1) /* ignore flag from controller driver? */ + return; + + /* + * scsi: sd,cd + */ + + if (strncmp("sd", dev->dv_xname, 2) == 0 || + strncmp("cd", dev->dv_xname, 2) == 0) { + + sbsc = (struct scsibus_softc *)dev->dv_parent; + if (cputyp == CPU_147) { + target = bootctrllun % 8; /* XXX: 147 only */ + lun = bootdevlun; /* XXX: 147, untested */ + } else { + /* + * XXX: on the 167: + * ignore bootctrllun + */ + target = bootdevlun / 10; + lun = bootdevlun % 10; + } + + if (sbsc->sc_link[target][lun] != NULL && + sbsc->sc_link[target][lun]->device_softc == (void *)dev) { + bootdv = dev; + return; + } + } + + return; } /* diff --git a/sys/arch/mvme68k/mvme68k/locore.s b/sys/arch/mvme68k/mvme68k/locore.s index d1c7f67e0ef..1867f276493 100644 --- a/sys/arch/mvme68k/mvme68k/locore.s +++ b/sys/arch/mvme68k/mvme68k/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.7 1996/05/03 09:03:49 niklas Exp $ */ +/* $OpenBSD: locore.s,v 1.8 1996/05/29 16:37:17 chuck Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -110,21 +110,32 @@ tmpstk: start: movw #PSL_HIGHIPL,sr | no interrupts movl #0,a5 | RAM starts at 0 - movl sp@(4),d7 | get boothowto - movl sp@(8),d6 | get bootdev - movl sp@(12),a4 | get _esym - - RELOC(_smini,a0) - movl sp@(16),a0@ | get _smini - RELOC(_emini,a0) - movl sp@(20),a0@ | get _emini + movl sp@(4), d7 | get boothowto + movl sp@(8), d6 | get bootaddr + movl sp@(12),d5 | get bootctrllun + movl sp@(16),d4 | get bootdevlun + movl sp@(20),d3 | get bootpart + movl sp@(24),d2 | get esyms + /* note: d2-d7 in use */ RELOC(tmpstk, a0) movl a0,sp | give ourselves a temporary stack + RELOC(_edata, a0) | clear out BSS + movl #_end-4,d0 | (must be <= 256 kB) + subl #_edata,d0 + lsrl #2,d0 +1: clrl a0@+ + dbra d0,1b + movc vbr,d0 | save prom's trap #15 vector RELOC(_promvbr, a0) movl d0, a0@ + RELOC(_esym, a0) + movl d2,a0@ | store end of symbol table + /* note: d2 now free, d3-d7 still in use */ + RELOC(_lowram, a0) + movl a5,a0@ | store start of physical memory clrl sp@- trap #15 @@ -137,11 +148,6 @@ start: subql #1, d0 bne 1b - RELOC(_esym, a0) - movl a4,a0@ | store end of symbol table - RELOC(_lowram, a0) - movl a5,a0@ | store start of physical memory - clrl d0 RELOC(_brdid, a1) movw a1@(MVMEPROM_BRDID_MODEL), d0 @@ -358,22 +364,16 @@ Lstart1: movl d1,a0@ | and physmem /* configure kernel and proc0 VA space so we can get going */ .globl _Sysseg, _pmap_bootstrap, _avail_start -#ifdef MFS - /* preserve miniroot if it exists */ - RELOC(_emini,a0) | end of miniroot - movl a0@,d5 - jne Lstart2 -#endif #ifdef DDB RELOC(_esym,a0) | end of static kernel test/data/syms - movl a0@,d5 + movl a0@,d2 jne Lstart2 #endif - movl #_end,d5 | end of static kernel text/data + movl #_end,d2 | end of static kernel text/data Lstart2: - addl #NBPG-1,d5 - andl #PG_FRAME,d5 | round to a page - movl d5,a4 + addl #NBPG-1,d2 + andl #PG_FRAME,d2 | round to a page + movl d2,a4 addl a5,a4 | convert to PA #if 0 | XXX clear from end-of-kernel to 1M, as a workaround for an @@ -482,8 +482,12 @@ Lnocache0: movl #_vectab,d2 | set VBR movc d2,vbr movw #PSL_LOWIPL,sr | lower SPL - movl d7,_boothowto | save reboot flags - movl d6,_bootdev | and boot device + movl d3, _bootpart | save bootpart + movl d4, _bootdevlun | save bootdevlun + movl d5, _bootctrllun | save bootctrllun + movl d6, _bootaddr | save bootaddr + movl d7, _boothowto | save boothowto + /* d3-d7 now free */ /* * Create a fake exception frame so that cpu_fork() can copy it. |