summaryrefslogtreecommitdiff
path: root/sys/arch/i386/stand
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /sys/arch/i386/stand
initial import of NetBSD tree
Diffstat (limited to 'sys/arch/i386/stand')
-rw-r--r--sys/arch/i386/stand/Makefile118
-rw-r--r--sys/arch/i386/stand/as.c269
-rw-r--r--sys/arch/i386/stand/asbootblk.c236
-rw-r--r--sys/arch/i386/stand/bmap.c125
-rw-r--r--sys/arch/i386/stand/boot.c213
-rw-r--r--sys/arch/i386/stand/breadxx.c81
-rw-r--r--sys/arch/i386/stand/cga.c144
-rw-r--r--sys/arch/i386/stand/fd.c376
-rw-r--r--sys/arch/i386/stand/fdbootblk.c300
-rw-r--r--sys/arch/i386/stand/fs.c161
-rw-r--r--sys/arch/i386/stand/kbd.c269
-rw-r--r--sys/arch/i386/stand/prf.c57
-rw-r--r--sys/arch/i386/stand/saio.h71
-rw-r--r--sys/arch/i386/stand/srt0.c275
-rw-r--r--sys/arch/i386/stand/trimhd.c70
-rw-r--r--sys/arch/i386/stand/wd.c434
-rw-r--r--sys/arch/i386/stand/wdbootblk.c233
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 */