summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/i386/include/biosvar.h11
-rw-r--r--sys/arch/i386/stand/libsa/Makefile4
-rw-r--r--sys/arch/i386/stand/libsa/biosdev.c172
-rw-r--r--sys/arch/i386/stand/libsa/biosdev.h11
-rw-r--r--sys/arch/i386/stand/libsa/biosdisk.S219
5 files changed, 152 insertions, 265 deletions
diff --git a/sys/arch/i386/include/biosvar.h b/sys/arch/i386/include/biosvar.h
index f2546bec12e..931c23d6b56 100644
--- a/sys/arch/i386/include/biosvar.h
+++ b/sys/arch/i386/include/biosvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: biosvar.h,v 1.6 1997/08/07 01:08:17 mickey Exp $ */
+/* $OpenBSD: biosvar.h,v 1.7 1997/08/12 19:24:47 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -193,7 +193,6 @@
/* 0x0300 - 0xffff Reserved */
#define PMEV_DEFAULT 0xffffffff /* used for customization */
-
#ifdef _LOCORE
#define DOINT(n) int $0x20+(n)
#else
@@ -211,6 +210,14 @@ extern struct BIOS_regs {
u_int32_t biosr_es;
} BIOS_regs;
+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 */
+};
+
#ifdef _KERNEL
#include <machine/bus.h>
diff --git a/sys/arch/i386/stand/libsa/Makefile b/sys/arch/i386/stand/libsa/Makefile
index d0158588149..b0f36fda0c5 100644
--- a/sys/arch/i386/stand/libsa/Makefile
+++ b/sys/arch/i386/stand/libsa/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.19 1997/08/12 19:05:57 mickey Exp $
+# $OpenBSD: Makefile,v 1.20 1997/08/12 19:24:56 mickey Exp $
LIB= sa
@@ -13,7 +13,7 @@ DIR_KERN=$S/lib/libkern
#AS+= -a
# i386 stuff (so, it will possibly load in the same 64k)
-SRCS= unixsys.S bioscom.S biosdisk.S bioskbd.S gidt.S \
+SRCS= unixsys.S bioscom.S bioskbd.S gidt.S \
debug_i386.S dev_i386.c exec_i386.c biosdev.c gateA20.c memprobe.c \
time.c alloca.S apm_init.S machdep.c
diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c
index 89dcb9e9cb4..11cae12311c 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.22 1997/08/07 11:49:15 niklas Exp $ */
+/* $OpenBSD: biosdev.c,v 1.23 1997/08/12 19:24:57 mickey Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -47,17 +47,122 @@ struct BIOS_regs BIOS_regs;
struct biosdisk {
u_int dinfo;
- struct {
- u_int8_t mboot[DOSPARTOFF];
- struct dos_partition dparts[NDOSPART];
- u_int16_t signature;
- } mbr;
- struct disklabel disklabel;
dev_t bsddev;
u_int8_t biosdev;
int edd_flags;
+ struct disklabel disklabel;
};
+/*
+ *
+ * return a word that represents the max number
+ * of sectors and heads for this device
+ *
+ */
+static u_int16_t
+biosdinfo(dev)
+ u_int8_t dev;
+{
+ u_int16_t rv;
+ u_int8_t f;
+ __asm __volatile ("movb $8, %%ah\n\t"
+ DOINT(0x13) "\n\t"
+ "setc %b0\n\t"
+ /* form a word w/ nhead/nsect packed */
+ "movb %%cl, %b1\n\t"
+ "andb $0x3f, %b1"
+ : "=a" (f), "=d" (rv)
+ : "1" (dev) : "%ecx", "cc");
+ if (f)
+ return 0x0118; /* ds/hd 3" is the default */
+ else
+ return rv;
+}
+
+/*
+ * reset disk system
+ */
+static __inline int
+biosdreset(dev)
+ u_int8_t dev;
+{
+ int rv;
+ __asm __volatile (DOINT(0x13) "\n\t"
+ "setc %b0"
+ : "=a" (rv)
+ : "0" (0), "id" (dev) : "%ecx", "cc");
+ return rv;
+}
+
+static int
+biosd_rw(rw, dev, cyl, head, sect, nsect, buf)
+ u_int8_t dev;
+ int cyl, head, sect, nsect;
+ void *buf;
+{
+ int rv;
+ BIOS_regs.biosr_es = (u_int32_t)buf >> 4;
+ __asm __volatile ("movb %b7, %h1\n\t"
+ "movb %b6, %%dh\n\t"
+ "andl $0xf, %4\n\t"
+ /* cylinder; the highest 2 bits of cyl is in %cl */
+ "xchgb %%ch, %%cl\n\t"
+ "rorb $2, %%cl\n\t"
+ "orb %b5, %%cl\n\t"
+ "incb %%cl\n\t"
+ DOINT(0x13) "\n\t"
+ "setc %b0"
+ : "=a" (rv)
+ : "0" (nsect), "d" (dev), "c" (cyl),
+ "b" (buf), "m" (sect), "m" (head),
+ "m" ((rw == F_READ)? 2: 3)
+ : "cc", "memory");
+
+ return (rv & 0xff)? rv >> 8 : 0;
+}
+
+/*
+ * check the features supported by the bios for the drive
+ */
+static __inline int
+EDDcheck (dev)
+ u_int8_t dev;
+{
+ u_int8_t rv;
+ u_int16_t bm, sgn;
+ __asm __volatile("movb $0x44, %%ah\n\t"
+ DOINT(0x13) "\n\t"
+ "setc %b0"
+ : "=a" (rv), "=c" (bm), "=b" (sgn)
+ : "2" (0x55aa)
+ : "%edx", "cc");
+ if (!rv && sgn == 0xaa55)
+ return bm;
+ else
+ return -1;
+}
+
+int
+EDD_rw(int rw, u_int8_t dev, u_int64_t daddr, u_int32_t nblk, void *buf)
+{
+ u_int16_t rv;
+ struct EDD_CB cb;
+
+ cb.edd_len = sizeof(cb);
+ cb.edd_nblk = nblk;
+ cb.edd_buf = (u_int32_t)buf;
+ cb.edd_daddr = daddr;
+
+ __asm __volatile ("movb %b3, %%ah\n\t"
+ DOINT(0x13) "\n\t"
+ "setc %b0"
+ : "=a" (rv)
+ : "d" (dev), "S" (&cb),
+ "0" ((rw == F_READ)? 0x4200: 0x4300)
+ : "%ecx", "cc");
+ return (rv & 0xff)? rv >> 8 : 0;
+}
+
int
biosopen(struct open_file *f, ...)
{
@@ -126,8 +231,10 @@ biosopen(struct open_file *f, ...)
case 0: /* wd */
case 4: /* sd */
case 17: /* hd */
- maj = 17;
bd->biosdev = (u_int8_t)(unit | 0x80);
+ if (maj == 17)
+ unit = 0;
+ maj = 17;
break;
case 2: /* fd */
bd->biosdev = (u_int8_t)unit;
@@ -163,8 +270,13 @@ biosopen(struct open_file *f, ...)
#endif
if (maj == 17) { /* hd, wd, sd */
+ struct {
+ u_int8_t mboot[DOSPARTOFF];
+ struct dos_partition dparts[NDOSPART];
+ u_int16_t signature;
+ } mbr;
if ((errno = biosstrategy(bd, F_READ, DOSBBSECTOR,
- DEV_BSIZE, &bd->mbr, NULL)) != 0) {
+ DEV_BSIZE, &mbr, NULL)) != 0) {
#ifdef DEBUG
if (debug)
printf("cannot read MBR\n");
@@ -174,7 +286,7 @@ biosopen(struct open_file *f, ...)
}
/* check mbr signature */
- if (bd->mbr.signature != 0xaa55) {
+ if (mbr.signature != 0xaa55) {
#ifdef DEBUG
if (debug)
printf("bad MBR signature\n");
@@ -184,14 +296,14 @@ biosopen(struct open_file *f, ...)
}
for (off = 0, i = 0; off == 0 && i < NDOSPART; i++)
- if (bd->mbr.dparts[i].dp_typ == DOSPTYP_OPENBSD)
- off = bd->mbr.dparts[i].dp_start + LABELSECTOR;
+ if (mbr.dparts[i].dp_typ == DOSPTYP_OPENBSD)
+ off = mbr.dparts[i].dp_start + LABELSECTOR;
/* just in case */
if (off == 0)
for (off = 0, i = 0; off == 0 && i < NDOSPART; i++)
- if (bd->mbr.dparts[i].dp_typ == DOSPTYP_NETBSD)
- off = bd->mbr.dparts[i].dp_start +
+ if (mbr.dparts[i].dp_typ == DOSPTYP_NETBSD)
+ off = mbr.dparts[i].dp_start +
LABELSECTOR;
if (off == 0) {
@@ -211,7 +323,7 @@ biosopen(struct open_file *f, ...)
#endif
/* read disklabel */
if ((errno = biosstrategy(bd, F_READ, off,
- DEV_BSIZE, buf, NULL)) != 0) {
+ DEV_BSIZE, buf, NULL)) != 0) {
#ifdef DEBUG
if (debug)
printf("failed to read disklabel\n");
@@ -245,7 +357,7 @@ biosopen(struct open_file *f, ...)
}
/* BIOS disk errors translation table */
-const struct bd_error {
+static const struct bd_error {
u_int8_t bd_id;
int unix_id;
char *msg;
@@ -285,7 +397,6 @@ const struct bd_error {
{ 0xE0, EIO , "status register error" },
{ 0xFF, EIO , "sense operation failed" }
};
-const int bd_nents = NENTS(bd_errors);
int
biosstrategy(void *devdata, int rw,
@@ -303,7 +414,8 @@ biosstrategy(void *devdata, int rw,
#ifdef BIOS_DEBUG
if (debug)
- printf("biosstrategy(%p,%s,%u,%u,%p,%p), dev=%x:%x\nbiosread:",
+ 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
@@ -342,27 +454,23 @@ biosstrategy(void *devdata, int rw,
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; error && (j > 0); j--) {
- if(rw == F_READ)
- error = biosread(bd->biosdev, cyl, hd, sect, n, bb);
- else
- error = bioswrite(bd->biosdev, cyl, hd, sect, n, bb);
-
- switch (error) {
+ for (error = 1, j = 5; j-- && error;)
+ switch (error = biosd_rw(rw, bd->biosdev,
+ cyl, hd, sect, n, bb)) {
case 0x00: /* No errors */
case 0x11: /* ECC corrected */
error = 0;
break;
default: /* All other errors */
- for (p = bd_errors; p < &bd_errors[bd_nents] &&
- p->bd_id != error; p++);
+ for (p = bd_errors;
+ p < &bd_errors[NENTS(bd_errors)] &&
+ p->bd_id != error; p++);
printf("\nBIOS error %x (%s)\n",
- p->bd_id, p->msg);
+ p->bd_id, p->msg);
biosdreset(bd->biosdev);
break;
}
- }
if (bb != buf && rw == F_READ)
bcopy (bb, buf, n * DEV_BSIZE);
@@ -371,8 +479,9 @@ biosstrategy(void *devdata, int rw,
#ifdef BIOS_DEBUG
if (debug) {
if (error != 0) {
- for (p = bd_errors; p < &bd_errors[bd_nents] &&
- p->bd_id != error; p++);
+ for (p = bd_errors;
+ p < &bd_errors[NENTS(bd_errors)] &&
+ p->bd_id != error; p++);
printf("=%x(%s)", p->bd_id, p->msg);
}
putchar('\n');
@@ -395,7 +504,6 @@ biosclose(struct open_file *f)
int
biosioctl(struct open_file *f, u_long cmd, void *data)
{
-
return 0;
}
diff --git a/sys/arch/i386/stand/libsa/biosdev.h b/sys/arch/i386/stand/libsa/biosdev.h
index 3887fa4538e..e78a4032403 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.13 1997/08/12 19:16:37 mickey Exp $ */
+/* $OpenBSD: biosdev.h,v 1.14 1997/08/12 19:24:58 mickey Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -40,15 +40,6 @@ int biosopen __P((struct open_file *, ...));
int biosclose __P((struct open_file *));
int biosioctl __P((struct open_file *, u_long, void *));
-/* biosdisk.S */
-u_int16_t biosdinfo __P((int dev));
-int biosdreset __P((int dev));
-int biosread __P((int dev, int cyl, int hd, int sect, int nsect, void *));
-int bioswrite __P((int dev, int cyl, int hd, int sect, int nsect, void *));
-int EDDcheck __P((dev_t));
-int EDDread __P((dev_t, u_int64_t, u_int32_t, void *));
-int EDDwrite __P((dev_t, u_int64_t, u_int32_t, void *));
-
/* bioskbd.S */
int kbd_probe __P((void));
void kbd_putc __P((int c));
diff --git a/sys/arch/i386/stand/libsa/biosdisk.S b/sys/arch/i386/stand/libsa/biosdisk.S
deleted file mode 100644
index 196bb723de3..00000000000
--- a/sys/arch/i386/stand/libsa/biosdisk.S
+++ /dev/null
@@ -1,219 +0,0 @@
-/* $OpenBSD: biosdisk.S,v 1.13 1997/07/30 19:40:56 flipk Exp $ */
-
-/*
- * Copyright (c) 1997 Michael Shalayeff
- * 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Michael Shalayeff.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * 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 REGENTS OR CONTRIBUTORS 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.
- *
- */
-
-#include <machine/asm.h>
-#define _LOCORE
-#include <machine/biosvar.h>
-#include "debug_md.h"
-#undef _LOCORE
-#include <assym.h>
-
-
- .globl _C_LABEL(errno) /* XXX used for bios errors */
- .globl _C_LABEL(BIOS_regs)
-/*
- * int biosread(dev,cyl,head,sect,nsect,buf)
- * read number of sectors from disk
- */
-ENTRY(biosread)
- pushl %ebp
- movl %esp, %ebp
- pushl %ecx
- pushl %ebx
- pushl %edi
- pushl %es
-
- movb 8(%ebp), %dl # device
- movw 12(%ebp), %cx
- xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl
- rorb $2, %cl
- movb 16(%ebp), %dh # head
- movb 20(%ebp), %al
- orb %al, %cl
- incb %cl # sector; sec starts from 1, not 0
- movb $0x2, %ah # subfunction
- movb 24(%ebp), %al # number of sectors
- movl 28(%ebp), %ebx # offset
- movl %ebx, %edi # split off for seg:off pair
- andl $0xf, %ebx # atomic read for up to 64k
- shrl $4, %edi
- movl %edi, _C_LABEL(BIOS_regs)+biosr_es
-
- DOINT(0x13)
- movb $0, %al
- jnc 1f
- movb %ah, %al
-1:
- movzbl %al, %eax # return value in %ax
-
- popl %es
- popl %edi
- popl %ebx
- popl %ecx
- popl %ebp
- ret
-
-ENTRY(bioswrite)
- movl $1, %eax
- ret
-
-/*
- *
- * u_int16_t biosdinfo(): return a word that represents the
- * max number of sectors and heads and drives for this device
- *
- */
-
-ENTRY(biosdinfo)
- pushl %ebp
- movl %esp, %ebp
- pushl %ebx
- pushl %ecx
-
- movb 8(%ebp), %dl # drive #
- movb $0x08, %ah # ask for disk info
- DOINT(0x13)
- movb $1, %ah # max head
- movb $18, %al # max sector
- jc 1f
-
- /* form a word w/ nhead/nsect packed */
- movb %dh, %ah # max head
- andb $0x3f, %cl # mask of cylinder gunk
- movb %cl, %al # max sector (and # sectors)
-1:
- popl %ecx
- popl %ebx
- popl %ebp
- ret
-
-
-/*
- *
- * biosdreset(): reset disk system
- *
- */
-
-ENTRY(biosdreset)
- pushl %ebx
- pushl %ecx
-
- movb $0x00, %ah # reset disk system
- movb 8(%ebp), %dl # drive #
- DOINT(0x13)
-
- popl %ecx
- popl %ebx
- ret
-
-/*
- * int EDDcheck(dev)
- * check the features supported by the bios for the drive
- */
-ENTRY(EDDcheck)
- pushl %ebp
- movl %esp, %ebp
- pushl %ecx
- pushl %ebx
-
- movb $0x44, %ah
- movw $0x55aa, %bx
- movl 8(%ebp), %edx
- DOINT(0x13)
- movl $-1, %eax
- jc 1f
- cmpw $0xaa55, %bx
- jne 1f
- xorl %eax, %eax
- movw %cx, %ax /* API support bitmap */
-1:
- popl %ebx
- popl %ecx
- popl %ebp
- ret
-
- .data
-
-ddp: .byte 0x10 # size of packet
- .byte 0 # reserved
- .word 0 # # of blocks to transfer
- .long 0 # address to read/write to
- .long 0,0 # start to read here
-
- .text
-/*
- * int EDDread(dev,abs_sect,nsect,buf)
- * read nsect starting on absolute sector #abs_sect into buf
- */
-ENTRY(EDDread)
- pushl %ebp
- movl %esp, %ebp
- pushl %ecx
- pushl %ebx
- pushl %esi
-
- movl 8(%ebp), %edx /* drive */
- movl ddp, %esi
- movl 20(%ebp), %eax /* nblks */
- movw %ax, 2(%esi)
- movl 12(%ebp), %eax /* abs starting sector */
- movl %eax, 8(%esi)
- movl 16(%ebp), %eax
- movl %eax, 12(%esi)
- movl 24(%ebp), %eax /* buffer */
- movl %eax, 4(%esi)
- movb $0x42, %ah
- DOINT(0x13)
- jnc 1f
- xorl %eax, %eax
-
-1: movzbl %ah, %eax
- movl %eax, _C_LABEL(errno)
- movw 2(%esi), %ax /* return number of blocks read ok */
-
- popl %esi
- popl %ebx
- popl %ecx
- popl %ebp
- ret
-
-/*
- * int EDDwrite(dev,abs_sect,nsect,buf)
- * read nsect starting on absolute sector #abs_sect into buf
- */
-ENTRY(EDDwrite)
- movl $19, _C_LABEL(errno)
- movl $0, %eax
- ret
-