summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1997-10-22 23:34:42 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1997-10-22 23:34:42 +0000
commit75ff2b524f49004c6afee07d65b8dfa530bf747d (patch)
treee13109ca012cc4313c16dbcbc5585a2cb1bed8b9 /sys/arch/i386
parent0acb196dd2eff01035465ba82dbfe4ee14f19107 (diff)
newer, better stuff; some parts by toby@
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/stand/installboot/installboot.c38
-rw-r--r--sys/arch/i386/stand/libsa/Makefile4
-rw-r--r--sys/arch/i386/stand/libsa/apmprobe.c42
-rw-r--r--sys/arch/i386/stand/libsa/biosdev.c408
-rw-r--r--sys/arch/i386/stand/libsa/biosdev.h10
-rw-r--r--sys/arch/i386/stand/libsa/cmd_i386.c10
-rw-r--r--sys/arch/i386/stand/libsa/diskprobe.c133
-rw-r--r--sys/arch/i386/stand/libsa/exec_i386.c14
-rw-r--r--sys/arch/i386/stand/libsa/libsa.h11
-rw-r--r--sys/arch/i386/stand/libsa/machdep.c3
-rw-r--r--sys/arch/i386/stand/libsa/memprobe.c6
11 files changed, 345 insertions, 334 deletions
diff --git a/sys/arch/i386/stand/installboot/installboot.c b/sys/arch/i386/stand/installboot/installboot.c
index 2724c51f58c..1425a9e8a48 100644
--- a/sys/arch/i386/stand/installboot/installboot.c
+++ b/sys/arch/i386/stand/installboot/installboot.c
@@ -1,7 +1,8 @@
-/* $OpenBSD: installboot.c,v 1.20 1997/10/15 15:54:52 weingart Exp $ */
+/* $OpenBSD: installboot.c,v 1.21 1997/10/22 23:34:41 mickey Exp $ */
/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
/*
+ * Copyright (c) 1997 Michael Shalayeff
* Copyright (c) 1994 Paul Kranenburg
* All rights reserved.
*
@@ -138,6 +139,11 @@ main(argc, argv)
proto = argv[optind + 1];
realdev = dev = argv[optind + 2];
+ /* Open and check raw disk device */
+ if ((devfd = opendev(dev, (nowrite? O_RDONLY:O_RDWR),
+ OPENDEV_PART, &realdev)) < 0)
+ err(1, "open: %s", realdev);
+
mib[0] = CTL_MACHDEP;
mib[1] = CPU_BIOS;
mib[2] = BIOS_DEV;
@@ -147,29 +153,25 @@ main(argc, argv)
sysctl(mib, 3, &biosdev, &size, NULL, 0) != -1) {
if (biosdev & 0x80) {
- u_int geo;
+ bios_diskinfo_t di;
- mib[2] = BIOS_GEOMETRY;
- size = sizeof(geo);
+ mib[2] = BIOS_DISKINFO;
+ mib[3] = 0xa0000004;
+ size = sizeof(di);
- if (sysctl(mib, 3, &geo, &size, NULL, 0) == -1)
+ if (sysctl(mib, 4, &di, &size, NULL, 0) == -1)
err(1, "sysctl");
if (nheads == -1)
- nheads = BIOSNHEADS(geo);
+ nheads = di.bios_heads;
if (nsectors == -1)
- nsectors = BIOSNSECTS(geo);
+ nsectors = di.bios_sectors;
}
}
if (nheads == -1 || nsectors == -1)
errx(1, "Unable to get BIOS geometry, must specify -h and -s");
- /* Open and check raw disk device */
- if ((devfd = opendev(dev, (nowrite? O_RDONLY:O_RDWR),
- OPENDEV_PART, &realdev)) < 0)
- err(1, "open: %s", realdev);
-
if (verbose) {
fprintf(stderr, "boot: %s\n", boot);
fprintf(stderr, "proto: %s\n", proto);
@@ -212,7 +214,8 @@ main(argc, argv)
/* Sync filesystems (to clean in-memory superblock?) */
sync(); sleep(1);
- if (dl.d_type != 0 && dl.d_type < DTYPE_FLOPPY) {
+ if (dl.d_type != 0 && dl.d_type != DTYPE_FLOPPY &&
+ dl.d_type != DTYPE_VND) {
if (lseek(devfd, (off_t)DOSBBSECTOR, SEEK_SET) < 0 ||
read(devfd, &mbr, sizeof(mbr)) < sizeof(mbr))
err(4, "can't read master boot record");
@@ -358,7 +361,7 @@ loadblocknums(boot, devfd, dl)
struct disklabel *dl;
{
int i, fd;
- struct stat statbuf;
+ struct stat statbuf, sb;
struct statfs statfsbuf;
struct partition *pl;
struct fs *fs;
@@ -402,6 +405,13 @@ loadblocknums(boot, devfd, dl)
if (fstat(fd, &statbuf) != 0)
err(1, "fstat: %s", boot);
+ if (fstat(devfd, &sb) != 0)
+ err(1, "fstat: %s", realdev);
+
+ printf("%x,%x\n", statbuf.st_dev/MAXPARTITIONS, major(sb.st_rdev));
+ if (statbuf.st_rdev / MAXPARTITIONS != sb.st_rdev / MAXPARTITIONS)
+ /* errx(1, "cross-device install") */;
+
pl = &dl->d_partitions[DISKPART(statbuf.st_dev)];
close(fd);
diff --git a/sys/arch/i386/stand/libsa/Makefile b/sys/arch/i386/stand/libsa/Makefile
index 843a4acf4ce..a3ee13f8b14 100644
--- a/sys/arch/i386/stand/libsa/Makefile
+++ b/sys/arch/i386/stand/libsa/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.28 1997/10/17 18:46:54 weingart Exp $
+# $OpenBSD: Makefile,v 1.29 1997/10/22 23:34:35 mickey Exp $
LIB= sa
@@ -23,7 +23,7 @@ SRCS+= alloc.c exit.c exec.c getfile.c gets.c globals.c strcmp.c strlen.c \
strncmp.c memcmp.c memcpy.c memset.c printf.c strerror.c strncpy.c
# math for cd9660
-SRCS+= divdi3.c qdivrem.c
+#SRCS+= divdi3.c qdivrem.c
# io routines
SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c fstat.c ioctl.c lseek.c \
diff --git a/sys/arch/i386/stand/libsa/apmprobe.c b/sys/arch/i386/stand/libsa/apmprobe.c
index 772fa478ef8..51389567fb7 100644
--- a/sys/arch/i386/stand/libsa/apmprobe.c
+++ b/sys/arch/i386/stand/libsa/apmprobe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apmprobe.c,v 1.1 1997/10/17 18:46:53 weingart Exp $ */
+/* $OpenBSD: apmprobe.c,v 1.2 1997/10/22 23:34:36 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -57,12 +57,11 @@
*/
#include "libsa.h"
+#include <stand/boot/bootarg.h>
#include <machine/apmvar.h>
#include <machine/biosvar.h>
#include "debug.h"
-extern struct BIOS_vars BIOS_vars;
-
static __inline u_int
apm_check()
{
@@ -99,7 +98,8 @@ apm_disconnect()
}
static __inline int
-apm_connect()
+apm_connect(ai)
+ bios_apminfo_t *ai;
{
register u_int16_t f;
__asm __volatile (DOINT(0x15) "\n\t"
@@ -108,19 +108,19 @@ apm_connect()
"movzwl %%ax, %%eax\n\tshll $4, %0\n\t"
"movzwl %%cx, %%ecx\n\tshll $4, %2\n\t"
"movzwl %%dx, %%edx\n\tshll $4, %3\n\t"
- : "=a" (BIOS_vars.bios_apm_code32_base),
+ : "=a" (ai->apm_code32_base),
"=b" (f),
- "=c" (BIOS_vars.bios_apm_code16_base),
- "=d" (BIOS_vars.bios_apm_data_base)
+ "=c" (ai->apm_code16_base),
+ "=d" (ai->apm_data_base)
: "0" (APM_PROT32_CONNECT), "1" (APM_DEV_APM_BIOS)
: "cc");
- BIOS_vars.bios_apm_entry = BIOS_regs.biosr_bx;
+ ai->apm_entry = BIOS_regs.biosr_bx;
#if 0
- BIOS_vars.bios_apm_code_len = BIOS_regs.biosr_si & 0xffff;
- BIOS_vars.bios_apm_data_len = BIOS_regs.biosr_di & 0xffff;
+ ai->apm_code_len = BIOS_regs.biosr_si & 0xffff;
+ ai->apm_data_len = BIOS_regs.biosr_di & 0xffff;
#else
- BIOS_vars.bios_apm_code_len = 0x10000;
- BIOS_vars.bios_apm_data_len = 0x10000;
+ ai->apm_code_len = 0x10000;
+ ai->apm_data_len = 0x10000;
#endif
return (f & 0xff)? f >> 8 : 0;
}
@@ -128,25 +128,25 @@ apm_connect()
void
apmprobe()
{
- if ((BIOS_vars.bios_apm_detail = apm_check())) {
+ bios_apminfo_t ai;
+
+ if ((ai.apm_detail = apm_check())) {
printf("apm0");
apm_disconnect();
- if (apm_connect() != 0)
+ if (apm_connect(&ai) != 0)
printf(": connect error\n");
#ifdef DEBUG
printf(": %x text=%x/%x[%x] data=%x[%x] @ %x",
- BIOS_vars.bios_apm_detail,
- BIOS_vars.bios_apm_code32_base,
- BIOS_vars.bios_apm_code16_base,
- BIOS_vars.bios_apm_code_len,
- BIOS_vars.bios_apm_data_base,
- BIOS_vars.bios_apm_data_len,
- BIOS_vars.bios_apm_entry);
+ ai.apm_detail, ai.apm_code32_base,
+ ai.apm_code16_base, ai.apm_code_len,
+ ai.apm_data_base, ai.apm_data_len,
+ ai.apm_entry);
#else
printf(" detected");
#endif
putchar('\n');
+ addbootarg(BOOTARG_APMINFO, sizeof(ai), &ai);
}
}
diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c
index dbb2f53bc49..24b91a8f119 100644
--- a/sys/arch/i386/stand/libsa/biosdev.c
+++ b/sys/arch/i386/stand/libsa/biosdev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: biosdev.c,v 1.38 1997/10/18 00:33:15 weingart Exp $ */
+/* $OpenBSD: biosdev.c,v 1.39 1997/10/22 23:34:36 mickey Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -41,58 +41,68 @@
#include "libsa.h"
#include "biosdev.h"
+static const char *biosdisk_err __P((u_int));
+static int biosdisk_errno __P((u_int));
+
extern int debug;
-extern bios_diskinfo_t bios_diskinfo[];
struct biosdisk {
bios_diskinfo_t *bios_info;
- int edd_flags;
+ dev_t bsddev;
struct disklabel disklabel;
};
+struct EDD_CB {
+ u_int8_t edd_len; /* size of packet */
+ u_int8_t edd_res; /* reserved */
+ u_int16_t edd_nblk; /* # of blocks to transfer */
+ u_int32_t edd_buf; /* address of buffer */
+ u_int64_t edd_daddr; /* starting block */
+};
+
/*
* return a word that represents the max number
* of sectors and heads for this device
*
*/
-u_int32_t
-biosdinfo(dev)
- int dev;
-{
- u_int f, rv;
- __asm __volatile (DOINT(0x13) "; setc %b0\n\t"
- /* form a word with ntrack/nhead/nsect packed */
- "shll $16, %1; movw %%cx, %w1"
- /* "movb %%cl, %b1; andb $0x3f, %b1" */
- : "=a" (f), "=d" (rv)
- : "0" (0x800), "1" (dev) : "%ecx", "cc");
- return (f & 0xff)? 0 : rv;
-}
-
-/*
- * Probe if given bios disk exists.
- *
- * NOTE: This seems to hang on certain machines. Use biosdinfo()
- * first, and verify with biosdprobe() IFF biosdinfo() succeeds
- * first.
- *
- * XXX - biosdinfo() and biosdprobe() should be integrated into 1 fcn.
- */
-u_int32_t
-biosdprobe(dev)
+int
+bios_getinfo(dev, pdi)
int dev;
+ bios_diskinfo_t *pdi;
{
- u_int32_t val = 0;
+ u_int rv, bm, sgn;
+ __asm __volatile (DOINT(0x13) "\n\t"
+ "setc %b0; movzbl %h1, %1\n\t"
+ "movzbl %%cl, %3; andb $0x3f, %b3\n\t"
+ "xchgb %%cl, %%ch; rorb $2, %%ch"
+ : "=a" (rv), "=d" (pdi->bios_heads),
+ "=c" (pdi->bios_cylinders),
+ "=b" (pdi->bios_sectors)
+ : "0" (0x0800), "1" (dev) : "cc");
+
+ pdi->bios_number = dev;
+ pdi->bios_heads++; /* make it number of heads */
+
+ if (rv & 0xff)
+ return (rv & 0xff) >> 8;
+
+ /* EDD support check */
+ __asm __volatile(DOINT(0x13) "; setc %b0"
+ : "=a" (rv), "=c" (bm), "=b" (sgn)
+ : "0" (0x4400), "2" (0x55aa) : "%edx", "cc");
+ if (!(rv & 0xff) && (sgn & 0xffff) == 0xaa55)
+ pdi->bios_edd = bm & 0xffff;
+ else
+ pdi->bios_edd = -1;
- __asm __volatile (
- DOINT(0x13) "\n\t"
- "setc %b0 \n\t"
- : "=a" (val)
- : "0" (0x1500),
- "d" (dev)
- : "%ecx", "%edx", "cc");
+ /*
+ * NOTE: This seems to hang on certain machines. Use function #8
+ * first, and verify with #21 IFF #8 succeeds first.
+ */
+ __asm __volatile (DOINT(0x13) "; setc %b0"
+ : "=a" (rv) : "0" (0x1500), "d" (dev) : "%ecx", "cc");
- return(val & 0xffff);
+ return rv & 0xffff;
}
/*
@@ -111,7 +121,7 @@ biosdreset(dev)
/*
* Read/Write a block from given place using the BIOS.
*/
-int
+static __inline int
biosd_rw(rw, dev, cyl, head, sect, nsect, buf)
int rw, dev, cyl, head;
int sect, nsect;
@@ -138,20 +148,6 @@ biosd_rw(rw, dev, cyl, head, sect, nsect, buf)
return (rv & 0xff)? rv >> 8 : 0;
}
-/*
- * check the features supported by the bios for the drive
- */
-static __inline int
-EDDcheck (dev)
- int dev;
-{
- int rv, bm, sgn;
- __asm __volatile(DOINT(0x13) "; setc %b0"
- : "=a" (rv), "=c" (bm), "=b" (sgn)
- : "0" (0x4400), "2" (0x55aa) : "%edx", "cc");
- return ((rv & 0xff) && (sgn & 0xffff) == 0xaa55)? bm & 0xffff : -1;
-}
-
int
EDD_rw(rw, dev, daddr, nblk, buf)
int rw, dev;
@@ -173,17 +169,125 @@ EDD_rw(rw, dev, daddr, nblk, buf)
return (rv & 0xff)? rv >> 8 : 0;
}
-char *
+/*
+ * Read given sector, handling retry/errors/etc.
+ */
+int
+biosd_io(rw, dev, cyl, head, sect, nsect, buf)
+ int rw, dev, cyl, head;
+ int sect, nsect;
+ void* buf;
+{
+ int j, error;
+ void *bb;
+
+#ifdef BIOS_DEBUG
+ if (debug)
+ printf("biosd_io(%s,%x,%u,%u,%u,%u,%p)\n",
+ (rw==F_READ?"reading":"writing"), dev,
+ cyl, head, sect, nsect, buf);
+#endif
+
+ /* use a bounce buffer to not cross 64k DMA boundary */
+ if ((((u_int32_t)buf) & ~0xffff) !=
+ (((u_int32_t)buf + nsect * DEV_BSIZE) & ~0xffff)) {
+ /*
+ * XXX we believe that all the io is buffered
+ * by fs routines, so no big reads anyway
+ */
+ bb = alloca(nsect * DEV_BSIZE);
+ if (rw != F_READ)
+ bcopy (buf, bb, nsect * DEV_BSIZE);
+ } else
+ bb = buf;
+#ifdef BIOS_DEBUG
+ if (debug)
+ printf(" (%d,%d,%d,%d)@%p", cyl, head, sect, nsect, bb);
+#endif
+ /* Try to do operation up to 5 times */
+ for (error = 1, j = 5; j-- && error;)
+ switch (error = biosd_rw(rw, dev, cyl, head, sect, nsect, bb)) {
+ case 0x00: /* No errors */
+ case 0x11: /* ECC corrected */
+ error = 0;
+ break;
+
+ default: /* All other errors */
+ printf("\nBIOS error 0x%x (%s)\n", error, biosdisk_err(error));
+ biosdreset(dev);
+ break;
+ }
+
+ if (bb != buf && rw == F_READ)
+ bcopy (bb, buf, nsect * DEV_BSIZE);
+
+#ifdef BIOS_DEBUG
+ if (debug) {
+ if (error != 0)
+ printf("=0x%x(%s)", error, biosdisk_err(error));
+ putchar('\n');
+ }
+#endif
+
+ return biosdisk_errno(error);
+}
+
+/*
+ * Try to read the bsd label on the given BIOS device
+ */
+const char *
bios_getdisklabel(dev, label)
int dev;
struct disklabel *label;
{
- char *st, buf[DEV_BSIZE];
+ daddr_t off = LABELSECTOR;
+ bios_diskinfo_t *bd;
+ char *st, *buf;
struct dos_mbr mbr;
- int error;
+ int cyl, head, sect;
+ int error, i;
+
+ /* Read MBR */
+ bd = bios_dklookup(dev);
+ btochs(DOSBBSECTOR, cyl, head, sect, bd->bios_heads, bd->bios_sectors);
+
+ error = biosd_io(F_READ, dev, cyl, head, sect, 1, &mbr);
+ if(error)
+ return(biosdisk_err(error));
- error = biosd_rw(F_READ, dev, 0, 0, 1, 1, &mbr);
- st = getdisklabel(buf, label);
+ /* check mbr signature */
+ if (mbr.dmbr_sign != DOSMBR_SIGNATURE)
+ return("bad MBR signature\n");
+
+ /* Search for OpenBSD partition */
+ for (off = 0, i = 0; off == 0 && i < NDOSPART; i++)
+ if (mbr.dmbr_parts[i].dp_typ == DOSPTYP_OPENBSD)
+ off = mbr.dmbr_parts[i].dp_start + LABELSECTOR;
+
+ /* just in case */
+ if (off == 0)
+ for (off = 0, i = 0; off == 0 && i < NDOSPART; i++)
+ if (mbr.dmbr_parts[i].dp_typ == DOSPTYP_NETBSD)
+ off = mbr.dmbr_parts[i].dp_start + LABELSECTOR;
+
+ if (off == 0)
+ return("no BSD partition\n");
+
+ /* Load BSD disklabel */
+ buf = alloca(DEV_BSIZE);
+#ifdef BIOS_DEBUG
+ if (debug)
+ printf("loading disklabel @ %u\n", off);
+#endif
+ /* read disklabel */
+ btochs(off, cyl, head, sect, bd->bios_heads, bd->bios_sectors);
+ error = biosd_io(F_READ, dev, cyl, head, sect, 1, buf);
+
+ if(error)
+ return("failed to read disklabel");
+
+ /* Fill in disklabel */
+ st = getdisklabel(buf, label);
return(st);
}
@@ -192,11 +296,10 @@ biosopen(struct open_file *f, ...)
{
va_list ap;
register char *cp, **file;
+ const char *st;
dev_t maj, unit, part;
register struct biosdisk *bd;
- daddr_t off = LABELSECTOR;
- u_int8_t *buf;
- int i, biosdev;
+ int biosdev;
va_start(ap, f);
cp = *(file = va_arg(ap, char **));
@@ -248,141 +351,51 @@ biosopen(struct open_file *f, ...)
else
f->f_flags |= F_RAW;
- bd = alloc(sizeof(*bd));
- bzero(bd, sizeof(bd));
-
+ biosdev = unit;
switch (maj) {
case 0: /* wd */
case 4: /* sd */
case 17: /* hd */
- biosdev = unit | 0x80;
- if (maj == 17)
- unit = 0;
- maj = 17;
+ biosdev |= 0x80;
break;
case 2: /* fd */
- biosdev = unit;
break;
- case 7: /* mcd */
- case 15: /* scd */
- case 6: /* cd */
- case 18: /* acd */
-#ifdef BIOS_DEBUG
- printf("Booting from CD is not yet supported\n");
-#endif
- case 3: /* wt */
-#ifdef BIOS_DEBUG
- if (maj == 3)
- printf("Booting from Wangtek is not supported\n");
-#endif
default:
- free(bd, 0);
return ENXIO;
}
- bd->bios_info = diskfind(biosdev);
- if (!bd->bios_info)
- return ENXIO;
+ bd = alloc(sizeof(*bd));
+ bzero(bd, sizeof(bd));
- /* Get EDD stuff */
- bd->edd_flags = EDDcheck(biosdev);
+ if (!(bd->bios_info = bios_dklookup(biosdev)))
+ return ENXIO;
- /* maj is fixed later w/ disklabel read */
- bootdev = MAKEBOOTDEV(maj, 0, 0, unit, part);
+ bootdev = bd->bios_info->bsd_dev;
+ bd->bsddev = bootdev = MAKEBOOTDEV(B_TYPE(bootdev), B_ADAPTOR(bootdev),
+ B_CONTROLLER(bootdev), unit, part);
#ifdef BIOS_DEBUG
if (debug) {
printf("BIOS geometry: heads=%u, s/t=%u; EDD=%d\n",
- BIOSNHEADS(bd->dinfo), BIOSNSECTS(bd->dinfo),
- bd->edd_flags);
+ bd->bios_info->bios_heads, bd->bios_info->bios_sectors,
+ bd->bios_info->bios_edd);
}
#endif
- if (maj == 17) { /* hd, wd, sd */
- struct dos_mbr mbr;
-
- if ((errno = biosstrategy(bd, F_READ, DOSBBSECTOR,
- DEV_BSIZE, &mbr, NULL)) != 0) {
-#ifdef BIOS_DEBUG
- if (debug)
- printf("cannot read MBR\n");
-#endif
- free(bd, 0);
- return errno;
- }
-
- /* check mbr signature */
- if (mbr.dmbr_sign != DOSMBR_SIGNATURE) {
-#ifdef BIOS_DEBUG
- if (debug)
- printf("bad MBR signature\n");
-#endif
- free(bd, 0);
- return ERDLAB;
- }
-
- for (off = 0, i = 0; off == 0 && i < NDOSPART; i++)
- if (mbr.dmbr_parts[i].dp_typ == DOSPTYP_OPENBSD)
- off = mbr.dmbr_parts[i].dp_start + LABELSECTOR;
-
- /* just in case */
- if (off == 0)
- for (off = 0, i = 0; off == 0 && i < NDOSPART; i++)
- if (mbr.dmbr_parts[i].dp_typ == DOSPTYP_NETBSD)
- off = mbr.dmbr_parts[i].dp_start +
- LABELSECTOR;
-
- if (off == 0) {
-#ifdef BIOS_DEBUG
- if (debug)
- printf("no BSD partition\n");
-#endif
- free(bd, 0);
- return ERDLAB;
- }
- }
-
- buf = alloca(DEV_BSIZE);
-#ifdef BIOS_DEBUG
- if (debug)
- printf("loading disklabel @ %u\n", off);
-#endif
- /* read disklabel */
- if ((errno = biosstrategy(bd, F_READ, off,
- DEV_BSIZE, buf, NULL)) != 0) {
-#ifdef BIOS_DEBUG
- if (debug)
- printf("failed to read disklabel\n");
-#endif
- free(bd, 0);
- return ERDLAB;
- }
-
- if ((cp = getdisklabel(buf, &bd->disklabel)) != NULL) {
-#ifdef BIOS_DEBUG
+ /* Get disklabel from drive */
+ if ((st = bios_getdisklabel(biosdev, &bd->disklabel)) != NULL) {
if (debug)
- printf("%s\n", cp);
-#endif
- free(bd, 0);
- return EUNLAB;
- }
+ printf("%s\n", st);
- if (maj == 17) { /* figure out what it's exactly */
- switch (bd->disklabel.d_type) {
- case DTYPE_SCSI: maj = 4; break;
- default: maj = 0; break;
- }
+ return ERDLAB;
}
- /* and again w/ fixed maj */
- bootdev = MAKEBOOTDEV(maj, 0, 0, unit, part);
-
f->f_devdata = bd;
return 0;
}
-static __inline const char *
+static const char *
biosdisk_err(error)
u_int error;
{
@@ -429,7 +442,7 @@ biosdisk_err(error)
return ++p;
}
-static __inline int
+static int
biosdisk_errno(error)
u_int error;
{
@@ -471,75 +484,36 @@ biosstrategy(devdata, rw, blk, size, buf, rsize)
size_t *rsize;
{
u_int8_t error = 0;
- register struct biosdisk *bd = (struct biosdisk *)devdata;
- register size_t i, nsect, n, spt;
+ struct biosdisk *bd = (struct biosdisk *)devdata;
+ register size_t i, nsect, n, spt, tpc;
+ int dev;
nsect = (size + DEV_BSIZE-1) / DEV_BSIZE;
-#if 0
if (rsize != NULL)
blk += bd->disklabel.
d_partitions[B_PARTITION(bd->bsddev)].p_offset;
-#endif
-
-#ifdef BIOS_DEBUG
- if (debug)
- printf("biosstrategy(%p,%s,%u,%u,%p,%p), dev=%x:%x\n"
- "biosdread:",
- bd, (rw==F_READ?"reading":"writing"), blk, size,
- buf, rsize, bd->biosdev, bd->bsddev);
-#endif
/* handle floppies w/ different from drive geometry */
- if (!(bd->bios_info->bios_number & 0x80) && bd->disklabel.d_nsectors != 0)
+ if (!(bd->bios_info->bios_number & 0x80) &&
+ bd->disklabel.d_nsectors != 0)
spt = bd->disklabel.d_nsectors;
else
spt = bd->bios_info->bios_sectors;
+ tpc = bd->bios_info->bios_heads;
+ dev = bd->bios_info->bios_number;
+
for (i = 0; error == 0 && i < nsect;
i += n, blk += n, buf += n * DEV_BSIZE) {
- register int cyl, hd, sect, j;
- void *bb;
+ register int cyl, hd, sect;
- btochs(blk, cyl, hd, sect, (bd->bios_info->bios_heads), spt);
+ btochs(blk, cyl, hd, sect, tpc, spt);
if ((sect + (nsect - i)) >= spt)
n = spt - sect;
else
n = nsect - i;
- /* use a bounce buffer to not cross 64k DMA boundary */
- if ((((u_int32_t)buf) & ~0xffff) !=
- (((u_int32_t)buf + n * DEV_BSIZE) & ~0xffff)) {
- /*
- * XXX we believe that all the io is buffered
- * by fs routines, so no big reads anyway
- */
- bb = alloca(n * DEV_BSIZE);
- if (rw != F_READ)
- bcopy (buf, bb, n * DEV_BSIZE);
- } else
- bb = buf;
-#ifdef BIOS_DEBUG
- if (debug)
- printf(" (%d,%d,%d,%d)@%p", cyl, hd, sect, n, bb);
-#endif
- /* Try to do operation up to 5 times */
- for (error = 1, j = 5; j-- && error;)
- switch (error = biosd_rw(rw, bd->bios_info->bios_number,
- cyl, hd, sect, n, bb)) {
- case 0x00: /* No errors */
- case 0x11: /* ECC corrected */
- error = 0;
- break;
-
- default: /* All other errors */
- printf("\nBIOS error 0x%x (%s)\n", error,
- biosdisk_err(error));
- biosdreset(bd->bios_info->bios_number);
- break;
- }
-
- if (bb != buf && rw == F_READ)
- bcopy (bb, buf, n * DEV_BSIZE);
+ error = biosd_io(rw, dev, cyl, hd, sect, n, buf);
}
#ifdef BIOS_DEBUG
diff --git a/sys/arch/i386/stand/libsa/biosdev.h b/sys/arch/i386/stand/libsa/biosdev.h
index b3aff102afa..b2b828316f3 100644
--- a/sys/arch/i386/stand/libsa/biosdev.h
+++ b/sys/arch/i386/stand/libsa/biosdev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: biosdev.h,v 1.22 1997/10/17 15:03:22 weingart Exp $ */
+/* $OpenBSD: biosdev.h,v 1.23 1997/10/22 23:34:37 mickey Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -41,10 +41,12 @@ int biosstrategy __P((void *, int, daddr_t, size_t, void *, size_t *));
int biosopen __P((struct open_file *, ...));
int biosclose __P((struct open_file *));
int biosioctl __P((struct open_file *, u_long, void *));
-u_int32_t biosdinfo __P((int));
-u_int32_t biosdprobe __P((int));
-int biosd_rw __P((int, int, int, int, int, int, void*));
+int bios_getinfo __P((int, bios_diskinfo_t *));
+int biosd_io __P((int, int, int, int, int, int, void*));
+const char * bios_getdisklabel __P((int, struct disklabel *));
+/* diskprobe.c */
+bios_diskinfo_t *bios_dklookup __P((int));
/* bioscons.c */
void pc_probe __P((struct consdev *));
diff --git a/sys/arch/i386/stand/libsa/cmd_i386.c b/sys/arch/i386/stand/libsa/cmd_i386.c
index 241a052b8c2..823ab7a858c 100644
--- a/sys/arch/i386/stand/libsa/cmd_i386.c
+++ b/sys/arch/i386/stand/libsa/cmd_i386.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd_i386.c,v 1.14 1997/10/21 02:42:31 mickey Exp $ */
+/* $OpenBSD: cmd_i386.c,v 1.15 1997/10/22 23:34:37 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff, Tobias Weingartner
@@ -48,12 +48,6 @@ static int Xmemory __P((void));
/* From gidt.S */
int bootbuf __P((int, int));
-/* From probedisk.c */
-extern bios_diskinfo_t bios_diskinfo[];
-
-/* From probemem.c */
-extern bios_memmap_t *memory_map;
-
const struct cmd_table cmd_machine[] = {
{ "diskinfo", CMDT_CMD, Xdiskinfo },
{ "regs", CMDT_CMD, Xregs },
@@ -120,7 +114,7 @@ Xboot()
printf("[%x,%d]\n", dev, part);
/* Read boot sector from device */
- st = biosd_rw(F_READ, dev, 0, 0, 1, 1, buf);
+ st = biosd_io(F_READ, dev, 0, 0, 1, 1, buf);
if(st) goto bad;
/* Frob boot flag in buffer from HD */
diff --git a/sys/arch/i386/stand/libsa/diskprobe.c b/sys/arch/i386/stand/libsa/diskprobe.c
index d59ad4a5ed7..66d7f6fd83d 100644
--- a/sys/arch/i386/stand/libsa/diskprobe.c
+++ b/sys/arch/i386/stand/libsa/diskprobe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: diskprobe.c,v 1.2 1997/10/18 00:33:15 weingart Exp $ */
+/* $OpenBSD: diskprobe.c,v 1.3 1997/10/22 23:34:38 mickey Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -34,91 +34,116 @@
#include <sys/param.h>
#include <sys/reboot.h>
+#include <sys/disklabel.h>
+#include <stand/boot/bootarg.h>
#include <machine/biosvar.h>
#include "biosdev.h"
#include "libsa.h"
-
-extern struct BIOS_vars BIOS_vars;
-
/* These get passed to kernel */
bios_diskinfo_t bios_diskinfo[16];
-
-/* Find info on given BIOS disk */
-bios_diskinfo_t *
-diskfind(dev)
- int dev;
+#if notyet
+/* Checksum given buffer */
+static u_int32_t
+bufsum(buf, len)
+ void *buf;
+ int len;
{
- int i;
+ u_int32_t sum = 0;
+ u_int8_t *p = buf;
- for(i = 0; bios_diskinfo[i].bios_number != -1; i++)
- if(bios_diskinfo[i].bios_number == dev)
- return(&bios_diskinfo[i]);
+ while(len--){
+ sum += p[len];
+ }
+ return(sum);
+}
- return(NULL);
+/* Checksum given drive until different */
+void
+disksum(pos)
+ int pos;
+{
+ u_int32_t sum;
+ int len, i;
}
+#endif
/* Probe for all BIOS disks */
void
diskprobe()
{
- int drive, i = 0;
+ u_int drive, i = 0, rv;
+ struct disklabel label;
+ u_int unit, type;
printf("Probing disks:");
/* Floppies */
- for(drive = 0; drive < 4; drive++){
- u_int32_t p = biosdinfo(drive);
-
- if(BIOSNSECTS(p) < 2) continue;
- if(p){
- u_int32_t t = biosdprobe(drive);
- if(t & 0x00FF) continue;
- if(!(t & 0xFF00)) continue;
+ for(drive = 0; drive < 4; drive++) {
+ rv = bios_getinfo(drive, &bios_diskinfo[i]);
- printf(" fd%d", drive);
+ if( (rv & 0x00FF)) continue;
+ if(!(rv & 0xFF00)) continue;
- /* Fill out best we can */
- bios_diskinfo[i].bsd_dev = MAKEBOOTDEV(2, 0, 0, 0, 0); /* fd? */
- bios_diskinfo[i].bios_number = drive;
- bios_diskinfo[i].bios_cylinders = BIOSNTRACKS(p);
- bios_diskinfo[i].bios_heads = BIOSNHEADS(p);
- bios_diskinfo[i].bios_sectors = BIOSNSECTS(p);
+ printf(" fd%u", drive);
- i++;
- }
+ /* Fill out best we can - (fd?) */
+ bios_diskinfo[i].bsd_dev = MAKEBOOTDEV(2, 0, 0, drive, 0);
+#if 0
+ disksum(&bios_diskinfo[i]);
+#endif
+ i++;
}
/* Hard disks */
- for(drive = 0x80; drive < 0x88; drive++){
- u_int32_t p = biosdinfo(drive);
-
- if(BIOSNSECTS(p) < 2) continue;
- if(p){
- u_int32_t t = biosdprobe(drive);
- if(t & 0x00FF) continue;
- if(!(t & 0xFF00)) continue;
-
- printf(" hd%d", drive - 128);
-
- /* Fill out best we can */
- bios_diskinfo[i].bsd_dev = -1; /* XXX - fill in */
- bios_diskinfo[i].bios_number = drive;
- bios_diskinfo[i].bios_cylinders = BIOSNTRACKS(p);
- bios_diskinfo[i].bios_heads = BIOSNHEADS(p);
- bios_diskinfo[i].bios_sectors = BIOSNSECTS(p);
-
- i++;
+ for(drive = 0x80; drive < 0x88; drive++) {
+ rv = bios_getinfo(drive, &bios_diskinfo[i]);
+
+ if( (rv & 0x00FF)) continue;
+ if(!(rv & 0xFF00)) continue;
+
+ unit = drive - 0x80;
+ printf(" hd%u%s", unit, (bios_diskinfo[i].bios_edd > 0?"+":""));
+
+ /* Try to find the label, to figure out device type */
+ if((bios_getdisklabel(drive, &label)) ) {
+ printf("*");
+ type = 0; /* XXX let it be IDE */
+ } else {
+ /* Best guess */
+ if (label.d_type == DTYPE_SCSI)
+ type = 4;
+ else
+ type = 0;
}
+
+ /* Fill out best we can */
+ bios_diskinfo[i].bsd_dev = MAKEBOOTDEV(type, 0, 0, unit, 0);
+#if 0
+ disksum(&bios_diskinfo[i]);
+#endif
+ i++;
}
/* End of list */
bios_diskinfo[i].bios_number = -1;
-
- /* XXX - This needs a better place! */
- BIOS_vars.boot_data = bios_diskinfo;
+ addbootarg(BOOTARG_DISKINFO,
+ (i + 1) * sizeof(bios_diskinfo[0]), bios_diskinfo);
printf("\n");
}
+/* Find info on given BIOS disk */
+bios_diskinfo_t *
+bios_dklookup(dev)
+ register int dev;
+{
+ register int i;
+
+ for(i = 0; bios_diskinfo[i].bios_number != -1; i++)
+ if(bios_diskinfo[i].bios_number == dev)
+ return(&bios_diskinfo[i]);
+
+ return(NULL);
+}
diff --git a/sys/arch/i386/stand/libsa/exec_i386.c b/sys/arch/i386/stand/libsa/exec_i386.c
index ccbac6da03f..5ea02d0acc2 100644
--- a/sys/arch/i386/stand/libsa/exec_i386.c
+++ b/sys/arch/i386/stand/libsa/exec_i386.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec_i386.c,v 1.17 1997/09/19 17:20:43 niklas Exp $ */
+/* $OpenBSD: exec_i386.c,v 1.18 1997/10/22 23:34:38 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -38,6 +38,7 @@
#include <sys/exec.h>
#include <sys/reboot.h>
#include <dev/cons.h>
+#include <stand/boot/bootarg.h>
#include <machine/biosvar.h>
#include "libsa.h"
@@ -51,6 +52,8 @@ machdep_start(startaddr, howto, loadaddr, ssym, esym)
char *startaddr, *loadaddr, *ssym, *esym;
int howto;
{
+ size_t argc;
+ void *argv = makebootargs(&argc);
#ifdef EXEC_DEBUG
struct exec *x;
@@ -61,17 +64,16 @@ machdep_start(startaddr, howto, loadaddr, ssym, esym)
x->a_midmag, x->a_text, x->a_data, x->a_bss, x->a_syms,
x->a_entry, x->a_trsize, x->a_drsize);
- printf("/bsd(%x,%x,%x,%x,%x,%x,%x)\n",
+ printf("/bsd(%x,%x,%x,%x,%x,%x,%d,%p)\n",
howto, bootdev, BOOT_APIVER, round_to_size(esym),
- extmem, cnvmem, (int)&BIOS_vars, sizeof(BIOS_vars));
+ extmem, cnvmem, argc, argv);
getchar();
#endif
(int)startaddr &= 0xffffff;
- printf("entry point at 0x%x\n", (int)startaddr);
+ printf("entry point at %p\n", startaddr);
/* stack and the gung is ok at this point, so, no need for asm setup */
(*(startfuncp)startaddr)(howto, bootdev, BOOT_APIVER,
- round_to_size(esym), extmem, cnvmem, (int)&BIOS_vars,
- sizeof (BIOS_vars));
+ round_to_size(esym), extmem, cnvmem, argc, (int)argv);
/* not reached */
}
diff --git a/sys/arch/i386/stand/libsa/libsa.h b/sys/arch/i386/stand/libsa/libsa.h
index 01b764dfc0b..dba1ac8ae9f 100644
--- a/sys/arch/i386/stand/libsa/libsa.h
+++ b/sys/arch/i386/stand/libsa/libsa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: libsa.h,v 1.20 1997/10/18 00:33:16 weingart Exp $ */
+/* $OpenBSD: libsa.h,v 1.21 1997/10/22 23:34:39 mickey Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -47,12 +47,15 @@ void *alloca __P((size_t));
void machdep __P((void));
void time_print __P((void));
-bios_diskinfo_t *diskfind __P((int));
-
-
extern const char bdevs[][4];
extern const int nbdevs;
extern int bootdev; /* XXX pass through the global to exec_i386 */
extern u_int cnvmem, extmem; /* XXX global pass memprobe()->machdep_start() */
+/* diskprobe.c */
+extern bios_diskinfo_t bios_diskinfo[];
+
+/* memprobe.c */
+extern bios_memmap_t *memory_map;
+
#define MACHINE_CMD cmd_machine /* we have i386 specific sommands */
diff --git a/sys/arch/i386/stand/libsa/machdep.c b/sys/arch/i386/stand/libsa/machdep.c
index 139f6063788..e4cdd9deca6 100644
--- a/sys/arch/i386/stand/libsa/machdep.c
+++ b/sys/arch/i386/stand/libsa/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.20 1997/10/18 05:13:17 mickey Exp $ */
+/* $OpenBSD: machdep.c,v 1.21 1997/10/22 23:34:39 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -38,7 +38,6 @@
#include "debug.h"
struct BIOS_regs BIOS_regs;
-struct BIOS_vars BIOS_vars;
int bootdev;
#if defined(DEBUG) && !defined(_TEST)
diff --git a/sys/arch/i386/stand/libsa/memprobe.c b/sys/arch/i386/stand/libsa/memprobe.c
index 01de42f56d6..3632484ecf8 100644
--- a/sys/arch/i386/stand/libsa/memprobe.c
+++ b/sys/arch/i386/stand/libsa/memprobe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: memprobe.c,v 1.22 1997/10/22 00:14:25 weingart Exp $ */
+/* $OpenBSD: memprobe.c,v 1.23 1997/10/22 23:34:40 mickey Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner, Michael Shalayeff
@@ -276,8 +276,10 @@ memprobe()
printf("\n");
#endif
pm->type = BIOS_MAP_END;
+ /* Register in global var */
+ addbootarg(BOOTARG_MEMMAP, (pm - bm + 1) * sizeof(*bm), bm);
+ memory_map = bm; /* XXX for 'machine mem' command only */
printf("mem0:");
- memory_map = bm;
/* Get total free memory */
for(im = bm; im->type != BIOS_MAP_END; im++) {