From 643fdea67cc6ba1bd757567d352506e5b944835d Mon Sep 17 00:00:00 2001 From: Michael Shalayeff Date: Tue, 12 Aug 1997 19:24:59 +0000 Subject: call BIOS inline (add struct EDD_cb into biosvar.h) --- sys/arch/i386/include/biosvar.h | 11 +- sys/arch/i386/stand/libsa/Makefile | 4 +- sys/arch/i386/stand/libsa/biosdev.c | 172 ++++++++++++++++++++++----- sys/arch/i386/stand/libsa/biosdev.h | 11 +- sys/arch/i386/stand/libsa/biosdisk.S | 219 ----------------------------------- 5 files changed, 152 insertions(+), 265 deletions(-) delete mode 100644 sys/arch/i386/stand/libsa/biosdisk.S 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 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 -#define _LOCORE -#include -#include "debug_md.h" -#undef _LOCORE -#include - - - .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 - -- cgit v1.2.3