diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /sys/arch/i386/stand |
initial import of NetBSD tree
Diffstat (limited to 'sys/arch/i386/stand')
-rw-r--r-- | sys/arch/i386/stand/Makefile | 118 | ||||
-rw-r--r-- | sys/arch/i386/stand/as.c | 269 | ||||
-rw-r--r-- | sys/arch/i386/stand/asbootblk.c | 236 | ||||
-rw-r--r-- | sys/arch/i386/stand/bmap.c | 125 | ||||
-rw-r--r-- | sys/arch/i386/stand/boot.c | 213 | ||||
-rw-r--r-- | sys/arch/i386/stand/breadxx.c | 81 | ||||
-rw-r--r-- | sys/arch/i386/stand/cga.c | 144 | ||||
-rw-r--r-- | sys/arch/i386/stand/fd.c | 376 | ||||
-rw-r--r-- | sys/arch/i386/stand/fdbootblk.c | 300 | ||||
-rw-r--r-- | sys/arch/i386/stand/fs.c | 161 | ||||
-rw-r--r-- | sys/arch/i386/stand/kbd.c | 269 | ||||
-rw-r--r-- | sys/arch/i386/stand/prf.c | 57 | ||||
-rw-r--r-- | sys/arch/i386/stand/saio.h | 71 | ||||
-rw-r--r-- | sys/arch/i386/stand/srt0.c | 275 | ||||
-rw-r--r-- | sys/arch/i386/stand/trimhd.c | 70 | ||||
-rw-r--r-- | sys/arch/i386/stand/wd.c | 434 | ||||
-rw-r--r-- | sys/arch/i386/stand/wdbootblk.c | 233 |
17 files changed, 3432 insertions, 0 deletions
diff --git a/sys/arch/i386/stand/Makefile b/sys/arch/i386/stand/Makefile new file mode 100644 index 00000000000..325b8c9e2b7 --- /dev/null +++ b/sys/arch/i386/stand/Makefile @@ -0,0 +1,118 @@ +# $NetBSD: Makefile,v 1.5 1994/10/27 04:21:44 cgd Exp $ +# @(#)Makefile 7.9 (Berkeley) 5/8/91 + +DESTDIR=/usr +LD=/usr/bin/ld +STAND= /sys/stand +INCPATH=-I/sys/sys -I/sys -I/sys/ufs -I${STAND} +VPATH= ${STAND} +STANDDIR= ${DESTDIR}/mdec + +CC= cc -traditional +CPP= cpp -traditional ${INCPATH} -DSTANDALONE -DAT386 + +RELOC= 98000 +RELOC2= 98200 + +CFLAGS= -DSTANDALONE -DAT386 -O ${INCPATH} + +DRIVERS=cga.c fd.c kbd.c wd.c as.c +SRCS= boot.c fdbootblk.c prf.c \ + srt0.c wdbootblk.c ${DRIVERS} ${SASRC} + +ALL= wdboot bootwd fdboot bootfd asboot bootas + +all: ${ALL} + +# startups + +srt0.o: srt0.c + ${CPP} -E -DLOCORE -DRELOC=0x${RELOC} srt0.c | ${AS} -o srt0.o + +wsrt0.o: srt0.c + ${CPP} -E -DLOCORE -DSMALL -DRELOC=0x${RELOC} -DREL srt0.c | \ + ${AS} -o wsrt0.o + +relsrt0.o: srt0.c + ${CPP} -E -DLOCORE -DRELOC=0x${RELOC} -DREL srt0.c | ${AS} -o relsrt0.o + +# block 0 boots + +wdbootblk.o: wdbootblk.c + ${CPP} -E -DLOCORE -DRELOC=0x${RELOC} wdbootblk.c | ${AS} -o $@ + +fdbootblk.o: fdbootblk.c + ${CPP} -E -DLOCORE -DRELOC=0x${RELOC} fdbootblk.c | ${AS} -o $@ + +asbootblk.o: asbootblk.c + cc -c -O -DRELOC=0x${RELOC} ${INCPATH} asbootblk.c + +# getting booted from disc + +wdboot: wdbootblk.o trimhd + ${LD} -N -T ${RELOC} wdbootblk.o + rm -f $@; strip a.out; trimhd 32 <a.out >$@; rm -f a.out; ls -l $@ + +bootwd: wsrt0.o boot.o bmap.o cga.o fs.o kbd.o prf.o wd.o printf.o breadwd.o trimhd + ${LD} -N -T ${RELOC2} wsrt0.o boot.o bmap.o cga.o kbd.o prf.o printf.o \ + breadwd.o fs.o wd.o -lc + size a.out + rm -f $@; strip a.out; trimhd 32 <a.out >$@; rm -f a.out; ls -l $@ + +fdboot: fdbootblk.o trimhd + ${LD} -N -T ${RELOC} fdbootblk.o + rm -f $@; strip a.out; trimhd 32 <a.out >$@; rm -f a.out; ls -l $@ + +bootfd: wsrt0.o boot.o bmap.o cga.o fs.o kbd.o prf.o fd.o printf.o breadfd.o trimhd + ${LD} -N -T ${RELOC2} wsrt0.o boot.o bmap.o cga.o kbd.o prf.o printf.o \ + breadfd.o fs.o fd.o -lc + size a.out + rm -f $@; strip a.out; trimhd 32 <a.out >$@; rm -f a.out; ls -l $@ + +asboot: asbootblk.o trimhd + ${LD} -N -T 7c00 asbootblk.o + rm -f $@; strip a.out; trimhd 32 <a.out >$@; rm -f a.out; ls -l $@ + +bootas: wsrt0.o boot.o bmap.o cga.o fs.o kbd.o prf.o as.o printf.o breadas.o trimhd + ${LD} -N -T ${RELOC2} wsrt0.o boot.o bmap.o cga.o kbd.o prf.o printf.o \ + breadas.o fs.o as.o -lc + size a.out + rm -f $@; strip a.out; trimhd 32 <a.out >$@; rm -f a.out; ls -l $@ + + +breadwd.o: breadwd.c breadxx.o +breadfd.o: breadfd.c breadxx.o +breadas.o: breadas.c breadxx.o + +breadxx.o: + touch breadxx.o + +breadwd.c: breadxx.c + rm -f breadwd.c + sed -e 's/XX/wd/' -e 's/xx/wd/g' < breadxx.c >> breadwd.c + +breadfd.c: breadxx.c + rm -f breadfd.c + sed -e 's/XX/fd/' -e 's/xx/fd/g' < breadxx.c >> breadfd.c + +breadas.c: breadxx.c + rm -f breadas.c + sed -e 's/XX/as/' -e 's/xx/as/g' < breadxx.c >> breadas.c + +trimhd: trimhd.c + ${CC} ${CFLAGS} -s -o trimhd trimhd.c + +clean: + rm -f *.o *.exe *.i sm_*.c trimhd + rm -f a.out bfd bwd fdb wdb ${ALL} + rm -f boot[a-wyz]? boot[a-wyz]?? boot[a-wyz]?.c boot[a-wyz]??.c \ + conf[a-wyz]?.c conf[a-wyz]??.c bread[a-wyz]?.c + +cleandir: clean + rm -f ${MAN} tags .depend + +depend: ${SRCS} + mkdep ${INCPATH} -DSTANDALONE ${SRCS} ${DUMMIES} + +install: ${ALL} + cp ${ALL} ${STANDDIR} diff --git a/sys/arch/i386/stand/as.c b/sys/arch/i386/stand/as.c new file mode 100644 index 00000000000..2a3b6700f22 --- /dev/null +++ b/sys/arch/i386/stand/as.c @@ -0,0 +1,269 @@ +/* $NetBSD: as.c,v 1.4 1994/10/27 04:21:45 cgd Exp $ */ + +/* + * sys/i386/stand/as.c + * + * Standalone driver for Adaptech 1542 SCSI + * + * Pace Willisson pace@blitz.com April 8, 1992 + */ + +#include "param.h" +#include "disklabel.h" +#include "i386/isa/asreg.h" +#include "saio.h" + +#ifdef ASDEBUG +#define ASPRINT(x) { printf x; DELAY (10000); } +#else +#define ASPRINT(x) +#endif + +#define NRETRIES 3 + +int as_port = 0x330; + +struct mailbox_entry mailbox[2]; + +int +asopen(io) +struct iob *io; +{ + struct disklabel *dd; + char cdb[6]; + char data[12]; + int val; + int oval; + int i; + struct iob aio; + + if (io->i_unit < 0 || io->i_unit > 8 + || io->i_part < 0 || io->i_part > 8 + || io->i_ctlr < 0 || io->i_ctlr > 0) + return (-1); + + /* dma setup: see page 5-31 in the Adaptech manual */ + outb (0xd6, 0xc1); + outb (0xd4, 0x01); + + ASPRINT (("resetting adaptech card... ")); + + outb (as_port + AS_CONTROL, AS_CONTROL_SRST); + + /* delay a little */ + for (i = 0; i < 100; i++) + inb (0x84); + + while (inb (as_port + AS_STATUS) != (AS_STATUS_INIT | AS_STATUS_IDLE)) + ; + + ASPRINT (("reset ok ")); + + as_put_byte (AS_CMD_MAILBOX_INIT); + as_put_byte (1); /* one mailbox out, one in */ + as_put_byte ((int)mailbox >> 16); + as_put_byte ((int)mailbox >> 8); + as_put_byte ((int)mailbox); + + while (inb (as_port + AS_STATUS) & AS_STATUS_INIT) + ; + + ASPRINT (("mailbox init ok ")); + + /* do mode select to set the logical block size */ + bzero (cdb, 6); + cdb[0] = 0x15; /* MODE SELECT */ + cdb[4] = 12; /* parameter list length */ + + bzero (data, 12); + data[3] = 8; /* block descriptor length */ + data[9] = DEV_BSIZE >> 16; + data[10] = DEV_BSIZE >> 8; + data[11] = DEV_BSIZE; + + if (ascmd (io->i_unit, 0, cdb, 6, data, 12, 1) < 0) { + printf ("as%d: error setting logical block size\n", + io->i_unit); + return (-1); + } + + aio = *io; + aio.i_bn = LABELSECTOR; + aio.i_cc = DEV_BSIZE; + /*io->i_ma = buf;*/ + aio.i_boff = 0; + +#ifdef was + if (asstrategy (&aio, F_READ) == DEV_BSIZE) { + dd = (struct disklabel *)aio.i_ma; + io->i_boff = dd->d_partitions[io->i_part].p_offset; + ASPRINT (("partition offset %d ", io->i_boff)); + } +#else +{ +extern struct disklabel disklabel; + io->i_boff = disklabel.d_partitions[io->i_part].p_offset; + ASPRINT (("partition offset %d ", io->i_boff)); +} +#endif + + ASPRINT (("asopen ok ")); + return(0); +} + +/* func is F_WRITE or F_READ + * io->i_unit, io->i_part, io->i_bn is starting block + * io->i_cc is byte count + * io->i_ma is memory address + * io->i_boff is block offset for this partition (set up in asopen) + */ +int +asstrategy(io, func) +struct iob *io; +{ + char cdb[6]; + int blkno; + int retry; + + ASPRINT (("asstrategy(target=%d, block=%d+%d, count=%d) ", + io->i_unit, io->i_bn, io->i_boff, io->i_cc)); + + if (func == F_WRITE) { + printf ("as%d: write not supported\n", io->i_unit); + return (0); + } + + if (io->i_cc == 0) + return (0); + + if (io->i_cc % DEV_BSIZE != 0) { + printf ("as%d: transfer size not multiple of %d\n", + io->i_unit, DEV_BSIZE); + return (0); + } + + /* retry in case we get a unit-attention error, which just + * means the drive has been reset since the last command + */ + for (retry = 0; retry < NRETRIES; retry++) { + blkno = io->i_bn + io->i_boff; + + cdb[0] = 8; /* scsi read opcode */ + cdb[1] = (blkno >> 16) & 0x1f; + cdb[2] = blkno >> 8; + cdb[3] = blkno; + cdb[4] = io->i_cc / DEV_BSIZE; + cdb[5] = 0; /* control byte (used in linking) */ + + if (ascmd (io->i_unit, 1, cdb, 6, io->i_ma, io->i_cc, + retry == NRETRIES - 1) >= 0) { + ASPRINT (("asstrategy ok ")); + return (io->i_cc); + } + } + + ASPRINT (("asstrategy failed ")); + return (0); +} + +int +ascmd (target, readflag, cdb, cdblen, data, datalen, printerr) +int target; +int readflag; +char *cdb; +int cdblen; +char *data; +int datalen; +int printerr; +{ + struct ccb ccb; + int physaddr; + unsigned char *sp; + int i; + + if (mailbox[0].cmd != 0) + /* this can't happen, unless the card flakes */ + _stop ("asstart: mailbox not available\n"); + + bzero (&ccb, sizeof ccb); + + ccb.ccb_opcode = 0; + ccb.ccb_addr_and_control = target << 5; + if (datalen != 0) + ccb.ccb_addr_and_control |= readflag ? 8 : 0x10; + else + ccb.ccb_addr_and_control |= 0x18; + + ccb.ccb_data_len_msb = datalen >> 16; + ccb.ccb_data_len_mid = datalen >> 8; + ccb.ccb_data_len_lsb = datalen; + + ccb.ccb_requst_sense_allocation_len = MAXSENSE; + + physaddr = (int)data; + ccb.ccb_data_ptr_msb = physaddr >> 16; + ccb.ccb_data_ptr_mid = physaddr >> 8; + ccb.ccb_data_ptr_lsb = physaddr; + + ccb.ccb_scsi_command_len = cdblen; + bcopy (cdb, ccb.ccb_cdb, cdblen); + +#ifdef ASDEBUG + printf ("ccb: "); + for (i = 0; i < 48; i++) + printf ("%x ", ((unsigned char *)&ccb)[i]); + printf ("\n"); + /*getchar ();*/ +#endif + + physaddr = (int)&ccb; + mailbox[0].msb = physaddr >> 16; + mailbox[0].mid = physaddr >> 8; + mailbox[0].lsb = physaddr; + mailbox[0].cmd = 1; + + /* tell controller to look in its mailbox */ + outb (as_port + AS_CONTROL, AS_CONTROL_IRST); + as_put_byte (AS_CMD_START_SCSI_COMMAND); + + /* wait for status */ + ASPRINT (("waiting for status...")); + while (mailbox[1].cmd == 0) + ; + mailbox[1].cmd = 0; + + + if (ccb.ccb_host_status != 0 || ccb.ccb_target_status != 0) { +#ifdef ASDEBUG + printerr = 1; +#endif + if (printerr) { + printf ("as%d error: hst=%x tst=%x sense=", + target, + ccb.ccb_host_status, + ccb.ccb_target_status); + sp = ccb_sense (&ccb); + for (i = 0; i < 8; i++) + printf ("%x ", sp[i]); + printf ("\n"); +#ifdef ASDEBUG + /*getchar ();*/ +#endif + } + return (-1); + } + + ASPRINT (("ascmd ok ")); + + return (0); +} + +int +as_put_byte (val) +int val; +{ + while (inb (as_port + AS_STATUS) & AS_STATUS_CDF) + ; + outb (as_port + AS_DATA_OUT, val); +} + diff --git a/sys/arch/i386/stand/asbootblk.c b/sys/arch/i386/stand/asbootblk.c new file mode 100644 index 00000000000..aae9e648e7c --- /dev/null +++ b/sys/arch/i386/stand/asbootblk.c @@ -0,0 +1,236 @@ +/* $NetBSD: asbootblk.c,v 1.4 1994/10/27 04:21:46 cgd Exp $ */ + +/* + * sys/i386/stand/asbootblk.c + * + * Boot block for Adaptech 1542 SCSI + * + * April 10, 1992 + * Pace Willisson + * pace@blitz.com + * + * Placed in the public domain with NO WARRANTIES, not even the + * implied warranties for MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. + * + * To compile: + * + * cc -O -c -DRELOC=0x70000 asbootblk.c + * ld -N -T 7c00 asbootblk.o + * + * This should result in a file with 512 bytes of text and no initialized + * data. Strip the 32 bit header and place in block 0. + * + * When run, this program copies at least the first 8 blocks of SCSI + * target 0 to the address specified by RELOC, then jumps to the + * address RELOC+1024 (skipping the boot block and disk label). Usually, + * disks have 512 bytes per block, but I don't think they ever have + * less, and it wont hurt if they are bigger, as long as RELOC + 8*SIZE + * is less than 0xa0000. + * + * This bootblock does not support fdisk partitions, and can only be used + * as the master boot block. + */ + +#include "param.h" +#include "disklabel.h" +#include "i386/isa/asreg.h" + +/* RELOC should be defined with a -D flag to cc */ + +#define SECOND_LEVEL_BOOT_START (RELOC + 0x400) +#define READ_SIZE 8192 + +#define as_port 0x330 +#define target 0 + + +#define NBLOCKS (READ_SIZE / 512) /* how many logical blocks to read */ + + +/* These are the parameters to pass to the second level boot */ +#define dev 4 /* major device number of as driver in + i386/stand/conf.c and i386/i386/conf.c */ +#define unit 0 /* partition number of root file system */ +#define off 0 /* block offset of root file system */ + +/* inline i/o borrowed from Roell X server */ +static __inline__ void +outb(port, val) +short port; +char val; +{ + __asm__ volatile("outb %%al, %1" : :"a" (val), "d" (port)); +} + +static __inline__ unsigned int +inb(port) +short port; +{ + unsigned int ret; + __asm__ volatile("xorl %%eax, %%eax; inb %1, %%al" + : "=a" (ret) : "d" (port)); + return ret; +} + +/* this code is linked at 0x7c00 and is loaded there by the BIOS */ + +asm (" + /* we're running in 16 real mode, so normal assembly doesn't work */ +bootbase: + /* interrupts off */ + cli + + /* load gdt */ + .byte 0x2e,0x0f,0x01,0x16 /* lgdt %cs:$imm */ + .word _gdtarg + 2 + + /* turn on protected mode */ + smsw %ax + orb $1,%al + lmsw %ax + + /* flush prefetch queue and reload %cs */ + .byte 0xea /* ljmp $8, flush */ + .word flush + .word 8 + +flush: + /* now running in 32 bit mode */ + movl $0x10,%eax + movl %ax,%ds + movl %ax,%es + movl %ax,%ss + movl $0x7c00,%esp + call _main +"); /* end of asm */ + +const char gdt[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0xff, 0xff, 0, 0, 0, 0x9f, 0xcf, 0, /* code segment */ + 0xff, 0xff, 0, 0, 0, 0x93, 0xcf, 0, /* data segment */ +}; + +const struct { + short filler; + short size; + const char *gdt; +} gdtarg = { 0, sizeof gdt - 1, gdt }; + +#define CRTBASE ((char *)0xb8000) +#define CHECKPOINT(x) (CRTBASE[0] = x) + +volatile struct mailbox_entry mailbox[2]; +const char ccb[] = { + 0, /* opcode: normal read/write */ + (target << 5) | 8, /* target num and read flag */ + 10, /* scsi cmd len */ + 1, /* no automatic request for sense */ + READ_SIZE >> 16, /* data length */ + READ_SIZE >> 8, + READ_SIZE, + RELOC >> 16, /* data pointer */ + RELOC >> 8, + RELOC, + 0, 0, 0, /* link pointer */ + 0, /* link id */ + 0, /* host status */ + 0, /* target status */ + 0, 0, /* reserved */ + + /* scsi cdb */ + 0x28, /* read opcode */ + 0, /* logical unit number */ + 0, 0, 0, 0, /* logical block address */ + 0, /* reserved */ + 0, NBLOCKS, /* transfer length */ + 0, /* link control */ +}; + +int (*f)(); + +main () +{ + int i; + extern char edata[], end[]; + char volatile * volatile p, *q; + int physaddr; + + CHECKPOINT ('a'); + + /* clear bss */ + for (p = edata; p < end; p++) + *p = 0; + + f = (int (*)())SECOND_LEVEL_BOOT_START; + + /* dma setup: see page 5-31 in the Adaptech manual */ + /* this knows we are using drq 5 */ + outb (0xd6, 0xc1); + outb (0xd4, 0x01); + + outb (as_port + AS_CONTROL, AS_CONTROL_SRST); + + /* delay a little */ + inb (0x84); + + while (inb (as_port + AS_STATUS) != (AS_STATUS_INIT | AS_STATUS_IDLE)) + ; + + CHECKPOINT ('b'); + + as_put_byte (AS_CMD_MAILBOX_INIT); + as_put_byte (1); /* one mailbox out, one in */ + as_put_byte ((int)mailbox >> 16); + as_put_byte ((int)mailbox >> 8); + as_put_byte ((int)mailbox); + + while (inb (as_port + AS_STATUS) & AS_STATUS_INIT) + ; + + CHECKPOINT ('c'); + + mailbox[0].msb = (int)ccb >> 16; + mailbox[0].mid = (int)ccb >> 8; + mailbox[0].lsb = (int)ccb; + mailbox[0].cmd = 1; + + as_put_byte (AS_CMD_START_SCSI_COMMAND); + + /* wait for done */ + while (mailbox[1].cmd == 0) + ; + + CHECKPOINT ('d'); + + if (mailbox[1].cmd != 1) { + /* some error */ + CHECKPOINT ('X'); + while (1); + } + + CHECKPOINT ('e'); + + /* the optimazation that gcc uses when it knows we are jumpping + * to a constant address is broken, so we have to use a variable + * here + */ + (*f)(dev, unit, off); +} + +int +as_put_byte (val) +int val; +{ + while (inb (as_port + AS_STATUS) & AS_STATUS_CDF) + ; + outb (as_port + AS_DATA_OUT, val); +} + +asm (" +ebootblkcode: + . = 510 + .byte 0x55 + .byte 0xaa +ebootblk: /* MUST BE EXACTLY 0x200 BIG FOR SURE */ +"); diff --git a/sys/arch/i386/stand/bmap.c b/sys/arch/i386/stand/bmap.c new file mode 100644 index 00000000000..e1dbe7eea3d --- /dev/null +++ b/sys/arch/i386/stand/bmap.c @@ -0,0 +1,125 @@ +/* $NetBSD: bmap.c,v 1.3 1994/10/27 04:21:48 cgd Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1989 Regents of the University of California. + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + * + * @(#)ufs_bmap.c 7.13 (Berkeley) 5/8/91 + */ + +#include "param.h" +#include "dinode.h" +#include "fs.h" +#include "errno.h" + +/* + * Bmap converts a the logical block number of a file + * to its physical block number on the disk. The conversion + * is done by using the logical block number to index into + * the array of block pointers described by the dinode. + */ +extern struct fs *fs; +extern int bdev; + +static daddr_t bap[2*1024]; +static daddr_t bnobap; + +bmap(dip, bn, bnp) + register struct dinode *dip; + register daddr_t bn; + daddr_t *bnp; +{ + register daddr_t nb; + int i, j, sh; + int error; + +/*fprintf(stderr, "bmap %d ", bn);*/ + if (bn < 0) + return (EFBIG); + + /* + * The first NDADDR blocks are direct blocks + */ + if (bn < NDADDR) { + nb = dip->di_db[bn]; + if (nb == 0) { + *bnp = (daddr_t)-1; +/*fprintf(stderr, "%d\n", *bnp);*/ + return (0); + } + *bnp = fsbtodb(fs, nb); +/*fprintf(stderr, "%d\n", *bnp);*/ + return (0); + } + /* + * Determine the number of levels of indirection. + */ + sh = 1; + bn -= NDADDR; + for (j = NIADDR; j > 0; j--) { + sh *= NINDIR(fs); + if (bn < sh) + break; + bn -= sh; + } + if (j == 0) + return (EFBIG); + /* + * Fetch through the indirect blocks. + */ + nb = dip->di_ib[NIADDR - j]; + if (nb == 0) { + *bnp = (daddr_t)-1; +/*fprintf(stderr, "%d\n", *bnp);*/ + return (0); + } + for (; j <= NIADDR; j++) { + daddr_t bno = fsbtodb(fs, nb); + + if (bnobap != bno && +(error = bread(bdev, bno, &bap, + (int)fs->fs_bsize))) { + return (error); + } + bnobap = bno; + sh /= NINDIR(fs); + i = (bn / sh) % NINDIR(fs); + nb = bap[i]; + if (nb == 0) { + *bnp = (daddr_t)-1; +/*fprintf(stderr, "%d\n", *bnp);*/ + return (0); + } + } + *bnp = fsbtodb(fs, nb); +/*fprintf(stderr, "%d\n", *bnp);*/ + return (0); +} diff --git a/sys/arch/i386/stand/boot.c b/sys/arch/i386/stand/boot.c new file mode 100644 index 00000000000..de8f5528096 --- /dev/null +++ b/sys/arch/i386/stand/boot.c @@ -0,0 +1,213 @@ +/* $NetBSD: boot.c,v 1.6 1994/10/27 04:21:49 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + */ + +#ifdef lint +char copyright[] = +"@(#) Copyright (c) 1990 The Regents of the University of California.\n\ + All rights reserved.\n"; +#endif /* not lint */ + +#ifdef lint +#ifdef notdef +static char sccsid[] = "@(#)boot.c 7.3 (Berkeley) 5/4/91"; +#endif +static char rcsid[] = "$NetBSD: boot.c,v 1.6 1994/10/27 04:21:49 cgd Exp $"; +#endif /* not lint */ + +#include "param.h" +#include "reboot.h" +#include <a.out.h> +#include "saio.h" +#include "disklabel.h" +#include "dinode.h" + +/* + * Boot program, loaded by boot block from remaing 7.5K of boot area. + * Sifts through disklabel and attempts to load an program image of + * a standalone program off the disk. If keyboard is hit during load, + * or if an error is encounter, try alternate files. + */ + +char *files[] = { "netbsd", "onetbsd", "netbsd.old", + "386bsd", "o386bsd", "386bsd.old", + "vmunix", "ovmunix", "vmunix.old", + "boot", 0}; +int retry = 0; +extern struct disklabel disklabel; +extern int bootdev, cyloffset; +static unsigned char *biosparams = (char *) 0x9ff00; /* XXX */ + +/* + * Boot program... loads /boot out of filesystem indicated by arguements. + * We assume an autoboot unless we detect a misconfiguration. + */ + +main(dev, unit, off) +{ + register struct disklabel *lp; + register int io; + register char **bootfile = files; + int howto = 0; + extern int scsisn; /* XXX */ + + + /* are we a disk, if so look at disklabel and do things */ + lp = &disklabel; + if (lp->d_type == DTYPE_SCSI) /* XXX */ + off = htonl(scsisn); /* XXX */ + +/*printf("cyl %x %x hd %x sect %x ", biosparams[0], biosparams[1], biosparams[2], biosparams[0xe]); + printf("dev %x unit %x off %d\n", dev, unit, off);*/ + + if (lp->d_magic == DISKMAGIC) { + /* + * Synthesize bootdev from dev, unit, type and partition + * information from the block 0 bootstrap. + * It's dirty work, but someone's got to do it. + * This will be used by the filesystem primatives, and + * drivers. Ultimately, opendev will be created corresponding + * to which drive to pass to top level bootstrap. + */ + for (io = 0; io < lp->d_npartitions; io++) { + int sn; + + if (lp->d_partitions[io].p_size == 0) + continue; + if (lp->d_type == DTYPE_SCSI) + sn = off; + else + sn = off * lp->d_secpercyl; + if (lp->d_partitions[io].p_offset == sn) + break; + } + + if (io == lp->d_npartitions) goto screwed; + cyloffset = off; + } else { +screwed: + /* probably a bad or non-existant disklabel */ + io = 0 ; + howto |= RB_SINGLE|RB_ASKNAME ; + } + + /* construct bootdev */ + /* currently, PC has no way of booting off alternate controllers */ + bootdev = MAKEBOOTDEV(/*i_dev*/ dev, /*i_adapt*/0, /*i_ctlr*/0, + unit, /*i_part*/io); + + for (;;) { + +/*printf("namei %s", *bootfile);*/ + io = namei(*bootfile); + if (io > 2) { + copyunix(io, howto, off); + } else + printf("File not found"); + + printf(" - didn't load %s, ",*bootfile); + if(*++bootfile == 0) bootfile = files; + printf("will try %s\n", *bootfile); + + wait(1<<((retry++) + 10)); + } +} + +/*ARGSUSED*/ +copyunix(io, howto, cyloff) + register io; +{ + struct exec x; + int i; + char *addr,c; + struct dinode fil; + int off; + + fetchi(io, &fil); +/*printf("mode %o ", fil.di_mode);*/ + i = iread(&fil, 0, (char *)&x, sizeof x); + off = sizeof x; + if (i != sizeof x || x.a_magic != 0413) { + printf("Not an executable format"); + return; + } + + if (roundup(x.a_text, 4096) + x.a_data + x.a_bss > (unsigned)&fil) { + printf("File too big to load"); + return; + } + + off = 4096; + if (iread(&fil, off, (char *)0, x.a_text) != x.a_text) + goto shread; + off += x.a_text; + + addr = (char *)x.a_text; + while ((int)addr & CLOFSET) + *addr++ = 0; + + if (iread(&fil, off, addr, x.a_data) != x.a_data) + goto shread; + + addr += x.a_data; + + if (addr + x.a_bss > (unsigned) &fil) { + printf("Warning: bss overlaps bootstrap"); + x.a_bss = (unsigned)addr - (unsigned)&fil; + } + bzero(addr, x.a_bss); + + /* mask high order bits corresponding to relocated system base */ + x.a_entry &= ~0xfff00000; + + /*if (scankbd()) { + printf("Operator abort"); + kbdreset(); + return; + }*/ + + /* howto, bootdev, cyl */ + /*printf("entry %x [%x] ", x.a_entry, *(int *) x.a_entry);*/ + bcopy(0x9ff00, 0x300, 0x20); /* XXX */ + i = (*((int (*)()) x.a_entry))(howto, bootdev, off); + + if (i) printf("Program exits with %d", i) ; + return; +shread: + printf("Read of file is incomplete"); + return; +} diff --git a/sys/arch/i386/stand/breadxx.c b/sys/arch/i386/stand/breadxx.c new file mode 100644 index 00000000000..616af2e9659 --- /dev/null +++ b/sys/arch/i386/stand/breadxx.c @@ -0,0 +1,81 @@ +/* $NetBSD: breadxx.c,v 1.3 1994/10/27 04:21:50 cgd Exp $ */ + +/* + * Copyright (c) 1989, 1990, 1991, 1992 William F. Jolitz, TeleMuse + * 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 software is a component of "386BSD" developed by + William F. Jolitz, TeleMuse. + * 4. Neither the name of the developer nor the name "386BSD" + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ + * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS + * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT. + * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT + * NOT MAKE USE THIS WORK. + * + * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED + * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN + * REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES + * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING + * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND + * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE + * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS + * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPER 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. + */ + +/* + * Interface to driver to obtain a block off the disk drive. + */ +#include "param.h" +#include "saio.h" + + +char *devname = "XX"; +static ss = 1; +struct iob iobuf; +bread(bdev, off, addr, sz) + char *addr; +{ + +/*printf("bread %d %d %x %d\n", bdev, off, addr, sz);*/ + iobuf.i_dev = 0; + iobuf.i_adapt = 0; + iobuf.i_ctlr = 0; + iobuf.i_part = 0; + iobuf.i_unit = 0; + iobuf.i_cc = sz; + iobuf.i_bn = off; + iobuf.i_ma = addr; + /*io.i_boff= 0;*/ + iobuf.i_flgs = F_FILE | F_READ; + if(ss) { ss=0; xxopen(&iobuf); } + xxstrategy(&iobuf, F_READ); + scankbd(); + return(0); +} + diff --git a/sys/arch/i386/stand/cga.c b/sys/arch/i386/stand/cga.c new file mode 100644 index 00000000000..47fdbf5daa8 --- /dev/null +++ b/sys/arch/i386/stand/cga.c @@ -0,0 +1,144 @@ +/* $NetBSD: cga.c,v 1.3 1994/10/27 04:21:51 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + * + * @(#)cga.c 5.3 (Berkeley) 4/28/91 + */ + +#include "param.h" + +#define COL 80 +#define ROW 25 +#define CHR 2 +#define MONO_BASE 0x3B4 +#define MONO_BUF 0xB0000 +#define CGA_BASE 0x3D4 +#define CGA_BUF 0xB8000 + +static u_char att = 0x7 ; +u_char *Crtat = (u_char *)CGA_BUF; + +static unsigned int addr_6845 = CGA_BASE; +cursor(pos) +int pos; +{ + outb(addr_6845,14); + outb(addr_6845+1,pos >> 8); + outb(addr_6845,15); + outb(addr_6845+1,pos&0xff); +} + +sput(c) +u_char c; +{ + + static u_char *crtat = 0; + unsigned cursorat; u_short was; + u_char *cp; + + if (crtat == 0) { + + /* XXX probe to find if a color or monochrome display */ + was = *(u_short *)Crtat; + *(u_short *)Crtat = 0xA55A; + if (*(u_short *)Crtat != 0xA55A) { + Crtat = (u_char *) MONO_BUF; + addr_6845 = MONO_BASE; + } + *(u_short *)Crtat = was; + + /* Extract cursor location */ + outb(addr_6845,14); + cursorat = inb(addr_6845+1)<<8 ; + outb(addr_6845,15); + cursorat |= inb(addr_6845+1); + + if(cursorat <= COL*ROW) { + crtat = Crtat + cursorat*CHR; + /* att = crtat[1]; /* use current attribute present */ + } else crtat = Crtat; + + /* clean display */ + for (cp = crtat; cp < Crtat+ROW*COL*CHR; cp += 2) { + cp[0] = ' '; + cp[1] = att; + } + } + + switch (c) { + + case '\t': + do + sput(' '); + while ((int)crtat % (8*CHR)); + break; + + case '\010': + crtat -= CHR; + break; + + case '\r': + crtat -= (crtat - Crtat) % (COL*CHR); + break; + + case '\n': + crtat += COL*CHR ; + break; + + default: + crtat[0] = c; + crtat[1] = att; + crtat += CHR; + break ; + } + +#ifndef SMALL + /* implement a scroll */ + if (crtat >= Crtat+COL*ROW*CHR) { + /* move text up */ + bcopy(Crtat+COL*CHR, Crtat, COL*(ROW-1)*CHR); + + /* clear line */ + for (cp = Crtat+ COL*(ROW-1)*CHR; + cp < Crtat + COL*ROW*CHR ; cp += 2) + cp[0] = ' '; + + crtat -= COL*CHR ; + } +#endif + + cursor((crtat-Crtat)/CHR); +} diff --git a/sys/arch/i386/stand/fd.c b/sys/arch/i386/stand/fd.c new file mode 100644 index 00000000000..d5808d93ee0 --- /dev/null +++ b/sys/arch/i386/stand/fd.c @@ -0,0 +1,376 @@ +/* $NetBSD: fd.c,v 1.3 1994/10/27 04:21:52 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Don Ahn. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + * + * @(#)fd.c 7.3 (Berkeley) 5/25/91 + */ + +/****************************************************************************/ +/* standalone fd driver */ +/****************************************************************************/ +#include "param.h" +#include "disklabel.h" +#include "i386/isa/fdreg.h" +#include "i386/isa/isa.h" +#include "saio.h" + +#define NUMRETRY 10 +/*#define FDDEBUG*/ + +#define NFD 2 +#define FDBLK 512 + +extern struct disklabel disklabel; + +struct fd_type { + int sectrac; /* sectors per track */ + int secsize; /* size code for sectors */ + int datalen; /* data len when secsize = 0 */ + int gap; /* gap len between sectors */ + int tracks; /* total num of tracks */ + int size; /* size of disk in sectors */ + int steptrac; /* steps per cylinder */ + int trans; /* transfer speed code */ +}; + +struct fd_type fd_types[] = { + { 18,2,0xFF,0x1B,80,2880,1,0 }, /* 1.44 meg HD 3.5in floppy */ + { 15,2,0xFF,0x1B,80,2400,1,0 }, /* 1.2 meg HD floppy */ + /* need 720K 3.5in here as well */ +#ifdef noway + { 9,2,0xFF,0x23,40,720,2,1 }, /* 360k floppy in 1.2meg drive */ + { 9,2,0xFF,0x2A,40,720,1,1 }, /* 360k floppy in DD drive */ +#endif +}; + + +/* state needed for current transfer */ +static int probetype; +static int fd_type; +static int fd_motor; +static int fd_retry; +static int fd_drive; +static int fd_status[7]; + +static int fdc = IO_FD1; /* floppy disk base */ + +/* Make sure DMA buffer doesn't cross 64k boundary */ +char bounce[FDBLK]; + + +/****************************************************************************/ +/* fdstrategy */ +/****************************************************************************/ +int +fdstrategy(io,func) +register struct iob *io; +int func; +{ + char *address; + long nblocks,blknum; + int unit, iosize; + +#ifdef FDDEBUG +printf("fdstrat "); +#endif + unit = io->i_unit; + /*fd_type = io->i_part;*/ + + /* + * Set up block calculations. + */ + iosize = io->i_cc / FDBLK; + blknum = (unsigned long) io->i_bn * DEV_BSIZE / FDBLK; + nblocks = fd_types[fd_type].size /* disklabel.d_secperunit */; + if ((blknum + iosize > nblocks) || blknum < 0) { +#ifdef nope + printf("bn = %d; sectors = %d; type = %d; fssize = %d ", + blknum, iosize, fd_type, nblocks); + printf("fdstrategy - I/O out of filesystem boundaries\n"); +#endif + return(-1); + } + + address = io->i_ma; + while (iosize > 0) { +/*printf("iosize %d ", iosize);*/ + if (fdio(func, unit, blknum, address)) + return(-1); + iosize--; + blknum++; + address += FDBLK; + } + return(io->i_cc); +} + +int ccyl = -1; + +int +fdio(func, unit, blknum, address) +int func,unit,blknum; +char *address; +{ + int i,j, cyl, sectrac,sec,head,numretry; + struct fd_type *ft; + +/*printf("fdio ");*/ + ft = &fd_types[fd_type]; + + sectrac = ft->sectrac; + cyl = blknum / (sectrac*2); + numretry = NUMRETRY; + + if (func == F_WRITE) + bcopy(address,bounce,FDBLK); + +retry: + if (ccyl != cyl) { + out_fdc(15); /* Seek function */ + out_fdc(unit); /* Drive number */ + out_fdc(cyl); + + waitio(); + } + + out_fdc(0x8); + i = in_fdc(); j = in_fdc(); + if (!(i&0x20) || (cyl != j)) { + numretry--; + ccyl = j; + if (numretry) goto retry; + + printf("Seek error %d, req = %d, at = %d\n",i,cyl,j); + printf("unit %d, type %d, sectrac %d, blknum %d\n", + unit,fd_type,sectrac,blknum); + + return -1; + } + ccyl = cyl; + + /* set up transfer */ + fd_dma(func == F_READ, bounce, FDBLK); + sec = blknum % (sectrac * 2) /*disklabel.d_secpercyl*/; + head = sec / sectrac; + sec = sec % sectrac + 1; +#ifdef FDDEBUG + printf("sec %d hd %d cyl %d ", sec, head, cyl); +#endif + + if (func == F_READ) out_fdc(0xE6);/* READ */ + else out_fdc(0xC5); /* WRITE */ + out_fdc(head << 2 | fd_drive); /* head & unit */ + out_fdc(cyl); /* track */ + out_fdc(head); + out_fdc(sec); /* sector */ + out_fdc(ft->secsize); /* sector size */ + out_fdc(sectrac); /* sectors/track */ + out_fdc(ft->gap); /* gap size */ + out_fdc(ft->datalen); /* data length */ + + waitio(); + + for(i=0;i<7;i++) { + fd_status[i] = in_fdc(); + } + if (fd_status[0]&0xF8) { + numretry--; + + if (!probetype) + printf("FD err %lx %lx %lx %lx %lx %lx %lx\n", + fd_status[0], fd_status[1], fd_status[2], fd_status[3], + fd_status[4], fd_status[5], fd_status[6] ); + if (numretry) goto retry; + return -1; + } + if (func == F_READ) + bcopy(bounce,address,FDBLK); + return 0; +} + +/****************************************************************************/ +/* fdc in/out */ +/****************************************************************************/ +int +in_fdc() +{ + int i; + while ((i = inb(fdc+fdsts) & 192) != 192) if (i == 128) return -1; + return inb(0x3f5); +} + +dump_stat() +{ + int i; + for(i=0;i<7;i++) { + fd_status[i] = in_fdc(); + if (fd_status[i] < 0) break; + } +#ifdef FDDEBUGx +printf("FD bad status :%lx %lx %lx %lx %lx %lx %lx\n", + fd_status[0], fd_status[1], fd_status[2], fd_status[3], + fd_status[4], fd_status[5], fd_status[6] ); +#endif +} + +set_intr() +{ + /* initialize 8259's */ + outb(0x20,0x11); + outb(0x21,32); + outb(0x21,4); + outb(0x21,1); + outb(0x21,0x0f); /* turn on int 6 */ + +/* + outb(0xa0,0x11); + outb(0xa1,40); + outb(0xa1,2); + outb(0xa1,1); + outb(0xa1,0xff); */ + +} + + + +waitio() +{ +char c; +int n; + + do + outb(0x20,0xc); /* read polled interrupt */ + while ((c=inb(0x20))&0x7f != 6); /* wait for int */ + outb(0x20,0x20); +} + +out_fdc(x) +int x; +{ + int r; + do { + r = (inb(fdc+fdsts) & 192); + if (r==128) break; + if (r==192) { + dump_stat(); /* error: direction. eat up output */ + } + } while (1); + outb(0x3f5,x&0xFF); +} + + +/****************************************************************************/ +/* fdopen/fdclose */ +/****************************************************************************/ +fdopen(io) + register struct iob *io; +{ + int unit, type, i; + struct fd_type *ft; + char buf[512]; + + unit = io->i_unit; + /* type = io->i_part; */ + io->i_boff = 0; /* no disklabels -- tar/dump wont work */ +#ifdef FDDEBUG + printf("fdopen %d %d ", unit, type); +#endif + ft = &fd_types[0]; + fd_drive = unit; + + set_intr(); /* init intr cont */ + + /* Try a reset, keep motor on */ + outb(0x3f2,0); + for(i=0; i < 100000; i++); + outb(0x3f2,unit | (unit ? 32 : 16) ); + for(i=0; i < 100000; i++); + outb(0x3f2,unit | 0xC | (unit ? 32 : 16) ); + outb(0x3f7,ft->trans); + fd_motor = 1; + + waitio(); + + out_fdc(3); /* specify command */ + out_fdc(0xDF); + out_fdc(2); + + out_fdc(7); /* Recalibrate Function */ + out_fdc(unit); + + waitio(); + probetype = 1; + for (fd_type = 0; fd_type < sizeof(fd_types)/sizeof(fd_types[0]); + fd_type++, ft++) { + /*for(i=0; i < 100000; i++); + outb(0x3f7,ft->trans); + for(i=0; i < 100000; i++);*/ + if (fdio(F_READ, unit, ft->sectrac-1, buf) >= 0){ + probetype = 0; + return(0); + } + } + printf("failed fdopen"); + return(-1); +} + + +/****************************************************************************/ +/* fd_dma */ +/* set up DMA read/write operation and virtual address addr for nbytes */ +/****************************************************************************/ +fd_dma(read,addr,nbytes) +int read; +unsigned long addr; +int nbytes; +{ + /* Set read/write bytes */ + if (read) { + outb(0xC,0x46); outb(0xB,0x46); + } else { + outb(0xC,0x4A); outb(0xB,0x4A); + } + /* Send start address */ + outb(0x4,addr & 0xFF); + outb(0x4,(addr>>8) & 0xFF); + outb(0x81,(addr>>16) & 0xFF); + /* Send count */ + nbytes--; + outb(0x5,nbytes & 0xFF); + outb(0x5,(nbytes>>8) & 0xFF); + /* set channel 2 */ + outb(0x0A,2); +} + diff --git a/sys/arch/i386/stand/fdbootblk.c b/sys/arch/i386/stand/fdbootblk.c new file mode 100644 index 00000000000..e0f1fd05077 --- /dev/null +++ b/sys/arch/i386/stand/fdbootblk.c @@ -0,0 +1,300 @@ +/* $NetBSD: fdbootblk.c,v 1.6 1994/10/27 04:21:53 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + * + * @(#)fdbootblk.c 7.2 (Berkeley) 5/4/91 + */ + +/* + * fdbootblk.s: + * Written 10/6/90 by William F. Jolitz + * Initial block boot for AT/386 with typical stupid NEC controller + * + * Goal is to read in sucessive 7.5Kbytes of bootstrap to + * execute. + * + * No attempt is made to handle disk errors. + */ +/*#include "/sys/i386/isa/isa.h" +#include "/sys/i386/isa/fdreg.h"*/ +#define NOP inb $0x84,%al +#define BIOSRELOC 0x7c00 +#define start RELOC+0x400 + + /* mumbo-jumbo to pacify DOS, in the hope of getting diskcopy to work */ + jmp 1f + .asciz "NetBSD " + .byte 1 # sectors per allocation + .word 15 # additional sectors for bootstrap + .word 0 # number of DOS fat sectors + .word 0 # number of DOS rootdir entries + .byte 0xf0 # media descriptor + .word 0 # number of sectors per a DOS fat entry + .word 18 # number of sectors per track + .word 2 # number of heads + .long 0 # number of hidden sectors + .long 2880-18 # logical sectors per volume + .byte 0 # physical drive + .byte 0x29 # ? + .long 137 # binary id + .ascii "Release 0.1" # volume label + .space 5 +1: + /* step 0 force descriptors to bottom of address space */ + + cli + .byte 0xb8,0x30,0x00 /* mov $0x30,%ax */ + mov %ax, %ss + .byte 0xbc,0x00,0x01 /* mov $0x100,%sp */ + + xorl %eax,%eax + movl %ax,%ds + movl %ax,%es + + /* obtain BIOS parameters for hard disk XXX */ + movb $0x9f,%ah /* write to 0x9ff00 XXX */ + movb $0xf0,%al + mov %ax,%es + xor %edi,%edi + + .byte 0xf, 0xb4, 0x36 ; .word 0x41*4 /* lfs 0x41*4, %si */ + xorb %ch,%ch + movb $0x10,%cl + fs + rep + movsb + + .byte 0xf, 0xb4, 0x36 ; .word 0x46*4 /* lfs 0x46*4, %si */ + xorb %ch,%ch + movb $0x10,%cl + fs + rep + movsb + + xorl %eax,%eax + movl %ax,%es + + /* step 1 load new descriptor table */ + + .byte 0x2E,0x0F,1,0x16 /* word aword cs lgdt GDTptr */ + .word BIOSRELOC+0xa4 #GDTptr + + /* step 2 turn on protected mode */ + + smsw %ax + orb $1,%al + lmsw %ax + jmp 1f + nop + + /* step 3 reload segment descriptors */ + + 1: + xorl %eax,%eax + movb $0x10,%al + movl %ax,%ds + movl %ax,%es + movl %ax,%ss + word + ljmp $0x8,$ BIOSRELOC+0xb3 /* would be nice if .-RELOC+0x7c00 worked */ + + /* Global Descriptor Table contains three descriptors: + * 0x00: Null: not used + * 0x08: Code: code segment starts at 0 and extents for 4 gigabytes + * 0x10: Data: data segment starts at 0 and extends for 4 gigabytes + * (overlays code) + */ +GDT: +NullDesc: .word 0,0,0,0 # null descriptor - not used +CodeDesc: .word 0xFFFF # limit at maximum: (bits 15:0) + .byte 0,0,0 # base at 0: (bits 23:0) + .byte 0x9f # present/priv level 0/code/conforming/readable + .byte 0xcf # page granular/default 32-bit/limit(bits 19:16) + .byte 0 # base at 0: (bits 31:24) +DataDesc: .word 0xFFFF # limit at maximum: (bits 15:0) + .byte 0,0,0 # base at 0: (bits 23:0) + .byte 0x93 # present/priv level 0/data/expand-up/writeable + .byte 0xcf # page granular/default 32-bit/limit(bits 19:16) + .byte 0 # base at 0: (bits 31:24) + +/* Global Descriptor Table pointer + * contains 6-byte pointer information for LGDT + */ +GDTptr: .word 0x17 # limit to three 8 byte selectors(null,code,data) + .long BIOSRELOC+0x8c # GDT -- arrgh, gas again! +readcmd: .byte 0xe6,0,0,0,0,2,18,0x1b,0xff + + /* step 4 relocate to final bootstrap address. */ +reloc: + movl $ BIOSRELOC,%esi + movl $ RELOC,%edi + movl $512,%ecx + rep + movsb + movl $0xa0000, %esp + pushl $dodisk + ret + + /* step 5 load remaining 15 sectors off disk */ +dodisk: + movl $ RELOC+0x200, %edi + xorl %ebx, %ebx + incb %bl # shl $1,%bl + incb %bl + movb $0x20,%al # do a eoi + outb %al,$0x20 + + NOP + movb $0xbf,%al # enable floppy interrupt, mask out rest + outb %al,$0x21 + NOP + 8: + movb %bl,readcmd+4 + movl %edi,%ecx + + /* Set read/write bytes */ + xorl %edx,%edx + movb $0x0c,%dl # outb(0xC,junk); outb(0xB,0x46); + outb %al,%dx # reset DMA controller first/last flip-flop + NOP + decb %dx + movb $0x46,%al # single mode, write mem, chan 2 + outb %al,%dx # output DMA controller mode byte + + /* Send start address */ + movb $0x04,%dl # outb(0x4, addr); + movb %cl,%al + outb %al,%dx + NOP + movb %ch,%al # outb(0x4, addr>>8); + outb %al,%dx + NOP + rorl $8,%ecx # outb(0x81, addr>>16); + movb %ch,%al + outb %al,$0x81 + NOP + + /* Send count */ + movb $0x05,%dl # outb(0x5, 0); + xorl %eax,%eax + outb %al,%dx + NOP + movb $2,%al # outb(0x5,2); + outb %al,%dx + NOP + + /* set channel 2 */ + movb $2,%al # outb(0x0A,2); + outb %al,$0x0A + NOP + + /* issue read command to fdc */ + movw $0x3f4,%dx + movl $readcmd,%esi + xorl %ecx,%ecx + movb $9,%cl + + 2: NOP + inb %dx,%al + testb $0x80,%al + jz 2b + + incb %dx + NOP + movl (%esi),%al + outb %al,%dx + NOP + incl %esi + decb %dx + loop 2b + + /* watch the icu looking for an interrupt signalling completion */ + xorl %edx,%edx + movb $0x20,%dl + 2: + NOP + movb $0xc,%al + outb %al,%dx + NOP + inb %dx,%al + andb $0x7f,%al + cmpb $6,%al + jne 2b + NOP + movb $0x20,%al # do a eoi + outb %al,%dx + NOP + + movl $0x3f4,%edx + xorl %ecx,%ecx + movb $7,%cl + 2: + NOP + inb %dx,%al + andb $0xC0,%al + cmpb $0xc0,%al + jne 2b + incb %dx + inb %dx,%al + decb %dx + loop 2b + + /* extract the status bytes after the read. must we do this? */ + addw $0x200,%edi # next addr to load to + incb %bl + cmpb $15,%bl + jle 8b + + /* for clever bootstrap, dig out boot unit and cylinder */ + pushl $0 + pushl $0 + + /* fd controller is major device 2 */ + pushl $2 /* dev */ + + /* sorry, no flags at this point! */ + + movl $ start, %eax + call %eax /* main (dev, unit, off) */ + +ebootblkcode: + + /* remaining space usable for a disk label */ + + .org 0x1fe + .word 0xaa55 /* signature -- used by BIOS ROM */ + +ebootblk: /* MUST BE EXACTLY 0x200 BIG FOR SURE */ diff --git a/sys/arch/i386/stand/fs.c b/sys/arch/i386/stand/fs.c new file mode 100644 index 00000000000..bb964d93130 --- /dev/null +++ b/sys/arch/i386/stand/fs.c @@ -0,0 +1,161 @@ +/* $NetBSD: fs.c,v 1.3 1994/10/27 04:21:54 cgd Exp $ */ + +/* + * Copyright (c) 1992 William F. Jolitz, TeleMuse + * 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 software is a component of "386BSD" developed by + William F. Jolitz, TeleMuse. + * 4. Neither the name of the developer nor the name "386BSD" + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ + * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS + * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT. + * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT + * NOT MAKE USE THIS WORK. + * + * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED + * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN + * REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES + * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING + * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND + * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE + * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS + * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPER 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. + * + * Routines to sift through a BSD fast filesystem. -wfj + */ + +#include "param.h" +#include "fs.h" +#include "dir.h" +#include "dinode.h" +#include "saio.h" + +int bdev; +char superb[SBSIZE], abuf[MAXBSIZE]; +struct fs *fs; + +/* + * Translate name to inode number. + */ +namei(s) char *s; { + int ino; + struct dinode rd; +/*printf("namei %s\n", s);*/ + + if (!fs) { + bread(bdev, SBOFF/DEV_BSIZE, superb, SBSIZE); + fs = (struct fs *)superb; + } + fetchi(2, &rd); + return(ilookup(&rd, s)); +} + +/* + * look for a file in this inode. + */ +ilookup(dip, s) struct dinode *dip; char *s; { + struct direct dirent; + int off; + +/*printf("ilookup %x %s %d\n", dip, s, dip->di_size);*/ + off = 0; + do { + iread(dip, off, (char *)&dirent, sizeof(struct direct)); + off += dirent.d_reclen; +/*printf("%s ", dirent.d_name);*/ + if (strcmp (dirent.d_name, s) == 0) + return (dirent.d_ino); + } while (off < dip->di_size && dirent.d_reclen); + return (0); +} + +/* + * Extract an inode and return it. + */ +fetchi(i, dip) struct dinode *dip; { + +/*printf("fetchi %d %x\n", i, dip);*/ + bread(bdev, fsbtodb(fs, itod(fs, i)), abuf, fs->fs_bsize); + bcopy (abuf + itoo(fs,i) * sizeof(struct dinode), + dip, sizeof(struct dinode)); + /*printf("mode %o link %d uid %d gid %d size %d [ ", + dip->di_mode, dip->di_nlink, dip->di_uid, dip->di_gid, dip->di_size); + for (i=0; i < NDADDR; i++) + printf("%d ", dip->di_db[i]); + printf("] ("); + for (i=0; i < NIADDR; i++) + printf("%d ", dip->di_ib[i]); + printf(")\n");*/ +} + +/* + * Read data contents of an inode + */ +iread(dip, off, p, sz) + struct dinode *dip; + char *p; +{ + daddr_t physblock; + int va = sz; + char *op, *pp; + +/*printf("iread %x %d %x %d\n", dip, off, p, sz);*/ + while (sz > 0) { + int lbn, bs, o; + + lbn = lblkno(fs, off); + bs = dblksize(fs, dip, lbn); + o = blkoff(fs, off); + + /* logical to physical translation */ + bmap(dip, lbn, &physblock); + + /* if sz larger than blksize, i/o direct, + otherwise to local buffer */ + if (o == 0 && bs <= sz) + bread(bdev, physblock, p, bs); + else { + bread(bdev, physblock, abuf, bs); + bs -= o; + bs = bs > sz ? sz : bs; + bcopy(abuf + o, p, bs); + } +/*printf("bs %d sz %d", bs, sz);*/ + sz -= bs; + p += bs; + off += bs; + if (bs==0) break; + } + return(va); +} + +_stop(s) { + printf("Failed:%s\n", s); + exit(0); +} diff --git a/sys/arch/i386/stand/kbd.c b/sys/arch/i386/stand/kbd.c new file mode 100644 index 00000000000..134bd889f4a --- /dev/null +++ b/sys/arch/i386/stand/kbd.c @@ -0,0 +1,269 @@ +/* $NetBSD: kbd.c,v 1.3 1994/10/27 04:21:56 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + * + * @(#)kbd.c 7.4 (Berkeley) 5/4/91 + */ + +#define L 0x01 /* locking function */ +#define SHF 0x02 /* keyboard shift */ +#define ALT 0x04 /* alternate shift -- alternate chars */ +#define NUM 0x08 /* numeric shift cursors vs. numeric */ +#define CTL 0x10 /* control shift -- allows ctl function */ +#define CPS 0x20 /* caps shift -- swaps case of letter */ +#define ASCII 0x40 /* ascii code for this key */ +#define STP 0x80 /* stop output */ + +typedef unsigned char u_char; + +u_char inb(); + +#ifdef notdef +u_char action[] = { +0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */ +ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */ +ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */ +ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */ +ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */ +ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */ +ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */ + ALT, ASCII, CPS|L, 0, 0, ASCII, 0, 0, /* scan 56-63 */ + 0, 0, 0, 0, 0, NUM|L, STP|L, ASCII, /* scan 64-71 */ +ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */ +ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; + +u_char unshift[] = { /* no shift */ +0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */ +'7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */ + +'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */ +'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */ + +'d' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */ +'\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */ + +'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */ +ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ + + 0, 0, 0, 0, 0, NUM|L, STP|L, '7', /* scan 64-71 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ + + '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; + +u_char shift[] = { /* shift shift */ +0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */ +'&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */ +'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */ +'O' , 'P' , '[' , ']' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */ +'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */ +'"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */ +'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ +ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ + 0, 0, 0, 0, 0, NUM|L, STP|L, '7', /* scan 64-71 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ + '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; + +u_char ctl[] = { /* CTL shift */ +0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */ +'&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */ +021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */ +017 , 020 , 033 , 035 , '\r' , CTL , 001 , 013 , /* scan 24-31 */ +004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */ +'\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */ +002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ +ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ +CPS|L, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */ + 0, 0, 033, '7' , '4' , '1' , 0, NUM|L, /* scan 88-95 */ +'8' , '5' , '2' , 0, STP|L, '9' , '6' , '3' , /*scan 96-103*/ +'.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/ +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; + +#ifdef notdef +struct key { + u_short action; /* how this key functions */ + char ascii[8]; /* ascii result character indexed by shifts */ +}; +#endif + +u_char shfts, ctls, alts, caps, num, stp; +#endif + +#define KBSTATP 0x64 /* kbd status port */ +#define KBS_INP_BUF_FUL 0x02 /* kbd char ready */ +#define KBDATAP 0x60 /* kbd data port */ +#define KBSTATUSPORT 0x61 /* kbd status */ + +u_char odt, bdt; + +u_char kbd() { + u_char dt, brk, act; + +loop: + while(inb(0x64)&1 == 0); + dt = inb(0x60); + do { + while(inb(0x64)&1 == 0); + } while(dt == inb(0x60)); + odt = dt; + + brk = dt & 0x80 ; dt = dt & 0x7f ; + +#ifdef notdef + act = action[dt]; + if (act&SHF) { + if(brk) shfts = 0; else shfts = 1; + } + if (act&ALT) { + if(brk) alts = 0; else alts = 1; + } + if (act&NUM) { + if (act&L) { + if(!brk) num ^= 1; + } else if(brk) num = 0; else num = 1; + } + if (act&CTL) { + if(brk) ctls = 0; else ctls = 1; + } + if (act&CPS) { + if (act&L) { + if(!brk) caps ^= 1; + } else if(brk) caps = 0; else caps = 1; + } + if (act&STP) { + if (act&L) { + if(!brk) stp ^= 1; + } else if(brk) stp = 0; else stp = 1; + } + if(ctls && alts && dt == 83) exit(); + if ((act&ASCII) && !brk) { + u_char chr; + + if (shfts){ + chr = shift[dt] ; } else { + if (ctls) { + chr = ctl[dt] ; } else { + chr = unshift[dt] ; } } + if (caps && (chr >= 'a' && chr <= 'z')) { + chr -= 'a' - 'A' ; + } + /*do + while(inb(0x64)&1 == 0) ; + while (inb(0x60) == (chr | 0x80)); + while(inb(0x64)&1 == 1) inb(0x60);A*/ + return(chr); + } +#else + if (brk) + return(1); +#endif + goto loop; +} + +scankbd() { +u_char c; + +#ifdef notdef + c = inb(0x60); + if (c == 83) exit(); + /*if (c == 0xaa) return (0); + if (c == 0xfa) return (0);*/ + + if (bdt == 0) { bdt = c&0x7f; return(0); } + + if(odt) return(1); + + c &= 0x7f; + + if (bdt == c) return(0); + odt = c; +#endif + return(1); +} + +kbdreset() +{ + u_char c; + + /* Enable interrupts and keyboard controller */ + while (inb(0x64)&2); outb(0x64,0x60); + while (inb(0x64)&2); outb(0x60,0x4D); + + /* Start keyboard stuff RESET */ + while (inb(0x64)&2); /* wait input ready */ + outb(0x60,0xFF); /* RESET */ + + while((c=inb(0x60))!=0xFA) ; + + /* While we are here, defeat gatea20 */ + while (inb(0x64)&2); /* wait input ready */ + outb(0x64,0xd1); + while (inb(0x64)&2); /* wait input ready */ + outb(0x60,0xdf); + while (inb(0x64)&2); /* wait input ready */ + odt = bdt = 0; + inb(0x60); +} + +#ifdef notdef; +u_char getchar() { + u_char c; + + c = kbd(); + if (c == '\b' || c == '\177') return(c); + if (c == '\r') c = '\n'; + putchar(c); + return(c); +} +#endif + +reset_cpu() { + + while (inb(0x64)&2); /* wait input ready */ + outb(0x64,0xFE); /* Reset Command */ + wait(4000000); + /* NOTREACHED */ +} diff --git a/sys/arch/i386/stand/prf.c b/sys/arch/i386/stand/prf.c new file mode 100644 index 00000000000..4a06fc56e67 --- /dev/null +++ b/sys/arch/i386/stand/prf.c @@ -0,0 +1,57 @@ +/* $NetBSD: prf.c,v 1.3 1994/10/27 04:21:57 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + * + * @(#)prf.c 7.4 (Berkeley) 5/4/91 + */ + +#include "types.h" + +putchar(c) +char c; +{ + if (c == '\n') + sput('\r'); + sput(c); + return(0); +} + +wait(n) { + int v; + + while(n-- && (v = scankbd()) == 0); + if (v) kbdreset(); +} diff --git a/sys/arch/i386/stand/saio.h b/sys/arch/i386/stand/saio.h new file mode 100644 index 00000000000..0bc793dd0d3 --- /dev/null +++ b/sys/arch/i386/stand/saio.h @@ -0,0 +1,71 @@ +/* $NetBSD: saio.h,v 1.3 1994/10/27 04:21:58 cgd Exp $ */ + +/* + * Copyright (c) 1989, 1990, 1991, 1992 William F. Jolitz, TeleMuse + * 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 software is a component of "386BSD" developed by + William F. Jolitz, TeleMuse. + * 4. Neither the name of the developer nor the name "386BSD" + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ + * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS + * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT. + * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT + * NOT MAKE USE THIS WORK. + * + * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED + * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN + * REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES + * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING + * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND + * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE + * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS + * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPER 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. + * + * I/O interface to driver. + */ + +/* + */ +struct iob { + int i_dev; + int i_adapt; + int i_ctlr; + int i_part; + int i_unit; + int i_cc; + int i_bn; + int i_ma; + int i_boff; + int i_flgs; +#define F_WRITE 0x1 +#define F_FILE 0x2 +#define F_READ 0x4 +}; + +#define BBSIZE 8192 diff --git a/sys/arch/i386/stand/srt0.c b/sys/arch/i386/stand/srt0.c new file mode 100644 index 00000000000..b5cf9247393 --- /dev/null +++ b/sys/arch/i386/stand/srt0.c @@ -0,0 +1,275 @@ +/* $NetBSD: srt0.c,v 1.3 1994/10/27 04:21:59 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + * + * @(#)srt0.c 5.3 (Berkeley) 4/28/91 + */ + +/* + * Startup code for standalone system + * Non-relocating version -- for programs which are loaded by boot + * Relocating version for boot + * Small relocating version for "micro" boot + */ + + .globl _end + .globl _edata + .globl _main + .globl __rtt + .globl _exit + .globl _bootdev + .globl _cyloffset +#define NOP inb $0x84,%al ; inb $0x84,%al + +#ifdef SMALL + /* where the disklabel goes if we have one */ + .globl _disklabel +_disklabel: + .space 512 + .globl _scsisn + .set _scsisn, RELOC+0x60 +#endif + + .globl entry + .set entry,0 + .globl start + +#if defined(REL) && !defined(SMALL) + + /* relocate program and enter at symbol "start" */ + + #movl $entry-RELOC,%esi # from beginning of ram + movl $0,%esi + #movl $entry,%edi # to relocated area + movl $ RELOC,%edi # to relocated area + # movl $_edata-RELOC,%ecx # this much + movl $64*1024,%ecx + cld + rep + movsb + # relocate program counter to relocation base + pushl $start + ret +#endif + +start: + + /* setup stack pointer */ + +#ifdef REL + leal 4(%esp),%eax /* ignore old pc */ + movl $ RELOC-3*4,%ebx + /* copy boot parameters */ + pushl $3*4 + pushl %ebx + pushl %eax + call _bcopy + movl %ebx,%esp +#else + /* save old stack state */ + movl %esp,savearea + movl %ebp,savearea+4 + movl $ RELOC-0x2400,%esp +#endif + + /* clear memory as needed */ + + movl %esp,%esi +#ifdef REL + + /* + * Clear Bss and up to 64K heap + */ + movl $64*1024,%ebx + movl $_end,%eax # should be movl $_end-_edata but ... + subl $_edata,%eax + #addl %ebx,%eax + pushl %eax + pushl $_edata + call _bzero + + /* + * Clear 64K of stack + */ + movl %esi,%eax + subl %ebx,%eax + subl $5*4,%ebx + pushl %ebx + pushl %eax + call _bzero +#else + movl $_edata,%edx + movl %esp,%eax + subl %edx,%eax + pushl %edx + pushl %esp + call _bzero +#endif + + call _kbdreset /* resets keyboard and gatea20 brain damage */ + movl %esi,%esp + call _main + jmp 1f + + .data +_bootdev: .long 0 +_cyloffset: .long 0 +savearea: .long 0,0 # sp & bp to return to + .text + .globl _wait + +__rtt: + pushl $1000000 + call _wait + popl %eax + movl $-7,%eax + jmp 1f + +_exit: + pushl $1000000 + call _wait + popl %eax + movl 4(%esp),%eax +1: +#ifdef REL +#ifndef SMALL + call _reset_cpu +#endif + movw $0x1234,%ax + movw %ax,0x472 # warm boot + movl $0,%esp # segment violation + ret +#else + movl savearea,%esp + movl savearea+4,%ebp + ret +#endif + + .globl _inb +_inb: movl 4(%esp),%edx + subl %eax,%eax # clr eax + NOP + inb %dx,%al + ret + + .globl _outb +_outb: movl 4(%esp),%edx + NOP + movl 8(%esp),%eax + outb %al,%dx + ret + + .globl ___udivsi3 +___udivsi3: + movl 4(%esp),%eax + xorl %edx,%edx + divl 8(%esp) + ret + + .globl ___divsi3 +___divsi3: + movl 4(%esp),%eax + xorl %edx,%edx + cltd + idivl 8(%esp) + ret + + # + # bzero (base,cnt) + # + + .globl _bzero +_bzero: + pushl %edi + movl 8(%esp),%edi + movl 12(%esp),%ecx + movb $0x00,%al + cld + rep + stosb + popl %edi + ret + + # + # bcopy (src,dst,cnt) + # NOTE: does not (yet) handle overlapped copies + # + + .globl _bcopy +_bcopy: + pushl %esi + pushl %edi + movl 12(%esp),%esi + movl 16(%esp),%edi + movl 20(%esp),%ecx + cld + rep + movsb + popl %edi + popl %esi + ret + + # insw(port,addr,cnt) + .globl _insw +_insw: + pushl %edi + movw 8(%esp),%dx + movl 12(%esp),%edi + movl 16(%esp),%ecx + NOP + cld + nop + .byte 0x66,0xf2,0x6d # rep insw + nop + movl %edi,%eax + popl %edi + ret + + # outsw(port,addr,cnt) + .globl _outsw +_outsw: + pushl %esi + movw 8(%esp),%dx + movl 12(%esp),%esi + movl 16(%esp),%ecx + NOP + cld + nop + .byte 0x66,0xf2,0x6f # rep outsw + nop + movl %esi,%eax + popl %esi + ret diff --git a/sys/arch/i386/stand/trimhd.c b/sys/arch/i386/stand/trimhd.c new file mode 100644 index 00000000000..1480f98d004 --- /dev/null +++ b/sys/arch/i386/stand/trimhd.c @@ -0,0 +1,70 @@ +/* $NetBSD: trimhd.c,v 1.3 1994/10/27 04:22:00 cgd Exp $ */ + +/* + * Copyright (c) 1989, 1990, 1991, 1992 William F. Jolitz, TeleMuse + * 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 software is a component of "386BSD" developed by + William F. Jolitz, TeleMuse. + * 4. Neither the name of the developer nor the name "386BSD" + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ + * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS + * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT. + * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT + * NOT MAKE USE THIS WORK. + * + * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED + * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN + * REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES + * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING + * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND + * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE + * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS + * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPER 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. + * + * Trim off the start of a file. + */ + +main(argc, argv) char *argv[]; { + int val, rv, buf; + + if (argc != 2) return(1); + if ((val = atoi(argv[1]))<= 0) return(1); + + buf = malloc(1024); + read (0, buf, val); + do { + rv = read (0, buf, 1024); + if (rv > 0) + rv = write(1, buf, rv); + } while (rv == 1024); + if(rv > 0) + return (0); + else + return (1); +} diff --git a/sys/arch/i386/stand/wd.c b/sys/arch/i386/stand/wd.c new file mode 100644 index 00000000000..ce9540c47f0 --- /dev/null +++ b/sys/arch/i386/stand/wd.c @@ -0,0 +1,434 @@ +/* $NetBSD: wd.c,v 1.4 1994/10/27 04:22:01 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + * + * @(#)wd.c 7.3 (Berkeley) 5/4/91 + */ + +/* device driver for winchester disk */ + +#include "param.h" +#include "dkbad.h" +#include "disklabel.h" +#include "i386/isa/isa.h" +#include "i386/isa/wdreg.h" +#include "saio.h" + +#define SMALL +#define NWD 1 /* number of hard disk units supported, max 2 */ +#define RETRIES 5 /* number of retries before giving up */ + +int noretries, wdquiet; +/* #define WDDEBUG*/ + +#ifdef SMALL +extern struct disklabel disklabel; +#else +struct disklabel wdsizes[NWD]; +#endif + +extern cyloffset ; /* bootstrap's idea of cylinder for disklabel */ + +/* + * Record for the bad block forwarding code. + * This is initialized to be empty until the bad-sector table + * is read from the disk. + */ +#define TRKSEC(trk,sec) ((trk << 8) + sec) + +struct dkbad dkbad[NWD]; +static wdcport; + +wdopen(io) + register struct iob *io; +{ + register struct disklabel *dd; + +#ifdef WDDEBUG + printf("wdopen "); +#endif +#ifdef SMALL + dd = &disklabel; +#else + dd = &wdsizes[io->i_unit]; + if (io->i_part > 8) + _stop("Invalid partition number"); + if(io->i_ctlr > 1) + _stop("Invalid controller number"); +#endif + if (wdinit(io)) + _stop("wd initialization error"); + io->i_boff = dd->d_partitions[io->i_part].p_offset ; +/*printf("boff %d ", io->i_boff);*/ + return(0); +} + +wdstrategy(io,func) + register struct iob *io; +{ + register int iosize; /* number of sectors to do IO for this loop */ + register daddr_t sector; + int nblocks, cyloff; + int unit, partition; + char *address; + register struct disklabel *dd; + + unit = io->i_unit; + partition = io->i_part; +#ifdef WDDEBUG + printf("wdstrat %d %d ", unit, partition); +#endif +#ifdef SMALL + dd = &disklabel; +#else + dd = &wdsizes[unit]; +#endif + iosize = io->i_cc / dd->d_secsize; + /* + * Convert PGSIZE "blocks" to sectors. + * Note: doing the conversions this way limits the partition size + * to about 8 million sectors (1-8 Gb). + */ +/*printf("bn%d ", io->i_bn);*/ + sector = (unsigned long) io->i_bn * DEV_BSIZE / dd->d_secsize; + nblocks = dd->d_partitions[partition].p_size; +#ifndef SMALL + if (iosize < 0 || sector + iosize > nblocks || sector < 0) { +#ifdef WDDEBUG + printf("bn = %d; sectors = %d; partition = %d; fssize = %d\n", + io->i_bn, iosize, partition, nblocks); +#endif + printf("wdstrategy - I/O out of filesystem boundaries\n"); + return(-1); + } + if (io->i_bn * DEV_BSIZE % dd->d_secsize) { + printf("wdstrategy - transfer starts in midsector\n"); + return(-1); + } + if (io->i_cc % dd->d_secsize) { + printf("wd: transfer of partial sector\n"); + return(-1); + } +#endif + sector += io->i_boff; + + address = io->i_ma; + while (iosize > 0) { + if (wdio(func, unit, sector, address)) + return(-1); + iosize--; + sector++; + address += dd->d_secsize; + } + return(io->i_cc); +} + +/* + * Routine to do a one-sector I/O operation, and wait for it + * to complete. + */ +wdio(func, unit, blknm, addr) + short *addr; +{ + struct disklabel *dd; + register wdc = wdcport; + struct bt_bad *bt_ptr; + int i; + int retries = 0; + long cylin, head, sector; + u_char opcode, erro; + +#ifdef SMALL + dd = &disklabel; +#else + dd = &wdsizes[unit]; +#endif + if (func == F_WRITE) + opcode = WDCC_WRITE; + else + opcode = WDCC_READ; + + /* Calculate data for output. */ + cylin = blknm / dd->d_secpercyl; + head = (blknm % dd->d_secpercyl) / dd->d_nsectors; + sector = blknm % dd->d_nsectors; + + /* + * See if the current block is in the bad block list. + */ + if (blknm > BBSIZE/DEV_BSIZE) /* should be BBSIZE */ + for (bt_ptr = dkbad[unit].bt_bad; bt_ptr->bt_cyl != -1; bt_ptr++) { + if (bt_ptr->bt_cyl > cylin) + /* Sorted list, and we passed our cylinder. quit. */ + break; + if (bt_ptr->bt_cyl == cylin && + bt_ptr->bt_trksec == (head << 8) + sector) { + /* + * Found bad block. Calculate new block addr. + * This starts at the end of the disk (skip the + * last track which is used for the bad block list), + * and works backwards to the front of the disk. + */ +#ifdef WDDEBUG + printf("--- badblock code -> Old = %d; ", + blknm); +#endif + printf("--- badblock code -> Old = %d; ", + blknm); + blknm = dd->d_secperunit - dd->d_nsectors + - (bt_ptr - dkbad[unit].bt_bad) - 1; + cylin = blknm / dd->d_secpercyl; + head = (blknm % dd->d_secpercyl) / dd->d_nsectors; + sector = blknm % dd->d_nsectors; +#ifdef WDDEBUG + printf("new = %d\n", blknm); +#endif + break; + } + } + + sector += 1; +retry: +#ifdef WDDEBUG + printf("sec %d sdh %x cylin %d ", sector, + WDSD_IBM | (unit<<4) | (head & 0xf), cylin); +#endif +/*printf("c %d h %d s %d ", cylin, head, sector);*/ + outb(wdc+wd_precomp, 0xff); + outb(wdc+wd_seccnt, 1); + outb(wdc+wd_sector, sector); + outb(wdc+wd_cyl_lo, cylin); + outb(wdc+wd_cyl_hi, cylin >> 8); + + /* Set up the SDH register (select drive). */ + outb(wdc+wd_sdh, WDSD_IBM | (unit<<4) | (head & 0xf)); + while ((inb(wdc+wd_status) & WDCS_READY) == 0) ; + + outb(wdc+wd_command, opcode); + while (opcode == WDCC_READ && (inb(wdc+wd_status) & WDCS_BUSY)) + ; + /* Did we get an error? */ + if (opcode == WDCC_READ && (inb(wdc+wd_status) & WDCS_ERR)) + goto error; + + /* Ready to remove data? */ + while ((inb(wdc+wd_status) & WDCS_DRQ) == 0) ; + + if (opcode == WDCC_READ) + insw(wdc+wd_data,addr,256); + else outsw(wdc+wd_data,addr,256); + + /* Check data request (should be done). */ + if (inb(wdc+wd_status) & WDCS_DRQ) goto error; + + while (opcode == WDCC_WRITE && (inb(wdc+wd_status) & WDCS_BUSY)) ; + + if (inb(wdc+wd_status) & WDCS_ERR) goto error; + +#ifdef WDDEBUG +printf("addr %x",addr); +#endif + return (0); +error: + erro = inb(wdc+wd_error); + if (++retries < RETRIES) + goto retry; + if (!wdquiet) + printf("wd%d: hard %s error: sector %d status %b error %b\n", unit, + opcode == WDCC_READ? "read" : "write", blknm, + inb(wdc+wd_status), WDCS_BITS, erro, WDERR_BITS); + return (-1); +} + +wdinit(io) + struct iob *io; +{ + register wdc; + struct disklabel *dd; + unsigned int unit; + struct dkbad *db; + int i, errcnt = 0; + char buf[512]; + static open[NWD]; + + unit = io->i_unit; + if (open[unit]) return(0); + + wdcport = io->i_ctlr ? IO_WD2 : IO_WD1; + wdc = wdcport; + +#ifdef SMALL + dd = &disklabel; +#else + dd = &wdsizes[unit]; +#endif + + /* reset controller */ + outb(wdc+wd_ctlr,6); + DELAY(1000); + outb(wdc+wd_ctlr,2); + DELAY(1000); + while(inb(wdc+wd_status) & WDCS_BUSY); /* 06 Sep 92*/ + outb(wdc+wd_ctlr,8); + + /* set SDH, step rate, do restore to recalibrate drive */ +tryagainrecal: + outb(wdc+wd_sdh, WDSD_IBM | (unit << 4)); + wdwait(); + outb(wdc+wd_command, WDCC_RESTORE | WD_STEP); + wdwait(); + if ((i = inb(wdc+wd_status)) & WDCS_ERR) { + printf("wd%d: recal status %b error %b\n", + unit, i, WDCS_BITS, inb(wdc+wd_error), WDERR_BITS); + if (++errcnt < 10) + goto tryagainrecal; + return(-1); + } + +#ifndef SMALL + /* + * Some controllers require this (after a recal they + * revert to a logical translation mode to compensate for + * dos limitation on 10-bit cylinders -- *shudder* -wfj) + * note: heads *must* be fewer than or equal to 8 to + * compensate for some IDE drives that latch this for all time. + */ + outb(wdc+wd_sdh, WDSD_IBM | (unit << 4) + 8 -1); + outb(wdc+wd_seccnt, 35 ); + outb(wdc+wd_cyl_lo, 1224); + outb(wdc+wd_cyl_hi, 1224/256); + outb(wdc+wd_command, 0x91); + while (inb(wdc+wd_status) & WDCS_BUSY) ; + + errcnt = 0; +retry: + /* + * Read in LABELSECTOR to get the pack label and geometry. + */ + outb(wdc+wd_precomp, 0xff); /* sometimes this is head bit 3 */ + outb(wdc+wd_seccnt, 1); + outb(wdc+wd_sector, LABELSECTOR + 1); + outb(wdc+wd_cyl_lo, (cyloffset & 0xff)); + outb(wdc+wd_cyl_hi, (cyloffset >> 8)); + outb(wdc+wd_sdh, WDSD_IBM | (unit << 4)); + wdwait(); + outb(wdc+wd_command, WDCC_READ); + wdwait(); + if ((i = inb(wdc+wd_status)) & WDCS_ERR) { + int err; + + err = inb(wdc+wd_error); + if (++errcnt < RETRIES) + goto retry; + if (!wdquiet) + printf("wd%d: reading label, status %b error %b\n", + unit, i, WDCS_BITS, err, WDERR_BITS); + return(-1); + } + + /* Ready to remove data? */ + while ((inb(wdc+wd_status) & WDCS_DRQ) == 0) ; + + i = insw(wdc+wd_data, buf, 256); + +#ifdef WDDEBUG + printf("magic %x,insw %x, %x\n", + ((struct disklabel *) (buf + LABELOFFSET))->d_magic, i, buf); +#endif + if (((struct disklabel *) (buf + LABELOFFSET))->d_magic == DISKMAGIC) { + *dd = * (struct disklabel *) (buf + LABELOFFSET); + open[unit] = 1; + } else { + if (!wdquiet) + printf("wd%d: bad disk label\n", unit); + if (io->i_flgs & F_FILE) return(-1); + dkbad[unit].bt_bad[0].bt_cyl = -1; + dd->d_secpercyl = 1999999 ; dd->d_nsectors = 17 ; + dd->d_secsize = 512; + outb(wdc+wd_precomp, 0xff); /* force head 3 bit off */ + return (0) ; + } +#ifdef WDDEBUG + printf("magic %x sect %d\n", dd->d_magic, dd->d_nsectors); +#endif +#endif !SMALL + +/*printf("C%dH%dS%d ", dd->d_ncylinders, dd->d_ntracks, dd->d_nsectors);*/ + + /* now that we know the disk geometry, tell the controller */ + outb(wdc+wd_cyl_lo, dd->d_ncylinders+1); + outb(wdc+wd_cyl_hi, (dd->d_ncylinders+1)>>8); + outb(wdc+wd_sdh, WDSD_IBM | (unit << 4) + dd->d_ntracks-1); + outb(wdc+wd_seccnt, dd->d_nsectors); + outb(wdc+wd_command, 0x91); + while (inb(wdc+wd_status) & WDCS_BUSY) ; + + dkbad[unit].bt_bad[0].bt_cyl = -1; + + if (dd->d_flags & D_BADSECT) { + /* + * Read bad sector table into memory. + */ + i = 0; + do { + int blknm = dd->d_secperunit - dd->d_nsectors + i; + errcnt = wdio(F_READ, unit, blknm, buf); + } while (errcnt && (i += 2) < 10 && i < dd->d_nsectors); + db = (struct dkbad *)(buf); +#define DKBAD_MAGIC 0x4321 + if (errcnt == 0 && db->bt_mbz == 0 && db->bt_flag == DKBAD_MAGIC) + dkbad[unit] = *db; + else { + if (!wdquiet) + printf("wd%d: error in bad-sector file\n", unit); + dkbad[unit].bt_bad[0].bt_cyl = -1; + } + } + return(0); +} + +wdwait() +{ + register wdc = wdcport; + register i = 0; + + while (inb(wdc+wd_status) & WDCS_BUSY) + ; + while ((inb(wdc+wd_status) & WDCS_READY) == 0) + if (i++ > 100000) + return(-1); + return(0); +} diff --git a/sys/arch/i386/stand/wdbootblk.c b/sys/arch/i386/stand/wdbootblk.c new file mode 100644 index 00000000000..a196d330e25 --- /dev/null +++ b/sys/arch/i386/stand/wdbootblk.c @@ -0,0 +1,233 @@ +/* $NetBSD: wdbootblk.c,v 1.3 1994/10/27 04:22:02 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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. + * + * @(#)wdbootblk.c 7.1 (Berkeley) 4/28/91 + */ + +/* + * wdbootblk.s: + * Written 7/6/90 by William F. Jolitz + * Initial block boot for AT/386 with typical Western Digital + * WD 1002-WA2 (or upwards compatable). Works either as + * first and sole partition bootstrap, or as loaded by a + * earlier BIOS boot when on an inner partition of the disk. + * + * Goal is to read in sucessive 7.5Kbytes of bootstrap to + * execute. + * + * No attempt is made to handle disk errors. + */ +#include "i386/isa/isa.h" +#include "i386/isa/wdreg.h" +#define NOP inb $0x84,%al +#define BIOSRELOC 0x7c00 +#define start RELOC+0x400 + + /* step 0 force descriptors to bottom of address space */ + + cli + .byte 0xb8,0x30,0x00 /* mov $0x30,%ax */ + mov %ax, %ss + .byte 0xbc,0x00,0x01 /* mov $0x100,%sp */ + + xorl %eax,%eax + movl %ax,%ds + movl %ax,%es + + /* obtain BIOS parameters for hard disk XXX */ + movb $0x9f,%ah /* write to 0x9ff00 XXX */ + movb $0xf0,%al + mov %ax,%es + xor %edi,%edi + + .byte 0xf, 0xb4, 0x36 ; .word 0x41*4 /* lfs 0x41*4, %si */ + xorb %ch,%ch + movb $0x10,%cl + fs + rep + movsb + + .byte 0xf, 0xb4, 0x36 ; .word 0x46*4 /* lfs 0x46*4, %si */ + xorb %ch,%ch + movb $0x10,%cl + fs + rep + movsb + + xorl %eax,%eax + movl %ax,%es + + /* step 1 load new descriptor table */ + + .byte 0x3E,0x0F,1,0x16 + .word BIOSRELOC+0x6e #GDTptr + # word aword cs lgdt GDTptr + + /* step 2 turn on protected mode */ + + smsw %ax + orb $1,%al + lmsw %ax + jmp 1f + nop + + /* step 3 reload segment descriptors */ + +1: + xorl %eax,%eax + movb $0x10,%al + movl %ax,%ds + movl %ax,%es + movl %ax,%ss + word + ljmp $0x8,$ BIOSRELOC+0x74 /* would be nice if .-RELOC+0x7c00 worked */ + + /* Global Descriptor Table contains three descriptors: + * 0x00: Null: not used + * 0x08: Code: code segment starts at 0 and extents for 4 gigabytes + * 0x10: Data: data segment starts at 0 and extends for 4 gigabytes + * (overlays code) + */ +GDT: +NullDesc: .word 0,0,0,0 # null descriptor - not used +CodeDesc: .word 0xFFFF # limit at maximum: (bits 15:0) + .byte 0,0,0 # base at 0: (bits 23:0) + .byte 0x9f # present/priv level 0/code/conforming/readable + .byte 0xcf # page granular/default 32-bit/limit(bits 19:16) + .byte 0 # base at 0: (bits 31:24) +DataDesc: .word 0xFFFF # limit at maximum: (bits 15:0) + .byte 0,0,0 # base at 0: (bits 23:0) + .byte 0x93 # present/priv level 0/data/expand-up/writeable + .byte 0xcf # page granular/default 32-bit/limit(bits 19:16) + .byte 0 # base at 0: (bits 31:24) + +/* Global Descriptor Table pointer + * contains 6-byte pointer information for LGDT + */ +GDTptr: .word 0x17 # limit to three 8 byte selectors(null,code,data) + .long BIOSRELOC+0x56 # GDT -- arrgh, gas again! + + /* step 4 relocate to final bootstrap address. */ +reloc: + movl $ BIOSRELOC,%esi + movl $ RELOC,%edi + movl $512,%ecx + rep + movsb + movl $0xa0000, %esp + pushl $dodisk + ret + + /* step 5 load remaining 15 sectors off disk */ +dodisk: + movl $ IO_WD1+wd_seccnt,%edx + movb $ 15,%al + outb %al,%dx + NOP + movl $ IO_WD1+wd_sector,%edx + movb $ 2,%al + outb %al,%dx + NOP + #outb(wdc+wd_cyl_lo, (cyloffset & 0xff)); + #outb(wdc+wd_cyl_hi, (cyloffset >> 8)); + #outb(wdc+wd_sdh, WDSD_IBM | (unit << 4)); + + movl $ IO_WD1+wd_command,%edx + movb $ WDCC_READ,%al + outb %al,%dx + NOP + cld + + /* check to make sure controller is not busy and we have data ready */ +readblk: + movl $ IO_WD1+wd_status,%edx + NOP + inb %dx,%al + testb $ WDCS_BUSY,%al + jnz readblk + testb $ WDCS_DRQ,%al + jz readblk + + /* read a block into final position in memory */ + + movl $ IO_WD1+wd_data,%edx + movl $ 256,%ecx + .byte 0x66,0xf2,0x6d # rep insw + NOP + + /* need more blocks to be read in? */ + + cmpl $ RELOC+16*512-1,%edi + jl readblk + + /* for clever bootstrap, dig out boot unit and cylinder */ + + movl $ IO_WD1+wd_cyl_lo,%edx + inb %dx,%al + xorl %ecx,%ecx + movb %al,%cl + incl %edx + NOP + inb %dx,%al /* cyl_hi */ + movb %al,%ch + pushl %ecx /* cyloffset */ + + incl %edx + xorl %eax,%eax + NOP + inb %dx,%al /* sdh */ + andb $0x10,%al /* isolate unit # bit */ + shrb $4,%al + pushl %eax /* unit */ + + /* wd controller is major device 0 */ + xorl %eax,%eax + pushl %eax /* bootdev */ + + /* sorry, no flags at this point! */ + + movl $ start, %eax + call %eax /* main (dev, unit, offset) */ + +ebootblkcode: + + /* remaining space usable for a disk label */ + + .org 0x1fe + .word 0xaa55 /* signature -- used by BIOS ROM */ + +ebootblk: /* MUST BE EXACTLY 0x200 BIG FOR SURE */ |