summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2004-02-25 00:16:04 +0000
committerderaadt <deraadt@openbsd.org>2004-02-25 00:16:04 +0000
commit6483bf473d569c03ffbcaef275dca7f68546a80e (patch)
treeceb8b5a851f4f8b3d42e83104889d47806adbb3f
parentDo not check for end of line too early, as this will confuse the cursor (diff)
downloadwireguard-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.c511
-rw-r--r--sys/arch/amd64/amd64/dkcsum.c192
-rw-r--r--sys/arch/amd64/amd64/locore.S43
-rw-r--r--sys/arch/amd64/amd64/machdep.c135
-rw-r--r--sys/arch/amd64/conf/files.amd645
-rw-r--r--sys/arch/amd64/include/cpu.h5
-rw-r--r--sys/arch/amd64/stand/libsa/exec_i386.c6
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 */
}