aboutsummaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorsvn2git <svn2git@FreeBSD.org>1994-07-01 00:00:00 -0800
committersvn2git <svn2git@FreeBSD.org>1994-07-01 00:00:00 -0800
commit5e0e9b99dc3fc0ecd49d929db0d57c784b66f481 (patch)
treee779b5a6edddbb949b7990751b12d6f25304ba86 /sys/i386
parenta16f65c7d117419bd266c28a1901ef129a337569 (diff)
downloadsrc-releng/1.tar.gz
src-releng/1.zip
Release FreeBSD 1.1.5.1release/1.1.5.1_cvsreleng/1
This commit was manufactured to restore the state of the 1.1.5.1-RELEASE image. Releases prior to 5.3-RELEASE are omitting the secure/ and crypto/ subdirs.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/boot/Makefile45
-rw-r--r--sys/i386/boot/biosbootbin0 -> 512 bytes
-rw-r--r--sys/i386/boot/bootbin0 -> 7632 bytes
-rw-r--r--sys/i386/boot/boot.c12
-rwxr-xr-xsys/i386/boot/boot.symbin0 -> 10379 bytes
-rw-r--r--sys/i386/boot/boot2.S12
-rw-r--r--sys/i386/boot/bootbiosbin0 -> 7120 bytes
-rw-r--r--sys/i386/boot/disk.c45
-rw-r--r--sys/i386/boot/io.c20
-rw-r--r--sys/i386/boot/start.S3
-rw-r--r--sys/i386/conf/ECLIPSE66
-rw-r--r--sys/i386/conf/GENERICAH13
-rw-r--r--sys/i386/conf/GENERICBT12
-rw-r--r--sys/i386/conf/HAMSTER67
-rw-r--r--sys/i386/conf/LAPTOP68
-rw-r--r--sys/i386/conf/LINT79
-rw-r--r--sys/i386/conf/Makefile.i38618
-rw-r--r--sys/i386/conf/SYSCONS86
-rw-r--r--sys/i386/conf/TIME64
-rw-r--r--sys/i386/conf/WCARCH67
-rw-r--r--sys/i386/conf/WCARCHIVE73
-rw-r--r--sys/i386/conf/devices.i3863
-rw-r--r--sys/i386/conf/files.i38694
-rw-r--r--sys/i386/doc/Changes209
-rw-r--r--sys/i386/doc/Makefile19
-rw-r--r--sys/i386/doc/ata/ata-145
-rw-r--r--sys/i386/doc/ata/ata-10213
-rw-r--r--sys/i386/doc/ata/ata-11201
-rw-r--r--sys/i386/doc/ata/ata-24
-rw-r--r--sys/i386/doc/ata/ata-327
-rw-r--r--sys/i386/doc/ata/ata-459
-rw-r--r--sys/i386/doc/ata/ata-5189
-rw-r--r--sys/i386/doc/ata/ata-6337
-rw-r--r--sys/i386/doc/ata/ata-7321
-rw-r--r--sys/i386/doc/ata/ata-8143
-rw-r--r--sys/i386/doc/ata/ata-9721
-rw-r--r--sys/i386/doc/ata/ata-apx426
-rw-r--r--sys/i386/doc/ata/ata-prt174
-rw-r--r--sys/i386/doc/ata/ata-toc159
-rw-r--r--sys/i386/doc/ed.relnotes174
-rw-r--r--sys/i386/doc/options.texi974
-rw-r--r--sys/i386/doc/sound.doc38
-rw-r--r--sys/i386/doc/vm_layout.doc32
-rw-r--r--sys/i386/doc/wt.doc77
-rw-r--r--sys/i386/i386/autoconf.c7
-rw-r--r--sys/i386/i386/conf.c65
-rw-r--r--sys/i386/i386/db_interface.c21
-rw-r--r--sys/i386/i386/exception.s138
-rw-r--r--sys/i386/i386/in_cksum.c94
-rw-r--r--sys/i386/i386/locore.s117
-rw-r--r--sys/i386/i386/machdep.c133
-rw-r--r--sys/i386/i386/math_emulate.c144
-rw-r--r--sys/i386/i386/microtime.s87
-rw-r--r--sys/i386/i386/pmap.c879
-rw-r--r--sys/i386/i386/random.s60
-rw-r--r--sys/i386/i386/support.s323
-rw-r--r--sys/i386/i386/swtch.s43
-rw-r--r--sys/i386/i386/trap.c814
-rw-r--r--sys/i386/i386/vm_machdep.c889
-rw-r--r--sys/i386/include/ansi.h21
-rw-r--r--sys/i386/include/asmacros.h6
-rw-r--r--sys/i386/include/console.h31
-rw-r--r--sys/i386/include/cpu.h13
-rw-r--r--sys/i386/include/cpufunc.h13
-rw-r--r--sys/i386/include/ioctl_fd.h31
-rw-r--r--sys/i386/include/limits.h6
-rw-r--r--sys/i386/include/lpt.h24
-rw-r--r--sys/i386/include/mouse.h44
-rw-r--r--sys/i386/include/npx.h10
-rw-r--r--sys/i386/include/param.h6
-rw-r--r--sys/i386/include/pcaudioio.h75
-rw-r--r--sys/i386/include/pmap.h55
-rw-r--r--sys/i386/include/psl.h6
-rw-r--r--sys/i386/include/pte.h4
-rw-r--r--sys/i386/include/soundcard.h50
-rw-r--r--sys/i386/include/spl.h104
-rw-r--r--sys/i386/include/ultrasound.h9
-rw-r--r--sys/i386/include/vmparam.h2
-rw-r--r--sys/i386/isa/aha1542.c13
-rw-r--r--sys/i386/isa/bt742a.c111
-rw-r--r--sys/i386/isa/bt742a_32.c1694
-rw-r--r--sys/i386/isa/clock.c279
-rw-r--r--sys/i386/isa/com.c101
-rw-r--r--sys/i386/isa/debug.h85
-rw-r--r--sys/i386/isa/elink.c77
-rw-r--r--sys/i386/isa/elink.h39
-rw-r--r--sys/i386/isa/fd.c778
-rw-r--r--sys/i386/isa/fdc.h12
-rw-r--r--sys/i386/isa/fdreg.h20
-rw-r--r--sys/i386/isa/ft.c1188
-rw-r--r--sys/i386/isa/ftreg.h11
-rw-r--r--sys/i386/isa/ic/i82365.h190
-rw-r--r--sys/i386/isa/ic/nec765.h73
-rw-r--r--sys/i386/isa/icu.h12
-rw-r--r--sys/i386/isa/icu.s492
-rw-r--r--sys/i386/isa/if_ed.c1451
-rw-r--r--sys/i386/isa/if_edreg.h2
-rw-r--r--sys/i386/isa/if_el.c800
-rw-r--r--sys/i386/isa/if_elreg.h76
-rw-r--r--sys/i386/isa/if_ep.c164
-rw-r--r--sys/i386/isa/if_ie507.h19
-rw-r--r--sys/i386/isa/if_is.c10
-rw-r--r--sys/i386/isa/if_ze.c1951
-rw-r--r--sys/i386/isa/if_zereg.h859
-rw-r--r--sys/i386/isa/ipl.h7
-rw-r--r--sys/i386/isa/isa.c227
-rw-r--r--sys/i386/isa/isa.h9
-rw-r--r--sys/i386/isa/isa_device.h4
-rw-r--r--sys/i386/isa/kbdtables.h40
-rw-r--r--sys/i386/isa/lpa.c14
-rw-r--r--sys/i386/isa/lpt.c150
-rw-r--r--sys/i386/isa/mcd.c5
-rw-r--r--sys/i386/isa/npx.c22
-rw-r--r--sys/i386/isa/pcaudio.c430
-rw-r--r--sys/i386/isa/pccons.c101
-rw-r--r--sys/i386/isa/psm.c464
-rw-r--r--sys/i386/isa/seagate.c2036
-rw-r--r--sys/i386/isa/sio.c1242
-rw-r--r--sys/i386/isa/sound/CHANGELOG75
-rw-r--r--sys/i386/isa/sound/RELNOTES.Linux256
-rw-r--r--sys/i386/isa/sound/adlib_card.c13
-rw-r--r--sys/i386/isa/sound/audio.c106
-rw-r--r--sys/i386/isa/sound/debug.h29
-rw-r--r--sys/i386/isa/sound/dev_table.c148
-rw-r--r--sys/i386/isa/sound/dev_table.h46
-rw-r--r--sys/i386/isa/sound/dmabuf.c360
-rw-r--r--sys/i386/isa/sound/dsp.c270
-rw-r--r--sys/i386/isa/sound/gus_card.c87
-rw-r--r--sys/i386/isa/sound/gus_hw.h15
-rw-r--r--sys/i386/isa/sound/gus_linearvol.h18
-rw-r--r--sys/i386/isa/sound/gus_midi.c14
-rw-r--r--sys/i386/isa/sound/gus_vol.c70
-rw-r--r--sys/i386/isa/sound/gus_wave.c1834
-rw-r--r--sys/i386/isa/sound/ics2101.c265
-rw-r--r--sys/i386/isa/sound/local.h13
-rw-r--r--sys/i386/isa/sound/midi.c220
-rw-r--r--sys/i386/isa/sound/midibuf.c14
-rw-r--r--sys/i386/isa/sound/mpu401.c129
-rw-r--r--sys/i386/isa/sound/opl3.c68
-rw-r--r--sys/i386/isa/sound/os.h94
-rw-r--r--sys/i386/isa/sound/pas.h12
-rw-r--r--sys/i386/isa/sound/pas2_card.c135
-rw-r--r--sys/i386/isa/sound/pas2_midi.c16
-rw-r--r--sys/i386/isa/sound/pas2_mixer.c40
-rw-r--r--sys/i386/isa/sound/pas2_pcm.c91
-rw-r--r--sys/i386/isa/sound/patmgr.c41
-rw-r--r--sys/i386/isa/sound/pro_midi.c140
-rw-r--r--sys/i386/isa/sound/sb.h28
-rw-r--r--sys/i386/isa/sound/sb16_dsp.c627
-rw-r--r--sys/i386/isa/sound/sb16_midi.c287
-rw-r--r--sys/i386/isa/sound/sb_card.c13
-rw-r--r--sys/i386/isa/sound/sb_dsp.c1140
-rw-r--r--sys/i386/isa/sound/sb_midi.c224
-rw-r--r--sys/i386/isa/sound/sb_mixer.c422
-rw-r--r--sys/i386/isa/sound/sb_mixer.h212
-rw-r--r--sys/i386/isa/sound/sequencer.c311
-rw-r--r--sys/i386/isa/sound/sound_calls.h59
-rw-r--r--sys/i386/isa/sound/sound_config.h43
-rw-r--r--sys/i386/isa/sound/sound_switch.c445
-rw-r--r--sys/i386/isa/sound/soundcard.c307
-rw-r--r--sys/i386/isa/spkr.c23
-rw-r--r--sys/i386/isa/syscons.c623
-rw-r--r--sys/i386/isa/tw.c997
-rw-r--r--sys/i386/isa/ultra14f.c6
-rw-r--r--sys/i386/isa/vector.s196
-rw-r--r--sys/i386/isa/wd.c204
-rw-r--r--sys/i386/isa/wt.c3
-rw-r--r--sys/i386/isa/wt.c.orig902
-rw-r--r--sys/i386/netboot/Makefile9
-rw-r--r--sys/i386/netboot/bootmenu.c2
-rw-r--r--sys/i386/netboot/ether.c479
-rw-r--r--sys/i386/netboot/ether.h178
-rw-r--r--sys/i386/netboot/wd80x3.c240
-rw-r--r--sys/i386/pci/ncr.c5507
-rw-r--r--sys/i386/pci/ncr_reg.h489
-rw-r--r--sys/i386/pci/pci.c494
-rw-r--r--sys/i386/pci/pci.h58
-rw-r--r--sys/i386/pci/pci_config.c45
-rw-r--r--sys/i386/pci/pci_device.h88
-rw-r--r--sys/i386/pci/pcibios.c261
-rw-r--r--sys/i386/pci/pcibios.h53
181 files changed, 32225 insertions, 12340 deletions
diff --git a/sys/i386/boot/Makefile b/sys/i386/boot/Makefile
index 3f402426ee49..3c7418f7ddda 100644
--- a/sys/i386/boot/Makefile
+++ b/sys/i386/boot/Makefile
@@ -20,7 +20,7 @@
# the rights to redistribute these changes.
#
# from: Mach, Revision 2.2 92/04/04 11:33:46 rpd
-# $Id: Makefile,v 1.5 1993/12/11 20:35:15 ats Exp $
+# $Id: Makefile,v 1.10 1994/06/20 04:32:40 jkh Exp $
#
wd0:
@@ -32,7 +32,10 @@ wd0:
NOPROG= noprog
NOMAN= noman
-CFLAGS = -O -DDO_BAD144 -I${.CURDIR}
+# tunable loopcount parameter, waiting for keypress
+BOOTWAIT?= 2400
+
+CFLAGS = -O2 -DDO_BAD144 -DBOOTWAIT=${BOOTWAIT} -I${.CURDIR}
LIBS= -lc
INC= -I${.CURDIR}/../..
@@ -61,31 +64,31 @@ biosboot: boot
bootbios: boot
dd if=boot of=bootbios skip=1
-/usr/mdec/bootsd: bootbios
- cp bootbios /usr/mdec/bootsd
+${DESTDIR}/usr/mdec/bootsd: bootbios
+ cp bootbios ${DESTDIR}/usr/mdec/bootsd
-/usr/mdec/sdboot: biosboot
- cp biosboot /usr/mdec/sdboot
+${DESTDIR}/usr/mdec/sdboot: biosboot
+ cp biosboot ${DESTDIR}/usr/mdec/sdboot
-/usr/mdec/bootwd: /usr/mdec/bootsd
- rm -f /usr/mdec/bootwd
- ln /usr/mdec/bootsd /usr/mdec/bootwd
+${DESTDIR}/usr/mdec/bootwd: ${DESTDIR}/usr/mdec/bootsd
+ rm -f ${DESTDIR}/usr/mdec/bootwd
+ ln ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/bootwd
-/usr/mdec/wdboot: /usr/mdec/sdboot
- rm -f /usr/mdec/wdboot
- ln /usr/mdec/sdboot /usr/mdec/wdboot
+${DESTDIR}/usr/mdec/wdboot: ${DESTDIR}/usr/mdec/sdboot
+ rm -f ${DESTDIR}/usr/mdec/wdboot
+ ln ${DESTDIR}/usr/mdec/sdboot ${DESTDIR}/usr/mdec/wdboot
-/usr/mdec/bootfd: /usr/mdec/bootsd
- rm -f /usr/mdec/bootfd
- ln /usr/mdec/bootsd /usr/mdec/bootfd
+${DESTDIR}/usr/mdec/bootfd: ${DESTDIR}/usr/mdec/bootsd
+ rm -f ${DESTDIR}/usr/mdec/bootfd
+ ln ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/bootfd
-/usr/mdec/fdboot: /usr/mdec/sdboot
- rm -f /usr/mdec/fdboot
- ln /usr/mdec/sdboot /usr/mdec/fdboot
+${DESTDIR}/usr/mdec/fdboot: ${DESTDIR}/usr/mdec/sdboot
+ rm -f ${DESTDIR}/usr/mdec/fdboot
+ ln ${DESTDIR}/usr/mdec/sdboot ${DESTDIR}/usr/mdec/fdboot
-sd: /usr/mdec/bootsd /usr/mdec/sdboot
-wd: /usr/mdec/bootwd /usr/mdec/wdboot
-fd: /usr/mdec/bootfd /usr/mdec/fdboot
+sd: ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/sdboot
+wd: ${DESTDIR}/usr/mdec/bootwd ${DESTDIR}/usr/mdec/wdboot
+fd: ${DESTDIR}/usr/mdec/bootfd ${DESTDIR}/usr/mdec/fdboot
all: biosboot bootbios
diff --git a/sys/i386/boot/biosboot b/sys/i386/boot/biosboot
new file mode 100644
index 000000000000..9c572c5d2422
--- /dev/null
+++ b/sys/i386/boot/biosboot
Binary files differ
diff --git a/sys/i386/boot/boot b/sys/i386/boot/boot
new file mode 100644
index 000000000000..bba109001d81
--- /dev/null
+++ b/sys/i386/boot/boot
Binary files differ
diff --git a/sys/i386/boot/boot.c b/sys/i386/boot/boot.c
index 19de113b0c51..ad3c7b2ee258 100644
--- a/sys/i386/boot/boot.c
+++ b/sys/i386/boot/boot.c
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, [92/04/03 16:51:14 rvb]
- * $Id: boot.c,v 1.9.2.1 1994/05/01 05:14:49 rgrimes Exp $
+ * $Id: boot.c,v 1.14 1994/06/16 03:53:27 adam Exp $
*/
@@ -60,8 +60,7 @@ struct exec head;
int argv[10], esym;
char *name;
char *names[] = {
- "/386bsd", "/o386bsd", "/386bsd.old",
- "/vmunix", "/ovmunix", "/vmunix.old"
+ "/386bsd", "/o386bsd", "/386bsd.old"
};
#define NUMNAMES (sizeof(names)/sizeof(char *))
@@ -76,7 +75,7 @@ int drive;
ouraddr,
argv[7] = memsize(0),
argv[8] = memsize(1),
- "$Revision: 1.9.2.1 $");
+ "$Revision: 1.14 $");
printf("use hd(1,a)/386bsd to boot sd0 when wd0 is also installed\n");
gateA20();
loadstart:
@@ -138,13 +137,12 @@ loadprog(howto)
{
if((addr + head.a_text + head.a_data) > ouraddr)
{
- printf("kernel will not fit below loader\n");
+ printf("kernel overlaps loader\n");
return;
}
if((addr + head.a_text + head.a_data + head.a_bss) > 0xa0000)
{
- printf("kernel too big, won't fit in 640K with bss\n");
- printf("Only hope is to link the kernel for > 1MB\n");
+ printf("bss exceeds 640k limit\n");
return;
}
}
diff --git a/sys/i386/boot/boot.sym b/sys/i386/boot/boot.sym
new file mode 100755
index 000000000000..8249abc812dc
--- /dev/null
+++ b/sys/i386/boot/boot.sym
Binary files differ
diff --git a/sys/i386/boot/boot2.S b/sys/i386/boot/boot2.S
index 9270d4de0f3c..c49bde8d377e 100644
--- a/sys/i386/boot/boot2.S
+++ b/sys/i386/boot/boot2.S
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:26 rpd
- * $Id: boot2.S,v 1.3 1993/11/13 04:43:25 rgrimes Exp $
+ * $Id: boot2.S,v 1.4 1994/06/22 05:52:25 jkh Exp $
*/
#include "asm.h"
@@ -128,14 +128,22 @@ ENTRY(boot2)
mov %ax, %es
/* fix up IDT entries for bdb */
- subl $2, %ebx
+ data32
+ subl $2, %ebx /* calculate EA to check it */
+ jb 1f /* give up if it would trap */
+ addr32
movl %es: (%ebx), %eax /* actually movw to %ax */
addr32
movl %eax, EXT(Idt)+8*DEBUG_VECTOR /* actually movw %ax */
+1:
+ data32
subl $2, %ecx
+ jb 1f
+ addr32
movl %es: (%ecx), %eax /* actually movw to %ax */
addr32
movl %eax, EXT(Idt)+8*BREAKPOINT_VECTOR /* actually movw %ax */
+1:
/* finished with groping in real mode segments */
pop %es
diff --git a/sys/i386/boot/bootbios b/sys/i386/boot/bootbios
new file mode 100644
index 000000000000..a0ed09db1e0c
--- /dev/null
+++ b/sys/i386/boot/bootbios
Binary files differ
diff --git a/sys/i386/boot/disk.c b/sys/i386/boot/disk.c
index 1c7712f10517..8db41bbb6f4b 100644
--- a/sys/i386/boot/disk.c
+++ b/sys/i386/boot/disk.c
@@ -24,7 +24,17 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:49 rpd
- * $Id: disk.c,v 1.4 1994/02/22 22:59:40 rgrimes Exp $
+ * $Id: disk.c,v 1.5 1994/05/16 03:06:00 ache Exp $
+ */
+
+/*
+ * 93/10/08 bde
+ * If there is no 386BSD partition, initialize the label sector with
+ * LABELSECTOR instead of with garbage.
+ *
+ * 93/08/22 bde
+ * Fixed reading of bad sector table. It is at the end of the 'c'
+ * partition, which is not always at the end of the disk.
*/
#include "boot.h"
@@ -80,10 +90,12 @@ devopen()
#else EMBEDDED_DISKLABEL
Bread(dosdev, 0);
dptr = (struct dos_partition *)(((char *)0)+DOSPARTOFF);
+ sector = LABELSECTOR;
for (i = 0; i < NDOSPART; i++, dptr++)
- if (dptr->dp_typ == DOSPTYP_386BSD)
+ if (dptr->dp_typ == DOSPTYP_386BSD) {
+ sector = dptr->dp_start + LABELSECTOR;
break;
- sector = dptr->dp_start + LABELSECTOR;
+ }
Bread(dosdev, sector++);
dl=((struct disklabel *)0);
disklabel = *dl; /* structure copy (maybe useful later)*/
@@ -113,10 +125,20 @@ devopen()
int dkbbnum;
struct dkbad *dkbptr;
- /* find the first readable bad144 sector */
- /* some of this code is copied from ufs/disk_subr.c */
+ /* find the first readable bad sector table */
+ /* some of this code is copied from ufs/ufs_disksubr.c */
+ /* including the bugs :-( */
/* read a bad sector table */
- dkbbnum = dl->d_secperunit - dl->d_nsectors;
+
+#define BAD144_PART 2 /* XXX scattered magic numbers */
+#define BSD_PART 0 /* XXX should be 2 but bad144.c uses 0 */
+ if (dl->d_partitions[BSD_PART].p_offset != 0)
+ dkbbnum = dl->d_partitions[BAD144_PART].p_offset
+ + dl->d_partitions[BAD144_PART].p_size;
+ else
+ dkbbnum = dl->d_secperunit;
+ dkbbnum -= dl->d_nsectors;
+
if (dl->d_secsize > DEV_BSIZE)
dkbbnum *= dl->d_secsize / DEV_BSIZE;
else
@@ -138,9 +160,9 @@ devopen()
i += 2;
} while (i < 10 && i < dl->d_nsectors);
if (!do_bad144)
- printf("Bad badsect table\n");
+ printf("Bad bad sector table\n");
else
- printf("Using bad144 bad sector at %d\n", dkbbnum+i);
+ printf("Using bad sector table at %d\n", dkbbnum+i);
}
#endif DO_BAD144
}
@@ -245,7 +267,12 @@ badsect(dosdev, sector)
goto no_remap;
}
/* otherwise find replacement sector */
- newsec = dl->d_secperunit - dl->d_nsectors - i -1;
+ if (dl->d_partitions[BSD_PART].p_offset != 0)
+ newsec = dl->d_partitions[BAD144_PART].p_offset
+ + dl->d_partitions[BAD144_PART].p_size;
+ else
+ newsec = dl->d_secperunit;
+ newsec -= dl->d_nsectors + i + 1;
return newsec;
}
#endif DO_BAD144
diff --git a/sys/i386/boot/io.c b/sys/i386/boot/io.c
index 7cb6d02ba93a..29fd128c9ce7 100644
--- a/sys/i386/boot/io.c
+++ b/sys/i386/boot/io.c
@@ -1,3 +1,4 @@
+
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
@@ -24,7 +25,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:57 rpd
- * $Id: io.c,v 1.3 1993/10/16 19:11:36 rgrimes Exp $
+ * $Id: io.c,v 1.6 1994/06/16 03:53:29 adam Exp $
*/
#include <i386/include/pio.h>
@@ -38,10 +39,10 @@
#define KC_CMD_WIN 0xd0 /* read output port */
#define KC_CMD_WOUT 0xd1 /* write output port */
-#define KB_A20 0x9f /* enable A20,
+#define KB_A20 0xdf /* enable A20,
enable output buffer full interrupt
enable data line
- disable clock line */
+ enable clock line */
/*
* Gate A20 for high memory
@@ -137,13 +138,24 @@ getchar()
return(c);
}
+#if BOOTWAIT
+spinwait(i)
+int i;
+{
+ while (--i >= 0)
+ (void)inb(0x84);
+}
+#endif
+
gets(buf)
char *buf;
{
int i;
char *ptr=buf;
- for (i = 240000; i>0; i--)
+#if BOOTWAIT
+ for (i = BOOTWAIT; i>0; spinwait(10000),i--)
+#endif
if (ischar())
for (;;)
switch(*ptr = getchar() & 0xff) {
diff --git a/sys/i386/boot/start.S b/sys/i386/boot/start.S
index bdf387667780..44de86eb89f4 100644
--- a/sys/i386/boot/start.S
+++ b/sys/i386/boot/start.S
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:36:29 rpd
- * $Id: start.S,v 1.2 1993/10/16 19:11:38 rgrimes Exp $
+ * $Id: start.S,v 1.3 1994/06/13 19:27:52 jkh Exp $
*/
/*
@@ -99,6 +99,7 @@ start:
jae hd
fd:
+ mov $0x0, %dl
# reset the disk system
#ifdef DEBUG
data32
diff --git a/sys/i386/conf/ECLIPSE b/sys/i386/conf/ECLIPSE
new file mode 100644
index 000000000000..31eede546035
--- /dev/null
+++ b/sys/i386/conf/ECLIPSE
@@ -0,0 +1,66 @@
+#
+# GENERICAH -- Generic machine with WD/AHx family disks
+#
+# $Id: GENERICAH,v 1.36 1994/06/17 06:56:59 sean Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident ECLIPSE
+timezone 8 dst
+maxusers 10
+maxfdescs 2048 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+options "NCONS=4" #4 virtual consoles
+
+config "386bsd" root on sd0 swap on sd0 dumps on sd0
+
+controller isa0
+
+device pci0 at isa? bio irq 9 vector pciintr
+device ncr0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller scbus0
+
+device sd0
+device sd1
+
+device st0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ix0 at isa? port 0x320 net irq 10 iomem 0xd0000 iosiz 32768 vector ixintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 1
+pseudo-device ppp 1
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/GENERICAH b/sys/i386/conf/GENERICAH
index 4bba699be512..2c10cd45daa1 100644
--- a/sys/i386/conf/GENERICAH
+++ b/sys/i386/conf/GENERICAH
@@ -1,12 +1,13 @@
#
# GENERICAH -- Generic machine with WD/AHx family disks
#
-# $Id: GENERICAH,v 1.25.2.2 1994/04/12 16:37:30 csgr Exp $
+# $Id: GENERICAH,v 1.36 1994/06/17 06:56:59 sean Exp $
#
machine "i386"
cpu "I386_CPU"
cpu "I486_CPU"
+cpu "I586_CPU"
ident GENERICAH
timezone 8 dst
maxusers 10
@@ -22,14 +23,17 @@ options XSERVER #Xserver
options UCONSOLE #X Console support
options "FAT_CURSOR" #block cursor in syscons or pccons
#options GATEWAY #Host is a Gateway (forwards packets)
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+options "NCONS=4" #4 virtual consoles
-config "386bsd" root on wd0 swap on wd0 and sd0 dumps on wd0
+config "386bsd" root on wd0 swap on wd0 and wd1 and sd0 and sd1 dumps on wd0
controller isa0
controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
disk fd0 at fdc0 drive 0
disk fd1 at fdc0 drive 1
+#tape ft0 at fdc0 drive 2
controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
disk wd0 at wdc0 drive 0
@@ -41,6 +45,7 @@ disk wd3 at wdc1 drive 1
controller ahb0 at isa? bio irq 11 vector ahbintr
controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
+controller sea0 at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector seaintr
controller scbus0
device sd0
@@ -57,7 +62,7 @@ device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
device mcd1 at isa? port 0x340 bio irq 11 vector mcdintr
-device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
@@ -78,7 +83,7 @@ pseudo-device loop
pseudo-device ether
pseudo-device log
pseudo-device sl 2
-pseudo-device pty 12
+pseudo-device pty 16
pseudo-device speaker
pseudo-device swappager
diff --git a/sys/i386/conf/GENERICBT b/sys/i386/conf/GENERICBT
index 5311d76f7388..fae078940fa7 100644
--- a/sys/i386/conf/GENERICBT
+++ b/sys/i386/conf/GENERICBT
@@ -1,12 +1,13 @@
#
# GENERICBT -- Generic machine with WD/BTx family disks
#
-# $Id: GENERICBT,v 1.25.2.2 1994/04/12 16:37:32 csgr Exp $
+# $Id: GENERICBT,v 1.35 1994/06/08 00:30:32 phk Exp $
#
machine "i386"
cpu "I386_CPU"
cpu "I486_CPU"
+cpu "I586_CPU"
ident GENERICBT
timezone 8 dst
maxusers 10
@@ -22,14 +23,17 @@ options XSERVER #Xserver
options UCONSOLE #X Console support
options "FAT_CURSOR" #block cursor in syscons or pccons
#options GATEWAY #Host is a Gateway (forwards packets)
+options "NCONS=4" #4 virtual consoles
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
-config "386bsd" root on wd0 swap on wd0 and sd0 dumps on wd0
+config "386bsd" root on wd0 swap on wd0 and wd1 and sd0 and sd1 dumps on wd0
controller isa0
controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
disk fd0 at fdc0 drive 0
disk fd1 at fdc0 drive 1
+#tape ft0 at fdc0 drive 2
controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
disk wd0 at wdc0 drive 0
@@ -57,7 +61,7 @@ device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
device mcd1 at isa? port 0x340 bio irq 11 vector mcdintr
-device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
@@ -78,7 +82,7 @@ pseudo-device loop
pseudo-device ether
pseudo-device log
pseudo-device sl 2
-pseudo-device pty 12
+pseudo-device pty 16
pseudo-device speaker
pseudo-device swappager
diff --git a/sys/i386/conf/HAMSTER b/sys/i386/conf/HAMSTER
new file mode 100644
index 000000000000..a3da520cd05e
--- /dev/null
+++ b/sys/i386/conf/HAMSTER
@@ -0,0 +1,67 @@
+#
+# GENERICAH -- Generic machine with WD/AHx family disks
+#
+# $Id: GENERICAH,v 1.36 1994/06/17 06:56:59 sean Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident GENERICAH
+timezone 8 dst
+maxusers 10
+maxfdescs 2048 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+#options GATEWAY #Host is a Gateway (forwards packets)
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+options "NCONS=8" #4 virtual consoles
+
+config "386bsd" root on sd0 swap on sd0 dumps on sd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
+controller scbus0
+
+device sd0
+device sd1
+device sd2
+device sd3
+
+device st0
+device st1
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ix0 at isa? port 0x300 net irq 10 iomem 0xd0000 iosiz 32768 vector ixintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 2
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/LAPTOP b/sys/i386/conf/LAPTOP
new file mode 100644
index 000000000000..4c7ce3b2fbd7
--- /dev/null
+++ b/sys/i386/conf/LAPTOP
@@ -0,0 +1,68 @@
+#
+# LAPTOP -- Minimal machine with IDE drives.
+#
+# $Id: LAPTOP,v 1.3 1994/06/22 05:58:53 jkh Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident LAPTOP
+timezone 8 dst
+maxusers 8
+maxfdescs 256 #Max file descriptors per process
+options INET #InterNETworking
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+options "NCONS=8" #8 virtual consoles
+options LAPTOP
+
+# Do not use in binary distributions; put here because most laptops lack 387
+# support, and LAPTOP is not one of the kernels we build by default.
+options GPL_MATH_EMULATE #Support for x87 emualtion via GPL'd emu
+
+# Most laptops have PS/2 style trackball mice.
+options ALLOW_CONFLICT_IOADDR #no IO addr conflict checks (PS/2 mice)
+
+config "386bsd" root on wd0 swap on wd0 and wd1 and sd0 and sd1 dumps on wd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
+disk wd0 at wdc0 drive 0
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device lpt0 at isa? port? tty irq 7 vector lptintr
+device psm0 at isa? port "IO_KBD" tty irq 12 vector psmintr
+
+# IBM/National PCMCIA ethernet cards
+device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr
+
+# The digital speaker driver (/dev/pcaudio). Might as well since we almost
+# certainly won't have a sound card!
+device pca0 at isa? tty
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 1
+pseudo-device ppp 1
+pseudo-device pty 16
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index 129d2c5d6ea0..9235212a9920 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -4,38 +4,40 @@
#
# This kernel is NOT MEANT to be runnable!
#
-# $Id: LINT,v 1.53 1994/02/09 05:35:57 nate Exp $
+# $Id: LINT,v 1.79 1994/06/16 05:31:16 jkh Exp $
#
machine "i386"
cpu "I386_CPU"
cpu "I486_CPU"
+cpu "I586_CPU"
ident LINT
timezone 8 dst
maxusers 10
maxfdescs 2048 #Max file descriptors per process
options MATH_EMULATE #Support for x87 emulation
+# Do not use in binary distributions
+#options GPL_MATH_EMULATE #Support for x87 emualtion via
+ #new math emulator
+
config "386bsd" root on wd0 swap on wd0 and sd0 dumps on wd0
#
# options that appear as inline #ifdef's
#
-options "COM_BIDIR" #Bidirectional support in sys/isa/sio.c
options "COM_MULTIPORT" #Multiport support in sys/isa/sio.c
-options "FIFO_TRIGGER=FIFO_TRIGGER_1" #Use this fifo value in sio.c
options "COMPAT_43" #compatible with BSD 4.3
-options "SYMTAB_SPACE=104705" #This kernel needs LOTS of symtable
+options "SYMTAB_SPACE=119000" #This kernel needs LOTS of symtable
options GATEWAY #internetwork gateway
options KTRACE #kernel tracing
options "NCONS=8" #number of syscons virtual consoles
options "FAT_CURSOR" #block cursor in syscons or pccons
-options "STAR_SAVER" #syscons "stars" screen saver
-options "FADE_SAVER" #syscons "fade" screen saver
-options "SNAKE_SAVER" #syscons "snake" screen saver
-options "BLANK_SAVER" #syscons "blank" screen saver
+
+#options ALLOW_CONFLICT_IOADDR #no IO addr conflict checks (PS/2 mice)
+#options ALLOW_CONFLICT_IRQ #no IRQ conflict checks (mport serial)
options "TCP_COMPAT_42" #tcp/ip compatible with 4.2
# ^^^ NOT RECOMMENDED FOR NORMAL USE
@@ -53,13 +55,14 @@ options MACHVMCOMPAT #support for Mach-style vm calls
options IPBROADCASTECHO=1 #send reply to broadcast pings
options IPMASKAGENT=1 #send reply to icmp mask requests
options TPCONS #support X.25 network-layer service
+options USER_LDT #allow user-level control of i386 ldt
-options EXCLUDE_CHIP_MIDI # \ sound driver options
-options "EXCLUDE_MPU401" # \ exclude specified
-options EXCLUDE_GUS # / device or chip
-options EXCLUDE_SBPRO # / from driver
+# See /sys/i386/doc/sound.doc for information about EXCLUDE options for
+# the sound drivers.
-options USER_LDT #allow user-level control of i386 ldt
+# Multicast support.
+options MULTICAST # Multicast code
+options MROUTING # Multicast routing
#
# options that are in sys/conf/files
@@ -120,13 +123,15 @@ controller ahb0 at isa? bio irq 11 vector ahbintr
controller bt0 at isa? port "IO_BT0" bio irq 12 vector btintr
# driver for the Seagate ST01/ST02 card, not yet finished.
#controller sg0 at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector sgintr
-#dcfclk device-driver
+# driver for the Seagate ST01/ST02 or Future Domain 950 card, works
+controller sea0 at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector seaintr
controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
disk fd0 at fdc0 drive 0
disk fd1 at fdc0 drive 1
tape ft0 at fdc0 drive 2
+
# driver for the Western Digital and SMCC WD80xx cards, for the Novell
-# NE1000/200 card and the 3COM 3C503 card.
+# NE1000/2000 card and the 3COM 3C503 card.
device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr
# driver for the AT&T Starlan card.
device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
@@ -135,27 +140,38 @@ device is0 at isa? port 0x280 net irq 10 drq 7 vector isintr
#device ix0 at isa? port 0x320 net irq 10 iomem 0xd0000 iosiz 32768 vector ixintr
# driver for the Etherlink III ( 3C509 ) card, beta version.
device ep0 at isa? port 0x300 net irq 10 vector epintr
+#driver for the 3c501
+device el0 at isa? port 0x300 net irq 9 vector elintr
+# IBM/National PCMCIA ethernet cards
+device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr
+
#special cased above:
#controller isa0
-# interruptless parallel printer port driver
-device lpa0 at isa? port "IO_LPT1" tty
-device lpa1 at isa? port "IO_LPT2" tty
+
+# interruptless parallel printer port driver. NOW OBSOLETE, DON'T USE.
+#device lpa0 at isa? port "IO_LPT1" tty
+#device lpa1 at isa? port "IO_LPT2" tty
# interrupt driven parallel printer port driver
device lpt0 at isa? port "IO_LPT3" tty irq 7 vector lptintr
-# Driver for Mutsumi CD-ROM players
-device mcd0 at isa? port 0x300 bio irq 10 vector mcdint
+# Driver for Mitsumi CD-ROM players
+device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
# Driver for Logitech and ATI inport bus mice
device mse0 at isa? port 0x23c tty irq 5 vector mseintr
device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
-device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
#only one of pc0 or sc0 allowed
-#device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+#device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
device sio2 at isa? port "IO_COM3" tty irq 5 vector siointr
device sio3 at isa? port "IO_COM4" tty irq 9 vector siointr
+#PS/2 mouse driver (must follow pc0 or sc0 if enabled). Also enable
+#ALLOW_CONFLICT_IOADDR option (see above) if you want to use this.
+#device psm0 at isa? port "IO_KBD" tty irq 12 vector psmintr
+
pseudo-device speaker
-#tw device-driver
+device tw0 at isa? port 0x278 tty irq 5 vector twintr
+
controller uha0 at isa? port "IO_UHA0" bio irq 14 drq 5 vector uhaintr
controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
disk wd0 at wdc0 drive 0
@@ -166,14 +182,17 @@ disk wd3 at wdc1 drive 1
device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
# Various sound card drivers.
-# See /sys/i386/doc/sound.doc for more information.
-device snd5 at isa? port 0x330 irq 6 drq 0 vector mpuintr
+# See /sys/doc/sound.doc for more information.
+device snd5 at isa? port 0x330 irq 6 vector mpuintr
device snd4 at isa? port 0x220 irq 15 drq 6 vector gusintr
-device snd3 at isa? port 0x388 irq 12 drq 3 vector pasintr
+device snd3 at isa? port 0x388 irq 10 drq 6 vector pasintr
device snd2 at isa? port 0x220 irq 7 drq 1 vector sbintr
-device snd1 at isa? port 0x388 irq 0 drq 0 vector sbintr
-#
-#
+device snd6 at isa? port 0x220 irq 7 drq 5 vector sbintr
+device snd7 at isa? port 0x300
+device snd1 at isa? port 0x388
+
+# The digital speaker driver (/dev/pcaudio).
+device pca0 at isa? tty
+
# options that have not been resolved yet
-#
pseudo-device log
diff --git a/sys/i386/conf/Makefile.i386 b/sys/i386/conf/Makefile.i386
index df5fcf18c66c..0ecf4c5e14e5 100644
--- a/sys/i386/conf/Makefile.i386
+++ b/sys/i386/conf/Makefile.i386
@@ -1,6 +1,6 @@
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.i386,v 1.22 1994/02/17 06:51:15 rgrimes Exp $
+# $Id: Makefile.i386,v 1.27 1994/06/16 00:45:02 adam Exp $
#
# Makefile for FreeBSD
#
@@ -24,7 +24,15 @@ TOUCH= touch -f -c
LD= /usr/bin/ld
CC= cc
CPP= cpp
+.if defined(DEBUG)
+.if defined(NOSTRIP)
+STRIP= echo '(skipping) strip'
+.else
+STRIP= cp $@ $@.sym; strip
+.endif
+.else
STRIP= strip
+.endif
DBSYM= /usr/sbin/dbsym
S= ../..
@@ -51,11 +59,11 @@ NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
NORMAL_S= ${CPP} -I. -DLOCORE ${COPTS} $< | ${AS} ${ASFLAGS} -o $*.o
DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $<
DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
-SYSTEM_OBJS=locore.o exception.o swtch.o support.o ${OBJS} param.o \
+SYSTEM_OBJS=locore.o config.o exception.o swtch.o support.o ${OBJS} param.o \
ioconf.o conf.o machdep.o
SYSTEM_DEP=Makefile symbols.sort ${SYSTEM_OBJS}
SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
-SYSTEM_LD= @${LD} -Bstatic -Z -T ${LOAD_ADDRESS} -o $@ -X vers.o ${SYSTEM_OBJS}
+SYSTEM_LD= @${LD} -Bstatic -Z -T ${LOAD_ADDRESS} -o $@ -X ${SYSTEM_OBJS} vers.o
SYSTEM_LD_TAIL= @echo rearranging symbols; symorder symbols.sort $@; \
${DBSYM} -fT ${LOAD_ADDRESS} $@; ${STRIP} -x $@; size $@; chmod 755 $@
@@ -90,7 +98,7 @@ symbols.sort: ${I386}/i386/symbols.raw
locore.o: assym.s ${I386}/i386/locore.s machine/trap.h machine/psl.h \
machine/pte.h ${I386}/isa/vector.s ${I386}/isa/icu.s \
- $S/sys/errno.h machine/specialreg.h ${I386}/isa/debug.h \
+ $S/sys/errno.h machine/specialreg.h \
${I386}/isa/icu.h ${I386}/isa/isa.h vector.h $S/net/netisr.h \
machine/asmacros.h
${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/locore.s | \
@@ -104,7 +112,7 @@ exception.o: assym.s ${I386}/i386/exception.s machine/trap.h \
${AS} ${ASFLAGS} -o exception.o
swtch.o: assym.s ${I386}/i386/swtch.s \
- $S/sys/errno.h ${I386}/isa/debug.h machine/asmacros.h
+ $S/sys/errno.h machine/asmacros.h
${CPP} -I. ${COPTS} ${I386}/i386/swtch.s | \
${AS} ${ASFLAGS} -o swtch.o
diff --git a/sys/i386/conf/SYSCONS b/sys/i386/conf/SYSCONS
deleted file mode 100644
index 2143ec61c60d..000000000000
--- a/sys/i386/conf/SYSCONS
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# SYSCONS -- Generic machine with WD/AHx family disks and syscons
-#
-# $Id: SYSCONS,v 1.18 1994/02/07 10:42:04 rgrimes Exp $
-#
-
-machine "i386"
-cpu "I386_CPU"
-cpu "I486_CPU"
-ident SYSCONS
-timezone 8 dst
-maxusers 10
-maxfdescs 2048 #Max file descriptors per process
-options MATH_EMULATE #Support for x87 emulation
-options INET #InterNETworking
-options ISOFS #ISO File System
-options NFS #Network File System
-options PCFS #MSDOS File System
-options "COMPAT_43" #Compatible with BSD 4.3
-options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
-options XSERVER #Xserver
-options UCONSOLE #X Console support
-options "NCONS=8" #8 virtual consoles
-options "FAT_CURSOR" #block cursor in syscons
-options "STAR_SAVER" #syscons "stars" screen saver
-#options GATEWAY #Host is a Gateway (forwards packets)
-
-config "386bsd" root on wd0 swap on wd0 and sd0 dumps on wd0
-
-controller isa0
-
-controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
-disk fd0 at fdc0 drive 0
-disk fd1 at fdc0 drive 1
-
-controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
-disk wd0 at wdc0 drive 0
-disk wd1 at wdc0 drive 1
-
-controller wdc1 at isa? port "IO_WD2" bio irq 15 vector wdintr
-disk wd2 at wdc1 drive 0
-disk wd3 at wdc1 drive 1
-
-controller ahb0 at isa? bio irq 11 vector ahbintr
-controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
-controller scbus0
-
-device sd0
-device sd1
-device sd2
-device sd3
-
-device st0
-device st1
-
-device cd0 #Only need one of these, the code dynamically grows
-
-device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
-device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
-
-device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
-device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
-device sio2 at isa? port "IO_COM3" tty irq 5 vector siointr
-device sio3 at isa? port "IO_COM4" tty irq 9 vector siointr
-
-device lpt0 at isa? port "IO_LPT3" tty irq 7 vector lptintr
-device lpa0 at isa? port "IO_LPT1" tty
-device lpa1 at isa? port "IO_LPT2" tty
-
-device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr
-device ed1 at isa? port 0x300 net irq 5 iomem 0xd8000 vector edintr
-device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
-device is0 at isa? port 0x280 net irq 10 drq 7 vector isintr
-
-device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
-
-pseudo-device loop
-pseudo-device ether
-pseudo-device log
-pseudo-device sl 2
-pseudo-device pty 4
-pseudo-device speaker
-
-pseudo-device swappager
-pseudo-device vnodepager
-pseudo-device devpager
diff --git a/sys/i386/conf/TIME b/sys/i386/conf/TIME
new file mode 100644
index 000000000000..bc9c0d8e8752
--- /dev/null
+++ b/sys/i386/conf/TIME
@@ -0,0 +1,64 @@
+#
+# GENERICBT -- Generic machine with WD/BTx family disks
+#
+# $Id: GENERICBT,v 1.35 1994/06/08 00:30:32 phk Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident TIME
+timezone 8 dst
+maxusers 10
+maxfdescs 1024 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options "NCONS=4" #4 virtual consoles
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+
+config "386bsd" root on sd0 swap on sd0 dumps on sd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller bt0 at isa? port "IO_BT0" bio irq 11 vector btintr
+controller scbus0
+
+device sd0
+device sd1
+
+device st0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ed0 at isa? port 0x360 net irq 10 iomem 0xd8000 iosiz 16384 vector edintr
+#device ix0 at isa? port 0x320 net irq 10 iomem 0xd8000 iosiz 32768 vector ixintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 2
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/WCARCH b/sys/i386/conf/WCARCH
new file mode 100644
index 000000000000..f228ec5752d8
--- /dev/null
+++ b/sys/i386/conf/WCARCH
@@ -0,0 +1,67 @@
+#
+# GENERICBT -- Generic machine with WD/BTx family disks
+#
+# $Id: GENERICBT,v 1.35 1994/06/08 00:30:32 phk Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident TIME
+timezone 8 dst
+maxusers 10
+maxfdescs 1024 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options "NCONS=4" #4 virtual consoles
+options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
+
+config "386bsd" root on sd0 swap on sd0 dumps on sd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+# driver for the Adaptec 154x SCSI cards.
+controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
+
+#controller bt0 at isa? port "IO_BT0" bio irq 11 vector btintr
+#controller scbus0
+
+device sd0
+device sd1
+
+device st0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ed0 at isa? port 0x360 net irq 10 iomem 0xd8000 iosiz 16384 vector edintr
+#device ix0 at isa? port 0x320 net irq 10 iomem 0xd8000 iosiz 32768 vector ixintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device sl 2
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/WCARCHIVE b/sys/i386/conf/WCARCHIVE
new file mode 100644
index 000000000000..0ce90784f3fd
--- /dev/null
+++ b/sys/i386/conf/WCARCHIVE
@@ -0,0 +1,73 @@
+#
+# GENERICAH -- Generic machine with WD/AHx family disks
+#
+# $Id: GENERICAH,v 1.36 1994/06/17 06:56:59 sean Exp $
+#
+
+machine "i386"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+ident WCARCHIVE
+timezone 8 dst
+maxusers 40
+maxfdescs 1024 #Max file descriptors per process
+options INET #InterNETworking
+options ISOFS #ISO File System
+options NFS #Network File System
+options PCFS #MSDOS File System
+options "COMPAT_43" #Compatible with BSD 4.3
+options "TCP_COMPAT_42" #TCP/IP compatible with 4.2
+options XSERVER #Xserver
+options UCONSOLE #X Console support
+options "FAT_CURSOR" #block cursor in syscons or pccons
+options GATEWAY #Host is a Gateway (forwards packets)
+options "SCSI_DELAY=10" #Be pessimistic about Joe SCSI device
+options "NCONS=4" #4 virtual consoles
+options "NMBCLUSTERS=1024" #Needed space for many ftp connections
+
+config "386bsd" root on sd0 swap on sd0 and sd1 and sd2 dumps on sd0
+
+controller isa0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+
+controller ahb0 at isa? bio irq 11 vector ahbintr
+controller ahb1 at isa? bio irq 12 vector ahbintr
+
+#controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
+#controller aha1 at isa? port 0x230 bio irq 12 drq 6 vector ahaintr
+
+controller scbus0
+controller scbus1
+
+device sd0
+device sd1
+device sd2
+device sd3
+device sd4
+device sd5
+device sd6
+device sd7
+
+device cd0 #Only need one of these, the code dynamically grows
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+
+device lpt0 at isa? port? tty irq 7 vector lptintr
+
+device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 flags 0x4 vector edintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device log
+pseudo-device pty 32
+pseudo-device speaker
+
+pseudo-device swappager
+pseudo-device vnodepager
+pseudo-device devpager
diff --git a/sys/i386/conf/devices.i386 b/sys/i386/conf/devices.i386
index c388159afee3..3abc0605aac1 100644
--- a/sys/i386/conf/devices.i386
+++ b/sys/i386/conf/devices.i386
@@ -1,6 +1,6 @@
# This file tells what major numbers the various possible swap devices have.
#
-# $Id: devices.i386,v 1.5 1994/01/04 20:09:28 nate Exp $
+# $Id: devices.i386,v 1.6 1994/03/21 20:48:49 ats Exp $
#
wd 0
dk 1
@@ -10,3 +10,4 @@ sd 4
st 5
cd 6
mcd 7
+scd 8
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 1b84847c7713..92a79684af05 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.25 1994/02/07 04:27:59 alm Exp $
+# $Id: files.i386,v 1.39 1994/06/16 05:31:20 jkh Exp $
#
i386/i386/autoconf.c standard device-driver
i386/i386/cons.c standard
@@ -17,53 +17,61 @@ i386/i386/pmap.c standard
i386/i386/sys_machdep.c standard
i386/i386/trap.c standard
i386/i386/vm_machdep.c standard
+i386/i386/random.s optional multicast
i386/isa/aha1542.c optional aha device-driver
i386/isa/aha1742.c optional ahb device-driver
i386/isa/bt742a.c optional bt device-driver
i386/isa/clock.c standard
i386/isa/com.c optional com device-driver
-i386/isa/dcfclk.c optional dcfclk device-driver
i386/isa/fd.c optional fd device-driver
i386/isa/ft.c optional ft device-driver
i386/isa/if_ed.c optional ed device-driver
+i386/isa/if_el.c optional el device-driver
i386/isa/if_ep.c optional ep device-driver
i386/isa/if_ie.c optional ie device-driver
i386/isa/if_is.c optional is device-driver
i386/isa/if_ix.c optional ix device-driver
i386/isa/isa.c optional isa device-driver
-i386/isa/lpa.c optional lpa device-driver
i386/isa/lpt.c optional lpt device-driver
i386/isa/mcd.c optional mcd device-driver
i386/isa/mse.c optional mse device-driver
i386/isa/npx.c optional npx device-driver
i386/isa/syscons.c optional sc device-driver
i386/isa/pccons.c optional pc device-driver
+i386/isa/pcaudio.c optional pca device-driver
i386/isa/psm.c optional psm device-driver
i386/isa/sb.c optional sb device-driver
+i386/isa/scd.c optional scd device-driver
+i386/isa/seagate.c optional sea device-driver
i386/isa/sg.c optional sg device-driver
i386/isa/sio.c optional sio device-driver
-i386/isa/sound/adlib_card.c optional snd device-driver
-i386/isa/sound/audio.c optional snd device-driver
-i386/isa/sound/dev_table.c optional snd device-driver
-i386/isa/sound/dmabuf.c optional snd device-driver
-i386/isa/sound/dsp.c optional snd device-driver
-i386/isa/sound/gus_card.c optional snd device-driver
-i386/isa/sound/gus_midi.c optional snd device-driver
-i386/isa/sound/gus_vol.c optional snd device-driver
-i386/isa/sound/gus_wave.c optional snd device-driver
-i386/isa/sound/midi.c optional snd device-driver
-i386/isa/sound/midibuf.c optional snd device-driver
-i386/isa/sound/mpu401.c optional snd device-driver
-i386/isa/sound/opl3.c optional snd device-driver
-i386/isa/sound/pas2_card.c optional snd device-driver
-i386/isa/sound/pas2_midi.c optional snd device-driver
-i386/isa/sound/pas2_mixer.c optional snd device-driver
-i386/isa/sound/pas2_pcm.c optional snd device-driver
-i386/isa/sound/patmgr.c optional snd device-driver
-i386/isa/sound/pro_midi.c optional snd device-driver
-i386/isa/sound/sb_card.c optional snd device-driver
-i386/isa/sound/sb_dsp.c optional snd device-driver
-i386/isa/sound/sequencer.c optional snd device-driver
+i386/isa/sound/adlib_card.c optional snd device-driver
+i386/isa/sound/audio.c optional snd device-driver
+i386/isa/sound/dev_table.c optional snd device-driver
+i386/isa/sound/dmabuf.c optional snd device-driver
+i386/isa/sound/gus_card.c optional snd device-driver
+i386/isa/sound/gus_midi.c optional snd device-driver
+i386/isa/sound/gus_vol.c optional snd device-driver
+i386/isa/sound/gus_wave.c optional snd device-driver
+i386/isa/sound/ics2101.c optional snd device-driver
+i386/isa/sound/midi.c optional snd device-driver
+i386/isa/sound/midibuf.c optional snd device-driver
+i386/isa/sound/mpu401.c optional snd device-driver
+i386/isa/sound/opl3.c optional snd device-driver
+i386/isa/sound/pas2_card.c optional snd device-driver
+i386/isa/sound/pas2_midi.c optional snd device-driver
+i386/isa/sound/pas2_mixer.c optional snd device-driver
+i386/isa/sound/pas2_pcm.c optional snd device-driver
+i386/isa/sound/patmgr.c optional snd device-driver
+i386/isa/sound/pro_midi.c optional snd device-driver
+i386/isa/sound/sb16_dsp.c optional snd device-driver
+i386/isa/sound/sb16_midi.c optional snd device-driver
+i386/isa/sound/sb_card.c optional snd device-driver
+i386/isa/sound/sb_dsp.c optional snd device-driver
+i386/isa/sound/sb_midi.c optional snd device-driver
+i386/isa/sound/sb_mixer.c optional snd device-driver
+i386/isa/sound/sequencer.c optional snd device-driver
+i386/isa/sound/sound_switch.c optional snd device-driver
i386/isa/sound/soundcard.c optional snd device-driver
i386/isa/spkr.c optional speaker
i386/isa/tw.c optional tw device-driver
@@ -76,3 +84,39 @@ i386/isa/pcvt/pcvt_out.c optional vt device-driver
i386/isa/pcvt/pcvt_kbd.c optional vt device-driver
i386/isa/pcvt/pcvt_vtf.c optional vt device-driver
i386/isa/pcvt/pcvt_ext.c optional vt device-driver
+i386/isa/if_ze.c optional ze device-driver
+gnu/fpemul/div_small.s optional gpl_math_emulate
+gnu/fpemul/errors.c optional gpl_math_emulate
+gnu/fpemul/fpu_arith.c optional gpl_math_emulate
+gnu/fpemul/fpu_aux.c optional gpl_math_emulate
+gnu/fpemul/fpu_entry.c optional gpl_math_emulate
+gnu/fpemul/fpu_etc.c optional gpl_math_emulate
+gnu/fpemul/fpu_trig.c optional gpl_math_emulate
+gnu/fpemul/get_address.c optional gpl_math_emulate
+gnu/fpemul/load_store.c optional gpl_math_emulate
+gnu/fpemul/poly_2xm1.c optional gpl_math_emulate
+gnu/fpemul/poly_atan.c optional gpl_math_emulate
+gnu/fpemul/poly_div.s optional gpl_math_emulate
+gnu/fpemul/poly_l2.c optional gpl_math_emulate
+gnu/fpemul/poly_mul64.s optional gpl_math_emulate
+gnu/fpemul/poly_sin.c optional gpl_math_emulate
+gnu/fpemul/poly_tan.c optional gpl_math_emulate
+gnu/fpemul/polynomial.s optional gpl_math_emulate
+gnu/fpemul/reg_add_sub.c optional gpl_math_emulate
+gnu/fpemul/reg_compare.c optional gpl_math_emulate
+gnu/fpemul/reg_constant.c optional gpl_math_emulate
+gnu/fpemul/reg_div.s optional gpl_math_emulate
+gnu/fpemul/reg_ld_str.c optional gpl_math_emulate
+gnu/fpemul/reg_mul.c optional gpl_math_emulate
+gnu/fpemul/reg_norm.s optional gpl_math_emulate
+gnu/fpemul/reg_round.s optional gpl_math_emulate
+gnu/fpemul/reg_u_add.s optional gpl_math_emulate
+gnu/fpemul/reg_u_div.s optional gpl_math_emulate
+gnu/fpemul/reg_u_mul.s optional gpl_math_emulate
+gnu/fpemul/reg_u_sub.s optional gpl_math_emulate
+gnu/fpemul/wm_shrx.s optional gpl_math_emulate
+gnu/fpemul/wm_sqrt.s optional gpl_math_emulate
+i386/pci/ncr.c optional ncr device-driver
+i386/pci/pci.c optional pci device-driver
+i386/pci/pcibios.c optional pci device-driver
+i386/pci/pci_config.c optional pci device-driver
diff --git a/sys/i386/doc/Changes b/sys/i386/doc/Changes
deleted file mode 100644
index 590f087f85bf..000000000000
--- a/sys/i386/doc/Changes
+++ /dev/null
@@ -1,209 +0,0 @@
-Hello, Emacs, this is an -*- Indented-Text -*- file!
-
-$Id: Changes,v 1.15 1994/02/21 23:03:09 rgrimes Exp $
-
-This file is intended to keep track of important kernel and user
-changes in FreeBSD between releases. Entries are in reverse
-chronological order; userids can be decoded with the chart at the end
-of this file.
-
-Since 1.1 BETA:
-
-Between 1.1 BETA and 1.0.2:
-- Improved lpt driver, should no longer lock up when lprm is done on
- an active job. Fixed up the probe routine so that it works on most
- if not all printers now. (csgr/rgrimes)
-
-- Substantial changes to system configuration; you MUST re-build
- `config' before attempting to build a 1.1 kernel. (nate/martin)
-
-- Improved the quality of the information given to the user when
- a fatal trap occurs. (davidg)
-
-- Added support in the if_ed driver for the WD8013W, WD8003W, and
- WD8003EB. (davidg)
-
-- Change to generic console code to eliminate console hangs with all
- `pc' consoles. (davidg)
-
-- Upgrade to new version of syscons which handles the `hanging console'
- problem and adds some new features and code cleanup. (nate)
-
-- Various TCP bugs fixed - don't forward loopback packets; Nagel
- congestion avoidence - immediately ack small packets. (davidg)
-
-- TCP debugging code is now truly optional, thus reducing kernel size
- when it is disabled (the default). (davidg)
-
-- Because the `sio' FIFOs are now configurable, the `com' driver is no
- longer supported. (team sighs with relief)
-
-- Performance and stylistic improvements to the `sio' serial driver.
- Probe code now works somewhat better for oddball devices. The 16550
- FIFO length is now configurable using `flags' in the config
- declaration. (ache/bde)
-
-- Performance improvements and complete implementation of POSIX VMIN
- and VTIME for the generic TTY code. (ache/bde)
-
-- Crash dumps on SCSI disks now work and are standard. (rgrimes/davidg)
-
-- QMAGIC is now the official default executable format. (davidg)
-
-- Network booting is now supported, as is booting from DOS. (martin)
-
-- Local LDTs are now supported for WINE (based on work by John Brezak).
- (hsu/davidg)
-
-- DDB will now print symbolic arguments and line numbers in
- backtraces (from John Brezak). (davidg)
-
-- Added four pattern memory test to eliminate problems with buggy
- chipsets that incorrectly map memory, and to find problems with
- defective memory. The memory sizing code has been improved to
- further eliminate problems with buggy chipsets/BIOSs. (davidg)
-
-- USE_486_WRITE_PROTECT is now gone; the system will automatically
- detect 486 CPUs and behave accordingly. (davidg)
-
-- Added SysV IPC, messaging, and semaphore code by Danny Boulet.
- (hsu/davidg)
-
-- Because of the VM system changes, Paul Kranenburg's process
- filesystem is now MANDATORY in order for `ps' and friends to be able
- to dig up process information which has been paged out. (davidg)
-
-- Substantial VM system improvements: (dyson/davidg)
- o FreeBSD once again works on 4-MB machines.
- o Maximum and default size limits set to reasonable values.
- o The user area is now in the process address space, and can
- now be paged out along with the rest of the process.
- o Process page tables can now be paged out.
- o The physical map (pmap) module has been mostly rewritten for
- efficiency, and is considerably faster than it used to be.
- o The pageout system now actually implements modified LRU.
- o Process RSS soft limits implemented. Hooks are in place for
- RSS hard limits.
- o Pagers can now do multiple-page operations ("page fault
- clustering"), and page fault read behind and read ahead
- have been implemented to take advantage of this.
- o The vnode pager no longer drags pages through the buffer
- cache, eliminating an expensive memory copy and flushing
- of cached data.
- o When the system runs out of swap space, the faulting process
- is killed off (with a message to syslog); the old code would
- just deadlock.
- o Swap space allocation is much more efficient, and swap
- striping actually works now. It's now possible for every
- last block of swap space to be used before the systems runs
- out.
- o The pagedaemon's algorithms are considerably improved, thus
- reducing the amount of CPU time used by the pagedaemon.
- o All kernels MUST now load at virtual address 0xf010000, and
- the lower 640k is reclaimed for system use. This removes
- the 640K kernel size limit.
- o VM object cache size is now dynamic and a function of the
- kernel 'maxusers' parameter.
- o Memory in the I/O hole is explicitly marked non-cacheable.
-
-- Added 3C509 driver written by Herb Peyerl. (ats/nate)
-
-- Added a new 'wd' driver which does a much better job of probing, handles
- stray interrupts better, and supports multiple controllers. In addition
- this driver supports DOS partitions much better and conforms to ATA specs
- much better. NB: configuration lines for this driver are different
- than those for pervious versions; see a GENERIC for details.
- (nate/bde/guido)
-
-- Added support in the if_ed driver for the Toshiba ethernet cards.The
- support must be enabled with an "options TOSH_ETHER" in the config
- file. Done it this way, because i don't know how widespread the cards
- are. (ats)
-
-- Added support in the if_ed driver for the SMC Ultra via patches from
- Glen Lowe. (davidg)
-
-- Updated Mitsumi CD driver to work with FX models. (jkh/Gary
- Clark II)
-
-- Add extended formats set to floppy driver, improve autoconfiguration,
- add "fdformat" utility for floppy formatting.
- The format of floppy disk minor numbers has changed, thus
- necessitating a new `MAKEDEV fd'. (ache/joerg/Serge Vakulenko)
-
-- Add XNTPD to contrib section, and (un-compilable) kernel support for
- same to /sys/kern. (wollman)
-
-- Use linker-constructed sets to initialize certain system tables
- rather than manually enumerating all the options in the source files.
- This makes certain pseudo-devices and all image activators drop-in at
- link time, if desired. (wollman)
-
-- Added YP code from Theo Deraadt. (paul/nate)
-
-- Make all mandatory options ``standard''. (wollman)
-
-- Update `wt' driver to support more devices and controllers. The
- driver will also auto-detect tape density on models which support
- it. The structure of `wt' device minor numbers has changed;
- `MAKEDEV wt' must be run to create the new device nodes.
-
-- Re-design execve() system call to allow for multiple ``image activators''
- which recognize and load various file formats. Currently only
- a.out and interpreted formats are recognized. (davidg)
-
-- Provide the address of the faulting reference to signal handlers, to
- make life easier for smart garbage-collection algorithms. (hsu)
-
-- New, improved process tracing code from Sean Eric Fagan. (davidg)
-
-- Re-organize locore into several different source files according to
- function. (davidg)
-
-- On panic, don't reboot right away but give the user some time to
- abort the reboot or at least write down the panic message. (davidg)
-
-- Kernel timezone handling is now delegated to an external program,
- `adjkerntz'. No more bogus summer time jumps. (ache)
-
-- Separate all IP-related variables that users might want to modify into
- netinet/in_var.c. (wollman)
-
-- New, redesigned SCSI system; should run faster and have fewer bugs.
- (julian)
-
-- Make it possible to mmap(2) /dev/mem. (julian)
-
-Between 1.0.2 and 1.0:
-
-Between 1.0 EPSILON and 1.0 GAMMA:
-
-Between 1.0 GAMMA and 1.0 BETA:
-
-Between 1.0 BETA and 1.0 ALPHA:
-
-Between 1.0 ALPHA and Patchkit 0.2.4:
-
-Userids map as follows:
-ache Andrew Chernov
-alm Andrew Moore
-ats Andreas Schulz
-chmr Christoph Robitscho
-csgr Geoff Rehmet
-davidg David Greenman
-dyson John Dyson
-guido Guido van Rooij
-hsu Jeffrey Hsu
-jkh Jordan Hubbard
-joerg Joerg Wunsch
-jtc J.T. Conklin
-ljo L. Jonas Olson
-martin Martin Renters
-nate Nate Williams
-paul Paul Richards
-proven Chris Provenzano
-rich Rich Murphey
-rls Rob Shady
-smace Scott Mace
-swallace Steven Wallace
-wollman Garrett Wollman
diff --git a/sys/i386/doc/Makefile b/sys/i386/doc/Makefile
deleted file mode 100644
index 67fb36b0ceac..000000000000
--- a/sys/i386/doc/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# $Id: Makefile,v 1.1 1993/11/06 00:07:42 wollman Exp $
-#
-# Makefile for /sys/i386/doc
-# This creates options.info and options.doc from options.texi, if the
-# GNU makeinfo program is present, and fails miserably otherwise.
-#
-
-all: options.info options.doc
-
-options.info: options.texi
- makeinfo options.texi
-
-options.doc: options.texi
- makeinfo -o options.doc+ --no-headers options.texi
- sed '/^General Index/,$$d' < options.doc+ > options.doc
- rm -f options.doc+
-
-clean:
- rm -f options.info options.doc options.doc+
diff --git a/sys/i386/doc/ata/ata-1 b/sys/i386/doc/ata/ata-1
deleted file mode 100644
index 5486217b026b..000000000000
--- a/sys/i386/doc/ata/ata-1
+++ /dev/null
@@ -1,45 +0,0 @@
- Information Processing Systems --
-
- Common Access Method --
-
- AT Attachment
-
-
-1. Scope
-
-This standard defines the CAM (Common Access Method) AT Attachment.
-
-The CAM Committee was formed in October, 1988 and the first working document
-of the AT Attachment was introduced in March, 1989.
-
-1.1 Description of Clauses
-
-Clause 1 contains the Scope and Purpose.
-
-Clause 2 contains Referenced and Related International Standards.
-
-Clause 3 contains the General Description.
-
-Clause 4 contains the Glossary.
-
-Clause 5 contains the electrical and mechanical characteristics; covering
-the interface cabling requirements of the DC, data cables and connectors.
-
-Clause 6 contains the signal descriptions of the AT Attachment interface.
-
-Clause 7 contains descriptions of the registers of the AT Attachment
-interface.
-
-Clause 8 describes the programming requirements of the AT Attachment
-interface.
-
-Clause 9 contains descriptions of the commands of the AT Attachment interface.
-
-Clause 10 contains an overview of the protocol of the AT Attachment interface.
-
-Clause 11 contains the interface timing diagrams.
-
-Annex A is informative.
-
-Annex B is informative.
-
diff --git a/sys/i386/doc/ata/ata-10 b/sys/i386/doc/ata/ata-10
deleted file mode 100644
index f4c0336944d4..000000000000
--- a/sys/i386/doc/ata/ata-10
+++ /dev/null
@@ -1,213 +0,0 @@
-10. Protocol Overview
-
-Commands can be grouped into different classes according to the protocols
-followed for command execution. The command classes with their associated
-protocols are defined below.
-
-For all commands, the host first checks if BSY=1, and should proceed no
-further unless and until BSY=0. For most commands, the host will also wait for
-DRDY=1 before proceeding. Those commands shown with DRDY=x can be executed
-when DRDY=0.
-
-Data transfers may be accomplished in more ways than are described below, but
-these sequences should work with all known implementations of ATA drives.
-
-10.1 PIO Data In Commands
-
-This class includes:
-
- - Identify Drive
- - Read Buffer
- - Read Long
- - Read Sector(s)
-
-Execution includes the transfer of one or more 512 byte (>512 bytes on Read
-Long) sectors of data from the drive to the host.
-
- a) The host writes any required parameters to the Features, Sector Count,
- Sector Number, Cylinder and Drive/Head registers.
- b) The host writes the command code to the Command Register.
- c) The drive sets BSY and prepares for data transfer.
- d) When a sector of data is available, the drive sets DRQ and clears BSY
- prior to asserting INTRQ.
- e) After detecting INTRQ, the host reads the Status Register, then reads one
- sector of data via the Data Register. In response to the Status Register
- being read, the drive negates INTRQ.
- f) The drive clears DRQ. If transfer of another sector is required, the drive
- also sets BSY and the above sequence is repeated from d).
-
-10.1.1 PIO Read Command
-
- +- a) -+-- b) -+ +- e) -+--------+ +- e) -+--------+
- |Setup | Issue | | Read |Transfer| | Read |Transfer|
- | |Command| |Status| Data |:::::::|Status| Data |
- +------+-------+ +------+--------+ +------+--------+
- |BSY=0 | |BSY=1 |BSY=0 | |BSY=1 |BSY=0 | |BSY=1
- |DRDY=1 | | | | | |
- |DRQ=1 | |DRQ=0 |DRQ=1 | |DRQ=0
- |Assert|Negate | |Assert|Negate
- INTRQ INTRQ INTRQ INTRQ
-
-If Error Status is presented, the drive is prepared to transfer data, and it
-is at the host's discretion that the data is transferred.
-
-10.1.2 PIO Read Aborted Command
-
- +- a) -+-- b) -+ +- e) -+
- |Setup | Issue | | Read |
- | |Command| |Status|
- +------+-------+ +------+
- |BSY=0 | |BSY=1 |BSY=0 |
- |DRDY=1 | |
- |DRQ=1 |DRQ=0
- |Assert|Negate
- INTRQ INTRQ
-
-Although DRQ=1, there is no data to be transferred under this condition.
-
-10.2 PIO Data Out Commands
-
-This class includes:
-
- - Format
- - Write Buffer
- - Write Long
- - Write Sector(s)
-
-Execution includes the transfer of one or more 512 byte (>512 bytes on Write
-Long) sectors of data from the drive to the host.
-
- a) The host writes any required parameters to the Features, Sector Count,
- Sector Number, Cylinder and Drive/Head registers.
- b) The host writes the command code to the Command Register.
- c) The drive sets DRQ when it is ready to accept the first sector of data.
- d) The host writes one sector of data via the Data Register.
- e) The drive clears DRQ and sets BSY.
- f) When the drive has completed processing of the sector, it clears BSY and
- asserts INTRQ. If transfer of another sector is required, the drive also
- sets DRQ.
- g) After detecting INTRQ, the host reads the Status Register.
- h) The drive clears the interrupt.
- i) If transfer of another sector is required, the above sequence is repeated
- from d).
-
-10.2.1 PIO Write Command
-
- +- a) -+-- b) -+ +--------+ +- e) -+--------+ +- e) -+
- |Setup | Issue | |Transfer| | Read |Transfer| | Read |
- | |Command| | Data | |Status| Data |:::::::|Status|
- +------+-------+ +--------+ +------+--------+ +------+
- |BSY=0 | |BSY=1 |BSY=0 |BSY=1 |BSY=0 | |BSY=1 |BSY=0 |
- |DRDY=1 | | | | | | |
- |DRQ=1 |DRQ=0 |DRQ=1 | |DRQ=0 | |
- | | |Assert|Negate | |Assert|Negate
- INTRQ INTRQ INTRQ INTRQ
-
-10.2.2 PIO Write Aborted Command
-
- +- a) -+-- b) -+ +- e) -+
- |Setup | Issue | | Read |
- | |Command| |Status|
- +------+-------+ +------+
- |BSY=0 | |BSY=1 |BSY=0 |
- |DRDY=1 | |
- | |Assert|Negate
- INTRQ INTRQ
-
-10.3 Non-Data Commands
-
-This class includes:
-
- - Execute Drive Diagnostic (DRDY=x)
- - Idle
- - Initialize Drive Parameters (DRDY=x)
- - Read Power Mode
- - Read Verify Sector(s)
- - Recalibrate
- - Seek
- - Set Features
- - Set Multiple Mode
- - Standby
-
-Execution of these commands involves no data transfer.
-
- a) The host writes any required parameters to the Features, Sector Count,
- Sector Number, Cylinder and Drive/Head registers.
- b) The host writes the command code to the Command Register.
- c) The drive sets BSY.
- d) When the drive has completed processing, it clears BSY and asserts INTRQ.
- g) The host reads the Status Register.
- h) The drive negates INTRQ.
-
-10.4 Miscellaneous Commands
-
-This class includes:
-
- - Read Multiple
- - Sleep
- - Write Multiple
- - Write Same
-
-The protocol for these commands is contained in the individual command
-descriptions.
-
-10.5 DMA Data Transfer Commands (Optional)
-
-This class comprises:
-
- - Read DMA
- - Write DMA
-
-Data transfers using DMA commands differ in two ways from PIO transfers:
-
- - data transfers are performed using the slave-DMA channel
- - no intermediate sector interrupts are issued on multi-sector commands
-
-Initiation of the DMA transfer commands is identical to the Read Sector or
-Write Sector commands except that the host initializes the slave-DMA channel
-prior to issuing the command.
-
-The interrupt handler for DMA transfers is different in that:
-
- - no intermediate sector interrupts are issued on multi-sector commands
- - the host resets the DMA channel prior to reading status from the drive.
-
-The DMA protocol allows high performance multi-tasking operating systems to
-eliminate processor overhead associated with PIO transfers.
-
- a) Command Phase
- 1) Host initializes the slave-DMA channel
- 2) Host updates the Command Block Registers
- 3) Host writes command code to the Command Register
- b) Data Phase - the register contents are not valid during a DMA Data Phase.
- 1) The slave-DMA channel qualifies data transfers to and from the drive
- with DMARQ
- c) Status Phase
- 1) Drive generates the interrupt to the host
- 2) Host resets the slave-DMA channel
- 3) Host reads the Status Register and Error Register
-
-10.5.1 Normal DMA Transfer
-
- +--------------+-------+ +---------------------+ +---------+------+
- |Initialize DMA|Command| | DMA Data Transfer | |Reset DMA|Status|
- +--------------+-------+ +---------------------+ +---------+------+
- |BSY=0 |BSY=1 |BSY=x |BSY=1 |BSY=0
- |DRQ=x |nIEN=0
-
-10.5.2 Aborted DMA Transfer
-
- +--------------+-------+ +-------------+ +---------+------+
- |Initialize DMA|Command| | DMA Data | |Reset DMA|Status|
- +--------------+-------+ +-------------+ +---------+------+
- |BSY=0 |BSY=1 |BSY=x |BSY=1 |BSY=0
- |DRQ=1 |nIEN=0
-
-10.5.3 Aborted DMA Command
-
- +--------------+-------+ +---------+------+
- |Initialize DMA|Command| |Reset DMA|Status|
- +--------------+-------+ +---------+------+
- |BSY=0 |BSY=1 |BSY=1 |BSY=0
- |nIEN=0
-
diff --git a/sys/i386/doc/ata/ata-11 b/sys/i386/doc/ata/ata-11
deleted file mode 100644
index bba6a1073cc8..000000000000
--- a/sys/i386/doc/ata/ata-11
+++ /dev/null
@@ -1,201 +0,0 @@
-11. Timing
-
-11.1 Deskewing
-
-The host shall provide cable deskewing for all signals originating from the
-controller. The drive shall provide cable deskewing for all signals
-originating at the host.
-
-11.2 Symbols
-
-Certain symbols are used in the timing diagrams. These symbols and their
-respective definitions are listed below.
-
- / or \ - signal transition (asserted or negated) *
- < or > - data transition (asserted or negated)
- XXXXXX - undefined but not necessarily released
- . . . - the "other" condition if a signal is shown with no change
- #n - used to number the sequence in which events occur e.g. #a, #b
- _ _ __
-__/_ _/ - a degree of uncertainty as to when a signal may be asserted
-
-__ _ _
- \_ _\__ - a degree of uncertainty as to when a signal may be negated
-
-.. T - Nominal Clock Period
-..
- * All signals are shown with the Asserted condition facing to the top of
- the page. The negated condition is shown towards the bottom of the page
- relative to the asserted condition.
-
-..Within each figure the timing terms i.e. tA, tB etc are repeated. There is
-..no continuity of definition of tA from one figure to another.
-..
-11.3 Terms
-
-The interface uses a mixture of negative and positive signals for control and
-data. The terms asserted and negated are used for consistency and are
-independent of electrical characteristics.
-
-In all timing diagrams, the lower line indicates negated, and the upper line
-indicates asserted e.g. the following illustrates the representation of a
-signal named TEST going from negated to asserted and back to negated, based on
-the polarity of the signal.
-
- Assert Negate
- | |
- Bit Setting=1 |__________|
- Bit Setting=0 TEST _____/ \_______
-
- Assert Negate
- | |
- Bit Setting=0 |__________|
- Bit Setting=1 TEST- _____/ \_______
-
-.. Processor I/O Write, 16 Bit:
-11.4 Data Transfers
-
-Figure 11-1 defines the relationships between the interface signals for both
-16-bit and 8-bit data transfers.
-
- |<------------ t0 -------------------->|
- __________________________________________ |
- Address Valid *1 ...../ \________
- |<-t1->| ->| t9 |<-
- ->|t7|<- |<----------- t2 ------------->| ->|t8|<-
- | | |______________________________| | |_____
- DIOR-/DIOW- ____________/ \_______/
- | | |_ _ _ _ _ _ _ _ _ _ _____________ |
- Write Data Valid *2__________/_ _ _ _ _ _ _ _ _ _/ \__________
- | | | |<--t3---->| |
- | | | ->|t4|<- |
- | | |_ _ _ _ _ _ _ _ _ _ _ ___________ |
- Read Data Valid *2__________/_ _ _ _ _ _ _ _ _ _ _/ | \__________
- | | | |<--t5-->| | |
- | | | ->|t6|<- |
- | | | | | |
- | |__________________________________________|
- IOCS16- ________/ \_____
-
- *1 Drive Address consists of signals CS1FX-, CS3FX- and DA2-0
- *2 Data consists of DD0-15 (16-bit) or DD0-7 (8-bit)
-
- +------------------------------------------+-------+-------+-------+
- | PIO | Mode 0| Mode 1| Mode 2|
- | Timing Parameters | nsec | nsec | nsec |
- +----+------------------------------------------+-------+-------+-------+
- | t0 | Cycle Time (Min) | 600 | 383 | 240 |
- | t1 | Address Valid to DIOR-/DIOW- Setup (Min) | 70 | 50 | 30 |
- | t2 | DIOR-/DIOW- 16-bit (Min) | 165 | 125 | 100 |
- | | Pulse Width 8-bit (Min) | 290 | 290 | 290 |
- | t3 | DIOW- Data Setup (Min) | 60 | 45 | 30 |
- | t4 | DIOW- Data Hold (Min) | 30 | 20 | 15 |
- | t5 | DIOR- Data Setup (Min) | 50 | 35 | 20 |
- | t6 | DIOR- Data Hold (Min) | 5 | 5 | 5 |
- | t7 | Addr Valid to IOCS16- Assertion (Max) | 90 | 50 | 40 |
- | t8 | Addr Valid to IOCS16- Negation (Max) | 60 | 45 | 30 |
- | t9 | DIOR-/DIOW- to Address Valid Hold (Min) | 20 | 15 | 10 |
- +----+------------------------------------------+-------+-------+-------+
-..rm102
-.. NOTE: These are minimum acceptable interface timing requirements.
-
- FIGURE 11-1: PIO DATA TRANSFER TO/FROM DRIVE
-
- ___________________________________
- DIOR-/DIOW- __________/ \______________
- |
- |<- tA ->|<--- tB ---->|
- ___________________| |_____________________
- IORDY \___________________/
-
- Label Description Min Max Units
-
- tA IORDY Setup time - 35 nsecs
- tB IORDY Pulse Width - 1,250 nsecs
-
- WARNING: The use of IORDY for data transfers is a system integration issue
- which requires control of both ends of the cable.
-
- FIGURE 11-2: IORDY TIMING REQUIRMENTS
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- |<----------------------- t0 ---------------------->|
- ____________ _______
- DMARQ ___/ \______________________________________/ |
- |<- tC ->| |
- |_____________________________________________ |___
- DMACK- _______/ \_____/
- |<--- tI --->|________________|<----- tJ -----| |
- DIOR-/DIOW- ____________________/ \_________________________
- | | | |
- | |<------ tD ---->| |
- Read | ______________ |
- DD0-15 -------------------------------<______________>----------------
- | |<-- tE -->| |<- tF ->| |
- Write | _________________________ |
- DD0-15 --------------------------<_________________________>-----------
- | | | | |
- | |<-- tG -->|<-- tH -->| |
-
- +----------------------------------+-------+-------+-------+
- | DMA | Mode 0| Mode 1| Mode 2|
- | Timing Parameters | nsec | nsec | nsec |
- +----+----------------------------------+-------+-------+-------+
- | t0 | Cycle Time (Min) | 960 | 480 | 240 |
- | tC | DMACK to DMREQ Delay (Max) | 200 | 100 | 80 |
- | tD | DIOR-/DIOW- 16-bit (Min) | 480 | 240 | 120 |
- | tE | DIOR- Data Setup (Min) | 250 | 150 | 50 |
- | tF | DIOR- Data Hold (Min) | 5 | 5 | 5 |
- | tG | DIOW- Data Setup (Min) | 250 | 100 | 35 |
- | tH | DIOW- Data Hold (Min) | 50 | 30 | 20 |
- | tI | DMACK to DIOR-/DIOW- Setup (Min) | 0 | 0 | 0 |
- | tJ | DIOR-/DIOW- to DMACK Hold (Min) | 0 | 0 | 0 |
- +----+----------------------------------+-------+-------+-------+
-
- FIGURE 11-3: DMA DATA TRANSFER
-
-11.5 Power On and Hard Reset
-
- ______
- RESET- _____/ \_____________________________________________________
- |<-tM->|
- | | Drive 0
- _ _ _ _ _ _ _ _______ _ _ _ _ _ _ _ _ _ _ _ _ _|
- BSY _ _ _ _ _ _ _/ \_ _ _ _ _ *1 _ _ _ _ _ _\________________
- ->|tN|<-
- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
- DASP- _ _ _ _ _ _ _ _\_______/_ _ _ _ *2 _ _ _ _ _ _ _ _ _ _\=== *3 ==
- ->| tP |<- | |_ _ _ __________
- Control Registers_______________________________________/_ _ _ /
- | | |
- | | | Drive 1
- _ _ _ _ _ _ _ _ _________________________________|
- BSY _ _ _ _ _ _ _ _/ \________________
- _ _ _ _ _ _ _ _ _ _ ______ _ _ _ _ _
- PDIAG- _ _ _ _ _ _ _ _ _ _\____________________________/ \_ _ _ _ _
- | | | |<----------- tQ -------->|
- _ _ _ _ _ _ _ _ _ _________________________ _ _ _
- DASP- _ _ _ _ _ _ _ _ _\_____/ \ _ _ _\=== *3 ==
- |<- tR ->|<------------ tS -------------->|
- _ _ _ __________
- Control Registers_______________________________________/_ _ _ /
-
- *1 Drive 0 can set BSY=0 if Drive 1 not present
- *2 Drive 0 can use DASP- to indicate it is active if Drive 1 is not
- present
- *3 DASP- can be asserted to indicate that the drive is active
- +-------------------+------------+
- | Label | Units |
- +-------------------+------------+
- | tM (Min) | 25 usec |
- | tN (Max) | 400 nsec |
- | tP (Max) | 1 msec |
- | tQ (Max) | 30 secs |
- | tR Drive 0 (Max) | 450 msec |
- | tR Drive 1 (Max) | 400 msec |
- | tS (Max) | 30.5 secs |
- +-------------------+------------+
-
- FIGURE 11-4 RESET SEQUENCE
-
diff --git a/sys/i386/doc/ata/ata-2 b/sys/i386/doc/ata/ata-2
deleted file mode 100644
index bad2d9eea869..000000000000
--- a/sys/i386/doc/ata/ata-2
+++ /dev/null
@@ -1,4 +0,0 @@
-2. References
-
-None.
-
diff --git a/sys/i386/doc/ata/ata-3 b/sys/i386/doc/ata/ata-3
deleted file mode 100644
index 54645e040b7f..000000000000
--- a/sys/i386/doc/ata/ata-3
+++ /dev/null
@@ -1,27 +0,0 @@
-3. General Description
-
-The application environment for the AT Attachment is any computer which uses
-an AT Bus or 40-pin ATA interface.
-
-The AT Bus is a widely used and implemented interface for which a variety of
-peripherals have been manufactured. As a means of reducing size and cost, a
-class of products has emerged which embed the controller functionality in the
-drive. These new products utilize the AT Bus fixed disk interface protocol,
-and a subset of the AT bus. Because of their compatibility with existing AT
-hardware and software this interface quickly became a de facto industry
-standard.
-
-The purpose of the ATA standard is to define the de facto implementations.
-
-Software in the Operating System dispatches I/O (Input/Output) requests via
-the AT Bus to peripherals which respond to direct commands.
-
-3.1 Structure
-
-This standard relies upon specifications of the mechanical and electrical
-characteristics of the AT Bus and a subset of the AT Bus specifically
-developed for the direct attachment of peripherals.
-
-Also defined are the methods by which commands are directed to peripherals,
-the contents of registers and the method of data transfers.
-
diff --git a/sys/i386/doc/ata/ata-4 b/sys/i386/doc/ata/ata-4
deleted file mode 100644
index 0c2fb638ce8d..000000000000
--- a/sys/i386/doc/ata/ata-4
+++ /dev/null
@@ -1,59 +0,0 @@
-4. Definitions and Conventions
-
-4.1 Definitions
-
-For the purpose of this standard the following definitions apply:
-
-4.1.1 ATA (AT Attachment): ATA defines a compatible register set and a 40-pin
-connector and its associated signals.
-
-4.1.2 Data block: This term describes a data transfer, and is typically a
-single sector, except when declared otherwise by use of the Set Multiple
-command.
-
-4.1.3 DMA (Direct Memory Access): A means of data transfer between
-peripheral and host memory without processor intervention.
-
-4.1.4 Optional: This term describes features which are not required by the
-standard. However, if any feature defined by the standard is implemented, it
-shall be done in the same way as defined by the standard. Describing a feature
-as optional in the text is done to assist the reader. If there is a conflict
-between text and tables on a feature described as optional, the table shall be
-accepted as being correct.
-
-4.1.5 PIO (Programmed Input/Output): A means of data transfer that requires
-the use of the host processor.
-
-4.1.6 Reserved: Where this term is used for bits, bytes, fields and code
-values; the bits, bytes, fields and code values are set aside for future
-standardization, and shall be zero.
-
-..4.1.10 VU (Vendor Unique): This term defines those features that can be
-..defined by the vendor in a specific implementation. Caution should be
-..exercised in defining and using such features since they may or may not
-..vary between vendors.
-..
-4.1.7 VU (Vendor Unique): This term is used to describe bits, bytes,
-fields, code values and features which are not described in this standard,
-and may be used in a way that varies between vendors.
-
-4.2 Conventions
-
-Certain terms used herein are the proper names of signals. These are printed
-in uppercase to avoid possible confusion with other uses of the same words;
-e.g., ATTENTION. Any lowercase uses of these words have the normal American-
-English meaning.
-
-A number of conditions, commands, sequence parameters, events, English text,
-states or similar terms are printed with the first letter of each word in
-uppercase and the rest lowercase; e.g., In, Out, Request Status. Any lowercase
-uses of these words have the normal American-English meaning.
-
-The American convention of numbering is used i.e., the thousands and higher
-multiples are separated by a comma and a period is used as the decimal point.
-This is equivalent to the ISO convention of a space and comma.
-
- American: 0.6 ISO: 0,6
- 1,000 1 000
- 1,323,462.9 1 323 462,9
-
diff --git a/sys/i386/doc/ata/ata-5 b/sys/i386/doc/ata/ata-5
deleted file mode 100644
index c120a39b3736..000000000000
--- a/sys/i386/doc/ata/ata-5
+++ /dev/null
@@ -1,189 +0,0 @@
-5. Interface Cabling Requirements
-
-5.1 Configuration
-
-This standard provides the capability of operating on the AT Bus in a daisy
-chained configuration with a second drive that operates in accordance with
-these standards. One drive (selected as Drive 0) has been referred to as the
-master in industry terms and the second (selected as Drive 1) has been
-referred to as the slave (see Figure 5-3).
-
-The designation as Drive 0 or Drive 1 is made by a jumper plug or switch on
-the drive.
-
-Data is transferred in parallel (8 or 16 bits) either to or from host memory
-to the drive's buffer under the direction of commands previously transferred
-from the host. The drive performs all of the operations necessary to properly
-write data to, or read data from, the disk media. Data read from the media is
-stored in the drive's buffer pending transfer to the host memory and data is
-transferred from the host memory to the drive's buffer to be written to the
-media.
-
- +-----------------------------------------------------+
- | |
- | HOST |
- | |
- +---------------^-------------------------------------+
- | ATA Interface
- | _____________________
- |/ |
- +------v--+ +------v--+
- | DRIVE 0 | | DRIVE 1 |
- +---------+ +---------+
-
- FIGURE 5-1: ATA INTERFACE TO EMBEDDED BUS PERIPHERALS
-
- +-----------------------------------------------------+
- | |
- | HOST |
- | |
- +------+====== AT Bus ======+-------------------------+
- | |
- | ADAPTER |
- | |
- +--------^-----------+
- | ATA Interface
- | _____________________
- |/ |
- +------v--+ +------v--+
- | DRIVE 0 | | DRIVE 1 |
- +---------+ +---------+
-
- FIGURE 5-2: HOST BUS ADAPTER AND PERIPHERAL DEVICES
-
- +-----------------------------------------------------+
- | |
- | HOST |
- | |
- +---------------^-------------------------------------+
- | ATA Interface
- +------v-----+
- | |
- | CONTROLLER |
- | |
- +-^----^---^-+
- | | |__________________ Device Interface
- | ___|_________________ | e.g. ESDI, SCSI
- |/ | | |
- +-v----v--+ +-v----v--+
- | DRIVE | | DRIVE |
- +---------+ +---------+
-
- FIGURE 5-3: ATA INTERFACE TO CONTROLLER AND PERIPHERAL DEVICES
-
-5.2 Addressing Considerations
-
-In traditional controller operation, only the selected controller receives
-commands from the host following selection. In this standard, the register
-contents go to both drives (and their embedded controllers). The host
-discriminates between the two by using the DRV bit in the Drive/Head Register.
-
-5.3 DC Cable and Connector
-
-The drive receives DC power through a 4-pin or a low-power application 3-pin
-connector.
-
-5.3.1 4-Pin Power
-
-The pin assignments are shown in Table 5-1. Recommended part numbers for the
-mating connector to 18AWG cable are shown below, but equivalent parts may be
-used.
-
- Connector (4 Pin) AMP 1-480424-0 or equivalent.
- Contacts (Loose Piece) AMP 60619-4 or equivalent.
- Contacts (Strip) AMP 61117-4 or equivalent.
-
- TABLE 5-1: DC INTERFACE
- +------------------------+------------+
- | POWER LINE DESIGNATION | PIN NUMBER |
- +------------------------+------------+
- | +12 V | 1-01 |
- | +12 V RETURN | 1-02 |
- | +5 V RETURN | 1-03 |
- | +5 V | 1-04 |
- +------------------------+------------+
-
-5.3.2 3-Pin Power
-
-The pin assignments are shown in Table 5-2. Recommended part numbers for the
-mating connector to 18AWG cable are shown below, but equivalent parts may be
-used.
-
- Connector (3 Pin) Molex 5484 39-27-0032 or equivalent.
-
- TABLE 5-2: DC INTERFACE
- +------------------------+------------+
- | POWER LINE DESIGNATION | PIN NUMBER |
- +------------------------+------------+
- | +12 V | 1-01 |
- | Ground | 1-02 |
- | +5 V | 1-03 |
- +------------------------+------------+
-
-5.3.3 Device Grounding
-
-System ground may be connected to a "quick-connect" terminal equivalent to:
-
- Drive Connector Terminal AMP 61664-1 or equivalent.
- Cable Connector Terminal AMP 62137-2 or equivalent.
-
-Provision for tying the DC Logic ground and the chassis ground together or for
-separating these two ground planes is vendor specific.
-
-5.4 I/O Connector
-
-The I/O connector is a 40-pin connector as shown in Figure 5-4, with pin
-assignments as shown in Table 6-1.
-
-The connector should be keyed to prevent the possibility of installing it
-upside down. A key is provided by the removal of Pin 20. The corresponding pin
-on the cable connector should be plugged.
-
-The pin locations are governed by the cable plug, not the receptacle. The way
-in which the receptacle is mounted on the Printed Circuit Board affects the
-pin positions, and pin 1 should remain in the same relative position. This
-means the pin numbers of the receptacle may not reflect the conductor number
-of the plug. The header receptacle is not polarized, and all the signals are
-relative to Pin 20, which is keyed.
-
-By using the plug positions as primary, a straight cable can connect drives.
-As shown in Figure 5-4, conductor 1 on pin 1 of the plug has to be in the
-same relative position no matter what the receptacle numbering looks like.
-If receptacle numbering was followed, the cable would have to twist 180
-degrees between a drive with top-mounted receptacles, and a drive with
-bottom-mounted receptacles.
-
- +-----------------------+
- | 1|
- |40 20 2|
- ==+==== Circuit Board ====+== ==+==== Circuit Board ====+==
- | 1|
- |40 20 2|
- +-----------------------+
-.. * Location of pin number stamped as 1 when receptacle mounted upside down
- FIGURE 5-4: 40-PIN CONNECTOR MOUNTING
-
-Recommended part numbers for the mating connector are shown below, but
-equivalent parts may be used.
-
- Connector (40 Pin) 3M 3417-7000 or equivalent.
- Strain relief 3M 3448-2040 or equivalent.
- Flat Cable (Stranded 28 AWG) 3M 3365-40 or equivalent.
- Flat Cable (Stranded 28 AWG) 3M 3517-40 (Shielded) or equivalent.
-
-5.5 I/O Cable
-
-The cable specifications affect system integrity and the maximum length that
-can be supported in any application.
-
- TABLE 5-3: CABLE PARAMETERS
- +-------------------------------------+------+--------+
- | Cable length of 0.46m (18 inches) * | Min | Max |
- +-------------------------------------+------+--------+
- | Driver IoL Sink Current | 12mA | |
- | Driver IoH Source Current | | -400uA |
- | Cable Capacitive Loading | | 200pF |
- +-------------------------------------+------+--------+
- * This distance may be exceeded in circumstances where the
- characteristics of both ends of the cable can be controlled.
-
diff --git a/sys/i386/doc/ata/ata-6 b/sys/i386/doc/ata/ata-6
deleted file mode 100644
index 1bce4866f5b5..000000000000
--- a/sys/i386/doc/ata/ata-6
+++ /dev/null
@@ -1,337 +0,0 @@
-6. Physical Interface
-
-6.1 Signal Conventions
-
-Signal names are shown in all upper case letters. Signals can be asserted
-(active, true) in either a high (more positive voltage) or low (less positive
-voltage) state. A dash character (-) at the beginning or end of a signal name
-indicates it is asserted at the low level (active low). No dash or a plus
-character (+) at the beginning or end of a signal name indicates it is
-asserted high (active high). An asserted signal may be driven high or low by
-an active circuit, or it may be allowed to be pulled to the correct state by
-the bias circuitry.
-
-Control signals that are asserted for one function when high and asserted for
-another function when low are named with the asserted high function name
-followed by a slash character (/), and the asserted low function name followed
-with a dash (-) e.g. BITENA/BITCLR- enables a bit when high and clears a bit
-when low. All signals are TTL compatible unless otherwise noted. Negated means
-that the signal is driven by an active circuit to the state opposite to the
-asserted state (inactive, or false) or may be simply released (in which case
-the bias circuitry pulls it inactive, or false), at the option of the
-implementor.
-
-6.2 Signal Summary
-
-The physical interface consists of single ended TTL compatible receivers and
-drivers communicating through a 40-conductor flat ribbon nonshielded cable
-using an asynchronous interface protocol. The pin numbers and signal names
-are shown in Table 6-1. Reserved signals shall be left unconnected.
-
- TABLE 6-1: INTERFACE SIGNALS
- +----------------------------------+ +-----------+
- | HOST I/O | | DRIVE I/O |
- | CONNECTOR | | CONNECTOR |
- | | | |
- | HOST RESET 1 | ----- RESET- -------->| 1 |
- | 2 | ----- Ground -------- | 2 |
- | HOST DATA BUS BIT 7 3 |<----- DD7 ----------->| 3 |
- | HOST DATA BUS BIT 8 4 |<----- DD8 ----------->| 4 |
- | HOST DATA BUS BIT 6 5 |<----- DD6 ----------->| 5 |
- | HOST DATA BUS BIT 9 6 |<----- DD9 ----------->| 6 |
- | HOST DATA BUS BIT 5 7 |<----- DD5 ----------->| 7 |
- | HOST DATA BUS BIT 10 8 |<----- DD10 ---------->| 8 |
- | HOST DATA BUS BIT 4 9 |<----- DD4 ----------->| 9 |
- | HOST DATA BUS BIT 11 10 |<----- DD11 ---------->| 10 |
- | HOST DATA BUS BIT 3 11 |<----- DD3 ----------->| 11 |
- | HOST DATA BUS BIT 12 12 |<----- DD12 ---------->| 12 |
- | HOST DATA BUS BIT 2 13 |<----- DD2 ----------->| 13 |
- | HOST DATA BUS BIT 13 14 |<----- DD13 ---------->| 14 |
- | HOST DATA BUS BIT 1 15 |<----- DD1 ----------->| 15 |
- | HOST DATA BUS BIT 14 16 |<----- DD14 ---------->| 16 |
- | HOST DATA BUS BIT 0 17 |<----- DD0 ----------->| 17 |
- | HOST DATA BUS BIT 15 18 |<----- DD15 ---------->| 18 |
- | 19 | ----- Ground -------- | 19 |
- | 20 | ----- (keypin) ------ | 20 |
- | DMA REQUEST 21 |<----- DMARQ --------- | 21 |
- | 22 | ----- Ground -------- | 22 |
- | HOST I/O WRITE 23 | ----- DIOW- --------->| 23 |
- | 24 | ----- Ground -------- | 24 |
- | HOST I/O READ 25 | ----- DIOR- --------->| 25 |
- | 26 | ----- Ground -------- | 26 |
- | I/O CHANNEL READY 27 |<----- IORDY --------- | 27 |
- | SPINDLE SYNC 28 |*----- SPSYNC --------*| 28 |
- | DMA ACKNOWLEDGE 29 | ----- DMACK- -------->| 29 |
- | 30 | ----- Ground -------- | 30 |
- | HOST INTERRUPT REQUEST 31 |<----- INTRQ --------- | 31 |
- | HOST 16 BIT I/O 32 |<----- IOCS16- ------- | 32 |
- | HOST ADDRESS BUS BIT 1 33 | ----- DA1 ----------->| 33 |
- | PASSED DIAGNOSTICS 34 |*----- PDIAG- --------*| 34 |
- | HOST ADDRESS BUS BIT 0 35 | ----- DAO ----------->| 35 |
- | HOST ADDRESS BUS BIT 2 36 | ----- DA2 ----------->| 36 |
- | HOST CHIP SELECT 0 37 | ----- CS1FX- -------->| 37 |
- | HOST CHIP SELECT 1 38 | ----- CS3FX- -------->| 38 |
- | DRIVE ACTIVE/DRIVE 1 PRESENT 39 |<----- DASP- ---------*| 39 |
- | 40 | ----- Ground -------- | 40 |
- +----------------------------------+ +-----------+
-
- * Drive Intercommunication Signals
-
- +---HOST---+ +-Drive 0-+ +-Drive 1-+
- | 28 | ----->| 28 28 |<----- SPSYNC ---->| 28 |
- | 34 | ----- | 34 34 |<----- PDIAG- ---- | 34 |
- | 39 |<----- | 39 39 |<----- DASP- ----- | 39 |
- +----------+ +---------+ +---------+
-
-6.3 Signal Descriptions
-
-The interface signals and pins are described in more detail than shown in
-Table 6-1. The signals are listed according to function, rather than in
-numerical connector pin order. Table 6-2 lists signal name mnemonic, connector
-pin number, whether input to (I) or output from (O) the drive, and full signal
-name.
-
- TABLE 6-2: INTERFACE SIGNALS DESCRIPTION
- +--------+----+-----+
- | Signal | Pin| I/O |
- +--------+----+-----+-----------------------------------------------------+
- | CS1FX- | 37 | I | Drive chip Select 0 |
- | CS3FX- | 38 | I | Drive chip Select 1 |
- | DA0 | 35 | I | Drive Address Bus - Bit 0 |
- | DA1 | 33 | I | - Bit 1 |
- | DA2 | 36 | I | - Bit 2 |
- | DASP- | 39 | I/O | Drive Active/Drive 1 Present |
- | DD0 | 17 | I/O | Drive Data Bus - Bit 0 |
- | DD1 | 15 | I/O | - Bit 1 |
- | DD2 | 13 | I/O | - Bit 2 |
- | DD3 | 11 | I/O | - Bit 3 |
- | DD4 | 9 | I/O | - Bit 4 |
- | DD5 | 7 | I/O | - Bit 5 |
- | DD6 | 5 | I/O | - Bit 6 |
- | DD7 | 3 | I/O | - Bit 7 |
- | DD8 | 4 | I/O | - Bit 8 |
- | DD9 | 6 | I/O | - Bit 9 |
- | DD10 | 8 | I/O | - Bit 10 |
- | DD11 | 10 | I/O | - Bit 11 |
- | DD12 | 12 | I/O | - Bit 12 |
- | DD13 | 14 | I/O | - Bit 13 |
- | DD14 | 16 | I/O | - Bit 14 |
- | DD15 | 18 | I/O | - Bit 15 |
- | DIOR- | 25 | I | Drive I/O Read |
- | DIOW- | 23 | I | Drive I/O Write |
- | DMACK- | 29 | I | DMA Acknowledge |
- | DMARQ | 21 | O | DMA Request |
- | INTRQ | 31 | O | Drive Interrupt |
- | IOCS16-| 32 | O | Drive 16-bit I/O |
- | IORDY | 27 | O | I/O Channel Ready |
- | PDIAG- | 34 | I/O | Passed Diagnostics |
- | RESET- | 1 | I | Drive Reset |
- | SPSYNC | 28 | - | Spindle Sync |
- | keypin | 20 | - | Pin used for keying the interface connector. |
- +--------+----+-----+-----------------------------------------------------+
-
-6.3.1 CS1FX- (Drive chip Select 0)
-
-This is the chip select signal decoded from the host address bus used to
-select the Command Block Registers.
-
-6.3.2 CS3FX- (Drive chip Select 1)
-
-This is the chip select signal decoded from the host address bus used to
-select the Control Block Registers.
-
-6.3.3 DA0-2 (Drive Address Bus)
-
-This is the 3-bit binary coded address asserted by the host to access a
-register or data port in the drive.
-
-6.3.4 DASP- (Drive Active/Drive 1 Present)
-
-This is a time-multiplexed signal which indicates that a drive is active, or
-that Drive 1 is present. This signal shall be an open collector output and
-each drive shall have a 10K pull-up resistor.
-
-During power on initialization or after RESET- is negated, DASP- shall be
-asserted by Drive 1 within 400 msec to indicate that Drive 1 is present.
-
-Drive 0 shall allow up to 450 msec for Drive 1 to assert DASP-. If Drive 1 is
-not present, Drive 0 may assert DASP- to drive an activity LED.
-
-DASP- shall be negated following acceptance of the first valid command by
-Drive 1 or after 31 seconds, whichever comes first.
-
-Any time after negation of DASP-, either drive may assert DASP- to indicate
-that a drive is active.
-
-..rm102
- NOTE: Prior to the development of this standard, products were introduced
- which did not time multiplex DASP-. Some used two jumpers to indicate
- to Drive 0 whether Drive 1 was present. If such a drive is jumpered to
- indicate Drive 1 is present it should work successfully with a Drive 1
- which complies with this standard. If installed as Drive 1, such a
- drive may not work successfully because it may not assert DASP- for a
- long enough period to be recognized. However, it would assert DASP-
- to indicate that the drive is active.
-
-6.3.5 DD0-DD15 (Drive Data Bus)
-
-This is an 8- or 16-bit bidirectional data bus between the host and the drive.
-The lower 8 bits are used for 8-bit transfers e.g. registers, ECC bytes.
-
-6.3.6 DIOR- (Drive I/O Read)
-
-This is the Read strobe signal. The falling edge of DIOR- enables data from a
-register or the data port of the drive onto the host data bus, DD0-DD7 or DD0-
-DD15. The rising edge of DIOR- latches data at the host.
-
-6.3.7 DIOW- (Drive I/O Write)
-
-This is the Write strobe signal. The rising edge of DIOW- clocks data from the
-host data bus, DD0-DD7 or DD0-DD15, into a register or the data port of the
-drive.
-
-6.3.8 DMACK- (DMA Acknowledge) (Optional)
-
-This signal shall be used by the host in response to DMARQ to either
-acknowledge that data has been accepted, or that data is available.
-
-6.3.9 DMARQ (DMA Request) (Optional)
-
-This signal, used for DMA data transfers between host and drive, shall be
-asserted by the drive when it is ready to transfer data to or from the host.
-The direction of data transfer is controlled by DIOR- and DIOW-. This signal
-is used in a handshake manner with DMACK- i.e. the drive shall wait until the
-host asserts DMACK- before negating DMARQ, and re-asserting DMARQ if there is
-more data to transfer.
-
-When a DMA operation is enabled, IOCS16-, CS1FX- and CS3FX- shall not be
-asserted and transfers shall be 16-bits wide.
-
-..rm102
- NOTE: ATA products with DMA capability require a pull-down resistor on this
- signal to prevent spurious data transfers. This resistor may affect
- driver requirements for drives sharing this signal in systems with
- unbuffered ATA signals.
-
-6.3.10 INTRQ (Drive Interrupt)
-
-This signal is used to interrupt the host system. INTRQ is asserted only when
-the drive has a pending interrupt, the drive is selected, and the host has
-cleared nIEN in the Device Control Register. If nIEN=1, or the drive is not
-selected, this output is in a high impedance state, regardless of the presence
-or absence of a pending interrupt.
-
-INTRQ shall be negated by:
-
- - assertion of RESET- or
- - the setting of SRST of the Device Control Register, or
- - the host writing the Command Register or
- - the host reading the Status Register
-
-..rm102
- NOTE: Some drives may negate INTRQ on a PIO data transfer completion, except
- on a single sector read or on the last sector of a multi-sector read.
-
-On PIO transfers, INTRQ is asserted at the beginning of each data block to be
-transferred. A data block is typically a single sector, except when
-declared otherwise by use of the Set Multiple command. An exception occurs on
-Format Track, Write Sector(s), Write Buffer and Write Long commands - INTRQ
-shall not be asserted at the beginning of the first data block to be
-transferred.
-
-On DMA transfers, INTRQ is asserted only once, after the command has
-completed.
-
-6.3.11 IOCS16- (Drive 16-bit I/O)
-
-Except for DMA transfers, IOCS16- indicates to the host system that the 16-bit
-data port has been addressed and that the drive is prepared to send or receive
-a 16-bit data word. This shall be an open collector output.
-
- - When transferring in PIO mode, If IOCS16- is not asserted, transfers shall
- be 8-bit using DD0-7.
- - When transferring in PIO mode, if IOCS16- is asserted, transfers shall be
- 16-bit using DD0-15.
- for 16-bit data transfers.
- - When transferring in DMA mode, the host shall use a 16-bit DMA channel and
- IOCS16- shall not be asserted.
-
-6.3.12 IORDY (I/O Channel Ready) (Optional)
-
-This signal is negated to extend the host transfer cycle of any host register
-access (Read or Write) when the drive is not ready to respond to a data
-transfer request. When IORDY is not negated, IORDY shall be in a high
-impedance state.
-
-6.3.13 PDIAG- (Passed Diagnostics)
-
-This signal shall be asserted by Drive 1 to indicate to Drive 0 that it has
-completed diagnostics. A 10K pull-up resistor shall be used on this signal by
-each drive.
-
-Following a power on reset, software reset or RESET-, Drive 1 shall negate
-PDIAG- within 1 msec (to indicate to Drive 0 that it is busy). Drive 1 shall
-then assert PDIAG- within 30 seconds to indicate that it is no longer busy,
-and is able to provide status. After the assertion of PDIAG-, Drive 1 may be
-unable to accept commands until it has finished its reset procedure and is
-Ready (DRDY=1).
-
-Following the receipt of a valid Execute Drive Diagnostics command, Drive
-1 shall negate PDIAG- within 1 msec to indicate to Drive 0 that it is busy
-and has not yet passed its drive diagnostics. If Drive 1 is present then
-Drive 0 shall wait for up to 5 seconds from the receipt of a valid Execute
-Drive Diagnostics command for Drive 1 to assert PDIAG-. Drive 1 should
-clear BSY before asserting PDIAG-, as PDIAG- is used to indicate that
-Drive 1 has passed its diagnostics and is ready to post status.
-
-..
-If DASP- was not asserted by Drive 1 during reset initialization, Drive 0
-shall post its own status immediately after it completes diagnostics, and
-clear the Drive 1 Status Register to 00h. Drive 0 may be unable to accept
-commands until it has finished its reset procedure and is Ready (DRDY=1).
-
-6.3.14 RESET- (Drive Reset)
-
-This signal from the host system shall be asserted for at least 25 usec after
-voltage levels have stabilized during power on and negated thereafter unless
-some event requires that the drive(s) be reset following power on.
-
-6.3.15 SPSYNC (Spindle Synchronization) (Optional)
-
-This signal may be either input or output to the drive depending on a vendor-
-defined switch. If a drive is set to Master the signal is output, and if a
-drive is set to slave the signal is input.
-
-There is no requirement that each drive implementation be plug-compatible to
-the extent that a multiple vendor drive subsystem be operable. Mix and match
-of different manufacturers drives is unlikely because rpm, sync fields, sync
-bytes etc need to be virtually identical. However, if drives are designed to
-match the following recommendation, controllers can operate drives with a
-single implementation.
-
-There can only be one master drive at a time in a configuration. The host or
-the drive designated as master can generate SPSYNC at least once per rotation,
-but may be at a higher frequency.
-
-SPSYNC received by a drive is used as the synchronization signal to lock the
-spindles in step. The time to achieve synchronization varies, and is indicated
-by the drive setting DRDY i.e. if the drive does not achieve synchronization
-following power on or a reset, it shall not set DRDY.
-
-A master drive or the host generates SPSYNC and transmits it.
-
-A slave drive does not generate SPSYNC and is responsible to synchronize its
-index to SPSYNC.
-
-If a drive does not support synchronization, it shall ignore SPSYNC.
-
-In the event that a drive previously synchronized loses synchronization, but
-is otherwise operational, it does not clear DRDY.
-
-Prior to the introduction of this standard, this signal was defined as DALE
-(Drive Address Latch Enable), and used for an address valid indication from
-the host system. If used, the host address and chip selects, DAO through DA2,
-CS1FX-, and CS3FX- were valid at the negation of this signal and remained
-valid while DALE was negated, therefore, the drive did not need to latch these
-signals with DALE.
-
diff --git a/sys/i386/doc/ata/ata-7 b/sys/i386/doc/ata/ata-7
deleted file mode 100644
index 240706912a85..000000000000
--- a/sys/i386/doc/ata/ata-7
+++ /dev/null
@@ -1,321 +0,0 @@
-7. Logical Interface
-
-7.1 General
-
-7.1.1 Bit Conventions
-
-Bit names are shown in all upper case letters except where a lower case n
-precedes a bit name. This indicates that when nBIT=0 (bit is zero) the action
-is true and when nBIT=1 (bit is one) the action is false. If there is no
-preceding n, then when BIT=1 it is true, and when BIT=0 it is false.
-
-A bit can be set to one or cleared to zero and polarity influences whether it
-is to be interpreted as true or false:
-
- True BIT=1 nBIT=0
- False BIT=0 nBIT=1
-
-7.1.2 Environment
-
-The drives using this interface shall be programmed by the host computer to
-perform commands and return status to the host at command completion. When two
-drives are daisy chained on the interface, commands are written in parallel to
-both drives, and for all except the Execute Diagnostics command, only the
-selected drive executes the command. On an Execute Diagnostics command
-addressed to Drive 0, both drives shall execute the command, and Drive 1 shall
-post its status to Drive 0 via PDIAG-.
-
-Drives are selected by the DRV bit in the Drive/Head Register (see 7.2.8), and
-by a jumper or switch on the drive designating it as either a Drive 0 or as
-Drive 1. When DRV=0, Drive 0 is selected. When DRV=1, Drive 1 is selected.
-When drives are daisy chained, one shall be set as Drive 0 and the other as
-Drive 1. When a single drive is attached to the interface it shall be set as
-Drive 0.
-
-Prior to the adoption of this standard, some drives may have provided jumpers
-to indicate Drive 0 with no Drive 1 present, or Drive 0 with Drive 1 present.
-
-Throughout this document, drive selection always refers to the state of the
-DRV bit, and the position of the Drive 0/Drive 1 jumper or switch.
-
-7.2 I/O Register Descriptions
-
-Communication to or from the drive is through an I/O Register that routes the
-input or output data to or from registers (selected) by a code on signals from
-the host (CS1FX-, CS3FX-, DA2, DA1, DA0, DIOR- and DIOW-).
-
-The Command Block Registers are used for sending commands to the drive or
-posting status from the drive.
-
-The Control Block Registers are used for drive control and to post alternate
-status.
-
-Table 7-1 lists these registers and the addresses that select them.
-
-Logic conventions are: A = signal asserted
- N = signal negated
- x = does not matter which it is
-
- TABLE 7-1: I/O PORT FUNCTIONS/SELECTION ADDRESSES
- +-------------------------------+-----------------------------------------+
- | Addresses | Functions |
- |CS1FX-|CS3FX-| DA2 | DA1 | DA0 | READ (DIOR-) | WRITE (DIOW-) |
- +------+------+-----+-----+-----+---------------------+-------------------+
- | Control Block Registers |
- +------+------+-----+-----+-----+---------------------+-------------------+
- | N | N | x | x | x | Data Bus High Imped | Not used |
- | N | A | 0 | x | X | Data Bus High Imped | Not used |
- | N | A | 1 | 0 | x | Data Bus High Imped | Not used |
- | N | A | 1 | 1 | 0 | Alternate Status | Device Control |
- | N | A | 1 | 1 | 1 | Drive Address | Not used |
- +------+------+-----+-----+-----+---------------------+-------------------+
- | Command Block Registers |
- +------+------+-----+-----+-----+---------------------+-------------------+
- | A | N | 0 | 0 | 0 | Data | Data |
- | A | N | 0 | 0 | 1 | Error Register | Features |
- | A | N | 0 | 1 | 0 | Sector Count | Sector Count |
- | A | N | 0 | 1 | 1 | Sector Number | Sector Number |
- | A | N | 1 | 0 | 0 | Cylinder Low | Cylinder Low |
- | A | N | 1 | 0 | 1 | Cylinder High | Cylinder High |
- | A | N | 1 | 1 | 0 | Drive/Head | Drive/Head |
- | A | N | 1 | 1 | 1 | Status | Command |
- | A | A | x | x | x | Invalid Address | Invalid Address |
- +------+------+-----+-----+-----+---------------------+-------------------+
-
-7.2.1 Alternate Status Register
-
-This register contains the same information as the Status Register in the
-command block. The only difference being that reading this register does not
-imply interrupt acknowledge or clear a pending interrupt.
-
- 7 6 5 4 3 2 1 0
- +-------+-------+-------+-------+-------+-------+-------+-------+
- | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR |
- +-------+-------+-------+-------+-------+-------+-------+-------+
-
-See 7.2.13 for definitions of the bits in this register.
-
-7.2.2 Command Register
-
-This register contains the command code being sent to the drive. Command
-execution begins immediately after this register is written. The executable
-commands, the command codes, and the necessary parameters for each command are
-listed in Table 9-1.
-
-7.2.3 Cylinder High Register
-
-This register contains the high order bits of the starting cylinder address
-for any disk access. At the end of the command, this register is updated to
-reflect the current cylinder number. The most significant bits of the cylinder
-address shall be loaded into the cylinder high Register.
-
-..rm102
- NOTE: Prior to the introduction of this standard, only the lower 2 bits of
- this register were valid, limiting cylinder address to 10 bits i.e.
- 1,024 cylinders.
-
-7.2.4 Cylinder Low Register
-
-This register contains the low order 8 bits of the starting cylinder address
-for any disk access. At the end of the command, this register is updated to
-reflect the current cylinder number.
-
-7.2.5 Data Register
-
-This 16-bit register is used to transfer data blocks between the device data
-buffer and the host. It is also the register through which sector information
-is transferred on a Format command. Data transfers may be either PIO or DMA.
-
-7.2.6 Device Control Register
-
-The bits in this register are as follows:
-
- 7 6 5 4 3 2 1 0
- +-------+-------+-------+-------+-------+-------+-------+-------+
- | x | x | x | x | 1 | SRST | nIEN | 0 |
- +-------+-------+-------+-------+-------+-------+-------+-------+
-
- - SRST is the host software reset bit. The drive is held reset when this bit
- is set. If two disk drives are daisy chained on the interface, this bit
- resets both simultaneously. Drive 1 is not required to execute the DASP-
- handshake procedure.
- - nIEN is the enable bit for the drive interrupt to the host. When nIEN=0,
- and the drive is selected, INTRQ shall be enabled through a tri-state
- buffer. When nIEN=1, or the drive is not selected, the INTRQ signal shall
- be in a high impedance state.
-
-7.2.7 Drive Address Register
-
-This register contains the inverted drive select and head select addresses of
-the currently selected drive. The bits in this register are as follows:
-
- 7 6 5 4 3 2 1 0
- +-------+-------+-------+-------+-------+-------+-------+-------+
- | HiZ | nWTG | nHS3 | nHS2 | nHS1 | nHS0 | nDS1 | nDS0 |
- +-------+-------+-------+-------+-------+-------+-------+-------+
-
- - HiZ shall always be in a high impedance state.
- - nWTG is the Write Gate bit. When writing to the disk drive is in progress,
- nWTG=0.
- - nHS3 through nHS0 are the one's complement of the binary coded address of
- the currently selected head. For example, if nHS3 through nHS0 are 1100b,
- respectively, head 3 is selected. nHS3 is the most significant bit.
- - nDS1 is the drive select bit for drive 1. When drive 1 is selected and
- active, nDS1=0.
- - nDS0 is the drive select bit for drive 0. When drive 0 is selected and
- active, nDS0=0.
-
-..rm102
- NOTE: Care should be used when interpreting these bits, as they do not
- always represent the expected status of drive operations at the
- instant the status was put into this register. This is because of the
- use of cacheing, translate mode and the Drive 0/Drive 1 concept with
- each drive having its own embedded controller.
-
-7.2.8 Drive/Head Register
-
-This register contains the drive and head numbers. The contents of this
-register define the number of heads minus 1, when executing an Initialize
-Drive Parameters command.
-
- 7 6 5 4 3 2 1 0
- +-------+-------+-------+-------+-------+-------+-------+-------+
- | 1 | 0 | 1 | DRV | HS3 | HS2 | HS1 | HS0 |
- +-------+-------+-------+-------+-------+-------+-------+-------+
-
- - DRV is the binary encoded drive select number. When DRV=0, Drive 0 is
- selected. When DRV=1, Drive 1 is selected.
- - HS3 through HS0 contain the binary coded address of the head to be selected
- e.g. if HS3 through HS0 are 0011b, respectively, head 3 will be selected.
- HS3 is the most significant bit. At command completion, this register is
- updated to reflect the currently selected head.
-
-7.2.9 Error Register
-
-This register contains status from the last command executed by the drive or a
-Diagnostic Code.
-
-At the completion of any command except Execute Drive Diagnostic, the contents
-of this register are valid when ERR=1 in the Status Register.
-
-Following a power on, a reset, or completion of an Execute Drive Diagnostic
-command, this register contains a Diagnostic Code (see Table 9-2).
-
- 7 6 5 4 3 2 1 0
- +-------+-------+-------+-------+-------+-------+-------+-------+
- | BBK | UNC | 0 | IDNF | 0 | ABRT | TK0NF | AMNF |
- +-------+-------+-------+-------+-------+-------+-------+-------+
-
- - BBK (Bad Block Detected) indicates a bad block mark was detected in the
- requested sector's ID field.
- - UNC (Uncorrectable Data Error) indicates an uncorrectable data error has
- been encountered.
- - IDNF (ID Not Found) indicates the requested sector's ID field could not be
- found.
- - ABRT (Aborted Command) indicates the requested command has been aborted due
- to a drive status error (Not Ready, Write Fault, etc.) or because the
- command code is invalid.
- - TK0NF (Track 0 Not Found) indicates track 0 has not been found during a
- Recalibrate command.
- - AMNF (Address Mark Not Found) indicates the data address mark has not been
- found after finding the correct ID field.
- - Unused bits are cleared to zero.
-
-7.2.10 Features Register
-
-This register is command specific and may be used to enable and disable
-features of the interface e.g. by the Set Features Command to enable and
-disable cacheing.
-
-This register may be ignored by some drives.
-
-Some hosts, based on definitions prior to the completion of this standard, set
-values in this register to designate a recommended Write Precompensation
-Cylinder value.
-
-7.2.11 Sector Count Register
-
-This register contains the number of sectors of data requested to be
-transferred on a read or write operation between the host and the drive. If
-the value in this register is zero, a count of 256 sectors is specified.
-
-If this register is zero at command completion, the command was successful. If
-not successfully completed, the register contains the number of sectors which
-need to be transferred in order to complete the request.
-
-The contents of this register may be defined otherwise on some commands e.g.
-Initialize Drive Parameters, Format Track or Write Same commands.
-
-7.2.12 Sector Number Register
-
-This register contains the starting sector number for any disk data access for
-the subsequent command. The sector number may be from 1 to the maximum number
-of sectors per track.
-
-See the command descriptions for contents of the register at command
-completion (whether successful or unsuccessful).
-
-..Typically, when a read or write command completes successfully, the value
-..in the register is the last sector number accessed modulo the number of
-..sectors per track. Typically, if a command does not complete successfully,
-..the register contains the sector number at which an error occurred on a
-..multiple sector transfer.
-..
-7.2.13 Status Register
-
-This register contains the drive status. The contents of this register are
-updated at the completion of each command. When BSY is cleared, the other bits
-in this register shall be valid within 400 nsec. If BSY=1, no other bits in
-this register are valid. If the host reads this register when an interrupt is
-pending, it is considered to be the interrupt acknowledge. Any pending
-interrupt is cleared whenever this register is read.
-
-..rm102
- NOTE: If Drive 1 is not detected as being present, Drive 0 clears the Drive
- 1 Status Register to 00h (indicating that the drive is Not Ready).
-
- 7 6 5 4 3 2 1 0
- +-------+-------+-------+-------+-------+-------+-------+-------+
- | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR |
- +-------+-------+-------+-------+-------+-------+-------+-------+
-
- - BSY (Busy) is set whenever the drive has access to the Command Block
- Registers. The host should not access the Command Block Register when
- BSY=1. When BSY=1, a read of any Command Block Register shall return the
- contents of the Status Register. This bit is set by the drive (which may be
- able to respond at times when the media cannot be accessed) under the
- following circumstances:
- a) within 400 nsec after the negation of RESET- or after SRST has been set
- in the Device Control Register. Following acceptance of a reset it is
- recommended that BSY be set for no longer than 30 seconds by Drive 1 and
- no longer than 31 seconds by Drive 0.
- b) within 400 nsec of a host write of the Command Register with a Read,
- Read Long, Read Buffer, Seek, Recalibrate, Initialize Drive Parameters,
- Read Verify, Identify Drive, or Execute Drive Diagnostic command.
- c) within 5 usecs following transfer of 512 bytes of data during execution
- of a Write, Format Track, or Write Buffer command, or 512 bytes of data
- and the appropriate number of ECC bytes during the execution of a Write
- Long command.
- - DRDY (Drive Ready) indicates that the drive is capable of responding to a
- command. When there is an error, this bit is not changed until the Status
- Register is read by the host, at which time the bit again indicates the
- current readiness of the drive. This bit shall be cleared at power on and
- remain cleared until the drive is ready to accept a command.
- - DWF (Drive Write Fault) indicates the current write fault status. When an
- error occurs, this bit shall not be changed until the Status Register is
- read by the host, at which time the bit again indicates the current write
- fault status.
- - DSC (Drive Seek Complete) indicates that the drive heads are settled over a
- track. When an error occurs, this bit shall not be changed until the Status
- Register is read by the host, at which time the bit again indicates the
- current Seek Complete status.
- - DRQ (Data Request) indicates that the drive is ready to transfer a word or
- byte of data between the host and the drive.
- - CORR (Corrected Data) indicates that a correctable data error was
- encountered and the data has been corrected. This condition does not
- terminate a data transfer.
- - IDX (Index) is set once per disk revolution.
- - ERR (Error) indicates that an error occurred during execution of the
- previous command. The bits in the Error Register have additional
- information regarding the cause of the error.
-
diff --git a/sys/i386/doc/ata/ata-8 b/sys/i386/doc/ata/ata-8
deleted file mode 100644
index f651b6b49326..000000000000
--- a/sys/i386/doc/ata/ata-8
+++ /dev/null
@@ -1,143 +0,0 @@
-8. Programming Requirements
-
-8.1 Reset Response
-
-A reset is accepted within 400 nsec after the negation of RESET- or within 400
-nsec after SRST has been set in the Device Control Register.
-
-When the drive is reset by RESET-, Drive 1 shall indicate it is present by
-asserting DASP- within 400 msec, and DASP- shall remain asserted for 30
-seconds or until Drive 1 accepts the first command. See also 6.3.4 and 6.3.13.
-
-When the drive is reset by SRST, the drive shall set BSY=1.
-
-See also 7.2.6.
-
-When a reset is accepted, and with BSY set:
-
- a) Both drives perform any necessary hardware initialization
- b) Both drives clear any previously programmed drive parameters
- c) Both drives may revert to the default condition
- d) Both drives load the Command Block Registers with their default values
- e) If a hardware reset, Drive 0 waits for DASP- to be asserted by Drive 1
- f) If operational, Drive 1 asserts DASP-
- g) Drive 0 waits for PDIAG- to be asserted if Drive 1 asserts DASP-
- h) If operational, Drive 1 clears BSY
- i) If operational, Drive 1 asserts PDIAG-
- j) Drive 0 clears BSY
-
-No interrupt is generated when initialization is complete.
-
-The default values for the Command Block Registers if no self-tests are
-performed or if no errors occurred are:
-
- Error = 01h Cylinder Low = 00h
- Sector Count = 01h Cylinder High = 00h
- Sector Number = 01h Drive/Head = 00h
-
-The Error Register shall contain a Diagnostic Code (see Table 9.2) if a self-
-test is performed.
-
-Following any reset, the host should issue an Initialize Drive Parameters
-command to ensure the drive is initialized as desired.
-
-There are three types of reset in ATA. The following is a suggested method of
-classifying reset actions:
-
- - Power On Reset: the drive executes a series of electrical circuitry
- diagnostics, spins up the HDA, tests speed and other mechanical
- parametrics, and sets default values.
- - Hardware Reset: the drive executes a series of electrical circuitry
- diagnostics, and resets to default values.
- - Software Reset: the drive resets the interface circuitry to default values.
-
-8.2 Translate Mode
-
-The cylinder, head and sector geometry of the drive as presented to the host
-may differ from the actual physical geometry. Translate mode is an optional
-and device specific means of mapping between the two.
-
-8.3 Power Conditions
-
-Optional power commands permit the host to modify the behavior of the drive in
-a manner which reduces the power required to operate.
-
- TABLE 8-1: POWER CONDITIONS
- +----------+----+----+----+------------------+-----+
- | Mode |SRST| BSY|DRDY| Interface Active |Media|
- +----------+----+----+----+------------------+-----+
- | Sleep | 1 | x | x | No | 0 |
- | | | | | | |
- | Standby | x | 0 | 1 | Yes | 0 |
- | | | | | | |
- | Idle | x | 0 | 1 | Yes | 1 |
- | | | | | | |
- | Active | x | x | x | Yes | 1 |
- +----------+----+----+----+------------------+-----+
- | 1 = Active 0 = Inactive |
- +--------------------------------------------------+
-
-The lowest power consumption occurs in Sleep mode. When in Sleep mode, the
-drive needs a Software Reset to be activated (see 9.18). The time to respond
-could be as long as 30 seconds or more.
-
-In Standby mode the drive interface is capable of accepting commands, but as
-the media is not immediately accessible, it could take the drive as long as 30
-seconds or more to respond.
-
-In Idle mode the drive is capable of responding immediately to media access
-requests. A drive in Idle mode may take longer to complete the execution of a
-command because it may have to activate some circuitry.
-
-In Active mode the drive is capable of responding immediately to media access
-requests, and commands complete execution in the shortest possible time.
-
-Ready is not a power condition. A drive may post ready at the interface even
-though the media may not be accessible.
-
-See specific power-related commands.
-
-8.4 Error Posting
-
-The errors that are valid for each command are defined in Table 8-1. It is not
-a requirement that all valid conditions be implemented. See 7.2.9 and 7.2.13
-for the definition of the Error Register and Status Register bits.
-
- TABLE 8-2: REGISTER CONTENTS
- +----------------------------+---------------------+
- | Error Register | Status Register |
- |BBK|UNC|IDNF|ABRT|TK0NF|AMNF|DRDY|DWF|DSC|CORR|ERR|
- +------------------------+---+---+----+----+-----+----+----+---+---+----+---+
- | Check Power Mode | | | | V | | | V | V | V | | V |
- | Execute Drive Diags | See 9.2 | | | | | V |
- | Format Track | | | V | V | | | V | V | V | | V |
- | Identify Drive | | | | V | | | V | V | V | | V |
- | Idle | | | | V | | | V | V | V | | V |
- | Idle Immediate | | | | V | | | V | V | V | | V |
- | Initialize Drive Parms | | | | | | | V | V | V | | |
- | Recalibrate | | | | V | V | | V | V | V | | V |
- | Read Buffer | | | | V | | | V | V | V | | V |
- | Read DMA | V | V | V | V | | V | V | V | V | V | V |
- | Read Long | V | V | V | V | | V | V | V | V | V | V |
- | Read Multiple | V | V | V | V | | V | V | V | V | V | V |
- | Read Sector(s) | V | V | V | V | | V | V | V | V | V | V |
- | Read Verify Sector(s) | V | V | V | V | | V | V | V | V | V | V |
- | Seek | | | V | V | | | V | V | V | | V |
- | Set Features | | | | V | | | V | V | V | | V |
- | Set Multiple Mode | | | | V | | | V | V | V | | V |
- | Sleep | | | | V | | | V | V | V | | V |
- | Standby | | | | V | | | V | V | V | | V |
- | Standby Immediate | | | | V | | | V | V | V | | V |
- | Write Buffer | | | | V | | | V | V | V | | V |
- | Write DMA | V | | V | V | | | V | V | V | | V |
- | Write Long | V | | V | V | | | V | V | V | | V |
- | Write Multiple | V | | V | V | | | V | V | V | | V |
- | Write Same | V | | V | V | | | V | V | V | | V |
- | Write Sector(s) | V | | V | V | | | V | V | V | | V |
- | Write Verify | V | V | V | V | | V | V | V | V | V | V |
- +------------------------+---+---+----+----+-----+----+----+---+---+----+---+
- | Invalid Command Code | | | | V | | | V | V | V | | V |
- +------------------------+---+---+----+----+-----+----+----+---+---+----+---+
- | V = valid on this command |
- +---------------------------------------------------------------------------+
-
diff --git a/sys/i386/doc/ata/ata-9 b/sys/i386/doc/ata/ata-9
deleted file mode 100644
index 4cd3f6684989..000000000000
--- a/sys/i386/doc/ata/ata-9
+++ /dev/null
@@ -1,721 +0,0 @@
-9. Command Descriptions
-
-Commands are issued to the drive by loading the pertinent registers in the
-command block with the needed parameters, and then writing the command code to
-the Command Register.
-
-The manner in which a command is accepted varies. There are three classes
-(see Table 9-1) of command acceptance, all predicated on the fact that to
-receive a command, BSY=0:
-
- - Upon receipt of a Class 1 command, the drive sets BSY within 400 nsec.
- - Upon receipt of a Class 2 command, the drive sets BSY within 400 nsec, sets
- up the sector buffer for a write operation, sets DRQ within 700 usec, and
- clears BSY within 400 nsec of setting DRQ.
- - Upon receipt of a Class 3 command, the drive sets BSY within 400 nsec, sets
- up the sector buffer for a write operation, sets DRQ within 20 msec, and
- clears BSY within 400 nsec of setting DRQ.
-
-..rm102
- NOTE: DRQ may be set so quickly on Class 2 and Class 3 that the BSY
- transition is too short for BSY=1 to be recognized.
-
-The drive shall implement all mandatory commands as identified by an M, and
-may implement the optional commands identified by an O, in Table 9-1. V
-indicates a Vendor Specific command code.
-
- TABLE 9-1: COMMAND CODES AND PARAMETERS
- +-------+-------------------+
- +-----+ |Command| Parameters Used |
- |Class| | Code |FR SC SN CY DH |
- +-----+----------------------------------+---+-------+---+---+---+---+---+
- | 1 | Check Power Mode | O |98h E5h| | y | | | D |
- | 1 | Execute Drive Diagnostic | M | 90h | | | | | D*|
- | 2 | Format Track | M | 50h | * | y | | y | y |
- | 1 | Identify Drive | O | ECh | | | | | D |
- | 1 | Idle | O |97h E3h| | y | | | D |
- | 1 | Idle Immediate | O |95h E1h| | | | | D |
- | 1 | Initialize Drive Parameters | M | 91h | | y | | | y |
- | 1 | Recalibrate | M | 1xh | | | | | D |
- | 1 | Read Buffer | O | E4h | | | | | D |
- | 1 | Read DMA (w/retry) | O | C8h | | y | y | y | y |
- | 1 | Read DMA (w/o retry) | O | C9h | | y | y | y | y |
- | 1 | Read Multiple | O | C4h | | y | y | y | y |
- | 1 | Read Sector(s) (w/retry) | M | 20 | | y | y | y | y |
- | 1 | Read Sector(s) (w/o retry) | M | 21 | | y | y | y | y |
- | 1 | Read Long (w/retry) See 9.13 | M | 22 | | y | y | y | y |
- | 1 | Read Long (w/o retry) See 9.13 | M | 23 | | y | y | y | y |
- | 1 | Read Verify Sector(s) (w/retry) | M | 40 | | y | y | y | y |
- | 1 | Read Verify Sector(s) (w/o retry)| M | 41 | | y | y | y | y |
- | 1 | Seek | M | 7xh | | | y | y | y |
- | 1 | Set Features | O | EFh | y | | | | D |
- | 1 | Set Multiple Mode | O | C6h | | y | | | D |
- | 1 | Set Sleep Mode | O |99h E6h| | | | | D |
- | 1 | Standby | O |96h E2h| | y | | | D |
- | 1 | Standby Immediate | O |94h E0h| | | | | D |
- | 2 | Write Buffer | O | E8h | | | | | D |
- | 3 | Write DMA (w/retry) | O | CAh | | y | y | y | y |
- | 3 | Write DMA (w/o retry) | O | CBh | | y | y | y | y |
- | 3 | Write Multiple | O | C5h | * | y | y | y | y |
- | 3 | Write Same | O | E9h | y | y | y | y | y |
- | 2 | Write Sector(s) (w/retry) | M | 30 | * | y | y | y | y |
- | 2 | Write Sector(s) (w/o retry) | M | 31 | * | y | y | y | y |
- | 2 | Write Sector(s) (w/retry) | M | 32 | * | y | y | y | y |
- | 2 | Write Sector(s) (w/o retry) | M | 33 | * | y | y | y | y |
- | 3 | Write Verify | O | 3Ch | * | y | y | y | y |
- | | Vendor Unique | V | 9Ah | | | | | |
- | | Vendor Unique | V | C0-C3h| | | | | |
- | | Vendor Unique | V | 8xh | | | | | |
- | | Vendor Unique | V |F5h-FFh| | | | | |
- | | EATA Standard (CAM/89-004) | O |F0h-F4h| | | | | |
- | | Reserved: All remaining codes | | | | | | | |
- +-----+----------------------------------+---+-------+---+---+---+---+---+
- | | CY = Cylinder Registers SC = Sector Count Register |
- | | DH = Drive/Head Register SN = Sector Number Register |
- | | FR = Features Register (see command descriptions for use) |
-.. | | |
-.. | | M = Mandatory O = Optional V = Vendor Specific |
- | | y - the register contains a valid parameter for this command. |
- | | For the Drive/Head Register, y means both the drive and |
- | | head parameters are used. |
- | | D - only the drive parameter is valid and not the head parameter.|
- | | D* - Addressed to Drive 0 but both drives execute it. |
- | | * - Maintained for compatibility (see 7.2.9) |
- +-----+------------------------------------------------------------------+
-
-9.1 Check Power Mode
-
-This command checks the power mode.
-
-If the drive is in, going to, or recovering from the Standby Mode the drive
-shall set BSY, set the Sector Count Register to 00h, clear BSY, and generate
-an interrupt.
-
-If the drive is in the Idle Mode, the drive shall set BSY, set the Sector
-Count Register to FFh, clear BSY, and generate an interrupt.
-
-9.2 Execute Drive Diagnostic
-
-This command shall perform the internal diagnostic tests implemented by the
-drive. See also 6.3.4 and 6.3.13. The DRV bit is ignored. Both drives, if
-present, shall execute this command.
-
-If Drive 1 is present:
-
- - Drive 0 waits up to 5 seconds for Drive 1 to assert PDIAG-.
- - If Drive 1 has not asserted PDIAG-, indicating a failure, Drive 0 shall
- append 80h to its own diagnostic status.
- - Both drives shall execute diagnostics.
- - If Drive 1 diagnostic failure is detected when Drive 0 status is read,
- Drive 1 status is obtained by setting the DRV bit, and reading status.
-
-If there is no Drive 1 present:
-
- - Drive 0 posts only its own diagnostic results.
- - Drive 0 clears BSY, and generates an interrupt.
-
-The Diagnostic Code written to the Error Register is a unique 8-bit code as
-shown in Table 9-2, and not as the single bit flags defined in 7.2.9.
-
-..Table 9-2 details the codes and the corresponding explanations.
-If Drive 1 fails diagnostics, Drive 0 "ORs" 80h with its own status and loads
-that code into the Error Register. If Drive 1 passes diagnostics or there is
-no Drive 1 connected, Drive 0 "ORs" 00h with its own status and loads that
-code into the Error Register.
-
- TABLE 9-2: DIAGNOSTIC CODES
- +-------+
- | Code |
- +-------+----------------------------------+
- | 01h | No error detected |
- | 02h | Formatter device error |
- | 03h | Sector buffer error |
- | 04h | ECC circuitry error |
- | 05h | Controlling microprocessor error |
- | 8xh | Drive 1 failed |
- +-------+----------------------------------+
-
-9.3 Format Track
-
-The implementation of the Format Track command is vendor specific. The actions
-may be a physical reformatting of a track, initializing the data field
-contents to some value, or doing nothing.
-
-The Sector Count Register contains the number of sectors per track.
-
-The track address is specified in the Cylinder High and Cylinder Low
-Registers, and the number of sectors is specified in the Sector Count
-Register. When the command is accepted, the drive sets the DRQ bit and waits
-for the host to fill the sector buffer. When the sector buffer is full, the
-drive clears DRQ, sets BSY and begins command execution.
-
-The contents of the sector buffer shall not be written to the media, and may
-be either ignored or interpreted as follows:
-
- DD15 ---- DD0 DD15 ---- DD0
- +------+------+ +------+------+--------------------------+
- | First|Desc- | | Last |Desc- | Remainder of buffer |
- |Sector|riptor| : : : : : : |Sector|riptor| filled with zeros |
- +------+------+ +------+------+--------------------------+
-
-One 16-bit word represents each sector, the words being contiguous from the
-start of a sector. Any words remaining in the buffer after the representation
-of the last sector are filled with zeros. DD15-8 contain the sector number. If
-an interleave is specified, the words appear in the same sequence as they
-appear on the track. DD7-0 contain a descriptor value defined as follows:
-
- 00h - Format sector as good
- 20h - Unassign the alternate location for this sector
- 40h - Assign this sector to an alternate location
- 80h - Format sector as bad
-
-..rm102
- NOTE: Some users of the ATA drive expect the operating system partition
- table to be erased on a Format command. It is recommended that a drive
- which does not perform a physical format of the track, write a data
- pattern of all zeros to the sectors which have been specified by the
- Format Track command.
-
-..rm102
- NOTE: It is recommended that implementors resassign data blocks which show
- repeated errors.
-
-9.4 Identify Drive
-
-The Identify Drive command enables the host to receive parameter information
-from the drive. When the command is issued, the drive sets BSY, stores the
-required parameter information in the sector buffer, sets DRQ, and generates
-an interrupt. The host then reads the information out of the sector buffer.
-The parameter words in the buffer have the arrangement and meanings defined in
-Table 9-3. All reserved bits or words shall be zero.
-
- +-------+ TABLE 9-3: IDENTIFY DRIVE INFORMATION
- | Word |
- +-------+------------------------------------------------------------------+
- | 0 | General configuration bit-significant information: |
- | | 15 0 reserved for non-magnetic drives |
- | | 14 1=format speed tolerance gap required |
- | | 13 1=track offset option available |
- | | 12 1=data strobe offset option available |
- | | 11 1=rotational speed tolerance is > 0.5% |
- | | 10 1=disk transfer rate > 10 Mbs |
- | | 9 1=disk transfer rate > 5Mbs but <= 10Mbs |
- | | 8 1=disk transfer rate <= 5Mbs |
- | | 7 0 reserved for removable cartridge drive |
- | | 6 1=fixed drive |
- | | 5 1=spindle motor control option implemented |
- | | 4 1=head switch time > 15 usec |
- | | 3 1=not MFM encoded |
- | | 2 1=soft sectored |
- | | 1 1=hard sectored |
- | | 0 0=reserved |
- | 1 | Number of fixed cylinders |
- | 2 | reserved |
- | 3 | Number of heads |
- | 4 | Number of unformatted bytes per track |
- | 5 | Number of unformatted bytes per sector |
- | 6 | Number of sectors per track |
- | 7-9 | Vendor Unique |
- | 10-19 | Serial number (20 ASCII characters, 0000h=not specified) |
- | 20 | Buffer type |
- | 21 | Buffer size in 512 byte increments (0000h=not specified) |
- | 22 | # of ECC bytes passed on Read/Write Long cmds (0000h=not spec'd) |
- | 23-26 | Firmware revision (8 ASCII characters, 0000h=not specified) |
- | 27-46 | Model number (40 ASCII characters, 0000h=not specified) |
- | 47 | 0000h = Read/Write Multiple commands not implemented |
- | | x = number of sectors that can be transferred per interrupt |
- | | on Read and Write Multiple commands |
- | 48 | 0000h = cannot perform doubleword I/O |
- | | 0001h = can perform doubleword I/O |
- | 49 | Capabilities |
- | | 15-9 0=reserved |
- | | 8 1=DMA Supported |
- | | 7-0 Vendor Unique |
- | 50 | reserved |
- | 51 | PIO data transfer cycle timing mode |
- | 52 | DMA data transfer cycle timing mode |
- | 53-127| reserved |
- |128-159| Vendor Unique |
- |160-255| reserved |
- +-------+------------------------------------------------------------------+
-
-The fields described in 9.4.1 through 9.4.5 are not affected by the Initialize
-Drive Parameters command.
-
-9.4.1 Number of fixed cylinders
-
-The number of translated cylinders in the default translation mode.
-
-9.4.2 Number of heads
-
-The number of translated heads in the default translation mode.
-
-9.4.3 Number of unformatted bytes per track
-
-The number of unformatted bytes per translated track in the default
-translation mode.
-
-9.4.4 Number of unformatted bytes per sector
-
-The number of unformatted bytes per sector in the default translation mode.
-
-9.4.5 Number of sectors per track
-
-The number of sectors per track in the default translation mode.
-
-9.4.6 Serial Number
-
-The contents of this field are right justified and padded with spaces (20h).
-
-9.4.7 Buffer Type
-
-The contents of the field are determined by the manufacturer.
-
- 0000h = not specified.
- 0001h = a single ported single sector buffer which is not capable of
- simultaneous data transfers to or from the host and the disk.
- 0002h = a dual ported multi-sector buffer capable of simultaneous data
- transfers to or from the host and the disk.
- 0003h = a dual ported multi-sector buffer capable of simultaneous transfers
- with a read cacheing capability.
- 0004-FFFFh = reserved
-
-These codes are typically not used by the operating system, however, they are
-useful for diagnostic programs which perform initialization routines e.g. a
-different interleave may be desirable for 0001h vs 0002h or 0003h.
-
-9.4.8 Firmware Revision
-
-The contents of this field are left justified and padded with spaces (20h).
-
-9.4.9 Model Number
-
-The contents of this field are left justified and padded with spaces (20h).
-
-9.4.10 PIO data transfer cycle timing mode
-
-The PIO transfer timing for each ATA device falls into categories which have
-unique parametric timing specifications. To determine the proper device timing
-category, compare the Cycle Time specified in Figure 11-1 with the contents of
-this field. The value returned should fall into one of the categories
-specified in Figure 11-1, and if it does not, then Mode 0 shall be used to
-serve as the default timing.
-
-9.4.11 DMA data transfer cycle timing mode
-
-The DMA transfer timing for each ATA device falls into categories which have
-unique parametric timing specifications. To determine the proper device timing
-category, compare the Cycle Time specified in Figure 11-3 with the contents of
-this field. The value returned should fall into one of the categories
-specified in Figure 11-3, and if it does not, then Mode 0 shall be used to
-serve as the default timing.
-
-9.5 Idle
-
-This command causes the drive to set BSY, enter the Idle Mode, clear BSY, and
-generate an interrupt. The interrupt is generated even though the drive may
-not have fully transitioned to Idle Mode.
-
-If the drive is already spinning, the spinup sequence is not executed.
-
-If the Sector Count Register is non-zero then the automatic power down
-sequence shall be enabled and the timer begins counting down immediately. If
-the Sector Count Register is zero then the automatic power down sequence shall
-be disabled.
-
-9.6 Idle Immediate
-
-This command causes the drive to set BSY, enter the Idle Mode, clear BSY, and
-generate an interrupt. The interrupt is generated even though the drive may
-not have fully transitioned to Idle Mode.
-
-9.7 Initialize Drive Parameters
-
-..This command enables the host to control certain drive parameters. Some
-..parameters are standard while others are vendor specific.
-This command enables the host to set the number of sectors per track and the
-number of heads minus 1, per cylinder. Upon receipt of the command, the drive
-sets BSY, saves the parameters, clears BSY, and generates an interrupt.
-
-The only two register values used by this command are the Sector Count
-Register which specifies the number of sectors per track, and the Drive/Head
-Register which specifies the number of heads minus 1. The DRV bit designates
-these values to Drive 0 or Drive 1, as appropriate.
-
-The sector count and head values are not checked for validity by this command.
-If they are invalid, no error will be posted until an illegal access is made
-by some other command.
-
-9.8 Recalibrate
-
-This command moves the read/write heads from anywhere on the disk to cylinder
-0. Upon receipt of the command, the drive sets BSY and issues a seek to
-cylinder zero. The drive then waits for the seek to complete before updating
-status, clearing BSY and generating an interrupt.
-
-If the drive cannot reach cylinder 0, a Track Not Found error is posted.
-
-9.9 Read Buffer
-
-The Read Buffer command enables the host to read the current contents of the
-drive's sector buffer. When this command is issued, the drive sets BSY, sets
-up the sector buffer for a read operation, sets DRQ, clears BSY, and generates
-an interrupt. The host then reads up to 512 bytes of data from the buffer.
-
-The Read Buffer and Write Buffer commands shall be synchronized such that
-sequential Write Buffer and Read Buffer commands access the same 512 bytes
-within the buffer.
-
-9.10 Read DMA
-
-This command executes in a similar manner to the Read Sectors command except
-for the following:
-
- - the host initializes a slave-DMA channel prior to issuing the command
- - data transfers are qualified by DMARQ and are performed by the slave-DMA
- channel
- - the drive issues only one interrupt per command to indicate that data
- transfer has terminated and status is available.
-
-Any error encountered during execution of a Read DMA command results in the
-termination of data transfer at the sector where the error was detected. The
-sector in error is not transferred. The drive generates an interrupt to
-indicate that data transfer has terminated and status is available. The error
-posting is the same as that of the Read Sectors command.
-
-9.11 Read Long
-
-The Read Long command performs similarly to the Read Sectors command except
-that it returns the data and the ECC bytes contained in the data field of the
-desired sector. During a Read Long command, the drive does not check the ECC
-bytes to determine if there has been a data error. Only single sector read
-long operations are supported.
-
-The transfer of the ECC bytes shall be 8-bits wide.
-
-9.12 Read Multiple Command
-
-The Read Multiple command performs similarly to the Read Sectors command.
-Interrupts are not generated on every sector, but on the transfer of a block
-which contains the number of sectors defined by a Set Multiple command.
-
-Command execution is identical to the Read Sectors operation except that the
-number of sectors defined by a Set Multiple command are transferred without
-intervening interrupts. DRQ qualification of the transfer is required only at
-the start of the data block, not on each sector.
-
-The block count of sectors to be transferred without intervening interrupts is
-programmed by the Set Multiple Mode command, which shall be executed prior to
-the Read Multiple command.
-
-When the Read Multiple command is issued, the Sector Count Register contains
-the number of sectors (not the number of blocks or the block count) requested.
-
-If the number of requested sectors is not evenly divisible by the block count,
-as many full blocks as possible are transferred, followed by a final, partial
-block transfer. The partial block transfer shall be for n sectors, where
-
- n = (sector count) - modulo (block count)
-
-If the Read Multiple command is attempted before the Set Multiple Mode command
-has been executed or when Read Multiple commands are disabled, the Read
-Multiple operation shall be rejected with an Aborted Command error.
-
-Disk errors encountered during Read Multiple commands are posted at the
-beginning of the block or partial block transfer, but DRQ is still set and the
-data transfer shall take place as it normally would, including transfer of
-corrupted data, if any.
-
-The contents of the Command Block Registers following the transfer of a data
-block which had a sector in error are undefined. The host should retry the
-transfer as individual requests to obtain valid error information.
-
-Subsequent blocks or partial blocks are transferred only if the error was a
-correctable data error. All other errors cause the command to stop after
-transfer of the block which contained the error. Interrupts are generated when
-DRQ is set at the beginning of each block or partial block.
-
-..The error reporting is the same as that on a Read Sectors command.
-..
-9.13 Read Sector(s)
-
-This command reads from 1 to 256 sectors as specified in the Sector Count
-register. A sector count of 0 requests 256 sectors. The transfer begins at the
-sector specified in the Sector Number Register. See 10.1 for the DRQ, IRQ and
-BSY protocol on data transfers.
-
-If the drive is not already on the desired track, an implied seek is
-performed. Once at the desired track, the drive searches for the appropriate
-ID field.
-
-If retries are disabled and two index pulses have occurred without error free
-reading of the requested ID, an ID Not Found error is posted.
-
-If retries are enabled, up to a vendor specific number of attempts may be made
-to read the requested ID before posting an error.
-
-If the ID is read correctly, the data address mark shall be recognized within
-a specified number of bytes, or the Address Mark Not Found error is posted.
-
-..Once the data address mark is found, the data field is read into the sector
-..buffer, error bits are set if an error was encountered, DRQ is set, and an
-..interrupt is generated.
-..
-DRQ is always set regardless of the presence or absence of an error condition
-at the end of the sector.
-
-At command completion, the Command Block Registers contain the cylinder, head,
-and sector number of the last sector read.
-
-If an error occurs, the read terminates at the sector where the error
-occurred. The Command Block Registers contain the cylinder, head, and sector
-number of the sector where the error occurred.
-
-The flawed data is pending in the sector buffer.
-
-9.14 Read Verify Sector(s)
-
-This command is identical to the Read Sectors command, except that DRQ is
-never set, and no data is transferred to the host. See 10.3 for protocol.
-..When the command is accepted, the drive sets BSY.
-
-When the requested sectors have been verified, the drive clears BSY and
-generates an interrupt. Upon command completion, the Command Block Registers
-contain the cylinder, head, and sector number of the last sector verified.
-
-If an error occurs, the verify terminates at the sector where the error
-occurs. The Command Block Registers contain the cylinder, head, and sector
-number of the sector where the error occurred. The Sector Count Register shall
-contain the number of sectors not yet verified.
-
-9.15 Seek
-
-This command initiates a seek to the track and selects the head specified in
-the command block. The drive need not be formatted for a seek to execute
-properly. See 10.3 for protocol. The drive shall not set DSC=1 until the
-action of seeking has completed. The drive may return the interrupt before the
-seek is completed.
-
-If another command is issued to the drive while a seek is being executed, the
-drive sets BSY=1, waits for the seek to complete, and then begins execution of
-the command.
-
-..The Sector Number Register is used to translate between perceived and real
-..geometry.
-..
-9.16 Set Features
-
-This command is used by the host to establish the following parameters which
-affect the execution of certain drive features:
-
- 44h Vendor unique length of ECC on Read Long/Write Long commands
- 55h Disable read look-ahead feature
- AAh Enable read look-ahead feature
- BBh 4 bytes of ECC apply on Read Long/Write Long commands
-
-See 10.3 for protocol. If the value in the register is not supported or is
-invalid, the drive posts an Aborted Command error.
-
-At power on, or after a software or hardware reset, the default mode is read
-look-ahead enabled and 4 bytes of ECC.
-
-9.17 Set Multiple Mode
-
-This command enables the drive to perform Read and Write Multiple operations
-and establishes the block count for these commands. See 10.3 for protocol.
-
-The Sector Count Register is loaded with the number of sectors per block.
-Drives shall support block sizes of 2, 4, 8, and 16 sectors, if their buffer
-size is at least 8,192 bytes, and may also support other block sizes. Upon
-receipt of the command, the drive sets BSY=1 and checks the Sector Count
-Register.
-
-If the Sector Count Register contains a valid value and the block count is
-supported, the value is loaded for all subsequent Read Multiple and Write
-Multiple commands and execution of those commands is enabled. If a block count
-is not supported, an Aborted Command error is posted, and Read Multiple and
-Write Multiple commands are disabled.
-
-If the Sector Count Register contains 0 when the command is issued, Read and
-Write Multiple commands are disabled.
-
-At power on, or after a hardware or software reset, the default mode is Read
-and Write Multiple disabled.
-
-9.18 Sleep
-
-This command is the only way to cause the drive to enter Sleep Mode. The drive
-is spun down, and when it is stopped, BSY is cleared, an interrupt is
-generated, and the interface becomes inactive.
-
-The only way to recover from Sleep mode without a reset or power on, is for
-the host to issue a software reset.
-
-A drive shall not power on in Sleep Mode nor remain in Sleep Mode following a
-reset sequence. If the drive is already spun down, the spin down sequence is
-not executed.
-
-9.19 Standby
-
-This command causes the drive to enter the Standby Mode. See 10.3 for
-protocol. The drive may return the interrupt before the transition to Standby
-Mode is completed.
-
-If the drive is already spun down, the spin down sequence is not executed.
-
-If the Sector Count Register is non-zero then the automatic power down
-sequence shall be enabled and the timer will begin counting down when the
-drive returns to Idle mode. If the Sector Count Register is zero then the
-automatic power down sequence shall be disabled.
-
-9.20 Standby Immediate
-
-This command causes the drive to enter the Standby Mode. See 10.3 for
-protocol. The drive may return the interrupt before the transition to Standby
-Mode is completed.
-
-If the drive is already spun down, the spin down sequence is not executed.
-
-9.21 Write Buffer
-
-This command enables the host to overwrite the contents of the drive's sector
-buffer with any data pattern desired. See 10.2 for protocol.
-
-The Read Buffer and Write Buffer commands shall be synchronized within the
-drive such that sequential Write Buffer and Read Buffer commands access the
-same 512 bytes within the buffer.
-
-9.22 Write DMA
-
-This command executes in a similar manner to Write Sectors except for the
-following:
-
- - the host initializes a slave-DMA channel prior to issuing the command
- - data transfers are qualified by DMARQ and are performed by the slave-DMA
- channel
- - the drive issues only one interrupt per command to indicate that data
- transfer has terminated and status is available.
-
-Any error encountered during Write DMA execution results in the termination of
-data transfer. The drive issues an interrupt to indicate that data transfer
-has terminated and status is available in the Error Register. The error
-posting is the same as that of the Write Sectors command.
-
-9.23 Write Multiple Command
-
-This command is similar to the Write Sectors command. The drive sets BSY
-within 400 nsec of accepting the command, and interrupts are not presented on
-each sector but on the transfer of a block which contains the number of
-sectors defined by Set Multiple.
-
-Command execution is identical to the Write Sectors operation except that the
-number of sectors defined by the Set Multiple command are transferred without
-intervening interrupts. DRQ qualification of the transfer is required only at
-the start of the data block, not on each sector.
-
-The block count of sectors to be transferred without intervening interrupts is
-programmed by the Set Multiple Mode command, which shall be executed prior to
-the Read Multiple command.
-
-When the Write Multiple command is issued, the Sector Count Register contains
-the number of sectors (not the number of blocks or the block count) requested.
-
-If the number of requested sectors is not evenly divisible by the block count,
-as many full blocks as possible are transferred, followed by a final, partial
-block transfer. The partial block transfer is for n sectors, where
-
- n = (sector count) - modulo (block count)
-
-If the Write Multiple command is attempted before the Set Multiple Mode
-command has been executed or when Write Multiple commands are disabled, the
-Write Multiple operation shall be rejected with an aborted command error.
-
-Disk errors encountered during Write Multiple commands are posted after the
-attempted disk write of the block or partial block transferred. The Write
-command ends with the sector in error, even if it was in the middle of a
-block. Subsequent blocks are not transferred in the event of an error.
-Interrupts are generated when DRQ is set at the beginning of each block or
-partial block.
-
-..The Command Block Registers contain the cylinder, head, and sector number of
-..the sector where the error occurred and the Sector Count Register contains the
-..residual of sectors that need to be transferred for successful completion of
-..the command e.g. each block has 4 sectors, a request for 8 sectors is issued,
-..and an error occurs on the third sector. The Sector Count Register contains 6
-..and the address is that of the third sector.
-..
-The contents of the Command Block Registers following the transfer of a data
-block which had a sector in error are undefined. The host should retry the
-transfer as individual requests to obtain valid error information.
-
-9.24 Write Same
-
-This command executes in a similar manner to Write Sectors except that only
-one sector of data is transferred. The contents of the sector are written to
-the medium one or more times.
-
-NOTE: The Write Same command allows for initialization of part or all of the
-medium to the specified data with a single command.
-
-If the Features Register is 22h, the drive shall write that part of the medium
-specified by the sector count, sector number, cylinder and drive/head
-registers. If the Features Register contains DDh, the drive shall initialize
-all the user accessible medium. If the register contains a value other than
-22h or DDh, the command shall be rejected with an aborted command error.
-
-The drive issues an interrupt to indicate that the command is complete. Any
-error encountered during execution results in the termination of the write
-operation. Status is available in the Error Register if an error occurs. The
-error posting is the same as that of the Write Sectors command.
-
-9.25 Write Long
-
-This command is similar to the Write Sectors command except that it writes the
-data and the ECC bytes directly from the sector buffer; the drive does not
-generate the ECC bytes itself. Only single sector Write Long operations are
-supported.
-
-The transfer of the ECC bytes shall be 8-bits wide.
-
-9.26 Write Sector(s)
-
-This command writes from 1 to 256 sectors as specified in the Sector Count
-Register (a sector count of zero requests 256 sectors), beginning at the
-specified sector. See 10.1 for the DRQ, IRQ and BSY protocol on data
-transfers.
-
-..When this command is accepted, the drive sets DRQ and waits
-..for the host to fill the sector buffer with the data to be written. No
-..interrupt is generated to start the first buffer fill operation. Once the
-..buffer is full, the drive clears DRQ, sets BSY and begins command execution.
-..
-If the drive is not already on the desired track, an implied seek is
-performed. Once at the desired track, the drive searches for the appropriate
-ID field.
-
-If retries are disabled and two index pulses have occurred without error free
-reading of the requested ID, an ID Not Found error is posted.
-
-If retries are enabled, up to a vendor specific number of attempts may be made
-to read the requested ID before posting an error.
-
-If the ID is read correctly, the data loaded in the buffer is written to the
-data field of the sector, followed by the ECC bytes. Upon command completion,
-the Command Block Registers contain the cylinder, head, and sector number of
-the last sector written.
-
-If an error occurs during a write of more than one sector, writing terminates
-at the sector where the error occurs. The Command Block Registers contain the
-cylinder, head, and sector number of the sector where the error occurred. The
-host may then read the command block to determine what error has occurred, and
-on which sector.
-
-9.27 Write Verify
-
-This command is similar to the Write Sectors command, except that each sector
-is verified immediately after being written. The verify operation is a read
-without transfer and a check for data errors. Any errors encountered during
-the verify operation are posted. Multiple sector write verify commands write
-all the requested sectors and then verify all the requested sectors before
-generating the final interrupt.
-
diff --git a/sys/i386/doc/ata/ata-apx b/sys/i386/doc/ata/ata-apx
deleted file mode 100644
index cd8981c58eab..000000000000
--- a/sys/i386/doc/ata/ata-apx
+++ /dev/null
@@ -1,426 +0,0 @@
-Annex A: Diagnostic and Reset Considerations
- (informative).
-
-This annex describes the following timing relationships during:
-
- a) Power On and Hardware Resets
- - One drive
- - Two drives
- b) Software Reset
- - One drive
- - Two drives
- c) Diagnostic Command Execution
- - One drive
- - Two drives
- - Two drives - Drive1 failed
-
-The timing assumes the following:
-
- o DASP- is asserted by Drive1 and received by Drive0 at power-on or
- hardware reset to indicate the presence of Drive1. At all other times it
- is asserted by Drive0 and Drive1 to indicate when a drive is active.
- o PDIAG- is asserted by Drive1 and detected by Drive0. It is used by
- Drive1 to indicate to Drive0 that it has completed diagnostics and is
- ready to accept commands from the Host (BSY bit is cleared). This does not
- indicate that the drive is ready, only that it can accept commands. This
- line may remain asserted until the next reset occurs or an Execute
- Diagnostic command is received.
- o Unless indicated otherwise, all times are relative to the event that
- triggers the operation (RESET-, SRST=1, Execute Diagnostic Command).
-
-A.1 Power On and Hardware Resets
-
-A.1.1 Power On and Hardware Resets - One Drive
-
- - Host asserts RESET- for a minimum of 25 usec.
- - Drive0 sets BSY within 400 nsecs after RESET- is negated.
- - Drive0 negates DASP- within 1 msec after RESET- negated.
- - Drive0 performs hardware initialization
- - Drive0 may revert to its default condition
- - Drive0 waits 1 msec then samples for at least 450 msec for DASP- to be
- asserted from Drive1.
- - Drive0 clears BSY when ready to accept commands (within 31 seconds).
-
-A.1.2 Power On and Hardware Resets - Two Drives
-
- - Host asserts RESET- for a minimum of 25 usec.
- - Drive0 and Drive1 set BSY within 400 nsec after RESET- negated.
- - DASP- is negated within 1 msec after RESET- is negated.
-
-A.1.2.1 Drive1
-
- - Drive1 negates PDIAG- before asserting DASP-.
- - Drive1 asserts DASP- within 400 msecs after RESET- (to show presence).
- - Drive1 performs hardware initialization and executes its internal
- diagnostics.
- - Drive1 may revert to its default condition
- - Drive1 posts diagnostic results to the Error Register
- - Drive1 clears BSY when ready to accept commands.
- - Drive1 asserts PDIAG- to indicate that it is ready to accept commands
- (within 30 seconds from RESET-).
- - Drive1 negates DASP- after the first command is received or negates DASP-
- if no command is received within 30 seconds after RESET-.
-
-A.1.2.2 Drive0
-
- - Drive0 performs hardware initialization and executes its internal
- diagnostics.
- - Drive0 may revert to its default condition
- - Drive0 posts diagnostic results to the Error Register
- - After 1 msec, Drive0 waits at least 450 msec for DASP- to be asserted
- (from Drive1). If DASP- is not asserted, no Drive1 is present (see POWER-
- ON RESET - One Driveoperation).
- - Drive0 waits up to 31 seconds for Drive1 to assert PDIAG-. If PDIAG- is
- not asserted, Drive0 sets Bit7=1 in the Error Register.
- - Drive0 clears BSY when ready to accept commands (within 31 seconds).
-
-A.2 Software Reset
-
-A.2.1 Software Reset - One Drive
-
- - Host sets SRST=1 in the Device Control Register.
-.. - Drive0 waits for SRST to be cleared by Host.
-.. - Drive0 sets BSY within 400 nsec after SRST=0.
- - Drive0 sets BSY within 400 nsec after detecting that SRST=1.
- - Drive0 performs hardware initialization and executes its internal
- diagnostics.
- - Drive0 may revert to its default condition.
- - Drive0 posts diagnostic results to the Error Register.
- - Drive0 clears BSY when ready to accept commands (within 31 seconds).
-
-A.2.2 Software Reset - Two Drives
-
- - Host sets SRST=1 in the Device Control Register.
-.. - Drives wait for host to clear SRST.
-.. - Drive0 and Drive1 set BSY within 400 nsec after SRST=0.
- - Drive0 and Drive1 set BSY within 400 nsec after detecting that SRST=1.
- - Drive0 and Drive1 perform hardware initialization.
- - Drive0 and Drive1 may revert to their default condition.
-
-A.2.2.1 Drive1
-
- - Drive1 negates PDIAG- within 1 msec.
- - Drive1 clears BSY when ready to accept commands.
- - Drive1 asserts PDIAG- to indicate that it is ready to accept commands
- (within 30 seconds).
-
-A.2.2.2 Drive0
-
- - Drive0 waits up to 31 seconds for Drive1 to assert PDIAG-.
- - Drive0 clears BSY when ready to accept commands (within 31 seconds).
-
-A.3 Diagnostic Command Execution
-
-A.3.1 Diagnostic Command Execution - One Drive(Passed)
-
- - Drive0 sets BSY within 400 nsec after the Execute Diagnostic command was
- received.
- - Drive0 performs hardware initialization and internal diagnostics.
- - Drive0 resets Command Block registers to default condition.
- - Drive0 posts diagnostic results to the Error Register
- - Drive0 clears BSY when ready to accept commands (within 6 seconds).
-
-A.3.2 Diagnostic Command - Two Drives (Passed)
-
- - Drive0 and Drive1 set BSY within 400 nsec after the Execute Diagnostic
- command was received.
-
-A.3.2.1 Drive1
-
- - Drive1 negates PDIAG- within 1 msec after command received.
- - Drive1 performs hardware initialization and internal diagnostics.
- - Drive1 resets the Command Block registers to their default condition.
- - Drive1 posts diagnostic results to the Error Register
- - Drive1 clears BSY when ready to accept commands.
- - Drive1 asserts PDIAG- to indicate that it is ready to accept commands
- (within 5 seconds).
-
-A.3.2.2 Drive0
-
- - Drive0 performs hardware initialization and internal diagnostics.
- - Drive0 resets the Command Block registers to their default condition.
- - Drive0 waits up to <5 seconds for Drive1 to assert PDIAG-.
- - Drive0 posts diagnostic results to the Error Register
- - Drive0 clears BSY when ready to accept commands (within 6 seconds).
-
-A.3.3 Diagnostic Command Execution - One Drive(Failed)
-
- - Drive0 sets BSY within 400 nsec after Diagnostic command received.
- - Drive0 performs hardware initialization and internal diagnostics.
- - Drive0 resets Command Block registers to default condition.
- - Drive0 posts a Diagnostic Code to the Error Register indicating a failure.
- - Drive0 clears BSY when ready to accept commands (within 6 seconds)
-
-A.3.4 Diagnostic Command Execution - Two Drives (Drive1 Failed)
-
- - Drive0 and Drive1 set BSY within 400 nsec after Diagnostic command
- received.
-
-A.3.4.1 Drive1
-
- - Drive1 negates PDIAG- within 1 msec after command received.
- - Drive1 performs hardware initialization and internal diagnostics.
- - Drive1 resets the Command Block registers to their default condition.
- - Drive1 posts a Diagnostic Code to the Error Register indicating failure.
- - Drive1 clears BSY.
- - Drive1 does not assert PDIAG-, indicating that it failed diagnostics.
-
-A.3.4.2 Drive0
-
- - Drive0 performs hardware initialization and internal diagnostics.
- - Drive0 resets the Command Block registers to their default condition.
- - Drive0 waits 6 seconds for Drive1 to assert PDIAG- but PDIAG- is not
- asserted by Drive1.
- - Drive0 posts a Diagnostic Code to the Error Register setting Bit7=1 to
- indicate that Drive1 failed diagnostics.
- - Drive0 clears BSY when ready to accept commands (within 6 seconds).
-
-..rm102
- NOTE: The 6 seconds referenced above is a host-oriented value.
-
-Annex B: Diagnostic and Reset Considerations
- (informative).
-
-B.1 Power on and hardware reset (RESET-)
-
-DASP- is read by Drive0 to determine if Drive1 is present. If Drive1 is
-present Drive0 will read PDIAG- to determine when it is valid to clear BSY
-and whether Drive1 has powered on or reset without error, otherwise Drive0
-clears BSY whenever it is ready to accept commands. Drive 0 may assert DASP-
-to indicate drive activity.
-
-B.2 Software reset
-
-If Drive1 is present Drive0 will read PDIAG- to determine when it is valid
-to clear BSY and whether Drive1 has reset without any errors, otherwise
-Drive 0 will simply reset and clear BSY. DASP- is asserted by Drive0 (and
-Drive1 if it is present) in order to indicate drive active.
-
-B.3 DriveDiagnostic Command
-
-If Drive1 is present, Drive0 will read PDIAG- to determine when it is valid
-to clear BSY and if Drive1 passed or failed the Execute DriveDiagnostic
-command, otherwise Drive0 will simply execute its diagnostics and then clear
-BSY. DASP- is asserted by Drive0 (and Drive1 if it is present) in order to
-indicate the drive is active.
-
-B.4 Truth Table
-
-In all the above cases: Power on, RESET-, software reset, and the Execute
-DriveDiagnostics command the Drive0 Error Register is calculated as follows:
-
- Drive1 PDIAG- Drive0 Error
- Present? Asserted? Passed Register
-
- Yes Yes Yes 01h
- Yes Yes No 0xh
- Yes No Yes 81h
- Yes No No 8xh
- No (not read) Yes 01h
- No (not read) No 0xh
-
-Where x indicates the appropriate Diagnostic Code for the Power on, RESET-,
-software reset, or drivediagnostics error.
-
-B.5 Power On or Hardware Reset Algorithm
-
- 1) Power on or hardware reset
- 2) The hardware should automatically do the following:
- a) Set up the hardware to post both Drive0 and Drive1 status
- b) Set the Drive0 Status Register to 80h (set BSY and clear
- all the other status bits)
- c) Set the Drive1 Status Register to 80h (set BSY and clear all
- the other status bits)
- 3) Read the single Drive0/Drive1 jumper and note its state
- 4) Perform any remaining time critical hardware initialization including
- starting the spin up of the disk if needed
- 5) If Drive1
- a) Negate the PDIAG- signal
- b) Set up PDIAG- as an output
- c) Assert the DASP- output
- d) Set up DASP- as an output if necessary
- e) Set up the hardware so it posts Drive1 status only and
- continue to post 80h for Drive1 status
- NOTE: all this must happen within 400 msec after power on or RESET-
- If Drive0
- a) Set up PDIAG- as an input
- b) Release DASP- and set up DASP- as an input
- c) Test DASP- for 450 msec or until DASP- is asserted by Drive1
- d) If DASP- is asserted within 450 msec
- i) Note that Drive1 is present
- ii) Set up the hardware so it posts Drive0 status only
- and continue to post 80h for the Drive0 status
- If DASP- is not asserted within 450 msec
- i) note that Drive1 is not present
- e) Assert DASP- to indicate drive activity
- 6) Complete all the hardware initialization needed to get the drive ready,
- including:
- a) Set the Sector Count Register to 01h
- b) Set the Sector Number Register to 01h
- c) Set the Cylinder Low Register to 00h
- d) Set the Cylinder High Register to 00h
- e) Set the Drive/Head Register to 00h
- 7) If Drive1 and power on, or RESET- is valid
- a) Set the Error Register to Diagnostic Code 01h
- b) Set the Drive1 Status Register to 00h
- c) Assert PDIAG-
- NOTE: All this must happen within 5 seconds of power on or the
- negation of RESET-
- If Drive1 and power on or RESET- bad
- a) Set the Error Register to the appropriate Diagnostic Code
- b) Set the Drive1 Status Register to 00h
- NOTE: All this must happen within 5 seconds of power on or the
- negation of RESET-
- If Drive0, power on or RESET- valid, and a Drive1 is present
- a) Test PDIAG- for 6 seconds or until PDIAG- is asserted by Drive1
- b) If PDIAG- is asserted within 6 seconds
- i) Set the Error Register to Diagnostic Code 01h
- c) If PDIAG- is not asserted within 6 seconds
- i) Set the Error Register to 81h
- d) Set the Drive0 Status Register to 00h
- If Drive0, power on or RESET- bad, and a Drive1 is present
- a) Test PDIAG- for 6 seconds or until PDIAG- is asserted by
- Drive1
- b) If PDIAG- is asserted within 6 seconds
- i) Set the Error Register to the appropriate Diagnostic Code
- c) If PDIAG- is not asserted within 6 seconds
- i) Set the Error Register to 80h + the appropriate code
- d) Set the Drive0 Status Register to 00h
- If Drive0, power on or RESET- valid, and no Drive1 is present
- a) Set the Error Register to Diagnostic Code 01h
- b) Set the Drive1 Status Register to 00h
- c) Set the Drive0 Status Register to 00h
- If Drive0, power on or RESET- bad, and no Drive1 is present
- a) Set the Error Register to the appropriate Diagnostic Code
- b) Set the Drive1 Status Register to 00h
- c) Set the Drive0 Status Register to 00h
- 8) Finish spin up if needed
- 9) If Drive1
- a) Set the Drive1 Status Register to 50h
- b) Negate DASP- if a command is not received within 30 seconds
- If Drive0 and a Drive1 is present
- a) Set the Drive0 Status Register to 50h
- b) Negate DASP-
- If Drive0 and no Drive1 is present
- a) Leave the Drive1 Status Register 00h
- b) Set the Drive0 Status Register to 50h
- c) Negate DASP-
-
-B.6 Software Reset Algorithm
-
- 1) The software reset bit is set
- 2) If Drive1
- a) The hardware should set BUSY in the Drive1 Status Register
- b) Negate the PDIAG- signal
- NOTE: this must happen within 1 msec of the software reset
- If Drive0 and Drive1 is present
- a) The hardware should set BUSY in the Drive0 Status Register
- If Drive0 and there is no Drive1 the hardware should:
- a) Set BUSY in the Drive0 Status Register
- b) Set the Drive1 Status Register to 80h
- 3) Assert DASP-
- 4) Finish all the hardware initialization needed to place the drive in reset
- 5) Wait for the software reset bit to clear
- 6) Finish all hardware initialization needed to get the drive ready
- to receive any type of command from the host including:
- a) Set the Sector Count Register to 01h
- b) Set the Sector Number Register to 01h
- c) Set the Cylinder Low Register to 00h
- d) Set the Cylinder High Register to 00h
- e) Set the Drive/Head Register to 00h
- 7) If Drive1 and reset valid
- a) Set the Error Register to Diagnostic Code 01h
- b) Set the Drive1 Status Register to 50h
- c) Assert PDIAG-
- NOTE: All this must happen within 5 seconds of the clearing of
- the software reset bit
- If Drive1 and reset bad
- a) Set the Error Register to the appropriate Diagnostic Code
- b) Set the Drive1 Status Register to 50h
- NOTE: All this must happen within 5 seconds of the clearing of
- the software reset bit
- If Drive0, reset valid, and a Drive1 is present
- a) Test PDIAG- for 6 seconds or until PDIAG- is asserted by
- Drive1
- b) If PDIAG- is asserted within 6 seconds
- i) Set the Error Register to Diagnostic Code 01h
- c) If PDIAG- is not asserted within 6 seconds
- i) Set the Error Register to 81h
- d) Set the Drive0 Status Register to 50h
- If Drive0, reset bad, and a Drive1 is present
- a) Test PDIAG- for 31 seconds or until PDIAG- is asserted by
- Drive1
- b) If PDIAG- is asserted within 31 seconds
- i) Set the Error Register to the appropriate Diagnostic Code
- c) If PDIAG- is not asserted within 31 seconds
- i) Set the Error Register to 80h + the appropriate code
- d) Set the Drive0 Status Register to 50h
- If Drive0, reset valid, and no Drive1 is present
- a) Set the Error Register to Diagnostic Code 01h
- b) Set the Drive1 Status Register to 00h
- c) Set the Drive0 Status Register to 50h
- If Drive0, reset bad, and no Drive1 is present
- a) Set the Error Register to the appropriate Diagnostic Code
- b) Set the Drive1 Status Register to 00h
- c) Set the Drive0 Status Register to 50h
-
-B.7 Diagnostic Command Algorithm
-
- 1) The diagnostics command is received
- 2) If Drive1
- a) The hardware should set BUSY in the Drive1 Status Register
- b) Negate the PDIAG- signal
- NOTE: this must happen within 1 msec after command acceptance
- If Drive0 and Drive1 is present
- a) The hardware should set BUSY in the Drive0 Status Register
- If Drive0 and there is no Drive1 the hardware should
- a) Set BUSY in the Drive0 Status Register
- b) Set BUSY in the Drive1 Status Register
- 3) Assert DASP-
- 4) Perform all the drive diagnostics and note their results
- 5) Finish all the hardware initialization needed to get the drive ready
- to receive any type of command from the host including:
- a) Set the Sector Count Register to 01h
- b) Set the Sector Number Register to 01h
- c) Set the Cylinder Low Register to 00h
- d) Set the Cylinder High Register to 00h
- e) Set the Drive/Head Register to 00h
- 6) If Drive1 and passed
- a) Set the Error Register to Diagnostic Code 01h
- b) Set the Drive1 status to 50h
- c) Assert PDIAG-
- NOTE: All this must happen within 5 seconds of the acceptance
- of the diagnostic command
- If Drive1 and did not pass
- a) Set the Error Register to the appropriate Diagnostic Code
- b) Set the Drive1 status to 50h
- NOTE: All this must happen within 5 seconds of the acceptance
- of the diagnostic command
- If Drive0, passed, and a Drive1 is present
- a) Test PDIAG- for 6 seconds or until PDIAG- is asserted by
- Drive1
- b) If PDIAG- is asserted within 6 seconds
- i) Set the Error Register to Diagnostic Code 01h
- c) If PDIAG- is not asserted within 6 seconds
- i) Set the Error Register to 81h
- d) Set the Drive0 status to 50h
- e) Issue interrupt to the host
- If Drive0, did not pass, and a Drive1 is present
- a) Test PDIAG- for 6 seconds or until PDIAG- is asserted by Drive1
- b) If PDIAG- is asserted within 6 seconds
- i) Set the Error Register to the appropriate Diagnostic Code
- c) If PDIAG- is not asserted within seconds
- i) Set the Error Register to 80h + the appropriate code
- d) Set the Drive0 Status Register to 50h
- e) Issue interrupt to the host
- If Drive0, passed, and no Drive1 is present
- a) Set the Error Register to Diagnostic Code 01h
- b) Set the Drive1 Status Register to 00h
- c) Set the Drive0 Status Register to 50h
- d) Issue interrupt to the host
- If Drive0, did not pass, and no Drive1 is present
- a) Set the Error Register to the appropriate Diagnostic Code
- b) Set the Drive1 Status Register to 00h
- c) Set the Drive0 Status Register to 50h
- d) Issue interrupt to the host
-
diff --git a/sys/i386/doc/ata/ata-prt b/sys/i386/doc/ata/ata-prt
deleted file mode 100644
index 546510bcf6a0..000000000000
--- a/sys/i386/doc/ata/ata-prt
+++ /dev/null
@@ -1,174 +0,0 @@
-Copies of this proposal may be purchased from: CAM/89-002
-CAM Committee 408-867-6630
-14426 Black Walnut Ct, Saratoga CA 95070
-
- working document of the
- CAM (Common Access Method Committee)
-
- draft proposal
-
- ATA (AT Attachment)
-
- Rev 2.1 June 11, 1990
-
-ABSTRACT: This standard defines mechanical, electrical, and functional
-requirements for attaching small computers employing an AT Bus with
-intelligent peripheral devices. The resulting interface provides a common
-interface specification for systems manufacturers, system integrators,
-controller manufacturers, and suppliers of intelligent disk drives.
-
-
-CAUTION: This is a preliminary draft of the proposed standard. It is subject
-to change without notice, at the sole discretion of the CAM Committee. It is
-likely that some sections may change significantly, and most sections will
-change to some extent in the course of further development of this draft
-standard. This draft is distributed solely for the purpose of review and
-comment, and it should not be used as a design document without assuming the
-risk of an early implementation.
-
-COPYRIGHT NOTICE: This draft standard is based upon product specifications of
-contributing members, these documents may be copyrighted by the individual
-companies. This draft standard may be reproduced without further permission,
-for the purpose of review and comment or for the purpose of including in an
-appropriate product specification provided the risk of early implementation is
-assumed. All other rights are reserved.
-
-
-POINTS OF CONTACT:
-
- I. Dal Allan (CAM Committee Chairman)
- ENDL
- 14426 Black Walnut Court
- Saratoga, CA 95070
- (408) 867-6630
-
-
-
-If changes from the prior revision of this document are included, they may
-be identified by:
-
- - change bars at the side of each paragraph or
- - printed in bold or
- - printed in italics or
- - underscored in the text.
-
-The specific technique used will depend on the software used to detect the
-differences and the printer used to print the document.
-
-In the event that deleted text is identified by an overstrike, the Table of
-Contents will not be accurate.
-
-An electronic copy of this document is available from the CAM Committee
-(408-867-6630).
-
-This document has been prepared according to the style guide of the ISO
-(International Organization of Standards).
-
-
-If this document was printed in a 2-up form directly from the printer, NOTEs
-had to be adjusted to fit into a half-page, which may have resulted in an
-imperfect representation of the format within the NOTE. This is most likely
-to occur if a series of NOTEs are mixed in without any line separation.
-
-
-
-
-
-
-
-
-.. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-.. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-.. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-..
-.. Please look this revision over carefully. Larry and I have reviewed
-.. this document for editorial consistency.
-.. This is close to the final step in having a standards document.
-.. Please pay special attention to references, because any renumbering
-.. may mean a few boo-boos crept in. 
-..
-.. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-.. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-.. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-..
-.. EXPOSITORY REMARKS
-..
-..
-..
-..
-..
-..
-..
-..
-..I S O
-..
-..INTERNATIONAL ORGANIZATION FOR STANDARDIZATION
-..
-..
-..
-..
-..
-..
-.. Information Processing Systems --
-..
-.. Common Access Method AT Attachment
-..
-..
-..
-..
-..
-..
-..
-.. +-----------------------------------------+
-.. | +-------------------------------------+ |
-.. | | | |
-.. | | ISO 10***:198x | |
-.. | | | |
-.. | | | |
-.. | | | |
-.. | +-------------------------------------+ |
-.. +-----------------------------------------+
-..
-..
-..
-..
-..
-..
-..
-..
-.. Technical Editor: I. Dal Allan
-.. ENDL
-.. 14426 Black Walnut Court
-.. Saratoga
-.. CA 95070
-..
-.. Ph: 408-867-6630
-.. Fx: 408-867-2115
-.. Tx: 650-250-1752
-..
-..
-..foCommon Access Method AT Attachment
-..dm Merging ata-1 .dif
-..fi ata-1 .dif
-..dm Merging ata-2 .dif
-..fi ata-2 .dif
-..dm Merging ata-3 .dif
-..fi ata-3 .dif
-..dm Merging ata-4 .dif
-..fi ata-4 .dif
-..dm Merging ata-5 .dif
-..fi ata-5 .dif
-..dm Merging ata-6 .dif
-..fi ata-6 .dif
-..dm Merging ata-7 .dif
-..fi ata-7 .dif
-..dm Merging ata-8 .dif
-..fi ata-8 .dif
-..dm Merging ata-9 .dif
-..fi ata-9 .dif
-..dm Merging ata-10 .dif
-..fi ata-10 .dif
-..dm Merging ata-11 .dif
-..fi ata-11 .dif
-..dm Merging ata-apx .dif
-..fi ata-apx .dif
diff --git a/sys/i386/doc/ata/ata-toc b/sys/i386/doc/ata/ata-toc
deleted file mode 100644
index 1866f7677596..000000000000
--- a/sys/i386/doc/ata/ata-toc
+++ /dev/null
@@ -1,159 +0,0 @@
- TABLE OF CONTENTS
-
- 1. Scope 1
- 1.1 Description of Clauses 1
-
- 2. References 1
- 3. General Description 1
- 3.1 Structure 2
-
- 4. Definitions and Conventions 2
- 4.1 Definitions 2
- 4.2 Conventions 2
-
- 5. Interface Cabling Requirements 3
- 5.1 Configuration 3
- 5.2 Addressing Considerations 4
- 5.3 DC Cable and Connector 4
- 5.3.1 4-Pin Power 4
- 5.3.2 3-Pin Power 5
- 5.3.3 Device Grounding 5
-
- 5.4 I/O Connector 5
- 5.5 I/O Cable 6
-
- 6. Physical Interface 6
- 6.1 Signal Conventions 6
- 6.2 Signal Summary 7
- 6.3 Signal Descriptions 9
- 6.3.1 CS1FX- (Drive chip Select 0) 9
- 6.3.2 CS3FX- (Drive chip Select 1) 9
- 6.3.3 DA0-2 (Drive Address Bus) 10
- 6.3.4 DASP- (Drive Active/Drive 1 Present) 10
- 6.3.5 DD0-DD15 (Drive Data Bus) 10
- 6.3.6 DIOR- (Drive I/O Read) 10
- 6.3.7 DIOW- (Drive I/O Write) 10
- 6.3.8 DMACK- (DMA Acknowledge) (Optional) 10
- 6.3.9 DMARQ (DMA Request) (Optional) 11
- 6.3.10 INTRQ (Drive Interrupt) 11
- 6.3.11 IOCS16- (Drive 16-bit I/O) 11
- 6.3.12 IORDY (I/O Channel Ready) (Optional) 12
- 6.3.13 PDIAG- (Passed Diagnostics) 12
- 6.3.14 RESET- (Drive Reset) 12
- 6.3.15 SPSYNC (Spindle Synchronization) (Optional) 12
-
- 7. Logical Interface 13
- 7.1 General 13
- 7.1.1 Bit Conventions 13
- 7.1.2 Environment 13
-
- 7.2 I/O Register Descriptions 14
- 7.2.1 Alternate Status Register 14
- 7.2.2 Command Register 15
- 7.2.3 Cylinder High Register 15
- 7.2.4 Cylinder Low Register 15
- 7.2.5 Data Register 15
- 7.2.6 Device Control Register 15
- 7.2.7 Drive Address Register 16
- 7.2.8 Drive/Head Register 16
- 7.2.9 Error Register 16
- 7.2.10 Features Register 17
- 7.2.11 Sector Count Register 17
- 7.2.12 Sector Number Register 17
- 7.2.13 Status Register 18
-
- 8. Programming Requirements 19
- 8.1 Reset Response 19
- 8.2 Translate Mode 19
- 8.3 Power Conditions 20
- 8.4 Error Posting 20
-
- 9. Command Descriptions 21
- 9.1 Check Power Mode 24
- 9.2 Execute Drive Diagnostic 24
- 9.3 Format Track 24
- 9.4 Identify Drive 25
- 9.4.1 Number of fixed cylinders 26
- 9.4.2 Number of heads 27
- 9.4.3 Number of unformatted bytes per track 27
- 9.4.4 Number of unformatted bytes per sector 27
- 9.4.5 Number of sectors per track 27
- 9.4.6 Serial Number 27
- 9.4.7 Buffer Type 27
- 9.4.8 Firmware Revision 27
- 9.4.9 Model Number 27
- 9.4.10 PIO data transfer cycle timing mode 27
- 9.4.11 DMA data transfer cycle timing mode 28
-
- 9.5 Idle 28
- 9.6 Idle Immediate 28
- 9.7 Initialize Drive Parameters 28
- 9.8 Recalibrate 28
- 9.9 Read Buffer 28
- 9.10 Read DMA 29
- 9.11 Read Long 29
- 9.12 Read Multiple Command 29
- 9.13 Read Sector(s) 30
- 9.14 Read Verify Sector(s) 30
- 9.15 Seek 31
- 9.16 Set Features 31
- 9.17 Set Multiple Mode 31
- 9.18 Sleep 32
- 9.19 Standby 32
- 9.20 Standby Immediate 32
- 9.21 Write Buffer 32
- 9.22 Write DMA 32
- 9.23 Write Multiple Command 33
- 9.24 Write Same 33
- 9.25 Write Long 34
- 9.26 Write Sector(s) 34
- 9.27 Write Verify 34
-
- 10. Protocol Overview 35
- 10.1 PIO Data In Commands 35
- 10.1.1 PIO Read Command 35
- 10.1.2 PIO Read Aborted Command 36
-
- 10.2 PIO Data Out Commands 36
- 10.2.1 PIO Write Command 36
- 10.2.2 PIO Write Aborted Command 37
-
- 10.3 Non-Data Commands 37
- 10.4 Miscellaneous Commands 37
- 10.5 DMA Data Transfer Commands (Optional) 37
- 10.5.1 Normal DMA Transfer 38
- 10.5.2 Aborted DMA Transfer 38
- 10.5.3 Aborted DMA Command 38
-
- 11. Timing 39
- 11.1 Deskewing 39
- 11.2 Symbols 39
- 11.3 Terms 39
- 11.4 Data Transfers 40
- 11.5 Power On and Hard Reset 42
-
- FIGURES
-
- FIGURE 5-1: ATA INTERFACE TO EMBEDDED BUS PERIPHERALS 3
- FIGURE 5-2: HOST BUS ADAPTER AND PERIPHERAL DEVICES 4
- FIGURE 5-3: ATA INTERFACE TO CONTROLLER AND PERIPHERAL DEVICES 4
- FIGURE 5-4: 40-PIN CONNECTOR MOUNTING 6
- FIGURE 11-1: PIO DATA TRANSFER TO/FROM DRIVE 40
- FIGURE 11-2: IORDY TIMING REQUIRMENTS 41
- FIGURE 11-3: DMA DATA TRANSFER 41
- FIGURE 11-4 RESET SEQUENCE 42
-
- TABLES
-
- TABLE 5-1: DC INTERFACE 5
- TABLE 5-2: DC INTERFACE 5
- TABLE 5-3: CABLE PARAMETERS 6
- TABLE 6-1: INTERFACE SIGNALS 8
- TABLE 6-2: INTERFACE SIGNALS DESCRIPTION 9
- TABLE 7-1: I/O PORT FUNCTIONS/SELECTION ADDRESSES 14
- TABLE 8-1: POWER CONDITIONS 20
- TABLE 8-2: REGISTER CONTENTS 21
- TABLE 9-1: COMMAND CODES AND PARAMETERS 23
- TABLE 9-2: DIAGNOSTIC CODES 24
-
-
diff --git a/sys/i386/doc/ed.relnotes b/sys/i386/doc/ed.relnotes
deleted file mode 100644
index d01e21d4c427..000000000000
--- a/sys/i386/doc/ed.relnotes
+++ /dev/null
@@ -1,174 +0,0 @@
-
- Release Notes for 'ed' Device Driver
- David Greenman, 24-May-1993
- ------------------------------------
-
-Last updated: 22-November-1993
-
-INTRODUCTION
-------------
- The 'ed' device driver is a new, high performance device driver supporting
-the Western Digital/SMC 80x3 series (including 'EtherCard PLUS' 'Elite16' and
-'Ultra'), the 3Com 3c503 (both 8 and 16 bit versions), and the Novell NE1000/
-NE2000. All of the ethernet controllers use the DS8390, 83C690, or 83C790
-Network Interface Controller (NIC). The differences between the boards are in
-their memory capacity, bus width (8/16 bits), special logic (asic) used to
-configure the board, and the host access method to the NIC memory (shared or
-programmed I/O). Every effort has been made to conform to the manufactures'
-specifications for the NIC and asic. This includes both normal operation and
-error recovery.
-
-PERFORMANCE
------------
-
-transmit
---------
- The 8390 doesn't provide a mechanism for chained write buffers, so it is
-very important for maximum performance to queue the next packet for
-transmission as soon as the current one has completed. On boards with 16k or
-more of memory, the NIC memory is divided in a way that allows enough space
-for two full size packets to be buffered for transmission. When sufficient
-data is available for transmission, a packet is copied into the NIC memory,
-the transmission is started, and then an additional packet is copied into the
-NIC memory (to a different memory area). As soon as the first packet has
-completed, transmission of a second packet can then be started immediately.
-This results in nearly the highest performance possible from ethernet.
-
-Packets go out on the 'wire' with the following format:
-
-preamble dest-addr src-addr type data FCS intr-frame
-64bits 48bits 48bits 16bits 1500bytes 32bits 96bits
-
- With 10Mbits/sec, each bit is 100ns in duration. All of the above fields,
-except for data are of fixed length. With full sized packets (1500 bytes), the
-maximum unidirectional data rate can be calculated as: 6.4us + 4.8us + 4.8us +
-1.6us + 1200us + 3.2us + 9.6us = 1230.4us/packet = 812.74382 packets/second =
-1219115.7 (1190k) bytes/second. With TCP, there is a 40 byte overhead for the
-IP and TCP headers, so there is only 1460 bytes of data per packet. This
-reduces the maximum data rate to 1186606 bytes/second. With TCP, there will
-also be periodic acknowledgments which will reduce this figure somewhat both
-because of the additional traffic in the reverse direction and because of the
-occasional collisions that this will cause. Despite this, the data rate has
-still been consistantly measured at 1125000 (~1100k) bytes/second through a TCP
-socket. In these tests, the TCP window was set to 16384 bytes. With UDP, there
-is less overhead for the headers, and with 1472 bytes of data per packet, a
-data rate of 1196358.9 (1168k) bytes/sec is possible. UDP performance hasn't
-been precisely measured with this device driver, but less precise tests show
-this to be true (measured at around 1135k/second).
-
-receive
--------
- The 8390 implements an NIC memory ring-buffer to store incoming packets.
-The 8bit boards (8003, 3c503, and NE1000) usually have only 8k bytes of shared
-memory. This is only enough room for about 4 full size (1500 byte) packets.
-This can sometimes be a problem, especially on the original WD8003E and 3c503.
-This is because these boards' NIC memory access speed is also quite slow
-compared to newer 16bit boards - typically less than 1MB/second. The additional
-overhead of this slow memory access, and the fact that there is only room for 4
-full-sized packets means that the ring-buffer will occassionally overflow. When
-this happens, the board must be reset to avoid a lockup problem in early
-revision 8390's. Resetting the board will cause all of the data in the ring-
-buffer to be lost - requiring it to be re-transmitted/received...slowing things
-even further. Because of these problems, maximum throughput on boards of this
-type is only about 400-600k per second. The 16bit boards, however, have 16k of
-memory as well as much faster memory access speed. Typical memory access speed
-on these boards is about 1.7-4MB/second (with the Novell NE2000 being the
-slowest and the SMC 8013 being the fastest). These boards generally have no
-problems keeping up with full ethernet speed. The only problem I've seen with
-these boards is related to the (slow) performance of the BSD Net/2 malloc code
-when additional mbufs must be added to the pool. This can sometimes increase
-the total time to remove a packet enough for a ring-buffer overflow to occur.
-This tends to be highly transient, and quite rare on fast machines. I've only
-seen this problem when doing tests with large amounts of UDP traffic without
-any acknowledgments (uni-directional). Again, this has been very rare.
-
- All of the above tests were done using a 486DX2/66, 486DX/33, 386DX/40,
-8-9Mhz ISA bus, using FreeBSD 1.0. TCP tests were done with the 'ttcp'
-performance test utility, and also with FTP client/server. UDP tests were done
-with a modified version of ttcp (to work around a bug in the BSD Net/2 UDP
-code related to queue depth), and also with NFS.
-
-KERNEL INSTALLATION
--------------------
- (Note that this driver comes standard in FreeBSD 1.0, NetBSD 0.9, and 386BSD
-0.2, and therefore doesn't require installation)
- To 'install' this driver, the files if_ed.c and if_edreg.h must be copied
-into the i386/isa kernel source directory and the following line must be
-added into the file i386/conf/files.i386:
-
-i386/isa/if_ed.c optional ed device-driver
-
- To build a kernel that includes this driver, first comment out any 'we',
-'ec', or 'ne' devices in your kernel config file. Then, add a line similar to
-the following (modify to match your cards configuration):
-
-device ed0 at isa? port 0x300 net irq 10 iomem 0xcc000 vector edintr
-
- Note that the 'iosiz' option is not needed because the driver automatically
-figures this out. However, if you have problems with this, it can be specified
-to force the use of the size you specify.
- The iomem 0xcc000 option is not need for NE1000/NE2000 boards because they
-use programmed I/O rather than shared memory to access the NIC's memory.
- On 3Com boards, the tranceiver must be enabled in software (there is no
-hardware default). In this driver, this is controlled using the "LLC0" link-
-level control flag. The default for this flag can be set in your kernel config
-file by specifying 'flags 0x01' in the 'ed' device specification line (this
-is necessary for diskless support). Otherwise, the tranceiver is easily enabled
-and disabled with a command like "ifconfig ed0 -llc0" to enable the tranceiver
-or "ifconfig ed0 llc0" to disable it; this assumes that you have the modified
-ifconfig(8) that originally appeared in the 386BSD patchkit. To specify the
-'flags' option, use a line similar to:
-
-device ed0 at isa? port 0x300 net irq 10 flags 0x01 iomem 0xcc000 vector edintr
-
- Flags can be similarly specified to force 8 or 16bit mode, and disabling
-the use of transmitter double buffering. The various supported flag values
-are:
-
- Disable tranceiver 0x01
- Force 8 bit mode 0x02
- Force 16 bit mode 0x04
- Disable multi TX buffering 0x08
-
- To use multiple flags, simply add the values together. Note that these
-numbers are in hexadecimal. If the 'Force 8 bit' and 'Force 16 bit' flags are
-both specified, the 8 bit flag has precedence.
- The use of the above flags should only be necessary under exceptional
-conditions where the probe routine incorrectly determines the board type (such
-is the case with Compex boards, which require the 16bit flag and an iosiz
-16384), or where the high performance of the transmitter causes problems with
-other vendors hardware.
-
-
-KNOWN PROBLEMS
---------------
-
-1) Early revision DS8390B chips have problems. They lock-up whenever the
- receive ring-buffer overflows. They occassionally switch the byte order
- of the length field in the packet ring header (several different causes
- of this related to an off-by-one byte alignment) - resulting in "NIC
- memory corrupt - invalid length NNNNN" messages. The board is reset
- whenever these problems occur, but otherwise there is no problem with
- recovering from these conditions.
-2) 16bit boards that use shared memory can conflict with 8bit BIOSes, BIOS
- extensions (like the VGA), and 8bit devices with shared memory (again
- like the VGA, or perhaps a second ethernet board). There is a work-
- around for this in the driver, however. The problem is that the
- ethernet board stays in 16bit mode, asserting its '16bit' signal on
- the ISA bus. This signal is shared by other devices/ROMs in the same
- 128K memory segment as the ethernet card - causing the CPU to read the
- 8bit ROMs as if they were 16bit wide. The work-around involves setting
- the host access to the shared memory to 16bits only when the memory is
- actually accessed, and setting it back to 8bit mode all other times.
- Without this work-around, the machine will hang whenever a reboot is
- attempted. This work-around also allows the board to co-exist with
- other 8bit devices that have shared memory. This has only been
- implemented for SMC/WD boards, but I haven't seen this problem with
- 3Com boards (i.e. if you have a 3Com board, you might experiance the
- above problem - I haven't specifically tested for it).
-3) The NIC memory access to 3Com and Novell boards is much slower than it is on
- SMC boards; it's less than 1MB on 8bit boards and less than 2MB/second
- on the 16bit boards. This can lead to ring-buffer overruns resulting in
- additional lost data during heavy network traffic.
-
-$Id: ed.relnotes,v 1.4 1993/11/22 11:15:16 davidg Exp $
diff --git a/sys/i386/doc/options.texi b/sys/i386/doc/options.texi
deleted file mode 100644
index 4313cf009459..000000000000
--- a/sys/i386/doc/options.texi
+++ /dev/null
@@ -1,974 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-@c %**start of header
-@setfilename options.info
-@settitle Configuration Options for FreeBSD
-@c @setchapternewpage odd
-@c function index is option/pseudo/device names; concept is everything
-@c else
-@syncodeindex fn cp
-@finalout
-@c %**end of header
-
-@ifinfo
-$Id: options.texi,v 1.4.2.1 1994/03/07 01:51:59 rgrimes Exp $
-
-This file documents the configuration options available in the FreeBSD
-operating system.
-
-@display
-Copyright @copyright{} 1993, 1994, Garrett A. Wollman. All rights reserved.
-
-Redistribution and use in source and printed 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 and this list of conditions.
-2. Redistributions in printed form must reproduce the above copyright
- notice, this list of conditions and the following notice of
- authorship.
-
-Trademarks are property of their respective owners.
-@end display
-@end ifinfo
-
-@titlepage
-@title Configuration Options in FreeBSD
-@subtitle for FreeBSD 1.1
-@author Garrett A. Wollman
-@author FreeBSD Project
-
-@page
-@vskip 0pt plus 1filll
-
-i386, i387, and i486 are trademarks of Intel Corporation. SunOS is a
-registered trademark and NFS is a trademark of Sun Microsystems, Inc.
-Ultrix is a registered trademark of Digital Equipment Corporation.
-Xerox is a registered trademark and XNS is a trademark of Xerox
-Corporation. VESA is a trademark of the Video Electronics Standards
-Association. System V is a registered trademark of Novell Corporation.
-All other trademarks are property of their respective owners. FreeBSD
-is nobody's trademark, and damn proud of it.
-
-Copyright @copyright{} 1993, 1994, Garrett A. Wollman. All rights reserved.
-
-Redistribution and use in source and printed forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-@enumerate
-@item
-Redistributions of source code must retain the above copyright
-notice and this list of conditions.
-
-@item
-Redistributions in printed form must reproduce the above copyright
-notice, this list of conditions and the preceding notice of
-authorship.
-@end enumerate
-@end titlepage
-
-@node Top, Subsystems, (dir), (dir)
-@top FreeBSD Configuration Options
-
-This document describes kernel configuration options relevant to the
-FreeBSD operating system version 1.1. It is intended for readers who
-already have a general understanding of the process of configuring a BSD
-kernel and wish to get a general overview of the meaning of various
-configuration options. This document covers configurable options and
-pseudo-devices; it is intended that devices may be added at a later
-date.
-
-@menu
-* Subsystems:: Controlling subsystems.
-* Performance:: Performance enhancement.
-* Devices:: Device-control options.
-* Internals:: Non-user-serviceable parts.
-
-* Index:: General Index.
-@end menu
-
-@node Subsystems, Performance, Top, Top
-@c node,next,prev,up
-
-@chapter Options for Subsystems
-
-This chapter discusses options controlling the inclusion of various
-subsystems in FreeBSD. These include things like filesystems,
-networking modules, and whatnot. Remember that options containing
-underscores must be quoted.
-
-@table @code
-@item pseudo-device bpfilter @var{number}
-@findex bpfilter
-@cindex Berkeley packet filter
-@cindex Network interfaces
-The @samp{bpfilter} pseudo-device is the Berkeley Packet Filter,
-developed by Lawrence Berkeley Labs and based on an earlier packet
-filter from Stanford. See the @samp{bpf} manual page for more details.
-The @var{number} given is the maximum number of simultaneous users
-permitted. (NB: in previous version of BPF, the @var{number} had to be
-greater than the number of interfaces; this space is now dynamically
-allocated so this requirement is no longer present.)
-
-@item options CCITT
-@findex CCITT
-@cindex X.25
-@cindex Networking domains
-The @samp{CCITT} option enables support for the ITU-T X.25(1980)
-network-layer protocol. Nobody we know has a direct X.25 connection to
-anything, so this code has never been tested.
-
-@item options "COMPAT_42"
-@findex COMPAT_42
-@cindex UDP Checksums
-@cindex Checksums, UDP
-@cindex 4.2 Compatibility
-@cindex Compatibility options
-This option is used to disable UDP checksumming. Under ordinary
-circumstances it should never ever ever be defined; however, if you are
-stuck trying to communicate with an old 4.2BSD machine, or one running
-something derived from 4.2 like SunOS 3.5 or Ultrix 2.0, this may be
-necessary in order to successfully receive UDP packets.
-
-@item options "COMPAT_43"
-@findex COMPAT_43
-@cindex 4.3 Compatibility
-@cindex Compatibility options
-This option controls a whole host of features, mostly relating to
-system-call compatibilty with 4.3BSD. At the present time, it should
-not be turned off, as many utilities and library routines still depend
-on these obsolescent system calls being present. At some future date,
-this will probably be split up into two separate options, one for binary
-compatibility and one for the old but useful system calls.
-
-@item options "DIRECTED_BROADCAST"
-@findex DIRECTED_BROADCAST
-@cindex IP
-@cindex UDP
-If this option is enabled, the kernel will support sending IP broadcast
-packets to subnets other than the one that the machine is on, and when
-forwarding will accept such packets. That is to say, if your host lives
-on subnets @samp{132.198.3} and @samp{132.198.4}, and the
-@samp{132.198.3} side receives a packet addressed to
-@samp{132.198.4.255}, it will forward the packet as a broadcast on that
-subnet.
-
-@item pseudo-device ether
-@findex ether
-@cindex Ethernet
-@cindex Network interfaces
-This pseudo-device provides link-layer support for Ethernet device
-drivers. It is mandatory for all systems which include Ethernet or
-Ethernet-like devices, such as @samp{ed}, @samp{ie}, and @samp{is}.
-This code is due for a redesign.
-
-@item options EON
-@itemx pseudo-device eon
-@findex EON
-@cindex ISO 8473 CLNP
-@cindex Network interfaces
-The @samp{eon} network interface supports the ISO 8473
-Connectionless-Mode Network Protocol, tunnelled through IP version 4.
-@samp{eon} interfaces are created automatically once initially
-configured by adding ISO routes with IP destinations. At present, both
-the pseudo-device and option declaration are necessary.
-
-@item options FIFO
-@findex FIFO
-@cindex Named pipes
-This option enables support for System V-- and POSIX-style named pipes
-or fifos.
-
-@item options GATEWAY
-@itemx options IPFORWARDING=@var{value}
-@itemx options IPSENDREDIRECTS=@var{value}
-@findex GATEWAY
-@findex IPFORWARDING
-@findex IPSENDREDIRECTS
-@cindex ICMP
-@cindex IP
-@cindex Network parameters
-These three options control whether FreeBSD's IP forwarding functions
-are enabled. Technically speaking, because FreeBSD does not meet the
-standards set out in the ``Router Requirements'' document (RFC 1009),
-these should not be enabled, but sometimes it is necessary to enable
-this function. The @samp{GATEWAY} option turns on @samp{IPFORWARDING},
-and also controls the sizing of certain system tables. The
-@samp{IPFORWARDING} option controls the initial value of the
-@samp{ipforwarding} kernel variable (default 1 if @samp{GATEWAY}
-defined, 0 otherwise), which controls whether packets are acutally
-forwarded or not; @var{value} should be either @samp{0} or @samp{1}.
-@samp{IPSENDREDIRECTS} controls the initial value of the
-@samp{ipsendredirects} variable (default is one, but should be changed
-to zero); its @var{value} should also be either @samp{0} or @samp{1}.
-
-@item options INET
-@findex INET
-@cindex IP
-@cindex TCP
-@cindex UDP
-@cindex ICMP
-@cindex Networking domains
-This option controls the inclusion of the Internet protocol suite,
-including IP version 4, TCP, UDP, and ICMP. Support for IP multicast,
-IP next generation, and IGMP will be provided at a future date. It is
-not recommended to even attempt to generate a system with this option
-turned off, as many parts of the system depend on Internet networking in
-important and subtle ways.
-
-@item options ISO
-@itemx options TPIP
-@findex ISO
-@findex TPIP
-@cindex ISO 8473 CLNP
-@cindex ISO TP4
-@cindex ISO TP0
-@cindex ISO 9542 ESIS
-@cindex IEEE 802.2 LLC
-@cindex Networking domains
-These options control the inclusion of ISO OSI networking protocols.
-The TPIP option includes just enough support to run ISO Transport
-Protocol class 4 over IP, supporing the @samp{SOCK_SEQPACKET}
-abstraction. The ISO option includes support for CLNP, TP class 0,
-ISO 9542 ESIS, and IEEE 802.2 logical link control class 0 (for CLNP only).
-
-@item options ISOFS
-@findex ISOFS
-@cindex ISO 9660 filesystem
-@cindex CD-ROM
-@cindex Rock Ridge filesystem
-@cindex Filesystems
-The @samp{ISOFS} option enables kernel support for the ISO 9660 CD-ROM
-filesystem, including RockRidge extensions.
-
-@item options "ISO_X25ESIS"
-@findex ISO_X25ESIS
-@cindex ISO 9542 ESIS
-@cindex X.25
-This option controls whether ISO 9542 ESIS is run over ITU-T X.25 link
-layers. This requires the @samp{CCITT} option to be enabled as well.
-
-@item options KTRACE
-@findex KTRACE
-@cindex Kernel tracing
-This option enables the tracing of several classes of internal kernel
-events. See the @samp{ktrace} command for more details.
-
-@item pseudo-device log
-@findex log
-@cindex Kernel message logging
-The @samp{log} pseudo-device provides kernel support to send kernel
-messages to @samp{syslog}. It is mandatory.
-
-@item pseudo-device loop
-@findex loop
-@cindex Network interfaces
-The @samp{loop} pseudo-device provides the trivial network interface.
-It is required when any networking options are enabled.
-
-@item options MACHVMCOMPAT
-@findex MACHVMCOMPAT
-@cindex Mach virtual memory
-This option enables a Mach-compatible interface to the virtual memory
-subsystem, supporting system calls @samp{vm_allocate},
-@samp{vm_deallocate}, @samp{vm_inherit}, and @samp{vm_protect}.
-(Given the nature of the VM system, it is impossible to support a
-Mach-style @samp{vm_region} call, and in every case the `map' argument
-is ignored and replaced with the calling process's own map.)
-
-@item options MFS
-@findex MFS
-@cindex Memory filesystem
-@cindex Filesystems
-This option enables support for the memory filesystem, an in-core
-filesystem which lives in the swap area. Using MFS as a @file{/tmp}
-filesystem can dramatically increase the speed of
-temporary-space-intensive operations such as compilations. See the
-@samp{mount_mfs} manual page for more details.
-
-@item options NFS
-@findex NFS
-@cindex Network File System
-@cindex Filesystems
-The @samp{NFS} option enables support for Sun's Network File System.
-(Also called ``Nightmare'' or ``Not a''@dots{}.) This presently includes
-both client-- and server-side kernelized NFS support; it may in the
-future be broken into separate options. This NFS implmentation comes to
-BSD courtesy of Rick Macklem of the University of Guelph, and is not
-derived from Sun licensed source code. As a result, there are sometimes
-interoperability problems where the published specification is vague,
-and this option supports several new and useful features compared to
-Sun's. See the @samp{mount} manual page for more details.
-
-@item options NS
-@itemx options NSIP
-@findex NS
-@findex NSIP
-@cindex Xerox Network System
-@cindex XNS IDP
-@cindex XNS SPP
-@cindex Network interfaces
-@samp{NS} controls the inclusion of support for the Xerox Network
-Service protocol family. At the present time, it is not known whether
-this code even works; testers are welcome. The @samp{NSIP} option
-enables encapsulation of XNS IDP over IP.
-
-@item options PANICDELAY
-@itemx options PANICWAIT
-@findex PANICDELAY
-@findex PANICWAIT
-@cindex Kernel panics
-These options control whether the system waits after a panic. This is
-necessary on some systems which do not support crash dumps, so that the
-actual panic message can be read. The @samp{PANICDELAY} option inserts
-a delay of twenty seconds before self-destructing; the @samp{PANICWAIT}
-option instead waits for a key to be pressed on the console.
-
-@item options PCFS
-@findex PCFS
-@cindex MS-DOS filesystem
-@cindex Filesystems
-This option controls support for mounting MS-DOS disks and disk
-partitions under FreeBSD. The @samp{pcfs} manual page is presently very
-bogus.
-
-@item pseudo-device ppp @var{number}
-@findex ppp
-@cindex Point-To-Point Protocol
-@cindex Network interfaces
-The @samp{ppp} pseudo-device provides support for the Internet
-Point-to-Point protocol (RFC 1351 @i{et seq}), implemented as a line
-discipline over standard serial links. @var{number} should be the
-number of simultaneous PPP interfaces which will be configured.
-
-@item pseudo-device pty @var{number}
-@findex pty
-@cindex Pseudo-terminals
-This pseudo-device provides support for pseudo-ttys, which are required
-for @samp{rlogin}, @samp{telnet}, and @samp{xterm} to operate correctly;
-@var{number} should be set to the total number of these programs you
-expect to have running at any given time. Because pty's are not as yet
-dynamically allocated, and the underlying structures are large, it is
-best to keep this value as small as feasible, until this deficiency is
-remedied.
-
-@item options QUOTA
-@findex QUOTA
-@cindex Disk quotas
-@cindex Filesystems
-The @samp{QUOTA} option enables support for disk quotas. Note that NFS
-quota support is not available.
-
-@item pseudo-device sl @var{number}
-@findex sl
-@cindex Serial Line Internet Protocol
-@cindex SLIP
-@cindex CSLIP
-@cindex IP
-@cindex Network interfaces
-This pseudo-device provides support for the Serial Line Internet
-Protocol (RFC 1055), implemented as a line discipline over standard
-serial links. It includes support for Van Jacobson header compression.
-@var{number} should be the number of simultaneous SLIP interfaces which
-will be configured. See also the @samp{slattach} manual page.
-
-@item options SYSVSHM
-@item options SYSVSEM
-@item options SYSVMSG
-@itemx options SHMMAXPGS=@var{value}
-@findex SYSVSHM
-@findex SYSVSEM
-@findex SYSVMSG
-@findex SHMMAXPGS
-@cindex System V shared memory
-@cindex System V semaphores
-@cindex System V message queues
-@cindex System V IPC
-@cindex Shared memory, System V
-@cindex Semaphores, System V
-@cindex Message queues, System V
-@cindex IPC, System V
-The @samp{SYSVSHM} option enables kernel-side emulation of System
-V-compatible shared memory. The @samp{SHMMAXPGS} option (default 64
-pages or 256K) determines the maximum amount of shared memory available
-under this mechanism. The @samp{SYSVSEM} option provides emulation of
-System V-compatible semaphores, and likewise @samp{SYSVMSG} for message
-queues.
-
-@item options RMP
-@findex RMP
-@cindex Remote maintenance protocol
-@cindex Networking domains
-This option should control the inclusion of support for HP's remote
-maintenance protocol, but the source code is not included in FreeBSD at
-present, so enabling it will not result in any good.
-
-@item pseudo-device tb
-@findex tb
-@cindex Tablet line discipline
-The @samp{tb} pseudo-device provides support for the `tablet' line
-discipline. Nobody on the FreeBSD team actually has one of the tablets
-in question, so we have no idea if this actually works or not. It may
-not even compile.
-
-@item options "TCP_COMPAT_42"
-@findex TCP_COMPAT_42
-@cindex 4.2 Compatibility
-@cindex Compatibility options
-@cindex TCP
-This option controls the perpetuation of several bugs inherited from the
-4.2BSD implementation of TCP. It should only be defined in the
-circumstances outlined for @samp{COMPAT_42}, above.
-
-@item pseudo-device tun
-@findex tun
-@cindex Network interfaces
-The @samp{tun} driver provides a network interface which is attached to
-a character device. In this way, a user-mode program can grab packets
-out of the networking system, fiddle with them or move them around, and
-pass stuff packets back up into the kernel. It is not known if this
-device either compiles or operates correctly, although it was believed
-to do both at some time in the past.
-
-@item options UCONSOLE
-@findex UCONSOLE
-@cindex Console redirection
-This option allows any old user to grab kernel output away from the
-console and send it to the tty of their choice. It presents an
-incredile security hole for some systems, but is necessary in order to
-allow programs like @samp{xconsole} to operate. (The alternative,
-making @samp{xconsole} set-uid root, opens the exact same security
-hole.)
-
-@item options XE
-@findex XE
-@cindex X.25
-@cindex IEEE 802.2 LLC
-@cindex Network interfaces
-@cindex Ethernet
-This option should control the inclusion of support for running X.25
-over IEEE 802.2 LLC class 2, but that code was not included in the
-Networking/2 release, so enabling it will disable kernel compilation.
-Requires @samp{CCITT}.
-
-@item options XSERVER
-@findex XSERVER
-@cindex X Window System
-This obsolescent option enables support in the @samp{pc} console
-driver for certain operations required by the XFree86 server.
-@end table
-
-@node Performance, Devices, Subsystems, Top
-@c node,next,prev,up
-
-@chapter Performace and Debugging Options
-
-The following options are provided for system performace optimization.
-Note that kernel profiling is supported via the @samp{-p} option to the
-@samp{config} command; for more information see the @samp{config} manual
-page.
-
-@table @code
-@item psuedo-device ddb
-@findex ddb
-@cindex Kernel debugger
-@cindex Debugger, kernel
-This option enables the @samp{ddb} debugger, taken from Mach. See the
-@samp{ddb} and @samp{dbsym} manual pages for more information on the use
-of this debugger.
-
-@item options DIAGNOSTIC
-@itemx options NAMEI_DIAGNOSTIC
-@itemx options PARANOID
-@findex DIAGNOSTIC
-@findex NAMEI_DIAGNOSTIC
-@findex PARANOID
-@cindex Debugging options
-These debugging options reduce performace. They are intended to enable
-certain internal consistency checks which are not supposed to fail
-during correct operation, and so are normally disabled for performace
-reasons.
-
-@item options FASTLINKS
-@findex FASTLINKS
-@cindex Symbolic links
-@cindex Filesystems
-The @samp{FASTLINKS} option enables the creation of symbolic links whose
-target names reside entirely within the i-node of the link, when
-possible. This results in faster access for those links which are short
-enough (in practice, most of them). All kernels can read such links,
-but only @samp{FASTLINKS} kernels will create them, for compatibility
-with older kernels lacking such support.
-
-@item options ICMPPRINTFS
-@findex ICMPPRINTFS
-@cindex Debugging options
-@cindex ICMP
-This option is defined to allow debugging of ICMP (@dfn{Internet Control
-Message Protocol}) packets in the kernel. When defined and the
-@samp{icmpprintfs} kernel variable (default false) is set to true, ICMP
-packets will be printed out to the console when received. Note that it
-is probably better to use @samp{tcpdump} for this kind of debugging.
-
-@item options KGDB
-@findex KGDB
-@cindex Kernel debugger
-@cindex Debugger, kernel
-@cindex Remote debugging
-The @samp{KGDB} option enables certain bits of kernel code which will
-eventually be able to talk to a remote copy of the @samp{gdb} debugger
-over a serial connection. The present code does not work, but users are
-invited to hack on it and contribute the changes back to the FreeBSD
-team.
-
-@item options MCLSHIFT=@var{value}
-@findex MCLSHIFT
-@cindex Network parameters
-This option controls the number of bytes in an mbuf cluster, which is
-one of the basic units through which network data is managed. It is
-equal to the log base two of @samp{MCLBYTES}, the size of an mbuf
-cluster, and defaults to eleven (for an @samp{MCLBYTES} of 2048). It
-will likely eventually be bumped up to twelve (4096), so that the
-network code can take advantage of page flipping to reduce the numer of
-copies necessary.
-
-@item options SUBNETSARELOCAL
-@findex SUBNETSARELOCAL
-@cindex TCP
-@cindex Network parameters
-This option controls whether the TCP system believes that machines on
-other subnets of your network are considered to be ``local'' to your
-host. For most systems, this option should be on (the default); if you
-are directly connected to a class A network, however, then it may need
-to be turned off. (This is true of networks like the MILNET.)
-
-@item options "SYMTAB_SPACE=@var{value}"
-@findex SYMTAB_SPACE
-@cindex Debugger, kernel
-@cindex Kernel debugger
-This obsolescent option controls the amount of space that will be
-statically allocated in the debugger source code to hold the kernel
-symbol table that @samp{dbsym} sticks there. Eventually this will be
-dynamically allocated at load time. The default @var{value} is 63000
-bytes.
-@end table
-
-@node Devices, Internals, Performance, Top
-
-@chapter Device Options
-
-There are different device selections available depending on the type of
-bus present in your computer. We will cover generic FreeBSD devices,
-ISA-bus devices, and EISA-bus devices. A separate section describes the
-devices available in the SCSI subsystem.
-
-@menu
-* Generic:: Devices available in all FreeBSD systems.
-* ISA:: Devices specific to the ISA bus.
-* EISA:: Devices specific to the EISA bus.
-* MCA:: No support for Micro Channel, yet.
-* PCI:: No support for PCI, yet.
-* SCSI:: The SCSI subsystem.
-@end menu
-
-@node Generic, ISA,, Devices
-@section Generic Devices and Options
-
-The following devices and options are available in all FreeBSD
-configurations. In addition to these devices, a selection of ISA
-devices (@pxref{ISA}) is required in order to generate a workable
-system.
-
-@table @code
-@item machine "i386"
-@findex i386
-This mandatory declaration informs the @samp{config} program that you
-are using an i386 or compatible CPU, and enables the selection of all
-the other devices listed here.
-
-@item cpu "I386_CPU"
-@itemx cpu "I486_CPU"
-@findex I386_CPU
-@findex I486_CPU
-These two options control which specific CPUs will be supported by the
-generated kernel. If the kernel detects that it is not running on a CPU
-for which support was enabled, it will panic quickly upon startup. If
-you do not expect to need to run your kernel on an i386 or similar CPU,
-leaving out that support can increase virtual memory system performance.
-
-@item options "MATH_EMULATE"
-@findex MATH_EMULATE
-@cindex Floating-point emulator
-@cindex i387
-When this option is defined, the math coprocessor emulator is compiled
-into the kernel. When it is not defined and the coprocessor is absent,
-programs which use floating-point operations are automatically killed.
-
-@item device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
-@findex npx
-@cindex i386
-The @samp{npx} device provides support for the i387 numeric coprocessor
-and the floating-point portions of the i486 CPU. This will eventually
-be fixed to not require ISA to be configured.
-
-@item pseudo-device speaker
-@findex speaker
-The @samp{speaker} pseudo-device provides support for rudimentary access
-to the PC's speaker via @file{/dev/spkr}. It provides a
-character-device interface which interprets @samp{PLAY} strings similar
-to IBM PC Advanced BASIC, as well as an @samp{ioctl} interface with more
-fine-grained control. See the @samp{spkr} manual page for more
-information.
-@end table
-
-@node ISA, EISA, Generic, Devices
-@section ISA-bus Devices and Options
-
-The following options are specific to ISA-bus devices and systems.
-Since the EISA bus is backwards-compatible with the ISA bus, all these
-options also apply to EISA systems. The same goes for VESA Local Bus
-(VL-Bus) systems.
-
-@table @code
-@item controller isa0
-@findex isa
-This @strong{mandatory} declaration must precede any other devices
-listed in this section. It provides the basic support for the ISA-bus
-glue logic, including DMA and autoconfiguration.
-
-@item controller aha0 at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
-@findex aha
-@cindex Adaptec 154x
-@cindex SCSI host adaptors
-The @samp{aha} device supports the Adaptec 154x series of SCSI
-controllers, and attempts to support other vendors' controllers which
-claim compatibility with the Adaptec 1542, such as the BusLogic 545.
-This device is included in the @samp{GENERICAH} distribution kernel.
-The @samp{scbus} device (@pxref{SCSI}) is a prerequisite for this
-device.
-
-@item controller bt0 at isa? port "IO_BT0" bio irq 12 vector btintr
-@findex bt
-@cindex Bustek 742
-@cindex SCSI host adaptors
-This device supports the Bustek 742 SCSI controller. It is included in
-the @samp{GENERICBT} distribution kernel; the @samp{scbus} device
-(@pxref{SCSI}) is a prerequisite.
-
-@item options COM_BIDIR
-@findex COM_BIDIR
-@cindex Bi-directional serial ports
-@cindex Serial ports
-This option enables bi-directional support in the @samp{sio} serial
-driver. This option is slated for removal, at which time bi-directional
-support will always be enabled. See the @samp{comcontrol} manual page
-for more information.
-
-@item options COM_MULTIPORT
-@findex COM_MULTIPORT
-@cindex Multi-port serial boards
-@cindex Serial ports
-This option enables support in the @samp{sio} serial driver for certain
-multi-port serial boards.
-
-@item device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr
-@itemx device ed1 at isa? port 0x300 net irq 5 iomem 0xd8000 vector edintr
-@findex ed
-@cindex Western Digital 80x3
-@cindex 3Com 3C503
-@cindex Novel NE1000/NE2000
-@cindex Network interfaces
-@cindex Ethernet
-The @samp{ed} network interface driver provides support for the Western
-Digital/SMC 80x3 series, the 3Com 3c503, and Novell NE1000 and NE2000
-series of Ethernet controllers. It automatically detects differences
-among the various versions of these controllers and adapts
-appropriately. The @samp{ed1} line shown is for the Novell boards; the
-@samp{ed0} line is appropriate for all other supported controllers.
-(The Novell controllers cannot be configured to use port 0x280.)
-
-@item controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
-@itemx disk fd0 at fdc0 drive 0
-@itemx disk fd1 at fdc0 drive 1
-@itemx tape ft0 at fdc0 drive 2
-@findex fd
-@findex ft
-@cindex Floppy disk
-@cindex Floppy tape
-@cindex QIC-80
-@cindex Tape drives
-@cindex Cartridge tape drives
-@cindex Quarter-Inch-Cartridge (QIC) tape drives
-@cindex Disk drives
-The @samp{fdc} driver provides support for the standard PC floppy-disk
-controller. The @samp{fd} sub-driver supports 3.5-- and 5.25-inch
-floppy disks in the standard 360KB, 720KB, 1200KB, 1440KB, and 2880KB
-formats, as well as a number of other formats not supported by DOS. The
-@samp{ft} driver is available for QIC-80 ``floppy tape'' support.
-The drivers support formatting of both tapes and disks. This driver is
-substantially improved from that shipped in previous releases of
-FreeBSD.
-
-@item device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
-@findex ie
-@cindex AT&T EN100
-@cindex AT&T StarLAN 10
-@cindex Network interfaces
-@cindex Ethernet
-@cindex StarLAN
-This network interface driver provides support for the AT&T StarLAN 10
-and EN100 family of controllers. Note that the configuration specified
-here is not the default configuration, but one which attempts to deal
-with the conflicts that arise in more modern systems. (It is expected
-that this driver will be expanded in the future to support other similar
-cards in the manner of @samp{ed}.)
-
-@item device is0 at isa? port 0x280 net irq 10 drq 7 vector isintr
-@findex is
-@cindex Isolan 4141-0
-@cindex Isolink 4110
-@cindex Ethernet
-@cindex Network interfaces
-The @samp{is} network interface driver supports the Isolan 4141-0 and
-Isolink 4110 Ethernet controllers.
-
-@c @item device ix0 at isa? port 0x320 net irq 10 iomem 0xd0000 iosiz 32768 \
-@c @itemx vector ixintr
-@c @findex ix
-@c @cindex Intel EtherEXPRESS
-@c @cindex Ethernet
-@c @cindex Network interfaces
-@c This device is known to exist, but is not presently in the FreeBSD
-@c source tree. When it is made available, this information will be
-@c updated.
-
-@item device lpa0 at isa? port "IO_LPT1" tty
-@itemx device lpt0 at isa? port "IO_LPT1" tty irq 7 vector lptintr
-@findex lpa
-@findex lpt
-@cindex Parallel printers
-The @samp{lpa} device provides support for the parallel printer driver
-accessed as @file{/dev/lp}. The @samp{lpt} driver provides the same
-functionality, but only works with those printer controllers which
-support interrupt-driven operations. If you receive @samp{ISA strayintr
-7} messages correlated with the use of the @samp{lpa} driver, chances
-are that your controller supports interrupt-driven operation, and you
-should switch to the @samp{lpt} driver.
-
-The @samp{lpa} driver is obsolete, and will be removed in release 1.2,
-to be replaced by special flags to the @samp{lpt} driver.
-
-@item device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
-@findex mcd
-@cindex Mitsumi CD-ROM
-@cindex CD-ROM
-This device provides support for the Mitsumi non-SCSI CD-ROM drive.
-Performance is known to be quite slow.
-
-@c mse, anyone?
-
-@item device pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
-@itemx device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
-@itemx options NCONS=@var{value}
-@itemx options COMCONSOLE
-@findex pc
-@findex sc
-@findex NCONS
-@findex COMCONSOLE
-@cindex Console devices
-@cindex pccons
-@cindex Syscons
-@cindex Virtual consoles
-@cindex X Window System
-The @samp{pc} and @samp{sc} devices provide support for the system
-display and keyboard, which is the default console. There might
-actually be documentation somewhere for both of these. The @samp{sc}
-device requires the @samp{NCONS} option to be defined to some value; it
-represents the number of virtual consoles to be provided by the driver;
-a reasonable value is 8. One of @samp{pc} or @samp{sc} is presently
-required unless @samp{COMSONSOLE} is enabled, in which case a serial
-port is made into the console.
-
-@c sb, anyone?
-
-@item device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
-@itemx device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
-@itemx device sio2 at isa? port "IO_COM3" tty irq 5 vector siointr
-@itemx device sio3 at isa? port "IO_COM4" tty irq 9 vector siointr
-@findex sio
-@cindex Serial ports
-@cindex National 8250/16450/16550
-@cindex Bi-directional serial ports
-@cindex Multi-port serial boards
-The @samp{sio} driver provides support for high-speed serial
-communications using the standard 8250, 16450, and 16550 UART chips. It
-provides a standard tty interface for these devices as
-@file{/dev/tty@var{unit}}, and, when enabled with the @samp{comcontrol}
-program, a call-out capability as @file{/dev/cua@var{unit}} (@var{unit}
-is two digits, zero-padded in both cases). Certain multi-port systems
-are also supported.
-
-@item device uha0 at isa? port "IO_UHA0" bio irq 14 drq 5 vector uhaintr
-@findex uha
-@cindex Ultrastor 14F
-@cindex Ultrastor 34F
-@cindex SCSI host adaptors
-This device supports the Ultrastor 14F and related SCSI controllers. It
-is included in the @samp{GENERICBT} distribution kernel, and requires
-@samp{scbus} (@pxref{SCSI}) as a prerequisite. The Ultrastor 24F is not
-supported.
-
-@item controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
-@itemx disk wd0 at wdc0 drive 0
-@itemx disk wd1 at wdc0 drive 1
-@findex wd
-@cindex Western Digital WD100x
-@cindex ST-506 hard disks
-@cindex RLL hard disks
-@cindex ESDI hard disks
-@cindex IDE hard disks
-@cindex Disk drives
-The @samp{wd} device supports standard ST-506, RLL, ESDI, and IDE hard
-disks, as controlled by the Western Digital WD100x series of controllers
-(and compatible hardware). This version is substantially improved from
-that provided in FreeBSD 1.0.
-
-@item device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
-@findex wt
-@cindex Archive QIC-02
-@cindex Wangtek QIC-02
-@cindex Cartridge tape drives
-@cindex QIC-02
-@cindex QIC-36
-@cindex Tape drives
-@cindex Quarter-Inch-Cartridge (QIC) tape drives
-This driver supports Archive QIC-02 and Wangtek QIC-02 and QIC-36
-cartridge tape controllers.
-@end table
-
-@node EISA, MCA, ISA, Devices
-@section EISA-bus Devices and Options
-
-There is presently only one EISA-specific device driver.
-
-@table @code
-@item controller ahb0 at isa? bio irq 11 vector ahbintr
-@findex ahb
-@cindex Adaptec 174x
-@cindex SCSI host adaptors
-The @samp{ahb} driver provides support for the Adaptec AHA-174x series
-of SCSI controllers. This controller is included in the
-@samp{GENERICAH} distribution kernel, and requires the @samp{scbus}
-driver (@pxref{SCSI}) as a prerequisite.
-@end table
-
-@node MCA, PCI, EISA, Devices
-@section Micro Channel Devices and Options
-
-@cindex Micro Channel Architecture
-We don't support Micro Channel right now. Anyone interested in working
-on Micro Channel support should send mail to
-@samp{FreeBSD-Questions@@freefall.cdrom.com} for information on how to
-help.
-
-@node PCI, SCSI, MCA, Devices
-@section PCI Devices and Options
-
-@cindex PCI
-We don't support PCI, either. Anyone interested in working on PCI
-support should send mail to @samp{FreeBSD-Questions@@freefall.cdrom.com}
-for information on how to help.
-
-@node SCSI,, PCI, Devices
-@section The SCSI Subsystem
-
-The SCSI subsystem consists of a set of adaptor-specific driver
-routines, which were described in the previous sections, and the generic
-SCSI device drivers, which handle the standardized interactions with
-devices on the SCSI bus.
-
-@c devices: cd, ch, scbus, sd, sg, st
-
-@table @code
-@item device cd0
-@findex cd
-@cindex CD-ROM
-@cindex SCSI devices
-The @samp{cd} device provides support for CD-ROM drives. Only one
-@samp{cd} device need be configured, as the driver automatically
-allocates units for each CD-ROM drive found. Playing of audio CDs is
-also supported, on drives which support it, through @code{ioctl} calls.
-Support for retrieval of CD audio over the SCSI bus is not presently
-available.
-
-@item device ch0
-@findex ch
-@cindex Media changers
-@cindex SCSI devices
-The @samp{ch} driver supports SCSI media changers; this may include
-tape, removable disk, and CD changers. One @samp{ch} device should be
-configured for each changer you expect to support.
-
-@item device scbus0
-@findex scbus
-@cindex SCSI bus management
-This driver forms the core of the SCSI subsystem. It provides the
-device-independent routines that manage SCSI transactions, keep track of
-attached devices, and act as glue between SCSI-device-specific drivers
-and system-specific host adaptors. This device is @emph{mandatory} for
-all SCSI systems.
-
-@item device sd0
-@findex sd
-@cindex SCSI devices
-@cindex Disk drives
-The @samp{sd} driver provides access to non-removable SCSI disks. One
-@samp{sd} device should be defined for each disk you expect to have
-simultaneously connected to the system.
-
-@c @item device sg0
-@c @findex sg
-@c @cindex SCSI devices
-@c @cindex Generic SCSI
-@c @cindex Unsupported SCSI devices
-@c This driver provides support for development of user-mode drivers and
-@c other programs which access the SCSI bus directly. One @samp{sg} device
-@c should be defined for each @emph{host adaptor} you have installed in
-@c your system.
-
-@item device st0
-@findex st
-@cindex SCSI devices
-@cindex Tape drives
-@cindex Quarter-Inch-Cartridge (QIC) tape drives
-The @samp{st} driver supports generic SCSI tape drives. One @samp{st}
-device should be defined for each tape drive you wish to access. See
-the @samp{st} manual page for information about how to manipulate the
-parameters of this device.
-
-@item device uk0
-@findex uk
-@cindex SCSI devices
-@cindex Unknown SCSI devices
-The @samp{uk} driver provides an attachment point for all otherwise
-unrecognized SCSI devices. You can't actually do anything with such a
-device, except perhaps send it an inquiry command using the @samp{scsi}
-program (q.v.).
-@end table
-
-@node Internals, Index, Devices, Top
-
-@chapter Internal Use Only
-
-Eventually, this chapter will document some of the kernel manifest
-constants which are not defines, but which can be tweaked in various
-header files.
-
-@node Index,, Internals, Top
-@appendix General Index
-
-Items in @code{typewriter} font are option or device names.
-
-@printindex cp
-
-@bye
diff --git a/sys/i386/doc/sound.doc b/sys/i386/doc/sound.doc
deleted file mode 100644
index 7f5b9da64e6d..000000000000
--- a/sys/i386/doc/sound.doc
+++ /dev/null
@@ -1,38 +0,0 @@
-To enable sound card support, you need to add one or more of the following
-lines to your kernel configuration file:
-
-device snd5 at isa? port 0x330 irq 6 drq 0 vector mpuintr
-device snd4 at isa? port 0x220 irq 15 drq 6 vector gusintr
-device snd3 at isa? port 0x388 irq 12 drq 3 vector pasintr
-device snd2 at isa? port 0x220 irq 7 drq 1 vector sbintr
-device snd1 at isa? port 0x388 irq 0 drq 0 vector sbintr
-
- Unit numbers are:
- 1 for Yamaha FM synth
- 2 for SB/SB Pro DSP
- 3 for PAS PCM and Midi
- 4 for GUS
- 5 for MPU-401
-
- If you have ProAudioSpectrum, uncomment units 3 and 2.
- If you have SoundBlaster, uncomment 2 and 1.
- If you have GravisUltrasound, uncomment 4
- If you have MPU-401, uncomment 5
-
-NOTE: The MPU-401 driver may or may not work, and is unfortunately
-unverifiable since no one I know has one. If you can test this,
-please let me know! Also note that you will have to change these
-settings if your soundcard is set for a non-standard address or IRQ.
-Please check your documentation (or verify with any provided DOS utilities
-that may have come with your card) and set the IRQ or address fields
-accordingly.
-
-
-Also: Some systems with the OPTI chipset will require you to #define
-BROKEN_BUS_CLOCK in /sys/i386/sound/pas2_card.c. Symptoms are that
-you will hear a lot of clicking and popping sounds, like a geiger counter,
-coming out of the PAS even when is not playing anything.
-
-
-
- - Jordan Hubbard (jkh@freefall.cdrom.com)
diff --git a/sys/i386/doc/vm_layout.doc b/sys/i386/doc/vm_layout.doc
deleted file mode 100644
index 3734fd8ab088..000000000000
--- a/sys/i386/doc/vm_layout.doc
+++ /dev/null
@@ -1,32 +0,0 @@
-Physical Memory Layout:
-
-NOT YET DONE
-
-
-
-Virtual Memory Layout:
-
-Page Table Directories, and how they relate to the vm address space
-Note: PTDI stands for Page Table Directory Index.
-
-PTDI Address pmap.h/param.h Calculation to locate it in vm space
---------------------------------------------------------------------------------
- FFFFF000 APTD APTmap + (APTDPTDI * NBPG)
- FFC00000 APTmap APTDPTDI << PDRSHIFT
-3FF FFC00000 APTDPTDI #define (NPTEPG-1)
- FFBFFFFF KERNEND ((KPTDI+NKPDE) << PDRSHIFT) - 1
-3FD FF400000 .
-3FC FF000000 .
-3FB FEC00000 .
-3FA FE800000 .
-3F9 FE400000 .
- FE000000 KERNBASE KPTDI << PDRSHIFT
-3F8 FE000000 KPTDI #define (APTDPTDI-NKPDE)
- FDFF8000 Sysmap PTmap + (KPTDI * NBPG)
- FDFF7FF8 APTpde PTD + (APTDPTDI * sizeof(pde))
- FDFF7FDC PTDpde PTD + (PTDPTDI * sizeof(pde))
- FDFF7000 PTD PTmap + (PTDPTDI * NBPG)
- FDC00000 PTmap PTDPTDI << PDRSHIFT
-3F7 FDC00000 PTDPTDI #define (KPTDI-1)
-
-$Id: vm_layout.doc,v 1.6 1993/10/16 19:25:07 rgrimes Exp $
diff --git a/sys/i386/doc/wt.doc b/sys/i386/doc/wt.doc
deleted file mode 100644
index 1e9f1bafec8a..000000000000
--- a/sys/i386/doc/wt.doc
+++ /dev/null
@@ -1,77 +0,0 @@
-This is the streamer tape driver for 386bsd and FreeBSD, which
-supports Wangtek and Archive compatible QIC-02/QIC-36 controllers.
-It was developed as a replacement of the old Wangtek tape driver from CMU.
-
-In comparison with the CMU driver, this version has the following enhancements:
-1) Support for Archive SC402 and SC499 tape controllers added.
-2) Support for up to three tape controllers on the same machine.
-3) Support for BSD-style ioctls MTIOCGET, MTIOCTOP.
- Mt command now works adequately with this driver.
-2) Asynchronous REWIND and FSF operations, close() will not wait
- until they finish. The next open() will wait for it instead.
-4) Use of WTQICMD ioctl is limited to ERASE and RETENS operations.
- This prevents the user from locking the tape driver by strange
- tape operations.
-5) Tape density switching added.
-6) The status of the process, blocked on the tape operation,
- is displayed at the WCHAN column of the `ps' command as:
-
- wtread reading data from the tape
- wtwrite writing data to the tape
- wtrfm reading the tape marker
- wtwfm writing the tape marker
- wtrew rewinding the tape
- wterase doing WTQICMD ERASE operation
- wtretens doing WTQICMD RETENS operation
- wtorew doing MTIOCTOP REW/OFFL operation
- wtorfm doing MTIOCTOP FSF operation
- wtowfm doing MTIOCTOP WEOF operation
-
-7) It's possible to use the tape with "default density",
- useful for devices which don't support density switching
- or do automatic format determination.
-8) Some controllers support only 1024 block length.
- Setting WT_BSIZE bit in device minor number turns on this mode.
-
-Minor number structure:
- 0bfffuuu
-Fields:
- uuu - Unit number. It's possible to install
- up to three tape controllers on the same machine,
- using DRQs 1..3. Hence, unit number can lie
- in range 0..2.
- fff - Tape format number:
- 0 - /dev/rwt0 - default density (auto select)
- 1 - /dev/rwt0a - QIC 11 (obsolete)
- 2 - /dev/rwt0b - QIC 24 (60 megabytes)
- 3 - /dev/rwt0c - QIC 120 (120 megabytes)
- 4 - /dev/rwt0d - QIC 150 (150 megabytes)
- 5 - /dev/rwt0e - QIC 300 (300 megabytes?)
- 6 - /dev/rwt0f - QIC 600 (600 megabytes?)
- b - Long block size flag. With this bit set,
- the driver will perform all i/o operations
- with the controller using 1024-byte
- blocks, instead of 512 ones.
- Some controllers need it (CMS for example).
- If you Wangtek controller does not stream well,
- you can try to use /dev/rWt0 device instead
- of /dev/rwt0 (uncomment needed lines in /dev/MAKEDEV
- to create it).
-
-Block interface (writing blocks less than 2048 bytes) is not functioning
-pwoperly. Use raw interface instead.
-
-Thanks to all who helped to test it on the following hardware:
-
-Controller Drive Volume Interface Thanks to
----------------------------------------------------------------------------
-Archive SC-499 Archive 2150L 150 Meg QIC-02 KIAE
-CMS? ? 150 Meg QIC-02 KIAE
-Everex EV 831/833 ? ? QIC-36 Joergen Haegg
-Wangtek ASSY Wangtek 60 Meg QIC-02 Ken Whedbee
-Tecmar QT150i? Wangtek 5150EQ ? QIC-02? Marko Teiste
-? Wangtek 5099EK 60 Meg QIC-36 Robert Shien
-Archive SC400S ? 60 Meg ? Warren Toomey
-
-Sergey Ryzhkov, Serge Vakulenko
-E-mail: <sir@kiae.su>, <vak@zebub.msk.su>
diff --git a/sys/i386/i386/autoconf.c b/sys/i386/i386/autoconf.c
index 7584c02b353e..5b571a04432c 100644
--- a/sys/i386/i386/autoconf.c
+++ b/sys/i386/i386/autoconf.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
- * $Id: autoconf.c,v 1.8.2.1 1994/03/23 23:45:08 rgrimes Exp $
+ * $Id: autoconf.c,v 1.11 1994/03/21 15:02:47 ache Exp $
*/
/*
@@ -79,6 +79,11 @@ configure()
isa_configure();
#endif
+#include "pci.h"
+#if NPCI > 0
+ pci_configure();
+#endif
+
#if GENERICxxx && !defined(DISKLESS)
if ((boothowto & RB_ASKNAME) == 0)
setroot();
diff --git a/sys/i386/i386/conf.c b/sys/i386/i386/conf.c
index b1ed3063a3b1..8e0bf2673c3a 100644
--- a/sys/i386/i386/conf.c
+++ b/sys/i386/i386/conf.c
@@ -41,7 +41,7 @@
* SUCH DAMAGE.
*
* from: @(#)conf.c 5.8 (Berkeley) 5/12/91
- * $Id: conf.c,v 1.20.2.1 1994/05/04 07:45:12 rgrimes Exp $
+ * $Id: conf.c,v 1.28 1994/05/30 03:35:53 ache Exp $
*/
#include "param.h"
@@ -213,6 +213,7 @@ struct bdevsw bdevsw[] =
cddump, cdsize, 0 },
{ mcdopen, mcdclose, mcdstrategy, mcdioctl, /*7*/
mcddump, mcdsize, 0 },
+ { 0, } /* block major 8 is reserved for local use */
/*
* If you need a bdev major number, please contact the FreeBSD team
* by sending mail to "FreeBSD-hackers@freefall.cdrom.com".
@@ -236,7 +237,7 @@ d_close_t pcclose;
d_rdwr_t pcread, pcwrite;
d_ioctl_t pcioctl;
d_mmap_t pcmmap;
-extern struct tty pccons;
+extern struct tty *pccons;
/* controlling TTY */
d_open_t cttyopen;
@@ -262,7 +263,7 @@ d_close_t ptcclose;
d_rdwr_t ptcread, ptcwrite;
d_select_t ptcselect;
d_ioctl_t ptyioctl;
-extern struct tty pt_tty[];
+extern struct tty *pt_tty[];
#else
#define ptsopen (d_open_t *)enxio
#define ptsclose (d_close_t *)enxio
@@ -285,9 +286,8 @@ d_close_t comclose;
d_rdwr_t comread;
d_rdwr_t comwrite;
d_ioctl_t comioctl;
-d_select_t comselect;
#define comreset (d_reset_t *)enxio
-extern struct tty com_tty[];
+extern struct tty *com_tty[];
#else
#define comopen (d_open_t *)enxio
#define comclose (d_close_t *)enxio
@@ -295,7 +295,6 @@ extern struct tty com_tty[];
#define comwrite (d_rdwr_t *)enxio
#define comioctl (d_ioctl_t *)enxio
#define comreset (d_reset_t *)enxio
-#define comselect (d_select_t *)enxio
#define com_tty NULL
#endif
@@ -401,33 +400,15 @@ d_ioctl_t bpfioctl;
#define bpfioctl (d_ioctl_t *)enxio
#endif
-#include "dcfclk.h"
-#if NDCFCLK > 0
-d_open_t dcfclkopen;
-d_close_t dcfclkclose;
-d_rdwr_t dcfclkread;
-d_ioctl_t dcfclkioctl;
-d_select_t dcfclkselect;
-#else
-#define dcfclkopen (d_open_t *)enxio
-#define dcfclkclose (d_close_t *)enxio
-#define dcfclkread (d_rdwr_t *)enxio
-#define dcfclkioctl (d_ioctl_t *)enxio
-#define dcfclkselect (d_select_t *)enxio
-#endif
-
-#include "lpa.h"
-#if NLPA > 0
-d_open_t lpaopen;
-d_close_t lpaclose;
-d_rdwr_t lpawrite;
-d_ioctl_t lpaioctl;
-#else
+/*
+ * lpa has been removed from the tree,
+ * but the major dev no for it still remains.
+ * (lpt now provides all the functionality which lpa used to.)
+ */
#define lpaopen (d_open_t *)enxio
#define lpaclose (d_close_t *)enxio
#define lpawrite (d_rdwr_t *)enxio
#define lpaioctl (d_ioctl_t *)enxio
-#endif
#include "speaker.h"
#if NSPEAKER > 0
@@ -442,6 +423,21 @@ d_ioctl_t spkrioctl;
#define spkrioctl (d_ioctl_t *)enxio
#endif
+#include "pca.h"
+#if NPCA > 0
+d_open_t pcaopen;
+d_close_t pcaclose;
+d_rdwr_t pcawrite;
+d_ioctl_t pcaioctl;
+d_select_t pcaselect;
+#else
+#define pcaopen (d_open_t *)enxio
+#define pcaclose (d_close_t *)enxio
+#define pcawrite (d_rdwr_t *)enxio
+#define pcaioctl (d_ioctl_t *)enxio
+#define pcaselect (d_select_t *)enxio
+#endif
+
#include "mse.h"
#if NMSE > 0
d_open_t mseopen;
@@ -464,7 +460,7 @@ d_ioctl_t sioioctl;
d_select_t sioselect;
d_stop_t siostop;
#define sioreset (d_reset_t *)enxio
-extern struct tty sio_tty[];
+extern struct tty *sio_tty[];
#else
#define sioopen (d_open_t *)enxio
#define sioclose (d_close_t *)enxio
@@ -544,7 +540,7 @@ struct cdevsw cdevsw[] =
logselect, nommap, NULL },
{ comopen, comclose, comread, comwrite, /*8*/
comioctl, nostop, comreset, com_tty, /* com */
- comselect, nommap, NULL },
+ ttselect, nommap, NULL },
{ Fdopen, fdclose, rawread, rawwrite, /*9*/
fdioctl, nostop, nullreset, NULL, /* Fd (!=fd) */
seltrue, nommap, fdstrategy },
@@ -590,9 +586,9 @@ struct cdevsw cdevsw[] =
{ bpfopen, bpfclose, bpfread, bpfwrite, /*23*/
bpfioctl, nostop, nullreset, NULL, /* bpf */
bpfselect, nommap, NULL },
- { dcfclkopen, dcfclkclose, dcfclkread, nowrite, /*24*/
- dcfclkioctl, nostop, nullreset, NULL, /* dcfclk */
- dcfclkselect, nommap, NULL },
+ { pcaopen, pcaclose, noread, pcawrite, /*24*/
+ pcaioctl, nostop, nullreset, NULL, /* pcaudio */
+ pcaselect, nommap, NULL },
{ lpaopen, lpaclose, noread, lpawrite, /*25*/
lpaioctl, nullstop, nullreset, NULL, /* lpa */
seltrue, nommap, NULL },
@@ -614,6 +610,7 @@ struct cdevsw cdevsw[] =
{ ukopen, ukclose, noread, nowrite, /*31*/
ukioctl, nostop, nullreset, NULL, /* unknown */
seltrue, nommap, NULL }, /* scsi */
+ { 0, } /* character device 32 is reserved for local use */
/*
* If you need a cdev major number, please contact the FreeBSD team
* by sending mail to `freebsd-hackers@freefall.cdrom.com'.
diff --git a/sys/i386/i386/db_interface.c b/sys/i386/i386/db_interface.c
index 7e68844e4ade..aeeedbecdac1 100644
--- a/sys/i386/i386/db_interface.c
+++ b/sys/i386/i386/db_interface.c
@@ -23,7 +23,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: db_interface.c,v 1.5 1993/12/19 00:50:00 wollman Exp $
+ * $Id: db_interface.c,v 1.7 1994/06/22 05:52:28 jkh Exp $
*/
/*
@@ -178,8 +178,6 @@ db_read_bytes(addr, size, data)
db_nofault = 0;
}
-struct pte *pmap_pte(pmap_t, vm_offset_t);
-
/*
* Write bytes to kernel address space for debugger.
*/
@@ -234,9 +232,24 @@ db_write_bytes(addr, size, data)
}
}
+/*
+ * XXX move this to machdep.c and allow it to be called iff any debugger is
+ * installed.
+ * XXX msg is not printed.
+ */
void
Debugger (msg)
const char *msg;
{
- asm ("int $3");
+ static volatile u_char in_Debugger;
+
+ if (!in_Debugger) {
+ in_Debugger = 1;
+#ifdef __GNUC__
+ asm("int $3");
+#else
+ int3();
+#endif
+ in_Debugger = 0;
+ }
}
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index aa2e3d940fd1..f247c0a233af 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: exception.s,v 1.2 1994/01/03 07:55:20 davidg Exp $
+ * $Id: exception.s,v 1.3 1994/04/02 07:00:23 davidg Exp $
*/
#include "npx.h" /* NNPX */
@@ -39,7 +39,9 @@
#include "errno.h" /* error return codes */
-#include "i386/isa/debug.h" /* BDE debugging macros */
+#include "machine/spl.h" /* SWI_AST_MASK ... */
+
+#include "machine/psl.h" /* PSL_I */
#include "machine/trap.h" /* trap codes */
#include "syscall.h" /* syscall numbers */
@@ -57,31 +59,49 @@
/*****************************************************************************/
/*
* Trap and fault vector routines
- *
+ */
+#define IDTVEC(name) ALIGN_TEXT ; .globl _X/**/name ; _X/**/name:
+#define TRAP(a) pushl $(a) ; jmp _alltraps
+
+/*
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
* control. The sti's give the standard losing behaviour for ddb and kgdb.
*/
-#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
-#define TRAP(a) pushl $(a) ; jmp alltraps
+#ifdef BDE_DEBUGGER
+#define BDBTRAP(name) \
+ ss ; \
+ cmpb $0,_bdb_exists ; \
+ je 1f ; \
+ testb $SEL_RPL_MASK,4(%esp) ; \
+ jne 1f ; \
+ ss ; \
+ .globl bdb_/**/name/**/_ljmp ; \
+bdb_/**/name/**/_ljmp: ; \
+ ljmp $0,$0 ; \
+1:
+#else
+#define BDBTRAP(name)
+#endif
+
#ifdef KGDB
-# define BPTTRAP(a) sti; pushl $(a) ; jmp bpttraps
+# define BPTTRAP(a) testl $PSL_I,4+8(%esp) ; je 1f ; sti ; 1: ; \
+ pushl $(a) ; jmp _bpttraps
#else
-# define BPTTRAP(a) sti; TRAP(a)
+# define BPTTRAP(a) testl $PSL_I,4+8(%esp) ; je 1f ; sti ; 1: ; TRAP(a)
#endif
+MCOUNT_LABEL(user)
+MCOUNT_LABEL(btrap)
+
IDTVEC(div)
pushl $0; TRAP(T_DIVIDE)
IDTVEC(dbg)
-#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
BDBTRAP(dbg)
-#endif
pushl $0; BPTTRAP(T_TRCTRAP)
IDTVEC(nmi)
pushl $0; TRAP(T_NMI)
IDTVEC(bpt)
-#if defined(BDE_DEBUGGER) && defined(BDBTRAP)
BDBTRAP(bpt)
-#endif
pushl $0; BPTTRAP(T_BPTFLT)
IDTVEC(ofl)
pushl $0; TRAP(T_OFLOW)
@@ -114,22 +134,24 @@ IDTVEC(fpu)
* error. It would be better to handle npx interrupts as traps but
* this is difficult for nested interrupts.
*/
- pushl $0 /* dummy error code */
- pushl $T_ASTFLT
+ pushl $0 /* dumby error code */
+ pushl $0 /* dumby trap type */
pushal
- nop /* silly, the bug is for popal and it only
- * bites when the next instruction has a
- * complicated address mode */
pushl %ds
pushl %es /* now the stack frame is a trap frame */
movl $KDSEL,%eax
movl %ax,%ds
movl %ax,%es
- pushl _cpl
+ FAKE_MCOUNT(12*4(%esp))
+ movl _cpl,%eax
+ pushl %eax
pushl $0 /* dummy unit to finish building intr frame */
incl _cnt+V_TRAP
+ orl $SWI_AST_MASK,%eax
+ movl %eax,_cpl
call _npxintr
- jmp doreti
+ MEXITCOUNT
+ jmp _doreti
#else /* NNPX > 0 */
pushl $0; TRAP(T_ARITHTRAP)
#endif /* NNPX > 0 */
@@ -166,25 +188,37 @@ IDTVEC(rsvd14)
pushl $0; TRAP(31)
SUPERALIGN_TEXT
-alltraps:
+_alltraps:
pushal
- nop
pushl %ds
pushl %es
movl $KDSEL,%eax
movl %ax,%ds
movl %ax,%es
+ FAKE_MCOUNT(12*4(%esp))
calltrap:
+ FAKE_MCOUNT(_btrap) /* init "from" _btrap -> calltrap */
incl _cnt+V_TRAP
+ orl $SWI_AST_MASK,_cpl
call _trap
/*
- * Return through doreti to handle ASTs. Have to change trap frame
+ * There was no place to save the cpl so we have to recover it
+ * indirectly. For traps from user mode it was 0, and for traps
+ * from kernel mode Oring SWI_AST_MASK into it didn't change it.
+ */
+ subl %eax,%eax
+ testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
+ jne 1f
+ movl _cpl,%eax
+1:
+ /*
+ * Return via _doreti to handle ASTs. Have to change trap frame
* to interrupt frame.
*/
- movl $T_ASTFLT,TF_TRAPNO(%esp) /* new trap type (err code not used) */
- pushl _cpl
- pushl $0 /* dummy unit */
- jmp doreti
+ pushl %eax
+ subl $4,%esp
+ MEXITCOUNT
+ jmp _doreti
#ifdef KGDB
/*
@@ -192,17 +226,18 @@ calltrap:
* to the regular trap code.
*/
SUPERALIGN_TEXT
-bpttraps:
+_bpttraps:
pushal
- nop
pushl %ds
pushl %es
movl $KDSEL,%eax
movl %ax,%ds
movl %ax,%es
+ FAKE_MCOUNT(12*4(%esp))
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp) /* non-kernel mode? */
jne calltrap /* yes */
call _kgdb_trap_glue
+ MEXITCOUNT
jmp calltrap
#endif
@@ -214,7 +249,6 @@ IDTVEC(syscall)
pushfl /* Room for tf_err */
pushfl /* Room for tf_trapno */
pushal
- nop
pushl %ds
pushl %es
movl $KDSEL,%eax /* switch to kernel segments */
@@ -222,51 +256,17 @@ IDTVEC(syscall)
movl %ax,%es
movl TF_ERR(%esp),%eax /* copy eflags from tf_err to fs_eflags */
movl %eax,TF_EFLAGS(%esp)
- movl $0,TF_ERR(%esp) /* zero tf_err */
+ FAKE_MCOUNT(12*4(%esp))
incl _cnt+V_SYSCALL
+ movl $SWI_AST_MASK,_cpl
call _syscall
/*
- * Return through doreti to handle ASTs.
+ * Return via _doreti to handle ASTs.
*/
- movl $T_ASTFLT,TF_TRAPNO(%esp) /* new trap type (err code not used) */
- pushl _cpl
- pushl $0
- jmp doreti
-
-#ifdef SHOW_A_LOT
-/*
- * 'show_bits' was too big when defined as a macro. The line length for some
- * enclosing macro was too big for gas. Perhaps the code would have blown
- * the cache anyway.
- */
- ALIGN_TEXT
-show_bits:
- pushl %eax
- SHOW_BIT(0)
- SHOW_BIT(1)
- SHOW_BIT(2)
- SHOW_BIT(3)
- SHOW_BIT(4)
- SHOW_BIT(5)
- SHOW_BIT(6)
- SHOW_BIT(7)
- SHOW_BIT(8)
- SHOW_BIT(9)
- SHOW_BIT(10)
- SHOW_BIT(11)
- SHOW_BIT(12)
- SHOW_BIT(13)
- SHOW_BIT(14)
- SHOW_BIT(15)
- popl %eax
- ret
-
- .data
-bit_colors:
- .byte GREEN,RED,0,0
- .text
-
-#endif /* SHOW_A_LOT */
+ pushl $0 /* cpl to restore */
+ subl $4,%esp
+ MEXITCOUNT
+ jmp _doreti
/*
* include generated interrupt vectors and ISA intr code
diff --git a/sys/i386/i386/in_cksum.c b/sys/i386/i386/in_cksum.c
index 0dec1d67056d..0b3d3e5d9637 100644
--- a/sys/i386/i386/in_cksum.c
+++ b/sys/i386/i386/in_cksum.c
@@ -32,7 +32,7 @@
*
* from tahoe: in_cksum.c 1.2 86/01/05
* from: @(#)in_cksum.c 1.3 (Berkeley) 1/19/91
- * $Id: in_cksum.c,v 1.4 1993/12/19 00:50:02 wollman Exp $
+ * $Id: in_cksum.c,v 1.5 1994/03/07 11:47:30 davidg Exp $
*/
#include "param.h"
@@ -56,9 +56,10 @@
* Thanks to gcc we don't have to guess
* which registers contain sum & w.
*/
-#define CLC asm("clc")
-#define ADD(n) asm("adcl " #n "(%2), %0": "=r"(sum): "0"(sum), "r"(w))
-#define MOP asm("adcl $0, %0": "=r"(sum): "0"(sum))
+#define ADD(n) asm("addl " #n "(%2), %0" : "=r" (sum) : "0" (sum), "r" (w))
+#define ADDC(n) asm("adcl " #n "(%2), %0" : "=r" (sum) : "0" (sum), "r" (w))
+#define LOAD(n) asm volatile("movb " #n "(%1), %0" : "=r" (junk) : "r" (w))
+#define MOP asm("adcl $0, %0" : "=r" (sum) : "0" (sum))
int
in_cksum(m, len)
@@ -114,28 +115,90 @@ in_cksum(m, len)
}
}
/*
+ * Advance to a 486 cache line boundary.
+ */
+ if (4 & (int) w && mlen >= 4) {
+ ADD(0);
+ MOP;
+ w += 2;
+ mlen -= 4;
+ }
+ if (8 & (int) w && mlen >= 8) {
+ ADD(0);
+ ADDC(4);
+ MOP;
+ w += 4;
+ mlen -= 8;
+ }
+ /*
* Do as much of the checksum as possible 32 bits at at time.
* In fact, this loop is unrolled to make overhead from
* branches &c small.
*/
+ mlen -= 1;
while ((mlen -= 32) >= 0) {
+ u_char junk;
/*
- * Clear the carry flag, add with carry 16 words
- * and fold-in last carry by adding a 0 with carry.
+ * Add with carry 16 words and fold in the last
+ * carry by adding a 0 with carry.
+ *
+ * The early ADD(16) and the LOAD(32) are to load
+ * the next 2 cache lines in advance on 486's. The
+ * 486 has a penalty of 2 clock cycles for loading
+ * a cache line, plus whatever time the external
+ * memory takes to load the first word(s) addressed.
+ * These penalties are unavoidable. Subsequent
+ * accesses to a cache line being loaded (and to
+ * other external memory?) are delayed until the
+ * whole load finishes. These penalties are mostly
+ * avoided by not accessing external memory for
+ * 8 cycles after the ADD(16) and 12 cycles after
+ * the LOAD(32). The loop terminates when mlen
+ * is initially 33 (not 32) to guaranteed that
+ * the LOAD(32) is within bounds.
*/
- CLC;
- ADD(0); ADD(4); ADD(8); ADD(12);
- ADD(16); ADD(20); ADD(24); ADD(28);
- MOP; w += 16;
+ ADD(16);
+ ADDC(0);
+ ADDC(4);
+ ADDC(8);
+ ADDC(12);
+ LOAD(32);
+ ADDC(20);
+ ADDC(24);
+ ADDC(28);
+ MOP;
+ w += 16;
+ }
+ mlen += 32 + 1;
+ if (mlen >= 32) {
+ ADD(16);
+ ADDC(0);
+ ADDC(4);
+ ADDC(8);
+ ADDC(12);
+ ADDC(20);
+ ADDC(24);
+ ADDC(28);
+ MOP;
+ w += 16;
+ mlen -= 32;
}
- mlen += 32;
- while ((mlen -= 8) >= 0) {
- CLC;
- ADD(0); ADD(4);
+ if (mlen >= 16) {
+ ADD(0);
+ ADDC(4);
+ ADDC(8);
+ ADDC(12);
+ MOP;
+ w += 8;
+ mlen -= 16;
+ }
+ if (mlen >= 8) {
+ ADD(0);
+ ADDC(4);
MOP;
w += 4;
+ mlen -= 8;
}
- mlen += 8;
if (mlen == 0 && byte_swapped == 0)
continue; /* worth 1% maybe ?? */
REDUCE;
@@ -172,4 +235,3 @@ in_cksum(m, len)
REDUCE;
return (~sum & 0xffff);
}
-
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 57ee6a93832d..d0317103d43e 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
- * $Id: locore.s,v 1.15 1994/02/01 04:08:54 davidg Exp $
+ * $Id: locore.s,v 1.20 1994/06/14 17:49:42 davidg Exp $
*/
/*
@@ -51,7 +51,6 @@
#include "machine/pte.h" /* page table entry definitions */
#include "errno.h" /* error return codes */
#include "machine/specialreg.h" /* x86 special registers */
-#include "i386/isa/debug.h" /* BDE debugging macros */
#include "machine/cputypes.h" /* x86 cpu type definitions */
#include "syscall.h" /* system call numbers */
#include "machine/asmacros.h" /* miscellaneous asm macros */
@@ -102,8 +101,10 @@ _esym: .long 0 /* ptr to end of syms */
.globl _boothowto,_bootdev,_curpcb
- .globl _cpu,_cold,_atdevbase
+ .globl _cpu,_cold,_atdevbase,_cpu_vendor,_cpu_id
_cpu: .long 0 /* are we 386, 386sx, or 486 */
+_cpu_id: .long 0
+_cpu_vendor: .space 17
_cold: .long 1 /* cold till we are not */
_atdevbase: .long 0 /* location of start of iomem in virtual */
_atdevphys: .long 0 /* location of device mapping ptes (phys) */
@@ -123,7 +124,7 @@ _proc0paddr: .long 0 /* address of proc 0 address space */
#ifdef BDE_DEBUGGER
.globl _bdb_exists /* flag to indicate BDE debugger is available */
-_bde_exists: .long 0
+_bdb_exists: .long 0
#endif
.globl tmpstk
@@ -140,10 +141,10 @@ tmpstk:
* btext: beginning of text section.
* Also the entry point (jumped to directly from the boot blocks).
*/
-ENTRY(btext)
+NON_GPROF_ENTRY(btext)
movw $0x1234,0x472 /* warm boot */
jmp 1f
- .space 0x500 /* skip over warm boot shit */
+ .org 0x500 /* space for BIOS variables */
/*
* pass parameters on stack (howto, bootdev, unit, cyloffset, esym)
@@ -151,7 +152,8 @@ ENTRY(btext)
* ( if we want to hold onto /boot, it's physical %esp up to _end)
*/
- 1: movl 4(%esp),%eax
+ 1:
+ movl 4(%esp),%eax
movl %eax,_boothowto-KERNBASE
movl 8(%esp),%eax
movl %eax,_bootdev-KERNBASE
@@ -164,30 +166,76 @@ ENTRY(btext)
movl _nfs_diskless_size-KERNBASE,%ecx
movl 20(%esp),%esi
movl $(_nfs_diskless-KERNBASE),%edi
+ cld
rep
movsb
#endif
- /* find out our CPU type. */
- pushfl
- popl %eax
- movl %eax,%ecx
- xorl $0x40000,%eax
- pushl %eax
- popfl
- pushfl
- popl %eax
- xorl %ecx,%eax
- shrl $18,%eax
- andl $1,%eax
- push %ecx
- popfl
-
- cmpl $0,%eax
- jne 1f
- movl $CPU_386,_cpu-KERNBASE
+ /* don't trust what the BIOS gives for eflags */
+ pushl $PSL_MBO
+ popfl
+
+ /* Find out our CPU type. */
+
+ /* Try to toggle alignment check flag; does not exist on 386. */
+ pushfl
+ popl %eax
+ movl %eax,%ecx
+ orl $PSL_AC,%eax
+ pushl %eax
+ popfl
+ pushfl
+ popl %eax
+ xorl %ecx,%eax
+ andl $PSL_AC,%eax
+ pushl %ecx
+ popfl
+
+ testl %eax,%eax
+ jnz 1f
+ movl $CPU_386,_cpu-KERNBASE
+ jmp 2f
+
+1: /* Try to toggle identification flag; does not exist on early 486s. */
+ pushfl
+ popl %eax
+ movl %eax,%ecx
+ xorl $PSL_ID,%eax
+ pushl %eax
+ popfl
+ pushfl
+ popl %eax
+ xorl %ecx,%eax
+ andl $PSL_ID,%eax
+ pushl %ecx
+ popfl
+
+ testl %eax,%eax
+ jnz 1f
+ movl $CPU_486,_cpu-KERNBASE
+ jmp 2f
+
+1: /* Use the `cpuid' instruction. */
+ xorl %eax,%eax
+ .byte 0x0f,0xa2 # cpuid 0
+ movl %ebx,_cpu_vendor-KERNBASE # store vendor string
+ movl %edx,_cpu_vendor+4-KERNBASE
+ movl %ecx,_cpu_vendor+8-KERNBASE
+ movb $0,_cpu_vendor+12-KERNBASE
+
+ movl $1,%eax
+ .byte 0x0f,0xa2 # cpuid 1
+ movl %eax,_cpu_id-KERNBASE # store cpu_id
+ rorl $8,%eax # extract family type
+ andl $15,%eax
+ cmpl $5,%eax
+ jae 1f
+
+ /* less than Pentium; must be 486 */
+ movl $CPU_486,_cpu-KERNBASE
jmp 2f
-1: movl $CPU_486,_cpu-KERNBASE
+
+1: movl $CPU_586,_cpu-KERNBASE
2:
/*
@@ -217,7 +265,7 @@ ENTRY(btext)
movl $_end-KERNBASE,%ecx
addl $NBPG-1,%ecx /* page align up */
andl $~(NBPG-1),%ecx
- movl %ecx,%esi /* esi=start of tables */
+ movl %ecx,%esi /* esi = start of free memory */
movl %ecx,_KERNend-KERNBASE /* save end of kernel */
/* clear bss */
@@ -296,7 +344,7 @@ ENTRY(btext)
shrl $PGSHIFT,%ecx
orl $PG_V|PG_KW,%eax /* valid, kernel read/write */
fillkpt
-#endif
+#endif /* KGDB || BDE_DEBUGGER */
/* now initialize the page dir, upages, p0stack PT, and page tables */
@@ -309,7 +357,7 @@ ENTRY(btext)
addl %esi,%ebx /* address of page directory */
addl $((1+UPAGES+1)*NBPG),%ebx /* offset to kernel page tables */
fillkpt
-
+
/* map I/O memory map */
movl _KPTphys-KERNBASE,%ebx /* base of kernel page tables */
@@ -368,6 +416,7 @@ ENTRY(btext)
movl $_gdt-KERNBASE,%edi
movl %edi,2(%esp)
movl $8*18/4,%ecx
+ cld
rep /* copy gdt */
movsl
movl $_gdt-KERNBASE,-8+2(%edi) /* adjust gdt self-ptr */
@@ -389,6 +438,7 @@ ENTRY(btext)
movl $_idt-KERNBASE,%edi
movl %edi,6+2(%esp)
movl $8*4/4,%ecx
+ cld
rep /* copy idt */
movsl
@@ -397,7 +447,7 @@ ENTRY(btext)
addl $2*6,%esp
popal
-#endif
+#endif /* BDE_DEBUGGER */
/* load base of page directory and enable mapping */
movl %esi,%eax /* phys address of ptd in proc 0 */
@@ -436,7 +486,7 @@ begin: /* now running relocated at KERNBASE where the system is linked to run */
movl $_gdt+8*9,%eax /* adjust slots 9-17 */
movl $9,%ecx
reloc_gdt:
- movb $0xfe,7(%eax) /* top byte of base addresses, was 0, */
+ movb $KERNBASE>>24,7(%eax) /* top byte of base addresses, was 0, */
addl $8,%eax /* now KERNBASE>>24 */
loop reloc_gdt
@@ -444,7 +494,7 @@ reloc_gdt:
je 1f
int $3
1:
-#endif
+#endif /* BDE_DEBUGGER */
/*
* Skip over the page tables and the kernel stack
@@ -494,7 +544,7 @@ lretmsg1:
.asciz "lret: toinit\n"
-#define LCALL(x,y) .byte 0x9a ; .long y; .word x
+#define LCALL(x,y) .byte 0x9a ; .long y ; .word x
/*
* Icode is copied out to process 1 and executed in user mode:
* execve("/sbin/init", argv, envp); exit(0);
@@ -551,4 +601,3 @@ NON_GPROF_ENTRY(sigcode)
.globl _szsigcode
_szsigcode:
.long _szsigcode-_sigcode
-
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 3e0a368b4b44..05546058fbd0 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,13 +35,12 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.36.2.5 1994/04/18 04:56:56 rgrimes Exp $
+ * $Id: machdep.c,v 1.47 1994/06/17 13:32:07 davidg Exp $
*/
#include "npx.h"
#include "isa.h"
-#include <stddef.h>
#include "param.h"
#include "systm.h"
#include "signalvar.h"
@@ -58,7 +57,6 @@
#include "malloc.h"
#include "mbuf.h"
#include "msgbuf.h"
-#include "net/netisr.h"
#ifdef SYSVSHM
#include "sys/shm.h"
@@ -96,6 +94,8 @@ static void initcpu(void);
static int test_page(int *, int);
extern int grow(struct proc *,int);
+const char machine[] = "PC-Class";
+const char *cpu_model;
#ifndef PANIC_REBOOT_WAIT_TIME
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
@@ -115,22 +115,22 @@ int bufpages = BUFPAGES;
#else
int bufpages = 0;
#endif
+#ifdef BOUNCEPAGES
+int bouncepages = BOUNCEPAGES;
+#else
+int bouncepages = 0;
+#endif
extern int freebufspace;
+extern char *bouncememory;
int _udatasel, _ucodesel;
/*
* Machine-dependent startup code
*/
-int boothowto = 0, Maxmem = 0, maxmem = 0, badpages = 0, physmem = 0;
+int boothowto = 0, Maxmem = 0, badpages = 0, physmem = 0;
long dumplo;
extern int bootdev;
-#ifdef SMALL
-extern int forcemaxmem;
-#endif
-#if defined(GENERICAH) || defined(GENERICBT)
-int generic_hack = 1;
-#endif
int biosmem;
vm_offset_t phys_avail[6];
@@ -141,6 +141,8 @@ int cpu_class;
void dumpsys __P((void));
+#define offsetof(type, member) ((size_t)(&((type *)0)->member))
+
void
cpu_startup()
{
@@ -255,6 +257,7 @@ again:
panic("startup: no room for tables");
goto again;
}
+
/*
* End of second pass, addresses have been assigned
*/
@@ -295,6 +298,22 @@ again:
printf("using %d buffers containing %d bytes of memory\n",
nbuf, bufpages * CLBYTES);
+#ifndef NOBOUNCE
+ /*
+ * If there is more than 16MB of memory, allocate some bounce buffers
+ */
+ if (Maxmem > 4096) {
+ if (bouncepages == 0)
+ bouncepages = 96; /* largest physio size + extra */
+ bouncememory = (char *)kmem_alloc(kernel_map, bouncepages * PAGE_SIZE);
+ }
+
+ /*
+ * init bounce buffers
+ */
+ vm_bounce_init();
+#endif
+
/*
* Set up CPU-specific registers, cache, etc.
*/
@@ -324,10 +343,13 @@ struct cpu_nameclass i386_cpus[] = {
static void
identifycpu()
{
+ extern unsigned long cpu_id;
+ extern char cpu_vendor[];
printf("CPU: ");
if (cpu >= 0 && cpu < (sizeof i386_cpus/sizeof(struct cpu_nameclass))) {
printf("%s", i386_cpus[cpu].cpu_name);
cpu_class = i386_cpus[cpu].cpu_class;
+ cpu_model = i386_cpus[cpu].cpu_name;
} else {
printf("unknown cpu type %d\n", cpu);
panic("startup: bad cpu id");
@@ -350,6 +372,10 @@ identifycpu()
printf("unknown"); /* will panic below... */
}
printf("-class CPU)");
+ if(cpu_id)
+ printf(" Id = 0x%x",cpu_id);
+ if(*cpu_vendor)
+ printf(" Origin = \"%s\"",cpu_vendor);
printf("\n"); /* cpu speed would be nice, but how? */
/*
@@ -503,7 +529,7 @@ sendsig(catcher, sig, mask, code)
* Return to previous pc and psl as specified by
* context left by sendsig. Check carefully to
* make sure that the user has not modified the
- * psl to gain improper priviledges or to cause
+ * psl to gain improper privileges or to cause
* a machine fault.
*/
struct sigreturn_args {
@@ -558,11 +584,11 @@ sigreturn(p, uap, retval)
#define null_sel(sel) \
(!ISLDT(sel) && IDXSEL(sel) == 0)
- if ((scp->sc_cs&0xffff != _ucodesel && !valid_ldt_sel(scp->sc_cs)) ||
- (scp->sc_ss&0xffff != _udatasel && !valid_ldt_sel(scp->sc_ss)) ||
- (scp->sc_ds&0xffff != _udatasel && !valid_ldt_sel(scp->sc_ds) &&
+ if (((scp->sc_cs&0xffff) != _ucodesel && !valid_ldt_sel(scp->sc_cs)) ||
+ ((scp->sc_ss&0xffff) != _udatasel && !valid_ldt_sel(scp->sc_ss)) ||
+ ((scp->sc_ds&0xffff) != _udatasel && !valid_ldt_sel(scp->sc_ds) &&
!null_sel(scp->sc_ds)) ||
- (scp->sc_es&0xffff != _udatasel && !valid_ldt_sel(scp->sc_es) &&
+ ((scp->sc_es&0xffff) != _udatasel && !valid_ldt_sel(scp->sc_es) &&
!null_sel(scp->sc_es))) {
#ifdef DEBUG
printf("sigreturn: cs=0x%x ss=0x%x ds=0x%x es=0x%x\n",
@@ -709,10 +735,10 @@ boot(arghowto)
#endif
die:
printf("Rebooting...\n");
- DELAY (100000); /* wait 100ms for printf's to complete */
+ DELAY(1000000); /* wait 1 sec for printf's to complete and be read */
cpu_reset();
for(;;) ;
- /*NOTREACHED*/
+ /* NOTREACHED */
}
unsigned long dumpmag = 0x8fca0101UL; /* magic number for savecore */
@@ -782,36 +808,6 @@ microtime(tvp)
}
#endif /* HZ */
-void
-physstratdone(bp)
- struct buf *bp;
-{
- wakeup((caddr_t) bp);
- bp->b_flags &= ~B_CALL;
-}
-
-void
-physstrat(bp, strat, prio)
- struct buf *bp;
- int (*strat)(), prio;
-{
- register int s;
- caddr_t baddr;
-
- bp->b_flags |= B_CALL;
- bp->b_iodone = physstratdone;
- vmapbuf(bp);
- (*strat)(bp);
- /* pageout daemon doesn't wait for pushed pages */
- if (bp->b_flags & B_DIRTY)
- return;
- s = splbio();
- while ((bp->b_flags & B_DONE) == 0)
- tsleep((caddr_t)bp, prio, "physstr", 0);
- splx(s);
- vunmapbuf(bp);
-}
-
static void
initcpu()
{
@@ -1001,7 +997,7 @@ setidt(idx, func, typ, dpl)
ip->gd_hioffset = ((int)func)>>16 ;
}
-#define IDTVEC(name) __CONCAT(X, name)
+#define IDTVEC(name) __CONCAT(X,name)
typedef void idtvec_t();
extern idtvec_t
@@ -1012,7 +1008,7 @@ extern idtvec_t
IDTVEC(rsvd1), IDTVEC(rsvd2), IDTVEC(rsvd3), IDTVEC(rsvd4),
IDTVEC(rsvd5), IDTVEC(rsvd6), IDTVEC(rsvd7), IDTVEC(rsvd8),
IDTVEC(rsvd9), IDTVEC(rsvd10), IDTVEC(rsvd11), IDTVEC(rsvd12),
- IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(rsvd14), IDTVEC(syscall);
+ IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(syscall);
int _gsel_tss;
@@ -1044,8 +1040,9 @@ init386(first)
* the address space
*/
gdt_segs[GCODE_SEL].ssd_limit = i386_btop(i386_round_page(&etext)) - 1;
- gdt_segs[GDATA_SEL].ssd_limit = 0xffffffffUL; /* XXX constant? */
+ gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1;
for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
+
/* make ldt memory segments */
/*
* The data segment limit must not cover the user area because we
@@ -1146,7 +1143,7 @@ init386(first)
#ifndef LARGEMEM
if (biosextmem > 65536) {
panic("extended memory beyond limit of 64MB");
- /* NOT REACHED */
+ /* NOTREACHED */
}
#endif
@@ -1169,25 +1166,6 @@ init386(first)
if ((pagesinext > 3840) && (pagesinext < 4096))
pagesinext = 3840;
-#if defined(GENERICAH) || defined(GENERICBT)
- /* XXX This is an ugle hack so that machines with >16MB of memory
- * can be booted using the GENERIC* kernels and not have to worry
- * about bus mastered DMA on the ISA bus. It is ONLY compiled into
- * the GENERIC* kernels and can be disabled by tweaking the global
- * generic_hack to be zero using gdb.
- */
- if (generic_hack) {
- if (pagesinext > 3840) {
- printf("WARNING WARNING WARNING WARNING WARNING WARNING\n");
- printf("GENERIC* kernels only USE the first 16MB of your ");
- printf("%dMB.\n", (pagesinext + 256) / 256);
- printf("Read the RELNOTES.FreeBSD file for the reason.\n");
- printf("WARNING WARNING WARNING WARNING WARNING WARNING\n");
- pagesinext = 3840;
- }
- }
-#endif /* defined (GENERICAH) || defiend(GENERICBT) */
-
/*
* Maxmem isn't the "maximum memory", it's the highest page of
* of the physical address space. It should be "Maxphyspage".
@@ -1266,9 +1244,9 @@ init386(first)
}
}
printf("done.\n");
-
- maxmem = Maxmem - 1; /* highest page of usable memory */
- avail_end = (maxmem << PAGE_SHIFT) - i386_round_page(sizeof(struct msgbuf));
+
+ avail_end = (Maxmem << PAGE_SHIFT)
+ - i386_round_page(sizeof(struct msgbuf));
/*
* Initialize pointers to the two chunks of memory; for use
@@ -1334,15 +1312,6 @@ test_page(address, pattern)
return(0);
}
-/*aston() {
- schednetisr(NETISR_AST);
-}*/
-
-void
-setsoftclock() {
- schednetisr(NETISR_SCLK);
-}
-
/*
* insert an element into a queue
*/
diff --git a/sys/i386/i386/math_emulate.c b/sys/i386/i386/math_emulate.c
index 256f8fb1033d..c6df09e9dddb 100644
--- a/sys/i386/i386/math_emulate.c
+++ b/sys/i386/i386/math_emulate.c
@@ -6,7 +6,7 @@
* [expediant "port" of linux 8087 emulator to 386BSD, with apologies -wfj]
*
* from: 386BSD 0.1
- * $Id: math_emulate.c,v 1.7 1994/01/29 22:07:16 nate Exp $
+ * $Id: math_emulate.c,v 1.9 1994/06/05 19:31:45 ats Exp $
*/
/*
@@ -107,243 +107,255 @@ math_emulate(struct trapframe * info)
switch (code) {
case 0x1d0: /* fnop */
return(0);
- case 0x1d1: case 0x1d2: case 0x1d3:
+ case 0x1d1: case 0x1d2: case 0x1d3: /* fst to 32-bit mem */
case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7:
math_abort(info,SIGILL);
- case 0x1e0:
+ case 0x1e0: /* fchs */
ST(0).exponent ^= 0x8000;
return(0);
- case 0x1e1:
+ case 0x1e1: /* fabs */
ST(0).exponent &= 0x7fff;
return(0);
case 0x1e2: case 0x1e3:
math_abort(info,SIGILL);
- case 0x1e4:
+ case 0x1e4: /* ftst */
ftst(PST(0));
return(0);
- case 0x1e5:
+ case 0x1e5: /* fxam */
printf("fxam not implemented\n\r");
math_abort(info,SIGILL);
- case 0x1e6: case 0x1e7:
+ case 0x1e6: case 0x1e7: /* fldenv */
math_abort(info,SIGILL);
- case 0x1e8:
+ case 0x1e8: /* fld1 */
fpush();
ST(0) = CONST1;
return(0);
- case 0x1e9:
+ case 0x1e9: /* fld2t */
fpush();
ST(0) = CONSTL2T;
return(0);
- case 0x1ea:
+ case 0x1ea: /* fld2e */
fpush();
ST(0) = CONSTL2E;
return(0);
- case 0x1eb:
+ case 0x1eb: /* fldpi */
fpush();
ST(0) = CONSTPI;
return(0);
- case 0x1ec:
+ case 0x1ec: /* fldlg2 */
fpush();
ST(0) = CONSTLG2;
return(0);
- case 0x1ed:
+ case 0x1ed: /* fldln2 */
fpush();
ST(0) = CONSTLN2;
return(0);
- case 0x1ee:
+ case 0x1ee: /* fldz */
fpush();
ST(0) = CONSTZ;
return(0);
case 0x1ef:
math_abort(info,SIGILL);
- case 0x1f0: case 0x1f1: case 0x1f2: case 0x1f3:
- case 0x1f4: case 0x1f5: case 0x1f6: case 0x1f7:
- case 0x1f8: case 0x1f9: case 0x1fa: case 0x1fb:
- case 0x1fe: case 0x1ff:
+ case 0x1f0: /* f2xm1 */
+ case 0x1f1: /* fyl2x */
+ case 0x1f2: /* fptan */
+ case 0x1f3: /* fpatan */
+ case 0x1f4: /* fxtract */
+ case 0x1f5: /* fprem1 */
+ case 0x1f6: /* fdecstp */
+ case 0x1f7: /* fincstp */
+ case 0x1f8: /* fprem */
+ case 0x1f9: /* fyl2xp1 */
+ case 0x1fa: /* fsqrt */
+ case 0x1fb: /* fsincos */
+ case 0x1fe: /* fsin */
+ case 0x1ff: /* fcos */
uprintf(
"math_emulate: instruction %04x not implemented\n",
code + 0xd800);
math_abort(info,SIGILL);
- case 0x1fd:
+ case 0x1fc: /* frndint */
+ frndint(PST(0),&tmp);
+ real_to_real(&tmp,&ST(0));
+ return(0);
+ case 0x1fd: /* fscale */
/* incomplete and totally inadequate -wfj */
Fscale(PST(0), PST(1), &tmp);
real_to_real(&tmp,&ST(0));
return(0); /* 19 Sep 92*/
- case 0x1fc:
- frndint(PST(0),&tmp);
- real_to_real(&tmp,&ST(0));
- return(0);
- case 0x2e9:
+ case 0x2e9: /* ????? */
+/* if this should be a fucomp ST(0),ST(1) , it must be a 0x3e9 ATS */
fucom(PST(1),PST(0));
fpop(); fpop();
return(0);
- case 0x3d0: case 0x3d1:
+ case 0x3d0: case 0x3d1: /* fist ?? */
return(0);
- case 0x3e2:
+ case 0x3e2: /* fclex */
I387.swd &= 0x7f00;
return(0);
- case 0x3e3:
+ case 0x3e3: /* fninit */
I387.cwd = 0x037f;
I387.swd = 0x0000;
I387.twd = 0x0000;
return(0);
case 0x3e4:
return(0);
- case 0x6d9:
+ case 0x6d9: /* fcompp */
fcom(PST(1),PST(0));
fpop(); fpop();
return(0);
- case 0x7e0:
+ case 0x7e0: /* fstsw ax */
*(short *) &info->tf_eax = I387.swd;
return(0);
}
switch (code >> 3) {
- case 0x18:
+ case 0x18: /* fadd */
fadd(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(0));
return(0);
- case 0x19:
+ case 0x19: /* fmul */
fmul(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(0));
return(0);
- case 0x1a:
+ case 0x1a: /* fcom */
fcom(PST(code & 7),PST(0));
return(0);
- case 0x1b:
+ case 0x1b: /* fcomp */
fcom(PST(code & 7),PST(0));
fpop();
return(0);
- case 0x1c:
+ case 0x1c: /* fsubr */
real_to_real(&ST(code & 7),&tmp);
tmp.exponent ^= 0x8000;
fadd(PST(0),&tmp,&tmp);
real_to_real(&tmp,&ST(0));
return(0);
- case 0x1d:
+ case 0x1d: /* fsub */
ST(0).exponent ^= 0x8000;
fadd(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(0));
return(0);
- case 0x1e:
+ case 0x1e: /* fdivr */
fdiv(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(0));
return(0);
- case 0x1f:
+ case 0x1f: /* fdiv */
fdiv(PST(code & 7),PST(0),&tmp);
real_to_real(&tmp,&ST(0));
return(0);
- case 0x38:
+ case 0x38: /* fld */
fpush();
- ST(0) = ST((code & 7)+1);
+ ST(0) = ST((code & 7)+1); /* why plus 1 ????? ATS */
return(0);
- case 0x39:
+ case 0x39: /* fxch */
fxchg(&ST(0),&ST(code & 7));
return(0);
- case 0x3b:
+ case 0x3b: /* ??? ??? wrong ???? ATS */
ST(code & 7) = ST(0);
fpop();
return(0);
- case 0x98:
+ case 0x98: /* fadd */
fadd(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(code & 7));
return(0);
- case 0x99:
+ case 0x99: /* fmul */
fmul(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(code & 7));
return(0);
- case 0x9a:
+ case 0x9a: /* ???? , my manual don't list a direction bit
+for fcom , ??? ATS */
fcom(PST(code & 7),PST(0));
return(0);
- case 0x9b:
+ case 0x9b: /* same as above , ATS */
fcom(PST(code & 7),PST(0));
fpop();
return(0);
- case 0x9c:
+ case 0x9c: /* fsubr */
ST(code & 7).exponent ^= 0x8000;
fadd(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(code & 7));
return(0);
- case 0x9d:
+ case 0x9d: /* fsub */
real_to_real(&ST(0),&tmp);
tmp.exponent ^= 0x8000;
fadd(PST(code & 7),&tmp,&tmp);
real_to_real(&tmp,&ST(code & 7));
return(0);
- case 0x9e:
+ case 0x9e: /* fdivr */
fdiv(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(code & 7));
return(0);
- case 0x9f:
+ case 0x9f: /* fdiv */
fdiv(PST(code & 7),PST(0),&tmp);
real_to_real(&tmp,&ST(code & 7));
return(0);
- case 0xb8:
+ case 0xb8: /* ffree */
printf("ffree not implemented\n\r");
math_abort(info,SIGILL);
- case 0xb9:
+ case 0xb9: /* fstp ???? where is the pop ? ATS */
fxchg(&ST(0),&ST(code & 7));
return(0);
- case 0xba:
+ case 0xba: /* fst */
ST(code & 7) = ST(0);
return(0);
- case 0xbb:
+ case 0xbb: /* ????? encoding of fstp to mem ? ATS */
ST(code & 7) = ST(0);
fpop();
return(0);
- case 0xbc:
+ case 0xbc: /* fucom */
fucom(PST(code & 7),PST(0));
return(0);
- case 0xbd:
+ case 0xbd: /* fucomp */
fucom(PST(code & 7),PST(0));
fpop();
return(0);
- case 0xd8:
+ case 0xd8: /* faddp */
fadd(PST(code & 7),PST(0),&tmp);
real_to_real(&tmp,&ST(code & 7));
fpop();
return(0);
- case 0xd9:
+ case 0xd9: /* fmulp */
fmul(PST(code & 7),PST(0),&tmp);
real_to_real(&tmp,&ST(code & 7));
fpop();
return(0);
- case 0xda:
+ case 0xda: /* ??? encoding of ficom with 16 bit mem ? ATS */
fcom(PST(code & 7),PST(0));
fpop();
return(0);
- case 0xdc:
+ case 0xdc: /* fsubrp */
ST(code & 7).exponent ^= 0x8000;
fadd(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(code & 7));
fpop();
return(0);
- case 0xdd:
+ case 0xdd: /* fsubp */
real_to_real(&ST(0),&tmp);
tmp.exponent ^= 0x8000;
fadd(PST(code & 7),&tmp,&tmp);
real_to_real(&tmp,&ST(code & 7));
fpop();
return(0);
- case 0xde:
+ case 0xde: /* fdivrp */
fdiv(PST(0),PST(code & 7),&tmp);
real_to_real(&tmp,&ST(code & 7));
fpop();
return(0);
- case 0xdf:
+ case 0xdf: /* fdivp */
fdiv(PST(code & 7),PST(0),&tmp);
real_to_real(&tmp,&ST(code & 7));
fpop();
return(0);
- case 0xf8:
+ case 0xf8: /* fild 16-bit mem ???? ATS */
printf("ffree not implemented\n\r");
math_abort(info,SIGILL);
fpop();
return(0);
- case 0xf9:
+ case 0xf9: /* ????? ATS */
fxchg(&ST(0),&ST(code & 7));
return(0);
- case 0xfa:
- case 0xfb:
+ case 0xfa: /* fist 16-bit mem ? ATS */
+ case 0xfb: /* fistp 16-bit mem ? ATS */
ST(code & 7) = ST(0);
fpop();
return(0);
diff --git a/sys/i386/i386/microtime.s b/sys/i386/i386/microtime.s
index d167b6ee556a..4c77fd08117d 100644
--- a/sys/i386/i386/microtime.s
+++ b/sys/i386/i386/microtime.s
@@ -31,10 +31,10 @@
* SUCH DAMAGE.
*
* from: Steve McCanne's microtime code
- * $Id: microtime.s,v 1.2 1993/10/16 14:15:08 rgrimes Exp $
+ * $Id: microtime.s,v 1.4 1994/05/02 09:44:20 sos Exp $
*/
-#include "asm.h"
+#include "machine/asmacros.h"
#include "../isa/isa.h"
#include "../isa/timerreg.h"
@@ -44,31 +44,25 @@
*/
#ifndef HZ
ENTRY(microtime)
- pushl %edi
+ pushl %edi # save registers
pushl %esi
pushl %ebx
- movl $_time,%ebx
+ movl $_time, %ebx # get timeval ptr
+ movl (%ebx), %edi # sec = time.tv_sec
+ movl 4(%ebx), %esi # usec = time.tv_usec
cli # disable interrupts
- movl (%ebx),%edi # sec = time.tv_sec
- movl 4(%ebx),%esi # usec = time.tv_usec
+ movl $(TIMER_SEL0|TIMER_LATCH), %eax
+ outb %al, $TIMER_MODE # latch timer 0's counter
- movl $(TIMER_SEL0|TIMER_LATCH),%eax
- outb %al,$TIMER_MODE # latch timer 0's counter
+ xorl %ebx, %ebx # clear ebx
+ inb $TIMER_CNTR0, %al # Read counter value, LSB first
+ movb %al, %bl
+ inb $TIMER_CNTR0, %al
+ movb %al, %bh
- #
- # Read counter value into ebx, LSB first
- #
- inb $TIMER_CNTR0,%al
- movzbl %al,%ebx
- inb $TIMER_CNTR0,%al
- movzbl %al,%eax
- sall $8,%eax
- orl %eax,%ebx
-
- #
# Now check for counter overflow. This is tricky because the
# timer chip doesn't let us atomically read the current counter
# value and the output state (i.e., overflow state). We have
@@ -96,38 +90,45 @@ ENTRY(microtime)
# we're called from an ipl less than the clock. Otherwise,
# it might not work. Currently, only gettimeofday and bpf
# call microtime so it's not a problem.
- #
- cmpl $11890,%ebx
- jle 2f
- movl $0x0a,%eax # tell ICU we want IRR
- outb %al,$IO_ICU1
- inb $IO_ICU1,%al # read IRR in ICU
- testb $1,%al # is a timer interrupt pending?
+ movl _timer0_prescale, %eax # adjust value if timer is
+ addl _timer0_divisor, %eax # reprogrammed
+ addl $-11932, %eax
+ subl %eax, %ebx
+
+ cmpl $11890, %ebx # do we have a possible overflow condition
+ jle 1f
+
+ inb $IO_ICU1, %al # read IRR in ICU
+ testb $1, %al # is a timer interrupt pending?
je 1f
- addl $-11932,%ebx # yes, subtract one clock period
+ addl $-11932, %ebx # yes, subtract one clock period
1:
- movl $0x0b,%eax # tell ICU we want ISR
- outb %al,$IO_ICU1 # (rest of kernel expects this)
-2:
sti # enable interrupts
- movl $11932,%eax # subtract counter value from 11932 since
- subl %ebx,%eax # it is a count-down value
- imull $1000,%eax,%eax
- movl $0,%edx # zero extend eax for div
- movl $1193,%ecx
+ movl $11932, %eax # subtract counter value from 11932 since
+ subl %ebx, %eax # it is a count-down value
+
+ movl %eax, %ebx # this really is a "imull $1000, %eax, %eax"
+ sall $10, %eax # instruction, but this saves us
+ sall $3, %ebx # 33/23 clocks on a 486/386 CPU
+ subl %ebx, %eax #
+ sall $1, %ebx # /sos
+ subl %ebx, %eax #
+
+ movl $0, %edx # zero extend eax into edx for div
+ movl $1193, %ecx
idivl %ecx # convert to usecs: mult by 1000/1193
- addl %eax,%esi # add counter usecs to time.tv_usec
- cmpl $1000000,%esi # carry in timeval?
- jl 3f
- subl $1000000,%esi # adjust usec
+ addl %eax, %esi # add counter usecs to time.tv_usec
+ cmpl $1000000, %esi # carry in timeval?
+ jl 2f
+ subl $1000000, %esi # adjust usec
incl %edi # bump sec
-3:
- movl 16(%esp),%ecx # load timeval pointer arg
- movl %edi,(%ecx) # tvp->tv_sec = sec
- movl %esi,4(%ecx) # tvp->tv_usec = usec
+2:
+ movl 16(%esp), %ecx # load timeval pointer arg
+ movl %edi, (%ecx) # tvp->tv_sec = sec
+ movl %esi, 4(%ecx) # tvp->tv_usec = usec
popl %ebx # restore regs
popl %esi
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index da74b5f6455b..a1c04662cb8b 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -1,6 +1,10 @@
/*
* Copyright (c) 1991 Regents of the University of California.
* All rights reserved.
+ * Copyright (c) 1994 John S. Dyson
+ * All rights reserved.
+ * Copyright (c) 1994 David Greenman
+ * All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
@@ -35,7 +39,7 @@
* SUCH DAMAGE.
*
* from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
- * $Id: pmap.c,v 1.19.2.1 1994/04/18 04:56:59 rgrimes Exp $
+ * $Id: pmap.c,v 1.26 1994/06/11 17:09:39 paul Exp $
*/
/*
@@ -51,7 +55,8 @@
* Major modifications by John S. Dyson primarily to support
* pageable page tables, eliminating pmap_attributes,
* discontiguous memory pages, and using more efficient string
- * instructions. Jan 13, 1994.
+ * instructions. Jan 13, 1994. Further modifications on Mar 2, 1994,
+ * general clean-up and efficiency mods.
*/
/*
@@ -86,6 +91,7 @@
#include "malloc.h"
#include "user.h"
#include "i386/include/cpufunc.h"
+#include "i386/include/cputypes.h"
#include "vm/vm.h"
#include "vm/vm_kern.h"
@@ -99,55 +105,6 @@
*/
#define BSDVM_COMPAT 1
-#ifdef DEBUG
-struct {
- int kernel; /* entering kernel mapping */
- int user; /* entering user mapping */
- int ptpneeded; /* needed to allocate a PT page */
- int pwchange; /* no mapping change, just wiring or protection */
- int wchange; /* no mapping change, just wiring */
- int mchange; /* was mapped but mapping to different page */
- int managed; /* a managed page */
- int firstpv; /* first mapping for this PA */
- int secondpv; /* second mapping for this PA */
- int ci; /* cache inhibited */
- int unmanaged; /* not a managed page */
- int flushes; /* cache flushes */
-} enter_stats;
-struct {
- int calls;
- int removes;
- int pvfirst;
- int pvsearch;
- int ptinvalid;
- int uflushes;
- int sflushes;
-} remove_stats;
-
-int debugmap = 0;
-int pmapdebug = 0 /* 0xffff */;
-#define PDB_FOLLOW 0x0001
-#define PDB_INIT 0x0002
-#define PDB_ENTER 0x0004
-#define PDB_REMOVE 0x0008
-#define PDB_CREATE 0x0010
-#define PDB_PTPAGE 0x0020
-#define PDB_CACHE 0x0040
-#define PDB_BITS 0x0080
-#define PDB_COLLECT 0x0100
-#define PDB_PROTECT 0x0200
-#define PDB_PDRTAB 0x0400
-#define PDB_PARANOIA 0x2000
-#define PDB_WIRING 0x4000
-#define PDB_PVDUMP 0x8000
-
-int pmapvacflush = 0;
-#define PVF_ENTER 0x01
-#define PVF_REMOVE 0x02
-#define PVF_PROTECT 0x04
-#define PVF_TOTAL 0x80
-#endif
-
/*
* Get PDEs and PTEs for user/kernel address space
*/
@@ -156,14 +113,14 @@ int pmapvacflush = 0;
#define pmap_pte_pa(pte) (*(int *)(pte) & PG_FRAME)
-#define pmap_pde_v(pte) ((pte)->pd_v)
-#define pmap_pte_w(pte) ((pte)->pg_w)
-/* #define pmap_pte_ci(pte) ((pte)->pg_ci) */
-#define pmap_pte_m(pte) ((pte)->pg_m)
-#define pmap_pte_u(pte) ((pte)->pg_u)
-#define pmap_pte_v(pte) ((pte)->pg_v)
-#define pmap_pte_set_w(pte, v) ((pte)->pg_w = (v))
-#define pmap_pte_set_prot(pte, v) ((pte)->pg_prot = (v))
+#define pmap_pde_v(pte) ((*(int *)pte & PG_V) != 0)
+#define pmap_pte_w(pte) ((*(int *)pte & PG_W) != 0)
+#define pmap_pte_m(pte) ((*(int *)pte & PG_M) != 0)
+#define pmap_pte_u(pte) ((*(int *)pte & PG_U) != 0)
+#define pmap_pte_v(pte) ((*(int *)pte & PG_V) != 0)
+
+#define pmap_pte_set_w(pte, v) ((v)?(*(int *)pte |= PG_W):(*(int *)pte &= ~PG_W))
+#define pmap_pte_set_prot(pte, v) ((*(int *)pte &= ~PG_PROT), (*(int *)pte |= (v)))
/*
* Given a map and a machine independent protection code,
@@ -184,19 +141,21 @@ vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */
int i386pagesperpage; /* PAGE_SIZE / I386_PAGE_SIZE */
boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */
vm_offset_t vm_first_phys, vm_last_phys;
-vm_offset_t pager_sva, pager_eva;
-
-static inline boolean_t pmap_testbit();
-static inline void pmap_changebit();
-static inline int pmap_is_managed();
-static inline void *vm_get_pmap();
-static inline void vm_put_pmap();
-static inline void pmap_use_pt();
-inline struct pte *pmap_pte();
-static inline pv_entry_t get_pv_entry();
-void pmap_alloc_pv_entry();
-void pmap_clear_modify();
-void i386_protection_init();
+
+static inline boolean_t pmap_testbit();
+static inline void pmap_changebit();
+static inline int pmap_is_managed();
+static inline void *vm_get_pmap();
+static inline void vm_put_pmap();
+inline void pmap_use_pt();
+inline void pmap_unuse_pt();
+inline pt_entry_t * const pmap_pte();
+static inline pv_entry_t get_pv_entry();
+void pmap_alloc_pv_entry();
+void pmap_clear_modify();
+void i386_protection_init();
+extern vm_offset_t pager_sva, pager_eva;
+extern int cpu_class;
#if BSDVM_COMPAT
#include "msgbuf.h"
@@ -204,13 +163,12 @@ void i386_protection_init();
/*
* All those kernel PT submaps that BSD is so fond of
*/
-struct pte *CMAP1, *CMAP2, *mmap;
+pt_entry_t *CMAP1, *CMAP2, *mmap;
caddr_t CADDR1, CADDR2, vmmap;
-struct pte *msgbufmap;
+pt_entry_t *msgbufmap;
struct msgbuf *msgbufp;
#endif
-struct vm_map * pmap_fmap(pmap_t pmap) ;
void init_pv_entries(int) ;
/*
@@ -221,26 +179,24 @@ void init_pv_entries(int) ;
* [ what about induced faults -wfj]
*/
-inline struct pte *
-pmap_pte(pmap, va)
+inline pt_entry_t *
+const pmap_pte(pmap, va)
register pmap_t pmap;
vm_offset_t va;
{
- if (pmap && pmap_pde_v(pmap_pde(pmap, va))) {
+ if (pmap && *pmap_pde(pmap, va)) {
+ vm_offset_t frame = (int) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
/* are we current address space or kernel? */
- if (pmap->pm_pdir[PTDPTDI].pd_pfnum == PTDpde.pd_pfnum
- || pmap == kernel_pmap)
- return ((struct pte *) vtopte(va));
-
+ if ( (pmap == kernel_pmap) || (frame == ((int) PTDpde & PG_FRAME)))
+ return ((pt_entry_t *) vtopte(va));
/* otherwise, we are alternate address space */
else {
- if (pmap->pm_pdir[PTDPTDI].pd_pfnum
- != APTDpde.pd_pfnum) {
+ if ( frame != ((int) APTDpde & PG_FRAME) ) {
APTDpde = pmap->pm_pdir[PTDPTDI];
tlbflush();
}
- return((struct pte *) avtopte(va));
+ return((pt_entry_t *) avtopte(va));
}
}
return(0);
@@ -258,40 +214,34 @@ pmap_extract(pmap, va)
register pmap_t pmap;
vm_offset_t va;
{
- struct pde save;
+ pd_entry_t save;
vm_offset_t pa;
int s;
- s = splhigh();
- if (pmap && pmap_pde_v(pmap_pde(pmap, va))) {
+ if (pmap && *pmap_pde(pmap, va)) {
+ vm_offset_t frame = (int) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
/* are we current address space or kernel? */
- if (pmap->pm_pdir[PTDPTDI].pd_pfnum == PTDpde.pd_pfnum
- || pmap == kernel_pmap) {
+ if ( (pmap == kernel_pmap)
+ || (frame == ((int) PTDpde & PG_FRAME)) ) {
pa = *(int *) vtopte(va);
/* otherwise, we are alternate address space */
} else {
- if (pmap->pm_pdir[PTDPTDI].pd_pfnum
- != APTDpde.pd_pfnum) {
- save = APTDpde;
+ if ( frame != ((int) APTDpde & PG_FRAME)) {
APTDpde = pmap->pm_pdir[PTDPTDI];
tlbflush();
- pa = *(int *) avtopte(va);
- APTDpde = save;
- tlbflush();
- } else {
- tlbflush();
- pa = *(int *) avtopte(va);
}
+ pa = *(int *) avtopte(va);
}
pa = (pa & PG_FRAME) | (va & ~PG_FRAME);
- splx(s);
return pa;
}
- splx(s);
return 0;
}
+/*
+ * determine if a page is managed (memory vs. device)
+ */
static inline int
pmap_is_managed(pa)
vm_offset_t pa;
@@ -309,36 +259,51 @@ pmap_is_managed(pa)
}
/*
- * increment/decrement pmap wiring count
+ * find the vm_page_t of a pte (only) given va of pte and pmap
*/
-static inline void
-pmap_use_pt(pmap, va, use)
+inline vm_page_t
+pmap_pte_vm_page(pmap, pt)
+ pmap_t pmap;
+ vm_offset_t pt;
+{
+ pt = i386_trunc_page( pt);
+ pt = (pt - UPT_MIN_ADDRESS) / NBPG;
+ pt = ((vm_offset_t) pmap->pm_pdir[pt]) & PG_FRAME;
+ return PHYS_TO_VM_PAGE(pt);
+}
+
+/*
+ * Wire a page table page
+ */
+inline void
+pmap_use_pt(pmap, va)
pmap_t pmap;
vm_offset_t va;
- int use;
{
- vm_offset_t pt, pa;
- pv_entry_t pv;
- vm_page_t m;
+ vm_offset_t pt;
- if (va >= VM_MAX_ADDRESS)
+ if (va >= VM_MAX_ADDRESS || !pmap_initialized)
return;
- pt = i386_trunc_page(vtopte(va));
- pa = pmap_extract(pmap, pt);
- if (pa == 0) {
- printf("Warning pmap_use_pt pte paging failure\n");
- }
- if (!pa || !pmap_is_managed(pa))
- return;
- pv = pa_to_pvh(pa);
-
- m = PHYS_TO_VM_PAGE(pa);
- if (use) {
- vm_page_wire(m);
- } else {
- vm_page_unwire(m);
- }
+ pt = (vm_offset_t) vtopte(va);
+ vm_page_hold( pmap_pte_vm_page(pmap, pt));
+}
+
+/*
+ * Unwire a page table page
+ */
+inline void
+pmap_unuse_pt(pmap, va)
+ pmap_t pmap;
+ vm_offset_t va;
+{
+ vm_offset_t pt;
+
+ if (va >= VM_MAX_ADDRESS || !pmap_initialized)
+ return;
+
+ pt = (vm_offset_t) vtopte(va);
+ vm_page_unhold( pmap_pte_vm_page(pmap, pt));
}
/* [ macro again?, should I force kstack into user map here? -wfj ] */
@@ -370,7 +335,7 @@ pmap_bootstrap(firstaddr, loadaddr)
{
#if BSDVM_COMPAT
vm_offset_t va;
- struct pte *pte;
+ pt_entry_t *pte;
#endif
extern int IdlePTD;
@@ -436,6 +401,8 @@ pmap_bootstrap(firstaddr, loadaddr)
* Initialize the pmap module.
* Called by vm_init, to initialize any structures that the pmap
* system needs to map virtual memory.
+ * pmap_init has been enhanced to support in a fairly consistant
+ * way, discontiguous physical memory.
*/
void
pmap_init(phys_start, phys_end)
@@ -538,12 +505,7 @@ pmap_create(size)
if (size)
return(NULL);
- /* XXX: is it ok to wait here? */
pmap = (pmap_t) malloc(sizeof *pmap, M_VMPMAP, M_WAITOK);
-#ifdef notifwewait
- if (pmap == NULL)
- panic("pmap_create: cannot allocate a pmap");
-#endif
bzero(pmap, sizeof(*pmap));
pmap_pinit(pmap);
return (pmap);
@@ -590,7 +552,7 @@ pmap_pinit(pmap)
/* install self-referential address mapping entry */
*(int *)(pmap->pm_pdir+PTDPTDI) =
- ((int)pmap_extract(kernel_pmap, (vm_offset_t)pmap->pm_pdir)) | PG_V | PG_KW;
+ ((int)pmap_kextract((vm_offset_t)pmap->pm_pdir)) | PG_V | PG_KW;
pmap->pm_count = 1;
simple_lock_init(&pmap->pm_lock);
@@ -698,6 +660,11 @@ get_pv_entry()
return tmp;
}
+/*
+ * this *strange* allocation routine *statistically* eliminates the
+ * *possibility* of a malloc failure (*FATAL*) for a pv_entry_t data structure.
+ * also -- this code is MUCH MUCH faster than the malloc equiv...
+ */
void
pmap_alloc_pv_entry()
{
@@ -755,7 +722,7 @@ pmap_alloc_pv_entry()
/*
* init the pv_entry allocation system
*/
-#define PVSPERPAGE 16
+#define PVSPERPAGE 64
void
init_pv_entries(npg)
int npg;
@@ -778,15 +745,13 @@ get_pt_entry(pmap)
pmap_t pmap;
{
pt_entry_t *ptp;
+ vm_offset_t frame = (int) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
/* are we current address space or kernel? */
- if (pmap->pm_pdir[PTDPTDI].pd_pfnum == PTDpde.pd_pfnum
- || pmap == kernel_pmap)
+ if (pmap == kernel_pmap || frame == ((int) PTDpde & PG_FRAME)) {
ptp=PTmap;
-
/* otherwise, we are alternate address space */
- else {
- if (pmap->pm_pdir[PTDPTDI].pd_pfnum
- != APTDpde.pd_pfnum) {
+ } else {
+ if ( frame != ((int) APTDpde & PG_FRAME)) {
APTDpde = pmap->pm_pdir[PTDPTDI];
tlbflush();
}
@@ -808,9 +773,9 @@ pmap_remove_entry(pmap, pv, va)
vm_offset_t va;
{
pv_entry_t npv;
- int s;
int wired;
- s = splhigh();
+ int s;
+ s = splimp();
if (pmap == pv->pv_pmap && va == pv->pv_va) {
npv = pv->pv_next;
if (npv) {
@@ -849,121 +814,144 @@ pmap_remove(pmap, sva, eva)
register pt_entry_t *ptp,*ptq;
vm_offset_t pa;
register pv_entry_t pv;
- vm_offset_t asva, va;
+ vm_offset_t va;
vm_page_t m;
- int oldpte;
+ pt_entry_t oldpte;
if (pmap == NULL)
return;
ptp = get_pt_entry(pmap);
+/*
+ * special handling of removing one page. a very
+ * common operation and easy to short circuit some
+ * code.
+ */
+ if( (sva + NBPG) == eva) {
+
+ if( *pmap_pde( pmap, sva) == 0)
+ return;
+
+ ptq = ptp + i386_btop(sva);
+
+ if( !*ptq)
+ return;
+ /*
+ * Update statistics
+ */
+ if (pmap_pte_w(ptq))
+ pmap->pm_stats.wired_count--;
+ pmap->pm_stats.resident_count--;
+
+ pa = pmap_pte_pa(ptq);
+ oldpte = *ptq;
+ *ptq = 0;
+
+ if (pmap_is_managed(pa)) {
+ if ((((int) oldpte & PG_M) && (sva < USRSTACK || sva > UPT_MAX_ADDRESS))
+ || (sva >= USRSTACK && sva < USRSTACK+(UPAGES*NBPG))) {
+ if (sva < pager_sva || sva >= pager_eva) {
+ m = PHYS_TO_VM_PAGE(pa);
+ m->flags &= ~PG_CLEAN;
+ }
+ }
+
+ pv = pa_to_pvh(pa);
+ pmap_remove_entry(pmap, pv, sva);
+ pmap_unuse_pt(pmap, sva);
+ }
+ tlbflush();
+ return;
+ }
- /* this is essential since we must check the PDE(sva) for precense */
- while (sva <= eva && !pmap_pde_v(pmap_pde(pmap, sva)))
- sva = (sva & PD_MASK) + (1<<PD_SHIFT);
sva = i386_btop(sva);
eva = i386_btop(eva);
- for (; sva < eva; sva++) {
+ while (sva < eva) {
/*
* Weed out invalid mappings.
* Note: we assume that the page directory table is
* always allocated, and in kernel virtual.
*/
- if (!pmap_pde_v(pmap_pde(pmap, i386_ptob(sva))))
- {
+ if ( *pmap_pde(pmap, i386_ptob(sva)) == 0 ) {
/* We can race ahead here, straight to next pde.. */
- sva = sva & ~((NBPG/PTESIZE) - 1);
- sva = sva + NBPG/PTESIZE - 1;
+ nextpde:
+ sva = ((sva + NPTEPG) & ~(NPTEPG - 1));
continue;
- }
+ }
- ptq=ptp+sva;
-
+ ptq = ptp + sva;
/*
- * search for page table entries
+ * search for page table entries, use string operations
+ * that are much faster than
+ * explicitly scanning when page tables are not fully
+ * populated.
*/
- if (!pmap_pte_v(ptq)) {
- vm_offset_t nscan = ((sva + (NBPG/PTESIZE)) & ~((NBPG/PTESIZE) - 1)) - sva;
+ if ( *ptq == 0) {
+ vm_offset_t pdnxt = ((sva + NPTEPG) & ~(NPTEPG - 1));
+ vm_offset_t nscan = pdnxt - sva;
+ int found = 0;
+
if ((nscan + sva) > eva)
nscan = eva - sva;
- if (nscan) {
- int found;
-
- asm("xorl %%eax,%%eax;cld;repe;scasl;jz 1f;incl %%eax;1:;"
- :"=D"(ptq),"=a"(found)
- :"c"(nscan),"0"(ptq)
- :"cx");
- if (found)
- ptq -= 1;
+ asm("xorl %%eax,%%eax;cld;repe;scasl;jz 1f;incl %%eax;1:;"
+ :"=D"(ptq),"=a"(found)
+ :"c"(nscan),"0"(ptq)
+ :"cx");
- sva = ptq - ptp;
+ if( !found) {
+ sva = pdnxt;
+ continue;
}
- if (sva >= eva)
- goto endofloop;
- }
-
-
- if (!(sva & 0x3ff)) /* Only check once in a while */
- {
- if (!pmap_pde_v(pmap_pde(pmap, i386_ptob(sva)))) {
- /* We can race ahead here, straight to next pde.. */
- sva = sva & ~((NBPG/PTESIZE) - 1);
- sva = sva + NBPG/PTESIZE - 1;
- continue;
- }
- }
+ ptq -= 1;
- if (!pmap_pte_v(ptq))
- continue;
+ sva = ptq - ptp;
+ }
/*
* Update statistics
*/
- if (pmap_pte_w(ptq))
+ oldpte = *ptq;
+ if (((int)oldpte) & PG_W)
pmap->pm_stats.wired_count--;
pmap->pm_stats.resident_count--;
- pa = pmap_pte_pa(ptq);
- oldpte = *(int *) ptq;
-
/*
* Invalidate the PTEs.
* XXX: should cluster them up and invalidate as many
* as possible at once.
*/
- *(int *)ptq = 0;
+ *ptq = 0;
+
+ va = i386_ptob(sva);
/*
* Remove from the PV table (raise IPL since we
* may be called at interrupt time).
*/
- if (!pmap_is_managed(pa))
+ pa = ((int)oldpte) & PG_FRAME;
+ if (!pmap_is_managed(pa)) {
+ ++sva;
continue;
+ }
- va = i386_ptob(sva);
-
- if (((oldpte & PG_M) && (va < USRSTACK || va > UPT_MAX_ADDRESS))
+ if ((((int) oldpte & PG_M) && (va < USRSTACK || va > UPT_MAX_ADDRESS))
|| (va >= USRSTACK && va < USRSTACK+(UPAGES*NBPG))) {
- /*
- * don't update the dirty bit for pager mappings
- */
- if( va < pager_sva || va >= pager_eva) {
+ if (va < pager_sva || va >= pager_eva) {
m = PHYS_TO_VM_PAGE(pa);
m->flags &= ~PG_CLEAN;
}
}
pv = pa_to_pvh(pa);
- asva = i386_ptob(sva);
- pmap_remove_entry(pmap, pv, asva);
- pmap_use_pt(pmap, asva, 0);
+ pmap_remove_entry(pmap, pv, va);
+ pmap_unuse_pt(pmap, va);
+ ++sva;
}
-endofloop:
tlbflush();
}
@@ -973,6 +961,11 @@ endofloop:
* Removes this physical page from
* all physical maps in which it resides.
* Reflects back modify bits to the pager.
+ *
+ * Notes:
+ * Original versions of this routine were very
+ * inefficient because they iteratively called
+ * pmap_remove (slow...)
*/
void
pmap_remove_all(pa)
@@ -1004,21 +997,22 @@ pmap_remove_all(pa)
pte = ptp + va;
if (pmap_pte_w(pte))
pmap->pm_stats.wired_count--;
- if (pmap_pte_v(pte))
+ if ( *pte)
pmap->pm_stats.resident_count--;
- if (((*(int *)pte & PG_M) && (pv->pv_va < USRSTACK || pv->pv_va > UPT_MAX_ADDRESS))
+ /*
+ * update the vm_page_t clean bit
+ */
+ if ( (m->flags & PG_CLEAN) &&
+ ((((int) *pte) & PG_M) && (pv->pv_va < USRSTACK || pv->pv_va > UPT_MAX_ADDRESS))
|| (pv->pv_va >= USRSTACK && pv->pv_va < USRSTACK+(UPAGES*NBPG))) {
- /*
- * don't update the dirty bit for pager mappings
- */
- if( pv->pv_va < pager_sva || pv->pv_va >= pager_eva) {
+ if (pv->pv_va < pager_sva || pv->pv_va >= pager_eva) {
m->flags &= ~PG_CLEAN;
}
}
- *(int *)pte = 0;
- pmap_use_pt(pmap, pv->pv_va, 0);
+ *pte = 0;
+ pmap_unuse_pt(pmap, pv->pv_va);
npv = pv->pv_next;
if (npv) {
@@ -1027,10 +1021,8 @@ pmap_remove_all(pa)
} else {
pv->pv_pmap = NULL;
}
-
}
splx(s);
-
tlbflush();
}
@@ -1049,7 +1041,6 @@ pmap_protect(pmap, sva, eva, prot)
register vm_offset_t va;
int i386prot;
register pt_entry_t *ptp;
- int reqactivate = 0;
int evap = i386_btop(eva);
int s;
@@ -1065,70 +1056,62 @@ pmap_protect(pmap, sva, eva, prot)
ptp = get_pt_entry(pmap);
- for (va = sva; va < eva; va += PAGE_SIZE) {
+ va = sva;
+ while (va < eva) {
+ int found=0;
+ int svap;
+ vm_offset_t nscan;
/*
* Page table page is not allocated.
* Skip it, we don't want to force allocation
* of unnecessary PTE pages just to set the protection.
*/
- if (!pmap_pde_v(pmap_pde(pmap, va))) {
+ if (! *pmap_pde(pmap, va)) {
/* XXX: avoid address wrap around */
+nextpde:
if (va >= i386_trunc_pdr((vm_offset_t)-1))
break;
- va = i386_round_pdr(va + PAGE_SIZE) - PAGE_SIZE;
+ va = i386_round_pdr(va + PAGE_SIZE);
continue;
}
pte = ptp + i386_btop(va);
+ if( *pte == 0) {
/*
* scan for a non-empty pte
*/
- {
- int found=0;
- int svap = pte - ptp;
- vm_offset_t nscan =
- ((svap + (NBPG/PTESIZE)) & ~((NBPG/PTESIZE) - 1)) - svap;
+ svap = pte - ptp;
+ nscan = ((svap + NPTEPG) & ~(NPTEPG - 1)) - svap;
+
if (nscan + svap > evap)
nscan = evap - svap;
- if (nscan) {
+
+ found = 0;
+ if (nscan)
asm("xorl %%eax,%%eax;cld;repe;scasl;jz 1f;incl %%eax;1:;"
:"=D"(pte),"=a"(found)
:"c"(nscan),"0"(pte):"cx");
- pte -= 1;
- svap = pte - ptp;
+ if( !found)
+ goto nextpde;
+
+ pte -= 1;
+ svap = pte - ptp;
- }
- if (svap >= evap)
- goto endofloop;
va = i386_ptob(svap);
- if (!found)
- continue;
}
- /*
- * Page not valid. Again, skip it.
- * Should we do this? Or set protection anyway?
- */
- if (!pmap_pte_v(pte))
- continue;
-
i386prot = pte_prot(pmap, prot);
-
- if (va < UPT_MIN_ADDRESS)
+ if (va < UPT_MAX_ADDRESS) {
i386prot |= PG_u;
- else if (va < UPT_MAX_ADDRESS)
- i386prot |= PG_u | PG_RW;
-
- if (i386prot != pte->pg_prot) {
- reqactivate = 1;
- pmap_pte_set_prot(pte, i386prot);
+ if( va >= UPT_MIN_ADDRESS)
+ i386prot |= PG_RW;
}
+ pmap_pte_set_prot(pte, i386prot);
+ va += PAGE_SIZE;
}
-endofloop:
- if (reqactivate)
- tlbflush();
+ tlbflush();
}
/*
@@ -1152,10 +1135,9 @@ pmap_enter(pmap, va, pa, prot, wired)
boolean_t wired;
{
register pt_entry_t *pte;
- register int npte;
+ register pt_entry_t npte;
vm_offset_t opa;
- boolean_t cacheable = TRUE;
- boolean_t checkpv = TRUE;
+ int cacheable=1;
if (pmap == NULL)
return;
@@ -1167,7 +1149,7 @@ pmap_enter(pmap, va, pa, prot, wired)
/*
* Page Directory table entry not valid, we need a new PT page
*/
- if (!pmap_pde_v(pmap_pde(pmap, va))) {
+ if ( *pmap_pde(pmap, va) == 0) {
pg("ptdi %x, va %x", pmap->pm_pdir[PTDPTDI], va);
}
@@ -1211,7 +1193,7 @@ pmap_enter(pmap, va, pa, prot, wired)
int s;
pv = pa_to_pvh(pa);
- s = splhigh();
+ s = splimp();
/*
* No entries yet, use header as the first entry
*/
@@ -1232,11 +1214,12 @@ pmap_enter(pmap, va, pa, prot, wired)
pv->pv_next = npv;
}
splx(s);
+ cacheable = 1;
} else {
- cacheable = FALSE;
+ cacheable = 0;
}
- pmap_use_pt(pmap, va, 1);
+ pmap_use_pt(pmap, va);
/*
* Increment counters
@@ -1249,11 +1232,12 @@ validate:
/*
* Now validate mapping with desired protection/wiring.
*/
- npte = (pa & PG_FRAME) | pte_prot(pmap, prot) | PG_V;
-
- if (!cacheable) {
- npte |= PG_N;
- }
+ npte = (pt_entry_t) ( (int) (pa | pte_prot(pmap, prot) | PG_V));
+ /*
+ * for correctness:
+ */
+ if( !cacheable)
+ (int) npte |= PG_N;
/*
* When forking (copy-on-write, etc):
@@ -1269,43 +1253,244 @@ validate:
* used (referenced) bits.
*/
if (pa == opa)
- npte |= *(int *)pte & (PG_M|PG_U);
+ (int) npte |= (int) *pte & (PG_M|PG_U);
+
if (wired)
- npte |= PG_W;
+ (int) npte |= PG_W;
if (va < UPT_MIN_ADDRESS)
- npte |= PG_u;
+ (int) npte |= PG_u;
else if (va < UPT_MAX_ADDRESS)
- npte |= PG_u | PG_RW;
+ (int) npte |= PG_u | PG_RW;
- if (npte != *(int *)pte) {
- *(int *)pte = npte;
+ if( *pte != npte) {
+ *pte = npte;
tlbflush();
}
}
/*
- * pmap_page_protect:
- *
- * Lower the permission for all mappings to a given page.
+ * add a wired page to the kva
*/
void
-pmap_page_protect(phys, prot)
- vm_offset_t phys;
- vm_prot_t prot;
+pmap_kenter(va, pa)
+ vm_offset_t va;
+ register vm_offset_t pa;
{
- void pmap_copy_on_write();
- switch (prot) {
- case VM_PROT_READ:
- case VM_PROT_READ|VM_PROT_EXECUTE:
- pmap_copy_on_write(phys);
- break;
- case VM_PROT_ALL:
- break;
- default:
- pmap_remove_all(phys);
- break;
- }
+ register pt_entry_t *pte;
+ register pv_entry_t pv, npv;
+ vm_offset_t opa;
+ int s;
+
+ /*
+ * Enter on the PV list if part of our managed memory
+ * Note that we raise IPL while manipulating pv_table
+ * since pmap_enter can be called at interrupt time.
+ */
+
+ pte = vtopte(va);
+
+ opa = pmap_pte_pa(pte);
+ /*
+ * Mapping has not changed, must be protection or wiring change.
+ */
+ if (opa == pa) {
+ /*
+ * Wiring change, just update stats.
+ * We don't worry about wiring PT pages as they remain
+ * resident as long as there are valid mappings in them.
+ * Hence, if a user page is wired, the PT page will be also.
+ */
+ if (!pmap_pte_w(pte)) {
+ kernel_pmap->pm_stats.wired_count++;
+ }
+ goto validate;
+ }
+
+ if (opa) {
+ pmap_remove(kernel_pmap, va, va + PAGE_SIZE);
+ }
+
+ pv = pa_to_pvh(pa);
+ s = splimp();
+ /*
+ * No entries yet, use header as the first entry
+ */
+ if (pv->pv_pmap == NULL) {
+ pv->pv_va = va;
+ pv->pv_pmap = kernel_pmap;
+ pv->pv_next = NULL;
+ }
+ /*
+ * There is at least one other VA mapping this page.
+ * Place this entry after the header.
+ */
+ else {
+ npv = get_pv_entry();
+ npv->pv_va = va;
+ npv->pv_pmap = kernel_pmap;
+ npv->pv_next = pv->pv_next;
+ pv->pv_next = npv;
+ }
+ splx(s);
+
+ /*
+ * Increment counters
+ */
+ kernel_pmap->pm_stats.resident_count++;
+
+validate:
+
+ /*
+ * Now validate mapping with desired protection/wiring.
+ */
+ *pte = (pt_entry_t) ( (int) (pa | PG_RW | PG_V | PG_W));
+}
+
+/*
+ * this code makes some *MAJOR* assumptions:
+ * 1. Current pmap & pmap exists.
+ * 2. Not wired.
+ * 3. Read access.
+ * 4. No page table pages.
+ * 5. Tlbflush is deferred to calling procedure.
+ * 6. Page IS managed.
+ * but is *MUCH* faster than pmap_enter...
+ */
+
+static inline void
+pmap_enter_quick(pmap, va, pa)
+ register pmap_t pmap;
+ vm_offset_t va;
+ register vm_offset_t pa;
+{
+ register pt_entry_t *pte;
+ register pv_entry_t pv, npv;
+ int s;
+
+ /*
+ * Enter on the PV list if part of our managed memory
+ * Note that we raise IPL while manipulating pv_table
+ * since pmap_enter can be called at interrupt time.
+ */
+
+ pte = vtopte(va);
+ if (pmap_pte_pa(pte)) {
+ pmap_remove(pmap, va, va + PAGE_SIZE);
+ }
+
+ pv = pa_to_pvh(pa);
+ s = splimp();
+ /*
+ * No entries yet, use header as the first entry
+ */
+ if (pv->pv_pmap == NULL) {
+ pv->pv_va = va;
+ pv->pv_pmap = pmap;
+ pv->pv_next = NULL;
+ }
+ /*
+ * There is at least one other VA mapping this page.
+ * Place this entry after the header.
+ */
+ else {
+ npv = get_pv_entry();
+ npv->pv_va = va;
+ npv->pv_pmap = pmap;
+ npv->pv_next = pv->pv_next;
+ pv->pv_next = npv;
+ }
+ splx(s);
+
+ pmap_use_pt(pmap, va);
+
+ /*
+ * Increment counters
+ */
+ pmap->pm_stats.resident_count++;
+
+validate:
+
+ /*
+ * Now validate mapping with desired protection/wiring.
+ */
+ *pte = (pt_entry_t) ( (int) (pa | PG_RO | PG_V | PG_u));
+}
+
+/*
+ * pmap_object_init_pt preloads the ptes for a given object
+ * into the specified pmap. This eliminates the blast of soft
+ * faults on process startup and immediately after an mmap.
+ */
+void
+pmap_object_init_pt(pmap, addr, object, offset, size)
+ pmap_t pmap;
+ vm_offset_t addr;
+ vm_object_t object;
+ vm_offset_t offset;
+ vm_offset_t size;
+{
+
+ vm_offset_t tmpoff;
+ vm_page_t p;
+ int s;
+ vm_offset_t v, lastv=0;
+ pt_entry_t pte;
+ extern vm_map_t kernel_map;
+ vm_offset_t objbytes;
+
+ if (!pmap)
+ return;
+
+ /*
+ * if we are processing a major portion of the object, then
+ * scan the entire thing.
+ */
+ if( size > object->size / 2) {
+ objbytes = size;
+ p = (vm_page_t) queue_first(&object->memq);
+ while (!queue_end(&object->memq, (queue_entry_t) p) && objbytes != 0) {
+ tmpoff = p->offset;
+ if( tmpoff < offset) {
+ p = (vm_page_t) queue_next(&p->listq);
+ continue;
+ }
+ tmpoff -= offset;
+ if( tmpoff >= size) {
+ p = (vm_page_t) queue_next(&p->listq);
+ continue;
+ }
+
+ if ((p->flags & (PG_BUSY|PG_FICTITIOUS)) == 0 ) {
+ vm_page_hold(p);
+ v = i386_trunc_page(((vm_offset_t)vtopte( addr+tmpoff)));
+ /* a fault might occur here */
+ *(volatile char *)v += 0;
+ vm_page_unhold(p);
+ pmap_enter_quick(pmap, addr+tmpoff, VM_PAGE_TO_PHYS(p));
+ }
+ p = (vm_page_t) queue_next(&p->listq);
+ objbytes -= NBPG;
+ }
+ } else {
+ /*
+ * else lookup the pages one-by-one.
+ */
+ for(tmpoff = 0; tmpoff < size; tmpoff += NBPG) {
+ if( p = vm_page_lookup(object, tmpoff + offset)) {
+ if( (p->flags & (PG_BUSY|PG_FICTITIOUS)) == 0) {
+ vm_page_hold(p);
+ v = i386_trunc_page(((vm_offset_t)vtopte( addr+tmpoff)));
+ /* a fault might occur here */
+ *(volatile char *)v += 0;
+ vm_page_unhold(p);
+ pmap_enter_quick(pmap, addr+tmpoff, VM_PAGE_TO_PHYS(p));
+ }
+ }
+ }
+ }
+
+ tlbflush();
}
/*
@@ -1343,7 +1528,7 @@ pmap_change_wiring(pmap, va, wired)
* been changed by the kernel
*/
if (!wired)
- pmap_pte_m(pte) = 1;
+ (int) *pte |= PG_M;
}
@@ -1357,14 +1542,12 @@ pmap_change_wiring(pmap, va, wired)
*/
void
pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
- pmap_t dst_pmap;
- pmap_t src_pmap;
+ pmap_t dst_pmap, src_pmap;
vm_offset_t dst_addr;
vm_size_t len;
vm_offset_t src_addr;
{
}
-
/*
* Require that all active physical maps contain no
* incorrect entries NOW. [This update includes
@@ -1450,20 +1633,23 @@ pmap_pageable(pmap, sva, eva, pageable)
{
}
+/*
+ * this routine returns true if a physical page resides
+ * in the given pmap.
+ */
boolean_t
pmap_page_exists(pmap, pa)
pmap_t pmap;
vm_offset_t pa;
{
register pv_entry_t pv;
- register int *pte;
int s;
if (!pmap_is_managed(pa))
return FALSE;
pv = pa_to_pvh(pa);
- s = splhigh();
+ s = splimp();
/*
* Not found, check current mappings returning
@@ -1481,20 +1667,25 @@ pmap_page_exists(pmap, pa)
return(FALSE);
}
+/*
+ * pmap_testbit tests bits in pte's
+ * note that the testbit/changebit routines are inline,
+ * and a lot of things compile-time evaluate.
+ */
static inline boolean_t
pmap_testbit(pa, bit)
register vm_offset_t pa;
int bit;
{
register pv_entry_t pv;
- register int *pte;
+ pt_entry_t *pte;
int s;
if (!pmap_is_managed(pa))
return FALSE;
pv = pa_to_pvh(pa);
- s = splhigh();
+ s = splimp();
/*
* Not found, check current mappings returning
@@ -1502,8 +1693,21 @@ pmap_testbit(pa, bit)
*/
if (pv->pv_pmap != NULL) {
for (; pv; pv = pv->pv_next) {
+ /*
+ * if the bit being tested is the modified bit,
+ * then mark UPAGES as always modified, and
+ * ptes as never modified.
+ */
+ if (bit & PG_U ) {
+ if ((pv->pv_va >= pager_sva) && (pv->pv_va < pager_eva)) {
+ continue;
+ }
+ }
if (bit & PG_M ) {
if (pv->pv_va >= USRSTACK) {
+ if (pv->pv_va >= pager_sva && pv->pv_va < pager_eva) {
+ continue;
+ }
if (pv->pv_va < USRSTACK+(UPAGES*NBPG)) {
splx(s);
return TRUE;
@@ -1514,8 +1718,8 @@ pmap_testbit(pa, bit)
}
}
}
- pte = (int *) pmap_pte(pv->pv_pmap, pv->pv_va);
- if (*pte & bit) {
+ pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+ if ((int) *pte & bit) {
splx(s);
return TRUE;
}
@@ -1525,6 +1729,9 @@ pmap_testbit(pa, bit)
return(FALSE);
}
+/*
+ * this routine is used to modify bits in ptes
+ */
static inline void
pmap_changebit(pa, bit, setem)
vm_offset_t pa;
@@ -1532,16 +1739,15 @@ pmap_changebit(pa, bit, setem)
boolean_t setem;
{
register pv_entry_t pv;
- register int *pte, npte;
+ register pt_entry_t *pte, npte;
vm_offset_t va;
int s;
- int reqactivate = 0;
if (!pmap_is_managed(pa))
return;
pv = pa_to_pvh(pa);
- s = splhigh();
+ s = splimp();
/*
* Loop over all current mappings setting/clearing as appropos
@@ -1551,34 +1757,47 @@ pmap_changebit(pa, bit, setem)
for (; pv; pv = pv->pv_next) {
va = pv->pv_va;
- /*
- * XXX don't write protect pager mappings
- */
- if (!setem && (bit == PG_RW)) {
- extern vm_offset_t pager_sva, pager_eva;
-
- if (va >= pager_sva && va < pager_eva)
- continue;
- }
+ /*
+ * don't write protect pager mappings
+ */
+ if (!setem && (bit == PG_RW)) {
+ if (va >= pager_sva && va < pager_eva)
+ continue;
+ }
- pte = (int *) pmap_pte(pv->pv_pmap, va);
+ pte = pmap_pte(pv->pv_pmap, va);
if (setem)
- npte = *pte | bit;
+ (int) npte = (int) *pte | bit;
else
- npte = *pte & ~bit;
- if (*pte != npte) {
- *pte = npte;
- tlbflush();
- }
+ (int) npte = (int) *pte & ~bit;
+ *pte = npte;
}
}
splx(s);
+ tlbflush();
}
/*
- * Clear the modify bits on the specified physical page.
+ * pmap_page_protect:
+ *
+ * Lower the permission for all mappings to a given page.
*/
+void
+pmap_page_protect(phys, prot)
+ vm_offset_t phys;
+ vm_prot_t prot;
+{
+ if ((prot & VM_PROT_WRITE) == 0) {
+ if (prot & (VM_PROT_READ | VM_PROT_EXECUTE))
+ pmap_changebit(phys, PG_RW, FALSE);
+ else
+ pmap_remove_all(phys);
+ }
+}
+/*
+ * Clear the modify bits on the specified physical page.
+ */
void
pmap_clear_modify(pa)
vm_offset_t pa;
@@ -1591,7 +1810,6 @@ pmap_clear_modify(pa)
*
* Clear the reference bit on the specified physical page.
*/
-
void
pmap_clear_reference(pa)
vm_offset_t pa;
@@ -1624,7 +1842,6 @@ boolean_t
pmap_is_modified(pa)
vm_offset_t pa;
{
-
return(pmap_testbit(pa, PG_M));
}
@@ -1680,32 +1897,17 @@ i386_protection_init()
}
#ifdef DEBUG
-void
-pmap_pvdump(pa)
- vm_offset_t pa;
-{
- register pv_entry_t pv;
-
- printf("pa %x", pa);
- for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next) {
- printf(" -> pmap %x, va %x, flags %x",
- pv->pv_pmap, pv->pv_va, pv->pv_flags);
- pads(pv->pv_pmap);
- }
- printf(" ");
-}
-
/* print address space of pmap*/
void
pads(pm)
pmap_t pm;
{
unsigned va, i, j;
- struct pte *ptep;
+ pt_entry_t *ptep;
if (pm == kernel_pmap) return;
for (i = 0; i < 1024; i++)
- if (pm->pm_pdir[i].pd_v)
+ if (pm->pm_pdir[i])
for (j = 0; j < 1024 ; j++) {
va = (i<<PD_SHIFT)+(j<<PG_SHIFT);
if (pm == kernel_pmap && va < KERNBASE)
@@ -1718,4 +1920,23 @@ pads(pm)
} ;
}
+
+void
+pmap_pvdump(pa)
+ vm_offset_t pa;
+{
+ register pv_entry_t pv;
+
+ printf("pa %x", pa);
+ for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next) {
+#ifdef used_to_be
+ printf(" -> pmap %x, va %x, flags %x",
+ pv->pv_pmap, pv->pv_va, pv->pv_flags);
+#endif
+ printf(" -> pmap %x, va %x",
+ pv->pv_pmap, pv->pv_va);
+ pads(pv->pv_pmap);
+ }
+ printf(" ");
+}
#endif
diff --git a/sys/i386/i386/random.s b/sys/i386/i386/random.s
new file mode 100644
index 000000000000..eab2f74475f5
--- /dev/null
+++ b/sys/i386/i386/random.s
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1990,1993 The 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: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Here is a very good random number generator. This implementation is
+ * based on ``Two Fast Implementations of the "Minimal Standard" Random
+ * Number Generator'', David G. Carta, Communications of the ACM, Jan 1990,
+ * Vol 33 No 1. Do NOT modify this code unless you have a very thorough
+ * understanding of the algorithm. It's trickier than you think. If
+ * you do change it, make sure that its 10,000'th invocation returns
+ * 1043618065.
+ *
+ * Here is easier-to-decipher pseudocode:
+ *
+ * p = (16807*seed)<30:0> # e.g., the low 31 bits of the product
+ * q = (16807*seed)<62:31> # e.g., the high 31 bits starting at bit 32
+ * if (p + q < 2^31)
+ * seed = p + q
+ * else
+ * seed = ((p + q) & (2^31 - 1)) + 1
+ * return (seed);
+ *
+ * The result is in (0,2^31), e.g., it's always positive.
+ */
+#include "asm.h"
+
+ .data
+randseed:
+ .word 1
+ .text
+ENTRY(random)
+ movl $16807,%eax
+ imull randseed
+ shll $1,%edx
+ movl %eax,%ecx
+ and $0x7fffffff,%eax
+ shrl $31,%ecx
+ orl %ecx,%edx
+ addl %edx,%eax
+ jge 1f
+ incl %eax
+1:
+ movl %eax,randseed
+ ret
diff --git a/sys/i386/i386/support.s b/sys/i386/i386/support.s
index 14808109213f..2f3aa9a10410 100644
--- a/sys/i386/i386/support.s
+++ b/sys/i386/i386/support.s
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: support.s,v 1.4 1994/02/01 04:09:07 davidg Exp $
+ * $Id: support.s,v 1.11 1994/06/11 02:30:05 davidg Exp $
*/
#include "assym.s" /* system definitions */
@@ -75,7 +75,7 @@ ENTRY(inw) /* val = inw(port) */
ENTRY(insb) /* insb(port, addr, cnt) */
pushl %edi
- movw 8(%esp),%dx
+ movl 8(%esp),%edx
movl 12(%esp),%edi
movl 16(%esp),%ecx
cld
@@ -88,7 +88,7 @@ ENTRY(insb) /* insb(port, addr, cnt) */
ENTRY(insw) /* insw(port, addr, cnt) */
pushl %edi
- movw 8(%esp),%dx
+ movl 8(%esp),%edx
movl 12(%esp),%edi
movl 16(%esp),%ecx
cld
@@ -99,6 +99,19 @@ ENTRY(insw) /* insw(port, addr, cnt) */
popl %edi
ret
+ENTRY(insl) /* insl(port, addr, cnt) */
+ pushl %edi
+ movl 8(%esp),%edx
+ movl 12(%esp),%edi
+ movl 16(%esp),%ecx
+ cld
+ rep
+ insl
+ NOP
+ movl %edi,%eax
+ popl %edi
+ ret
+
ENTRY(rtcin) /* rtcin(val) */
movl 4(%esp),%eax
outb %al,$0x70
@@ -124,7 +137,7 @@ ENTRY(outw) /* outw(port, val) */
ENTRY(outsb) /* outsb(port, addr, cnt) */
pushl %esi
- movw 8(%esp),%dx
+ movl 8(%esp),%edx
movl 12(%esp),%esi
movl 16(%esp),%ecx
cld
@@ -137,7 +150,7 @@ ENTRY(outsb) /* outsb(port, addr, cnt) */
ENTRY(outsw) /* outsw(port, addr, cnt) */
pushl %esi
- movw 8(%esp),%dx
+ movl 8(%esp),%edx
movl 12(%esp),%esi
movl 16(%esp),%ecx
cld
@@ -148,11 +161,36 @@ ENTRY(outsw) /* outsw(port, addr, cnt) */
popl %esi
ret
+ENTRY(outsl) /* outsl(port, addr, cnt) */
+ pushl %esi
+ movl 8(%esp),%edx
+ movl 12(%esp),%esi
+ movl 16(%esp),%ecx
+ cld
+ rep
+ outsl
+ NOP
+ movl %esi,%eax
+ popl %esi
+ ret
+
/*
* bcopy family
*/
-/* void bzero(void *base, u_int cnt) */
+
+/*
+ * void bzero(void *base, u_int cnt)
+ * Special code for I486 because stosl uses lots
+ * of clocks. Makes little or no difference on DX2 type
+ * machines, but stosl is about 1/2 as fast as
+ * memory moves on a standard DX !!!!!
+ */
ENTRY(bzero)
+#if defined(I486_CPU)
+ cmpl $CPUCLASS_486,_cpu_class
+ jz 1f
+#endif
+
pushl %edi
movl 8(%esp),%edi
movl 12(%esp),%ecx
@@ -168,6 +206,107 @@ ENTRY(bzero)
popl %edi
ret
+#if defined(I486_CPU)
+ SUPERALIGN_TEXT
+1:
+ movl 4(%esp),%edx
+ movl 8(%esp),%ecx
+ xorl %eax,%eax
+/
+/ do 64 byte chunks first
+/
+/ XXX this is probably over-unrolled at least for DX2's
+/
+2:
+ cmpl $64,%ecx
+ jb 3f
+ movl %eax,(%edx)
+ movl %eax,4(%edx)
+ movl %eax,8(%edx)
+ movl %eax,12(%edx)
+ movl %eax,16(%edx)
+ movl %eax,20(%edx)
+ movl %eax,24(%edx)
+ movl %eax,28(%edx)
+ movl %eax,32(%edx)
+ movl %eax,36(%edx)
+ movl %eax,40(%edx)
+ movl %eax,44(%edx)
+ movl %eax,48(%edx)
+ movl %eax,52(%edx)
+ movl %eax,56(%edx)
+ movl %eax,60(%edx)
+ addl $64,%edx
+ subl $64,%ecx
+ jnz 2b
+ ret
+
+/
+/ do 16 byte chunks
+/
+ SUPERALIGN_TEXT
+3:
+ cmpl $16,%ecx
+ jb 4f
+ movl %eax,(%edx)
+ movl %eax,4(%edx)
+ movl %eax,8(%edx)
+ movl %eax,12(%edx)
+ addl $16,%edx
+ subl $16,%ecx
+ jnz 3b
+ ret
+
+/
+/ do 4 byte chunks
+/
+ SUPERALIGN_TEXT
+4:
+ cmpl $4,%ecx
+ jb 5f
+ movl %eax,(%edx)
+ addl $4,%edx
+ subl $4,%ecx
+ jnz 4b
+ ret
+
+/
+/ do 1 byte chunks
+/ a jump table seems to be faster than a loop or more range reductions
+/
+/ XXX need a const section for non-text
+/
+ SUPERALIGN_TEXT
+jtab:
+ .long do0
+ .long do1
+ .long do2
+ .long do3
+
+ SUPERALIGN_TEXT
+5:
+ jmp jtab(,%ecx,4)
+
+ SUPERALIGN_TEXT
+do3:
+ movw %ax,(%edx)
+ movb %al,2(%edx)
+ ret
+
+ SUPERALIGN_TEXT
+do2:
+ movw %ax,(%edx)
+ ret
+
+ SUPERALIGN_TEXT
+do1:
+ movb %al,(%edx)
+
+ SUPERALIGN_TEXT
+do0:
+ ret
+#endif /* I486_CPU */
+
/* fillw(pat, base, cnt) */
ENTRY(fillw)
pushl %edi
@@ -182,7 +321,6 @@ ENTRY(fillw)
/* filli(pat, base, cnt) */
ENTRY(filli)
-filli:
pushl %edi
movl 8(%esp),%eax
movl 12(%esp),%edi
@@ -232,8 +370,8 @@ bcopyw:
movl 20(%esp),%ecx
cmpl %esi,%edi /* potentially overlapping? */
jnb 1f
- cld /* nope, copy forwards */
shrl $1,%ecx /* copy by 16-bit words */
+ cld /* nope, copy forwards */
rep
movsw
adc %ecx,%ecx /* any bytes left? */
@@ -247,10 +385,10 @@ bcopyw:
1:
addl %ecx,%edi /* copy backwards */
addl %ecx,%esi
- std
andl $1,%ecx /* any fractional bytes? */
decl %edi
decl %esi
+ std
rep
movsb
movl 20(%esp),%ecx /* copy remainder by 16-bit words */
@@ -269,7 +407,7 @@ ENTRY(bcopyx)
cmpl $2,%eax
je bcopyw /* not _bcopyw, to avoid multiple mcounts */
cmpl $4,%eax
- je bcopy
+ je bcopy /* XXX the shared ret's break mexitcount */
jmp bcopyb
/*
@@ -286,8 +424,8 @@ bcopy:
movl 20(%esp),%ecx
cmpl %esi,%edi /* potentially overlapping? */
jnb 1f
- cld /* nope, copy forwards */
shrl $2,%ecx /* copy by 32-bit words */
+ cld /* nope, copy forwards */
rep
movsl
movl 20(%esp),%ecx
@@ -302,10 +440,10 @@ bcopy:
1:
addl %ecx,%edi /* copy backwards */
addl %ecx,%esi
- std
andl $3,%ecx /* any fractional bytes? */
decl %edi
decl %esi
+ std
rep
movsb
movl 20(%esp),%ecx /* copy remainder by 32-bit words */
@@ -395,6 +533,12 @@ ENTRY(copyout) /* copyout(from_kernel, to_user, len) */
movl %edi,%eax
addl %ebx,%eax
jc copyout_fault
+/*
+ * XXX STOP USING VM_MAXUSER_ADDRESS.
+ * It is an end address, not a max, so every time it is used correctly it
+ * looks like there is an off by one error, and of course it caused an off
+ * by one error in several places.
+ */
cmpl $VM_MAXUSER_ADDRESS,%eax
ja copyout_fault
@@ -449,13 +593,13 @@ ENTRY(copyout) /* copyout(from_kernel, to_user, len) */
/* bcopy(%esi, %edi, %ebx) */
3:
- cld
movl %ebx,%ecx
shrl $2,%ecx
+ cld
rep
movsl
movb %bl,%cl
- andb $3,%cl /* XXX can we trust the rest of %ecx on clones? */
+ andb $3,%cl
rep
movsb
@@ -488,15 +632,22 @@ ENTRY(copyin)
movl 16(%esp),%edi /* caddr_t to */
movl 20(%esp),%ecx /* size_t len */
+ /*
+ * make sure address is valid
+ */
+ movl %esi,%edx
+ addl %ecx,%edx
+ jc copyin_fault
+ cmpl $VM_MAXUSER_ADDRESS,%edx
+ ja copyin_fault
+
movb %cl,%al
shrl $2,%ecx /* copy longword-wise */
cld
- gs
rep
movsl
movb %al,%cl
andb $3,%cl /* copy remaining bytes */
- gs
rep
movsb
@@ -517,39 +668,42 @@ copyin_fault:
ret
/*
- * fu{byte,sword,word} : fetch a byte(sword, word) from user memory
+ * fu{byte,sword,word} : fetch a byte (sword, word) from user memory
*/
ALTENTRY(fuiword)
ENTRY(fuword)
- movl __udatasel,%ax
- movl %ax,%gs
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
- movl 4(%esp),%edx
- gs
+ movl 4(%esp),%edx /* from */
+
+ cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */
+ ja fusufault
+
movl (%edx),%eax
movl $0,PCB_ONFAULT(%ecx)
ret
ENTRY(fusword)
- movl __udatasel,%ax
- movl %ax,%gs
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl 4(%esp),%edx
- gs
+
+ cmpl $VM_MAXUSER_ADDRESS-2,%edx
+ ja fusufault
+
movzwl (%edx),%eax
movl $0,PCB_ONFAULT(%ecx)
ret
ALTENTRY(fuibyte)
ENTRY(fubyte)
- movl __udatasel,%ax
- movl %ax,%gs
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl 4(%esp),%edx
- gs
+
+ cmpl $VM_MAXUSER_ADDRESS-1,%edx
+ ja fusufault
+
movzbl (%edx),%eax
movl $0,PCB_ONFAULT(%ecx)
ret
@@ -563,15 +717,10 @@ fusufault:
ret
/*
- * su{byte,sword,word}: write a byte(word, longword) to user memory
- */
-/*
- * we only have to set the right segment selector.
+ * su{byte,sword,word}: write a byte (word, longword) to user memory
*/
ALTENTRY(suiword)
ENTRY(suword)
- movl __udatasel,%ax
- movl %ax,%gs
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl 4(%esp),%edx
@@ -580,9 +729,10 @@ ENTRY(suword)
#if defined(I486_CPU) || defined(I586_CPU)
cmpl $CPUCLASS_386,_cpu_class
- jne 2f
+ jne 2f /* we only have to set the right segment selector */
#endif /* I486_CPU || I586_CPU */
+ /* XXX - page boundary crossing is still not handled */
movl %edx,%eax
shrl $IDXSHIFT,%edx
andb $0xfc,%dl
@@ -603,16 +753,16 @@ ENTRY(suword)
#endif
2:
+ cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address validity */
+ ja fusufault
+
movl 8(%esp),%eax
- gs
movl %eax,(%edx)
xorl %eax,%eax
movl %eax,PCB_ONFAULT(%ecx)
ret
ENTRY(susword)
- movl __udatasel,%eax
- movl %ax,%gs
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl 4(%esp),%edx
@@ -624,6 +774,7 @@ ENTRY(susword)
jne 2f
#endif /* I486_CPU || I586_CPU */
+ /* XXX - page boundary crossing is still not handled */
movl %edx,%eax
shrl $IDXSHIFT,%edx
andb $0xfc,%dl
@@ -644,8 +795,10 @@ ENTRY(susword)
#endif
2:
+ cmpl $VM_MAXUSER_ADDRESS-2,%edx /* verify address validity */
+ ja fusufault
+
movw 8(%esp),%ax
- gs
movw %ax,(%edx)
xorl %eax,%eax
movl %eax,PCB_ONFAULT(%ecx)
@@ -684,8 +837,10 @@ ENTRY(subyte)
#endif
2:
+ cmpl $VM_MAXUSER_ADDRESS-1,%edx /* verify address validity */
+ ja fusufault
+
movb 8(%esp),%al
- gs
movb %al,(%edx)
xorl %eax,%eax
movl %eax,PCB_ONFAULT(%ecx)
@@ -702,11 +857,12 @@ ENTRY(copyoutstr)
pushl %esi
pushl %edi
movl _curpcb,%ecx
- movl $cpystrflt,PCB_ONFAULT(%ecx)
+ movl $cpystrflt,PCB_ONFAULT(%ecx) /* XXX rename copyoutstr_fault */
movl 12(%esp),%esi /* %esi = from */
movl 16(%esp),%edi /* %edi = to */
movl 20(%esp),%edx /* %edx = maxlen */
+ cld
#if defined(I386_CPU)
@@ -721,8 +877,8 @@ ENTRY(copyoutstr)
* we look at a page at a time and the end address is on a page
* boundary.
*/
- cmpl $VM_MAXUSER_ADDRESS,%edi
- jae cpystrflt
+ cmpl $VM_MAXUSER_ADDRESS-1,%edi
+ ja cpystrflt
movl %edi,%eax
shrl $IDXSHIFT,%eax
@@ -736,6 +892,7 @@ ENTRY(copyoutstr)
pushl %edx
pushl %edi
call _trapwrite
+ cld
popl %edi
popl %edx
orl %eax,%eax
@@ -747,7 +904,7 @@ ENTRY(copyoutstr)
movl $NBPG,%ecx
subl %eax,%ecx /* ecx = NBPG - (src % NBPG) */
cmpl %ecx,%edx
- jge 3f
+ jae 3f
movl %edx,%ecx /* ecx = min(ecx, edx) */
3:
orl %ecx,%ecx
@@ -780,13 +937,11 @@ ENTRY(copyoutstr)
decl %edx
jz 2f
/*
- * gs override doesn't work for stosb. Use the same explicit check
- * as in copyout(). It's much slower now because it is per-char.
- * XXX - however, it would be faster to rewrite this function to use
+ * XXX - would be faster to rewrite this function to use
* strlen() and copyout().
*/
- cmpl $VM_MAXUSER_ADDRESS,%edi
- jae cpystrflt
+ cmpl $VM_MAXUSER_ADDRESS-1,%edi
+ ja cpystrflt
lodsb
stosb
@@ -805,6 +960,28 @@ ENTRY(copyoutstr)
#endif /* I486_CPU || I586_CPU */
/*
+ * This was split from copyinstr_fault mainly because pushing gs changes the
+ * stack offsets. It's better to have it separate for mcounting too.
+ */
+cpystrflt:
+ movl $EFAULT,%eax
+cpystrflt_x:
+ /* set *lencopied and return %eax */
+ movl _curpcb,%ecx
+ movl $0,PCB_ONFAULT(%ecx)
+ movl 20(%esp),%ecx
+ subl %edx,%ecx
+ movl 24(%esp),%edx
+ orl %edx,%edx
+ jz 1f
+ movl %ecx,(%edx)
+1:
+ popl %edi
+ popl %esi
+ ret
+
+
+/*
* copyinstr(from, to, maxlen, int *lencopied)
* copy a string from from to to, stop when a 0 character is reached.
* return ENAMETOOLONG if string is longer than maxlen, and
@@ -815,18 +992,24 @@ ENTRY(copyinstr)
pushl %esi
pushl %edi
movl _curpcb,%ecx
- movl $cpystrflt,PCB_ONFAULT(%ecx)
+ movl $copyinstr_fault,PCB_ONFAULT(%ecx)
movl 12(%esp),%esi /* %esi = from */
movl 16(%esp),%edi /* %edi = to */
movl 20(%esp),%edx /* %edx = maxlen */
+ /*
+ * XXX should avoid touching gs. Either copy the string in and
+ * check the bounds later or get its length and check the bounds
+ * and then use copyin().
+ */
+ pushl %gs
movl __udatasel,%eax
movl %ax,%gs
incl %edx
-
+ cld
1:
decl %edx
- jz 4f
+ jz 2f
gs
lodsb
stosb
@@ -836,26 +1019,27 @@ ENTRY(copyinstr)
/* Success -- 0 byte reached */
decl %edx
xorl %eax,%eax
- jmp 6f
-4:
+ jmp 3f
+2:
/* edx is zero -- return ENAMETOOLONG */
movl $ENAMETOOLONG,%eax
- jmp 6f
+ jmp 3f
-cpystrflt:
+ ALIGN_TEXT
+copyinstr_fault:
movl $EFAULT,%eax
-cpystrflt_x:
-6:
+3:
/* set *lencopied and return %eax */
movl _curpcb,%ecx
movl $0,PCB_ONFAULT(%ecx)
- movl 20(%esp),%ecx
+ movl 24(%esp),%ecx
subl %edx,%ecx
- movl 24(%esp),%edx
+ movl 28(%esp),%edx
orl %edx,%edx
- jz 7f
+ jz 4f
movl %ecx,(%edx)
-7:
+4:
+ popl %gs
popl %edi
popl %esi
ret
@@ -872,7 +1056,7 @@ ENTRY(copystr)
movl 16(%esp),%edi /* %edi = to */
movl 20(%esp),%edx /* %edx = maxlen */
incl %edx
-
+ cld
1:
decl %edx
jz 4f
@@ -971,15 +1155,6 @@ ENTRY(ssdtosd)
popl %ebx
ret
-#if 0
-/* tlbflush() */
-ENTRY(tlbflush)
- movl %cr3,%eax
- orl $I386_CR3PAT,%eax
- movl %eax,%cr3
- ret
-#endif
-
/* load_cr0(cr0) */
ENTRY(load_cr0)
movl 4(%esp),%eax
@@ -991,11 +1166,6 @@ ENTRY(rcr0)
movl %cr0,%eax
ret
-/* rcr2() */
-ENTRY(rcr2)
- movl %cr2,%eax
- ret
-
/* rcr3() */
ENTRY(rcr3)
movl %cr3,%eax
@@ -1037,4 +1207,3 @@ ENTRY(longjmp)
xorl %eax,%eax /* return(1); */
incl %eax
ret
-
diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s
index 0851bae3a001..f9d4f91c082c 100644
--- a/sys/i386/i386/swtch.s
+++ b/sys/i386/i386/swtch.s
@@ -33,15 +33,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: swtch.s,v 1.4 1994/01/31 10:26:59 davidg Exp $
+ * $Id: swtch.s,v 1.6 1994/04/20 07:06:18 davidg Exp $
*/
#include "npx.h" /* for NNPX */
#include "assym.s" /* for preprocessor defines */
#include "errno.h" /* for error codes */
-#include "i386/isa/debug.h" /* for SHOW macros */
#include "machine/asmacros.h" /* for miscellaneous assembly macros */
+#define LOCORE /* XXX inhibit C declarations */
+#include "machine/spl.h" /* for SWI_AST_MASK ... */
+
/*****************************************************************************/
/* Scheduling */
@@ -132,23 +134,31 @@ rem3: .asciz "remrq"
sw0: .asciz "swtch"
/*
- * When no processes are on the runq, Swtch branches to idle
+ * When no processes are on the runq, swtch() branches to _idle
* to wait for something to come ready.
*/
ALIGN_TEXT
-Idle:
+_idle:
+ MCOUNT
movl _IdlePTD,%ecx
movl %ecx,%cr3
movl $tmpstk-4,%esp
sti
- SHOW_STI
+
+ /*
+ * XXX callers of swtch() do a bogus splclock(). Locking should
+ * be left to swtch().
+ */
+ movl $SWI_AST_MASK,_cpl
+ testl $~SWI_AST_MASK,_ipending
+ je idle_loop
+ call _splz
ALIGN_TEXT
idle_loop:
- call _spl0
cli
cmpl $0,_whichqs
- jne sw1
+ jne sw1a
sti
hlt /* wait for interrupt */
jmp idle_loop
@@ -161,9 +171,7 @@ badsw:
/*
* Swtch()
*/
- SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
ENTRY(swtch)
-
incl _cnt+V_SWTCH
/* switch to new process. first, save context as needed */
@@ -208,14 +216,14 @@ ENTRY(swtch)
/* save is done, now choose a new process or idle */
sw1:
cli
- SHOW_CLI
+sw1a:
movl _whichqs,%edi
2:
/* XXX - bsf is sloow */
bsfl %edi,%eax /* find a full q */
- je Idle /* if none, idle */
+ je _idle /* if none, idle */
+
/* XX update whichqs? */
-swfnd:
btrl %eax,%edi /* clear q full status */
jnb 2b /* if it was clear, look for another */
movl %eax,%ebx /* save which one we are using */
@@ -296,7 +304,6 @@ swfnd:
*/
pushl PCB_IML(%edx)
sti
- SHOW_STI
#if 0
call _splx
#endif
@@ -312,7 +319,7 @@ ENTRY(mvesp)
movl %esp,%eax
ret
/*
- * struct proc *swtch_to_inactive(p) ; struct proc *p;
+ * struct proc *swtch_to_inactive(struct proc *p);
*
* At exit of a process, move off the address space of the
* process and onto a "safe" one. Then, on a temporary stack
@@ -327,6 +334,7 @@ ENTRY(swtch_to_inactive)
movl %ecx,%cr3 /* good bye address space */
#write buffer?
movl $tmpstk-4,%esp /* temporary stack, compensated for call */
+ MEXITCOUNT
jmp %edx /* return, execute remainder of cleanup */
/*
@@ -418,7 +426,7 @@ ENTRY(addupc)
movl 8(%ebp),%eax /* pc */
subl PR_OFF(%edx),%eax /* pc -= up->pr_off */
- jl L1 /* if (pc < 0) return */
+ jb L1 /* if (pc was < off) return */
shrl $1,%eax /* praddr = pc >> 1 */
imull PR_SCALE(%edx),%eax /* praddr *= up->pr_scale */
@@ -448,8 +456,3 @@ proffault:
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
leave
ret
-
-/* To be done: */
-ENTRY(astoff)
- ret
-
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 34a2993ba1e7..c21693c85990 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (C) 1994, David Greenman
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
@@ -34,11 +35,11 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.17 1994/02/08 09:26:01 davidg Exp $
+ * $Id: trap.c,v 1.27 1994/06/22 05:52:30 jkh Exp $
*/
/*
- * 386 Trap and System call handleing
+ * 386 Trap and System call handling
*/
#include "isa.h"
@@ -68,28 +69,13 @@
#include "machine/trap.h"
-#ifdef __GNUC__
-
-/*
- * The "r" contraint could be "rm" except for fatal bugs in gas. As usual,
- * we omit the size from the mov instruction to avoid nonfatal bugs in gas.
- */
-#define read_gs() ({ u_short gs; __asm("mov %%gs,%0" : "=r" (gs)); gs; })
-#define write_gs(newgs) __asm("mov %0,%%gs" : : "r" ((u_short) newgs))
-
-#else /* not __GNUC__ */
-
-u_short read_gs __P((void));
-void write_gs __P((/* promoted u_short */ int gs));
-
-#endif /* __GNUC__ */
+int trap_pfault __P((struct trapframe *, int));
+void trap_fatal __P((struct trapframe *));
extern int grow(struct proc *,int);
struct sysent sysent[];
int nsysent;
-extern short cpl;
-extern short netmask, ttymask, biomask;
#define MAX_TRAP_MSG 27
char *trap_msg[] = {
@@ -102,7 +88,7 @@ char *trap_msg[] = {
"arithmetic trap", /* 6 T_ARITHTRAP */
"system forced exception", /* 7 T_ASTFLT */
"segmentation (limit) fault", /* 8 T_SEGFLT */
- "protection fault", /* 9 T_PROTFLT */
+ "general protection fault", /* 9 T_PROTFLT */
"trace trap", /* 10 T_TRCTRAP */
"", /* 11 unused */
"page fault", /* 12 T_PAGEFLT */
@@ -123,15 +109,59 @@ char *trap_msg[] = {
"stack fault", /* 27 T_STKFLT */
};
-#define pde_v(v) (PTD[((v)>>PD_SHIFT)&1023].pd_v)
+static inline void
+userret(p, frame, osyst)
+ struct proc *p;
+ struct trapframe *frame;
+ struct timeval *osyst;
+{
+ int sig, s;
+
+ while (sig = CURSIG(p))
+ psig(sig);
+ p->p_pri = p->p_usrpri;
+ if (want_resched) {
+ /*
+ * Since we are curproc, clock will normally just change
+ * our priority without moving us from one queue to another
+ * (since the running process is not on a queue.)
+ * If that happend after we put ourselves on the run queue
+ * but before swtch()'ed, we might not be on the queue
+ * indicated by our priority.
+ */
+ s = splclock();
+ setrq(p);
+ p->p_stats->p_ru.ru_nivcsw++;
+ swtch();
+ splx(s);
+ while (sig = CURSIG(p))
+ psig(sig);
+ }
+ if (p->p_stats->p_prof.pr_scale) {
+ int ticks;
+ struct timeval *tv = &p->p_stime;
+
+ ticks = ((tv->tv_sec - osyst->tv_sec) * 1000 +
+ (tv->tv_usec - osyst->tv_usec) / 1000) / (tick / 1000);
+ if (ticks) {
+#ifdef PROFTIMER
+ extern int profscale;
+ addupc(frame->tf_eip, &p->p_stats->p_prof,
+ ticks * profscale);
+#else
+ addupc(frame->tf_eip, &p->p_stats->p_prof, ticks);
+#endif
+ }
+ }
+ curpri = p->p_pri;
+}
/*
* trap(frame):
- * Exception, fault, and trap interface to BSD kernel. This
- * common code is called from assembly language IDT gate entry
+ * Exception, fault, and trap interface to the FreeBSD kernel.
+ * This common code is called from assembly language IDT gate entry
* routines that prepare a suitable stack frame, and restore this
- * frame after the exception has been processed. Note that the
- * effect is as if the arguments were passed call by reference.
+ * frame after the exception has been processed.
*/
/*ARGSUSED*/
@@ -139,361 +169,369 @@ void
trap(frame)
struct trapframe frame;
{
- register int i;
- register struct proc *p = curproc;
+ struct proc *p = curproc;
struct timeval syst;
- int ucode, type, code, eva, fault_type;
+ int i = 0, ucode = 0, type, code, eva, fault_type;
frame.tf_eflags &= ~PSL_NT; /* clear nested trap XXX */
type = frame.tf_trapno;
+ code = frame.tf_err;
+
+ if (ISPL(frame.tf_cs) == SEL_UPL) {
+ /* user trap */
+
+ syst = p->p_stime;
+ p->p_regs = (int *)&frame;
+
+ switch (type) {
+ case T_RESADFLT: /* reserved addressing fault */
+ case T_PRIVINFLT: /* privileged instruction fault */
+ case T_RESOPFLT: /* reserved operand fault */
+ ucode = type;
+ i = SIGILL;
+ break;
+
+ case T_BPTFLT: /* bpt instruction fault */
+ case T_TRCTRAP: /* trace trap */
+ frame.tf_eflags &= ~PSL_T;
+ i = SIGTRAP;
+ break;
+
+ case T_ARITHTRAP: /* arithmetic trap */
+ ucode = code;
+ i = SIGFPE;
+ break;
+
+ case T_ASTFLT: /* Allow process switch */
+ astoff();
+ cnt.v_soft++;
+ if ((p->p_flag & SOWEUPC) && p->p_stats->p_prof.pr_scale) {
+ addupc(frame.tf_eip, &p->p_stats->p_prof, 1);
+ p->p_flag &= ~SOWEUPC;
+ }
+ goto out;
+
+ case T_PROTFLT: /* general protection fault */
+ case T_SEGNPFLT: /* segment not present fault */
+ case T_STKFLT: /* stack fault */
+ ucode = code + BUS_SEGM_FAULT ;
+ i = SIGBUS;
+ break;
+
+ case T_PAGEFLT: /* page fault */
+ i = trap_pfault(&frame, TRUE);
+
+ if (i == 0)
+ goto out;
+
+ ucode = T_PAGEFLT;
+ break;
+
+ case T_DIVIDE: /* integer divide fault */
+ ucode = FPE_INTDIV_TRAP;
+ i = SIGFPE;
+ break;
+
+#if NISA > 0
+ case T_NMI:
#if NDDB > 0
- if (curpcb && curpcb->pcb_onfault) {
- if (frame.tf_trapno == T_BPTFLT
- || frame.tf_trapno == T_TRCTRAP)
+ /* NMI can be hooked up to a pushbutton for debugging */
+ printf ("NMI ... going to debugger\n");
if (kdb_trap (type, 0, &frame))
return;
- }
#endif
-
- if (curpcb == 0 || curproc == 0)
- goto skiptoswitch;
- if (curpcb->pcb_onfault && frame.tf_trapno != T_PAGEFLT) {
- extern int _udatasel;
-
- if (read_gs() != (u_short) _udatasel)
- /*
- * Some user has corrupted %gs but we depend on it in
- * copyout() etc. Fix it up and retry.
- *
- * (We don't preserve %fs or %gs, so users can change
- * them to either _ucodesel, _udatasel or a not-present
- * selector, possibly ORed with 0 to 3, making them
- * volatile for other users. Not preserving them saves
- * time and doesn't lose functionality or open security
- * holes.)
- */
- write_gs(_udatasel);
- else
-copyfault:
- frame.tf_eip = (int)curpcb->pcb_onfault;
- return;
- }
+ /* machine/parity/power fail/"kitchen sink" faults */
+ if (isa_nmi(code) == 0) return;
+ /* FALL THROUGH */
+#endif
- syst = p->p_stime;
- if (ISPL(frame.tf_cs) == SEL_UPL) {
- type |= T_USER;
- p->p_regs = (int *)&frame;
- }
+ case T_OFLOW: /* integer overflow fault */
+ ucode = FPE_INTOVF_TRAP;
+ i = SIGFPE;
+ break;
-skiptoswitch:
- ucode=0;
- eva = rcr2();
- code = frame.tf_err;
+ case T_BOUND: /* bounds check fault */
+ ucode = FPE_SUBRNG_TRAP;
+ i = SIGFPE;
+ break;
- if ((type & ~T_USER) == T_PAGEFLT)
- goto pfault;
+ case T_DNA:
+#if NNPX > 0
+ /* if a transparent fault (due to context switch "late") */
+ if (npxdna())
+ return;
+#endif /* NNPX > 0 */
- switch (type) {
- case T_SEGNPFLT|T_USER:
- case T_STKFLT|T_USER:
- case T_PROTFLT|T_USER: /* protection fault */
- ucode = code + BUS_SEGM_FAULT ;
- i = SIGBUS;
- break;
+#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE)
+ i = math_emulate(&frame);
+ if (i == 0) {
+ if (!(frame.tf_eflags & PSL_T))
+ return;
+ frame.tf_eflags &= ~PSL_T;
+ i = SIGTRAP;
+ }
+ /* else ucode = emulator_only_knows() XXX */
+#else /* MATH_EMULATE || GPL_MATH_EMULATE */
+ i = SIGFPE;
+ ucode = FPE_FPU_NP_TRAP;
+#endif /* MATH_EMULATE || GPL_MATH_EMULATE */
+ break;
+
+ case T_FPOPFLT: /* FPU operand fetch fault */
+ ucode = T_FPOPFLT;
+ i = SIGILL;
+ break;
+
+ default:
+ trap_fatal(&frame);
+ }
+ } else {
+ /* kernel trap */
- case T_PRIVINFLT|T_USER: /* privileged instruction fault */
- case T_RESADFLT|T_USER: /* reserved addressing fault */
- case T_RESOPFLT|T_USER: /* reserved operand fault */
- case T_FPOPFLT|T_USER: /* coprocessor operand fault */
- ucode = type &~ T_USER;
- i = SIGILL;
- break;
+ switch (type) {
+ case T_PAGEFLT: /* page fault */
+ (void) trap_pfault(&frame, FALSE);
+ return;
- case T_ASTFLT|T_USER: /* Allow process switch */
- astoff();
- cnt.v_soft++;
- if ((p->p_flag & SOWEUPC) && p->p_stats->p_prof.pr_scale) {
- addupc(frame.tf_eip, &p->p_stats->p_prof, 1);
- p->p_flag &= ~SOWEUPC;
+ case T_PROTFLT: /* general protection fault */
+ case T_SEGNPFLT: /* segment not present fault */
+ if (curpcb && curpcb->pcb_onfault) {
+ frame.tf_eip = (int)curpcb->pcb_onfault;
+ return;
+ }
+ break;
+
+#if NDDB > 0
+ case T_BPTFLT:
+ case T_TRCTRAP:
+ if (kdb_trap (type, 0, &frame))
+ return;
+ break;
+#else
+ case T_TRCTRAP: /* trace trap -- someone single stepping lcall's */
+ /* Q: how do we turn it on again? */
+ frame.tf_eflags &= ~PSL_T;
+ return;
+#endif
+
+#if NISA > 0
+ case T_NMI:
+#if NDDB > 0
+ /* NMI can be hooked up to a pushbutton for debugging */
+ printf ("NMI ... going to debugger\n");
+ if (kdb_trap (type, 0, &frame))
+ return;
+#endif
+ /* machine/parity/power fail/"kitchen sink" faults */
+ if (isa_nmi(code) == 0) return;
+ /* FALL THROUGH */
+#endif
}
- goto out;
- case T_DNA|T_USER:
-#if NNPX > 0
- /* if a transparent fault (due to context switch "late") */
- if (npxdna()) return;
-#endif /* NNPX > 0 */
-#ifdef MATH_EMULATE
- i = math_emulate(&frame);
- if (i == 0) return;
-#else /* MATH_EMULTATE */
- panic("trap: math emulation necessary!");
-#endif /* MATH_EMULTATE */
- ucode = FPE_FPU_NP_TRAP;
- break;
+ trap_fatal(&frame);
+ }
- case T_BOUND|T_USER:
- ucode = FPE_SUBRNG_TRAP;
- i = SIGFPE;
- break;
+ trapsignal(p, i, ucode);
- case T_OFLOW|T_USER:
- ucode = FPE_INTOVF_TRAP;
- i = SIGFPE;
- break;
+#ifdef DIAGNOSTIC
+ eva = rcr2();
+ if (type <= MAX_TRAP_MSG) {
+ uprintf("fatal process exception: %s",
+ trap_msg[type]);
+ if ((type == T_PAGEFLT) || (type == T_PROTFLT))
+ uprintf(", fault VA = 0x%x", eva);
+ uprintf("\n");
+ }
+#endif
- case T_DIVIDE|T_USER:
- ucode = FPE_INTDIV_TRAP;
- i = SIGFPE;
- break;
+out:
+ userret(p, &frame, &syst);
+}
- case T_ARITHTRAP|T_USER:
- ucode = code;
- i = SIGFPE;
- break;
+int
+trap_pfault(frame, usermode)
+ struct trapframe *frame;
+ int usermode;
+{
+ vm_offset_t va;
+ struct vmspace *vm;
+ vm_map_t map = 0;
+ int rv = 0, oldflags;
+ vm_prot_t ftype;
+ extern vm_map_t kernel_map;
+ int eva;
+ struct proc *p = curproc;
+
+ eva = rcr2();
+ va = trunc_page((vm_offset_t)eva);
- pfault:
- case T_PAGEFLT: /* allow page faults in kernel mode */
- case T_PAGEFLT|T_USER: /* page fault */
- {
- vm_offset_t va;
- struct vmspace *vm;
- vm_map_t map = 0;
- int rv = 0, oldflags;
- vm_prot_t ftype;
- unsigned nss, v;
- extern vm_map_t kernel_map;
+ /*
+ * Don't allow user-mode faults in kernel address space
+ */
+ if (usermode && (va >= KERNBASE)) {
+ goto nogo;
+ }
+
+ if ((p == 0) || (va >= KERNBASE)) {
+ vm = 0;
+ map = kernel_map;
+ } else {
+ vm = p->p_vmspace;
+ map = &vm->vm_map;
+ }
+
+ if (frame->tf_err & PGEX_W)
+ ftype = VM_PROT_READ | VM_PROT_WRITE;
+ else
+ ftype = VM_PROT_READ;
- va = trunc_page((vm_offset_t)eva);
+ oldflags = p->p_flag;
+ if (map != kernel_map) {
+ vm_offset_t pa;
+ vm_offset_t v = (vm_offset_t) vtopte(va);
+ vm_page_t ptepg;
/*
- * Don't allow user-mode faults in kernel address space
+ * Keep swapout from messing with us during this
+ * critical time.
*/
- if ((type == (T_PAGEFLT|T_USER)) && (va >= KERNBASE)) {
- goto nogo;
- }
+ p->p_flag |= SLOCK;
- if ((p == 0) || (type == T_PAGEFLT && va >= KERNBASE)) {
- vm = 0;
- map = kernel_map;
- } else {
- vm = p->p_vmspace;
- map = &vm->vm_map;
+ /*
+ * Grow the stack if necessary
+ */
+ if ((caddr_t)va > vm->vm_maxsaddr
+ && (caddr_t)va < (caddr_t)USRSTACK) {
+ if (!grow(p, va)) {
+ rv = KERN_FAILURE;
+ p->p_flag &= ~SLOCK;
+ p->p_flag |= (oldflags & SLOCK);
+ goto nogo;
+ }
}
- if (code & PGEX_W)
- ftype = VM_PROT_READ | VM_PROT_WRITE;
- else
- ftype = VM_PROT_READ;
-
- oldflags = p->p_flag;
- if (map != kernel_map) {
- vm_offset_t pa;
- vm_offset_t v = (vm_offset_t) vtopte(va);
-
- /*
- * Keep swapout from messing with us during this
- * critical time.
- */
- p->p_flag |= SLOCK;
-
- /*
- * Grow the stack if necessary
- */
- if ((caddr_t)va > vm->vm_maxsaddr
- && (caddr_t)va < (caddr_t)USRSTACK) {
- if (!grow(p, va)) {
- rv = KERN_FAILURE;
- p->p_flag &= ~SLOCK;
- p->p_flag |= (oldflags & SLOCK);
- goto nogo;
- }
- }
+ /*
+ * Check if page table is mapped, if not,
+ * fault it first
+ */
- /*
- * Check if page table is mapped, if not,
- * fault it first
- */
+ /* Fault the pte only if needed: */
+ *(volatile char *)v += 0;
- /* Fault the pte only if needed: */
- *(volatile char *)v += 0;
+ ptepg = (vm_page_t) pmap_pte_vm_page(vm_map_pmap(map), v);
+ if( ptepg->hold_count == 0)
+ ptepg->act_count += 3;
+ vm_page_hold(ptepg);
- /* Get the physical address: */
- pa = pmap_extract(vm_map_pmap(map), v);
+ /* Fault in the user page: */
+ rv = vm_fault(map, va, ftype, FALSE);
- /* And wire the pte page at system vm level: */
- vm_page_wire(PHYS_TO_VM_PAGE(pa));
+ vm_page_unhold(ptepg);
- /* Fault in the user page: */
- rv = vm_fault(map, va, ftype, FALSE);
+ /*
+ * page table pages don't need to be kept if they
+ * are not held
+ */
+ if( ptepg->hold_count == 0 && ptepg->wire_count == 0) {
+ pmap_page_protect( VM_PAGE_TO_PHYS(ptepg),
+ VM_PROT_NONE);
+ vm_page_free(ptepg);
+ }
- /* Unwire the pte page: */
- vm_page_unwire(PHYS_TO_VM_PAGE(pa));
- p->p_flag &= ~SLOCK;
- p->p_flag |= (oldflags & SLOCK);
- } else {
- /*
- * Since we know that kernel virtual address addresses
- * always have pte pages mapped, we just have to fault
- * the page.
- */
- rv = vm_fault(map, va, ftype, FALSE);
- }
+ p->p_flag &= ~SLOCK;
+ p->p_flag |= (oldflags & SLOCK);
+ } else {
+ /*
+ * Since we know that kernel virtual address addresses
+ * always have pte pages mapped, we just have to fault
+ * the page.
+ */
+ rv = vm_fault(map, va, ftype, FALSE);
+ }
- if (rv == KERN_SUCCESS) {
- if (type == T_PAGEFLT)
- return;
- goto out;
- }
+ if (rv == KERN_SUCCESS)
+ return (0);
nogo:
- if (type == T_PAGEFLT) {
- if (curpcb->pcb_onfault)
- goto copyfault;
-
- goto we_re_toast;
+ if (!usermode) {
+ if (curpcb->pcb_onfault) {
+ frame->tf_eip = (int)curpcb->pcb_onfault;
+ return (0);
}
- i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
+ trap_fatal(frame);
+ }
- /* kludge to pass faulting virtual address to sendsig */
- ucode = type &~ T_USER;
- frame.tf_err = eva;
+ /* kludge to pass faulting virtual address to sendsig */
+ frame->tf_err = eva;
- break;
- }
+ return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
+}
-#if NDDB == 0
- case T_TRCTRAP: /* trace trap -- someone single stepping lcall's */
- frame.tf_eflags &= ~PSL_T;
+void
+trap_fatal(frame)
+ struct trapframe *frame;
+{
+ int code, type, eva;
- /* Q: how do we turn it on again? */
- return;
-#endif
-
- case T_BPTFLT|T_USER: /* bpt instruction fault */
- case T_TRCTRAP|T_USER: /* trace trap */
- frame.tf_eflags &= ~PSL_T;
- i = SIGTRAP;
- break;
+ code = frame->tf_err;
+ type = frame->tf_trapno;
+ eva = rcr2();
-#if NISA > 0
- case T_NMI:
- case T_NMI|T_USER:
-#if NDDB > 0
- /* NMI can be hooked up to a pushbutton for debugging */
- printf ("NMI ... going to debugger\n");
- if (kdb_trap (type, 0, &frame))
- return;
-#endif
- /* machine/parity/power fail/"kitchen sink" faults */
- if (isa_nmi(code) == 0) return;
- /* FALL THROUGH */
-#endif
- default:
- we_re_toast:
-
- fault_type = type & ~T_USER;
- if (fault_type <= MAX_TRAP_MSG)
- printf("\n\nFatal trap %d: %s while in %s mode\n",
- fault_type, trap_msg[fault_type],
- ISPL(frame.tf_cs) == SEL_UPL ? "user" : "kernel");
- if (fault_type == T_PAGEFLT) {
- printf("fault virtual address = 0x%x\n", eva);
- printf("fault code = %s %s, %s\n",
- code & PGEX_U ? "user" : "supervisor",
- code & PGEX_W ? "write" : "read",
- code & PGEX_P ? "protection violation" : "page not present");
- }
- printf("instruction pointer = 0x%x\n", frame.tf_eip);
- printf("processor eflags = ");
- if (frame.tf_eflags & EFL_TF)
- printf("trace/trap, ");
- if (frame.tf_eflags & EFL_IF)
- printf("interrupt enabled, ");
- if (frame.tf_eflags & EFL_NT)
- printf("nested task, ");
- if (frame.tf_eflags & EFL_RF)
- printf("resume, ");
- if (frame.tf_eflags & EFL_VM)
- printf("vm86, ");
- printf("IOPL = %d\n", (frame.tf_eflags & EFL_IOPL) >> 12);
- printf("current process = ");
- if (curproc) {
- printf("%d (%s)\n",
- curproc->p_pid, curproc->p_comm ?
- curproc->p_comm : "");
- } else {
- printf("Idle\n");
- }
- printf("interrupt mask = ");
- if ((cpl & netmask) == netmask)
- printf("net ");
- if ((cpl & ttymask) == ttymask)
- printf("tty ");
- if ((cpl & biomask) == biomask)
- printf("bio ");
- if (cpl == 0)
- printf("none");
- printf("\n");
+ if (type <= MAX_TRAP_MSG)
+ printf("\n\nFatal trap %d: %s while in %s mode\n",
+ type, trap_msg[type],
+ ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel");
+ if (type == T_PAGEFLT) {
+ printf("fault virtual address = 0x%x\n", eva);
+ printf("fault code = %s %s, %s\n",
+ code & PGEX_U ? "user" : "supervisor",
+ code & PGEX_W ? "write" : "read",
+ code & PGEX_P ? "protection violation" : "page not present");
+ }
+ printf("instruction pointer = 0x%x\n", frame->tf_eip);
+ printf("processor eflags = ");
+ if (frame->tf_eflags & EFL_TF)
+ printf("trace/trap, ");
+ if (frame->tf_eflags & EFL_IF)
+ printf("interrupt enabled, ");
+ if (frame->tf_eflags & EFL_NT)
+ printf("nested task, ");
+ if (frame->tf_eflags & EFL_RF)
+ printf("resume, ");
+ if (frame->tf_eflags & EFL_VM)
+ printf("vm86, ");
+ printf("IOPL = %d\n", (frame->tf_eflags & EFL_IOPL) >> 12);
+ printf("current process = ");
+ if (curproc) {
+ printf("%d (%s)\n",
+ curproc->p_pid, curproc->p_comm ?
+ curproc->p_comm : "");
+ } else {
+ printf("Idle\n");
+ }
+ printf("interrupt mask = ");
+ if ((cpl & net_imask) == net_imask)
+ printf("net ");
+ if ((cpl & tty_imask) == tty_imask)
+ printf("tty ");
+ if ((cpl & bio_imask) == bio_imask)
+ printf("bio ");
+ if (cpl == 0)
+ printf("none");
+ printf("\n");
#ifdef KDB
- if (kdb_trap(&psl))
- return;
+ if (kdb_trap(&psl))
+ return;
#endif
#if NDDB > 0
- if (kdb_trap (type, 0, &frame))
- return;
-#endif
- if (fault_type <= MAX_TRAP_MSG)
- panic(trap_msg[fault_type]);
- else
- panic("unknown/reserved trap");
-
- /* NOT REACHED */
- }
-
- trapsignal(p, i, ucode);
- if ((type & T_USER) == 0)
+ if (kdb_trap (type, 0, frame))
return;
-out:
- while (i = CURSIG(p))
- psig(i);
- p->p_pri = p->p_usrpri;
- if (want_resched) {
- int s;
- /*
- * Since we are curproc, clock will normally just change
- * our priority without moving us from one queue to another
- * (since the running process is not on a queue.)
- * If that happened after we setrq ourselves but before we
- * swtch()'ed, we might not be on the queue indicated by
- * our priority.
- */
- s = splclock();
- setrq(p);
- p->p_stats->p_ru.ru_nivcsw++;
- swtch();
- splx(s);
- while (i = CURSIG(p))
- psig(i);
- }
- if (p->p_stats->p_prof.pr_scale) {
- int ticks;
- struct timeval *tv = &p->p_stime;
-
- ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
- (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
- if (ticks) {
-#ifdef PROFTIMER
- extern int profscale;
- addupc(frame.tf_eip, &p->p_stats->p_prof,
- ticks * profscale);
-#else
- addupc(frame.tf_eip, &p->p_stats->p_prof, ticks);
#endif
- }
- }
- curpri = p->p_pri;
+ if (type <= MAX_TRAP_MSG)
+ panic(trap_msg[type]);
+ else
+ panic("unknown/reserved trap");
}
/*
@@ -505,7 +543,6 @@ out:
int trapwrite(addr)
unsigned addr;
{
- unsigned nss;
struct proc *p;
vm_offset_t va, v;
struct vmspace *vm;
@@ -572,21 +609,17 @@ int trapwrite(addr)
/*ARGSUSED*/
void
syscall(frame)
- volatile struct trapframe frame;
+ struct trapframe frame;
{
- register int *locr0 = ((int *)&frame);
- register caddr_t params;
- register int i;
- register struct sysent *callp;
- register struct proc *p = curproc;
+ caddr_t params;
+ int i;
+ struct sysent *callp;
+ struct proc *p = curproc;
struct timeval syst;
int error, opc;
int args[8], rval[2];
int code;
-#ifdef lint
- r0 = 0; r0 = r0; r1 = 0; r1 = r1;
-#endif
syst = p->p_stime;
if (ISPL(frame.tf_cs) != SEL_UPL)
panic("syscall");
@@ -610,13 +643,11 @@ syscall(frame)
if ((i = callp->sy_narg * sizeof (int)) &&
(error = copyin(params, (caddr_t)args, (u_int)i))) {
- frame.tf_eax = error;
- frame.tf_eflags |= PSL_C; /* carry bit */
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSCALL))
ktrsyscall(p->p_tracep, code, callp->sy_narg, args);
#endif
- goto done;
+ goto bad;
}
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSCALL))
@@ -624,81 +655,40 @@ syscall(frame)
#endif
rval[0] = 0;
rval[1] = frame.tf_edx;
-/*pg("%d. s %d\n", p->p_pid, code);*/
+
error = (*callp->sy_call)(p, args, rval);
- if (error == ERESTART)
- frame.tf_eip = opc;
- else if (error != EJUSTRETURN) {
- if (error) {
-/*pg("error %d", error);*/
- frame.tf_eax = error;
- frame.tf_eflags |= PSL_C; /* carry bit */
- } else {
- frame.tf_eax = rval[0];
- frame.tf_edx = rval[1];
- frame.tf_eflags &= ~PSL_C; /* carry bit */
- }
- }
- /* else if (error == EJUSTRETURN) */
- /* nothing to do */
-done:
- /*
- * Reinitialize proc pointer `p' as it may be different
- * if this is a child returning from fork syscall.
- */
- p = curproc;
- while (i = CURSIG(p))
- psig(i);
- p->p_pri = p->p_usrpri;
- if (want_resched) {
- int s;
+
+ switch (error) {
+
+ case 0:
/*
- * Since we are curproc, clock will normally just change
- * our priority without moving us from one queue to another
- * (since the running process is not on a queue.)
- * If that happened after we setrq ourselves but before we
- * swtch()'ed, we might not be on the queue indicated by
- * our priority.
+ * Reinitialize proc pointer `p' as it may be different
+ * if this is a child returning from fork syscall.
*/
- s = splclock();
- setrq(p);
- p->p_stats->p_ru.ru_nivcsw++;
- swtch();
- splx(s);
- while (i = CURSIG(p))
- psig(i);
- }
- if (p->p_stats->p_prof.pr_scale) {
- int ticks;
- struct timeval *tv = &p->p_stime;
+ p = curproc;
+ frame.tf_eax = rval[0];
+ frame.tf_edx = rval[1];
+ frame.tf_eflags &= ~PSL_C; /* carry bit */
+ break;
- ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
- (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
- if (ticks) {
-#ifdef PROFTIMER
- extern int profscale;
- addupc(frame.tf_eip, &p->p_stats->p_prof,
- ticks * profscale);
-#else
- addupc(frame.tf_eip, &p->p_stats->p_prof, ticks);
-#endif
- }
+ case ERESTART:
+ frame.tf_eip = opc;
+ break;
+
+ case EJUSTRETURN:
+ break;
+
+ default:
+ bad:
+ frame.tf_eax = error;
+ frame.tf_eflags |= PSL_C; /* carry bit */
+ break;
}
- curpri = p->p_pri;
+
+ userret(p, &frame, &syst);
+
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p->p_tracep, code, error, rval[0]);
#endif
-#ifdef DIAGNOSTICx
-{ extern int _udatasel, _ucodesel;
- if (frame.tf_ss != _udatasel)
- printf("ss %x call %d\n", frame.tf_ss, code);
- if ((frame.tf_cs&0xffff) != _ucodesel)
- printf("cs %x call %d\n", frame.tf_cs, code);
- if (frame.tf_eip > VM_MAXUSER_ADDRESS) {
- printf("eip %x call %d\n", frame.tf_eip, code);
- frame.tf_eip = 0;
- }
-}
-#endif
}
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index ac7174eb8b53..8b7e625cf41e 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
* Copyright (c) 1989, 1990 William Jolitz
+ * Copyright (c) 1994 John Dyson
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@@ -37,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.11.2.1 1994/03/24 08:56:56 rgrimes Exp $
+ * $Id: vm_machdep.c,v 1.28 1994/06/06 12:08:16 davidg Exp $
*/
#include "npx.h"
@@ -53,6 +54,837 @@
#include "vm/vm.h"
#include "vm/vm_kern.h"
+#define b_cylin b_resid
+
+#define MAXCLSTATS 256
+int clstats[MAXCLSTATS];
+int rqstats[MAXCLSTATS];
+
+
+#ifndef NOBOUNCE
+vm_map_t io_map;
+volatile int kvasfreecnt;
+
+
+caddr_t bouncememory;
+int bouncepages, bpwait;
+vm_offset_t *bouncepa;
+int bmwait, bmfreeing;
+
+#define BITS_IN_UNSIGNED (8*sizeof(unsigned))
+int bounceallocarraysize;
+unsigned *bounceallocarray;
+int bouncefree;
+
+#define SIXTEENMEG (4096*4096)
+#define MAXBKVA 1024
+
+/* special list that can be used at interrupt time for eventual kva free */
+struct kvasfree {
+ vm_offset_t addr;
+ vm_offset_t size;
+} kvaf[MAXBKVA];
+
+
+vm_offset_t vm_bounce_kva();
+/*
+ * get bounce buffer pages (count physically contiguous)
+ * (only 1 inplemented now)
+ */
+vm_offset_t
+vm_bounce_page_find(count)
+ int count;
+{
+ int bit;
+ int s,i;
+
+ if (count != 1)
+ panic("vm_bounce_page_find -- no support for > 1 page yet!!!");
+
+ s = splbio();
+retry:
+ for (i = 0; i < bounceallocarraysize; i++) {
+ if (bounceallocarray[i] != 0xffffffff) {
+ if (bit = ffs(~bounceallocarray[i])) {
+ bounceallocarray[i] |= 1 << (bit - 1) ;
+ bouncefree -= count;
+ splx(s);
+ return bouncepa[(i * BITS_IN_UNSIGNED + (bit - 1))];
+ }
+ }
+ }
+ bpwait = 1;
+ tsleep((caddr_t) &bounceallocarray, PRIBIO, "bncwai", 0);
+ goto retry;
+}
+
+void
+vm_bounce_kva_free(addr, size, now)
+ vm_offset_t addr;
+ vm_offset_t size;
+ int now;
+{
+ int s = splbio();
+ kvaf[kvasfreecnt].addr = addr;
+ kvaf[kvasfreecnt].size = size;
+ ++kvasfreecnt;
+ if( now) {
+ /*
+ * this will do wakeups
+ */
+ vm_bounce_kva(0,0);
+ } else {
+ if (bmwait) {
+ /*
+ * if anyone is waiting on the bounce-map, then wakeup
+ */
+ wakeup((caddr_t) io_map);
+ bmwait = 0;
+ }
+ }
+ splx(s);
+}
+
+/*
+ * free count bounce buffer pages
+ */
+void
+vm_bounce_page_free(pa, count)
+ vm_offset_t pa;
+ int count;
+{
+ int allocindex;
+ int index;
+ int bit;
+
+ if (count != 1)
+ panic("vm_bounce_page_free -- no support for > 1 page yet!!!\n");
+
+ for(index=0;index<bouncepages;index++) {
+ if( pa == bouncepa[index])
+ break;
+ }
+
+ if( index == bouncepages)
+ panic("vm_bounce_page_free: invalid bounce buffer");
+
+ allocindex = index / BITS_IN_UNSIGNED;
+ bit = index % BITS_IN_UNSIGNED;
+
+ bounceallocarray[allocindex] &= ~(1 << bit);
+
+ bouncefree += count;
+ if (bpwait) {
+ bpwait = 0;
+ wakeup((caddr_t) &bounceallocarray);
+ }
+}
+
+/*
+ * allocate count bounce buffer kva pages
+ */
+vm_offset_t
+vm_bounce_kva(size, waitok)
+ int size;
+ int waitok;
+{
+ int i;
+ int startfree;
+ vm_offset_t kva = 0;
+ int s = splbio();
+more:
+ if (!bmfreeing && kvasfreecnt) {
+ bmfreeing = 1;
+ for (i = 0; i < kvasfreecnt; i++) {
+ pmap_remove(kernel_pmap,
+ kvaf[i].addr, kvaf[i].addr + kvaf[i].size);
+ kmem_free_wakeup(io_map, kvaf[i].addr,
+ kvaf[i].size);
+ }
+ kvasfreecnt = 0;
+ bmfreeing = 0;
+ if( bmwait) {
+ bmwait = 0;
+ wakeup( (caddr_t) io_map);
+ }
+ }
+
+ if( size == 0) {
+ splx(s);
+ return NULL;
+ }
+
+ if ((kva = kmem_alloc_pageable(io_map, size)) == 0) {
+ if( !waitok) {
+ splx(s);
+ return NULL;
+ }
+ bmwait = 1;
+ tsleep((caddr_t) io_map, PRIBIO, "bmwait", 0);
+ goto more;
+ }
+ splx(s);
+ return kva;
+}
+
+/*
+ * same as vm_bounce_kva -- but really allocate (but takes pages as arg)
+ */
+vm_offset_t
+vm_bounce_kva_alloc(count)
+int count;
+{
+ int i;
+ vm_offset_t kva;
+ vm_offset_t pa;
+ if( bouncepages == 0) {
+ kva = (vm_offset_t) malloc(count*NBPG, M_TEMP, M_WAITOK);
+ return kva;
+ }
+ kva = vm_bounce_kva(count*NBPG, 1);
+ for(i=0;i<count;i++) {
+ pa = vm_bounce_page_find(1);
+ pmap_kenter(kva + i * NBPG, pa);
+ }
+ pmap_update();
+ return kva;
+}
+
+/*
+ * same as vm_bounce_kva_free -- but really free
+ */
+void
+vm_bounce_kva_alloc_free(kva, count)
+ vm_offset_t kva;
+ int count;
+{
+ int i;
+ vm_offset_t pa;
+ if( bouncepages == 0) {
+ free((caddr_t) kva, M_TEMP);
+ return;
+ }
+ for(i = 0; i < count; i++) {
+ pa = pmap_kextract(kva + i * NBPG);
+ vm_bounce_page_free(pa, 1);
+ }
+ vm_bounce_kva_free(kva, count*NBPG, 0);
+}
+
+/*
+ * do the things necessary to the struct buf to implement
+ * bounce buffers... inserted before the disk sort
+ */
+void
+vm_bounce_alloc(bp)
+ struct buf *bp;
+{
+ int countvmpg;
+ vm_offset_t vastart, vaend;
+ vm_offset_t vapstart, vapend;
+ vm_offset_t va, kva;
+ vm_offset_t pa;
+ int dobounceflag = 0;
+ int bounceindex;
+ int i;
+ int s;
+
+ if (bouncepages == 0)
+ return;
+
+ if (bp->b_flags & B_BOUNCE) {
+ printf("vm_bounce_alloc: called recursively???\n");
+ return;
+ }
+
+ if (bp->b_bufsize < bp->b_bcount) {
+ printf("vm_bounce_alloc: b_bufsize(0x%x) < b_bcount(0x%x) !!!!\n",
+ bp->b_bufsize, bp->b_bcount);
+ panic("vm_bounce_alloc");
+ }
+
+/*
+ * This is not really necessary
+ * if( bp->b_bufsize != bp->b_bcount) {
+ * printf("size: %d, count: %d\n", bp->b_bufsize, bp->b_bcount);
+ * }
+ */
+
+
+ vastart = (vm_offset_t) bp->b_un.b_addr;
+ vaend = (vm_offset_t) bp->b_un.b_addr + bp->b_bufsize;
+
+ vapstart = i386_trunc_page(vastart);
+ vapend = i386_round_page(vaend);
+ countvmpg = (vapend - vapstart) / NBPG;
+
+/*
+ * if any page is above 16MB, then go into bounce-buffer mode
+ */
+ va = vapstart;
+ for (i = 0; i < countvmpg; i++) {
+ pa = pmap_kextract(va);
+ if (pa >= SIXTEENMEG)
+ ++dobounceflag;
+ va += NBPG;
+ }
+ if (dobounceflag == 0)
+ return;
+
+ if (bouncepages < dobounceflag)
+ panic("Not enough bounce buffers!!!");
+
+/*
+ * allocate a replacement kva for b_addr
+ */
+ kva = vm_bounce_kva(countvmpg*NBPG, 1);
+ va = vapstart;
+ for (i = 0; i < countvmpg; i++) {
+ pa = pmap_kextract(va);
+ if (pa >= SIXTEENMEG) {
+ /*
+ * allocate a replacement page
+ */
+ vm_offset_t bpa = vm_bounce_page_find(1);
+ pmap_kenter(kva + (NBPG * i), bpa);
+ /*
+ * if we are writing, the copy the data into the page
+ */
+ if ((bp->b_flags & B_READ) == 0) {
+ pmap_update();
+ bcopy((caddr_t) va, (caddr_t) kva + (NBPG * i), NBPG);
+ }
+ } else {
+ /*
+ * use original page
+ */
+ pmap_kenter(kva + (NBPG * i), pa);
+ }
+ va += NBPG;
+ }
+ pmap_update();
+
+/*
+ * flag the buffer as being bounced
+ */
+ bp->b_flags |= B_BOUNCE;
+/*
+ * save the original buffer kva
+ */
+ bp->b_savekva = bp->b_un.b_addr;
+/*
+ * put our new kva into the buffer (offset by original offset)
+ */
+ bp->b_un.b_addr = (caddr_t) (((vm_offset_t) kva) |
+ ((vm_offset_t) bp->b_savekva & (NBPG - 1)));
+ return;
+}
+
+/*
+ * hook into biodone to free bounce buffer
+ */
+void
+vm_bounce_free(bp)
+ struct buf *bp;
+{
+ int i;
+ vm_offset_t origkva, bouncekva, bouncekvaend;
+ int countvmpg;
+ int s;
+
+/*
+ * if this isn't a bounced buffer, then just return
+ */
+ if ((bp->b_flags & B_BOUNCE) == 0)
+ return;
+
+/*
+ * This check is not necessary
+ * if (bp->b_bufsize != bp->b_bcount) {
+ * printf("vm_bounce_free: b_bufsize=%d, b_bcount=%d\n",
+ * bp->b_bufsize, bp->b_bcount);
+ * }
+ */
+
+ origkva = (vm_offset_t) bp->b_savekva;
+ bouncekva = (vm_offset_t) bp->b_un.b_addr;
+
+/*
+ * check every page in the kva space for b_addr
+ */
+ for (i = 0; i < bp->b_bufsize; ) {
+ vm_offset_t mybouncepa;
+ vm_offset_t copycount;
+
+ copycount = i386_round_page(bouncekva + 1) - bouncekva;
+ mybouncepa = pmap_kextract(i386_trunc_page(bouncekva));
+
+/*
+ * if this is a bounced pa, then process as one
+ */
+ if ( mybouncepa != pmap_kextract( i386_trunc_page( origkva))) {
+ vm_offset_t tocopy = copycount;
+ if (i + tocopy > bp->b_bufsize)
+ tocopy = bp->b_bufsize - i;
+/*
+ * if this is a read, then copy from bounce buffer into original buffer
+ */
+ if (bp->b_flags & B_READ)
+ bcopy((caddr_t) bouncekva, (caddr_t) origkva, tocopy);
+/*
+ * free the bounce allocation
+ */
+ vm_bounce_page_free(mybouncepa, 1);
+ }
+
+ origkva += copycount;
+ bouncekva += copycount;
+ i += copycount;
+ }
+
+/*
+ * add the old kva into the "to free" list
+ */
+
+ bouncekva= i386_trunc_page((vm_offset_t) bp->b_un.b_addr);
+ bouncekvaend= i386_round_page((vm_offset_t)bp->b_un.b_addr + bp->b_bufsize);
+
+ vm_bounce_kva_free( bouncekva, (bouncekvaend - bouncekva), 0);
+ bp->b_un.b_addr = bp->b_savekva;
+ bp->b_savekva = 0;
+ bp->b_flags &= ~B_BOUNCE;
+
+ return;
+}
+
+
+/*
+ * init the bounce buffer system
+ */
+void
+vm_bounce_init()
+{
+ vm_offset_t minaddr, maxaddr;
+ int i;
+
+ io_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, MAXBKVA * NBPG, FALSE);
+ kvasfreecnt = 0;
+
+ if (bouncepages == 0)
+ return;
+
+ bounceallocarraysize = (bouncepages + BITS_IN_UNSIGNED - 1) / BITS_IN_UNSIGNED;
+ bounceallocarray = malloc(bounceallocarraysize * sizeof(unsigned), M_TEMP, M_NOWAIT);
+
+ if (!bounceallocarray)
+ panic("Cannot allocate bounce resource array\n");
+
+ bzero(bounceallocarray, bounceallocarraysize * sizeof(unsigned));
+ bouncepa = malloc(bouncepages * sizeof(vm_offset_t), M_TEMP, M_NOWAIT);
+ if (!bouncepa)
+ panic("Cannot allocate physical memory array\n");
+
+ for(i=0;i<bouncepages;i++) {
+ vm_offset_t pa;
+ if( (pa = pmap_kextract((vm_offset_t) bouncememory + i * NBPG)) >= SIXTEENMEG)
+ panic("bounce memory out of range");
+ if( pa == 0)
+ panic("bounce memory not resident");
+ bouncepa[i] = pa;
+ }
+ bouncefree = bouncepages;
+
+}
+#endif /* NOBOUNCE */
+
+
+static void
+cldiskvamerge( kvanew, orig1, orig1cnt, orig2, orig2cnt)
+ vm_offset_t kvanew;
+ vm_offset_t orig1, orig1cnt;
+ vm_offset_t orig2, orig2cnt;
+{
+ int i;
+ vm_offset_t pa;
+/*
+ * enter the transfer physical addresses into the new kva
+ */
+ for(i=0;i<orig1cnt;i++) {
+ vm_offset_t pa;
+ pa = pmap_kextract((caddr_t) orig1 + i * PAGE_SIZE);
+ pmap_kenter(kvanew + i * PAGE_SIZE, pa);
+ }
+
+ for(i=0;i<orig2cnt;i++) {
+ vm_offset_t pa;
+ pa = pmap_kextract((caddr_t) orig2 + i * PAGE_SIZE);
+ pmap_kenter(kvanew + (i + orig1cnt) * PAGE_SIZE, pa);
+ }
+ pmap_update();
+}
+
+void
+cldisksort(struct buf *dp, struct buf *bp, vm_offset_t maxio)
+{
+ register struct buf *ap, *newbp;
+ int i, trycount=0;
+ vm_offset_t orig1pages, orig2pages;
+ vm_offset_t orig1begin, orig2begin;
+ vm_offset_t kvanew, kvaorig;
+
+ if( bp->b_bcount < MAXCLSTATS*PAGE_SIZE)
+ ++rqstats[bp->b_bcount/PAGE_SIZE];
+ /*
+ * If nothing on the activity queue, then
+ * we become the only thing.
+ */
+ ap = dp->b_actf;
+ if(ap == NULL) {
+ dp->b_actf = bp;
+ dp->b_actl = bp;
+ bp->av_forw = NULL;
+ return;
+ }
+
+
+ if (bp->b_flags & B_READ) {
+ while( ap->av_forw && (ap->av_forw->b_flags & B_READ))
+ ap = ap->av_forw;
+ goto insert;
+ }
+
+ /*
+ * If we lie after the first (currently active)
+ * request, then we must locate the second request list
+ * and add ourselves to it.
+ */
+
+ if (bp->b_pblkno < ap->b_pblkno) {
+ while (ap->av_forw) {
+ /*
+ * Check for an ``inversion'' in the
+ * normally ascending block numbers,
+ * indicating the start of the second request list.
+ */
+ if (ap->av_forw->b_pblkno < ap->b_pblkno) {
+ /*
+ * Search the second request list
+ * for the first request at a larger
+ * block number. We go before that;
+ * if there is no such request, we go at end.
+ */
+ do {
+ if (bp->b_pblkno < ap->av_forw->b_pblkno)
+ goto insert;
+ ap = ap->av_forw;
+ } while (ap->av_forw);
+ goto insert; /* after last */
+ }
+ ap = ap->av_forw;
+ }
+ /*
+ * No inversions... we will go after the last, and
+ * be the first request in the second request list.
+ */
+ goto insert;
+ }
+ /*
+ * Request is at/after the current request...
+ * sort in the first request list.
+ */
+ while (ap->av_forw) {
+ /*
+ * We want to go after the current request
+ * if there is an inversion after it (i.e. it is
+ * the end of the first request list), or if
+ * the next request is a larger block than our request.
+ */
+ if (ap->av_forw->b_pblkno < ap->b_pblkno ||
+ bp->b_pblkno < ap->av_forw->b_pblkno )
+ goto insert;
+ ap = ap->av_forw;
+ }
+
+insert:
+
+#ifndef NOBOUNCE
+ /*
+ * read clustering with new read-ahead disk drives hurts mostly, so
+ * we don't bother...
+ */
+ if( bp->b_flags & (B_READ|B_SYNC))
+ goto nocluster;
+ if( bp->b_bcount != bp->b_bufsize) {
+ goto nocluster;
+ }
+ /*
+ * we currently only cluster I/O transfers that are at page-aligned
+ * kvas and transfers that are multiples of page lengths.
+ */
+ if ((bp->b_flags & B_BAD) == 0 &&
+ ((bp->b_bcount & PAGE_MASK) == 0) &&
+ (((vm_offset_t) bp->b_un.b_addr & PAGE_MASK) == 0)) {
+ if( maxio > MAXCLSTATS*PAGE_SIZE)
+ maxio = MAXCLSTATS*PAGE_SIZE;
+ /*
+ * merge with previous?
+ * conditions:
+ * 1) We reside physically immediately after the previous block.
+ * 2) The previous block is not first on the device queue because
+ * such a block might be active.
+ * 3) The mode of the two I/Os is identical.
+ * 4) The previous kva is page aligned and the previous transfer
+ * is a multiple of a page in length.
+ * 5) And the total I/O size would be below the maximum.
+ */
+ if( (ap->b_pblkno + (ap->b_bcount / DEV_BSIZE) == bp->b_pblkno) &&
+ (dp->b_actf != ap) &&
+ ((ap->b_flags & ~(B_CLUSTER|B_BOUNCE)) == (bp->b_flags & ~B_BOUNCE)) &&
+ ((ap->b_flags & B_BAD) == 0) &&
+ ((ap->b_bcount & PAGE_MASK) == 0) &&
+ (((vm_offset_t) ap->b_un.b_addr & PAGE_MASK) == 0) &&
+ (ap->b_bcount + bp->b_bcount < maxio)) {
+
+ /*
+ * something is majorly broken in the upper level
+ * fs code... blocks can overlap!!! this detects
+ * the overlap and does the right thing.
+ */
+ if( ap->av_forw &&
+ bp->b_pblkno + ((bp->b_bcount / DEV_BSIZE) > ap->av_forw->b_pblkno)) {
+ goto nocluster;
+ }
+
+ orig1begin = (vm_offset_t) ap->b_un.b_addr;
+ orig1pages = ap->b_bcount / PAGE_SIZE;
+
+ orig2begin = (vm_offset_t) bp->b_un.b_addr;
+ orig2pages = bp->b_bcount / PAGE_SIZE;
+
+ /*
+ * see if we can allocate a kva, if we cannot, the don't
+ * cluster.
+ */
+ kvanew = vm_bounce_kva( PAGE_SIZE * (orig1pages + orig2pages), 0);
+ if( !kvanew) {
+ goto nocluster;
+ }
+
+ if( (ap->b_flags & B_CLUSTER) == 0) {
+
+ /*
+ * get a physical buf pointer
+ */
+ newbp = (struct buf *)trypbuf();
+ if( !newbp) {
+ vm_bounce_kva_free( kvanew, PAGE_SIZE * (orig1pages + orig2pages), 1);
+ goto nocluster;
+ }
+
+ cldiskvamerge( kvanew, orig1begin, orig1pages, orig2begin, orig2pages);
+
+ /*
+ * build the new bp to be handed off to the device
+ */
+
+ --clstats[ap->b_bcount/PAGE_SIZE];
+ *newbp = *ap;
+ newbp->b_flags |= B_CLUSTER;
+ newbp->b_un.b_addr = (caddr_t) kvanew;
+ newbp->b_bcount += bp->b_bcount;
+ newbp->b_bufsize = newbp->b_bcount;
+ newbp->b_clusterf = ap;
+ newbp->b_clusterl = bp;
+ ++clstats[newbp->b_bcount/PAGE_SIZE];
+
+ /*
+ * enter the new bp onto the device queue
+ */
+ if( ap->av_forw)
+ ap->av_forw->av_back = newbp;
+ else
+ dp->b_actl = newbp;
+
+ if( dp->b_actf != ap )
+ ap->av_back->av_forw = newbp;
+ else
+ dp->b_actf = newbp;
+
+ /*
+ * enter the previous bps onto the cluster queue
+ */
+ ap->av_forw = bp;
+ bp->av_back = ap;
+
+ ap->av_back = NULL;
+ bp->av_forw = NULL;
+
+ } else {
+ vm_offset_t addr;
+
+ cldiskvamerge( kvanew, orig1begin, orig1pages, orig2begin, orig2pages);
+ /*
+ * free the old kva
+ */
+ vm_bounce_kva_free( orig1begin, ap->b_bufsize, 0);
+ --clstats[ap->b_bcount/PAGE_SIZE];
+
+ ap->b_un.b_addr = (caddr_t) kvanew;
+
+ ap->b_clusterl->av_forw = bp;
+ bp->av_forw = NULL;
+ bp->av_back = ap->b_clusterl;
+ ap->b_clusterl = bp;
+
+ ap->b_bcount += bp->b_bcount;
+ ap->b_bufsize = ap->b_bcount;
+ ++clstats[ap->b_bcount/PAGE_SIZE];
+ }
+ return;
+ /*
+ * merge with next?
+ * conditions:
+ * 1) We reside physically before the next block.
+ * 3) The mode of the two I/Os is identical.
+ * 4) The next kva is page aligned and the next transfer
+ * is a multiple of a page in length.
+ * 5) And the total I/O size would be below the maximum.
+ */
+ } else if( ap->av_forw &&
+ (bp->b_pblkno + (bp->b_bcount / DEV_BSIZE) == ap->av_forw->b_pblkno) &&
+ ((bp->b_flags & ~B_BOUNCE) == (ap->av_forw->b_flags & ~(B_CLUSTER|B_BOUNCE))) &&
+ ((ap->av_forw->b_flags & B_BAD) == 0) &&
+ ((ap->av_forw->b_bcount & PAGE_MASK) == 0) &&
+ (((vm_offset_t) ap->av_forw->b_un.b_addr & PAGE_MASK) == 0) &&
+ (ap->av_forw->b_bcount + bp->b_bcount < maxio)) {
+
+ /*
+ * something is majorly broken in the upper level
+ * fs code... blocks can overlap!!! this detects
+ * the overlap and does the right thing.
+ */
+ if( (ap->b_pblkno + (ap->b_bcount / DEV_BSIZE)) > bp->b_pblkno) {
+ goto nocluster;
+ }
+
+ orig1begin = (vm_offset_t) bp->b_un.b_addr;
+ orig1pages = bp->b_bcount / PAGE_SIZE;
+
+ orig2begin = (vm_offset_t) ap->av_forw->b_un.b_addr;
+ orig2pages = ap->av_forw->b_bcount / PAGE_SIZE;
+
+ /*
+ * see if we can allocate a kva, if we cannot, the don't
+ * cluster.
+ */
+ kvanew = vm_bounce_kva( PAGE_SIZE * (orig1pages + orig2pages), 0);
+ if( !kvanew) {
+ goto nocluster;
+ }
+
+ /*
+ * if next isn't a cluster we need to create one
+ */
+ if( (ap->av_forw->b_flags & B_CLUSTER) == 0) {
+
+ /*
+ * get a physical buf pointer
+ */
+ newbp = (struct buf *)trypbuf();
+ if( !newbp) {
+ vm_bounce_kva_free( kvanew, PAGE_SIZE * (orig1pages + orig2pages), 1);
+ goto nocluster;
+ }
+
+ cldiskvamerge( kvanew, orig1begin, orig1pages, orig2begin, orig2pages);
+ ap = ap->av_forw;
+ --clstats[ap->b_bcount/PAGE_SIZE];
+ *newbp = *ap;
+ newbp->b_flags |= B_CLUSTER;
+ newbp->b_un.b_addr = (caddr_t) kvanew;
+ newbp->b_blkno = bp->b_blkno;
+ newbp->b_pblkno = bp->b_pblkno;
+ newbp->b_bcount += bp->b_bcount;
+ newbp->b_bufsize = newbp->b_bcount;
+ newbp->b_clusterf = bp;
+ newbp->b_clusterl = ap;
+ ++clstats[newbp->b_bcount/PAGE_SIZE];
+
+ if( ap->av_forw)
+ ap->av_forw->av_back = newbp;
+ else
+ dp->b_actl = newbp;
+
+ if( dp->b_actf != ap )
+ ap->av_back->av_forw = newbp;
+ else
+ dp->b_actf = newbp;
+
+ bp->av_forw = ap;
+ ap->av_back = bp;
+
+ bp->av_back = NULL;
+ ap->av_forw = NULL;
+ } else {
+ vm_offset_t addr;
+
+ cldiskvamerge( kvanew, orig1begin, orig1pages, orig2begin, orig2pages);
+ ap = ap->av_forw;
+ vm_bounce_kva_free( orig2begin, ap->b_bufsize, 0);
+
+ ap->b_un.b_addr = (caddr_t) kvanew;
+ bp->av_forw = ap->b_clusterf;
+ ap->b_clusterf->av_back = bp;
+ ap->b_clusterf = bp;
+ bp->av_back = NULL;
+ --clstats[ap->b_bcount/PAGE_SIZE];
+
+ ap->b_blkno = bp->b_blkno;
+ ap->b_pblkno = bp->b_pblkno;
+ ap->b_bcount += bp->b_bcount;
+ ap->b_bufsize = ap->b_bcount;
+ ++clstats[ap->b_bcount/PAGE_SIZE];
+
+ }
+ return;
+ }
+ }
+#endif
+ /*
+ * don't merge
+ */
+nocluster:
+ ++clstats[bp->b_bcount/PAGE_SIZE];
+ bp->av_forw = ap->av_forw;
+ if( bp->av_forw)
+ bp->av_forw->av_back = bp;
+ else
+ dp->b_actl = bp;
+
+ ap->av_forw = bp;
+ bp->av_back = ap;
+}
+
+/*
+ * quick version of vm_fault
+ */
+
+void
+vm_fault_quick( v, prot)
+ vm_offset_t v;
+ int prot;
+{
+ if( (cpu_class == CPUCLASS_386) &&
+ (prot & VM_PROT_WRITE))
+ vm_fault(&curproc->p_vmspace->vm_map, v,
+ VM_PROT_READ|VM_PROT_WRITE, FALSE);
+ else if( prot & VM_PROT_WRITE)
+ *(volatile char *)v += 0;
+ else
+ *(volatile char *)v;
+}
+
+
/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the kernel stack and pcb, making the child
@@ -213,32 +1045,6 @@ setredzone(pte, vaddr)
}
/*
- * Move pages from one kernel virtual address to another.
- * Both addresses are assumed to reside in the Sysmap,
- * and size must be a multiple of CLSIZE.
- */
-void
-pagemove(from, to, size)
- register caddr_t from, to;
- int size;
-{
- register struct pte *fpte, *tpte;
-
- if (size % CLBYTES)
- panic("pagemove");
- fpte = kvtopte(from);
- tpte = kvtopte(to);
- while (size > 0) {
- *tpte++ = *fpte;
- *(int *)fpte++ = 0;
- from += NBPG;
- to += NBPG;
- size -= NBPG;
- }
- tlbflush();
-}
-
-/*
* Convert kernel VA to physical address
*/
u_long
@@ -246,7 +1052,7 @@ kvtop(void *addr)
{
vm_offset_t va;
- va = pmap_extract(kernel_pmap, (vm_offset_t)addr);
+ va = pmap_kextract((vm_offset_t)addr);
if (va == 0)
panic("kvtop: zero page frame");
return((int)va);
@@ -255,22 +1061,11 @@ kvtop(void *addr)
extern vm_map_t phys_map;
/*
- * Map an IO request into kernel virtual address space. Requests fall into
- * one of five catagories:
- *
- * B_PHYS|B_UAREA: User u-area swap.
- * Address is relative to start of u-area (p_addr).
- * B_PHYS|B_PAGET: User page table swap.
- * Address is a kernel VA in usrpt (Usrptmap).
- * B_PHYS|B_DIRTY: Dirty page push.
- * Address is a VA in proc2's address space.
- * B_PHYS|B_PGIN: Kernel pagein of user pages.
- * Address is VA in user's address space.
- * B_PHYS: User "raw" IO request.
- * Address is VA in user's address space.
+ * Map an IO request into kernel virtual address space.
*
- * All requests are (re)mapped into kernel VA space via the useriomap
- * (a name with only slightly more meaning than "kernelmap")
+ * All requests are (re)mapped into kernel VA space.
+ * Notice that we use b_bufsize for the size of the buffer
+ * to be mapped. b_bcount might be modified by the driver.
*/
void
vmapbuf(bp)
@@ -289,18 +1084,18 @@ vmapbuf(bp)
addr = bp->b_saveaddr = bp->b_un.b_addr;
off = (int)addr & PGOFSET;
p = bp->b_proc;
- npf = btoc(round_page(bp->b_bcount + off));
+ npf = btoc(round_page(bp->b_bufsize + off));
kva = kmem_alloc_wait(phys_map, ctob(npf));
bp->b_un.b_addr = (caddr_t) (kva + off);
while (npf--) {
pa = pmap_extract(&p->p_vmspace->vm_pmap, (vm_offset_t)addr);
if (pa == 0)
panic("vmapbuf: null page frame");
- pmap_enter(vm_map_pmap(phys_map), kva, trunc_page(pa),
- VM_PROT_READ|VM_PROT_WRITE, TRUE);
+ pmap_kenter(kva, trunc_page(pa));
addr += PAGE_SIZE;
kva += PAGE_SIZE;
}
+ pmap_update();
}
/*
@@ -317,7 +1112,7 @@ vunmapbuf(bp)
if ((bp->b_flags & B_PHYS) == 0)
panic("vunmapbuf");
- npf = btoc(round_page(bp->b_bcount + ((int)addr & PGOFSET)));
+ npf = btoc(round_page(bp->b_bufsize + ((int)addr & PGOFSET)));
kva = (vm_offset_t)((int)addr & ~PGOFSET);
kmem_free_wakeup(phys_map, kva, ctob(npf));
bp->b_un.b_addr = bp->b_saveaddr;
diff --git a/sys/i386/include/ansi.h b/sys/i386/include/ansi.h
index 3a54968b1595..c932ba7a598b 100644
--- a/sys/i386/include/ansi.h
+++ b/sys/i386/include/ansi.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)ansi.h 7.1 (Berkeley) 3/9/91
- * $Id: ansi.h,v 1.2 1993/10/16 14:39:05 rgrimes Exp $
+ * $Id: ansi.h,v 1.3 1994/04/04 21:11:11 wollman Exp $
*/
#ifndef _ANSI_H_
@@ -53,6 +53,23 @@
#define _SIZE_T_ unsigned int /* sizeof() */
#define _TIME_T_ long /* time() */
#define _VA_LIST_ char * /* va_list */
-#define _WCHAR_T_ unsigned short /* wchar_t */
+
+/*
+ * Runes (wchar_t) is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''. Two things are happening here. It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
+ * it looks like 10646 will be a 31 bit standard. This means that if your
+ * ints cannot hold 32 bits, you will be in trouble. The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use _RUNE_T_ instead of int. By changing it here, you
+ * lose a bit of ANSI conformance, but your programs will still work.
+ *
+ * Note that _WCHAR_T_ and _RUNE_T_ must be of the same type. When wchar_t
+ * and rune_t are typedef'd, _WCHAR_T_ will be undef'd, but _RUNE_T remains
+ * defined for ctype.h.
+ */
+#define _BSD_WCHAR_T_ int /* wchar_t */
+#define _BSD_RUNE_T_ int /* rune_t */
+
#endif /* _ANSI_H_ */
diff --git a/sys/i386/include/asmacros.h b/sys/i386/include/asmacros.h
index f0f2c014178c..4af0b97a8abf 100644
--- a/sys/i386/include/asmacros.h
+++ b/sys/i386/include/asmacros.h
@@ -5,6 +5,11 @@
#define GEN_ENTRY(name) ALIGN_TEXT; .globl name; name:
#define NON_GPROF_ENTRY(name) GEN_ENTRY(_/**/name)
+/* These three are place holders for future changes to the profiling code */
+#define MCOUNT_LABEL(name)
+#define MEXITCOUNT
+#define FAKE_MCOUNT(caller)
+
#ifdef GPROF
/*
* ALTENTRY() must be before a corresponding ENTRY() so that it can jump
@@ -30,6 +35,7 @@
*/
#define ALTENTRY(name) GEN_ENTRY(_/**/name)
#define ENTRY(name) GEN_ENTRY(_/**/name)
+#define MCOUNT
#endif
diff --git a/sys/i386/include/console.h b/sys/i386/include/console.h
index 011889032ecc..c52a3943c764 100644
--- a/sys/i386/include/console.h
+++ b/sys/i386/include/console.h
@@ -14,7 +14,7 @@
* DK9210 Aalborg SO Phone: +45 9814 8076
*
* from:@(#)console.h 1.1 940105
- * $Id: console.h,v 1.7 1994/02/04 10:35:29 chmr Exp $
+ * $Id: console.h,v 1.9 1994/05/20 12:21:49 sos Exp $
*/
#ifndef _CONSOLE_H_
@@ -55,7 +55,7 @@
#define GIO_FONT8x14 _IOR('c', 67, fnt14_t)
#define PIO_FONT8x16 _IOW('c', 68, fnt16_t)
#define GIO_FONT8x16 _IOR('c', 69, fnt16_t)
-#define CONS_GETINFO _IOR('c', 73, vid_info_t)
+#define CONS_GETINFO _IOWR('c', 73, vid_info_t)
#define CONS_GETVERS _IOR('c', 74, long)
#define CONS_80x25TEXT _IO('c', 102)
#define CONS_80x50TEXT _IO('c', 103)
@@ -124,16 +124,19 @@ struct vt_mode {
#define NUM_STATES 8 /* states per key */
#define ALTGR_OFFSET 128 /* offset for altlock keys */
+struct key_t {
+ u_char map[NUM_STATES];
+ u_char spcl;
+ u_char flgs;
+};
+
struct keymap {
u_short n_keys;
- struct key_t {
- u_char map[NUM_STATES];
- u_char spcl;
- u_char flgs;
- } key[NUM_KEYS];
+ struct key_t key[NUM_KEYS];
};
#define MAXFK 16
+#define NUM_FKEYS 60
struct fkeytab {
u_char str[MAXFK];
@@ -190,6 +193,7 @@ typedef struct ssaver ssaver_t;
#define NLK 0x05 /* num lock key */
#define SLK 0x06 /* scroll lock key */
#define LALT 0x07 /* left alt key */
+#define BTAB 0x08 /* backwards tab */
#define LCTR 0x09 /* left control key */
#define NEXT 0x0a /* switch to next screen */
#define F_SCR 0x0b /* switch to first screen */
@@ -214,11 +218,14 @@ typedef struct ssaver ssaver_t;
#define KB_STAT 0x64 /* kbd status port */
#define KB_BUF_FULL 0x01 /* kbd has char pending */
#define KB_READY 0x02 /* kbd ready for command */
+#define KB_MODE 0x4D /* kbd mode (trans, ints enable)*/
#define KB_WRITE 0x60 /* kbd write command */
-#define KB_SETLEDS 0xed /* kbd set leds */
-#define KB_SETRAD 0xf3 /* kbd set repeat&delay command */
-#define KB_ACK 0xfa /* kbd acknowledge answer */
-#define KB_RESET_CPU 0xfe /* kbd reset main cpu command */
-#define KB_RESET 0xff /* kbd reset */
+#define KB_RESET_DONE 0xAA /* kbd reset command completed */
+#define KB_SETLEDS 0xED /* kbd set leds */
+#define KB_ECHO 0xEE /* kbd set leds */
+#define KB_SETRAD 0xF3 /* kbd set repeat&delay command */
+#define KB_ACK 0xFA /* kbd acknowledge answer */
+#define KB_RESEND 0xFE /* kbd resend cmd answer */
+#define KB_RESET 0xFF /* kbd reset */
#endif
diff --git a/sys/i386/include/cpu.h b/sys/i386/include/cpu.h
index 184f5b86151d..82ab4c3734dc 100644
--- a/sys/i386/include/cpu.h
+++ b/sys/i386/include/cpu.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)cpu.h 5.4 (Berkeley) 5/9/91
- * $Id: cpu.h,v 1.4 1993/11/07 17:42:46 wollman Exp $
+ * $Id: cpu.h,v 1.5 1994/04/02 07:00:35 davidg Exp $
*/
#ifndef _MACHINE_CPU_H_
@@ -58,18 +58,21 @@
* Arguments to hardclock, softclock and gatherstats
* encapsulate the previous machine state in an opaque
* clockframe; for now, use generic intrframe.
+ * XXX softclock() has been fixed. It never needed a
+ * whole frame, only a usermode flag, at least on this
+ * machine. Fix the rest.
*/
typedef struct intrframe clockframe;
#define CLKF_USERMODE(framep) (ISPL((framep)->if_cs) == SEL_UPL)
-#define CLKF_BASEPRI(framep) ((framep)->if_ppl == 0)
+#define CLKF_BASEPRI(framep) (((framep)->if_ppl & ~SWI_AST_MASK) == 0)
#define CLKF_PC(framep) ((framep)->if_eip)
/*
* Preempt the current process if in interrupt from user mode,
* or after the current trap/syscall if in system mode.
*/
-#define need_resched() { want_resched++; aston(); }
+#define need_resched() { want_resched = 1; aston(); }
/*
* Give a profiling tick to the current process from the softclock
@@ -84,7 +87,8 @@ typedef struct intrframe clockframe;
*/
#define signotify(p) aston()
-#define aston() (astpending++)
+#define aston() setsoftast()
+#define astoff()
/*
* pull in #defines for kinds of processors
@@ -97,7 +101,6 @@ struct cpu_nameclass {
};
#ifdef KERNEL
-extern int astpending; /* want a trap before returning to user mode */
extern int want_resched; /* resched was called */
extern int cpu;
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index 65cc855793f0..16bb63b86a17 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -2,7 +2,7 @@
* Functions to provide access to special i386 instructions.
* XXX - bezillions more are defined in locore.s but are not declared anywhere.
*
- * $Id: cpufunc.h,v 1.9 1994/01/31 23:48:23 davidg Exp $
+ * $Id: cpufunc.h,v 1.11 1994/06/01 03:09:51 davidg Exp $
*/
#ifndef _MACHINE_CPUFUNC_H_
@@ -11,6 +11,8 @@
#include <sys/cdefs.h>
#include <sys/types.h>
+#include "machine/spl.h"
+
#ifdef __GNUC__
static inline int bdb(void)
@@ -69,6 +71,14 @@ tlbflush()
__asm __volatile("movl %%cr3, %%eax; movl %%eax, %%cr3" : : : "ax");
}
+static inline u_long
+rcr2()
+{
+ u_long data;
+ __asm __volatile("movl %%cr2,%%eax" : "=a" (data));
+ return data;
+}
+
static inline
int
imin(a, b)
@@ -224,7 +234,6 @@ void load_cr0 __P((u_int cr0));
u_int rcr0 __P((void));
void load_cr3(u_long);
u_long rcr3(void);
-u_long rcr2(void);
void setidt __P((int, void (*)(), int, int));
extern u_long kvtop(void *);
diff --git a/sys/i386/include/ioctl_fd.h b/sys/i386/include/ioctl_fd.h
index 2e3ac3104726..a8c17f69ac4a 100644
--- a/sys/i386/include/ioctl_fd.h
+++ b/sys/i386/include/ioctl_fd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1992-1993 by Joerg Wunsch, Dresden
+ * Copyright (C) 1992-1994 by Joerg Wunsch, Dresden
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -11,17 +11,18 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
*/
#ifndef _IOCTL_FD_H
@@ -94,5 +95,11 @@ struct fd_type {
#define FD_FORM _IOW('F', 61, struct fd_formb) /* format a track */
#define FD_GTYPE _IOR('F', 62, struct fd_type) /* get drive type */
+#define FD_STYPE _IOW('F', 63, struct fd_type) /* set drive type */
+
+#define FD_GOPTS _IOR('F', 64, int) /* drive options, see below */
+#define FD_SOPTS _IOW('F', 65, int)
+
+#define FDOPT_NORETRY 0x0001 /* no retries on failure (cleared on close) */
#endif /* !def _IOCTL_FD_H */
diff --git a/sys/i386/include/limits.h b/sys/i386/include/limits.h
index 568ad40848a3..586d6e2f5a69 100644
--- a/sys/i386/include/limits.h
+++ b/sys/i386/include/limits.h
@@ -31,15 +31,14 @@
* SUCH DAMAGE.
*
* from: @(#)limits.h 7.2 (Berkeley) 6/28/90
- * $Id: limits.h,v 1.4 1993/12/19 05:14:46 alm Exp $
+ * $Id: limits.h,v 1.6 1994/04/04 21:11:12 wollman Exp $
*/
#ifndef _MACHINE_LIMITS_H_
#define _MACHINE_LIMITS_H_ 1
#define CHAR_BIT 8 /* number of bits in a char */
-#define CLK_TCK 60 /* ticks per second */
-#define MB_LEN_MAX 1 /* no multibyte characters */
+#define MB_LEN_MAX 6 /* allow 21-bit UTF2 */
#define SCHAR_MIN (-0x7f-1) /* max value for a signed char */
#define SCHAR_MAX 0x7f /* min value for a signed char */
@@ -61,6 +60,7 @@
#define LONG_MIN (-0x7fffffff-1) /* min value for a long */
#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+#define CLK_TCK 128 /* ticks per second */
#define UQUAD_MAX 0xffffffffffffffffLL /* max unsigned quad */
#define QUAD_MAX 0x7fffffffffffffffLL /* max signed quad */
#define QUAD_MIN (-0x7fffffffffffffffLL-1) /* min signed quad */
diff --git a/sys/i386/include/lpt.h b/sys/i386/include/lpt.h
new file mode 100644
index 000000000000..87af5bcc5875
--- /dev/null
+++ b/sys/i386/include/lpt.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 1994 Geoffrey M. Rehmet
+ *
+ * This program is free software; you may redistribute it and/or
+ * modify it, provided that it retain the above copyright notice
+ * and the following disclaimer.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Geoff Rehmet, Rhodes University, South Africa <csgr@cs.ru.ac.za>
+ *
+ */
+
+#ifndef _LPT_PRINTER_H_
+#define _LPT_PRINTER_H_
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#define LPT_IRQ _IOW('p', 1, long) /* set interrupt status */
+
+#endif
diff --git a/sys/i386/include/mouse.h b/sys/i386/include/mouse.h
new file mode 100644
index 000000000000..95a66e474c6d
--- /dev/null
+++ b/sys/i386/include/mouse.h
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1992, 1993 Erik Forsberg.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ``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 I 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.
+ *
+ * $Id: mouse.h,v 1.1 1994/05/17 14:05:31 jkh Exp $
+ */
+
+struct mouseinfo {
+ unsigned char status;
+ char xmotion, ymotion;
+};
+
+#define BUTSTATMASK 0x07 /* Any mouse button down if any bit set */
+#define BUTCHNGMASK 0x38 /* Any mouse button changed if any bit set */
+
+#define BUT3STAT 0x01 /* Button 3 down if set */
+#define BUT2STAT 0x02 /* Button 2 down if set */
+#define BUT1STAT 0x04 /* Button 1 down if set */
+#define BUT3CHNG 0x08 /* Button 3 changed if set */
+#define BUT2CHNG 0x10 /* Button 2 changed if set */
+#define BUT1CHNG 0x20 /* Button 1 changed if set */
+#define MOVEMENT 0x40 /* Mouse movement detected */
+
+/* Ioctl definitions */
+
+#define MOUSEIOC ('M'<<8)
+#define MOUSEIOCREAD (MOUSEIOC|60)
diff --git a/sys/i386/include/npx.h b/sys/i386/include/npx.h
index ec29bf4fa024..168ef19fadd2 100644
--- a/sys/i386/include/npx.h
+++ b/sys/i386/include/npx.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)npx.h 5.3 (Berkeley) 1/18/91
- * $Id: npx.h,v 1.2 1993/10/16 14:39:22 rgrimes Exp $
+ * $Id: npx.h,v 1.3 1994/04/29 21:44:23 gclarkii Exp $
*/
/*
@@ -73,11 +73,13 @@ struct fpacc87 {
struct save87 {
struct env87 sv_env; /* floating point control/status */
struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */
-#ifndef dontdef
u_long sv_ex_sw; /* status word for last exception (was pad) */
u_long sv_ex_tw; /* tag word for last exception (was pad) */
- u_char sv_pad[8 * 2 - 2 * 4]; /* bogus historical padding */
-#endif
+#ifdef GPL_MATH_EMULATE
+ u_char sv_pad[60];
+#else
+ u_char sv_pad[8 * 2 - 2 * 4]; /* bogus historical padding */
+#endif /* GPL_MATH_EMULATE */
};
/* Cyrix EMC memory - mapped coprocessor context switch information */
diff --git a/sys/i386/include/param.h b/sys/i386/include/param.h
index fe97ad809b25..953ebb9d36c4 100644
--- a/sys/i386/include/param.h
+++ b/sys/i386/include/param.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)param.h 5.8 (Berkeley) 6/28/91
- * $Id: param.h,v 1.13 1994/01/31 04:18:54 davidg Exp $
+ * $Id: param.h,v 1.14 1994/03/07 11:38:47 davidg Exp $
*/
#ifndef _MACHINE_PARAM_H_
@@ -62,7 +62,7 @@
#define PAGE_SIZE (1 << PAGE_SHIFT)
#define PAGE_MASK (PAGE_SIZE-1)
#define PGOFSET (NBPG-1) /* byte offset into page */
-#define NPTEPG (NBPG/(sizeof (struct pte)))
+#define NPTEPG (NBPG/(sizeof (pt_entry_t)))
/* XXX PDRSHIFT and PD_SHIFT are two names for the same thing */
#define PDRSHIFT 22 /* LOG2(NBPDR) */
@@ -103,7 +103,7 @@
#endif /* MSIZE */
#ifndef MCLSHIFT
-#define MCLSHIFT 11 /* convert bytes to m_buf clusters */
+#define MCLSHIFT 12 /* convert bytes to m_buf clusters */
#endif /* MCLSHIFT */
#define MCLBYTES (1 << MCLSHIFT) /* size of an m_buf cluster */
#define MCLOFSET (MCLBYTES - 1) /* offset within an m_buf cluster */
diff --git a/sys/i386/include/pcaudioio.h b/sys/i386/include/pcaudioio.h
new file mode 100644
index 000000000000..71c7ebb4c226
--- /dev/null
+++ b/sys/i386/include/pcaudioio.h
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1994 Søren Schmidt
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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.
+ *
+ * $Id: pcaudioio.h,v 1.2 1994/05/20 12:22:40 sos Exp $
+ */
+
+#ifndef _PCAUDIOIO_H_
+#define _PCAUDIOIO_H_
+
+typedef struct audio_prinfo {
+ unsigned sample_rate; /* samples per second */
+ unsigned channels; /* # of channels (interleaved) */
+ unsigned precision; /* sample size in bits */
+ unsigned encoding; /* encoding method used */
+
+ unsigned gain; /* volume level: 0 - 255 */
+ unsigned port; /* input/output device */
+ unsigned _fill1[4];
+
+ unsigned samples; /* samples played */
+ unsigned eof; /* ?!? */
+ unsigned char pause; /* !=0 pause, ==0 continue */
+ unsigned char error; /* !=0 if overflow/underflow */
+ unsigned char waiting; /* !=0 if others wants access */
+ unsigned char _fill2[3];
+
+ unsigned char open; /* is device open */
+ unsigned char active; /* !=0 if sound hardware is active */
+} audio_prinfo_t;
+
+typedef struct audio_info {
+ audio_prinfo_t play;
+ audio_prinfo_t record;
+ unsigned monitor_gain;
+ unsigned _fill[4];
+} audio_info_t;
+
+#define AUDIO_ENCODING_ULAW (1) /* u-law encoding */
+#define AUDIO_ENCODING_ALAW (2) /* A-law encoding */
+#define AUDIO_ENCODING_RAW (3) /* linear encoding */
+
+#define AUDIO_MIN_GAIN (0) /* minimum volume value */
+#define AUDIO_MAX_GAIN (255) /* maximum volume value */
+
+#define AUDIO_INITINFO(i) memset((void*)i, 0xff, sizeof(audio_info_t))
+
+#define AUDIO_GETINFO _IOR('A', 1, audio_info_t)
+#define AUDIO_SETINFO _IOWR('A', 2, audio_info_t)
+#define AUDIO_DRAIN _IO('A', 3)
+#define AUDIO_FLUSH _IO('A', 4)
+
+#endif /*!_PCAUDIOIO_H*/
diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h
index ba27f793735d..507baf94b356 100644
--- a/sys/i386/include/pmap.h
+++ b/sys/i386/include/pmap.h
@@ -42,7 +42,7 @@
*
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
- * $Id: pmap.h,v 1.10 1994/01/31 04:19:00 davidg Exp $
+ * $Id: pmap.h,v 1.16 1994/06/07 17:48:46 davidg Exp $
*/
#ifndef _PMAP_MACHINE_
@@ -58,7 +58,8 @@ struct pde
unsigned int
pd_v:1, /* valid bit */
pd_prot:2, /* access control */
- pd_mbz1:2, /* reserved, must be zero */
+ pd_ncpwt:1, /* page cache write through */
+ pd_ncpcd:1, /* page cache disable */
pd_u:1, /* hardware maintained 'used' bit */
:1, /* not used */
pd_mbz2:2, /* reserved, must be zero */
@@ -76,7 +77,8 @@ struct pte
unsigned int
pg_v:1, /* valid bit */
pg_prot:2, /* access control */
- pg_mbz1:2, /* reserved, must be zero */
+ pg_ncpwt:1, /* page cache write through */
+ pg_ncpcd:1, /* page cache disable */
pg_u:1, /* hardware maintained 'used' bit */
pg_m:1, /* hardware maintained modified bit */
pg_mbz2:2, /* reserved, must be zero */
@@ -91,10 +93,12 @@ unsigned int
#define PG_RW 0x00000002
#define PG_u 0x00000004
#define PG_PROT 0x00000006 /* all protection bits . */
-#define PG_W 0x00000200
-#define PG_N 0x00000800 /* Non-cacheable */
-#define PG_M 0x00000040
+#define PG_NC_PWT 0x00000008 /* page cache write through */
+#define PG_NC_PCD 0x00000010 /* page cache disable */
+#define PG_N 0x00000018 /* Non-cacheable */
#define PG_U 0x00000020
+#define PG_M 0x00000040
+#define PG_W 0x00000200
#define PG_FRAME 0xfffff000UL
#define PG_NOACC 0
@@ -115,8 +119,10 @@ unsigned int
#define PGEX_W 0x02 /* during a Write cycle */
#define PGEX_U 0x04 /* access from User mode (UPL) */
-typedef struct pde pd_entry_t; /* page directory entry */
-typedef struct pte pt_entry_t; /* Mach page table entry */
+/* typedef struct pde pd_entry_t; */ /* page directory entry */
+/* typedef struct pte pt_entry_t; */ /* Mach page table entry */
+typedef unsigned int *pd_entry_t;
+typedef unsigned int *pt_entry_t;
/*
* NKPDE controls the virtual space of the kernel, what ever is left, minus
@@ -145,18 +151,18 @@ typedef struct pte pt_entry_t; /* Mach page table entry */
#define KPTDI (APTDPTDI-NKPDE)/* start of kernel virtual pde's */
#define PTDPTDI (KPTDI-1) /* ptd entry that points to ptd! */
#define KSTKPTDI (PTDPTDI-1) /* ptd entry for u./kernel&user stack */
-#define KSTKPTEOFF (NBPG/sizeof(struct pde)-UPAGES) /* pte entry for kernel stack */
+#define KSTKPTEOFF (NBPG/sizeof(pd_entry_t)-UPAGES) /* pte entry for kernel stack */
-#define PDESIZE sizeof(struct pde) /* for assembly files */
-#define PTESIZE sizeof(struct pte) /* for assembly files */
+#define PDESIZE sizeof(pd_entry_t) /* for assembly files */
+#define PTESIZE sizeof(pt_entry_t) /* for assembly files */
/*
* Address of current and alternate address space page table maps
* and directories.
*/
#ifdef KERNEL
-extern struct pte PTmap[], APTmap[], Upte;
-extern struct pde PTD[], APTD[], PTDpde, APTDpde, Upde;
+extern pt_entry_t PTmap[], APTmap[], Upte;
+extern pd_entry_t PTD[], APTD[], PTDpde, APTDpde, Upde;
extern pt_entry_t *Sysmap;
extern int IdlePTD; /* physical address of "Idle" state directory */
@@ -171,12 +177,29 @@ extern int IdlePTD; /* physical address of "Idle" state directory */
#define vtopte(va) (PTmap + i386_btop(va))
#define kvtopte(va) vtopte(va)
#define ptetov(pt) (i386_ptob(pt - PTmap))
-#define vtophys(va) (i386_ptob(vtopte(va)->pg_pfnum) | ((int)(va) & PGOFSET))
+#define vtophys(va) (((int) (*vtopte(va))&PG_FRAME) | ((int)(va) & PGOFSET))
#define ispt(va) ((va) >= UPT_MIN_ADDRESS && (va) <= KPT_MAX_ADDRESS)
#define avtopte(va) (APTmap + i386_btop(va))
#define ptetoav(pt) (i386_ptob(pt - APTmap))
-#define avtophys(va) (i386_ptob(avtopte(va)->pg_pfnum) | ((int)(va) & PGOFSET))
+#define avtophys(va) (((int) (*avtopte(va))&PG_FRAME) | ((int)(va) & PGOFSET))
+
+#ifdef KERNEL
+/*
+ * Routine: pmap_kextract
+ * Function:
+ * Extract the physical page address associated
+ * kernel virtual address.
+ */
+static inline vm_offset_t
+pmap_kextract(va)
+ vm_offset_t va;
+{
+ vm_offset_t pa = *(int *)vtopte(va);
+ pa = (pa & PG_FRAME) | (va & ~PG_FRAME);
+ return pa;
+}
+#endif
/*
* macros to generate page directory/table indicies
@@ -252,7 +275,7 @@ extern void pmap_remove(struct pmap *, vm_offset_t, vm_offset_t);
extern void pmap_protect(struct pmap *, vm_offset_t, vm_offset_t, vm_prot_t);
extern void pmap_enter(pmap_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t);
extern void pmap_change_wiring(pmap_t, vm_offset_t, boolean_t);
-extern inline struct pte *pmap_pte(pmap_t, vm_offset_t);
+extern inline pt_entry_t * const pmap_pte(pmap_t, vm_offset_t);
extern vm_offset_t pmap_extract(pmap_t, vm_offset_t);
extern void pmap_copy(pmap_t, pmap_t, vm_offset_t, vm_size_t, vm_offset_t);
extern void pmap_collect(pmap_t);
diff --git a/sys/i386/include/psl.h b/sys/i386/include/psl.h
index eb15d181b464..c877648ee796 100644
--- a/sys/i386/include/psl.h
+++ b/sys/i386/include/psl.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)psl.h 5.2 (Berkeley) 1/18/91
- * $Id: psl.h,v 1.3.2.1 1994/03/07 01:23:56 rgrimes Exp $
+ * $Id: psl.h,v 1.5 1994/06/07 23:53:52 phk Exp $
*/
#ifndef _MACHINE_PSL_H_
@@ -56,6 +56,10 @@
#define PSL_NT 0x00004000 /* nested task bit */
#define PSL_RF 0x00010000 /* restart flag bit */
#define PSL_VM 0x00020000 /* virtual 8086 mode bit */
+#define PSL_AC 0x00040000 /* alignment checking */
+#define PSL_VIF 0x00080000 /* virtual interrupt enable */
+#define PSL_VIP 0x00100000 /* virtual interrupt pending */
+#define PSL_ID 0x00200000 /* identification bit */
#define PSL_MBZ 0xffc08028 /* must be zero bits */
#define PSL_MBO 0x00000002 /* must be one bits */
diff --git a/sys/i386/include/pte.h b/sys/i386/include/pte.h
index ac0cb541de95..4b1f71091e2b 100644
--- a/sys/i386/include/pte.h
+++ b/sys/i386/include/pte.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)pte.h 5.5 (Berkeley) 5/9/91
- * $Id: pte.h,v 1.4 1994/01/31 06:52:41 davidg Exp $
+ * $Id: pte.h,v 1.5 1994/03/07 11:38:49 davidg Exp $
*/
#ifndef _MACHINE_PTE_H_
@@ -114,7 +114,7 @@ unsigned int
/*
* Pte related macros
*/
-#define dirty(pte) ((pte)->pg_m)
+#define dirty(pte) ((pte) & PG_M)
#ifndef LOCORE
#ifdef KERNEL
diff --git a/sys/i386/include/soundcard.h b/sys/i386/include/soundcard.h
index 23f20313d98a..ce28a144242d 100644
--- a/sys/i386/include/soundcard.h
+++ b/sys/i386/include/soundcard.h
@@ -1,5 +1,5 @@
#ifndef _SOUNDCARD_H_
-#define _SOUNDCARD_H_ 1
+#define _SOUNDCARD_H_
/*
* Copyright by Hannu Savolainen 1993
*
@@ -30,14 +30,15 @@
/*
* If you make modifications to this file, please contact me before
* distributing the modified version. There is already enough
- * diversity in the world.
+ * divercity in the world.
*
* Regards,
* Hannu Savolainen
- * hsavolai@cs.helsinki.fi
+ * hannu@voxware.pp.fi, Hannu.Savolainen@helsinki.fi
*/
-#define SOUND_VERSION 200
+#define SOUND_VERSION 205
+#define VOXWARE
#include <sys/ioctl.h>
@@ -50,6 +51,8 @@
#define SNDCARD_PAS 3
#define SNDCARD_GUS 4
#define SNDCARD_MPU401 5
+#define SNDCARD_SB16 6
+#define SNDCARD_SB16MIDI 7
/***********************************
* IOCTL Commands for /dev/sequencer
@@ -66,9 +69,9 @@
*/
/* #define IOCTYPE (0xff<<8) */
#define IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */
-#define IOC_VOID 0x20000000 /* no parameters */
-#define IOC_OUT 0x40000000 /* copy out parameters */
-#define IOC_IN 0x80000000 /* copy in parameters */
+#define IOC_VOID 0x00000000 /* no parameters */
+#define IOC_OUT 0x20000000 /* copy out parameters */
+#define IOC_IN 0x40000000 /* copy in parameters */
#define IOC_INOUT (IOC_IN|IOC_OUT)
/* the 0x20000000 is so we can distinguish new ioctl's from old */
#define _IO(x,y) ((int)(IOC_VOID|(x<<8)|y))
@@ -180,7 +183,7 @@ struct patch_info {
int volume;
int spare[4];
- char data[0]; /* The waveform data starts here */
+ char data[1]; /* The waveform data starts here */
};
@@ -307,6 +310,14 @@ struct patmgr_info { /* Note! size must be < 4k since kmalloc() is used */
#define CTRL_EXPRESSION 253
#define CTRL_MAIN_VOLUME 252
#define SEQ_BALANCE 11
+#define SEQ_VOLMODE 12
+
+/*
+ * Volume mode decides how volumes are used
+ */
+
+#define VOL_METHOD_ADAGIO 1
+#define VOL_METHOD_LINEAR 2
/*
* Note! SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO are used also as
@@ -402,7 +413,8 @@ struct midi_info {
char name[30];
int device; /* 0-N. INITIALIZE BEFORE CALLING */
unsigned long capabilities; /* To be defined later */
- int dummies[19]; /* Reserve space */
+ int dev_type;
+ int dummies[18]; /* Reserve space */
};
/********************************************
@@ -418,6 +430,7 @@ struct midi_info {
#define SOUND_PCM_WRITE_CHANNELS _IOWR('P', 6, int)
#define SOUND_PCM_WRITE_FILTER _IOWR('P', 7, int)
#define SNDCTL_DSP_POST _IO ('P', 8)
+#define SNDCTL_DSP_SUBDIVIDE _IOWR('P', 9, int)
#define SOUND_PCM_READ_RATE _IOR ('P', 2, int)
#define SOUND_PCM_READ_CHANNELS _IOR ('P', 6, int)
@@ -430,6 +443,7 @@ struct midi_info {
#define SOUND_PCM_POST SNDCTL_DSP_POST
#define SOUND_PCM_RESET SNDCTL_DSP_RESET
#define SOUND_PCM_SYNC SNDCTL_DSP_SYNC
+#define SOUND_PCM_SUBDIVIDE SNDCTL_DSP_SUBDIVIDE
/*********************************************
* IOCTL commands for /dev/mixer
@@ -624,7 +638,8 @@ void seqbuf_dump(void); /* This function must be provided by programs */
* }
*/
-#define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len, _seqbufptr = 0
+#define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len; int _seqbufptr = 0
+#define SEQ_DECLAREBUF() extern unsigned char _seqbuf[]; extern int _seqbuflen;extern int _seqbufptr
#define SEQ_PM_DEFINES struct patmgr_info _pm_info
#define _SEQ_NEEDBUF(len) if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump()
#define _SEQ_ADVBUF(len) _seqbufptr += len
@@ -638,6 +653,17 @@ void seqbuf_dump(void); /* This function must be provided by programs */
_pm_info.parm1 = bank, _pm_info.parm2 = 128, \
ioctl(seqfd, SNDCTL_PMGR_ACCESS, &_pm_info))
+#define SEQ_VOLUME_MODE(dev, mode) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+ _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;\
+ _seqbuf[_seqbufptr+2] = (dev);\
+ _seqbuf[_seqbufptr+3] = (mode);\
+ _seqbuf[_seqbufptr+4] = 0;\
+ _seqbuf[_seqbufptr+5] = 0;\
+ _seqbuf[_seqbufptr+6] = 0;\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+
#define SEQ_START_NOTE(dev, voice, note, vol) {_SEQ_NEEDBUF(8);\
_seqbuf[_seqbufptr] = SEQ_EXTENDED;\
_seqbuf[_seqbufptr+1] = SEQ_NOTEON;\
@@ -728,8 +754,8 @@ void seqbuf_dump(void); /* This function must be provided by programs */
_seqbuf[_seqbufptr+2] = (device);\
_seqbuf[_seqbufptr+3] = 0;\
_SEQ_ADVBUF(4);}
-#define SEQ_WRPATCH(patch, len) {if (_seqbufptr) seqbuf_dump();\
- if (write(seqfd, (char*)(patch), len)==-1) \
+#define SEQ_WRPATCH(patchx, len) {if (_seqbufptr) seqbuf_dump();\
+ if (write(seqfd, (char*)(patchx), len)==-1) \
perror("Write patch: /dev/sequencer");}
#endif
diff --git a/sys/i386/include/spl.h b/sys/i386/include/spl.h
new file mode 100644
index 000000000000..0be93644a463
--- /dev/null
+++ b/sys/i386/include/spl.h
@@ -0,0 +1,104 @@
+#ifndef _MACHINE_IPL_H_
+#define _MACHINE_IPL_H_
+
+#include "machine/../isa/ipl.h" /* XXX "machine" means cpu for i386 */
+
+/*
+ * Software interrupt bit numbers in priority order. The priority only
+ * determines which swi will be dispatched next; a higher priority swi
+ * may be dispatched when a nested h/w interrupt handler returns.
+ */
+#define SWI_TTY (NHWI + 0)
+#define SWI_NET (NHWI + 1)
+#define SWI_CLOCK 30
+#define SWI_AST 31
+
+/*
+ * Corresponding interrupt-pending bits for ipending.
+ */
+#define SWI_TTY_PENDING (1 << SWI_TTY)
+#define SWI_NET_PENDING (1 << SWI_NET)
+#define SWI_CLOCK_PENDING (1 << SWI_CLOCK)
+#define SWI_AST_PENDING (1 << SWI_AST)
+
+/*
+ * Corresponding interrupt-disable masks for cpl. The ordering is now by
+ * inclusion (where each mask is considered as a set of bits). Everything
+ * except SWI_AST_MASK includes SWI_CLOCK_MASK so that softclock() doesn't
+ * run while other swi handlers are running and timeout routines can call
+ * swi handlers. Everything includes SWI_AST_MASK so that AST's are masked
+ * until just before return to user mode.
+ */
+#define SWI_TTY_MASK (SWI_TTY_PENDING | SWI_CLOCK_MASK)
+#define SWI_NET_MASK (SWI_NET_PENDING | SWI_CLOCK_MASK)
+#define SWI_CLOCK_MASK (SWI_CLOCK_PENDING | SWI_AST_MASK)
+#define SWI_AST_MASK SWI_AST_PENDING
+#define SWI_MASK (~HWI_MASK)
+
+#ifndef LOCORE
+
+extern unsigned bio_imask; /* group of interrupts masked with splbio() */
+extern unsigned cpl; /* current priority level mask */
+extern unsigned high_imask; /* group of interrupts masked with splhigh() */
+extern unsigned net_imask; /* group of interrupts masked with splimp() */
+extern volatile unsigned ipending; /* active interrupts masked by cpl */
+extern volatile unsigned netisr;
+extern unsigned tty_imask; /* group of interrupts masked with spltty() */
+
+/*
+ * ipending has to be volatile so that it is read every time it is accessed
+ * in splx() and spl0(), but we don't want it to be read nonatomically when
+ * it is changed. Pretending that ipending is a plain int happens to give
+ * suitable atomic code for "ipending |= constant;".
+ */
+#define setsoftast() (*(unsigned *)&ipending |= SWI_AST_PENDING)
+#define setsoftclock() (*(unsigned *)&ipending |= SWI_CLOCK_PENDING)
+#define setsoftnet() (*(unsigned *)&ipending |= SWI_NET_PENDING)
+#define setsofttty() (*(unsigned *)&ipending |= SWI_TTY_PENDING)
+
+void unpend_V __P((void));
+
+#ifdef __GNUC__
+
+void splz __P((void));
+
+#define GENSPL(name, set_cpl) \
+static __inline int name(void) \
+{ \
+ unsigned x; \
+ \
+ x = cpl; \
+ set_cpl; \
+ return (x); \
+}
+
+GENSPL(splbio, cpl |= bio_imask)
+GENSPL(splclock, cpl = HWI_MASK | SWI_MASK)
+GENSPL(splhigh, cpl = HWI_MASK | SWI_MASK)
+GENSPL(splimp, cpl |= net_imask)
+GENSPL(splnet, cpl |= SWI_NET_MASK)
+GENSPL(splsoftclock, cpl = SWI_CLOCK_MASK)
+GENSPL(splsofttty, cpl |= SWI_TTY_MASK)
+GENSPL(spltty, cpl |= tty_imask)
+
+static __inline void
+spl0(void)
+{
+ cpl = SWI_AST_MASK;
+ if (ipending & ~SWI_AST_MASK)
+ splz();
+}
+
+static __inline void
+splx(int ipl)
+{
+ cpl = ipl;
+ if (ipending & ~ipl)
+ splz();
+}
+
+#endif /* __GNUC__ */
+
+#endif /* LOCORE */
+
+#endif /* _MACHINE_IPL_H_ */
diff --git a/sys/i386/include/ultrasound.h b/sys/i386/include/ultrasound.h
index 9b6e78fbadce..40e2443e6f65 100644
--- a/sys/i386/include/ultrasound.h
+++ b/sys/i386/include/ultrasound.h
@@ -32,12 +32,6 @@
* and not portable.
*/
-#ifdef linux
-#include <linux/soundcard.h>
-#else
-#include <machine/soundcard.h>
-#endif
-
/*
* Private events for Gravis Ultrasound (GUS)
*
@@ -90,6 +84,7 @@
#define _GUS_VOICEFADE 0x0d
#define _GUS_VOLUME_SCALE 0x0e
#define _GUS_VOICEVOL2 0x0f
+#define _GUS_VOICE_POS 0x10
/*
* GUS API macros
@@ -120,5 +115,7 @@
#define GUS_RAMPON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPON, (p1), 0)
#define GUS_RAMPOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_RAMPOFF, 0, 0)
#define GUS_VOLUME_SCALE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_VOLUME_SCALE, (p1), (p2))
+#define GUS_VOICE_POS(chn, voice, p) _GUS_CMD(chn, voice, _GUS_VOICE_POS, \
+ (p) & 0xffff, ((p) >> 16) & 0xffff)
#endif
diff --git a/sys/i386/include/vmparam.h b/sys/i386/include/vmparam.h
index a5b657cd82c2..c5ed04dde346 100644
--- a/sys/i386/include/vmparam.h
+++ b/sys/i386/include/vmparam.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)vmparam.h 5.9 (Berkeley) 5/12/91
- * $Id: vmparam.h,v 1.11.2.1 1994/03/24 08:57:03 rgrimes Exp $
+ * $Id: vmparam.h,v 1.12 1994/03/21 09:35:24 davidg Exp $
*/
diff --git a/sys/i386/isa/aha1542.c b/sys/i386/isa/aha1542.c
index efeee385ba51..df1e3cada643 100644
--- a/sys/i386/isa/aha1542.c
+++ b/sys/i386/isa/aha1542.c
@@ -12,7 +12,7 @@
* on the understanding that TFS is not responsible for the correct
* functioning of this software in any circumstances.
*
- * $Id: aha1542.c,v 1.20.2.2 1994/05/03 05:16:50 rgrimes Exp $
+ * $Id: aha1542.c,v 1.27 1994/06/05 19:18:10 ats Exp $
*/
/*
@@ -299,8 +299,8 @@ struct aha_data {
struct aha_ccb *aha_ccb_free; /* the next free ccb */
struct aha_ccb aha_ccb[AHA_MBX_SIZE]; /* all the CCBs */
int aha_int; /* our irq level */
- int aha_dma; /* out DMA req channel */
- int aha_scsi_dev; /* ourscsi bus address */
+ int aha_dma; /* our DMA req channel */
+ int aha_scsi_dev; /* our scsi bus address */
struct scsi_link sc_link; /* prototype for subdevs */
} *ahadata[NAHA];
@@ -589,6 +589,7 @@ ahaattach(dev)
aha->sc_link.adapter_targ = aha->aha_scsi_dev;
aha->sc_link.adapter = &aha_switch;
aha->sc_link.device = &aha_dev;
+ aha->sc_link.flags = SDEV_BOUNCE;
/*
* ask the adapter what subunits are present
@@ -741,7 +742,7 @@ aha_get_ccb(unit, flags)
* to come free
*/
while ((!(rc = aha->aha_ccb_free)) && (!(flags & SCSI_NOSLEEP))) {
- sleep(&aha->aha_ccb_free, PRIBIO);
+ tsleep((caddr_t)&aha->aha_ccb_free, PRIBIO, "ahaccb", 0);
}
if (rc) {
aha->aha_ccb_free = aha->aha_ccb_free->next;
@@ -916,7 +917,7 @@ aha_init(unit)
#ifdef AHADEBUG
printf("aha%d: extended bios flags %x\n", unit, extbios.flags);
#endif /* AHADEBUG */
- printf("aha%d: 1542C/CF detected, unlocking mailbox\n");
+ printf("aha%d: 1542C/CF detected, unlocking mailbox\n", unit);
aha_cmd(unit, 2, 0, 0, 0, AHA_MBX_ENABLE,
0, extbios.mailboxlock);
}
@@ -1006,7 +1007,7 @@ aha_init(unit)
return (EIO);
}
#else
- printf ("\n");
+ printf (" (bus speed defaulted)\n");
#endif /*TUNE_1542*/
/*
* Initialize mail box
diff --git a/sys/i386/isa/bt742a.c b/sys/i386/isa/bt742a.c
index e160e9167cb1..990344f28ea6 100644
--- a/sys/i386/isa/bt742a.c
+++ b/sys/i386/isa/bt742a.c
@@ -12,7 +12,7 @@
* on the understanding that TFS is not responsible for the correct
* functioning of this software in any circumstances.
*
- * $Id: bt742a.c,v 1.12 1993/12/19 00:50:29 wollman Exp $
+ * $Id: bt742a.c,v 1.22 1994/06/15 04:19:23 jkh Exp $
*/
/*
@@ -126,7 +126,7 @@ struct bt_cmd_buf {
* these could be bigger but we need the bt_data to fit on a single page..
*/
-#define BT_MBX_SIZE 16 /* mail box size (MAX 255 MBxs) */
+#define BT_MBX_SIZE 32 /* mail box size (MAX 255 MBxs) */
/* don't need that many really */
#define BT_CCB_MAX 32 /* store up to 32CCBs at any one time */
/* in bt742a H/W ( Not MAX ? ) */
@@ -299,6 +299,21 @@ struct bt_config {
u_char :5;
};
+/*
+ * Determin 32bit address/Data firmware functionality from Bus type
+ * Note: bt742a/747[s|d]/757/946/445s will return 'E'
+ * bt542b/545s/545d will be return 'A'
+ * 94/05/18 amurai@spec.co.jp
+ */
+#define BT_BUS_TYPE_24bit 'A' /* PC/AT 24 bit address bus type */
+#define BT_BUS_TYPE_32bit 'E' /* EISA/VLB/PCI 32 bit address bus type */
+#define BT_BUS_TYPE_MCA 'M' /* Micro chanel is ? forget it right now */
+struct bt_ext_info {
+ u_char bus_type; /* Host adapter bus type */
+ u_char bios_addr; /* Bios Address-Not use*/
+ u_short max_seg; /* Max segment List */
+};
+
#define INT9 0x01
#define INT10 0x02
#define INT11 0x04
@@ -568,7 +583,8 @@ btprobe(dev)
}
/*
* If it's there, put in it's interrupt vectors
- */ dev->id_unit = unit;
+ */
+ dev->id_unit = unit;
dev->id_irq = (1 << bt->bt_int);
dev->id_drq = bt->bt_dma;
@@ -593,6 +609,7 @@ btattach(dev)
bt->sc_link.adapter_targ = bt->bt_scsi_dev;
bt->sc_link.adapter = &bt_switch;
bt->sc_link.device = &bt_dev;
+ bt->sc_link.flags = SDEV_BOUNCE;
/*
* ask the adapter what subunits are present
@@ -818,7 +835,8 @@ bt_get_ccb(unit, flags)
goto gottit;
} else {
if (!(flags & SCSI_NOSLEEP)) {
- sleep(&bt->bt_ccb_free, PRIBIO);
+ tsleep((caddr_t)&bt->bt_ccb_free, PRIBIO,
+ "btccb", 0);
}
}
}
@@ -987,6 +1005,7 @@ bt_init(unit)
unsigned char ad[4];
volatile int i, sts;
struct bt_config conf;
+ struct bt_ext_info info;
/*
* reset board, If it doesn't respond, assume
@@ -1008,6 +1027,32 @@ bt_init(unit)
return (ENXIO);
}
/*
+ * Make sure board has a capability of 32bit addressing.
+ * and Firmware also need a capability of 32bit addressing pointer
+ * in Extended mailbox and ccb structure.
+ * 94/05/18 amurai@spec.co.jp
+ */
+ bt_cmd(unit, 1, sizeof(info),0,&info, BT_INQUIRE_EXTENDED,sizeof(info));
+ switch (info.bus_type) {
+ case BT_BUS_TYPE_24bit: /* PC/AT 24 bit address bus */
+ printf("bt%d: bt54x-ISA(24bit) bus detected\n", unit);
+ break;
+ case BT_BUS_TYPE_32bit: /* EISA/VLB/PCI 32 bit bus */
+ printf("bt%d: PCI/EISA/VLB(32bit) bus detected\n",unit);
+ break;
+ case BT_BUS_TYPE_MCA: /* forget it right now */
+ printf("bt%d: MCA bus architecture detected..", unit);
+ printf("[giving up]\n");
+ return (ENXIO);
+ break;
+ default:
+ printf("bt%d: Unknown state detected...", unit);
+ printf("[giving up]\n");
+ return (ENXIO);
+ break;
+ }
+
+ /*
* Assume we have a board at this stage
* setup dma channel from jumpers and save int
* level
@@ -1107,8 +1152,6 @@ bt_init(unit)
bt->bt_mbx.tmbi = &bt->bt_mbx.mbi[0];
bt_inquire_setup_information(unit);
- /* Enable round-robin scheme - appeared at firmware rev. 3.31 */
- bt_cmd(unit, 1, 0, 0, 0, BT_ROUND_ROBIN, BT_ENABLE);
/*
* Note that we are going and return (to probe)
@@ -1122,9 +1165,14 @@ bt_inquire_setup_information(unit)
{
struct bt_data *bt = btdata[unit];
struct bt_setup setup;
+ char dummy[8];
struct bt_boardID bID;
int i;
+ /* Inquire Installed Devices */
+ bzero( &dummy[0], sizeof(dummy) );
+ bt_cmd(unit, 0, sizeof(dummy), 10, &dummy[0], BT_DEV_GET);
+
/* Inquire Board ID to Bt742 for firmware version */
bt_cmd(unit, 0, sizeof(bID), 0, &bID, BT_INQUIRE);
printf("bt%d: version %c.%c, ",
@@ -1143,19 +1191,37 @@ bt_inquire_setup_information(unit)
} else {
printf("no parity, ");
}
- printf("%d mbxs, %d ccbs\n", setup.num_mbx, bt->numccbs);
+ printf("%d mbxs, %d ccbs\n", setup.num_mbx, BT_CCB_MAX);
+
+ /*
+ * Displaying SCSI negotiation value by each target.
+ * How can I determin FAST scsi value? XXX amurai@spec.co.jp
+ */
for (i = 0; i < 8; i++) {
- if (!setup.sync[i].offset &&
- !setup.sync[i].period &&
- !setup.sync[i].valid)
+ if (!setup.sync[i].valid)
continue;
+ if (!setup.sync[i].offset && !setup.sync[i].period )
+ printf("bt%d: targ %d async\n", unit, i);
+ else
+ printf("bt%d: targ %d offset=%02d, period=%dnsec\n",
+ unit, i,
+ setup.sync[i].offset,
+ 200 + setup.sync[i].period * 50 );
+ }
- printf("bt%d: dev%02d Offset=%d,Transfer period=%d, Synchronous? %s",
- unit, i,
- setup.sync[i].offset, setup.sync[i].period,
- setup.sync[i].valid ? "Yes" : "No");
+ /*
+ * Enable round-robin scheme - appeared at firmware rev. 3.31
+ * Below rev 2.XX firmware has a problem for issuing
+ * BT_ROUND_ROBIN command amurai@spec.co.jp
+ */
+ if ( bID.firm_revision != '2' ) {
+ printf("bt%d: Enabling Round robin scheme\n", unit);
+ bt_cmd(unit, 1, 0, 0, 0, BT_ROUND_ROBIN, BT_ENABLE);
+ } else {
+ printf("bt%d: Not Enabling Round robin scheme\n", unit);
}
+
}
#ifndef min
@@ -1434,13 +1500,15 @@ bt_timeout(caddr_t arg1, int arg2)
struct bt_data *bt;
int s = splbio();
+ /*
+ * A timeout routine in kernel DONOT unlink
+ * Entry chains when time outed....So infinity Loop..
+ * 94/04/20 amurai@spec.co.jp
+ */
+ untimeout(bt_timeout, (caddr_t)ccb);
+
unit = ccb->xfer->sc_link->adapter_unit;
bt = btdata[unit];
- printf("bt%d:%d:%d (%s%d) timed out ", unit
- ,ccb->xfer->sc_link->target
- ,ccb->xfer->sc_link->lun
- ,ccb->xfer->sc_link->device->name
- ,ccb->xfer->sc_link->dev_unit);
#ifdef UTEST
bt_print_active_ccbs(unit);
@@ -1467,13 +1535,14 @@ bt_timeout(caddr_t arg1, int arg2)
ccb->xfer->retries = 0; /* I MEAN IT ! */
ccb->host_stat = BT_ABORTED;
bt_done(unit, ccb);
- } else { /* abort the operation that has timed out */
+ } else {
+ /* abort the operation that has timed out */
printf("bt%d: Try to abort\n", unit);
bt_send_mbo(unit, ~SCSI_NOMASK,
BT_MBO_ABORT, ccb);
/* 2 secs for the abort */
- timeout(bt_timeout, (caddr_t)ccb, 2 * hz);
ccb->flags = CCB_ABORTED;
+ timeout(bt_timeout, (caddr_t)ccb, 2 * hz);
}
splx(s);
}
diff --git a/sys/i386/isa/bt742a_32.c b/sys/i386/isa/bt742a_32.c
new file mode 100644
index 000000000000..f8eabf4de61f
--- /dev/null
+++ b/sys/i386/isa/bt742a_32.c
@@ -0,0 +1,1694 @@
+/*
+ * Written by Julian Elischer (julian@tfs.com)
+ * for TRW Financial Systems for use under the MACH(2.5) operating system.
+ *
+ * TRW Financial Systems, in accordance with their agreement with Carnegie
+ * Mellon University, makes this software available to CMU to distribute
+ * or use in any manner that they see fit as long as this message is kept with
+ * the software. For this reason TFS also grants any other persons or
+ * organisations permission to use or modify this software.
+ *
+ * TFS supplies this software to be publicly redistributed
+ * on the understanding that TFS is not responsible for the correct
+ * functioning of this software in any circumstances.
+ *
+ * $Id: bt742a_32.c,v 1.1 1994/06/17 19:05:57 jkh Exp $
+ */
+
+/*
+ * Bulogic/Bustek 32 bit Addressing Mode SCSI driver (Was bt742a.c)
+ *
+ * THIS DRIVER IS EXPERIMENTAL AND NOT ENABLED BY DEFAULT. It is
+ * provided here merely for reference purposes.
+ *
+ * NOTE: 1. Some bt5xx card can NOT handling 32 bit addressing mode.
+ * 2. OLD bt445s Revision A,B,C,D(nowired) + any firmware version
+ * has broken busmaster for handling 32 bit addressing on H/W bus side.
+ * 3. Extend probing still need to confirm by user base due to
+ * several H/W and firmware dependency. If you have a problem with
+ * extend probing, please contact to 'amurai@spec.co.jp'
+ *
+ * amurai@spec.co.jp 94/6/16
+ */
+
+#include <sys/types.h>
+
+#ifdef KERNEL /* don't laugh.. it compiles to a program too.. look */
+#include <bt.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#endif /* KERNEL */
+
+#include <i386/isa/isa_device.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
+#ifdef KERNEL
+#include "ddb.h"
+#include "kernel.h"
+#else /*KERNEL */
+#define NBT 1
+#endif /*KERNEL */
+
+typedef unsigned long int physaddr;
+
+/*
+ * I/O Port Interface
+ */
+
+#define BT_BASE bt->bt_base
+#define BT_CTRL_STAT_PORT (BT_BASE + 0x0) /* control & status */
+#define BT_CMD_DATA_PORT (BT_BASE + 0x1) /* cmds and datas */
+#define BT_INTR_PORT (BT_BASE + 0x2) /* Intr. stat */
+
+/*
+ * BT_CTRL_STAT bits (write)
+ */
+
+#define BT_HRST 0x80 /* Hardware reset */
+#define BT_SRST 0x40 /* Software reset */
+#define BT_IRST 0x20 /* Interrupt reset */
+#define BT_SCRST 0x10 /* SCSI bus reset */
+
+/*
+ * BT_CTRL_STAT bits (read)
+ */
+
+#define BT_STST 0x80 /* Self test in Progress */
+#define BT_DIAGF 0x40 /* Diagnostic Failure */
+#define BT_INIT 0x20 /* Mbx Init required */
+#define BT_IDLE 0x10 /* Host Adapter Idle */
+#define BT_CDF 0x08 /* cmd/data out port full */
+#define BT_DF 0x04 /* Data in port full */
+#define BT_INVDCMD 0x01 /* Invalid command */
+
+/*
+ * BT_CMD_DATA bits (write)
+ */
+
+#define BT_NOP 0x00 /* No operation */
+#define BT_MBX_INIT 0x01 /* Mbx initialization */
+#define BT_START_SCSI 0x02 /* start scsi command */
+#define BT_START_BIOS 0x03 /* start bios command */
+#define BT_INQUIRE 0x04 /* Adapter Inquiry */
+#define BT_MBO_INTR_EN 0x05 /* Enable MBO available interrupt */
+#define BT_SEL_TIMEOUT_SET 0x06 /* set selection time-out */
+#define BT_BUS_ON_TIME_SET 0x07 /* set bus-on time */
+#define BT_BUS_OFF_TIME_SET 0x08 /* set bus-off time */
+#define BT_SPEED_SET 0x09 /* set transfer speed */
+#define BT_DEV_GET 0x0a /* return installed devices */
+#define BT_CONF_GET 0x0b /* return configuration data */
+#define BT_TARGET_EN 0x0c /* enable target mode */
+#define BT_SETUP_GET 0x0d /* return setup data */
+#define BT_WRITE_CH2 0x1a /* write channel 2 buffer */
+#define BT_READ_CH2 0x1b /* read channel 2 buffer */
+#define BT_WRITE_FIFO 0x1c /* write fifo buffer */
+#define BT_READ_FIFO 0x1d /* read fifo buffer */
+#define BT_ECHO 0x1e /* Echo command data */
+#define BT_MBX_INIT_EXTENDED 0x81 /* Mbx initialization */
+#define BT_INQUIRE_EXTENDED 0x8D /* Adapter Setup Inquiry */
+
+/* The following command appeared at FirmWare 3.31 */
+#define BT_ROUND_ROBIN 0x8f /* Enable/Disable(default) round robin */
+#define BT_DISABLE 0x00 /* Parameter value for Disable */
+#define BT_ENABLE 0x01 /* Parameter value for Enable */
+
+struct bt_cmd_buf {
+ u_char byte[16];
+};
+
+/*
+ * BT_INTR_PORT bits (read)
+ */
+
+#define BT_ANY_INTR 0x80 /* Any interrupt */
+#define BT_SCRD 0x08 /* SCSI reset detected */
+#define BT_HACC 0x04 /* Command complete */
+#define BT_MBOA 0x02 /* MBX out empty */
+#define BT_MBIF 0x01 /* MBX in full */
+
+/*
+ * Mail box defs etc.
+ * these could be bigger but we need the bt_data to fit on a single page..
+ */
+
+#define BT_MBX_SIZE 32 /* mail box size (MAX 255 MBxs) */
+ /* don't need that many really */
+#define BT_CCB_MAX 32 /* store up to 32CCBs at any one time */
+ /* in bt742a H/W ( Not MAX ? ) */
+#define CCB_HASH_SIZE 32 /* when we have a physical addr. for */
+ /* a ccb and need to find the ccb in */
+ /* space, look it up in the hash table */
+#define CCB_HASH_SHIFT 9 /* only hash on multiples of 512 */
+#define CCB_HASH(x) ((((long int)(x))>>CCB_HASH_SHIFT) % CCB_HASH_SIZE)
+
+#define bt_nextmbx( wmb, mbx, mbio ) \
+ if ( (wmb) == &((mbx)->mbio[BT_MBX_SIZE - 1 ]) ) \
+ (wmb) = &((mbx)->mbio[0]); \
+ else \
+ (wmb)++;
+
+typedef struct bt_mbx_out {
+ physaddr ccb_addr;
+ unsigned char dummy[3];
+ unsigned char cmd;
+} BT_MBO;
+
+typedef struct bt_mbx_in {
+ physaddr ccb_addr;
+ unsigned char btstat;
+ unsigned char sdstat;
+ unsigned char dummy;
+ unsigned char stat;
+} BT_MBI;
+
+struct bt_mbx {
+ BT_MBO mbo[BT_MBX_SIZE];
+ BT_MBI mbi[BT_MBX_SIZE];
+ BT_MBO *tmbo; /* Target Mail Box out */
+ BT_MBI *tmbi; /* Target Mail Box in */
+};
+
+/*
+ * mbo.cmd values
+ */
+
+#define BT_MBO_FREE 0x0 /* MBO entry is free */
+#define BT_MBO_START 0x1 /* MBO activate entry */
+#define BT_MBO_ABORT 0x2 /* MBO abort entry */
+
+/*
+ * mbi.stat values
+ */
+
+#define BT_MBI_FREE 0x0 /* MBI entry is free */
+#define BT_MBI_OK 0x1 /* completed without error */
+#define BT_MBI_ABORT 0x2 /* aborted ccb */
+#define BT_MBI_UNKNOWN 0x3 /* Tried to abort invalid CCB */
+#define BT_MBI_ERROR 0x4 /* Completed with error */
+
+#if defined(BIG_DMA)
+WARNING...THIS WON'T WORK(won't fit on 1 page)
+/* #define BT_NSEG 2048*/ /* Number of scatter gather segments - to much vm */
+#define BT_NSEG 128
+#else
+#define BT_NSEG 33
+#endif /* BIG_DMA */
+
+struct bt_scat_gath {
+ unsigned long seg_len;
+ physaddr seg_addr;
+};
+
+struct bt_ccb {
+ unsigned char opcode;
+ unsigned char:3, data_in:1, data_out:1,:3;
+ unsigned char scsi_cmd_length;
+ unsigned char req_sense_length;
+ /*------------------------------------longword boundary */
+ unsigned long data_length;
+ /*------------------------------------longword boundary */
+ physaddr data_addr;
+ /*------------------------------------longword boundary */
+ unsigned char dummy[2];
+ unsigned char host_stat;
+ unsigned char target_stat;
+ /*------------------------------------longword boundary */
+ unsigned char target;
+ unsigned char lun;
+ unsigned char scsi_cmd[12]; /* 12 bytes (bytes only) */
+ unsigned char dummy2[1];
+ unsigned char link_id;
+ /*------------------------------------4 longword boundary */
+ physaddr link_addr;
+ /*------------------------------------longword boundary */
+ physaddr sense_ptr;
+/*-----end of HW fields-------------------------------longword boundary */
+ struct scsi_sense_data scsi_sense;
+ /*------------------------------------longword boundary */
+ struct bt_scat_gath scat_gath[BT_NSEG];
+ /*------------------------------------longword boundary */
+ struct bt_ccb *next;
+ /*------------------------------------longword boundary */
+ struct scsi_xfer *xfer; /* the scsi_xfer for this cmd */
+ /*------------------------------------longword boundary */
+ struct bt_mbx_out *mbx; /* pointer to mail box */
+ /*------------------------------------longword boundary */
+ int flags;
+#define CCB_FREE 0
+#define CCB_ACTIVE 1
+#define CCB_ABORTED 2
+ /*------------------------------------longword boundary */
+ struct bt_ccb *nexthash; /* if two hash the same */
+ /*------------------------------------longword boundary */
+ physaddr hashkey; /*physaddr of this ccb */
+ /*------------------------------------longword boundary */
+};
+
+/*
+ * opcode fields
+ */
+
+#define BT_INITIATOR_CCB 0x00 /* SCSI Initiator CCB */
+#define BT_TARGET_CCB 0x01 /* SCSI Target CCB */
+#define BT_INIT_SCAT_GATH_CCB 0x02 /* SCSI Initiator with scattter gather */
+#define BT_RESET_CCB 0x81 /* SCSI Bus reset */
+
+/*
+ * bt_ccb.host_stat values
+ */
+
+#define BT_OK 0x00 /* cmd ok */
+#define BT_LINK_OK 0x0a /* Link cmd ok */
+#define BT_LINK_IT 0x0b /* Link cmd ok + int */
+#define BT_SEL_TIMEOUT 0x11 /* Selection time out */
+#define BT_OVER_UNDER 0x12 /* Data over/under run */
+#define BT_BUS_FREE 0x13 /* Bus dropped at unexpected time */
+#define BT_INV_BUS 0x14 /* Invalid bus phase/sequence */
+#define BT_BAD_MBO 0x15 /* Incorrect MBO cmd */
+#define BT_BAD_CCB 0x16 /* Incorrect ccb opcode */
+#define BT_BAD_LINK 0x17 /* Not same values of LUN for links */
+#define BT_INV_TARGET 0x18 /* Invalid target direction */
+#define BT_CCB_DUP 0x19 /* Duplicate CCB received */
+#define BT_INV_CCB 0x1a /* Invalid CCB or segment list */
+#define BT_ABORTED 42 /* pseudo value from driver */
+
+struct bt_boardID {
+ u_char board_type;
+ u_char custom_feture;
+ char firm_revision;
+ u_char firm_version;
+};
+
+struct bt_setup {
+ u_char sync_neg:1;
+ u_char parity:1;
+ u_char :6;
+ u_char speed;
+ u_char bus_on;
+ u_char bus_off;
+ u_char num_mbx;
+ u_char mbx[3]; /* make a sense with back-word compatibility*/
+ struct {
+ u_char offset:4;
+ u_char period:3;
+ u_char valid:1;
+ } sync[8];
+ u_char disc_sts;
+};
+
+struct bt_config {
+ u_char chan;
+ u_char intr;
+ u_char scsi_dev:3;
+ u_char :5;
+};
+
+#define BT_INQUIRE_REV_THIRD 0x84 /* Get Adapter FirmWare version #3 */
+#define BT_INQUIRE_REV_FOURTH 0x85 /* Get Adapter FirmWare version #4 */
+
+/*
+ * Determine 32bit address/Data firmware functionality from the bus type
+ * Note: bt742a/747[s|d]/757/946/445s will return 'E'
+ * bt542b/545s/545d will return 'A'
+ * 94/05/18 amurai@spec.co.jp
+ */
+#define BT_BUS_TYPE_24bit 'A' /* PC/AT 24 bit address bus type */
+#define BT_BUS_TYPE_32bit 'E' /* EISA/VLB/PCI 32 bit address bus type */
+#define BT_BUS_TYPE_MCA 'M' /* Micro chanel is ? forget it right now */
+struct bt_ext_info {
+ u_char bus_type; /* Host adapter bus type */
+ u_char bios_addr; /* Bios Address-Not used */
+ u_short max_seg; /* Max segment List */
+ u_char num_mbx; /* Number of mailbox */
+ int32 mbx_base; /* mailbox base address */
+ struct {
+ u_char resv1:2; /* ??? */
+ u_char maxsync:1; /* ON: 10MB/s , OFF: 5MB/s */
+ u_char resv2:2; /* ??? */
+ u_char sync:1; /* ON: Sync, OFF: async ONLY!! */
+ u_char resv3:2; /* ??? */
+ } s;
+ u_char firmid[3]; /* Firmware ver. & rev. w/o last char */
+};
+
+#define BT_GET_BOARD_INFO 0x8b /* Get H/W ID and Revision */
+struct bt_board_info {
+ u_char id[4]; /* i.e bt742a -> '7','4','2','A' */
+ u_char ver[2]; /* i.e Board Revision 'H' -> 'H', 0x00 */
+};
+
+#define BT_GET_SYNC_VALUE 0x8c /* Get Synchronous Value */
+struct bt_sync_value {
+ u_char value[8]; /* Synchrnous value (value * 10 nsec) */
+};
+
+#define INT9 0x01
+#define INT10 0x02
+#define INT11 0x04
+#define INT12 0x08
+#define INT14 0x20
+#define INT15 0x40
+
+#define EISADMA 0x00
+#define CHAN0 0x01
+#define CHAN5 0x20
+#define CHAN6 0x40
+#define CHAN7 0x80
+
+#define KVTOPHYS(x) vtophys(x)
+#define PAGESIZ 4096
+#define INVALIDATE_CACHE {asm volatile( ".byte 0x0F ;.byte 0x08" ); }
+
+u_char bt_scratch_buf[256];
+
+struct bt_data {
+ short bt_base; /* base port for each board */
+ struct bt_mbx bt_mbx; /* all our mailboxes */
+ struct bt_ccb *bt_ccb_free; /* list of free CCBs */
+ struct bt_ccb *ccbhash[CCB_HASH_SIZE]; /* phys to kv hash */
+ int bt_int; /* int. read off board */
+ int bt_dma; /* DMA channel read of board */
+ int bt_scsi_dev; /* adapters scsi id */
+ int numccbs; /* how many we have malloc'd */
+ struct scsi_link sc_link; /* prototype for devs */
+} *btdata[NBT];
+
+/***********debug values *************/
+#define BT_SHOWCCBS 0x01
+#define BT_SHOWINTS 0x02
+#define BT_SHOWCMDS 0x04
+#define BT_SHOWMISC 0x08
+int bt_debug = 0;
+
+#ifdef KERNEL
+int btprobe();
+int btattach();
+int btintr();
+int32 bt_scsi_cmd();
+void bt_timeout(caddr_t, int);
+void bt_inquire_setup_information();
+void bt_done();
+void btminphys();
+u_int32 bt_adapter_info();
+struct bt_ccb *bt_get_ccb();
+struct bt_ccb *bt_ccb_phys_kv();
+
+static int btunit = 0;
+
+struct isa_driver btdriver =
+{
+ btprobe,
+ btattach,
+ "bt"
+};
+
+struct scsi_adapter bt_switch =
+{
+ bt_scsi_cmd,
+ btminphys,
+ 0,
+ 0,
+ bt_adapter_info,
+ "bt",
+ 0, 0
+};
+
+/* the below structure is so we have a default dev struct for out link struct */
+struct scsi_device bt_dev =
+{
+ NULL, /* Use default error handler */
+ NULL, /* have a queue, served by this */
+ NULL, /* have no async handler */
+ NULL, /* Use default 'done' routine */
+ "bt",
+ 0,
+ 0, 0
+};
+
+#endif /*KERNEL */
+
+#define BT_RESET_TIMEOUT 1000
+#ifndef KERNEL
+main()
+{
+ printf("bt_data is %d bytes\n", sizeof(struct bt_data));
+ printf("bt_ccb is %d bytes\n", sizeof(struct bt_ccb));
+ printf("bt_mbx is %d bytes\n", sizeof(struct bt_mbx));
+}
+
+#else /*KERNEL */
+
+/*
+ * bt_cmd(unit,icnt, ocnt,wait, retval, opcode, args)
+ *
+ * Activate Adapter command
+ * icnt: number of args (outbound bytes written after opcode)
+ * ocnt: number of expected returned bytes
+ * wait: number of seconds to wait for response
+ * retval: buffer where to place returned bytes
+ * opcode: opcode BT_NOP, BT_MBX_INIT, BT_START_SCSI ...
+ * args: parameters
+ *
+ * Performs an adapter command through the ports. Not to be confused with a
+ * scsi command, which is read in via the dma; one of the adapter commands
+ * tells it to read in a scsi command.
+ */
+int
+bt_cmd(unit, icnt, ocnt, wait, retval, opcode, args)
+ int unit;
+ int icnt;
+ int ocnt;
+ int wait;
+ u_char *retval;
+ unsigned opcode;
+ u_char args;
+{
+ struct bt_data *bt = btdata[unit];
+ unsigned *ic = &opcode;
+ u_char oc;
+ register i;
+ int sts;
+
+ /*
+ * multiply the wait argument by a big constant
+ * zero defaults to 1
+ */
+ if (wait)
+ wait *= 100000;
+ else
+ wait = 100000;
+ /*
+ * Wait for the adapter to go idle, unless it's one of
+ * the commands which don't need this
+ */
+ if (opcode != BT_MBX_INIT && opcode != BT_START_SCSI) {
+ i = 100000; /* 1 sec? */
+ while (--i) {
+ sts = inb(BT_CTRL_STAT_PORT);
+ if (sts & BT_IDLE) {
+ break;
+ }
+ DELAY(10);
+ }
+ if (i == 0) {
+ printf("bt%d: bt_cmd, host not idle(0x%x)\n", unit, sts);
+ return (ENXIO);
+ }
+ }
+ /*
+ * Now that it is idle, if we expect output, preflush the
+ * queue feeding to us.
+ */
+ if (ocnt) {
+ while ((inb(BT_CTRL_STAT_PORT)) & BT_DF)
+ inb(BT_CMD_DATA_PORT);
+ }
+ /*
+ * Output the command and the number of arguments given
+ * for each byte, first check the port is empty.
+ */
+ icnt++;
+ /* include the command */
+ while (icnt--) {
+ sts = inb(BT_CTRL_STAT_PORT);
+ for (i = wait; i; i--) {
+ sts = inb(BT_CTRL_STAT_PORT);
+ if (!(sts & BT_CDF))
+ break;
+ DELAY(10);
+ }
+ if (i == 0) {
+ printf("bt%d: bt_cmd, cmd/data port full\n", unit);
+ outb(BT_CTRL_STAT_PORT, BT_SRST);
+ return (ENXIO);
+ }
+ outb(BT_CMD_DATA_PORT, (u_char) (*ic++));
+ }
+ /*
+ * If we expect input, loop that many times, each time,
+ * looking for the data register to have valid data
+ */
+ while (ocnt--) {
+ sts = inb(BT_CTRL_STAT_PORT);
+ for (i = wait; i; i--) {
+ sts = inb(BT_CTRL_STAT_PORT);
+ if (sts & BT_DF)
+ break;
+ DELAY(10);
+ }
+ if (i == 0) {
+ printf("bt%d: bt_cmd, cmd/data port empty %d\n",
+ unit, ocnt);
+ return (ENXIO);
+ }
+ oc = inb(BT_CMD_DATA_PORT);
+ if (retval)
+ *retval++ = oc;
+ }
+ /*
+ * Wait for the board to report a finised instruction
+ */
+ i = 100000; /* 1 sec? */
+ while (--i) {
+ sts = inb(BT_INTR_PORT);
+ if (sts & BT_HACC) {
+ break;
+ }
+ DELAY(10);
+ }
+ if (i == 0) {
+ printf("bt%d: bt_cmd, host not finished(0x%x)\n", unit, sts);
+ return (ENXIO);
+ }
+ outb(BT_CTRL_STAT_PORT, BT_IRST);
+ return (0);
+}
+
+/*
+ * Check if the device can be found at the port given
+ * and if so, set it up ready for further work
+ * as an argument, takes the isa_device structure from
+ * autoconf.c
+ */
+int
+btprobe(dev)
+ struct isa_device *dev;
+{
+ /*
+ * find unit and check we have that many defined
+ */
+ int unit = btunit;
+ struct bt_data *bt;
+
+ if (unit >= NBT) {
+ printf("bt%d: unit number too high\n", unit);
+ return 0;
+ }
+ /*
+ * Allocate a storage area for us
+ */
+ if (btdata[unit]) {
+ printf("bt%d: memory already allocated\n", unit);
+ return 0;
+ }
+ bt = malloc(sizeof(struct bt_data), M_TEMP, M_NOWAIT);
+ if (!bt) {
+ printf("bt%d: cannot malloc!\n", unit);
+ return 0;
+ }
+ bzero(bt, sizeof(struct bt_data));
+ btdata[unit] = bt;
+ bt->bt_base = dev->id_iobase;
+
+ /*
+ * Try initialise a unit at this location
+ * sets up dma and bus speed, loads bt->bt_int
+ */
+ if (bt_init(unit) != 0) {
+ btdata[unit] = NULL;
+ free(bt, M_TEMP);
+ return 0;
+ }
+ /*
+ * If it's there, put in it's interrupt vectors
+ */
+ dev->id_unit = unit;
+ dev->id_irq = (1 << bt->bt_int);
+ dev->id_drq = bt->bt_dma;
+
+ btunit++;
+ return 1;
+}
+
+/*
+ * Attach all the sub-devices we can find
+ */
+int
+btattach(dev)
+ struct isa_device *dev;
+{
+ int unit = dev->id_unit;
+ struct bt_data *bt = btdata[unit];
+
+ /*
+ * fill in the prototype scsi_link.
+ */
+ bt->sc_link.adapter_unit = unit;
+ bt->sc_link.adapter_targ = bt->bt_scsi_dev;
+ bt->sc_link.adapter = &bt_switch;
+ bt->sc_link.device = &bt_dev;
+
+ /*
+ * Forcely Bounce buffer mechanizum is ON for some broken busmaster
+ * chip with over 16Mbytes boundary for while...
+ * amurai@spec.co.jp 94/06/16
+ */
+ bt->sc_link.flags = SDEV_BOUNCE; /*XXX*/
+
+ /*
+ * ask the adapter what subunits are present
+ */
+ scsi_attachdevs(&(bt->sc_link));
+ return 1;
+}
+
+/*
+ * Return some information to the caller about the adapter and its
+ * capabilities.
+ */
+u_int32
+bt_adapter_info(unit)
+ int unit;
+{
+ return (2); /* 2 outstanding requests at a time per device */
+}
+
+/*
+ * Catch an interrupt from the adaptor
+ */
+int
+btintr(unit)
+ int unit;
+{
+ struct bt_data *bt = btdata[unit];
+ BT_MBI *wmbi;
+ struct bt_mbx *wmbx;
+ struct bt_ccb *ccb;
+ unsigned char stat;
+ int i, wait;
+ int found = 0;
+
+#ifdef UTEST
+ printf("btintr ");
+#endif
+ /*
+ * First acknowlege the interrupt, Then if it's
+ * not telling about a completed operation
+ * just return.
+ */
+ stat = inb(BT_INTR_PORT);
+
+ /* Mail Box out empty ? */
+ if (stat & BT_MBOA) {
+ printf("bt%d: Available Free mbo post\n", unit);
+ /* Disable MBO available interrupt */
+ outb(BT_CMD_DATA_PORT, BT_MBO_INTR_EN);
+ wait = 100000; /* 1 sec enough? */
+ for (i = wait; i; i--) {
+ if (!(inb(BT_CTRL_STAT_PORT) & BT_CDF))
+ break;
+ DELAY(10);
+ }
+ if (i == 0) {
+ printf("bt%d: bt_intr, cmd/data port full\n", unit);
+ outb(BT_CTRL_STAT_PORT, BT_SRST);
+ return 1;
+ }
+ outb(BT_CMD_DATA_PORT, 0x00); /* Disable */
+ wakeup((caddr_t)&bt->bt_mbx);
+ outb(BT_CTRL_STAT_PORT, BT_IRST);
+ return 1;
+ }
+ if (!(stat & BT_MBIF)) {
+ outb(BT_CTRL_STAT_PORT, BT_IRST);
+ return 1;
+ }
+ /*
+ * If it IS then process the competed operation
+ */
+ wmbx = &bt->bt_mbx;
+ wmbi = wmbx->tmbi;
+ AGAIN:
+ while (wmbi->stat != BT_MBI_FREE) {
+ ccb = bt_ccb_phys_kv(bt, (wmbi->ccb_addr));
+ if (!ccb) {
+ wmbi->stat = BT_MBI_FREE;
+ printf("bt: BAD CCB ADDR!\n");
+ continue;
+ }
+ found++;
+ if ((stat = wmbi->stat) != BT_MBI_OK) {
+ switch (stat) {
+ case BT_MBI_ABORT:
+#ifdef UTEST
+ if (bt_debug & BT_SHOWMISC)
+ printf("abort ");
+#endif
+ ccb->host_stat = BT_ABORTED;
+ break;
+
+ case BT_MBI_UNKNOWN:
+ ccb = (struct bt_ccb *) 0;
+#ifdef UTEST
+ if (bt_debug & BT_SHOWMISC)
+ printf("unknown ccb for abort");
+#endif
+ break;
+
+ case BT_MBI_ERROR:
+ break;
+
+ default:
+ panic("Impossible mbxi status");
+
+ }
+#ifdef UTEST
+ if ((bt_debug & BT_SHOWCMDS) && ccb) {
+ u_char *cp;
+ cp = ccb->scsi_cmd;
+ printf("op=%x %x %x %x %x %x\n",
+ cp[0], cp[1], cp[2],
+ cp[3], cp[4], cp[5]);
+ printf("stat %x for mbi addr = 0x%08x\n"
+ ,wmbi->stat, wmbi);
+ printf("addr = 0x%x\n", ccb);
+ }
+#endif
+ }
+ wmbi->stat = BT_MBI_FREE;
+ if (ccb) {
+ untimeout(bt_timeout, (caddr_t)ccb);
+ bt_done(unit, ccb);
+ }
+ /* Set the IN mail Box pointer for next */ bt_nextmbx(wmbi, wmbx, mbi);
+ }
+ if (!found) {
+ for (i = 0; i < BT_MBX_SIZE; i++) {
+ if (wmbi->stat != BT_MBI_FREE) {
+ found++;
+ break;
+ }
+ bt_nextmbx(wmbi, wmbx, mbi);
+ }
+ if (!found) {
+ printf("bt%d: mbi at 0x%08x should be found, stat=%02x..resync\n",
+ unit, wmbi, stat);
+ } else {
+ found = 0;
+ goto AGAIN;
+ }
+ }
+ wmbx->tmbi = wmbi;
+ outb(BT_CTRL_STAT_PORT, BT_IRST);
+ return 1;
+}
+
+/*
+ * A ccb is put onto the free list.
+ */
+void
+bt_free_ccb(unit, ccb, flags)
+ int unit;
+ struct bt_ccb *ccb;
+ int flags;
+{
+ struct bt_data *bt = btdata[unit];
+ unsigned int opri = 0;
+
+ if (!(flags & SCSI_NOMASK))
+ opri = splbio();
+
+ ccb->next = bt->bt_ccb_free;
+ bt->bt_ccb_free = ccb;
+ ccb->flags = CCB_FREE;
+ /*
+ * If there were none, wake anybody waiting for one to come free,
+ * starting with queued entries.
+ */
+ if (!ccb->next) {
+ wakeup((caddr_t)&bt->bt_ccb_free);
+ }
+
+ if (!(flags & SCSI_NOMASK))
+ splx(opri);
+}
+
+/*
+ * Get a free ccb
+ *
+ * If there are none, see if we can allocate a new one. If so, put it in
+ * the hash table too otherwise either return an error or sleep.
+ */
+struct bt_ccb *
+bt_get_ccb(unit, flags)
+ int unit;
+ int flags;
+{
+ struct bt_data *bt = btdata[unit];
+ unsigned opri = 0;
+ struct bt_ccb *ccbp;
+ struct bt_mbx *wmbx; /* Mail Box pointer specified unit */
+ BT_MBO *wmbo; /* Out Mail Box pointer */
+ int hashnum;
+
+ if (!(flags & SCSI_NOMASK))
+ opri = splbio();
+ /*
+ * If we can and have to, sleep waiting for one to come free
+ * but only if we can't allocate a new one.
+ */
+ while (!(ccbp = bt->bt_ccb_free)) {
+ if (bt->numccbs < BT_CCB_MAX) {
+ if (ccbp = (struct bt_ccb *) malloc(sizeof(struct bt_ccb),
+ M_TEMP,
+ M_NOWAIT)) {
+ bzero(ccbp, sizeof(struct bt_ccb));
+ bt->numccbs++;
+ ccbp->flags = CCB_ACTIVE;
+ /*
+ * put in the phystokv hash table
+ * Never gets taken out.
+ */
+ ccbp->hashkey = KVTOPHYS(ccbp);
+ hashnum = CCB_HASH(ccbp->hashkey);
+ ccbp->nexthash = bt->ccbhash[hashnum];
+ bt->ccbhash[hashnum] = ccbp;
+ } else {
+ printf("bt%d: Can't malloc CCB\n", unit);
+ }
+ goto gottit;
+ } else {
+ if (!(flags & SCSI_NOSLEEP)) {
+ tsleep((caddr_t)&bt->bt_ccb_free, PRIBIO,
+ "btccb", 0);
+ }
+ }
+ }
+ if (ccbp) {
+ /* Get CCB from from free list */
+ bt->bt_ccb_free = ccbp->next;
+ ccbp->flags = CCB_ACTIVE;
+ }
+ gottit:
+ if (!(flags & SCSI_NOMASK))
+ splx(opri);
+
+ return (ccbp);
+}
+
+/*
+ * given a physical address, find the ccb that
+ * it corresponds to:
+ */
+struct bt_ccb *
+bt_ccb_phys_kv(bt, ccb_phys)
+ struct bt_data *bt;
+ physaddr ccb_phys;
+{
+ int hashnum = CCB_HASH(ccb_phys);
+ struct bt_ccb *ccbp = bt->ccbhash[hashnum];
+
+ while (ccbp) {
+ if (ccbp->hashkey == ccb_phys)
+ break;
+ ccbp = ccbp->nexthash;
+ }
+ return ccbp;
+}
+
+/*
+ * Get a MBO and then Send it
+ */
+BT_MBO *
+bt_send_mbo(int unit, int flags, int cmd, struct bt_ccb *ccb)
+{
+ struct bt_data *bt = btdata[unit];
+ unsigned opri = 0;
+ BT_MBO *wmbo; /* Mail Box Out pointer */
+ struct bt_mbx *wmbx; /* Mail Box pointer specified unit */
+ int i, wait;
+
+ wmbx = &bt->bt_mbx;
+
+ if (!(flags & SCSI_NOMASK))
+ opri = splbio();
+
+ /* Get the Target OUT mail Box pointer and move to Next */
+ wmbo = wmbx->tmbo;
+ wmbx->tmbo = (wmbo == &(wmbx->mbo[BT_MBX_SIZE - 1]) ?
+ &(wmbx->mbo[0]) : wmbo + 1);
+
+ /*
+ * Check the outmail box is free or not.
+ * Note: Under the normal operation, it shuld NOT happen to wait.
+ */
+ while (wmbo->cmd != BT_MBO_FREE) {
+ wait = 100000; /* 1 sec enough? */
+ /* Enable MBO available interrupt */
+ outb(BT_CMD_DATA_PORT, BT_MBO_INTR_EN);
+ for (i = wait; i; i--) {
+ if (!(inb(BT_CTRL_STAT_PORT) & BT_CDF))
+ break;
+ DELAY(10);
+ }
+ if (i == 0) {
+ printf("bt%d: bt_send_mbo, cmd/data port full\n", unit);
+ outb(BT_CTRL_STAT_PORT, BT_SRST);
+ return ((BT_MBO *) 0);
+ }
+ outb(BT_CMD_DATA_PORT, 0x01); /* Enable */
+ tsleep((caddr_t)wmbx, PRIBIO, "btsend", 0);
+ /* XXX */ /*can't do this! */
+ /* May be servicing an int */
+ }
+ /* Link CCB to the Mail Box */
+ wmbo->ccb_addr = KVTOPHYS(ccb);
+ ccb->mbx = wmbo;
+ wmbo->cmd = cmd;
+
+ /* Send it! */
+ outb(BT_CMD_DATA_PORT, BT_START_SCSI);
+
+ if (!(flags & SCSI_NOMASK))
+ splx(opri);
+
+ return (wmbo);
+}
+
+/*
+ * We have a ccb which has been processed by the
+ * adaptor, now we look to see how the operation
+ * went. Wake up the owner if waiting
+ */
+void
+bt_done(unit, ccb)
+ int unit;
+ struct bt_ccb *ccb;
+{
+ struct bt_data *bt = btdata[unit];
+ struct scsi_sense_data *s1, *s2;
+ struct scsi_xfer *xs = ccb->xfer;
+
+ SC_DEBUG(xs->sc_link, SDEV_DB2, ("bt_done\n"));
+ /*
+ * Otherwise, put the results of the operation
+ * into the xfer and call whoever started it
+ */
+ if ((ccb->host_stat != BT_OK || ccb->target_stat != SCSI_OK)
+ && (!(xs->flags & SCSI_ERR_OK))) {
+
+ s1 = &(ccb->scsi_sense);
+ s2 = &(xs->sense);
+
+ if (ccb->host_stat) {
+ switch (ccb->host_stat) {
+ case BT_ABORTED: /* No response */
+ case BT_SEL_TIMEOUT: /* No response */
+ SC_DEBUG(xs->sc_link, SDEV_DB3,
+ ("timeout reported back\n"));
+ xs->error = XS_TIMEOUT;
+ break;
+ default: /* Other scsi protocol messes */
+ xs->error = XS_DRIVER_STUFFUP;
+ SC_DEBUG(xs->sc_link, SDEV_DB3,
+ ("unexpected host_stat: %x\n",
+ ccb->host_stat));
+ }
+ } else {
+ switch (ccb->target_stat) {
+ case 0x02:
+ *s2 = *s1;
+ xs->error = XS_SENSE;
+ break;
+ case 0x08:
+ xs->error = XS_BUSY;
+ break;
+ default:
+ SC_DEBUG(xs->sc_link, SDEV_DB3,
+ ("unexpected target_stat: %x\n",
+ ccb->target_stat));
+ xs->error = XS_DRIVER_STUFFUP;
+ }
+ }
+ } else { /* All went correctly OR errors expected */
+ xs->resid = 0;
+ }
+ xs->flags |= ITSDONE;
+ bt_free_ccb(unit, ccb, xs->flags);
+ scsi_done(xs);
+}
+
+/*
+ * Start the board, ready for normal operation
+ */
+int
+bt_init(unit)
+ int unit;
+{
+ struct bt_data *bt = btdata[unit];
+ unsigned char ad[4];
+ volatile int i, sts;
+ struct bt_config conf;
+ struct bt_ext_info info;
+ struct bt_board_info binfo;
+
+ /*
+ * reset board, If it doesn't respond, assume
+ * that it's not there.. good for the probe
+ */
+
+ outb(BT_CTRL_STAT_PORT, BT_HRST | BT_SRST);
+
+ for (i = BT_RESET_TIMEOUT; i; i--) {
+ sts = inb(BT_CTRL_STAT_PORT);
+ if (sts == (BT_IDLE | BT_INIT))
+ break;
+ DELAY(1000);
+ }
+ if (i == 0) {
+#ifdef UTEST
+ printf("bt_init: No answer from board\n");
+#endif
+ return (ENXIO);
+ }
+
+ /*
+ * Displaying Board ID and Hardware Revision
+ * 94/05/18 amurai@spec.co.jp
+ */
+ bt_cmd(unit, 1, sizeof(binfo),0,&binfo,BT_GET_BOARD_INFO,sizeof(binfo));
+ printf("bt%d: Bt%c%c%c%c/%c%d-", unit,
+ binfo.id[0],
+ binfo.id[1],
+ binfo.id[2],
+ binfo.id[3],
+ binfo.ver[0],
+ (unsigned) binfo.ver[1]
+ );
+
+ /*
+ * Make sure board has a capability of 32bit addressing.
+ * and Firmware also need a capability of 32bit addressing pointer
+ * in Extended mailbox and ccb structure.
+ * 94/05/18 amurai@spec.co.jp
+ */
+ bt_cmd(unit, 1, sizeof(info),0,&info, BT_INQUIRE_EXTENDED,sizeof(info));
+ switch (info.bus_type) {
+ case BT_BUS_TYPE_24bit: /* PC/AT 24 bit address bus */
+ printf("ISA(24bit) bus\n");
+ break;
+ case BT_BUS_TYPE_32bit: /* EISA/VLB/PCI 32 bit bus */
+ printf("PCI/EISA/VLB(32bit) bus\n");
+ break;
+ case BT_BUS_TYPE_MCA: /* forget it right now */
+ printf("MCA bus architecture...");
+ printf("giving up\n");
+ return (ENXIO);
+ break;
+ default:
+ printf("Unknown state...");
+ printf("giving up\n");
+ return (ENXIO);
+ break;
+ }
+ if ( binfo.id[0] == '5' ) {
+ printf("bt%d: This driver is designed for using 32 bit addressing\n",unit);
+ printf("bt%d: mode firmware and EISA/PCI/VLB bus architecture bus\n",unit);
+ printf("bt%d: WITHOUT any software trick/overhead (i.e.bounce buffer).\n",unit);
+ printf("bt%d: If you have more than 16MBytes memory\n",unit);
+ printf("bt%d: your filesystem will get a serious damage.\n",unit);
+ } else if ( info.bus_type == BT_BUS_TYPE_24bit ) {
+ printf("bt%d: Your board should report a 32bit bus architecture type..\n",unit);
+ printf("bt%d: A firmware on your board may have a problem with over\n",unit);
+ printf("bt%d: 16MBytes memory handling with this driver.\n",unit);
+ }
+
+ /*
+ * Assume we have a board at this stage
+ * setup dma channel from jumpers and save int
+ * level
+ */
+ printf("bt%d: reading board settings, ", unit);
+
+ bt_cmd(unit, 0, sizeof(conf), 0, &conf, BT_CONF_GET);
+ switch (conf.chan) {
+ case EISADMA:
+ bt->bt_dma = -1;
+ break;
+ case CHAN0:
+ outb(0x0b, 0x0c);
+ outb(0x0a, 0x00);
+ bt->bt_dma = 0;
+ break;
+ case CHAN5:
+ outb(0xd6, 0xc1);
+ outb(0xd4, 0x01);
+ bt->bt_dma = 5;
+ break;
+ case CHAN6:
+ outb(0xd6, 0xc2);
+ outb(0xd4, 0x02);
+ bt->bt_dma = 6;
+ break;
+ case CHAN7:
+ outb(0xd6, 0xc3);
+ outb(0xd4, 0x03);
+ bt->bt_dma = 7;
+ break;
+ default:
+ printf("illegal dma setting %x\n", conf.chan);
+ return (EIO);
+ }
+ if (bt->bt_dma == -1)
+ printf("busmastering, ");
+ else
+ printf("dma=%d, ", bt->bt_dma);
+
+ switch (conf.intr) {
+ case INT9:
+ bt->bt_int = 9;
+ break;
+ case INT10:
+ bt->bt_int = 10;
+ break;
+ case INT11:
+ bt->bt_int = 11;
+ break;
+ case INT12:
+ bt->bt_int = 12;
+ break;
+ case INT14:
+ bt->bt_int = 14;
+ break;
+ case INT15:
+ bt->bt_int = 15;
+ break;
+ default:
+ printf("illegal int setting\n");
+ return (EIO);
+ }
+ printf("int=%d\n", bt->bt_int);
+
+ /* who are we on the scsi bus */
+ bt->bt_scsi_dev = conf.scsi_dev;
+ /*
+ * Initialize mail box
+ */
+ *((physaddr *) ad) = KVTOPHYS(&bt->bt_mbx);
+ bt_cmd(unit, 5, 0, 0, 0, BT_MBX_INIT_EXTENDED
+ ,BT_MBX_SIZE
+ ,ad[0]
+ ,ad[1]
+ ,ad[2]
+ ,ad[3]);
+
+ /*
+ * Set Pointer chain null for just in case
+ * Link the ccb's into a free-list W/O mbox
+ * Initialize mail box status to free
+ */
+ if (bt->bt_ccb_free != (struct bt_ccb *) 0) {
+ printf("bt%d: bt_ccb_free is NOT initialized but init here\n",
+ unit);
+ bt->bt_ccb_free = (struct bt_ccb *) 0;
+ }
+ for (i = 0; i < BT_MBX_SIZE; i++) {
+ bt->bt_mbx.mbo[i].cmd = BT_MBO_FREE;
+ bt->bt_mbx.mbi[i].stat = BT_MBI_FREE;
+ }
+ /*
+ * Set up initial mail box for round-robin operation.
+ */
+ bt->bt_mbx.tmbo = &bt->bt_mbx.mbo[0];
+ bt->bt_mbx.tmbi = &bt->bt_mbx.mbi[0];
+ bt_inquire_setup_information(unit, &info);
+
+
+ /*
+ * Note that we are going and return (to probe)
+ */
+ return 0;
+}
+
+void
+bt_inquire_setup_information(
+ int unit,
+ struct bt_ext_info *info )
+{
+ struct bt_data *bt = btdata[unit];
+ struct bt_setup setup;
+ struct bt_sync_value sync;
+ char dummy[8];
+ char sub_ver[3];
+ struct bt_boardID bID;
+ int i;
+
+ /* Inquire Installed Devices */
+ bzero( &dummy[0], sizeof(dummy) );
+ bt_cmd(unit, 0, sizeof(dummy), 100, &dummy[0], BT_DEV_GET);
+
+ /*
+ * If board has a capbility of Syncrhonouse mode,
+ * Get a SCSI Synchronous value
+ */
+ if ( info->s.sync ) {
+ bt_cmd(unit, 1, sizeof(sync), 100,
+ &sync,BT_GET_SYNC_VALUE,sizeof(sync));
+ }
+
+ /*
+ * Inquire Board ID to board for firmware version
+ */
+ bt_cmd(unit, 0, sizeof(bID), 0, &bID, BT_INQUIRE);
+ bt_cmd(unit, 0, 1, 0, &sub_ver[0], BT_INQUIRE_REV_THIRD );
+ i = ((int)(bID.firm_revision-'0')) * 10 + (int)(bID.firm_version-'0');
+ if ( i >= 33 ) {
+ bt_cmd(unit, 0, 1, 0, &sub_ver[1], BT_INQUIRE_REV_FOURTH );
+ } else {
+ /*
+ * Below rev 3.3 firmware has a problem for issuing
+ * the BT_INQUIRE_REV_FOURTH command.
+ */
+ sub_ver[1]='\0';
+ }
+ sub_ver[2]='\0';
+ if (sub_ver[1]==' ')
+ sub_ver[1]='\0';
+ printf("bt%d: version %c.%c%s, ",
+ unit, bID.firm_revision, bID.firm_version, sub_ver );
+
+ /*
+ * Obtain setup information from board.
+ */
+ bt_cmd(unit, 1, sizeof(setup), 0, &setup, BT_SETUP_GET, sizeof(setup));
+
+ if (setup.sync_neg && info->s.sync ) {
+ if ( info->s.maxsync ) {
+ printf("fast sync, "); /* Max 10MB/s */
+ } else {
+ printf("sync, "); /* Max 5MB/s */
+ }
+ } else {
+ if ( info->s.sync ) {
+ printf("async, "); /* Never try by board */
+ } else {
+ printf("async only, "); /* Doesn't has a capability on board */
+ }
+ }
+ if (setup.parity) {
+ printf("parity, ");
+ } else {
+ printf("no parity, ");
+ }
+ printf("%d mbxs, %d ccbs\n", setup.num_mbx, BT_CCB_MAX);
+
+ /*
+ * Displayi SCSI negotiation value by each target.
+ * amurai@spec.co.jp
+ */
+ for (i = 0; i < 8; i++) {
+ if (!setup.sync[i].valid )
+ continue;
+ if ( (!setup.sync[i].offset && !setup.sync[i].period)
+ || !info->s.sync ) {
+ printf("bt%d: targ %d async\n", unit, i);
+ } else {
+ printf("bt%d: targ %d sync rate=%2d.%02dMB/s(%dns), offset=%02d\n",
+ unit, i,
+ 100 / sync.value[i],
+ (100 % sync.value[i]) * 100 / sync.value[i],
+ sync.value[i] * 10,
+ setup.sync[i].offset );
+ }
+ }
+
+ /*
+ * Enable round-robin scheme - appeared at firmware rev. 3.31
+ * Below rev 3.XX firmware has a problem for issuing
+ * BT_ROUND_ROBIN command amurai@spec.co.jp
+ */
+ if ( bID.firm_revision >= '3' ) {
+ printf("bt%d: Enabling Round robin scheme\n", unit);
+ bt_cmd(unit, 1, 0, 0, 0, BT_ROUND_ROBIN, BT_ENABLE);
+ } else {
+ printf("bt%d: Not Enabling Round robin scheme\n", unit);
+ }
+
+}
+
+#ifndef min
+#define min(x,y) (x < y ? x : y)
+#endif /* min */
+
+void
+btminphys(bp)
+ struct buf *bp;
+{
+ if (bp->b_bcount > ((BT_NSEG - 1) * PAGESIZ)) {
+ bp->b_bcount = ((BT_NSEG - 1) * PAGESIZ);
+ }
+}
+
+/*
+ * start a scsi operation given the command and the data address. Also needs
+ * the unit, target and lu.
+ */
+int32
+bt_scsi_cmd(xs)
+ struct scsi_xfer *xs;
+{
+ struct scsi_sense_data *s1, *s2;
+ struct bt_ccb *ccb;
+ struct bt_scat_gath *sg;
+ int seg; /* scatter gather seg being worked on */
+ int i = 0;
+ int c = 0;
+ int thiskv;
+ physaddr thisphys, nextphys;
+ int unit = xs->sc_link->adapter_unit;
+ int bytes_this_seg, bytes_this_page, datalen, flags;
+ struct iovec *iovp;
+ struct bt_data *bt = btdata[unit];
+ BT_MBO *mbo;
+
+ SC_DEBUG(xs->sc_link, SDEV_DB2, ("bt_scsi_cmd\n"));
+ /*
+ * get a ccb (mbox-out) to use. If the transfer
+ * is from a buf (possibly from interrupt time)
+ * then we can't allow it to sleep
+ */
+ flags = xs->flags;
+ if (xs->bp)
+ flags |= (SCSI_NOSLEEP); /* just to be sure */
+ if (flags & ITSDONE) {
+ printf("bt%d: Already done?\n", unit);
+ xs->flags &= ~ITSDONE;
+ }
+ if (!(flags & INUSE)) {
+ printf("bt%d: Not in use?\n", unit);
+ xs->flags |= INUSE;
+ }
+ if (!(ccb = bt_get_ccb(unit, flags))) {
+ xs->error = XS_DRIVER_STUFFUP;
+ return (TRY_AGAIN_LATER);
+ }
+ SC_DEBUG(xs->sc_link, SDEV_DB3,
+ ("start ccb(%x)\n", ccb));
+ /*
+ * Put all the arguments for the xfer in the ccb
+ */
+ ccb->xfer = xs;
+ if (flags & SCSI_RESET) {
+ ccb->opcode = BT_RESET_CCB;
+ } else {
+ /* can't use S/G if zero length */
+ ccb->opcode = (xs->datalen ?
+ BT_INIT_SCAT_GATH_CCB
+ : BT_INITIATOR_CCB);
+ }
+ ccb->target = xs->sc_link->target;
+ ccb->data_out = 0;
+ ccb->data_in = 0;
+ ccb->lun = xs->sc_link->lun;
+ ccb->scsi_cmd_length = xs->cmdlen;
+ ccb->sense_ptr = KVTOPHYS(&(ccb->scsi_sense));
+ ccb->req_sense_length = sizeof(ccb->scsi_sense);
+
+ if ((xs->datalen) && (!(flags & SCSI_RESET))) { /* can use S/G only if not zero length */
+ ccb->data_addr = KVTOPHYS(ccb->scat_gath);
+ sg = ccb->scat_gath;
+ seg = 0;
+#ifdef TFS
+ if (flags & SCSI_DATA_UIO) {
+ iovp = ((struct uio *) xs->data)->uio_iov;
+ datalen = ((struct uio *) xs->data)->uio_iovcnt;
+ xs->datalen = 0;
+ while ((datalen) && (seg < BT_NSEG)) {
+ sg->seg_addr = (physaddr) iovp->iov_base;
+ xs->datalen += sg->seg_len = iovp->iov_len;
+ SC_DEBUGN(xs->sc_link, SDEV_DB4, ("(0x%x@0x%x)"
+ ,iovp->iov_len, iovp->iov_base));
+ sg++;
+ iovp++;
+ seg++;
+ datalen--;
+ }
+ } else
+#endif /* TFS */
+ {
+ /*
+ * Set up the scatter gather block
+ */
+
+ SC_DEBUG(xs->sc_link, SDEV_DB4,
+ ("%d @0x%x:- ", xs->datalen, xs->data));
+ datalen = xs->datalen;
+ thiskv = (int) xs->data;
+ thisphys = KVTOPHYS(thiskv);
+
+ while ((datalen) && (seg < BT_NSEG)) {
+ bytes_this_seg = 0;
+
+ /* put in the base address */
+ sg->seg_addr = thisphys;
+
+ SC_DEBUGN(xs->sc_link, SDEV_DB4,
+ ("0x%x", thisphys));
+
+ /* do it at least once */
+ nextphys = thisphys;
+ while ((datalen) && (thisphys == nextphys))
+ /*
+ * This page is contiguous (physically) with
+ * the the last, just extend the length
+ */
+ {
+ /* how far to the end of the page */
+ nextphys = (thisphys & (~(PAGESIZ - 1)))
+ + PAGESIZ;
+ bytes_this_page = nextphys - thisphys;
+ /**** or the data ****/
+ bytes_this_page = min(bytes_this_page
+ ,datalen);
+ bytes_this_seg += bytes_this_page;
+ datalen -= bytes_this_page;
+
+ /* get more ready for the next page */
+ thiskv = (thiskv & (~(PAGESIZ - 1)))
+ + PAGESIZ;
+ if (datalen)
+ thisphys = KVTOPHYS(thiskv);
+ }
+ /*
+ * next page isn't contiguous, finish the seg
+ */
+ SC_DEBUGN(xs->sc_link, SDEV_DB4,
+ ("(0x%x)", bytes_this_seg));
+ sg->seg_len = bytes_this_seg;
+ sg++;
+ seg++;
+ }
+ }
+ /* end of iov/kv decision */
+ ccb->data_length = seg * sizeof(struct bt_scat_gath);
+ SC_DEBUGN(xs->sc_link, SDEV_DB4, ("\n"));
+ if (datalen) {
+ /*
+ * there's still data, must have run out of segs!
+ */
+ printf("bt%d: bt_scsi_cmd, more than %d DMA segs\n",
+ unit, BT_NSEG);
+ xs->error = XS_DRIVER_STUFFUP;
+ bt_free_ccb(unit, ccb, flags);
+ return (HAD_ERROR);
+ }
+ } else { /* No data xfer, use non S/G values */
+ ccb->data_addr = (physaddr) 0;
+ ccb->data_length = 0;
+ }
+ ccb->link_id = 0;
+ ccb->link_addr = (physaddr) 0;
+ /*
+ * Put the scsi command in the ccb and start it
+ */
+ if (!(flags & SCSI_RESET)) {
+ bcopy(xs->cmd, ccb->scsi_cmd, ccb->scsi_cmd_length);
+ }
+ if (bt_send_mbo(unit, flags, BT_MBO_START, ccb) == (BT_MBO *) 0) {
+ xs->error = XS_DRIVER_STUFFUP;
+ bt_free_ccb(unit, ccb, flags);
+ return (TRY_AGAIN_LATER);
+ }
+ /*
+ * Usually return SUCCESSFULLY QUEUED
+ */
+ SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_sent\n"));
+ if (!(flags & SCSI_NOMASK)) {
+ timeout(bt_timeout, (caddr_t)ccb, (xs->timeout * hz) / 1000);
+ return (SUCCESSFULLY_QUEUED);
+ }
+ /*
+ * If we can't use interrupts, poll on completion
+ */
+ return (bt_poll(unit, xs, ccb));
+}
+
+/*
+ * Poll a particular unit, looking for a particular xs
+ */
+int
+bt_poll(unit, xs, ccb)
+ int unit;
+ struct scsi_xfer *xs;
+ struct bt_ccb *ccb;
+{
+ struct bt_data *bt = btdata[unit];
+ int done = 0;
+ int count = xs->timeout;
+ u_char stat;
+
+ /* timeouts are in msec, so we loop in 1000 usec cycles */
+ while (count) {
+ /*
+ * If we had interrupts enabled, would we
+ * have got an interrupt?
+ */
+ stat = inb(BT_INTR_PORT);
+ if (stat & BT_ANY_INTR) {
+ btintr(unit);
+ }
+ if (xs->flags & ITSDONE) {
+ break;
+ }
+ DELAY(1000); /* only happens in boot so ok */
+ count--;
+ }
+ if (count == 0) {
+ /*
+ * We timed out, so call the timeout handler manually,
+ * accounting for the fact that the clock is not running yet
+ * by taking out the clock queue entry it makes.
+ */
+ bt_timeout((caddr_t)ccb, 0);
+
+ /*
+ * because we are polling, take out the timeout entry
+ * bt_timeout made
+ */
+ untimeout(bt_timeout, (caddr_t)ccb);
+ count = 2000;
+ while (count) {
+ /*
+ * Once again, wait for the int bit
+ */
+ stat = inb(BT_INTR_PORT);
+ if (stat & BT_ANY_INTR) {
+ btintr(unit);
+ }
+ if (xs->flags & ITSDONE) {
+ break;
+ }
+ DELAY(1000); /* only happens in boot so ok */
+ count--;
+ }
+ if (count == 0) {
+ /*
+ * We timed out again... This is bad. Notice that
+ * this time there is no clock queue entry to remove.
+ */
+ bt_timeout((caddr_t)ccb, 0);
+ }
+ }
+ if (xs->error)
+ return (HAD_ERROR);
+ return (COMPLETE);
+}
+
+void
+bt_timeout(caddr_t arg1, int arg2)
+{
+ struct bt_ccb * ccb = (struct bt_ccb *)arg1;
+ int unit;
+ struct bt_data *bt;
+ int s = splbio();
+
+ /*
+ * A timeout routine in kernel DONOT unlink
+ * Entry chains when time outed....So infinity Loop..
+ * 94/04/20 amurai@spec.co.jp
+ */
+ untimeout(bt_timeout, (caddr_t)ccb);
+
+ unit = ccb->xfer->sc_link->adapter_unit;
+ bt = btdata[unit];
+
+#ifdef UTEST
+ bt_print_active_ccbs(unit);
+#endif
+
+ /*
+ * If the ccb's mbx is not free, then the board has gone Far East?
+ */
+ if (bt_ccb_phys_kv(bt, ccb->mbx->ccb_addr) == ccb &&
+ ccb->mbx->cmd != BT_MBO_FREE) {
+ printf("bt%d: not taking commands!\n", unit);
+ Debugger("bt742a");
+ }
+ /*
+ * If it has been through before, then
+ * a previous abort has failed, don't
+ * try abort again
+ */
+ if (ccb->flags == CCB_ABORTED) {
+ /*
+ * abort timed out
+ */
+ printf("bt%d: Abort Operation has timed out\n", unit);
+ ccb->xfer->retries = 0; /* I MEAN IT ! */
+ ccb->host_stat = BT_ABORTED;
+ bt_done(unit, ccb);
+ } else {
+ /* abort the operation that has timed out */
+ printf("bt%d: Try to abort\n", unit);
+ bt_send_mbo(unit, ~SCSI_NOMASK,
+ BT_MBO_ABORT, ccb);
+ /* 2 secs for the abort */
+ ccb->flags = CCB_ABORTED;
+ timeout(bt_timeout, (caddr_t)ccb, 2 * hz);
+ }
+ splx(s);
+}
+
+#ifdef UTEST
+void
+bt_print_ccb(ccb)
+ struct bt_ccb *ccb;
+{
+ printf("ccb:%x op:%x cmdlen:%d senlen:%d\n"
+ ,ccb
+ ,ccb->opcode
+ ,ccb->scsi_cmd_length
+ ,ccb->req_sense_length);
+ printf(" datlen:%d hstat:%x tstat:%x flags:%x\n"
+ ,ccb->data_length
+ ,ccb->host_stat
+ ,ccb->target_stat
+ ,ccb->flags);
+}
+
+void
+bt_print_active_ccbs(int unit)
+{
+ struct bt_data *bt = btdata[unit];
+ struct bt_ccb *ccb;
+ int i = 0;
+
+ while (i < CCB_HASH_SIZE) {
+ ccb = bt->ccbhash[i];
+ while (ccb) {
+ if (ccb->flags != CCB_FREE)
+ bt_print_ccb(ccb);
+ ccb = ccb->nexthash;
+ }
+ i++;
+ }
+}
+#endif /*UTEST */
+#endif /*KERNEL */
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
index cd87b28b90e6..5832801d24ae 100644
--- a/sys/i386/isa/clock.c
+++ b/sys/i386/isa/clock.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.6 1994/02/06 22:48:13 davidg Exp $
+ * $Id: clock.c,v 1.9 1994/05/02 09:41:24 sos Exp $
*/
/*
@@ -45,6 +45,7 @@
#include "time.h"
#include "kernel.h"
#include "machine/segments.h"
+#include "machine/frame.h"
#include "i386/isa/icu.h"
#include "i386/isa/isa.h"
#include "i386/isa/rtc.h"
@@ -55,22 +56,225 @@
#ifndef TIMER_FREQ
#define TIMER_FREQ 1193182 /* XXX - should be in isa.h */
#endif
+#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x))
+
+void hardclock();
+static int beeping;
+int timer0_divisor = TIMER_DIV(100); /* XXX should be hz */
+u_int timer0_prescale;
+static char timer0_state = 0, timer2_state = 0;
+static char timer0_reprogram = 0;
+static void (*timer_func)() = hardclock;
+static void (*new_function)();
+static u_int new_rate;
+static u_int hardclock_divisor;
+
+
+void
+timerintr(struct intrframe frame)
+{
+ timer_func(frame);
+ switch (timer0_state) {
+ case 0:
+ break;
+ case 1:
+ if ((timer0_prescale+=timer0_divisor) >= hardclock_divisor) {
+ hardclock(frame);
+ timer0_prescale = 0;
+ }
+ break;
+ case 2:
+ disable_intr();
+ outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
+ outb(TIMER_CNTR0, TIMER_DIV(new_rate)%256);
+ outb(TIMER_CNTR0, TIMER_DIV(new_rate)/256);
+ enable_intr();
+ timer0_divisor = TIMER_DIV(new_rate);
+ timer0_prescale = 0;
+ timer_func = new_function;
+ timer0_state = 1;
+ break;
+ case 3:
+ if ((timer0_prescale+=timer0_divisor) >= hardclock_divisor) {
+ hardclock(frame);
+ disable_intr();
+ outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
+ outb(TIMER_CNTR0, TIMER_DIV(hz)%256);
+ outb(TIMER_CNTR0, TIMER_DIV(hz)/256);
+ enable_intr();
+ timer0_divisor = TIMER_DIV(hz);
+ timer0_prescale = 0;
+ timer_func = hardclock;;
+ timer0_state = 0;
+ }
+ break;
+ }
+}
+
+
+int
+acquire_timer0(int rate, void (*function)() )
+{
+ if (timer0_state || !function)
+ return -1;
+
+ new_function = function;
+ new_rate = rate;
+ timer0_state = 2;
+ return 0;
+}
+
+
+int
+acquire_timer2(int mode)
+{
+ if (timer2_state)
+ return -1;
+ timer2_state = 1;
+ outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
+ return 0;
+}
+
+
+int
+release_timer0()
+{
+ if (!timer0_state)
+ return -1;
+ timer0_state = 3;
+ return 0;
+}
+
+
+int
+release_timer2()
+{
+ if (!timer2_state)
+ return -1;
+ timer2_state = 0;
+ outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
+ return 0;
+}
+
+
+static int
+getit()
+{
+ int high, low;
+
+ disable_intr();
+ /* select timer0 and latch counter value */
+ outb(TIMER_MODE, TIMER_SEL0);
+ low = inb(TIMER_CNTR0);
+ high = inb(TIMER_CNTR0);
+ enable_intr();
+ return ((high << 8) | low);
+}
+
+
+/*
+ * Wait "n" microseconds.
+ * Relies on timer 1 counting down from (TIMER_FREQ / hz)
+ * Note: timer had better have been programmed before this is first used!
+ */
+void
+DELAY(int n)
+{
+ int counter_limit, prev_tick, tick, ticks_left, sec, usec;
+
+#ifdef DELAYDEBUG
+ int getit_calls = 1;
+ int n1;
+ static int state = 0;
+
+ if (state == 0) {
+ state = 1;
+ for (n1 = 1; n1 <= 10000000; n1 *= 10)
+ DELAY(n1);
+ state = 2;
+ }
+ if (state == 1)
+ printf("DELAY(%d)...", n);
+#endif
+ /*
+ * Read the counter first, so that the rest of the setup overhead is
+ * counted. Guess the initial overhead is 20 usec (on most systems it
+ * takes about 1.5 usec for each of the i/o's in getit(). The loop
+ * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The
+ * multiplications and divisions to scale the count take a while).
+ */
+ prev_tick = getit(0, 0);
+ n -= 20;
+ /*
+ * Calculate (n * (TIMER_FREQ / 1e6)) without using floating point
+ * and without any avoidable overflows.
+ */
+ sec = n / 1000000;
+ usec = n - sec * 1000000;
+ ticks_left = sec * TIMER_FREQ
+ + usec * (TIMER_FREQ / 1000000)
+ + usec * ((TIMER_FREQ % 1000000) / 1000) / 1000
+ + usec * (TIMER_FREQ % 1000) / 1000000;
+
+ while (ticks_left > 0) {
+ tick = getit(0, 0);
+#ifdef DELAYDEBUG
+ ++getit_calls;
+#endif
+ if (tick > prev_tick)
+ ticks_left -= prev_tick - (tick - timer0_divisor);
+ else
+ ticks_left -= prev_tick - tick;
+ prev_tick = tick;
+ }
+#ifdef DELAYDEBUG
+ if (state == 1)
+ printf(" %d calls to getit() at %d usec each\n",
+ getit_calls, (n + 5) / getit_calls);
+#endif
+}
+
+
+static void
+sysbeepstop()
+{
+ outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */
+ release_timer2();
+ beeping = 0;
+}
+
+
+int
+sysbeep(int pitch, int period)
+{
+
+ if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
+ return -1;
+ disable_intr();
+ outb(TIMER_CNTR2, pitch);
+ outb(TIMER_CNTR2, (pitch>>8));
+ enable_intr();
+ if (!beeping) {
+ outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */
+ beeping = period;
+ timeout(sysbeepstop, 0, period);
+ }
+ return 0;
+}
-static void findcpuspeed(void);
void
startrtclock()
{
int s;
- findcpuspeed(); /* use the clock (while it's free)
- to find the cpu speed */
/* initialize 8253 clock */
outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
/* Correct rounding will buy us a better precision in timekeeping */
- outb (IO_TIMER1, (TIMER_FREQ+hz/2)/hz);
- outb (IO_TIMER1, ((TIMER_FREQ+hz/2)/hz)/256);
+ outb (IO_TIMER1, TIMER_DIV(hz)%256);
+ outb (IO_TIMER1, TIMER_DIV(hz)/256);
+ timer0_divisor = hardclock_divisor = TIMER_DIV(hz);
/* initialize brain-dead battery powered clock */
outb (IO_RTC, RTC_STATUSA);
@@ -83,44 +287,18 @@ startrtclock()
printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
}
-unsigned int delaycount; /* calibrated loop variable (1 millisecond) */
-
-#define FIRST_GUESS 0x2000
-static void
-findcpuspeed()
-{
- unsigned char low;
- unsigned int remainder;
-
- /* Put counter in count down mode */
- outb(IO_TIMER1+3, 0x34);
- outb(IO_TIMER1, 0xff);
- outb(IO_TIMER1, 0xff);
- delaycount = FIRST_GUESS;
- spinwait(1);
- /* Read the value left in the counter */
- low = inb(IO_TIMER1); /* least siginifcant */
- remainder = inb(IO_TIMER1); /* most significant */
- remainder = (remainder<<8) + low ;
- /* Formula for delaycount is :
- * (loopcount * timer clock speed)/ (counter ticks * 1000)
- */
- delaycount = (FIRST_GUESS * (TIMER_FREQ/1000)) / (0xffff-remainder);
-}
-
/* convert 2 digit BCD number */
int
-bcd(i)
- int i;
+bcd(int i)
{
return ((i/16)*10 + (i%16));
}
+
/* convert years to seconds (from 1970) */
unsigned long
-ytos(y)
-int y;
+ytos(int y)
{
int i;
unsigned long ret;
@@ -133,16 +311,16 @@ int y;
return ret;
}
+
/* convert months to seconds */
unsigned long
-mtos(m,leap)
-int m,leap;
+mtos(int m, int leap)
{
int i;
unsigned long ret;
ret = 0;
- for(i=1;i<m;i++) {
+ for(i=1; i<m; i++) {
switch(i){
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
ret += 31*24*60*60; break;
@@ -162,11 +340,10 @@ int m,leap;
* from a filesystem.
*/
void
-inittodr(base)
- time_t base;
+inittodr(time_t base)
{
unsigned long sec;
- int leap,day_week,t,yd;
+ int leap, day_week, t, yd;
int sa,s;
/* do we have a realtime clock present? (otherwise we loop below) */
@@ -180,26 +357,25 @@ inittodr(base)
sec = bcd(rtcin(RTC_YEAR)) + 1900;
if (sec < 1970)
sec += 100;
- leap = !(sec % 4); sec = ytos(sec); /* year */
- yd = mtos(bcd(rtcin(RTC_MONTH)),leap); sec += yd; /* month */
- t = (bcd(rtcin(RTC_DAY))-1) * 24*60*60; sec += t; yd += t; /* date */
+
+ leap = !(sec % 4); sec = ytos(sec); /* year */
+ yd = mtos(bcd(rtcin(RTC_MONTH)),leap); sec+=yd; /* month */
+ t = (bcd(rtcin(RTC_DAY))-1) * 24*60*60; sec+=t; yd+=t; /* date */
day_week = rtcin(RTC_WDAY); /* day */
sec += bcd(rtcin(RTC_HRS)) * 60*60; /* hour */
sec += bcd(rtcin(RTC_MIN)) * 60; /* minutes */
sec += bcd(rtcin(RTC_SEC)); /* seconds */
-
sec += tz.tz_minuteswest * 60;
-
time.tv_sec = sec;
}
+
#ifdef garbage
/*
* Initialze the time of day register, based on the time base which is, e.g.
* from a filesystem.
*/
-test_inittodr(base)
- time_t base;
+test_inittodr(time_t base)
{
outb(IO_RTC,9); /* year */
@@ -219,6 +395,7 @@ test_inittodr(base)
}
#endif
+
/*
* Restart the clock.
*/
@@ -227,12 +404,14 @@ resettodr()
{
}
+
/*
* Wire clock interrupt in.
*/
#define V(s) __CONCAT(V, s)
extern void V(clk)();
+
void
enablertclock()
{
@@ -240,12 +419,12 @@ enablertclock()
INTREN(IRQ0);
}
+
/*
* Delay for some number of milliseconds.
*/
void
-spinwait(millisecs)
- int millisecs;
+spinwait(int millisecs)
{
DELAY(1000 * millisecs);
}
diff --git a/sys/i386/isa/com.c b/sys/i386/isa/com.c
index dcaf878685be..25b4dee3238c 100644
--- a/sys/i386/isa/com.c
+++ b/sys/i386/isa/com.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: com.c,v 1.7 1993/12/19 00:50:32 wollman Exp $
+ * $Id: com.c,v 1.10 1994/05/30 03:14:13 ache Exp $
*/
#include "com.h"
@@ -86,7 +86,7 @@ int comconsinit;
int comdefaultrate = TTYDEF_SPEED;
int commajor;
short com_addr[NCOM];
-struct tty com_tty[NCOM];
+struct tty *com_tty[NCOM];
struct speedtab comspeedtab[] = {
0, 0,
@@ -199,12 +199,11 @@ comopen(int /*dev_t*/ dev, int flag, int mode, struct proc *p)
unit = UNIT(dev);
if (unit >= NCOM || (com_active & (1 << unit)) == 0)
return (ENXIO);
- tp = &com_tty[unit];
+ tp = com_tty[unit] = ttymalloc(com_tty[unit]);
tp->t_oproc = comstart;
tp->t_param = comparam;
tp->t_dev = dev;
if ((tp->t_state & TS_ISOPEN) == 0) {
- tp->t_state |= TS_WOPEN;
ttychars(tp);
if (tp->t_ispeed == 0) {
tp->t_iflag = TTYDEF_IFLAG;
@@ -223,9 +222,8 @@ comopen(int /*dev_t*/ dev, int flag, int mode, struct proc *p)
tp->t_state |= TS_CARR_ON;
while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 &&
(tp->t_state & TS_CARR_ON) == 0) {
- tp->t_state |= TS_WOPEN;
- if (error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH,
- ttopen, 0))
+ if (error = tsleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
+ "comdcd", 0))
break;
}
(void) spl0();
@@ -247,7 +245,7 @@ comclose(dev, flag, mode, p)
unit = UNIT(dev);
com = com_addr[unit];
- tp = &com_tty[unit];
+ tp = com_tty[unit];
(*linesw[tp->t_line].l_close)(tp, flag);
outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK);
#ifdef KGDB
@@ -255,10 +253,16 @@ comclose(dev, flag, mode, p)
if (kgdb_dev != makedev(commajor, unit))
#endif
outb(com+com_ier, 0);
- if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN ||
- (tp->t_state&TS_ISOPEN) == 0)
+ if (tp->t_cflag&HUPCL || (tp->t_state&TS_ISOPEN) == 0)
(void) commctl(dev, 0, DMSET);
ttyclose(tp);
+#ifdef broken /* session holds a ref to the tty; can't deallocate */
+ ttyfree(tp);
+ com_tty[unit] = (struct tty *)NULL;
+#endif
+ return (0);
+
+
return(0);
}
@@ -268,7 +272,7 @@ comread(dev, uio, flag)
struct uio *uio;
int flag;
{
- register struct tty *tp = &com_tty[UNIT(dev)];
+ register struct tty *tp = com_tty[UNIT(dev)];
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
}
@@ -280,7 +284,7 @@ comwrite(dev, uio, flag)
int flag;
{
int unit = UNIT(dev);
- register struct tty *tp = &com_tty[unit];
+ register struct tty *tp = com_tty[unit];
/*
* (XXX) We disallow virtual consoles if the physical console is
@@ -309,7 +313,7 @@ comintr(unit)
return;
case IIR_RXTOUT:
case IIR_RXRDY:
- tp = &com_tty[unit];
+ tp = com_tty[unit];
/*
* Process received bytes. Inline for speed...
*/
@@ -340,7 +344,7 @@ comintr(unit)
}
break;
case IIR_TXRDY:
- tp = &com_tty[unit];
+ tp = com_tty[unit];
tp->t_state &=~ (TS_BUSY|TS_FLUSH);
if (tp->t_line)
(*linesw[tp->t_line].l_start)(tp);
@@ -371,7 +375,7 @@ comeint(unit, stat, com)
register struct tty *tp;
register int c;
- tp = &com_tty[unit];
+ tp = com_tty[unit];
c = inb(com+com_data);
if ((tp->t_state & TS_ISOPEN) == 0) {
#ifdef KGDB
@@ -401,7 +405,7 @@ commint(unit, com)
register struct tty *tp;
register int stat;
- tp = &com_tty[unit];
+ tp = com_tty[unit];
stat = inb(com+com_msr);
if ((stat & MSR_DDCD) && (comsoftCAR & (1 << unit)) == 0) {
if (stat & MSR_DCD)
@@ -432,7 +436,7 @@ comioctl(dev, cmd, data, flag)
register com;
register int error;
- tp = &com_tty[unit];
+ tp = com_tty[unit];
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
if (error >= 0)
return (error);
@@ -545,26 +549,17 @@ comstart(tp)
s = spltty();
if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
goto out;
- if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
- if (tp->t_state&TS_ASLEEP) {
- tp->t_state &= ~TS_ASLEEP;
- wakeup((caddr_t)&tp->t_out);
- }
- if (tp->t_wsel) {
- selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
- tp->t_wsel = 0;
- tp->t_state &= ~TS_WCOLL;
- }
- }
- if (RB_LEN(&tp->t_out) == 0)
+ if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT) || tp->t_wsel)
+ ttwwakeup(tp);
+ if (RB_LEN(tp->t_out) == 0)
goto out;
if (inb(com+com_lsr) & LSR_TXRDY) {
- c = getc(&tp->t_out);
+ c = getc(tp->t_out);
tp->t_state |= TS_BUSY;
outb(com+com_data, c);
if (com_hasfifo & (1 << unit))
- for (c = 1; c < 16 && RB_LEN(&tp->t_out); ++c)
- outb(com+com_data, getc(&tp->t_out));
+ for (c = 1; c < 16 && RB_LEN(tp->t_out); ++c)
+ outb(com+com_data, getc(tp->t_out));
}
out:
splx(s);
@@ -647,7 +642,7 @@ comcnprobe(cp)
/* initialize required fields */
cp->cn_dev = makedev(commajor, unit);
- cp->cn_tp = &com_tty[unit];
+ cp->cn_tp = com_tty[unit];
#ifdef COMCONSOLE
cp->cn_pri = CN_REMOTE; /* Force a serial port console */
#else
@@ -747,43 +742,3 @@ comcnputc(dev, c)
splx(s);
}
#endif
-
-int
-comselect(dev, rw, p)
- dev_t dev;
- int rw;
- struct proc *p;
-{
- register struct tty *tp = &com_tty[UNIT(dev)];
- int nread;
- int s = spltty();
- struct proc *selp;
-
- switch (rw) {
-
- case FREAD:
- nread = ttnread(tp);
- if (nread > 0 ||
- ((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0))
- goto win;
- if (tp->t_rsel && (selp = pfind(tp->t_rsel)) && selp->p_wchan == (caddr_t)&selwait)
- tp->t_state |= TS_RCOLL;
- else
- tp->t_rsel = p->p_pid;
- break;
-
- case FWRITE:
- if (RB_LEN(&tp->t_out) <= tp->t_lowat)
- goto win;
- if (tp->t_wsel && (selp = pfind(tp->t_wsel)) && selp->p_wchan == (caddr_t)&selwait)
- tp->t_state |= TS_WCOLL;
- else
- tp->t_wsel = p->p_pid;
- break;
- }
- splx(s);
- return (0);
- win:
- splx(s);
- return (1);
-}
diff --git a/sys/i386/isa/debug.h b/sys/i386/isa/debug.h
deleted file mode 100644
index 92ecbd67f0fd..000000000000
--- a/sys/i386/isa/debug.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * from: debug.h, part of Bruce Evans interrupt code
- * $Id: debug.h,v 1.3 1993/11/13 02:25:20 davidg Exp $
- */
-
-#define SHOW_A_LOT_NOT
-
-#define BDBTRAP(name) \
- ss ; \
- cmpb $0,_bdb_exists ; \
- je 1f ; \
- testb $SEL_RPL_MASK,4(%esp) ; \
- jne 1f ; \
- ss ; \
-bdb_/**/name/**/_ljmp: ; \
- ljmp $0,$0 ; \
-1:
-
-#if 1
-#define COUNT_EVENT(group, event) incl (group) + (event) * 4
-#else
-#define COUNT_EVENT(group, event)
-#endif
-
-#ifdef SHOW_A_LOT
-
-#define GREEN 0x27 /* 0x27 for true green, 0x07 for mono */
-#define CLI_STI_X 63
-#define CPL_X 46
-#define IMEN_X 64
-#define IPENDING_X 29
-#define RED 0x47 /* 0x47 for true red, 0x70 for mono */
-
-#define SHOW_BIT(bit) ; \
- movl %ecx,%eax ; \
- shr $bit,%eax ; \
- andl $1,%eax ; \
- movb bit_colors(%eax),%al ; \
- movb %al,bit * 2 + 1(%ebx)
-
-#define SHOW_BITS(var, screen_offset) ; \
- pushl %ebx ; \
- pushl %ecx ; \
- movl _Crtat,%ebx ; \
- addl $screen_offset * 2,%ebx ; \
- movl _/**/var,%ecx ; \
- call show_bits ; \
- popl %ecx ; \
- popl %ebx
-
-#define SHOW_CLI \
- COUNT_EVENT(_intrcnt_show, 0) ; \
- pushl %eax ; \
- movl _Crtat,%eax ; \
- movb $RED,CLI_STI_X * 2 + 1(%eax) ; \
- popl %eax
-
-#define SHOW_CPL \
- COUNT_EVENT(_intrcnt_show, 1) ; \
- SHOW_BITS(cpl, CPL_X) ; \
-
-#define SHOW_IMEN \
- COUNT_EVENT(_intrcnt_show, 2) ; \
- SHOW_BITS(imen, IMEN_X)
-
-#define SHOW_IPENDING \
- COUNT_EVENT(_intrcnt_show, 3) ; \
- SHOW_BITS(ipending, IPENDING_X)
-
-#define SHOW_STI \
- COUNT_EVENT(_intrcnt_show, 4) ; \
- pushl %eax ; \
- movl _Crtat,%eax ; \
- movb $GREEN,CLI_STI_X * 2 + 1(%eax) ; \
- popl %eax
-
-#else /* not SHOW_A_LOT */
-
-#define SHOW_CLI COUNT_EVENT(_intrcnt_show, 0)
-#define SHOW_CPL COUNT_EVENT(_intrcnt_show, 1)
-#define SHOW_IMEN COUNT_EVENT(_intrcnt_show, 2)
-#define SHOW_IPENDING COUNT_EVENT(_intrcnt_show, 3)
-#define SHOW_STI COUNT_EVENT(_intrcnt_show, 4)
-
-#endif /* SHOW_A_LOT */
diff --git a/sys/i386/isa/elink.c b/sys/i386/isa/elink.c
new file mode 100644
index 000000000000..cd0057644a89
--- /dev/null
+++ b/sys/i386/isa/elink.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1994 Charles Hannum. 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 Charles Hannum.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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.
+ *
+ * $Id: elink.c,v 1.1 1994/05/25 20:06:40 ats Exp $
+ */
+
+/*
+ * Common code for dealing with 3COM ethernet cards.
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <machine/pio.h>
+#include <i386/isa/elink.h>
+
+/*
+ * Issue a `global reset' to all cards. We have to be careful to do this only
+ * once during autoconfig, to prevent resetting boards that have already been
+ * configured.
+ */
+void
+elink_reset()
+{
+ static int x = 0;
+
+ if (x == 0) {
+ x = 1;
+ outb(ELINK_ID_PORT, ELINK_RESET);
+ }
+}
+
+/*
+ * The `ID sequence' is really just snapshots of an 8-bit CRC register as 0
+ * bits are shifted in. Different board types use different polynomials.
+ */
+void
+elink_idseq(p)
+ register u_char p;
+{
+ register int i;
+ register u_char c;
+
+ c = 0xff;
+ for (i = 255; i; i--) {
+ outb(ELINK_ID_PORT, c);
+ if (c & 0x80) {
+ c <<= 1;
+ c ^= p;
+ } else
+ c <<= 1;
+ }
+}
diff --git a/sys/i386/isa/elink.h b/sys/i386/isa/elink.h
new file mode 100644
index 000000000000..93a5dac6f5ce
--- /dev/null
+++ b/sys/i386/isa/elink.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1994 Charles Hannum. 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 Charles Hannum.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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.
+ *
+ * $Id: elink.h,v 1.1 1994/05/25 20:06:43 ats Exp $
+ */
+
+#define ELINK_ID_PORT 0x100
+#define ELINK_RESET 0xc0
+
+#define ELINK_507_POLY 0xe7
+#define ELINK_509_POLY 0xcf
+
+void elink_reset __P((void));
+void elink_idseq __P((u_char p));
diff --git a/sys/i386/isa/fd.c b/sys/i386/isa/fd.c
index 8f3e1dc9cc94..f4632b9f2cb1 100644
--- a/sys/i386/isa/fd.c
+++ b/sys/i386/isa/fd.c
@@ -6,6 +6,12 @@
* This code is derived from software contributed to Berkeley by
* Don Ahn.
*
+ * Portions Copyright (c) 1993, 1994 by
+ * jc@irbs.UUCP (John Capo)
+ * vak@zebub.msk.su (Serge Vakulenko)
+ * ache@astral.msk.su (Andrew A. Chernov)
+ * joerg_wunsch@uriah.sax.de (Joerg Wunsch)
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -35,7 +41,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.21.2.1 1994/03/07 02:08:43 rgrimes Exp $
+ * $Id: fd.c,v 1.26 1994/05/22 12:30:32 joerg Exp $
*
*/
@@ -59,28 +65,29 @@
#include <sys/buf.h>
#include <sys/uio.h>
#include <sys/malloc.h>
+#include <sys/proc.h>
#include <sys/syslog.h>
#include "i386/isa/isa.h"
#include "i386/isa/isa_device.h"
#include "i386/isa/fdreg.h"
#include "i386/isa/fdc.h"
-#include "i386/isa/icu.h"
#include "i386/isa/rtc.h"
-#if NFT > 0
-extern int ftopen(), ftintr(), ftattach(), ftclose(), ftioctl();
-#endif
-
#define b_cylin b_resid
-#define FDBLK 512
/* misuse a flag to identify format operation */
#define B_FORMAT B_XXX
+/*
+ * this biotab field doubles as a field for the physical unit number
+ * on the controller
+ */
+#define id_physid id_scsiid
+
#define NUMTYPES 14
#define NUMDENS (NUMTYPES - 6)
-/* This defines (-1) must match index for fd_types */
+/* These defines (-1) must match index for fd_types */
#define F_TAPE_TYPE 0x020 /* bit for fd_types to indicate tape */
#define NO_TYPE 0 /* must match NO_TYPE in ft.c */
#define FD_1720 1
@@ -132,16 +139,17 @@ struct fdc_data fdc_data[NFDC];
struct fd_data {
struct fdc_data *fdc; /* pointer to controller structure */
int fdsu; /* this units number on this controller */
- int type; /* Drive type (HD, DD */
+ int type; /* Drive type (FD_1440...) */
struct fd_type *ft; /* pointer to the type descriptor */
int flags;
#define FD_OPEN 0x01 /* it's open */
#define FD_ACTIVE 0x02 /* it's active */
#define FD_MOTOR 0x04 /* motor should be on */
#define FD_MOTOR_WAIT 0x08 /* motor coming up */
- int skip;
- int hddrv;
- int track; /* where we think the head is */
+ int skip;
+ int hddrv;
+ int track; /* where we think the head is */
+ int options; /* user configurable options, see ioctl_fd.h */
} fd_data[NFD];
/***********************************************************************\
@@ -153,10 +161,48 @@ struct fd_data {
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
\***********************************************************************/
-#define id_physid id_scsiid /* this biotab field doubles as a field */
- /* for the physical unit number on the controller */
+#if NFT > 0
+int ftopen(dev_t, int);
+int ftintr(/* ftu_t */ int ftu);
+int ftclose(/* dev_t */ int, int);
+void ftstrategy(struct buf *);
+int ftioctl(/* dev_t */ int, int, caddr_t, int, struct proc *);
+int ftdump(/* dev_t */ int);
+int ftsize(/* dev_t */ int);
+int ftattach(struct isa_device *, struct isa_device *);
+#endif
+/* autoconfig functions */
+static int fdprobe(struct isa_device *);
+static int fdattach(struct isa_device *);
+
+/* exported functions */
+int fdsize (/* dev_t */ int);
+void fdintr(fdcu_t);
+int Fdopen(/* dev_t */int, int);
+int fdclose(/* dev_t */int, int);
+void fdstrategy(struct buf *);
+int fdioctl(/* dev_t */ int, int, caddr_t, int, struct proc *);
+
+/* needed for ft driver, thus exported */
+int in_fdc(fdcu_t);
+int out_fdc(fdcu_t, int);
+
+/* internal functions */
+static void set_motor(fdcu_t, int, int);
+# define TURNON 1
+# define TURNOFF 0
+static void fd_turnoff(caddr_t arg1, int arg2);
+static void fd_motor_on(caddr_t arg1, int arg2);
+static void fd_turnon(fdu_t);
+static void fdc_reset(fdc_p);
+static void fdstart(fdcu_t);
+static void fd_timeout(caddr_t, int);
+static void fd_pseudointr(caddr_t, int);
+static int fdstate(fdcu_t, fdc_p);
static int retrier(fdcu_t);
+static int fdformat(/* dev_t */ int, struct fd_formb *, struct proc *);
+
#define DEVIDLE 0
#define FINDWORK 1
@@ -188,25 +234,18 @@ char *fdstates[] =
"IOTIMEDOUT"
};
-
-int fd_debug = 1;
+/* CAUTION: fd_debug causes huge amounts of logging output */
+int fd_debug = 0;
#define TRACE0(arg) if(fd_debug) printf(arg)
-#define TRACE1(arg1,arg2) if(fd_debug) printf(arg1,arg2)
+#define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2)
#else /* DEBUG */
#define TRACE0(arg)
-#define TRACE1(arg1,arg2)
+#define TRACE1(arg1, arg2)
#endif /* DEBUG */
-static void fdstart(fdcu_t);
-void fdintr(fdcu_t);
-static void fd_turnoff(caddr_t, int);
-
/****************************************************************************/
/* autoconfiguration stuff */
/****************************************************************************/
-static int fdprobe(struct isa_device *);
-static int fdattach(struct isa_device *);
-
struct isa_driver fdcdriver = {
fdprobe, fdattach, "fdc",
};
@@ -214,56 +253,55 @@ struct isa_driver fdcdriver = {
/*
* probe for existance of controller
*/
-int
+static int
fdprobe(dev)
struct isa_device *dev;
{
fdcu_t fdcu = dev->id_unit;
if(fdc_data[fdcu].flags & FDC_ATTACHED)
{
- printf("fdc: same unit (%d) used multiple times\n",fdcu);
+ printf("fdc: same unit (%d) used multiple times\n", fdcu);
return 0;
}
fdc_data[fdcu].baseport = dev->id_iobase;
/* First - lets reset the floppy controller */
-
- outb(dev->id_iobase+fdout,0);
+ outb(dev->id_iobase+FDOUT, 0);
DELAY(100);
- outb(dev->id_iobase+fdout,FDO_FRST);
+ outb(dev->id_iobase+FDOUT, FDO_FRST);
/* see if it can handle a command */
- if (out_fdc(fdcu,NE7CMD_SPECIFY) < 0)
+ if (out_fdc(fdcu, NE7CMD_SPECIFY) < 0)
{
return(0);
}
- out_fdc(fdcu,0xDF);
- out_fdc(fdcu,2);
+ out_fdc(fdcu, NE7_SPEC_1(3, 240));
+ out_fdc(fdcu, NE7_SPEC_2(2, 0));
return (IO_FDCSIZE);
}
/*
* wire controller into system, look for floppy units
*/
-int
+static int
fdattach(dev)
struct isa_device *dev;
{
- unsigned fdt,st0, cyl;
- int hdr;
+ unsigned fdt;
fdu_t fdu;
fdcu_t fdcu = dev->id_unit;
fdc_p fdc = fdc_data + fdcu;
fd_p fd;
- int fdsu;
+ int fdsu, st0;
struct isa_device *fdup;
fdc->fdcu = fdcu;
fdc->flags |= FDC_ATTACHED;
fdc->dmachan = dev->id_drq;
fdc->state = DEVIDLE;
- hdr = 0;
+ /* reset controller, turn motor off, clear fdout mirror reg */
+ outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
printf("fdc%d:", fdcu);
/* check for each floppy drive */
@@ -303,25 +341,33 @@ fdattach(dev)
continue;
}
-#ifdef notyet
/* select it */
- fd_turnon1(fdu);
- spinwait(1000); /* 1 sec */
- out_fdc(fdcu,NE7CMD_RECAL); /* Recalibrate Function */
- out_fdc(fdcu,fdsu);
+ set_motor(fdcu, fdsu, TURNON);
spinwait(1000); /* 1 sec */
+ out_fdc(fdcu, NE7CMD_SEEK); /* seek some steps... */
+ out_fdc(fdcu, fdsu);
+ out_fdc(fdcu, 10);
+ spinwait(300); /* ...wait a moment... */
+ out_fdc(fdcu, NE7CMD_SENSEI); /* make controller happy */
+ (void)in_fdc(fdcu);
+ (void)in_fdc(fdcu);
+ out_fdc(fdcu, NE7CMD_RECAL); /* ...and go back to 0 */
+ out_fdc(fdcu, fdsu);
+ spinwait(1000); /* a second be enough for full stroke seek */
/* anything responding */
- out_fdc(fdcu,NE7CMD_SENSEI);
+ out_fdc(fdcu, NE7CMD_SENSEI);
st0 = in_fdc(fdcu);
- cyl = in_fdc(fdcu);
- if (st0 & 0xd0)
+ (void)in_fdc(fdcu);
+ set_motor(fdcu, fdsu, TURNOFF);
+
+ if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
continue;
-#endif
fd->track = -2;
fd->fdc = fdc;
fd->fdsu = fdsu;
+ fd->options = 0;
printf(" [%d: fd%d: ", fdsu, fdu);
switch (fdt) {
@@ -346,15 +392,10 @@ fdattach(dev)
fd->type = NO_TYPE;
break;
}
-
- fd_turnoff((caddr_t)fdu, 0);
- hdr = 1;
}
printf("\n");
- /* Set transfer to 500kbps */
- outb(fdc->baseport+fdctl,0); /*XXX*/
- return 1;
+ return (1);
}
int
@@ -365,102 +406,47 @@ fdsize(dev)
}
/****************************************************************************/
-/* fdstrategy */
-/****************************************************************************/
-void fdstrategy(struct buf *bp)
-{
- register struct buf *dp,*dp0,*dp1;
- long nblocks,blknum;
- int s;
- fdcu_t fdcu;
- fdu_t fdu;
- fdc_p fdc;
- fd_p fd;
-
- fdu = FDUNIT(minor(bp->b_dev));
- fd = &fd_data[fdu];
- fdc = fd->fdc;
- fdcu = fdc->fdcu;
-
-#if NFT > 0
- /* check for controller already busy with tape */
- if (fdc->flags & FDC_TAPE_BUSY) {
- bp->b_error = EBUSY;
- bp->b_flags |= B_ERROR;
- return;
- }
-#endif
- if ((fdu >= NFD) || (bp->b_blkno < 0)) {
- printf("fdstrat: fdu = %d, blkno = %d, bcount = %d\n",
- fdu, bp->b_blkno, bp->b_bcount);
- pg("fd:error in fdstrategy");
- bp->b_error = EINVAL;
- bp->b_flags |= B_ERROR;
- goto bad;
- }
- /*
- * Set up block calculations.
- */
- blknum = (unsigned long) bp->b_blkno * DEV_BSIZE/FDBLK;
- nblocks = fd->ft->size;
- if (blknum + (bp->b_bcount / FDBLK) > nblocks) {
- if (blknum == nblocks) {
- bp->b_resid = bp->b_bcount;
- } else {
- bp->b_error = ENOSPC;
- bp->b_flags |= B_ERROR;
- }
- goto bad;
- }
- bp->b_cylin = blknum / (fd->ft->sectrac * fd->ft->heads);
- dp = &(fdc->head);
- s = splbio();
- disksort(dp, bp);
- untimeout(fd_turnoff, (caddr_t)fdu); /* a good idea */
- fdstart(fdcu);
- splx(s);
- return;
-
-bad:
- biodone(bp);
- return;
-}
-
-/****************************************************************************/
/* motor control stuff */
/* remember to not deselect the drive we're working on */
/****************************************************************************/
-void
-set_motor(fdcu, fdu, reset)
+static void
+set_motor(fdcu, fdsu, turnon)
fdcu_t fdcu;
- fdu_t fdu;
- int reset;
+ int fdsu;
+ int turnon;
{
- int m0,m1;
- int selunit;
- fd_p fd;
- if(fd = fdc_data[fdcu].fd)/* yes an assign! */
- {
- selunit = fd->fdsu;
+ int fdout = fdc_data[fdcu].fdout;
+ int needspecify = 0;
+
+ if(turnon) {
+ fdout &= ~FDO_FDSEL;
+ fdout |= (FDO_MOEN0 << fdsu) + fdsu;
+ } else
+ fdout &= ~(FDO_MOEN0 << fdsu);
+
+ if(!turnon
+ && (fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0)
+ /* gonna turn off the last drive, put FDC to bed */
+ fdout &= ~ (FDO_FRST|FDO_FDMAEN);
+ else {
+ /* make sure controller is selected and specified */
+ if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0)
+ needspecify = 1;
+ fdout |= (FDO_FRST|FDO_FDMAEN);
}
- else
- {
- selunit = 0;
+
+ outb(fdc_data[fdcu].baseport+FDOUT, fdout);
+ fdc_data[fdcu].fdout = fdout;
+ TRACE1("[0x%x->FDOUT]", fdout);
+
+ if(needspecify) {
+ out_fdc(fdcu, NE7CMD_SPECIFY);
+ out_fdc(fdcu, NE7_SPEC_1(3, 240));
+ out_fdc(fdcu, NE7_SPEC_2(2, 0));
}
- m0 = fd_data[fdcu * DRVS_PER_CTLR + 0].flags & FD_MOTOR;
- m1 = fd_data[fdcu * DRVS_PER_CTLR + 1].flags & FD_MOTOR;
- outb(fdc_data[fdcu].baseport+fdout,
- selunit
- | (reset ? 0 : (FDO_FRST|FDO_FDMAEN))
- | (m0 ? FDO_MOEN0 : 0)
- | (m1 ? FDO_MOEN1 : 0));
- TRACE1("[0x%x->fdout]",(
- selunit
- | (reset ? 0 : (FDO_FRST|FDO_FDMAEN))
- | (m0 ? FDO_MOEN0 : 0)
- | (m1 ? FDO_MOEN1 : 0)));
}
+/* ARGSUSED */
static void
fd_turnoff(caddr_t arg1, int arg2)
{
@@ -470,11 +456,12 @@ fd_turnoff(caddr_t arg1, int arg2)
fd_p fd = fd_data + fdu;
s = splbio();
fd->flags &= ~FD_MOTOR;
- set_motor(fd->fdc->fdcu,fd->fdsu,0);
+ set_motor(fd->fdc->fdcu, fd->fdsu, TURNOFF);
splx(s);
}
-void
+/* ARGSUSED */
+static void
fd_motor_on(caddr_t arg1, int arg2)
{
fdu_t fdu = (fdu_t)arg1;
@@ -490,27 +477,39 @@ fd_motor_on(caddr_t arg1, int arg2)
splx(s);
}
-static void fd_turnon1(fdu_t);
-
-void
+static void
fd_turnon(fdu)
fdu_t fdu;
{
fd_p fd = fd_data + fdu;
if(!(fd->flags & FD_MOTOR))
{
- fd_turnon1(fdu);
- fd->flags |= FD_MOTOR_WAIT;
+ fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT);
+ set_motor(fd->fdc->fdcu, fd->fdsu, TURNON);
timeout(fd_motor_on, (caddr_t)fdu, hz); /* in 1 sec its ok */
}
}
static void
-fd_turnon1(fdu_t fdu)
+fdc_reset(fdc)
+ fdc_p fdc;
{
- fd_p fd = fd_data + fdu;
- fd->flags |= FD_MOTOR;
- set_motor(fd->fdc->fdcu,fd->fdsu,0);
+ fdcu_t fdcu = fdc->fdcu;
+
+ /* Try a reset, keep motor on */
+ outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
+ TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
+ DELAY(100);
+ /* enable FDC, but defer interrupts a moment */
+ outb(fdc->baseport + FDOUT, fdc->fdout & ~FDO_FDMAEN);
+ TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN);
+ DELAY(100);
+ outb(fdc->baseport + FDOUT, fdc->fdout);
+ TRACE1("[0x%x->FDOUT]", fdc->fdout);
+
+ out_fdc(fdcu, NE7CMD_SPECIFY);
+ out_fdc(fdcu, NE7_SPEC_1(3, 240));
+ out_fdc(fdcu, NE7_SPEC_2(2, 0));
}
/****************************************************************************/
@@ -522,17 +521,17 @@ in_fdc(fdcu)
{
int baseport = fdc_data[fdcu].baseport;
int i, j = 100000;
- while ((i = inb(baseport+fdsts) & (NE7_DIO|NE7_RQM))
+ while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM))
!= (NE7_DIO|NE7_RQM) && j-- > 0)
if (i == NE7_RQM) return -1;
if (j <= 0)
return(-1);
#ifdef DEBUG
- i = inb(baseport+fddata);
- TRACE1("[fddata->0x%x]",(unsigned char)i);
+ i = inb(baseport+FDDATA);
+ TRACE1("[FDDATA->0x%x]", (unsigned char)i);
return(i);
#else
- return inb(baseport+fddata);
+ return inb(baseport+FDDATA);
#endif
}
@@ -546,17 +545,17 @@ out_fdc(fdcu, x)
/* Check that the direction bit is set */
i = 100000;
- while ((inb(baseport+fdsts) & NE7_DIO) && i-- > 0);
+ while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0);
if (i <= 0) return (-1); /* Floppy timed out */
/* Check that the floppy controller is ready for a command */
i = 100000;
- while ((inb(baseport+fdsts) & NE7_RQM) == 0 && i-- > 0);
+ while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0);
if (i <= 0) return (-1); /* Floppy timed out */
/* Send the command and return */
- outb(baseport+fddata,x);
- TRACE1("[0x%x->fddata]",x);
+ outb(baseport+FDDATA, x);
+ TRACE1("[0x%x->FDDATA]", x);
return (0);
}
@@ -647,17 +646,97 @@ fdclose(dev, flags)
int flags;
{
fdu_t fdu = FDUNIT(minor(dev));
- int type = FDTYPE(minor(dev));
#if NFT > 0
+ int type = FDTYPE(minor(dev));
+
if (type & F_TAPE_TYPE)
- return ftclose(0);
+ return ftclose(dev, flags);
#endif
fd_data[fdu].flags &= ~FD_OPEN;
+ fd_data[fdu].options &= ~FDOPT_NORETRY;
return(0);
}
+/****************************************************************************/
+/* fdstrategy */
+/****************************************************************************/
+void
+fdstrategy(struct buf *bp)
+{
+ register struct buf *dp;
+ long nblocks, blknum;
+ int s;
+ fdcu_t fdcu;
+ fdu_t fdu;
+ fdc_p fdc;
+ fd_p fd;
+ size_t fdblk;
+
+ fdu = FDUNIT(minor(bp->b_dev));
+ fd = &fd_data[fdu];
+ fdc = fd->fdc;
+ fdcu = fdc->fdcu;
+ fdblk = 128 << (fd->ft->secsize);
+
+#if NFT > 0
+ if (FDTYPE(minor(bp->b_dev)) & F_TAPE_TYPE) {
+ /* ft tapes do not (yet) support strategy i/o */
+ bp->b_error = ENXIO;
+ bp->b_flags |= B_ERROR;
+ goto bad;
+ }
+ /* check for controller already busy with tape */
+ if (fdc->flags & FDC_TAPE_BUSY) {
+ bp->b_error = EBUSY;
+ bp->b_flags |= B_ERROR;
+ goto bad;
+ }
+#endif
+ if (!(bp->b_flags & B_FORMAT)) {
+ if ((fdu >= NFD) || (bp->b_blkno < 0)) {
+ printf("fdstrat: fdu = %d, blkno = %d, bcount = %d\n",
+ fdu, bp->b_blkno, bp->b_bcount);
+ bp->b_error = EINVAL;
+ bp->b_flags |= B_ERROR;
+ goto bad;
+ }
+ if ((bp->b_bcount % fdblk) != 0) {
+ bp->b_error = EINVAL;
+ bp->b_flags |= B_ERROR;
+ goto bad;
+ }
+ }
+
+ /*
+ * Set up block calculations.
+ */
+ blknum = (unsigned long) bp->b_blkno * DEV_BSIZE/fdblk;
+ nblocks = fd->ft->size;
+ if (blknum + (bp->b_bcount / fdblk) > nblocks) {
+ if (blknum == nblocks) {
+ bp->b_resid = bp->b_bcount;
+ } else {
+ bp->b_error = ENOSPC;
+ bp->b_flags |= B_ERROR;
+ }
+ goto bad;
+ }
+ bp->b_cylin = blknum / (fd->ft->sectrac * fd->ft->heads);
+ dp = &(fdc->head);
+ s = splbio();
+ disksort(dp, bp);
+ untimeout(fd_turnoff, (caddr_t)fdu); /* a good idea */
+ fdstart(fdcu);
+ splx(s);
+ return;
+
+bad:
+ biodone(bp);
+ return;
+}
+
/***************************************************************\
* fdstart *
* We have just queued something.. if the controller is not busy *
@@ -671,9 +750,7 @@ static void
fdstart(fdcu)
fdcu_t fdcu;
{
- register struct buf *dp,*bp;
int s;
- fdu_t fdu;
s = splbio();
if(fdc_data[fdcu].state == DEVIDLE)
@@ -683,38 +760,43 @@ fdstart(fdcu)
splx(s);
}
+/* ARGSUSED */
static void
fd_timeout(caddr_t arg1, int arg2)
{
fdcu_t fdcu = (fdcu_t)arg1;
fdu_t fdu = fdc_data[fdcu].fdu;
- int st0, st3, cyl;
- struct buf *dp,*bp;
- int s;
+ int baseport = fdc_data[fdcu].baseport;
+ struct buf *dp, *bp;
+ int s;
dp = &fdc_data[fdcu].head;
- s = splbio();
bp = dp->b_actf;
- out_fdc(fdcu,NE7CMD_SENSED);
- out_fdc(fdcu,fd_data[fdu].hddrv);
- st3 = in_fdc(fdcu);
-
- out_fdc(fdcu,NE7CMD_SENSEI);
- st0 = in_fdc(fdcu);
- cyl = in_fdc(fdcu);
- printf("fd%d: Operation timeout ST0 %b cyl %d ST3 %b\n",
- fdu,
- st0,
- NE7_ST0BITS,
- cyl,
- st3,
- NE7_ST3BITS);
+ /*
+ * Due to IBM's brain-dead design, the FDC has a faked ready
+ * signal, hardwired to ready == true. Thus, any command
+ * issued if there's no diskette in the drive will _never_
+ * complete, and must be aborted by resetting the FDC.
+ * Many thanks, Big Blue!
+ */
+
+ s = splbio();
+
+ TRACE1("fd%d[fd_timeout()]", fdu);
+ /* See if the controller is still busy (patiently awaiting data) */
+ if(((inb(baseport + FDSTS)) & (NE7_CB|NE7_RQM)) == NE7_CB)
+ {
+ TRACE1("[FDSTS->0x%x]", inb(baseport + FDSTS));
+ /* yup, it is; kill it now */
+ fdc_reset(&fdc_data[fdcu]);
+ printf("fd%d: Operation timeout\n", fdu);
+ }
if (bp)
{
retrier(fdcu);
- fdc_data[fdcu].status[0] = 0xc0;
+ fdc_data[fdcu].status[0] = NE7_ST0_IC_RC;
fdc_data[fdcu].state = IOTIMEDOUT;
if( fdc_data[fdcu].retry < 6)
fdc_data[fdcu].retry = 6;
@@ -730,11 +812,13 @@ fd_timeout(caddr_t arg1, int arg2)
}
/* just ensure it has the right spl */
+/* ARGSUSED */
static void
fd_pseudointr(caddr_t arg1, int arg2)
{
fdcu_t fdcu = (fdcu_t)arg1;
int s;
+
s = splbio();
fdintr(fdcu);
splx(s);
@@ -756,25 +840,26 @@ fdintr(fdcu_t fdcu)
(ftintr(fdu));
else
#endif
- while(fdstate(fdcu, fdc))
- ;
+ while(fdstate(fdcu, fdc))
+ ;
}
/***********************************************************************\
* The controller state machine. *
* if it returns a non zero value, it should be called again immediatly *
\***********************************************************************/
-int
+static int
fdstate(fdcu, fdc)
fdcu_t fdcu;
fdc_p fdc;
{
- int read, format, head, trac, sec = 0, i = 0, s, sectrac, cyl, st0;
+ int read, format, head, sec = 0, i = 0, sectrac, st0, cyl, st3;
unsigned long blknum;
fdu_t fdu = fdc->fdu;
fd_p fd;
- register struct buf *dp,*bp;
+ register struct buf *dp, *bp;
struct fd_formb *finfo = NULL;
+ size_t fdblk;
dp = &(fdc->head);
bp = dp->b_actf;
@@ -787,16 +872,17 @@ fdstate(fdcu, fdc)
fdc->state = DEVIDLE;
if(fdc->fd)
{
- printf("unexpected valid fd pointer (fdu = %d)\n"
- ,fdc->fdu);
+ printf("unexpected valid fd pointer (fdu = %d)\n",
+ fdc->fdu);
fdc->fd = (fd_p) 0;
fdc->fdu = -1;
}
- TRACE1("[fdc%d IDLE]",fdcu);
+ TRACE1("[fdc%d IDLE]", fdcu);
return(0);
}
fdu = FDUNIT(minor(bp->b_dev));
fd = fd_data + fdu;
+ fdblk = 128 << fd->ft->secsize;
if (fdc->fd && (fd != fdc->fd))
{
printf("confused fd pointers\n");
@@ -805,9 +891,9 @@ fdstate(fdcu, fdc)
format = bp->b_flags & B_FORMAT;
if(format)
finfo = (struct fd_formb *)bp->b_un.b_addr;
- TRACE1("fd%d",fdu);
- TRACE1("[%s]",fdstates[fdc->state]);
- TRACE1("(0x%x)",fd->flags);
+ TRACE1("fd%d", fdu);
+ TRACE1("[%s]", fdstates[fdc->state]);
+ TRACE1("(0x%x)", fd->flags);
untimeout(fd_turnoff, (caddr_t)fdu);
timeout(fd_turnoff, (caddr_t)fdu, 4 * hz);
switch (fdc->state)
@@ -818,6 +904,8 @@ fdstate(fdcu, fdc)
fd->skip = 0;
fdc->fd = fd;
fdc->fdu = fdu;
+ outb(fdc->baseport+FDCTL, fd->ft->trans);
+ TRACE1("[0x%x->FDCTL]", fd->ft->trans);
/*******************************************************\
* If the next drive has a motor startup pending, then *
* it will start up in it's own good time *
@@ -838,7 +926,7 @@ fdstate(fdcu, fdc)
}
else /* at least make sure we are selected */
{
- set_motor(fdcu,fd->fdsu,0);
+ set_motor(fdcu, fd->fdsu, TURNON);
}
fdc->state = DOSEEK;
break;
@@ -848,33 +936,55 @@ fdstate(fdcu, fdc)
fdc->state = SEEKCOMPLETE;
break;
}
- out_fdc(fdcu,NE7CMD_SEEK); /* Seek function */
- out_fdc(fdcu,fd->fdsu); /* Drive number */
- out_fdc(fdcu,bp->b_cylin * fd->ft->steptrac);
+ out_fdc(fdcu, NE7CMD_SEEK); /* Seek function */
+ out_fdc(fdcu, fd->fdsu); /* Drive number */
+ out_fdc(fdcu, bp->b_cylin * fd->ft->steptrac);
fd->track = -2;
fdc->state = SEEKWAIT;
- timeout(fd_timeout, (caddr_t)fdcu, 2 * hz);
return(0); /* will return later */
case SEEKWAIT:
- untimeout(fd_timeout, (caddr_t)fdcu);
/* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, hz / 50);
+ timeout(fd_pseudointr, (caddr_t)fdcu, hz / 32);
fdc->state = SEEKCOMPLETE;
return(0); /* will return later */
- break;
-
case SEEKCOMPLETE : /* SEEK DONE, START DMA */
/* Make sure seek really happened*/
if(fd->track == -2)
{
int descyl = bp->b_cylin * fd->ft->steptrac;
- out_fdc(fdcu,NE7CMD_SENSEI);
- i = in_fdc(fdcu);
- cyl = in_fdc(fdcu);
+ do {
+ out_fdc(fdcu, NE7CMD_SENSEI);
+ st0 = in_fdc(fdcu);
+ cyl = in_fdc(fdcu);
+ /*
+ * if this was a "ready changed" interrupt,
+ * fetch status again (can happen after
+ * enabling controller from reset state)
+ */
+ } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
+ if (0 == descyl)
+ {
+ /*
+ * seek to cyl 0 requested; make sure we are
+ * really there
+ */
+ out_fdc(fdcu, NE7CMD_SENSED);
+ out_fdc(fdcu, fdu);
+ st3 = in_fdc(fdcu);
+ if ((st3 & NE7_ST3_T0) == 0) {
+ printf(
+ "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n",
+ fdu, st3, NE7_ST3BITS);
+ if(fdc->retry < 3)
+ fdc->retry = 3;
+ return(retrier(fdcu));
+ }
+ }
if (cyl != descyl)
{
- printf("fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
- fdu, descyl, cyl, i, NE7_ST0BITS);
+ printf(
+ "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
+ fdu, descyl, cyl, st0, NE7_ST0BITS);
return(retrier(fdcu));
}
}
@@ -884,46 +994,73 @@ fdstate(fdcu, fdc)
fd->skip = (char *)&(finfo->fd_formb_cylno(0))
- (char *)finfo;
isa_dmastart(bp->b_flags, bp->b_un.b_addr+fd->skip,
- format ? bp->b_bcount : FDBLK, fdc->dmachan);
- blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/FDBLK
- + fd->skip/FDBLK;
+ format ? bp->b_bcount : fdblk, fdc->dmachan);
+ blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/fdblk
+ + fd->skip/fdblk;
sectrac = fd->ft->sectrac;
sec = blknum % (sectrac * fd->ft->heads);
head = sec / sectrac;
sec = sec % sectrac + 1;
-/*XXX*/ fd->hddrv = ((head&1)<<2)+fdu;
+ fd->hddrv = ((head&1)<<2)+fdu;
+
+ if(format || !read)
+ {
+ /* make sure the drive is writable */
+ out_fdc(fdcu, NE7CMD_SENSED);
+ out_fdc(fdcu, fdu);
+ st3 = in_fdc(fdcu);
+ if(st3 & NE7_ST3_WP)
+ {
+ /*
+ * XXX YES! this is ugly.
+ * in order to force the current operation
+ * to fail, we will have to fake an FDC
+ * error - all error handling is done
+ * by the retrier()
+ */
+ fdc->status[0] = NE7_ST0_IC_AT;
+ fdc->status[1] = NE7_ST1_NW;
+ fdc->status[2] = 0;
+ fdc->status[3] = fd->track;
+ fdc->status[4] = head;
+ fdc->status[5] = sec;
+ fdc->retry = 8; /* break out immediately */
+ fdc->state = IOTIMEDOUT; /* not really... */
+ return (1);
+ }
+ }
if(format)
{
/* formatting */
- out_fdc(fdcu,/* NE7CMD_FORMAT */ 0x4d);
- out_fdc(fdcu,head << 2 | fdu);
- out_fdc(fdcu,finfo->fd_formb_secshift);
- out_fdc(fdcu,finfo->fd_formb_nsecs);
- out_fdc(fdcu,finfo->fd_formb_gaplen);
- out_fdc(fdcu,finfo->fd_formb_fillbyte);
+ out_fdc(fdcu, NE7CMD_FORMAT);
+ out_fdc(fdcu, head << 2 | fdu);
+ out_fdc(fdcu, finfo->fd_formb_secshift);
+ out_fdc(fdcu, finfo->fd_formb_nsecs);
+ out_fdc(fdcu, finfo->fd_formb_gaplen);
+ out_fdc(fdcu, finfo->fd_formb_fillbyte);
}
else
{
if (read)
{
- out_fdc(fdcu,NE7CMD_READ); /* READ */
+ out_fdc(fdcu, NE7CMD_READ); /* READ */
}
else
{
- out_fdc(fdcu,NE7CMD_WRITE); /* WRITE */
+ out_fdc(fdcu, NE7CMD_WRITE); /* WRITE */
}
- out_fdc(fdcu,head << 2 | fdu); /* head & unit */
- out_fdc(fdcu,fd->track); /* track */
- out_fdc(fdcu,head);
- out_fdc(fdcu,sec); /* sector XXX +1? */
- out_fdc(fdcu,fd->ft->secsize); /* sector size */
- out_fdc(fdcu,sectrac); /* sectors/track */
- out_fdc(fdcu,fd->ft->gap); /* gap size */
- out_fdc(fdcu,fd->ft->datalen); /* data length */
+ out_fdc(fdcu, head << 2 | fdu); /* head & unit */
+ out_fdc(fdcu, fd->track); /* track */
+ out_fdc(fdcu, head);
+ out_fdc(fdcu, sec); /* sector XXX +1? */
+ out_fdc(fdcu, fd->ft->secsize); /* sector size */
+ out_fdc(fdcu, sectrac); /* sectors/track */
+ out_fdc(fdcu, fd->ft->gap); /* gap size */
+ out_fdc(fdcu, fd->ft->datalen); /* data length */
}
fdc->state = IOCOMPLETE;
- timeout(fd_timeout, (caddr_t)fdcu, 2 * hz);
+ timeout(fd_timeout, (caddr_t)fdcu, hz);
return(0); /* will return later */
case IOCOMPLETE: /* IO DONE, post-analyze */
untimeout(fd_timeout, (caddr_t)fdcu);
@@ -931,30 +1068,43 @@ fdstate(fdcu, fdc)
{
fdc->status[i] = in_fdc(fdcu);
}
- case IOTIMEDOUT: /*XXX*/
+ fdc->state = IOTIMEDOUT;
+ /* FALLTHROUGH */
+ case IOTIMEDOUT:
isa_dmadone(bp->b_flags, bp->b_un.b_addr+fd->skip,
- format ? bp->b_bcount : FDBLK, fdc->dmachan);
- if (fdc->status[0]&0xF8)
+ format ? bp->b_bcount : fdblk, fdc->dmachan);
+ if (fdc->status[0] & NE7_ST0_IC)
{
- if (fdc->status[1] & 0x10) {
+ if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
+ && fdc->status[1] & NE7_ST1_OR) {
/*
- * Operation not completed in reasonable time.
- * Just restart it, don't increment retry count.
- * (vak)
+ * DMA overrun. Someone hogged the bus
+ * and didn't release it in time for the
+ * next FDC transfer.
+ * Just restart it, don't increment retry
+ * count. (vak)
*/
fdc->state = SEEKCOMPLETE;
return (1);
}
+ else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV
+ && fdc->retry < 6)
+ fdc->retry = 6; /* force a reset */
+ else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
+ && fdc->status[2] & NE7_ST2_WC
+ && fdc->retry < 3)
+ fdc->retry = 3; /* force recalibrate */
return(retrier(fdcu));
}
/* All OK */
- fd->skip += FDBLK;
+ fd->skip += fdblk;
if (!format && fd->skip < bp->b_bcount)
{
/* set up next transfer */
- blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/FDBLK
- + fd->skip/FDBLK;
- bp->b_cylin = (blknum / (fd->ft->sectrac * fd->ft->heads));
+ blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/fdblk
+ + fd->skip/fdblk;
+ bp->b_cylin =
+ (blknum / (fd->ft->sectrac * fd->ft->heads));
fdc->state = DOSEEK;
}
else
@@ -970,68 +1120,76 @@ fdstate(fdcu, fdc)
}
return(1);
case RESETCTLR:
- /* Try a reset, keep motor on */
- set_motor(fdcu,fd->fdsu,1);
- DELAY(100);
- set_motor(fdcu,fd->fdsu,0);
- outb(fdc->baseport+fdctl,fd->ft->trans);
- TRACE1("[0x%x->fdctl]",fd->ft->trans);
+ fdc_reset(fdc);
fdc->retry++;
fdc->state = STARTRECAL;
break;
case STARTRECAL:
- out_fdc(fdcu,NE7CMD_SPECIFY); /* specify command */
- out_fdc(fdcu,0xDF);
- out_fdc(fdcu,2);
- out_fdc(fdcu,NE7CMD_RECAL); /* Recalibrate Function */
- out_fdc(fdcu,fdu);
+ out_fdc(fdcu, NE7CMD_RECAL); /* Recalibrate Function */
+ out_fdc(fdcu, fdu);
fdc->state = RECALWAIT;
return(0); /* will return later */
case RECALWAIT:
/* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, hz / 30);
+ timeout(fd_pseudointr, (caddr_t)fdcu, hz / 32);
fdc->state = RECALCOMPLETE;
return(0); /* will return later */
case RECALCOMPLETE:
- out_fdc(fdcu,NE7CMD_SENSEI);
- st0 = in_fdc(fdcu);
- cyl = in_fdc(fdcu);
- if (cyl != 0)
+ do {
+ out_fdc(fdcu, NE7CMD_SENSEI);
+ st0 = in_fdc(fdcu);
+ cyl = in_fdc(fdcu);
+ /*
+ * if this was a "ready changed" interrupt,
+ * fetch status again (can happen after
+ * enabling controller from reset state)
+ */
+ } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
+ if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0)
{
printf("fd%d: recal failed ST0 %b cyl %d\n", fdu,
st0, NE7_ST0BITS, cyl);
+ if(fdc->retry < 3) fdc->retry = 3;
return(retrier(fdcu));
}
fd->track = 0;
/* Seek (probably) necessary */
fdc->state = DOSEEK;
return(1); /* will return immediatly */
- case MOTORWAIT:
+ case MOTORWAIT:
if(fd->flags & FD_MOTOR_WAIT)
{
return(0); /* time's not up yet */
}
- fdc->state = DOSEEK;
+ /*
+ * since the controller was off, it has lost its
+ * idea about the current track it were; thus,
+ * recalibrate the bastard
+ */
+ fdc->state = STARTRECAL;
return(1); /* will return immediatly */
default:
printf("Unexpected FD int->");
- out_fdc(fdcu,NE7CMD_SENSEI);
+ out_fdc(fdcu, NE7CMD_SENSEI);
st0 = in_fdc(fdcu);
cyl = in_fdc(fdcu);
- printf("ST0 = %lx, PCN = %lx\n",i,sec);
- out_fdc(fdcu,0x4A);
- out_fdc(fdcu,fd->fdsu);
+ printf("ST0 = %x, PCN = %x\n", st0, cyl);
+ out_fdc(fdcu, NE7CMD_READID);
+ out_fdc(fdcu, fd->fdsu);
for(i=0;i<7;i++) {
fdc->status[i] = in_fdc(fdcu);
}
- printf("intr status :%lx %lx %lx %lx %lx %lx %lx ",
- fdc->status[0],
- fdc->status[1],
- fdc->status[2],
- fdc->status[3],
- fdc->status[4],
- fdc->status[5],
- fdc->status[6] );
+ if(fdc->status[0] != -1)
+ printf("intr status :%lx %lx %lx %lx %lx %lx %lx\n",
+ fdc->status[0],
+ fdc->status[1],
+ fdc->status[2],
+ fdc->status[3],
+ fdc->status[4],
+ fdc->status[5],
+ fdc->status[6] );
+ else
+ printf("FDC timed out\n");
return(0);
}
return(1); /* Come back immediatly to new state */
@@ -1042,11 +1200,13 @@ retrier(fdcu)
fdcu_t fdcu;
{
fdc_p fdc = fdc_data + fdcu;
- register struct buf *dp,*bp;
+ register struct buf *dp, *bp;
dp = &(fdc->head);
bp = dp->b_actf;
+ if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY)
+ goto fail;
switch(fdc->retry)
{
case 0: case 1: case 2:
@@ -1061,12 +1221,15 @@ retrier(fdcu)
case 7:
break;
default:
+ fail:
{
dev_t sav_b_dev = bp->b_dev;
/* Trick diskerr */
- bp->b_dev = makedev(major(bp->b_dev), (FDUNIT(minor(bp->b_dev))<<3)|3);
+ bp->b_dev = makedev(major(bp->b_dev),
+ (FDUNIT(minor(bp->b_dev))<<3)|3);
diskerr(bp, "fd", "hard error", LOG_PRINTF,
- fdc->fd->skip, (struct disklabel *)NULL);
+ fdc->fd->skip / DEV_BSIZE,
+ (struct disklabel *)NULL);
bp->b_dev = sav_b_dev;
printf(" (ST0 %b ", fdc->status[0], NE7_ST0BITS);
printf(" ST1 %b ", fdc->status[1], NE7_ST1BITS);
@@ -1101,9 +1264,11 @@ fdformat(dev, finfo, p)
struct buf *bp;
int rv = 0, s;
-
+ size_t fdblk;
+
fdu = FDUNIT(minor(dev));
fd = &fd_data[fdu];
+ fdblk = 128 << fd->ft->secsize;
/* set up a buffer header for fdstrategy() */
bp = (struct buf *)malloc(sizeof(struct buf), M_TEMP, M_NOWAIT);
@@ -1119,7 +1284,7 @@ fdformat(dev, finfo, p)
* seek to the requested cylinder
*/
bp->b_blkno = (finfo->cyl * (fd->ft->sectrac * fd->ft->heads)
- + finfo->head * fd->ft->sectrac) * FDBLK / DEV_BSIZE;
+ + finfo->head * fd->ft->sectrac) * fdblk / DEV_BSIZE;
bp->b_bcount = sizeof(struct fd_idfield_data) * finfo->fd_formb_nsecs;
bp->b_un.b_addr = (caddr_t)finfo;
@@ -1138,41 +1303,39 @@ fdformat(dev, finfo, p)
splx(s);
if(rv == EWOULDBLOCK)
- {
/* timed out */
- biodone(bp);
rv = EIO;
- }
+ if(bp->b_flags & B_ERROR)
+ rv = bp->b_error;
+ biodone(bp);
free(bp, M_TEMP);
return rv;
}
/*
- * fdioctl() from jc@irbs.UUCP (John Capo)
- * i386/i386/conf.c needs to have fdioctl() declared and remove the line that
- * defines fdioctl to be enxio.
*
- * TODO: Reformat.
- * Think about allocating buffer off stack.
+ * TODO: Think about allocating buffer off stack.
* Don't pass uncast 0's and NULL's to read/write/setdisklabel().
* Watch out for NetBSD's different *disklabel() interface.
*
- * Added functionality for floppy formatting
- * joerg_wunsch@uriah.sax.de (Joerg Wunsch)
*/
int
-fdioctl (dev, cmd, addr, flag, p)
+fdioctl(dev, cmd, addr, flag, p)
dev_t dev;
int cmd;
caddr_t addr;
int flag;
struct proc *p;
{
+ fdu_t fdu = FDUNIT(minor(dev));
+ fd_p fd = &fd_data[fdu];
+ size_t fdblk;
+
struct fd_type *fdt;
struct disklabel *dl;
char buffer[DEV_BSIZE];
- int error;
+ int error = 0;
#if NFT > 0
int type = FDTYPE(minor(dev));
@@ -1182,14 +1345,14 @@ fdioctl (dev, cmd, addr, flag, p)
return ftioctl(dev, cmd, addr, flag, p);
#endif
- error = 0;
+ fdblk = 128 << fd->ft->secsize;
switch (cmd)
{
case DIOCGDINFO:
bzero(buffer, sizeof (buffer));
dl = (struct disklabel *)buffer;
- dl->d_secsize = FDBLK;
+ dl->d_secsize = fdblk;
fdt = fd_data[FDUNIT(minor(dev))].ft;
dl->d_secpercyl = fdt->size / fdt->tracks;
dl->d_type = DTYPE_FLOPPY;
@@ -1221,12 +1384,12 @@ fdioctl (dev, cmd, addr, flag, p)
dl = (struct disklabel *)addr;
- if (error = setdisklabel ((struct disklabel *)buffer,
- dl, 0, NULL))
+ if ((error =
+ setdisklabel ((struct disklabel *)buffer, dl, 0, NULL)))
break;
error = writedisklabel(dev, fdstrategy,
- (struct disklabel *)buffer, NULL);
+ (struct disklabel *)buffer, NULL);
break;
case FD_FORM:
@@ -1243,11 +1406,42 @@ fdioctl (dev, cmd, addr, flag, p)
*(struct fd_type *)addr = *fd_data[FDUNIT(minor(dev))].ft;
break;
+ case FD_STYPE: /* set drive type */
+ /* this is considered harmful; only allow for superuser */
+ if(suser(p->p_ucred, &p->p_acflag) != 0)
+ return EPERM;
+ *fd_data[FDUNIT(minor(dev))].ft = *(struct fd_type *)addr;
+ break;
+
+ case FD_GOPTS: /* get drive options */
+ *(int *)addr = fd_data[FDUNIT(minor(dev))].options;
+ break;
+
+ case FD_SOPTS: /* set drive options */
+ fd_data[FDUNIT(minor(dev))].options = *(int *)addr;
+ break;
+
default:
- error = EINVAL;
+ error = ENOTTY;
break;
}
return (error);
}
#endif
+/*
+ * Hello emacs, these are the
+ * Local Variables:
+ * c-indent-level: 8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * c-brace-offset: -8
+ * c-brace-imaginary-offset: 0
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c++-hanging-braces: 1
+ * c++-access-specifier-offset: -8
+ * c++-empty-arglist-indent: 8
+ * c++-friend-offset: 0
+ * End:
+ */
diff --git a/sys/i386/isa/fdc.h b/sys/i386/isa/fdc.h
index 7d75d5a81b48..ef81b11a8387 100644
--- a/sys/i386/isa/fdc.h
+++ b/sys/i386/isa/fdc.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fdc.h,v 1.2 1994/02/14 22:24:25 nate Exp $
+ * $Id: fdc.h,v 1.3 1994/05/22 12:35:38 joerg Exp $
*
*/
@@ -49,12 +49,12 @@ struct fdc_data
#define FDC_HASFTAPE 0x02
#define FDC_TAPE_BUSY 0x04
struct fd_data *fd;
- int fdu; /* the active drive */
+ int fdu; /* the active drive */
+ int state;
+ int retry;
+ int fdout; /* mirror of the w/o digital output reg */
+ int status[7]; /* copy of the registers */
struct buf head; /* Head of buf chain */
- struct buf rhead; /* Raw head of buf chain */
- int state;
- int retry;
- int status[7]; /* copy of the registers */
};
/***********************************************************************\
diff --git a/sys/i386/isa/fdreg.h b/sys/i386/isa/fdreg.h
index b0e9593a93c5..9b5be2b87b1c 100644
--- a/sys/i386/isa/fdreg.h
+++ b/sys/i386/isa/fdreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)fdreg.h 7.1 (Berkeley) 5/9/91
- * $Id: fdreg.h,v 1.4 1994/02/07 22:12:42 alm Exp $
+ * $Id: fdreg.h,v 1.5 1994/05/22 12:35:40 joerg Exp $
*/
/*
@@ -42,24 +42,26 @@
#include "../i386/isa/ic/nec765.h"
/* registers */
-#define fdout 2 /* Digital Output Register (W) */
+#define FDOUT 2 /* Digital Output Register (W) */
#define FDO_FDSEL 0x03 /* floppy device select */
#define FDO_FRST 0x04 /* floppy controller reset */
#define FDO_FDMAEN 0x08 /* enable floppy DMA and Interrupt */
#define FDO_MOEN0 0x10 /* motor enable drive 0 */
#define FDO_MOEN1 0x20 /* motor enable drive 1 */
-#define FDO_MOEN2 0x30 /* motor enable drive 2 */
-#define FDO_MOEN3 0x40 /* motor enable drive 3 */
+#define FDO_MOEN2 0x40 /* motor enable drive 2 */
+#define FDO_MOEN3 0x80 /* motor enable drive 3 */
-#define fdsts 4 /* NEC 765 Main Status Register (R) */
-#define fddata 5 /* NEC 765 Data Register (R/W) */
+#define FDSTS 4 /* NEC 765 Main Status Register (R) */
+#define FDDATA 5 /* NEC 765 Data Register (R/W) */
-#define fdctl 7 /* Control Register (W) */
+#define FDCTL 7 /* Control Register (W) */
#define FDC_500KBPS 0x00 /* 500KBPS MFM drive transfer rate */
#define FDC_300KBPS 0x01 /* 300KBPS MFM drive transfer rate */
#define FDC_250KBPS 0x02 /* 250KBPS MFM drive transfer rate */
#define FDC_125KBPS 0x03 /* 125KBPS FM drive transfer rate */
+ /* for some controllers 1MPBS instead */
-#define fdin 7 /* Digital Input Register (R) */
+#define FDIN 7 /* Digital Input Register (R) */
#define FDI_DCHG 0x80 /* diskette has been changed */
-
+ /* requires drive and motor being selected */
+ /* is cleared by any step pulse to drive */
diff --git a/sys/i386/isa/ft.c b/sys/i386/isa/ft.c
index 09bc127090aa..1204613bcd8e 100644
--- a/sys/i386/isa/ft.c
+++ b/sys/i386/isa/ft.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1993 Steve Gerakines
+ * Copyright (c) 1993, 1994 Steve Gerakines
*
* This is freely redistributable software. You may do anything you
* wish with it, so long as the above notice stays intact.
@@ -17,8 +17,15 @@
* POSSIBILITY OF SUCH DAMAGE.
*
* ft.c - QIC-40/80 floppy tape driver
- * $Id: ft.c,v 1.4 1994/02/14 22:24:28 nate Exp $
+ * $Id: ft.c,v 1.7 1994/06/22 05:52:36 jkh Exp $
*
+ * 06/07/94 v0.9 ++sg
+ * Tape stuck on segment problem should be gone. Re-wrote buffering
+ * scheme. Added support for drives that do not automatically perform
+ * seek load point. Can handle more wakeup types now and should correctly
+ * report most manufacturer names. Fixed places where unit 0 was being
+ * sent to the fdc instead of the actual unit number. Added ioctl support
+ * for an in-core badmap.
*
* 01/26/94 v0.3b - Jim Babb
* Got rid of the hard coded device selection. Moved (some of) the
@@ -76,12 +83,13 @@
#include "ftreg.h"
/* Enable or disable debugging messages. */
-#define FTDBGALL 0 /* everything */
-/* #define DPRT(a) printf a */
-#define DPRT(a)
+#define FTDBGALL 0 /* 1 if you want everything */
+/*#define DPRT(a) printf a */
+#define DPRT(a)
/* Constants private to the driver */
#define FTPRI (PRIBIO) /* sleep priority */
+#define FTNBUFF 9 /* 8 for buffering, 1 for header */
/* The following items are needed from the fd driver. */
extern int in_fdc(int); /* read fdc registers */
@@ -92,11 +100,13 @@ extern int hz; /* system clock rate */
/* Type of tape attached */
/* use numbers that don't interfere with the possible floppy types */
#define NO_TYPE 0 /* (same as NO_TYPE in fd.c) */
- /* F_TAPE_TYPE must match value in fd.c */
-#define F_TAPE_TYPE 0x020 /* bit for ft->types to indicate tape */
-#define FT_MOUNTAIN (F_TAPE_TYPE | 1)
-#define FT_COLORADO (F_TAPE_TYPE | 2)
+/* F_TAPE_TYPE must match value in fd.c */
+#define F_TAPE_TYPE 0x020 /* bit for ft->types to indicate tape */
+#define FT_NONE (F_TAPE_TYPE | 0) /* no method required */
+#define FT_MOUNTAIN (F_TAPE_TYPE | 1) /* mountain */
+#define FT_COLORADO (F_TAPE_TYPE | 2) /* colorado */
+#define FT_INSIGHT (F_TAPE_TYPE | 3) /* insight */
/* Mode FDC is currently in: tape or disk */
enum { FDC_TAPE_MODE, FDC_DISK_MODE };
@@ -150,15 +160,25 @@ QIC_Geom *ftg = NULL; /* Current tape's geometry */
/*
* things relating to asynchronous commands
*/
-static int astk_depth; /* async_cmd stack depth */
static int awr_state; /* state of async write */
static int ard_state; /* state of async read */
static int arq_state; /* state of async request */
static int async_retries; /* retries, one per invocation */
static int async_func; /* function to perform */
static int async_state; /* state current function is at */
-static int async_arg[5]; /* up to 5 arguments for async cmds */
+static int async_arg0; /* up to 3 arguments for async cmds */
+static int async_arg1; /**/
+static int async_arg2; /**/
static int async_ret; /* return value */
+static struct _astk {
+ int over_func;
+ int over_state;
+ int over_retries;
+ int over_arg0;
+ int over_arg1;
+ int over_arg2;
+} astk[10];
+static struct _astk *astk_ptr = &astk[0]; /* Pointer to stack position */
/* List of valid async (interrupt driven) tape support functions. */
enum {
@@ -172,29 +192,36 @@ enum {
};
/* Call another asyncronous command from within async_cmd(). */
-#define CALL_ACMD(r,f,a,b,c,d,e) \
- astk[astk_depth].over_retries = async_retries; \
- astk[astk_depth].over_func = async_func; \
- astk[astk_depth].over_state = (r); \
- for (i = 0; i < 5; i++) \
- astk[astk_depth].over_arg[i] = async_arg[i]; \
+#define CALL_ACMD(r,f,a,b,c) \
+ astk_ptr->over_retries = async_retries; \
+ astk_ptr->over_func = async_func; \
+ astk_ptr->over_state = (r); \
+ astk_ptr->over_arg0 = async_arg0; \
+ astk_ptr->over_arg1 = async_arg1; \
+ astk_ptr->over_arg2 = async_arg2; \
async_func = (f); async_state = 0; async_retries = 0; \
- async_arg[0]=(a); async_arg[1]=(b); async_arg[2]=(c); \
- async_arg[3]=(d); async_arg[4]=(e); \
- astk_depth++; \
+ async_arg0=(a); async_arg1=(b); async_arg2=(c); \
+ astk_ptr++; \
goto restate
/* Perform an asyncronous command from outside async_cmd(). */
-#define ACMD_FUNC(r,f,a,b,c,d,e) over_async = (r); astk_depth = 0; \
+#define ACMD_FUNC(r,f,a,b,c) over_async = (r); astk_ptr = &astk[0]; \
async_func = (f); async_state = 0; async_retries = 0; \
- async_arg[0]=(a); async_arg[1]=(b); async_arg[2]=(c); \
- async_arg[3]=(d); async_arg[4]=(e); \
+ async_arg0=(a); async_arg1=(b); async_arg2=(c); \
async_cmd(ftu); \
return
/* Various wait channels */
+static char *wc_buff_avail = "bavail";
+static char *wc_buff_done = "bdone";
+static char *wc_iosts_change = "iochg";
+static char *wc_long_delay = "ldelay";
+static char *wc_intr_wait = "intrw";
+#define ftsleep(wc,to) tsleep((caddr_t)(wc),FTPRI,(wc),(to))
+
static struct {
int buff_avail;
+ int buff_done;
int iosts_change;
int long_delay;
int intr_wait;
@@ -223,8 +250,17 @@ struct ft_data {
unsigned char *xptr; /* pointer to buffer blk to xfer */
int xcnt; /* transfer count */
int xblk; /* block number to transfer */
- SegReq *curseg; /* Current segment to do I/O on */
- SegReq *bufseg; /* Buffered segment to r/w ahead */
+ int xseg; /* segment being transferred */
+ SegReq *segh; /* Current I/O request */
+ SegReq *segt; /* Tail of queued I/O requests */
+ SegReq *doneh; /* Completed I/O request queue */
+ SegReq *donet; /* Completed I/O request tail */
+ SegReq *segfree; /* Free segments */
+ SegReq *hdr; /* Current tape header */
+ int nsegq; /* Segments on request queue */
+ int ndoneq; /* Segments on completed queue */
+ int nfreelist; /* Segments on free list */
+
/* the next 3 should be defines in 'flags' */
int active; /* TRUE if transfer is active */
int rdonly; /* TRUE if tape is read-only */
@@ -261,85 +297,237 @@ void ftstrategy(struct buf *);
int ftioctl(dev_t, int, caddr_t, int, struct proc *);
int ftdump(dev_t);
int ftsize(dev_t);
-static void ft_timeout(caddr_t arg1, int arg2);
-void async_cmd(ftu_t);
-void async_req(ftu_t, int);
-void async_read(ftu_t, int);
-void async_write(ftu_t, int);
-void tape_start(ftu_t);
-void tape_end(ftu_t);
-void tape_inactive(ftu_t);
+static void ft_timeout(caddr_t, int);
+static void async_cmd(ftu_t);
+static void async_req(ftu_t, int);
+static void async_read(ftu_t, int);
+static void async_write(ftu_t, int);
+static void tape_start(ftu_t, int);
+static void tape_end(ftu_t);
+static void tape_inactive(ftu_t);
+static int tape_cmd(ftu_t, int);
+static int tape_status(ftu_t);
+static int qic_status(ftu_t, int, int);
+static int ftreq_rewind(ftu_t);
+static int ftreq_hwinfo(ftu_t, QIC_HWInfo *);
+
+/*****************************************************************************/
+
+
+/*
+ * Allocate a segment I/O buffer from the free list.
+ */
+static SegReq *
+segio_alloc(ft_p ft)
+{
+ SegReq *r;
+
+ /* Grab first item from free list */
+ if ((r = ft->segfree) != NULL) {
+ ft->segfree = ft->segfree->next;
+ ft->nfreelist--;
+ }
+ DPRT(("segio_alloc: nfree=%d ndone=%d nreq=%d\n", ft->nfreelist, ft->ndoneq, ft->nsegq));
+ return(r);
+}
+
+
+/*
+ * Queue a segment I/O request.
+ */
+static void
+segio_queue(ft_p ft, SegReq *sp)
+{
+ /* Put request on in process queue. */
+ if (ft->segt == NULL)
+ ft->segh = sp;
+ else
+ ft->segt->next = sp;
+ sp->next = NULL;
+ ft->segt = sp;
+ ft->nsegq++;
+ DPRT(("segio_queue: nfree=%d ndone=%d nreq=%d\n", ft->nfreelist, ft->ndoneq, ft->nsegq));
+}
+/*
+ * Segment I/O completed, place on correct queue.
+ */
+static void
+segio_done(ft_p ft, SegReq *sp)
+{
+ /* First remove from current I/O queue */
+ ft->segh = sp->next;
+ if (ft->segh == NULL) ft->segt = NULL;
+ ft->nsegq--;
+
+ if (sp->reqtype == FTIO_WRITING) {
+ /* Place on free list */
+ sp->next = ft->segfree;
+ ft->segfree = sp;
+ ft->nfreelist++;
+ wakeup((caddr_t)wc_buff_avail);
+ DPRT(("segio_done: (w) nfree=%d ndone=%d nreq=%d\n", ft->nfreelist, ft->ndoneq, ft->nsegq));
+ } else {
+ /* Put on completed I/O queue */
+ if (ft->donet == NULL)
+ ft->doneh = sp;
+ else
+ ft->donet->next = sp;
+ sp->next = NULL;
+ ft->donet = sp;
+ ft->ndoneq++;
+ wakeup((caddr_t)wc_buff_done);
+ DPRT(("segio_done: (r) nfree=%d ndone=%d nreq=%d\n", ft->nfreelist, ft->ndoneq, ft->nsegq));
+ }
+}
+/*
+ * Take I/O request from finished queue to free queue.
+ */
+static void
+segio_free(ft_p ft, SegReq *sp)
+{
+ /* First remove from done queue */
+ ft->doneh = sp->next;
+ if (ft->doneh == NULL) ft->donet = NULL;
+ ft->ndoneq--;
+
+ /* Place on free list */
+ sp->next = ft->segfree;
+ ft->segfree = sp;
+ ft->nfreelist++;
+ wakeup((caddr_t)wc_buff_avail);
+ DPRT(("segio_free: nfree=%d ndone=%d nreq=%d\n", ft->nfreelist, ft->ndoneq, ft->nsegq));
+}
+
/*
* Probe/attach floppy tapes.
*/
-int ftattach(isadev, fdup)
+int
+ftattach(isadev, fdup)
struct isa_device *isadev, *fdup;
{
- fdcu_t fdcu = isadev->id_unit; /* fdc active unit */
- fdc_p fdc = fdc_data + fdcu; /* pointer to controller structure */
- ftu_t ftu = fdup->id_unit;
- ft_p ft;
- ftsu_t ftsu = fdup->id_physid;
-
- if (ftu >= NFT)
- return 0;
- ft = &ft_data[ftu];
- /* Probe for tape */
- ft->attaching = 1;
- ft->type = NO_TYPE;
- ft->fdc = fdc;
- ft->ftsu = ftsu;
-
- tape_start(ftu); /* ready controller for tape */
- tape_cmd(ftu, QC_COL_ENABLE1);
- tape_cmd(ftu, QC_COL_ENABLE2);
- if (tape_status(ftu) >= 0) {
- ft->type = FT_COLORADO;
- fdc->flags |= FDC_HASFTAPE;
- printf(" [%d: ft%d: Colorado tape]",
- fdup->id_physid, fdup->id_unit );
-