diff options
Diffstat (limited to 'sys/arch/i386/stand')
-rw-r--r-- | sys/arch/i386/stand/installboot/installboot.c | 38 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/Makefile | 4 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/apmprobe.c | 42 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/biosdev.c | 408 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/biosdev.h | 10 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/cmd_i386.c | 10 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/diskprobe.c | 133 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/exec_i386.c | 14 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/libsa.h | 11 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/machdep.c | 3 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/memprobe.c | 6 |
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++) { |