diff options
author | 2004-02-25 00:16:04 +0000 | |
---|---|---|
committer | 2004-02-25 00:16:04 +0000 | |
commit | 6483bf473d569c03ffbcaef275dca7f68546a80e (patch) | |
tree | ceb8b5a851f4f8b3d42e83104889d47806adbb3f | |
parent | Do not check for end of line too early, as this will confuse the cursor (diff) | |
download | wireguard-openbsd-6483bf473d569c03ffbcaef275dca7f68546a80e.tar.xz wireguard-openbsd-6483bf473d569c03ffbcaef275dca7f68546a80e.zip |
dkcsum stuff for amd64, written by tom, who cannot commit it at the moment.
now the amd64 knows what drive it was booted from.
-rw-r--r-- | sys/arch/amd64/amd64/autoconf.c | 511 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/dkcsum.c | 192 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/locore.S | 43 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 135 | ||||
-rw-r--r-- | sys/arch/amd64/conf/files.amd64 | 5 | ||||
-rw-r--r-- | sys/arch/amd64/include/cpu.h | 5 | ||||
-rw-r--r-- | sys/arch/amd64/stand/libsa/exec_i386.c | 6 |
7 files changed, 588 insertions, 309 deletions
diff --git a/sys/arch/amd64/amd64/autoconf.c b/sys/arch/amd64/amd64/autoconf.c index 21a028d6f78..08792e43f10 100644 --- a/sys/arch/amd64/amd64/autoconf.c +++ b/sys/arch/amd64/amd64/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.4 2004/02/09 20:39:25 mickey Exp $ */ +/* $OpenBSD: autoconf.c,v 1.5 2004/02/25 00:16:04 deraadt Exp $ */ /* $NetBSD: autoconf.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -78,13 +78,12 @@ #endif void setroot(void); +void rootconf(void); void swapconf(void); void diskconf(void); int findblkmajor(struct device *); char *findblkname(int); -static struct device *getdisk(char *, int, int, dev_t *); struct device * parsedisk(char *, int, int, dev_t *); -static int getstr(char *, int); extern struct disklist *x86_64_alldisks; extern int x86_64_ndisks; @@ -99,7 +98,7 @@ extern int x86_64_ndisks; int cold = 1; /* if 1, still working on cold-start */ struct device *booted_device; int booted_partition; -dev_t bootdev; +dev_t bootdev = 0; #ifdef RAMDISK_HOOKS static struct device fakerdrootdev = { DV_DISK, {}, NULL, 0, "rd0", NULL }; @@ -143,221 +142,15 @@ cpu_configure(void) void diskconf(void) { - setroot(); + /* Checksum disks, same as /boot did, then fixup *dev vars */ + dkcsumattach(); + + rootconf(); swapconf(); dumpconf(); } void -setroot() -{ - struct swdevt *swp; - struct device *dv; - 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 - -#ifdef RAMDISK_HOOKS - bootdv = &fakerdrootdev; -#else - bootdv = booted_device; -#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 >= sizeof(buf)) - panic("setroot: device name too long"); - - 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 - ? booted_partition + 'a' : ' '); - printf(": "); - len = getstr(buf, sizeof(buf)); - if (len == 0 && bootdv != NULL) { - strlcpy(buf, bootdv->dv_xname, sizeof buf); - len = strlen(buf); - } - if (len > 0 && buf[len - 1] == '*') { - buf[--len] = '\0'; - dv = getdisk(buf, len, 1, &nrootdev); - if (dv != NULL) { - bootdv = dv; - nswapdev = nrootdev; - goto gotswap; - } - } - if (len == 4 && strncmp(buf, "exit", 4) == 0) - boot(RB_HALT); - dv = getdisk(buf, len, bp ? booted_partition : 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 == 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; - } - if (len == 4 && strncmp(buf, "exit", 4) == 0) - boot(RB_HALT); - 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 = booted_partition; - 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; - } -} - -void swapconf(void) { struct swdevt *swp; @@ -375,33 +168,6 @@ swapconf(void) } } -static struct device * -getdisk(str, len, defpart, devp) - char *str; - int len, defpart; - dev_t *devp; -{ - 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 - for (dv = alldevs.tqh_first; dv != NULL; - dv = dv->dv_list.tqe_next) { - 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; @@ -455,52 +221,6 @@ gotdisk: return (dv); } -static int -getstr(cp, size) - char *cp; - int size; -{ - char *lp; - int c; - 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; - } - } -} - /* XXX */ static struct nam2blk { char *name; @@ -535,3 +255,220 @@ findblkname(maj) return (nam2blk[i].name); return (NULL); } + +/* Code from here to handle "bsd swap generic" */ + +dev_t argdev = NODEV; + +/* + * 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. + */ +void +setroot() +{ + int majdev, mindev, unit, part, adaptor; + dev_t orootdev; +#ifdef DOSWAP + dev_t temp = 0; + struct swdevt *swp; +#endif + + if (boothowto & RB_DFLTROOT || + (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) + return; + majdev = B_TYPE(bootdev); + if (findblkname(majdev) == NULL) + return; + adaptor = B_ADAPTOR(bootdev); + part = B_PARTITION(bootdev); + unit = B_UNIT(bootdev); + mindev = (unit * MAXPARTITIONS) + part; + orootdev = rootdev; + rootdev = makedev(majdev, mindev); + /* + * If the original rootdev is the same as the one + * just calculated, don't need to adjust the swap configuration. + */ + printf("root on %s%d%c\n", findblkname(majdev), unit, part + 'a'); + if (rootdev == orootdev) + return; + +#ifdef DOSWAP + for (swp = swdevt; swp->sw_dev != NODEV; swp++) { + if (majdev == major(swp->sw_dev) && + mindev/MAXPARTITIONS == minor(swp->sw_dev)/MAXPARTITIONS) { + 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; +#endif +} + +#include "wd.h" +#if NWD > 0 +extern struct cfdriver wd_cd; +#endif +#include "sd.h" +#if NSD > 0 +extern struct cfdriver sd_cd; +#endif +#include "cd.h" +#if NCD > 0 +extern struct cfdriver cd_cd; +#endif +#include "mcd.h" +#if NMCD > 0 +extern struct cfdriver mcd_cd; +#endif +#include "fd.h" +#if NFD > 0 +extern struct cfdriver fd_cd; +#endif +#include "rd.h" +#if NRD > 0 +extern struct cfdriver rd_cd; +#endif +#include "raid.h" +#if NRAID > 0 +extern struct cfdriver raid_cd; +#endif + +struct genericconf { + struct cfdriver *gc_driver; + char *gc_name; + dev_t gc_major; +} genericconf[] = { +#if NWD > 0 + { &wd_cd, "wd", 0 }, +#endif +#if NFD > 0 + { &fd_cd, "fd", 2 }, +#endif +#if NSD > 0 + { &sd_cd, "sd", 4 }, +#endif +#if NCD > 0 + { &cd_cd, "cd", 6 }, +#endif +#if NMCD > 0 + { &mcd_cd, "mcd", 7 }, +#endif +#if NRD > 0 + { &rd_cd, "rd", 17 }, +#endif +#if NRAID > 0 + { &raid_cd, "raid", 19 }, +#endif + { 0 } +}; + +void +rootconf() +{ + register struct genericconf *gc; + int unit, part = 0; + char *num; + +#ifdef INSTALL + if (B_TYPE(bootdev) == 2) { + printf("\n\nInsert file system floppy...\n"); + if (!(boothowto & RB_ASKNAME)) + cngetc(); + } +#endif + + if (boothowto & RB_ASKNAME) { + char name[128]; +retry: + printf("root device? "); + cnpollc(TRUE); + getsn(name, sizeof name); + cnpollc(FALSE); + if (*name == '\0') + goto noask; + for (gc = genericconf; gc->gc_driver; gc++) + if (gc->gc_driver->cd_ndevs && + strncmp(gc->gc_name, name, + strlen(gc->gc_name)) == 0) + break; + if (gc->gc_driver) { + num = &name[strlen(gc->gc_name)]; + + unit = -2; + do { + if (unit != -2 && *num >= 'a' && + *num <= 'a'+MAXPARTITIONS-1 && + num[1] == '\0') { + part = *num++ - 'a'; + break; + } + if (unit == -2) + unit = 0; + unit = (unit * 10) + *num - '0'; + if (*num < '0' || *num > '9') + unit = -1; + } while (unit != -1 && *++num); + + if (unit < 0) { + printf("%s: not a unit number\n", + &name[strlen(gc->gc_name)]); + } else if (unit > gc->gc_driver->cd_ndevs || + gc->gc_driver->cd_devs[unit] == NULL) { + printf("%d: no such unit\n", unit); + } else { + printf("root on %s%d%c\n", gc->gc_name, unit, + 'a' + part); + rootdev = makedev(gc->gc_major, + unit * MAXPARTITIONS + part); + goto doswap; + } + } + printf("use one of: "); + for (gc = genericconf; gc->gc_driver; gc++) { + for (unit=0; unit < gc->gc_driver->cd_ndevs; unit++) { + if (gc->gc_driver->cd_devs[unit]) + printf("%s%d[a-%c] ", gc->gc_name, + unit, 'a'+MAXPARTITIONS-1); + } + } + printf("\n"); + goto retry; + } +noask: + if (mountroot == NULL) { + /* `swap generic' */ + setroot(); + } else { + /* preconfigured */ + int majdev, unit, part; + + majdev = major(rootdev); + if (findblkname(majdev) == NULL) + return; + part = minor(rootdev) % MAXPARTITIONS; + unit = minor(rootdev) / MAXPARTITIONS; + printf("root on %s%d%c\n", findblkname(majdev), unit, part + 'a'); + return; + } + +doswap: +#ifndef DISKLESS + mountroot = dk_mountroot; +#endif + swdevt[0].sw_dev = argdev = dumpdev = + makedev(major(rootdev), minor(rootdev) + 1); + /* swap size and dumplo set during autoconfigure */ +} diff --git a/sys/arch/amd64/amd64/dkcsum.c b/sys/arch/amd64/amd64/dkcsum.c new file mode 100644 index 00000000000..e1c4e285863 --- /dev/null +++ b/sys/arch/amd64/amd64/dkcsum.c @@ -0,0 +1,192 @@ +/* $OpenBSD: dkcsum.c,v 1.1 2004/02/25 00:16:04 deraadt Exp $ */ + +/*- + * Copyright (c) 1997 Niklas Hallqvist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * A checksumming pseudo device used to get unique labels of each disk + * that needs to be matched to BIOS disks. + */ + +#include <sys/param.h> +#include <sys/buf.h> +#include <sys/conf.h> +#include <sys/device.h> +#include <sys/disklabel.h> +#include <sys/fcntl.h> +#include <sys/proc.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/systm.h> + +#include <machine/biosvar.h> + +#include <lib/libz/zlib.h> + +#define b_cylin b_resid + +dev_t dev_rawpart(struct device *); /* XXX */ + +extern u_int32_t bios_cksumlen; +extern bios_diskinfo_t *bios_diskinfo; +extern dev_t bootdev; + +void +dkcsumattach(void) +{ + struct device *dv; + struct buf *bp; + struct bdevsw *bdsw; + dev_t dev; + int error; + u_int32_t csum; + bios_diskinfo_t *bdi, *hit; + + /* do nothing if no diskinfo passed from /boot, or a bad length */ + if (bios_diskinfo == NULL || bios_cksumlen * DEV_BSIZE > MAXBSIZE) + return; + + /* + * XXX Whatif DEV_BSIZE is changed to something else than the BIOS + * blocksize? Today, /boot doesn't cover that case so neither need + * I care here. + */ + bp = geteblk(bios_cksumlen * DEV_BSIZE); /* XXX error check? */ + + for (dv = alldevs.tqh_first; dv; dv = dv->dv_list.tqe_next) { + + if (dv->dv_class != DV_DISK) + continue; + bp->b_dev = dev = dev_rawpart(dv); + if (dev == NODEV) + continue; + bdsw = &bdevsw[major(dev)]; + + /* + * This open operation guarantees a proper initialization + * of the device, for future strategy calls. + */ + error = (*bdsw->d_open)(dev, FREAD, S_IFCHR, curproc); + if (error) { + /* XXX What to do here? */ + if (error != EIO) + printf("dkcsum: open of %s failed (%d)\n", + dv->dv_xname, error); + continue; + } + + /* Read blocks to cksum. XXX maybe a d_read should be used. */ + bp->b_blkno = 0; + bp->b_bcount = bios_cksumlen * DEV_BSIZE; + bp->b_flags = B_BUSY | B_READ; + bp->b_cylin = 0; + (*bdsw->d_strategy)(bp); + if (biowait(bp)) { + /* XXX What to do here? */ + printf("dkcsum: read of %s failed (%d)\n", + dv->dv_xname, error); + error = (*bdsw->d_close)(dev, 0, S_IFCHR, curproc); + if (error) + printf("dkcsum: close of %s failed (%d)\n", + dv->dv_xname, error); + continue; + } + error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc); + if (error) { + /* XXX What to do here? */ + printf("dkcsum: close of %s failed (%d)\n", + dv->dv_xname, error); + continue; + } + + csum = adler32(0, bp->b_data, bios_cksumlen * DEV_BSIZE); +#ifdef DEBUG + printf("dkcsum: checksum of %s is %x\n", dv->dv_xname, csum); +#endif + + /* Find the BIOS device */ + hit = 0; + for (bdi = bios_diskinfo; bdi->bios_number != -1; bdi++) { + /* Skip non-harddrives */ + if (!(bdi->bios_number & 0x80)) + continue; +#ifdef DEBUG + printf("dkcsum: " + "attempting to match with BIOS drive %x csum %x\n", + bdi->bios_number, bdi->checksum); +#endif + if (bdi->checksum == csum) { + if (!hit && !(bdi->flags & BDI_PICKED)) + hit = bdi; + else { + /* XXX add other heuristics here. */ + printf("dkcsum: warning: " + "dup BSD->BIOS disk mapping\n"); + } + } + } + + /* + * If we have no hit, that's OK, we can see a lot more devices + * than the BIOS can, so this case is pretty normal. + */ + if (hit) { +#ifdef DIAGNOSTIC + printf("dkcsum: %s matched BIOS disk %x\n", + dv->dv_xname, hit->bios_number); +#endif + } else { +#ifdef DIAGNOSTIC + printf("dkcsum: %s had no matching BIOS disk\n", + dv->dv_xname); +#endif + continue; + } + + /* Fixup bootdev if units match. This means that all of + * hd*, sd*, wd*, will be interpreted the same. Not 100% + * backwards compatible, but sd* and wd* should be phased- + * out in the bootblocks. + */ + if (B_UNIT(bootdev) == (hit->bios_number & 0x7F)) { + int type, ctrl, adap, part, unit; + + /* Translate to MAKEBOOTDEV() style */ + type = major(bp->b_dev); + adap = B_ADAPTOR(bootdev); + ctrl = B_CONTROLLER(bootdev); + unit = DISKUNIT(bp->b_dev); + part = B_PARTITION(bootdev); + + bootdev = MAKEBOOTDEV(type, ctrl, adap, unit, part); + } + + /* This will overwrite /boot's guess, just so you remember */ + hit->bsd_dev = MAKEBOOTDEV(major(bp->b_dev), 0, 0, + DISKUNIT(bp->b_dev), RAW_PART); + hit->flags |= BDI_PICKED; + } + bp->b_flags |= B_INVAL; + brelse(bp); +} diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S index ed2ad4bf6cd..e7aa2ffb9fe 100644 --- a/sys/arch/amd64/amd64/locore.S +++ b/sys/arch/amd64/amd64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.8 2004/02/23 09:12:59 mickey Exp $ */ +/* $OpenBSD: locore.S,v 1.9 2004/02/25 00:16:04 deraadt Exp $ */ /* $NetBSD: locore.S,v 1.2 2003/04/26 19:34:45 fvdl Exp $ */ /* @@ -143,12 +143,12 @@ #include <machine/asm.h> #if defined(MULTIPROCESSOR) - + #define SET_CURPROC(proc,cpu) \ movq CPUVAR(SELF),cpu ; \ movq proc,CPUVAR(CURPROC) ; \ movq cpu,P_CPU(proc) - + #else #define SET_CURPROC(proc,tcpu) movq proc,CPUVAR(CURPROC) @@ -158,7 +158,7 @@ #define GET_CURPCB(reg) movq CPUVAR(CURPCB),reg #define SET_CURPCB(reg) movq reg,CPUVAR(CURPCB) - + /* XXX temporary kluge; these should not be here */ /* Get definitions for IOM_BEGIN, IOM_END, and IOM_SIZE */ @@ -189,10 +189,10 @@ _C_LABEL(lapic_isr): .globl _C_LABEL(cpu_id),_C_LABEL(cpu_vendor), _C_LABEL(cpu_brand_id) .globl _C_LABEL(cpuid_level),_C_LABEL(cpu_feature) .globl _C_LABEL(esym),_C_LABEL(boothowto),_C_LABEL(bootdev) - .globl _C_LABEL(bootinfo),_C_LABEL(atdevbase) + .globl _C_LABEL(bootinfo), _C_LABEL(bootinfo_size), _C_LABEL(atdevbase) .globl _C_LABEL(proc0paddr),_C_LABEL(PTDpaddr) .globl _C_LABEL(biosbasemem),_C_LABEL(biosextmem) - .globl _C_LABEL(bootapiver), _C_LABEL(bootargc), _C_LABEL(bootargv) + .globl _C_LABEL(bootapiver) .globl _C_LABEL(gdtstore) _C_LABEL(cpu): .long 0 # are we 386, 386sx, or 486, # or Pentium, or.. @@ -207,8 +207,6 @@ _C_LABEL(cpu_brand_id): .long 0 # brand ID from 'cpuid' instruction _C_LABEL(esym): .quad 0 # ptr to end of syms _C_LABEL(atdevbase): .quad 0 # location of start of iomem in virtual _C_LABEL(bootapiver): .long 0 # /boot API version -_C_LABEL(bootargc): .long 0 # /boot argc -_C_LABEL(bootargv): .quad 0 # /boot argv _C_LABEL(proc0paddr): .quad 0 _C_LABEL(PTDpaddr): .quad 0 # paddr of PTD, for libkvm #ifndef REALBASEMEM @@ -266,7 +264,6 @@ start: movw $0x1234,0x472 # warm boot /* * Load parameters from stack * (howto, bootdev, bootapiver, esym, extmem, cnvmem, ac, av) - * */ movl 4(%esp),%eax movl %eax, RELOC(boothowto) @@ -288,13 +285,27 @@ start: movw $0x1234,0x472 # warm boot movl 12(%esp), %eax movl %eax, RELOC(bootapiver) - movl 28(%esp), %eax - movl %eax, RELOC(bootargc) - movl 32(%esp), %eax - movl $RELOC(bootargv), %ebx - movl %eax, (%ebx) - xorl %eax, %eax - movl %eax, 4(%ebx) + + /* + * Copy the boot arguments to bootinfo[] in machdep.c. + * + * We are passed the size of bootinfo[] in bootinfo_size, and + * we report how much data /boot passed us back in the same variable. + * + * machdep.c can then take action if bootinfo_size >= bootinfo[] + * (which would meant that we may have been passed too much data). + */ + movl 28(%esp), %eax + movl %eax, %ecx + cmpl RELOC(bootinfo_size), %ecx /* Too much? */ + jnc bi_size_ok + movl RELOC(bootinfo_size), %ecx /* Only copy this much */ +bi_size_ok: + movl %eax, RELOC(bootinfo_size) /* Report full amount */ + + movl $RELOC(bootinfo), %edi /* Destination */ + movl 32(%esp), %esi /* Source */ + rep movsb /* Copy this many bytes */ /* First, reset the PSL. */ pushl $PSL_MBO diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 1f1d24be232..b516a715843 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.11 2004/02/24 20:26:24 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.12 2004/02/25 00:16:04 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -107,6 +107,7 @@ #endif #include <dev/cons.h> +#include <stand/boot/bootarg.h> #include <uvm/uvm_extern.h> #include <uvm/uvm_page.h> @@ -122,6 +123,7 @@ #include <machine/specialreg.h> #include <machine/fpu.h> #include <machine/mtrr.h> +#include <machine/biosvar.h> #include <machine/mpbiosvar.h> #include <machine/reg.h> @@ -205,6 +207,35 @@ void (*initclock_func)(void) = i8254_initclocks; struct mtrr_funcs *mtrr_funcs; /* + * Format of boot information passed to us by 32-bit /boot + */ +typedef struct _boot_args32 { + int ba_type; + int ba_size; + int ba_nextX; /* a ptr in 32-bit world, but not here */ + char ba_arg[1]; +} bootarg32_t; + +#define BOOTARGC_MAX NBPG /* one page */ + +/* locore copies the arguments from /boot to here for us */ +char bootinfo[BOOTARGC_MAX]; +int bootinfo_size = BOOTARGC_MAX; + +void getbootinfo(char *, int); + +/* Data passed to us by /boot, filled in by getbootinfo() */ +#if NAPM > 0 || defined(DEBUG) +bios_apminfo_t *apm; +#endif +#if NPCI > 0 +bios_pciinfo_t *bios_pciinfo; +#endif +bios_diskinfo_t *bios_diskinfo; +bios_memmap_t *bios_memmap; +u_int32_t bios_cksumlen; + +/* * Size of memory segments, before any memory is stolen. */ phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; @@ -1219,6 +1250,23 @@ init_x86_64(first_avail) #if 0 uvmexp.ncolors = 2; #endif + + /* + * Boot arguments are in a single page specified by /boot. + * + * We require the "new" vector form, as well as memory ranges + * to be given in bytes rather than KB. + * + * locore copies the data into bootinfo[] for us. + */ + if ((bootapiver & (BAPIV_VECTOR | BAPIV_BMEMMAP)) == + (BAPIV_VECTOR | BAPIV_BMEMMAP)) { + if (bootinfo_size >= sizeof(bootinfo)) + panic("boot args too big"); + + getbootinfo(bootinfo, bootinfo_size); + } else + panic("invalid /boot"); avail_start = PAGE_SIZE; /* BIOS leaves data in low memory */ /* and VM system doesn't work with phys 0 */ @@ -1763,6 +1811,91 @@ splassert_check(int wantipl, const char *func) } #endif +void +getbootinfo(char *bootinfo, int bootinfo_size) +{ + bootarg32_t *q; + +#undef BOOTINFO_DEBUG +#ifdef BOOTINFO_DEBUG + printf("bootargv:"); +#endif + + for (q = (bootarg32_t *)bootinfo; + (q->ba_type != BOOTARG_END) && + ((((char *)q) - bootinfo) < bootinfo_size); + q = (bootarg32_t *)(((char *)q) + q->ba_size)) { + + switch (q->ba_type) { + case BOOTARG_MEMMAP: + bios_memmap = (bios_memmap_t *)q->ba_arg; +#ifdef BOOTINFO_DEBUG + printf(" memmap %p", bios_memmap); +#endif + break; + case BOOTARG_DISKINFO: + bios_diskinfo = (bios_diskinfo_t *)q->ba_arg; +#ifdef BOOTINFO_DEBUG + printf(" diskinfo %p", bios_diskinfo); +#endif + break; +#if 0 +#if NAPM > 0 || defined(DEBUG) + case BOOTARG_APMINFO: +#ifdef BOOTINFO_DEBUG + printf(" apminfo %p", q->ba_arg); +#endif + apm = (bios_apminfo_t *)q->ba_arg; + break; +#endif +#endif + case BOOTARG_CKSUMLEN: + bios_cksumlen = *(u_int32_t *)q->ba_arg; +#ifdef BOOTINFO_DEBUG + printf(" cksumlen %d", bios_cksumlen); +#endif + break; +#if 0 +#if NPCI > 0 + case BOOTARG_PCIINFO: + bios_pciinfo = (bios_pciinfo_t *)q->ba_arg; +#ifdef BOOTINFO_DEBUG + printf(" pciinfo %p", bios_pciinfo); +#endif + break; +#endif +#endif + case BOOTARG_CONSDEV: + if (q->ba_size >= sizeof(bios_consdev_t)) + { + bios_consdev_t *cdp = + (bios_consdev_t*)q->ba_arg; +#include "com.h" +#if NCOM > 0 + extern int comdefaultrate; /* ic/com.c */ + comdefaultrate = cdp->conspeed; +#endif +#ifdef BOOTINFO_DEBUG + printf(" console 0x%x:%d", + cdp->consdev, cdp->conspeed); +#endif + cnset(cdp->consdev); + } + break; + + default: +#ifdef BOOTINFO_DEBUG + printf(" unsupported arg (%d) %p", q->ba_type, + q->ba_arg); +#endif + break; + } + } +#ifdef BOOTINFO_DEBUG + printf("\n"); +#endif +} + int check_context(const struct reg *regs, struct trapframe *tf) { diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index 608a9f4ac38..9dcd8d58e06 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.amd64,v 1.1 2004/01/28 01:39:39 mickey Exp $ +# $OpenBSD: files.amd64,v 1.2 2004/02/25 00:16:41 deraadt Exp $ maxpartitions 16 maxusers 2 16 128 @@ -30,6 +30,9 @@ file arch/amd64/amd64/consinit.c file dev/cons.c file dev/cninit.c +file arch/amd64/amd64/dkcsum.c +file lib/libz/adler32.c !ppp_deflate & !ipsec & !crypto + file arch/amd64/amd64/db_disasm.c ddb file arch/amd64/amd64/db_interface.c ddb file arch/amd64/amd64/db_memrw.c ddb diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index ae7be5f6479..219689caa93 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.3 2004/02/11 03:07:46 deraadt Exp $ */ +/* $OpenBSD: cpu.h,v 1.4 2004/02/25 00:16:41 deraadt Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -312,6 +312,9 @@ void cpu_init_msrs(struct cpu_info *); /* trap.c */ void child_return(void *); +/* dkcsum.c */ +void dkcsumattach(void); + /* consinit.c */ void kgdb_port_init(void); diff --git a/sys/arch/amd64/stand/libsa/exec_i386.c b/sys/arch/amd64/stand/libsa/exec_i386.c index d1f78ac3cae..c14b5b8c240 100644 --- a/sys/arch/amd64/stand/libsa/exec_i386.c +++ b/sys/arch/amd64/stand/libsa/exec_i386.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_i386.c,v 1.2 2004/02/23 01:19:52 tom Exp $ */ +/* $OpenBSD: exec_i386.c,v 1.3 2004/02/25 00:16:42 deraadt Exp $ */ /* * Copyright (c) 1997-1998 Michael Shalayeff @@ -37,7 +37,7 @@ #include "libsa.h" #include <lib/libsa/loadfile.h> -typedef void (*startfuncp)(int, int, int, int, int, int, int, int, int) +typedef void (*startfuncp)(int, int, int, int, int, int, int, int) __attribute__ ((noreturn)); void @@ -68,6 +68,6 @@ run_loadfile(u_long *marks, int howto) ((int *)entry)[0], ((int *)entry)[1], ((int *)entry)[2], ((int *)entry)[3]); /* stack and the gung is ok at this point, so, no need for asm setup */ (*(startfuncp)entry)(howto, bootdev, BOOTARG_APIVER, - marks[MARK_END], extmem, cnvmem, ac, (int)av, cd.consdev); + marks[MARK_END], extmem, cnvmem, ac, (int)av); /* not reached */ } |