summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorasami <asami@FreeBSD.org>1996-07-23 07:46:59 +0000
committerasami <asami@FreeBSD.org>1996-07-23 07:46:59 +0000
commit80d063318901b953d4a5e1db64b20bea78785caf (patch)
treea4a7cbb6b9a6c0397043022de208c713b39053de
parent7f40ab6534c99db1b9436ab4748d58d4f7aeea29 (diff)
downloadFreeBSD-src-80d063318901b953d4a5e1db64b20bea78785caf.zip
FreeBSD-src-80d063318901b953d4a5e1db64b20bea78785caf.tar.gz
Update to current state of PC98 world.
Submitted by: The FreeBSD(98) development team
-rw-r--r--sys/amd64/include/cpufunc.h4
-rw-r--r--sys/conf/Makefile.pc984
-rw-r--r--sys/conf/files.pc985
-rw-r--r--sys/conf/options.pc986
-rw-r--r--sys/i386/include/cpufunc.h4
-rw-r--r--sys/pc98/apm/apm.c19
-rw-r--r--sys/pc98/boot/biosboot/Makefile7
-rw-r--r--sys/pc98/boot/biosboot/README.386BSD55
-rw-r--r--sys/pc98/boot/biosboot/boot.c19
-rw-r--r--sys/pc98/boot/biosboot/boot2.S6
-rw-r--r--sys/pc98/boot/biosboot/disk.c4
-rw-r--r--sys/pc98/boot/biosboot/start.S194
-rw-r--r--sys/pc98/boot/netboot/bootmenu.c30
-rw-r--r--sys/pc98/boot/netboot/main.c4
-rw-r--r--sys/pc98/boot/netboot/ns8390.c4
-rw-r--r--sys/pc98/cbus/clock.c264
-rw-r--r--sys/pc98/cbus/fdc.c11
-rw-r--r--sys/pc98/cbus/pcrtc.c264
-rw-r--r--sys/pc98/cbus/sio.c89
-rw-r--r--sys/pc98/conf/GENERIC17
-rw-r--r--sys/pc98/conf/GENERIC9817
-rw-r--r--sys/pc98/conf/Makefile.pc984
-rw-r--r--sys/pc98/conf/files.pc985
-rw-r--r--sys/pc98/conf/majors.pc983
-rw-r--r--sys/pc98/conf/options.pc986
-rw-r--r--sys/pc98/i386/locore.s28
-rw-r--r--sys/pc98/i386/machdep.c410
-rw-r--r--sys/pc98/i386/microtime.s8
-rw-r--r--sys/pc98/i386/pmap.c1133
-rw-r--r--sys/pc98/i386/support.s192
-rw-r--r--sys/pc98/i386/trap.c40
-rw-r--r--sys/pc98/i386/vm_machdep.c80
-rw-r--r--sys/pc98/pc98/clock.c264
-rw-r--r--sys/pc98/pc98/diskslice_machdep.c7
-rw-r--r--sys/pc98/pc98/fd.c11
-rw-r--r--sys/pc98/pc98/fd.c.new2680
-rw-r--r--sys/pc98/pc98/ft.c4
-rw-r--r--sys/pc98/pc98/ic/mb86960.h52
-rw-r--r--sys/pc98/pc98/if_ed.c311
-rw-r--r--sys/pc98/pc98/if_edreg.h1162
-rw-r--r--sys/pc98/pc98/if_ep.c288
-rw-r--r--sys/pc98/pc98/if_epreg.h13
-rw-r--r--sys/pc98/pc98/if_fe.c347
-rw-r--r--sys/pc98/pc98/if_fereg.h19
-rw-r--r--sys/pc98/pc98/if_zp.c11
-rw-r--r--sys/pc98/pc98/lpt.c4
-rw-r--r--sys/pc98/pc98/machdep.c410
-rw-r--r--sys/pc98/pc98/npx.c3
-rw-r--r--sys/pc98/pc98/pc98.c22
-rw-r--r--sys/pc98/pc98/pcaudio.c50
-rw-r--r--sys/pc98/pc98/pcibus.c6
-rw-r--r--sys/pc98/pc98/pcicx.c4
-rw-r--r--sys/pc98/pc98/random_machdep.c6
-rw-r--r--sys/pc98/pc98/sbic55.c10
-rw-r--r--sys/pc98/pc98/sbic55.c.new11
-rw-r--r--sys/pc98/pc98/scd.c6
-rw-r--r--sys/pc98/pc98/sio.c89
-rw-r--r--sys/pc98/pc98/sound/dmabuf.c3
-rw-r--r--sys/pc98/pc98/spkr.c92
-rw-r--r--sys/pc98/pc98/syscons.c506
-rw-r--r--sys/pc98/pc98/syscons.h68
-rw-r--r--sys/pc98/pc98/wcd.c20
-rw-r--r--sys/pc98/pc98/wd.c24
-rw-r--r--sys/sys/diskslice.h6
64 files changed, 2877 insertions, 6568 deletions
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index 9dce136..e49066a 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cpufunc.h,v 1.51 1996/07/01 18:12:23 bde Exp $
+ * $Id: cpufunc.h,v 1.52 1996/07/01 20:16:09 bde Exp $
*/
/*
@@ -252,6 +252,8 @@ outw(u_int port, u_short data)
}
#ifdef PC98
+#include <machine/spl.h>
+
static inline u_char
epson_inb(u_int port)
{
diff --git a/sys/conf/Makefile.pc98 b/sys/conf/Makefile.pc98
index d0915fa..e092349 100644
--- a/sys/conf/Makefile.pc98
+++ b/sys/conf/Makefile.pc98
@@ -3,7 +3,7 @@
# Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.i386,v 1.84 1996/06/08 23:27:16 jkh Exp $
+# $Id: Makefile.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
#
# Makefile for FreeBSD
#
@@ -31,7 +31,7 @@ I386= ${S}/i386
CWARNFLAGS?= -W -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit \
-Wnested-externs -Wstrict-prototypes -Wmissing-prototypes \
- -Winline
+ -Winline -Wunused
#
# The following flags are next up for working on:
# -Wall
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index eed4f92..027b2a5 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -2,7 +2,7 @@
# files marked standard are always included.
#
# modified for PC-9801 after:
-# $Id: files.i386,v 1.136 1996/06/07 22:26:59 nate Exp $
+# $Id: files.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -42,11 +42,13 @@ i386/i386/db_disasm.c optional ddb
i386/i386/db_interface.c optional ddb
i386/i386/db_trace.c optional ddb
pc98/i386/exception.s standard
+i386/i386/identcpu.c standard
i386/i386/in_cksum.c optional inet
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
# now normal.
# i386/i386/locore.s standard
pc98/i386/machdep.c standard
+pc98/pc98/pc98_machdep.c standard
i386/i386/math_emulate.c optional math_emulate
i386/i386/mem.c standard
pc98/i386/microtime.s standard
@@ -112,6 +114,7 @@ pc98/pc98/if_fe.c optional fe device-driver
#pc98/isa/if_ix.c optional ix device-driver
#pc98/isa/if_le.c optional le device-driver
#pc98/isa/if_lnc.c optional lnc device-driver
+#i386/isa/if_sr.c optional sr device-driver
#pc98/isa/if_ze.c optional ze device-driver
pc98/pc98/if_zp.c optional zp device-driver
pc98/pc98/pc98.c optional nec device-driver
diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98
index 1f4b112..e722e79 100644
--- a/sys/conf/options.pc98
+++ b/sys/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.13 1996/05/11 04:39:44 bde Exp $
+# $Id: options.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -23,3 +23,7 @@ FAT_CURSOR opt_pcvt.h
PCVT_FREEBSD opt_pcvt.h
PCVT_SCANSET opt_pcvt.h
XSERVER opt_pcvt.h
+
+CLK_CALIBRATION_LOOP opt_clock.h
+CLK_USE_I8254_CALIBRATION opt_clock.h
+CLK_USE_I586_CALIBRATION opt_clock.h
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index 9dce136..e49066a 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cpufunc.h,v 1.51 1996/07/01 18:12:23 bde Exp $
+ * $Id: cpufunc.h,v 1.52 1996/07/01 20:16:09 bde Exp $
*/
/*
@@ -252,6 +252,8 @@ outw(u_int port, u_short data)
}
#ifdef PC98
+#include <machine/spl.h>
+
static inline u_char
epson_inb(u_int port)
{
diff --git a/sys/pc98/apm/apm.c b/sys/pc98/apm/apm.c
index d140eb0..482eefb 100644
--- a/sys/pc98/apm/apm.c
+++ b/sys/pc98/apm/apm.c
@@ -14,7 +14,7 @@
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
- * $Id: apm.c,v 1.43 1996/06/04 17:50:28 nate Exp $
+ * $Id: apm.c,v 1.1.1.1 1996/06/14 10:04:36 asami Exp $
*/
#include "apm.h"
@@ -36,10 +36,8 @@
#include <sys/proc.h>
#include <sys/vnode.h>
#ifdef PC98
-#include "pc98/pc98/pc98.h"
#include "pc98/pc98/pc98_device.h"
#else
-#include "i386/isa/isa.h"
#include "i386/isa/isa_device.h"
#endif
#include <machine/apm_bios.h>
@@ -710,6 +708,11 @@ apmattach(struct isa_device *dvp)
#ifdef APM_DSVALUE_BUG
caddr_t apm_bios_work;
+ /*
+ * XXX - Malloc enough space for the APM DS, and then copy the
+ * current DS into the new space since the DS setup by the
+ * APM bios is going to get wiped out.
+ */
apm_bios_work = (caddr_t)malloc(apm_ds_limit, M_DEVBUF, M_NOWAIT);
bcopy((caddr_t)((apm_ds_base << 4) + APM_KERNBASE), apm_bios_work,
apm_ds_limit);
@@ -721,14 +724,15 @@ apmattach(struct isa_device *dvp)
sc->active = 0;
/* setup APM parameters */
- sc->cs16_base = (apm_cs32_base << 4) + APM_KERNBASE;
- sc->cs32_base = (apm_cs16_base << 4) + APM_KERNBASE;
+ sc->cs16_base = (apm_cs16_base << 4) + APM_KERNBASE;
+ sc->cs32_base = (apm_cs32_base << 4) + APM_KERNBASE;
sc->ds_base = (apm_ds_base << 4) + APM_KERNBASE;
sc->cs_limit = apm_cs_limit;
sc->ds_limit = apm_ds_limit;
sc->cs_entry = apm_cs_entry;
#ifdef APM_DSVALUE_BUG
+ /* Set the DS base to point to the newly made copy of the APM DS */
sc->ds_base = (u_int)apm_bios_work;
#endif /* APM_DSVALUE_BUG */
@@ -747,10 +751,11 @@ apmattach(struct isa_device *dvp)
printf("apm: Code entry 0x%08x, Idling CPU %s, Management %s\n",
sc->cs_entry, is_enabled(sc->slow_idle_cpu),
is_enabled(!sc->disabled));
- printf("apm: CS_limit=%x, DS_limit=%x\n", sc->cs_limit, sc->ds_limit);
+ printf("apm: CS_limit=0x%x, DS_limit=0x%x\n",
+ sc->cs_limit, sc->ds_limit);
#endif /* APM_DEBUG */
-#ifdef APM_DEBUG
+#ifdef 0
/* Workaround for some buggy APM BIOS implementations */
sc->cs_limit = 0xffff;
sc->ds_limit = 0xffff;
diff --git a/sys/pc98/boot/biosboot/Makefile b/sys/pc98/boot/biosboot/Makefile
index fb432ad..5c8f17a 100644
--- a/sys/pc98/boot/biosboot/Makefile
+++ b/sys/pc98/boot/biosboot/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.40 1996/05/11 04:27:23 bde Exp $
+# $Id: Makefile,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
#
PROG= boot
@@ -20,6 +20,11 @@ CFLAGS+= -DCOMCONSOLE=0x30 -DCOMCONSOLE_CLK=16 -DCOMCONSOLE_MODE=0x0c
# PROBE_KEYBOARD is defined).
#CFLAGS+= -DFORCE_COMCONSOLE
+# Enable code to take the default boot string from a fixed location on the
+# disk. See nextboot(8) and README.386BSD for more info.
+#CFLAGS+= -DNAMEBLOCK
+#CFLAGS+= -DNAMEBLOCK_WRITEBACK
+
# Bias the conversion from the BIOS drive number to the FreeBSD unit number
# for hard disks. This may be useful for people booting in a mixed IDE/SCSI
# environment (set BOOT_HD_BIAS to the number of IDE drives).
diff --git a/sys/pc98/boot/biosboot/README.386BSD b/sys/pc98/boot/biosboot/README.386BSD
index 0dc3cbc..5b293c1 100644
--- a/sys/pc98/boot/biosboot/README.386BSD
+++ b/sys/pc98/boot/biosboot/README.386BSD
@@ -1,3 +1,6 @@
+Note: all my original references to 386BSD also refer to freeBSD and NetBSD
+which in some ways are derived from 386BSD. --julian@freebsd.org
+
This Boot code is different from the original boot code that came with
386BSD in that it uses the BIOS to load the kernel and to provide all i/o
services. The advantage ofthis is that the same boot code exactly, can run
@@ -15,46 +18,60 @@ following operations occur:
1/ the BIOS loads the first block of the disk (called the Master Boot Record
or MBR) and if it has the correct magic numbers, jumps into it:
-2/ The MBR code, looks at the Partition table that is embedded within it,
+2/ The MBR code, looks at the Partition table that is embedded within it,
to determine which is the partition to boot from. If you install the
boot manager when FreeBSD is first installed, it will also give you a nice
menu for switching between operating systems.
-3/ The MBR will load the first record of the selected partition and
+3/ The MBR will load the first record of the selected partition and
if it has (the same) magic numbers, jumps into it. In 386bsd this is the
first stage boot, (or boot1) it is represented in /usr/mdec by
wdboot, asboot and sdboot. If the disk has been set up without DOS partitioning
then this block will be at block zero, and will have been loaded directly by
-the BIOS.
+the BIOS. This is the usual case with floppies.
4/ Boot1 will look at block0 (which might be itself if there are no DOS
-partitions) and will find the 386bsd partition, and using the information
-regarding the start position of that partition, will load the next 13 sectors
-or so, to around 90000 (640k - 64k). and will jump into it at the appropriate
-entry point. Since boot1 and boot2 were compiled together as one file
-and then split later, boot1 knows the exact position within boot2 of the
-entry point.
+partitions) and will find the 386bsd partition,
Boot 1 also contains a compiled in DOS partition table
(in case it is at block 0), which contains a 386bsd partition starting
at 0. This ensures that the same code can work whether or not
boot1 is at block 0.
+4A/ IF the NAMEBLOCK option is compiled into the bootcode, then the
+boot1 code will load and examine block1 (usually unused) and
+look for a default boot string to use later (if the correct magic number
+is present). If the option NAMEBLOCK_WRITEBACK is also defined, then
+it will zero out that name after finding it, and write the block back,
+having "used up" that name. The block may contain multiple different
+boot strings which will be "used up" one after the other (one per boot)
+They are set using the "nextboot" utility.
+
+4B/ Using the information found in step 4, regarding the start position
+of the BSD partition, boot1 will load the first 16 sectors of that partition,
+to around 0x10000 (64k) and will jump into it at the appropriate entry point.
+Since boot1 and boot2 were compiled together as one file and then split
+later, boot1 knows the exact position within boot2 of the entry point.
+
5/ Boot2 asks the user for a boot device, partition and filename, and then
loads the MBR of the selected device. This may or may not be the device
which was originally used to boot the first MBR. The partition table
of the new MBR is searched for a 386bsd partition, and if one is found,
that is then in turn searched for the disklabel. This could all be on the
-second disk at this point, if the user selected it.
+second disk at this point, if the user selected it. If the user makes no
+actions then a default string will be used.
+
+If the NAMEBLOCK option is used, then the default string may have been
+loaded from block2. If none was found then a compiled in default will be used.
-6/On finding the disklabel, boot2 can find the correct unix partition
-within the 386bsd partition, and using cutdown filesystem code,
-look for the file to boot (e.g. 386bsd).
+6/On finding the disklabel, on the disk the user spacified, boot2 can find
+the correct unix partition within the 386bsd partition, and using cutdown
+filesystem code, look for the file to boot (e.g., 386bsd).
7/ Boot2 loads this file starting at the location specified by the a.out header,
(see later) and leaps into it at the location specified in he header.
-if the file does not exist or cannot be loaded, boot2 goes back to step 5.
+if the file does not exist or cannot be loaded, boot2 goes back to step 5.
386bsd is now running and will hopefully start vm etc. and get to multi-user
mode.
@@ -78,10 +95,12 @@ partition, and you can change it to a 386BSD partition later. If you use
no DOS partitioning, then the compiled in table in Boot1 will do just fine.
If you want to do it by hand remember that BIOS counts sectors starting at 1.
-(cylinders and heads start at 0 (??))
+(cylinders and heads start at 0 (??))
2/ you cannot overwrite the bottom 4k of ram until you have finished ALL
bios calls, as BIOS uses this area as scratch memory.
+This is no longer really a problem as we no-longer support loading the kernel
+at location 0.
3/ Since BIOS runs in REAL mode, and Boot2 runs in protected mode,
Boot 2 switches back to real mode just before each BIOS call and then
@@ -90,8 +109,10 @@ back to protected mode on each return. Touch this at your peril.!
#########################################################################
In answering the prompt from Boot2:
you can,
-1/ leave it alone.. it will boot the indicated file from the first
+1/ leave it alone. It will boot the indicated file from the first
partition of the first drive seen by the BIOS (C:)
+If the NAMEBLOCK option is in use, the default name might be taken from block1
+(2nd block) on that drive (the drive on which boot 1 was loaded).
2/ enter only "-s" to boot the default to single user mode
@@ -148,4 +169,4 @@ Before you do this ensure you have a booting floppy with correct
disktab and bootblock files on it so that if it doesn't work, you can
re-disklabel from the floppy.
-$Id: README.386BSD,v 1.4 1996/04/07 14:27:57 bde Exp $
+$Id: README.386BSD,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
diff --git a/sys/pc98/boot/biosboot/boot.c b/sys/pc98/boot/biosboot/boot.c
index 284f036..57756ba 100644
--- a/sys/pc98/boot/biosboot/boot.c
+++ b/sys/pc98/boot/biosboot/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.50 1996/05/11 04:27:24 bde Exp $
+ * $Id: boot.c,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
*/
@@ -61,6 +61,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define NAMEBUF_LEN (8*1024)
+#ifdef NAMEBLOCK
+char *dflt_name;
+#endif
char namebuf[NAMEBUF_LEN];
struct exec head;
struct bootinfo bootinfo;
@@ -144,8 +147,19 @@ boot(int drive)
#endif
}
#endif /* PC98 */
-
+#ifdef NAMEBLOCK
+ /*
+ * XXX
+ * DAMN! I don't understand why this is not being set
+ * by the code in boot2.S
+ */
+ dflt_name= (char *)0x0000ffb0;
+ if( (*dflt_name++ == 'D') && (*dflt_name++ == 'N')) {
+ name = dflt_name;
+ } else
+#endif /*NAMEBLOCK*/
loadstart:
+ name = dflname; /* re-initialize in case of loop */
/* print this all each time.. (saves space to do so) */
/* If we have looped, use the previous entries as defaults */
printf("\n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory\n"
@@ -159,7 +173,6 @@ loadstart:
dosdev & 0x7f, devs[maj], unit, name);
#endif
- name = dflname; /* re-initialize in case of loop */
loadflags &= RB_SERIAL; /* clear all, but leave serial console */
getbootdev(namebuf, &loadflags);
ret = openrd();
diff --git a/sys/pc98/boot/biosboot/boot2.S b/sys/pc98/boot/biosboot/boot2.S
index d994d41..1374ad6 100644
--- a/sys/pc98/boot/biosboot/boot2.S
+++ b/sys/pc98/boot/biosboot/boot2.S
@@ -50,6 +50,7 @@
/*
* boot2() -- second stage boot
+ * SP points to default string if found
*/
ENTRY(boot2)
@@ -60,6 +61,11 @@ ENTRY(boot2)
mov %ax, %es
data32
shll $4, %eax
+#ifdef NAMEBLOCK
+ addr32
+ data32
+ movl %esp, EXT(dflt_name)
+#endif
/* fix up GDT entries for bootstrap */
#define FIXUP(gdt_index) \
diff --git a/sys/pc98/boot/biosboot/disk.c b/sys/pc98/boot/biosboot/disk.c
index 6c696b3..4520fcc 100644
--- a/sys/pc98/boot/biosboot/disk.c
+++ b/sys/pc98/boot/biosboot/disk.c
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:49 rpd
- * $Id: disk.c,v 1.16 1995/09/16 13:03:59 bde Exp $
+ * $Id: disk.c,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
*/
/*
@@ -58,8 +58,8 @@
#ifdef DO_BAD144
struct dkbad dkb;
int do_bad144;
-int bsize;
#endif DO_BAD144
+int bsize;
int spt, spc;
diff --git a/sys/pc98/boot/biosboot/start.S b/sys/pc98/boot/biosboot/start.S
index ab159d7..1400cf8 100644
--- a/sys/pc98/boot/biosboot/start.S
+++ b/sys/pc98/boot/biosboot/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.6 1995/09/16 13:51:20 bde Exp $
+ * $Id: start.S,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
*/
/*
@@ -60,6 +60,18 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
SIGNATURE= 0xaa55
LOADSZ= 8192 /* size of unix boot */
+NAMEBLOCKMAGIC= 0xfadefeed /* value of magicnumebr for block2 */
+
+/*
+ * This DEBUGMSG(msg) macro may be useful for debugging. Its use is
+ * restricted to this file since it only works in real mode.
+ */
+#define DEBUGMSG(msg) \
+ data32 ; \
+ mov $msg, %esi ; \
+ data32 ; \
+ call message
+
.text
.globl start
@@ -79,8 +91,13 @@ start:
data32
mov $BOOTSEG, %eax
mov %ax, %ss
+ /*
+ * make a little room on the stack for
+ * us to save the default bootstring we might find..
+ * effectively, we push the bootstring.
+ */
data32
- mov $BOOTSTACK, %esp
+ mov $BOOTSTACK-64, %esp
/* set up %es, (where we will load boot2 to) */
mov %ax, %es
@@ -221,6 +238,164 @@ hd:
*/
load:
+#ifdef NAMEBLOCK
+/*
+ * Load the second sector and see if it is a boot instruction block.
+ * If it is then scan the contents for the first valid string and copy it to
+ * the location of the default boot string.. then zero it out.
+ * Finally write the block back to disk with the zero'd out entry..
+ * I hate writing at this stage but we need this to be persistant.
+ * If the boot fails, then the next boot will get the next string.
+ * /etc/rc will regenerate a complete block2 iff teh boot succeeds.
+ *
+ * Format of block 2 is:
+ * [NAMEBLOCKMAGIC] <--0xdeafc0de
+ * [nulls]
+ * [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.experimental
+ * [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.old
+ * ....
+ * [bootstring]NULL <---e.g. 0:wd(0,f)/kernel
+ * FF FF FF
+ */
+where:
+ /*
+ * save things we might smash
+ * (that are not smashed immedatly after us anyway.)
+ */
+ data32
+ push %ecx /* preserve 'cyl,sector ' */
+ data32
+ push %edx
+/*
+ * Load the second sector
+ * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+ * Call with %ah = 0x2
+ * %al = number of sectors
+ * %ch = cylinder
+ * %cl = sector
+ * %dh = head
+ * %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+ * %es:%bx = segment:offset of buffer
+ * Return:
+ * %al = 0x0 on success; err code on failure
+ */
+ data32
+ movl $0x0201, %eax /function 2 (read) 1 sector */
+ xor %ebx, %ebx /* %bx = 0 */ /* buffer address (ES:0) */
+ data32
+ movl $0x0002, %ecx /* sector 2, cylinder 0 */
+ data32
+ andl $0x00ff, %edx /* head 0, drive N */
+ int $0x13
+ data32
+ jb read_error
+ /*
+ * confirm that it is one for us
+ */
+ data32
+ xorl %ebx, %ebx /* magic number at start of buffer */
+ data32
+ addr32
+ movl %es:(%ebx), %eax
+ data32
+ cmpl $NAMEBLOCKMAGIC, %eax
+ data32
+ jne notours /* not ours so return to caller */
+ /*
+ * scan for a bootstring
+ * Skip the magic number, and scan till we find a non-null,
+ * or a -1
+ */
+ incl %ebx /* quicker and smaller */
+ incl %ebx
+ incl %ebx
+scan:
+ incl %ebx
+ addr32
+ movb %es:(%ebx), %al /* load the next byte */
+ testb %al, %al /* and if it is null */
+ data32 /* keep scanning (past deleted entries) */
+ jz scan
+ incb %al /* now look for -1 */
+ data32
+ jz notours /* if we reach the 0xFF then we have finished */
+
+ /*
+ * save our settings.. we need them twice..
+ */
+ data32
+ push %ebx
+ /*
+ * copy it to the default string location
+ * which is just above the stack for 64 bytes.
+ */
+ data32
+ movl $BOOTSTACK-64, %ecx /* 64 bytes at the top of the stack */
+nxtbyte:
+ addr32
+ movb %es:(%ebx), %al /* get the next byte in */
+ addr32
+ movb %al, %es:(%ecx) /* and transfer it to the name buffer */
+ incl %ebx /* get on with the next byte */
+ incl %ecx /* get on with the next byte */
+ testb %al, %al /* if it was 0 then quit this */
+ data32
+ jnz nxtbyte /* and looop if more to do */
+
+ /*
+ * restore the saved settings and
+ * zero it out so next time we don't try it again
+ */
+ data32
+ pop %ebx /* get back our starting location */
+#ifdef NAMEBLOCK_WRITEBACK
+nxtbyte2:
+ addr32
+ movb %es:(%ebx), %al /* get the byte */
+ addr32
+ movb $0, %es:(%ebx) /* zero it out */
+ data32
+ incl %ebx /* point to the next byte */
+ testb %al, %al /* check if we have finished.. */
+ data32
+ jne nxtbyte2
+/*
+ * Write the second sector back
+ * Load the second sector
+ * BIOS call "INT 0x13 Function 0x3" to write sectors from memory to disk
+ * Call with %ah = 0x3
+ * %al = number of sectors
+ * %ch = cylinder
+ * %cl = sector
+ * %dh = head
+ * %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+ * %es:%bx = segment:offset of buffer
+ * Return:
+ * %al = 0x0 on success; err code on failure
+ */
+ data32
+ movl $0x0301, %eax /* write 1 sector */
+ xor %ebx, %ebx /* buffer is at offset 0 */
+ data32
+ movl $0x0002, %ecx /* block 2 */
+ data32
+ andl $0xff, %edx /* head 0 */
+ int $0x13
+ data32
+ jnb notours
+ data32
+ mov $eread, %esi
+ jmp err_stop
+#endif /* NAMEBLOCK_WRITEBACK */
+ /*
+ * return to the main-line
+ */
+notours:
+ data32
+ pop %edx
+ data32
+ pop %ecx
+#endif
data32
mov $LOADSZ, %ebx
addr32
@@ -334,15 +509,16 @@ vram:
/* error messages */
+
#ifdef DEBUG
-one: String "1\r\n\0"
-two: String "2\r\n\0"
-three: String "3\r\n\0"
-four: String "4\r\n\0"
-five: String "5\r\n\0"
-six: String "6\r\n\0"
-seven: String "7\r\n\0"
+one: String "1-\0"
+two: String "2-\0"
+three: String "3-\0"
+four: String "4-\0"
#endif DEBUG
+#ifdef NAMEBLOCK_WRITEBACK
+ewrite: String "Write error\r\n\0"
+#endif /* NAMEBLOCK_WRITEBACK */
eread: String "Read error\r\n\0"
enoboot: String "No bootable partition\r\n\0"
endofcode:
diff --git a/sys/pc98/boot/netboot/bootmenu.c b/sys/pc98/boot/netboot/bootmenu.c
index a67ac93..d8f2330 100644
--- a/sys/pc98/boot/netboot/bootmenu.c
+++ b/sys/pc98/boot/netboot/bootmenu.c
@@ -12,11 +12,12 @@ extern int hostnamelen;
extern unsigned long netmask;
extern eth_reset();
extern short aui;
+extern int howto;
int cmd_ip(), cmd_server(), cmd_kernel(), cmd_help(), exit();
int cmd_rootfs(), cmd_swapfs(), cmd_interface(), cmd_hostname();
int cmd_netmask(), cmd_swapsize(), cmd_swapopts(), cmd_rootopts();
-int cmd_aui(), cmd_gateway();
+int cmd_aui(), cmd_gateway(), cmd_flags();
struct bootcmds_t {
char *name;
@@ -39,6 +40,7 @@ struct bootcmds_t {
{"diskboot", exit, " boot from disk"},
{"autoboot", NULL, " continue"},
{"trans", cmd_aui, "<on|off> turn transceiver on|off"},
+ {"flags", cmd_flags, "[bcdhsv] set boot flags"},
{NULL, NULL, NULL}
};
@@ -284,6 +286,32 @@ cmd_swapopts(p)
}
/**************************************************************************
+CMD_FLAGS - Set boot flags
+**************************************************************************/
+cmd_flags(buf)
+ char *buf;
+{
+ char p;
+ int flags = 0;
+
+ while ((p = *buf++))
+ switch (p) {
+ case 'b': flags |= RB_HALT; break;
+ case 'c': flags |= RB_CONFIG; break;
+ case 'd': flags |= RB_KDB; break;
+ case 'h': flags ^= RB_SERIAL; break;
+ case 's': flags |= RB_SINGLE; break;
+ case 'v': flags |= RB_VERBOSE; break;
+ case ' ':
+ case '\t': break;
+ default: printf("Unknown boot flag: %c\n", p);
+ }
+
+ howto = flags;
+ return(0);
+}
+
+/**************************************************************************
EXECUTE - Decode command
**************************************************************************/
execute(buf)
diff --git a/sys/pc98/boot/netboot/main.c b/sys/pc98/boot/netboot/main.c
index d111d0d..2ae5c6e 100644
--- a/sys/pc98/boot/netboot/main.c
+++ b/sys/pc98/boot/netboot/main.c
@@ -24,7 +24,7 @@ struct bootinfo bootinfo;
int root_nfs_port;
unsigned long netmask;
char kernel_handle[32];
-int offset;
+int offset, howto;
extern char eth_driver[];
extern char packet[];
@@ -320,7 +320,7 @@ cfg_done:
bootinfo.bi_nfs_diskless = &nfsdiskless;
bootinfo.bi_size = sizeof bootinfo;
kernelentry = (void *)(head.a_entry & 0x00FFFFFF);
- (*kernelentry)(RB_BOOTINFO,NODEV,0,0,0,&bootinfo,0,0,0);
+ (*kernelentry)(howto|RB_BOOTINFO,NODEV,0,0,0,&bootinfo,0,0,0);
printf("*** %s execute failure ***\n",kernel);
}
diff --git a/sys/pc98/boot/netboot/ns8390.c b/sys/pc98/boot/netboot/ns8390.c
index 9fb328d..e0875e2 100644
--- a/sys/pc98/boot/netboot/ns8390.c
+++ b/sys/pc98/boot/netboot/ns8390.c
@@ -75,6 +75,10 @@ eth_probe()
for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE;
eth_asic_base += 0x20) {
chksum = 0;
+ /* Check for WD/SMC card by checking ethernet address */
+ if (inb(eth_asic_base+8) != 0) continue;
+ if (inb(eth_asic_base+9) != 0) continue;
+ if (inb(eth_asic_base+10) != 0xC0) continue;
for (i=8; i<16; i++)
chksum += inb(i+eth_asic_base);
if ((chksum & 0x00FF) == 0x00FF)
diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c
index b2befbf..071650c 100644
--- a/sys/pc98/cbus/clock.c
+++ b/sys/pc98/cbus/clock.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.58 1996/05/01 08:39:02 bde Exp $
+ * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
*/
/*
@@ -46,13 +46,14 @@
/*
* modified for PC98
- * $Id: clock.c,v 1.7 1994/03/26 22:56:13 kakefuda Exp kakefuda $
+ * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
*/
/*
* Primitive clock interrupt routines.
*/
#include "opt_ddb.h"
+#include "opt_clock.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -100,13 +101,13 @@
#define TIMER0_LATCH_COUNT 20
/*
- * Minimum maximum count that we are willing to program into timer0.
- * Must be large enough to guarantee that the timer interrupt handler
- * returns before the next timer interrupt. Must be larger than
- * TIMER0_LATCH_COUNT so that we don't have to worry about underflow in
- * the calculation of timer0_overflow_threshold.
+ * Maximum frequency that we are willing to allow for timer0. Must be
+ * low enough to guarantee that the timer interrupt handler returns
+ * before the next timer interrupt. Must result in a lower TIMER_DIV
+ * value than TIMER0_LATCH_COUNT so that we don't have to worry about
+ * underflow in the calculation of timer0_overflow_threshold.
*/
-#define TIMER0_MIN_MAX_COUNT TIMER_DIV(20000)
+#define TIMER0_MAX_FREQ 20000
int adjkerntz; /* local offset from GMT in seconds */
int disable_rtc_set; /* disable resettodr() if != 0 */
@@ -122,6 +123,23 @@ unsigned long i586_avg_tick;
#endif
int statclock_disable;
u_int stat_imask = SWI_CLOCK_MASK;
+#ifdef TIMER_FREQ
+static u_int timer_freq = TIMER_FREQ;
+#else
+#ifdef PC98
+#ifndef AUTO_CLOCK
+#ifndef PC98_8M
+static u_int timer_freq = 2457600;
+#else /* !PC98_8M */
+static u_int timer_freq = 1996800;
+#endif /* PC98_8M */
+#else /* AUTO_CLOCK */
+static u_int timer_freq = 2457600;
+#endif /* AUTO_CLOCK */
+#else /* IBM-PC */
+static u_int timer_freq = 1193182;
+#endif /* PC98 */
+#endif
int timer0_max_count;
u_int timer0_overflow_threshold;
u_int timer0_prescaler_count;
@@ -135,8 +153,6 @@ static u_int hardclock_max_count;
* timer_func currently needs to hold hardclock to handle the
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
* to switch between clkintr() and a slightly different timerintr().
- * This will require locking when acquiring and releasing timer0 - the
- * current (nonexistent) locking doesn't seem to be adequate even now.
*/
static void (*new_function) __P((struct clockframe *frame));
static u_int new_rate;
@@ -144,48 +160,32 @@ static u_int new_rate;
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
#endif
-#ifdef TIMER_FREQ
-static u_int timer_freq = TIMER_FREQ;
-#else
-#ifdef PC98
-#ifndef AUTO_CLOCK
-#ifndef PC98_8M
-static u_int timer_freq = 2457600;
-#else /* !PC98_8M */
-static u_int timer_freq = 1996800;
-#endif /* PC98_8M */
-#else /* AUTO_CLOCK */
-static u_int timer_freq = 2457600;
-#endif /* AUTO_CLOCK */
-#else /* IBM-PC */
-static u_int timer_freq = 1193182;
-#endif /* PC98 */
-#endif
-static char timer0_state = 0;
+
+/* Values for timerX_state: */
+#define RELEASED 0
+#define RELEASE_PENDING 1
+#define ACQUIRED 2
+#define ACQUIRE_PENDING 3
+
+static u_char timer0_state;
#ifdef PC98
-static char timer1_state = 0;
+static u_char timer1_state;
#endif
-static char timer2_state = 0;
+static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
int rtc_inb __P((void));
-#if 0
-void
-clkintr(struct clockframe frame)
-{
- hardclock(&frame);
- setdelayed();
-}
-#else
static void
clkintr(struct clockframe frame)
{
timer_func(&frame);
switch (timer0_state) {
- case 0:
+
+ case RELEASED:
setdelayed();
break;
- case 1:
+
+ case ACQUIRED:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
hardclock(&frame);
@@ -193,7 +193,8 @@ clkintr(struct clockframe frame)
timer0_prescaler_count -= hardclock_max_count;
}
break;
- case 2:
+
+ case ACQUIRE_PENDING:
setdelayed();
timer0_max_count = TIMER_DIV(new_rate);
timer0_overflow_threshold =
@@ -205,9 +206,10 @@ clkintr(struct clockframe frame)
enable_intr();
timer0_prescaler_count = 0;
timer_func = new_function;
- timer0_state = 1;
+ timer0_state = ACQUIRED;
break;
- case 3:
+
+ case RELEASE_PENDING:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
hardclock(&frame);
@@ -248,84 +250,140 @@ clkintr(struct clockframe frame)
}
#endif /* AUTO_CLOCK */
#else /* IBM-PC */
- time.tv_usec += (27645 *
+ time.tv_usec += (27465 *
(timer0_prescaler_count - hardclock_max_count))
>> 15;
#endif /* PC98 */
if (time.tv_usec >= 1000000)
time.tv_usec -= 1000000;
timer0_prescaler_count = 0;
- timer_func = hardclock;;
- timer0_state = 0;
+ timer_func = hardclock;
+ timer0_state = RELEASED;
}
break;
}
}
-#endif
+/*
+ * The acquire and release functions must be called at ipl >= splclock().
+ */
int
acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
{
- if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT ||
- !function)
- return -1;
+ static int old_rate;
+
+ if (rate <= 0 || rate > TIMER0_MAX_FREQ)
+ return (-1);
+ switch (timer0_state) {
+
+ case RELEASED:
+ timer0_state = ACQUIRE_PENDING;
+ break;
+
+ case RELEASE_PENDING:
+ if (rate != old_rate)
+ return (-1);
+ /*
+ * The timer has been released recently, but is being
+ * re-acquired before the release completed. In this
+ * case, we simply reclaim it as if it had not been
+ * released at all.
+ */
+ timer0_state = ACQUIRED;
+ break;
+
+ default:
+ return (-1); /* busy */
+ }
new_function = function;
- new_rate = rate;
- timer0_state = 2;
- return 0;
+ old_rate = new_rate = rate;
+ return (0);
}
#ifdef PC98
int
acquire_timer1(int mode)
{
- if (timer1_state)
- return -1;
- timer1_state = 1;
- outb(TIMER_MODE, TIMER_SEL1 | (mode &0x3f));
- return 0;
+
+ if (timer1_state != RELEASED)
+ return (-1);
+ timer1_state = ACQUIRED;
+
+ /*
+ * This access to the timer registers is as atomic as possible
+ * because it is a single instruction. We could do better if we
+ * knew the rate. Use of splclock() limits glitches to 10-100us,
+ * and this is probably good enough for timer2, so we aren't as
+ * careful with it as with timer0.
+ */
+ outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
+
+ return (0);
}
#endif
int
acquire_timer2(int mode)
{
- if (timer2_state)
- return -1;
- timer2_state = 1;
- outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
- return 0;
+
+ if (timer2_state != RELEASED)
+ return (-1);
+ timer2_state = ACQUIRED;
+
+ /*
+ * This access to the timer registers is as atomic as possible
+ * because it is a single instruction. We could do better if we
+ * knew the rate. Use of splclock() limits glitches to 10-100us,
+ * and this is probably good enough for timer2, so we aren't as
+ * careful with it as with timer0.
+ */
+ outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
+
+ return (0);
}
int
release_timer0()
{
- if (!timer0_state)
- return -1;
- timer0_state = 3;
- return 0;
+ switch (timer0_state) {
+
+ case ACQUIRED:
+ timer0_state = RELEASE_PENDING;
+ break;
+
+ case ACQUIRE_PENDING:
+ /* Nothing happened yet, release quickly. */
+ timer0_state = RELEASED;
+ break;
+
+ default:
+ return (-1);
+ }
+ return (0);
}
#ifdef PC98
int
release_timer1()
{
- if (!timer1_state)
- return -1;
- timer1_state = 0;
- outb(TIMER_MODE, TIMER_SEL1|TIMER_SQWAVE|TIMER_16BIT);
- return 0;
+
+ if (timer1_state != ACQUIRED)
+ return (-1);
+ timer1_state = RELEASED;
+ outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
+ return (0);
}
#endif
int
release_timer2()
{
- if (!timer2_state)
- return -1;
- timer2_state = 0;
- outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
- return 0;
+
+ if (timer2_state != ACQUIRED)
+ return (-1);
+ timer2_state = RELEASED;
+ outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
+ return (0);
}
#ifndef PC98
@@ -367,14 +425,19 @@ DDB_printrtc(void)
static int
getit(void)
{
+ u_long ef;
int high, low;
+ ef = read_eflags();
disable_intr();
- /* select timer0 and latch counter value */
+
+ /* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0);
+
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
- enable_intr();
+
+ write_eflags(ef);
return ((high << 8) | low);
}
@@ -459,33 +522,45 @@ sysbeepstop(void *chan)
int
sysbeep(int pitch, int period)
{
+ int x = splclock();
+
#ifdef PC98
if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
- return -1;
+ if (!beeping) {
+ /* Something else owns it. */
+ splx(x);
+ return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
+ }
disable_intr();
outb(0x3fdb, pitch);
outb(0x3fdb, (pitch>>8));
enable_intr();
if (!beeping) {
- outb(IO_PPI, (inb(IO_PPI) & 0xf7)); /* enable counter1 output to speaker */
+ /* enable counter1 output to speaker */
+ outb(IO_PPI, (inb(IO_PPI) & 0xf7));
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}
#else
-
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
- return -1;
+ if (!beeping) {
+ /* Something else owns it. */
+ splx(x);
+ return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
+ }
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 */
+ /* enable counter2 output to speaker */
+ outb(IO_PPI, inb(IO_PPI) | 3);
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}
#endif
- return 0;
+ splx(x);
+ return (0);
}
#ifndef PC98
@@ -546,7 +621,7 @@ calibrate_clocks(void)
u_int count, prev_count, tot_count;
int sec, start_sec, timeout;
- printf("Calibrating clock(s) relative to mc146818A clock ... ");
+ printf("Calibrating clock(s) relative to mc146818A clock...\n");
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
goto fail;
timeout = 100000000;
@@ -639,9 +714,10 @@ fail:
static void
set_timer_freq(u_int freq, int intr_freq)
{
- u_long ef;
+ u_long ef;
ef = read_eflags();
+ disable_intr();
timer_freq = freq;
timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
@@ -688,11 +764,7 @@ startrtclock()
#endif
#ifndef PC98
- /*
- * Temporarily calibrate with a high intr_freq to get a low
- * timer0_max_count to help detect bogus i8254 counts.
- */
- set_timer_freq(timer_freq, 20000);
+ set_timer_freq(timer_freq, hz);
freq = calibrate_clocks();
#ifdef CLK_CALIBRATION_LOOP
if (bootverbose) {
@@ -711,7 +783,8 @@ startrtclock()
delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
if (delta < timer_freq / 100) {
#ifndef CLK_USE_I8254_CALIBRATION
- printf(
+ if (bootverbose)
+ printf(
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
freq = timer_freq;
#endif
@@ -731,7 +804,8 @@ startrtclock()
#if defined(I586_CPU) || defined(I686_CPU)
#ifndef CLK_USE_I586_CALIBRATION
if (i586_ctr_rate != 0) {
- printf(
+ if (bootverbose)
+ printf(
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
i586_ctr_freq = 0;
i586_ctr_rate = 0;
@@ -750,7 +824,9 @@ startrtclock()
DELAY(1000000);
i586_count = rdtsc();
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
+#ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq);
+#endif
}
#endif
}
diff --git a/sys/pc98/cbus/fdc.c b/sys/pc98/cbus/fdc.c
index 55a8354..843d469 100644
--- a/sys/pc98/cbus/fdc.c
+++ b/sys/pc98/cbus/fdc.c
@@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.89 1996/05/03 20:15:11 phk Exp $
+ * $Id: fd.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
*
*/
@@ -430,7 +430,7 @@ static int fdformat(dev_t, struct fd_formb *, struct proc *);
#define IOTIMEDOUT 11
#ifdef DEBUG
-char *fdstates[] =
+static char const * const fdstates[] =
{
"DEVIDLE",
"FINDWORK",
@@ -447,7 +447,7 @@ char *fdstates[] =
};
/* CAUTION: fd_debug causes huge amounts of logging output */
-int fd_debug = 0;
+static int volatile fd_debug = 0;
#define TRACE0(arg) if(fd_debug) printf(arg)
#define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2)
#else /* DEBUG */
@@ -786,7 +786,10 @@ fdattach(struct isa_device *dev)
fdcu_t fdcu = dev->id_unit;
fdc_p fdc = fdc_data + fdcu;
fd_p fd;
- int fdsu, st0, st3, i, unithasfd;
+ int fdsu, st0, st3, i;
+#if NFT > 0
+ int unithasfd;
+#endif
#ifdef PC98
struct pc98_device *fdup;
#else
diff --git a/sys/pc98/cbus/pcrtc.c b/sys/pc98/cbus/pcrtc.c
index b2befbf..071650c 100644
--- a/sys/pc98/cbus/pcrtc.c
+++ b/sys/pc98/cbus/pcrtc.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.58 1996/05/01 08:39:02 bde Exp $
+ * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
*/
/*
@@ -46,13 +46,14 @@
/*
* modified for PC98
- * $Id: clock.c,v 1.7 1994/03/26 22:56:13 kakefuda Exp kakefuda $
+ * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
*/
/*
* Primitive clock interrupt routines.
*/
#include "opt_ddb.h"
+#include "opt_clock.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -100,13 +101,13 @@
#define TIMER0_LATCH_COUNT 20
/*
- * Minimum maximum count that we are willing to program into timer0.
- * Must be large enough to guarantee that the timer interrupt handler
- * returns before the next timer interrupt. Must be larger than
- * TIMER0_LATCH_COUNT so that we don't have to worry about underflow in
- * the calculation of timer0_overflow_threshold.
+ * Maximum frequency that we are willing to allow for timer0. Must be
+ * low enough to guarantee that the timer interrupt handler returns
+ * before the next timer interrupt. Must result in a lower TIMER_DIV
+ * value than TIMER0_LATCH_COUNT so that we don't have to worry about
+ * underflow in the calculation of timer0_overflow_threshold.
*/
-#define TIMER0_MIN_MAX_COUNT TIMER_DIV(20000)
+#define TIMER0_MAX_FREQ 20000
int adjkerntz; /* local offset from GMT in seconds */
int disable_rtc_set; /* disable resettodr() if != 0 */
@@ -122,6 +123,23 @@ unsigned long i586_avg_tick;
#endif
int statclock_disable;
u_int stat_imask = SWI_CLOCK_MASK;
+#ifdef TIMER_FREQ
+static u_int timer_freq = TIMER_FREQ;
+#else
+#ifdef PC98
+#ifndef AUTO_CLOCK
+#ifndef PC98_8M
+static u_int timer_freq = 2457600;
+#else /* !PC98_8M */
+static u_int timer_freq = 1996800;
+#endif /* PC98_8M */
+#else /* AUTO_CLOCK */
+static u_int timer_freq = 2457600;
+#endif /* AUTO_CLOCK */
+#else /* IBM-PC */
+static u_int timer_freq = 1193182;
+#endif /* PC98 */
+#endif
int timer0_max_count;
u_int timer0_overflow_threshold;
u_int timer0_prescaler_count;
@@ -135,8 +153,6 @@ static u_int hardclock_max_count;
* timer_func currently needs to hold hardclock to handle the
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
* to switch between clkintr() and a slightly different timerintr().
- * This will require locking when acquiring and releasing timer0 - the
- * current (nonexistent) locking doesn't seem to be adequate even now.
*/
static void (*new_function) __P((struct clockframe *frame));
static u_int new_rate;
@@ -144,48 +160,32 @@ static u_int new_rate;
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
#endif
-#ifdef TIMER_FREQ
-static u_int timer_freq = TIMER_FREQ;
-#else
-#ifdef PC98
-#ifndef AUTO_CLOCK
-#ifndef PC98_8M
-static u_int timer_freq = 2457600;
-#else /* !PC98_8M */
-static u_int timer_freq = 1996800;
-#endif /* PC98_8M */
-#else /* AUTO_CLOCK */
-static u_int timer_freq = 2457600;
-#endif /* AUTO_CLOCK */
-#else /* IBM-PC */
-static u_int timer_freq = 1193182;
-#endif /* PC98 */
-#endif
-static char timer0_state = 0;
+
+/* Values for timerX_state: */
+#define RELEASED 0
+#define RELEASE_PENDING 1
+#define ACQUIRED 2
+#define ACQUIRE_PENDING 3
+
+static u_char timer0_state;
#ifdef PC98
-static char timer1_state = 0;
+static u_char timer1_state;
#endif
-static char timer2_state = 0;
+static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
int rtc_inb __P((void));
-#if 0
-void
-clkintr(struct clockframe frame)
-{
- hardclock(&frame);
- setdelayed();
-}
-#else
static void
clkintr(struct clockframe frame)
{
timer_func(&frame);
switch (timer0_state) {
- case 0:
+
+ case RELEASED:
setdelayed();
break;
- case 1:
+
+ case ACQUIRED:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
hardclock(&frame);
@@ -193,7 +193,8 @@ clkintr(struct clockframe frame)
timer0_prescaler_count -= hardclock_max_count;
}
break;
- case 2:
+
+ case ACQUIRE_PENDING:
setdelayed();
timer0_max_count = TIMER_DIV(new_rate);
timer0_overflow_threshold =
@@ -205,9 +206,10 @@ clkintr(struct clockframe frame)
enable_intr();
timer0_prescaler_count = 0;
timer_func = new_function;
- timer0_state = 1;
+ timer0_state = ACQUIRED;
break;
- case 3:
+
+ case RELEASE_PENDING:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
hardclock(&frame);
@@ -248,84 +250,140 @@ clkintr(struct clockframe frame)
}
#endif /* AUTO_CLOCK */
#else /* IBM-PC */
- time.tv_usec += (27645 *
+ time.tv_usec += (27465 *
(timer0_prescaler_count - hardclock_max_count))
>> 15;
#endif /* PC98 */
if (time.tv_usec >= 1000000)
time.tv_usec -= 1000000;
timer0_prescaler_count = 0;
- timer_func = hardclock;;
- timer0_state = 0;
+ timer_func = hardclock;
+ timer0_state = RELEASED;
}
break;
}
}
-#endif
+/*
+ * The acquire and release functions must be called at ipl >= splclock().
+ */
int
acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
{
- if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT ||
- !function)
- return -1;
+ static int old_rate;
+
+ if (rate <= 0 || rate > TIMER0_MAX_FREQ)
+ return (-1);
+ switch (timer0_state) {
+
+ case RELEASED:
+ timer0_state = ACQUIRE_PENDING;
+ break;
+
+ case RELEASE_PENDING:
+ if (rate != old_rate)
+ return (-1);
+ /*
+ * The timer has been released recently, but is being
+ * re-acquired before the release completed. In this
+ * case, we simply reclaim it as if it had not been
+ * released at all.
+ */
+ timer0_state = ACQUIRED;
+ break;
+
+ default:
+ return (-1); /* busy */
+ }
new_function = function;
- new_rate = rate;
- timer0_state = 2;
- return 0;
+ old_rate = new_rate = rate;
+ return (0);
}
#ifdef PC98
int
acquire_timer1(int mode)
{
- if (timer1_state)
- return -1;
- timer1_state = 1;
- outb(TIMER_MODE, TIMER_SEL1 | (mode &0x3f));
- return 0;
+
+ if (timer1_state != RELEASED)
+ return (-1);
+ timer1_state = ACQUIRED;
+
+ /*
+ * This access to the timer registers is as atomic as possible
+ * because it is a single instruction. We could do better if we
+ * knew the rate. Use of splclock() limits glitches to 10-100us,
+ * and this is probably good enough for timer2, so we aren't as
+ * careful with it as with timer0.
+ */
+ outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
+
+ return (0);
}
#endif
int
acquire_timer2(int mode)
{
- if (timer2_state)
- return -1;
- timer2_state = 1;
- outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
- return 0;
+
+ if (timer2_state != RELEASED)
+ return (-1);
+ timer2_state = ACQUIRED;
+
+ /*
+ * This access to the timer registers is as atomic as possible
+ * because it is a single instruction. We could do better if we
+ * knew the rate. Use of splclock() limits glitches to 10-100us,
+ * and this is probably good enough for timer2, so we aren't as
+ * careful with it as with timer0.
+ */
+ outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
+
+ return (0);
}
int
release_timer0()
{
- if (!timer0_state)
- return -1;
- timer0_state = 3;
- return 0;
+ switch (timer0_state) {
+
+ case ACQUIRED:
+ timer0_state = RELEASE_PENDING;
+ break;
+
+ case ACQUIRE_PENDING:
+ /* Nothing happened yet, release quickly. */
+ timer0_state = RELEASED;
+ break;
+
+ default:
+ return (-1);
+ }
+ return (0);
}
#ifdef PC98
int
release_timer1()
{
- if (!timer1_state)
- return -1;
- timer1_state = 0;
- outb(TIMER_MODE, TIMER_SEL1|TIMER_SQWAVE|TIMER_16BIT);
- return 0;
+
+ if (timer1_state != ACQUIRED)
+ return (-1);
+ timer1_state = RELEASED;
+ outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
+ return (0);
}
#endif
int
release_timer2()
{
- if (!timer2_state)
- return -1;
- timer2_state = 0;
- outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
- return 0;
+
+ if (timer2_state != ACQUIRED)
+ return (-1);
+ timer2_state = RELEASED;
+ outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
+ return (0);
}
#ifndef PC98
@@ -367,14 +425,19 @@ DDB_printrtc(void)
static int
getit(void)
{
+ u_long ef;
int high, low;
+ ef = read_eflags();
disable_intr();
- /* select timer0 and latch counter value */
+
+ /* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0);
+
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
- enable_intr();
+
+ write_eflags(ef);
return ((high << 8) | low);
}
@@ -459,33 +522,45 @@ sysbeepstop(void *chan)
int
sysbeep(int pitch, int period)
{
+ int x = splclock();
+
#ifdef PC98
if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
- return -1;
+ if (!beeping) {
+ /* Something else owns it. */
+ splx(x);
+ return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
+ }
disable_intr();
outb(0x3fdb, pitch);
outb(0x3fdb, (pitch>>8));
enable_intr();
if (!beeping) {
- outb(IO_PPI, (inb(IO_PPI) & 0xf7)); /* enable counter1 output to speaker */
+ /* enable counter1 output to speaker */
+ outb(IO_PPI, (inb(IO_PPI) & 0xf7));
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}
#else
-
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
- return -1;
+ if (!beeping) {
+ /* Something else owns it. */
+ splx(x);
+ return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
+ }
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 */
+ /* enable counter2 output to speaker */
+ outb(IO_PPI, inb(IO_PPI) | 3);
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}
#endif
- return 0;
+ splx(x);
+ return (0);
}
#ifndef PC98
@@ -546,7 +621,7 @@ calibrate_clocks(void)
u_int count, prev_count, tot_count;
int sec, start_sec, timeout;
- printf("Calibrating clock(s) relative to mc146818A clock ... ");
+ printf("Calibrating clock(s) relative to mc146818A clock...\n");
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
goto fail;
timeout = 100000000;
@@ -639,9 +714,10 @@ fail:
static void
set_timer_freq(u_int freq, int intr_freq)
{
- u_long ef;
+ u_long ef;
ef = read_eflags();
+ disable_intr();
timer_freq = freq;
timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
@@ -688,11 +764,7 @@ startrtclock()
#endif
#ifndef PC98
- /*
- * Temporarily calibrate with a high intr_freq to get a low
- * timer0_max_count to help detect bogus i8254 counts.
- */
- set_timer_freq(timer_freq, 20000);
+ set_timer_freq(timer_freq, hz);
freq = calibrate_clocks();
#ifdef CLK_CALIBRATION_LOOP
if (bootverbose) {
@@ -711,7 +783,8 @@ startrtclock()
delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
if (delta < timer_freq / 100) {
#ifndef CLK_USE_I8254_CALIBRATION
- printf(
+ if (bootverbose)
+ printf(
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
freq = timer_freq;
#endif
@@ -731,7 +804,8 @@ startrtclock()
#if defined(I586_CPU) || defined(I686_CPU)
#ifndef CLK_USE_I586_CALIBRATION
if (i586_ctr_rate != 0) {
- printf(
+ if (bootverbose)
+ printf(
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
i586_ctr_freq = 0;
i586_ctr_rate = 0;
@@ -750,7 +824,9 @@ startrtclock()
DELAY(1000000);
i586_count = rdtsc();
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
+#ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq);
+#endif
}
#endif
}
diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c
index b16d153..66a8d71 100644
--- a/sys/pc98/cbus/sio.c
+++ b/sys/pc98/cbus/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.142 1996/05/02 09:34:40 phk Exp $
+ * $Id: sio.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
*/
#include "opt_comconsole.h"
@@ -138,14 +138,13 @@
#include <machine/clock.h>
#ifdef PC98
-#include <pc98/pc98/icu.h> /* XXX just to get at `imen' */
#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/icu.h>
#include <pc98/pc98/pc98_device.h>
#include <pc98/pc98/sioreg.h>
#include <pc98/pc98/ic/i8251.h>
#include <pc98/pc98/ic/ns16550.h>
#else
-#include <i386/isa/icu.h> /* XXX just to get at `imen' */
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/sioreg.h>
@@ -330,7 +329,9 @@ struct com_s {
struct termios lt_out;
bool_t do_timestamp;
+ bool_t do_dcd_timestamp;
struct timeval timestamp;
+ struct timeval dcd_timestamp;
u_long bytes_in; /* statistics */
u_long bytes_out;
@@ -366,8 +367,7 @@ struct com_s {
* by `config', not here.
*/
-/* Interrupt handling entry points. */
-inthand2_t siointrts;
+/* Interrupt handling entry point. */
void siopoll __P((void));
/* Device switch entry points. */
@@ -417,8 +417,6 @@ static char driver_name[] = "sio";
static struct com_s *p_com_addr[NSIO];
#define com_addr(unit) (p_com_addr[unit])
-static struct timeval intr_timestamp;
-
#ifdef PC98
struct pc98_driver siodriver = {
#else
@@ -958,18 +956,6 @@ sioprobe(dev)
/* EXTRA DELAY? */
/*
- * XXX DELAY() reenables CPU interrupts. This is a problem for
- * shared interrupts after the first device using one has been
- * successfully probed - config_isadev() has enabled the interrupt
- * in the ICU.
- */
-#ifdef PC98
- outb(IO_ICU1 + 2, 0xff);
-#else
- outb(IO_ICU1 + 1, 0xff);
-#endif
-
- /*
* Initialize the speed and the word size and wait long enough to
* drain the maximum of 16 bytes of junk in device output queues.
* The speed is undefined after a master reset and must be set
@@ -1042,7 +1028,7 @@ sioprobe(dev)
failures[0] = inb(iobase + com_cfcr) - CFCR_8BITS;
failures[1] = inb(iobase + com_ier) - IER_ETXRDY;
failures[2] = inb(iobase + com_mcr) - mcr_image;
- DELAY(1000); /* XXX */
+ DELAY(10000); /* Some internal modems need this time */
if (idev->id_irq != 0)
#ifdef PC98
failures[3] = pc98_irq_pending(idev) ? 0 : 1;
@@ -1082,11 +1068,6 @@ sioprobe(dev)
#endif
failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
-#ifdef PC98
- outb(IO_ICU1 + 2, imen); /* XXX */
-#else
- outb(IO_ICU1 + 1, imen); /* XXX */
-#endif
enable_intr();
result = IO_COMSIZE;
@@ -1868,32 +1849,6 @@ siodtrwakeup(chan)
wakeup(&com->dtr_wait);
}
-/* Interrupt routine for timekeeping purposes */
-void
-siointrts(unit)
- int unit;
-{
- /*
- * XXX microtime() reenables CPU interrupts. We can't afford to
- * be interrupted and don't want to slow down microtime(), so lock
- * out interrupts in another way.
- */
-#ifdef PC98
- outb(IO_ICU1 + 2, 0xff);
-#else /* IBM-PC */
- outb(IO_ICU1 + 1, 0xff);
-#endif /* PC98 */
- microtime(&intr_timestamp);
- disable_intr();
-#ifdef PC98
- outb(IO_ICU1 + 2, imen);
-#else /* IBM_PC */
- outb(IO_ICU1 + 1, imen);
-#endif /* PC98 */
-
- siointr(unit);
-}
-
void
siointr(unit)
int unit;
@@ -1947,9 +1902,6 @@ siointr1(com)
recv_data=0;
#endif /* PC98 */
- if (com->do_timestamp)
- /* XXX a little bloat here... */
- com->timestamp = intr_timestamp;
while (TRUE) {
#ifdef PC98
status_read:;
@@ -2024,6 +1976,8 @@ more_intr:
if (ioptr >= com->ibufend)
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
else {
+ if (com->do_timestamp)
+ microtime(&com->timestamp);
++com_events;
schedsofttty();
#if 0 /* for testing input latency vs efficiency */
@@ -2064,6 +2018,11 @@ cont:
#endif
modem_status = inb(com->modem_status_port);
if (modem_status != com->last_modem_status) {
+ if (com->do_dcd_timestamp
+ && !(com->last_modem_status & MSR_DCD)
+ && modem_status & MSR_DCD)
+ microtime(&com->dcd_timestamp);
+
/*
* Schedule high level to handle DCD changes. Note
* that we don't use the delta bits anywhere. Some
@@ -2115,11 +2074,7 @@ cont:
com->obufq.l_head = ioptr;
if (ioptr >= com->obufq.l_tail) {
struct lbq *qp;
-#ifdef PC98
- if(IS_8251(com->pc98_if_type))
- if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
- com_int_Tx_disable(com);
-#endif
+
qp = com->obufq.l_next;
qp->l_queued = FALSE;
qp = qp->l_next;
@@ -2130,6 +2085,11 @@ cont:
} else {
/* output just completed */
com->state &= ~CS_BUSY;
+#if defined(PC98)
+ if(IS_8251(com->pc98_if_type))
+ if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
+ com_int_Tx_disable(com);
+#endif
}
if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS;
@@ -2331,6 +2291,10 @@ sioioctl(dev, cmd, data, flag, p)
com->do_timestamp = TRUE;
*(struct timeval *)data = com->timestamp;
break;
+ case TIOCDCDTIMESTAMP:
+ com->do_dcd_timestamp = TRUE;
+ *(struct timeval *)data = com->dcd_timestamp;
+ break;
default:
splx(s);
return (ENOTTY);
@@ -3199,9 +3163,6 @@ static void
siocntxwait()
{
int timo;
-#ifdef PC98
- int tmp;
-#endif
/*
* Wait for any pending transmission to finish. Required to avoid
@@ -3551,8 +3512,6 @@ pc98_get_modem_status(struct com_s *com)
int stat, stat2;
register int msr;
- int ret;
-
stat = inb(com->sts_port);
stat2 = inb(com->in_modem_port);
msr = com->pc98_prev_modem_status
@@ -3763,7 +3722,7 @@ static void
com_cflag_and_speed_set( struct com_s *com, int cflag, int speed)
{
int cfcr=0, count;
- int s, previnterrupt;
+ int previnterrupt;
count = pc98_ttspeedtab( com, speed );
if ( count < 0 ) return;
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 3df81d4..8b2ae65 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -1,7 +1,7 @@
#
# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
#
-# $Id: GENERIC,v 1.70 1996/05/13 04:29:13 nate Exp $
+# $Id: GENERIC98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
#
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
@@ -62,14 +62,8 @@ options COM_MULTIPORT
# It is highly recomended to compile with following options, and to
# record the panic messages and the result of trace command brefore
# reporting a problem.
-#
-# If you need more information for the kernel, KTRACE option may help
-# you.
-#
options DDB
options DIAGNOSTIC
-#options KTRACE
-
config kernel root on wd0
@@ -138,7 +132,7 @@ device sio2 at nec? port 0x8d2 tty flags 0x101 vector siointr
device ed0 at nec? port 0x00d0 net irq 6 vector edintr
device ed1 at nec? port 0x56d0 net irq 5 vector edintr
device ed2 at nec? port 0x00d0 net irq 6 iomem 0xd0000 iosiz 16384 vector edintr
-device fe0 at nec? prot 0x00d0 net irq 3 vector feintr
+device fe0 at nec? port 0x00d0 net irq 3 vector feintr
device zp0 at nec? port 0x0300 net irq 10 iomem 0xe0000 vector zpintr
device ep0 at nec? port 0x00d0 net irq 6 vector epintr
@@ -160,5 +154,10 @@ pseudo-device sl 2
#pseudo-device ppp 1
pseudo-device tun 1
pseudo-device pty 16
-# keep this if you want to be able to continue to use /stand/sysinstall
pseudo-device gzip # Exec gzipped a.out's
+
+# KTRACE enables the system-call tracing facility ktrace(2).
+# This adds 4 KB bloat to your kernel, and slightly increases
+# the costs of each syscall.
+options KTRACE #kernel tracing
+
diff --git a/sys/pc98/conf/GENERIC98 b/sys/pc98/conf/GENERIC98
index 3df81d4..8b2ae65 100644
--- a/sys/pc98/conf/GENERIC98
+++ b/sys/pc98/conf/GENERIC98
@@ -1,7 +1,7 @@
#
# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
#
-# $Id: GENERIC,v 1.70 1996/05/13 04:29:13 nate Exp $
+# $Id: GENERIC98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
#
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
@@ -62,14 +62,8 @@ options COM_MULTIPORT
# It is highly recomended to compile with following options, and to
# record the panic messages and the result of trace command brefore
# reporting a problem.
-#
-# If you need more information for the kernel, KTRACE option may help
-# you.
-#
options DDB
options DIAGNOSTIC
-#options KTRACE
-
config kernel root on wd0
@@ -138,7 +132,7 @@ device sio2 at nec? port 0x8d2 tty flags 0x101 vector siointr
device ed0 at nec? port 0x00d0 net irq 6 vector edintr
device ed1 at nec? port 0x56d0 net irq 5 vector edintr
device ed2 at nec? port 0x00d0 net irq 6 iomem 0xd0000 iosiz 16384 vector edintr
-device fe0 at nec? prot 0x00d0 net irq 3 vector feintr
+device fe0 at nec? port 0x00d0 net irq 3 vector feintr
device zp0 at nec? port 0x0300 net irq 10 iomem 0xe0000 vector zpintr
device ep0 at nec? port 0x00d0 net irq 6 vector epintr
@@ -160,5 +154,10 @@ pseudo-device sl 2
#pseudo-device ppp 1
pseudo-device tun 1
pseudo-device pty 16
-# keep this if you want to be able to continue to use /stand/sysinstall
pseudo-device gzip # Exec gzipped a.out's
+
+# KTRACE enables the system-call tracing facility ktrace(2).
+# This adds 4 KB bloat to your kernel, and slightly increases
+# the costs of each syscall.
+options KTRACE #kernel tracing
+
diff --git a/sys/pc98/conf/Makefile.pc98 b/sys/pc98/conf/Makefile.pc98
index d0915fa..e092349 100644
--- a/sys/pc98/conf/Makefile.pc98
+++ b/sys/pc98/conf/Makefile.pc98
@@ -3,7 +3,7 @@
# Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.i386,v 1.84 1996/06/08 23:27:16 jkh Exp $
+# $Id: Makefile.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
#
# Makefile for FreeBSD
#
@@ -31,7 +31,7 @@ I386= ${S}/i386
CWARNFLAGS?= -W -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit \
-Wnested-externs -Wstrict-prototypes -Wmissing-prototypes \
- -Winline
+ -Winline -Wunused
#
# The following flags are next up for working on:
# -Wall
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index eed4f92..027b2a5 100644
--- a/sys/pc98/conf/files.pc98
+++ b/sys/pc98/conf/files.pc98
@@ -2,7 +2,7 @@
# files marked standard are always included.
#
# modified for PC-9801 after:
-# $Id: files.i386,v 1.136 1996/06/07 22:26:59 nate Exp $
+# $Id: files.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -42,11 +42,13 @@ i386/i386/db_disasm.c optional ddb
i386/i386/db_interface.c optional ddb
i386/i386/db_trace.c optional ddb
pc98/i386/exception.s standard
+i386/i386/identcpu.c standard
i386/i386/in_cksum.c optional inet
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
# now normal.
# i386/i386/locore.s standard
pc98/i386/machdep.c standard
+pc98/pc98/pc98_machdep.c standard
i386/i386/math_emulate.c optional math_emulate
i386/i386/mem.c standard
pc98/i386/microtime.s standard
@@ -112,6 +114,7 @@ pc98/pc98/if_fe.c optional fe device-driver
#pc98/isa/if_ix.c optional ix device-driver
#pc98/isa/if_le.c optional le device-driver
#pc98/isa/if_lnc.c optional lnc device-driver
+#i386/isa/if_sr.c optional sr device-driver
#pc98/isa/if_ze.c optional ze device-driver
pc98/pc98/if_zp.c optional zp device-driver
pc98/pc98/pc98.c optional nec device-driver
diff --git a/sys/pc98/conf/majors.pc98 b/sys/pc98/conf/majors.pc98
index fcfee6c..8659630 100644
--- a/sys/pc98/conf/majors.pc98
+++ b/sys/pc98/conf/majors.pc98
@@ -1,4 +1,4 @@
-$Id: majors.i386,v 1.5 1996/05/04 08:40:13 peter Exp $
+$Id: majors.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
Hopefully, this list will one day be obsoleted by DEVFS, but for now
this is the current allocation of device major numbers.
@@ -113,3 +113,4 @@ chrdev name comments
73 qcam quickcam
74 ccd concatenated disk
75 stli Stallion (intelligent cdk based) (gerg@stallion.oz.au)
+76 scc IBM Smart Capture Card (ohashi@mickey.ai.kyutech.ac.jp)
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index 1f4b112..e722e79 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.13 1996/05/11 04:39:44 bde Exp $
+# $Id: options.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -23,3 +23,7 @@ FAT_CURSOR opt_pcvt.h
PCVT_FREEBSD opt_pcvt.h
PCVT_SCANSET opt_pcvt.h
XSERVER opt_pcvt.h
+
+CLK_CALIBRATION_LOOP opt_clock.h
+CLK_USE_I8254_CALIBRATION opt_clock.h
+CLK_USE_I586_CALIBRATION opt_clock.h
diff --git a/sys/pc98/i386/locore.s b/sys/pc98/i386/locore.s
index bffecc5..90526a8 100644
--- a/sys/pc98/i386/locore.s
+++ b/sys/pc98/i386/locore.s
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
- * $Id: locore.s,v 1.72 1996/05/27 06:51:46 phk Exp $
+ * $Id: locore.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
*
* originally from: locore.s, by William F. Jolitz
*
@@ -116,7 +116,7 @@ _bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */
_KERNend: .long 0 /* phys addr end of kernel (just after bss) */
physfree: .long 0 /* phys addr of next free page */
-upa: .long 0 /* phys addr of proc0's UPAGES */
+p0upa: .long 0 /* phys addr of proc0's UPAGES */
p0upt: .long 0 /* phys addr of proc0's UPAGES page table */
.globl _IdlePTD
@@ -276,10 +276,10 @@ _pc98_system_parameter:
/* clear bss */
/*
- * XXX this should be done a little earlier. (bde)
+ * XXX this should be done a little earlier.
*
- * XXX we don't check that there is memory for our bss or page tables
- * before using it. (bde)
+ * XXX we don't check that there is memory for our bss and page tables
+ * before using it.
*
* XXX the boot program somewhat bogusly clears the bss. We still have
* to do it in case we were unzipped by kzipboot. Then the boot program
@@ -288,7 +288,7 @@ _pc98_system_parameter:
* XXX the gdt and idt are still somewhere in the boot program. We
* depend on the convention that the boot program is below 1MB and we
* are above 1MB to keep the gdt and idt away from the bss and page
- * tables. The idT is only used if BDE_DEBUGGER is enabled.
+ * tables. The idt is only used if BDE_DEBUGGER is enabled.
*/
movl $R(_end),%ecx
movl $R(_edata),%edi
@@ -326,7 +326,7 @@ _pc98_system_parameter:
#ifdef BDE_DEBUGGER
/*
* Complete the adjustments for paging so that we can keep tracing through
- * initi386() after the low (physical) addresses for the gdt and idT become
+ * initi386() after the low (physical) addresses for the gdt and idt become
* invalid.
*/
call bdb_commit_paging
@@ -916,7 +916,7 @@ over_symalloc:
/* Allocate UPAGES */
ALLOCPAGES(UPAGES)
- movl %esi,R(upa)
+ movl %esi,R(p0upa)
addl $KERNBASE, %esi
movl %esi, R(_proc0paddr)
@@ -951,13 +951,13 @@ map_read_write:
movl $1, %ecx
fillkptphys(PG_RW)
-/* Map proc0's page table for the UPAGES the physical way. */
+/* Map proc0's page table for the UPAGES. */
movl R(p0upt), %eax
movl $1, %ecx
fillkptphys(PG_RW)
-/* Map proc0s UPAGES the physical way */
- movl R(upa), %eax
+/* Map proc0's UPAGES in the physical way ... */
+ movl R(p0upa), %eax
movl $UPAGES, %ecx
fillkptphys(PG_RW)
@@ -966,13 +966,13 @@ map_read_write:
movl $ISA_HOLE_LENGTH>>PAGE_SHIFT, %ecx
fillkptphys(PG_RW|PG_N)
-/* Map proc0s UPAGES in the special page table for this purpose. */
- movl R(upa), %eax
+/* Map proc0s UPAGES in the special page table for this purpose ... */
+ movl R(p0upa), %eax
movl $KSTKPTEOFF, %ebx
movl $UPAGES, %ecx
fillkpt(R(p0upt), PG_RW)
-/* and put the page table in the pde. */
+/* ... and put the page table in the pde. */
movl R(p0upt), %eax
movl $KSTKPTDI, %ebx
movl $1, %ecx
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
index 029bbf5..78b2de4 100644
--- a/sys/pc98/i386/machdep.c
+++ b/sys/pc98/i386/machdep.c
@@ -35,13 +35,10 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.192 1996/06/08 11:03:01 bde Exp $
+ * $Id: machdep.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
*/
#include "npx.h"
-#ifndef PC98
-#include "isa.h"
-#endif
#include "opt_sysvipc.h"
#include "opt_ddb.h"
#include "opt_bounce.h"
@@ -117,10 +114,9 @@
#endif
#ifdef PC98
-#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
+#include <pc98/pc98/pc98_machdep.h>
#else
-#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/rtc.h>
#endif
@@ -132,31 +128,12 @@ extern int ptrace_single_step __P((struct proc *p));
extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data));
extern void dblfault_handler __P((void));
-extern void i486_bzero __P((void *, size_t));
-extern void i586_bzero __P((void *, size_t));
-extern void i686_bzero __P((void *, size_t));
+extern void identifycpu(void); /* XXX header file */
+extern void earlysetcpuclass(void); /* same header file */
static void cpu_startup __P((void *));
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
-static void identifycpu(void);
-
-char machine[] = "i386";
-SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
-
-static char cpu_model[128];
-SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "");
-
-struct kern_devconf kdc_cpu0 = {
- 0, 0, 0, /* filled in by dev_attach */
- "cpu", 0, { MDDT_CPU },
- 0, 0, 0, CPU_EXTERNALLEN,
- 0, /* CPU has no parent */
- 0, /* no parentdata */
- DC_BUSY, /* the CPU is always busy */
- cpu_model, /* no sense in duplication */
- DC_CLS_CPU /* class */
-};
#ifndef PANIC_REBOOT_WAIT_TIME
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
@@ -206,8 +183,6 @@ int boothowto = 0, bootverbose = 0, Maxmem = 0;
static int badpages = 0;
#ifdef PC98
int Maxmem_under16M = 0;
-extern pt_entry_t *panic_kwin_pte;
-extern caddr_t panic_kwin;
#endif
long dumplo;
extern int bootdev;
@@ -217,8 +192,6 @@ vm_offset_t phys_avail[10];
/* must be 2 less so 0 0 can signal end of chunks */
#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2)
-int cpu_class = CPUCLASS_386; /* smallest common denominator */
-
static void dumpsys __P((void));
static void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */
@@ -258,9 +231,12 @@ cpu_startup(dummy)
* Good {morning,afternoon,evening,night}.
*/
printf(version);
- cpu_class = i386_cpus[cpu].cpu_class;
+ earlysetcpuclass();
startrtclock();
identifycpu();
+#ifdef PERFMON
+ perfmon_init();
+#endif
printf("real memory = %d (%dK bytes)\n", ptoa(Maxmem), ptoa(Maxmem) / 1024);
/*
* Display any holes after the first chunk of extended memory.
@@ -499,176 +475,6 @@ setup_netisrs(ls)
}
}
-static struct cpu_nameclass i386_cpus[] = {
- { "Intel 80286", CPUCLASS_286 }, /* CPU_286 */
- { "i386SX", CPUCLASS_386 }, /* CPU_386SX */
- { "i386DX", CPUCLASS_386 }, /* CPU_386 */
- { "i486SX", CPUCLASS_486 }, /* CPU_486SX */
- { "i486DX", CPUCLASS_486 }, /* CPU_486 */
- { "Pentium", CPUCLASS_586 }, /* CPU_586 */
- { "Cy486DLC", CPUCLASS_486 }, /* CPU_486DLC */
- { "Pentium Pro", CPUCLASS_686 }, /* CPU_686 */
-};
-
-static void
-identifycpu()
-{
- printf("CPU: ");
- strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof cpu_model);
-
-#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
- if (!strcmp(cpu_vendor,"GenuineIntel")) {
- if ((cpu_id & 0xf00) > 3) {
- cpu_model[0] = '\0';
-
- switch (cpu_id & 0x3000) {
- case 0x1000:
- strcpy(cpu_model, "Overdrive ");
- break;
- case 0x2000:
- strcpy(cpu_model, "Dual ");
- break;
- }
-
- switch (cpu_id & 0xf00) {
- case 0x400:
- strcat(cpu_model, "i486 ");
- break;
- case 0x500:
- strcat(cpu_model, "Pentium"); /* nb no space */
- break;
- case 0x600:
- strcat(cpu_model, "Pentium Pro");
- break;
- default:
- strcat(cpu_model, "unknown");
- break;
- }
-
- switch (cpu_id & 0xff0) {
- case 0x400:
- strcat(cpu_model, "DX"); break;
- case 0x410:
- strcat(cpu_model, "DX"); break;
- case 0x420:
- strcat(cpu_model, "SX"); break;
- case 0x430:
- strcat(cpu_model, "DX2"); break;
- case 0x440:
- strcat(cpu_model, "SL"); break;
- case 0x450:
- strcat(cpu_model, "SX2"); break;
- case 0x470:
- strcat(cpu_model, "DX2 Write-Back Enhanced");
- break;
- case 0x480:
- strcat(cpu_model, "DX4"); break;
- break;
- }
- }
- }
-#endif
- printf("%s (", cpu_model);
- switch(cpu_class) {
- case CPUCLASS_286:
- printf("286");
- break;
-#if defined(I386_CPU)
- case CPUCLASS_386:
- printf("386");
- break;
-#endif
-#if defined(I486_CPU)
- case CPUCLASS_486:
- printf("486");
- bzero = i486_bzero;
- break;
-#endif
-#if defined(I586_CPU)
- case CPUCLASS_586:
- printf("%d.%02d-MHz ",
- ((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) / 100,
- ((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) % 100);
- printf("586");
- break;
-#endif
-#if defined(I686_CPU)
- case CPUCLASS_686:
- printf("%d.%02d-MHz ",
- ((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) / 100,
- ((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) % 100);
- printf("686");
- break;
-#endif
- default:
- printf("unknown"); /* will panic below... */
- }
- printf("-class CPU)\n");
-#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
- if(*cpu_vendor)
- printf(" Origin = \"%s\"",cpu_vendor);
- if(cpu_id)
- printf(" Id = 0x%lx",cpu_id);
-
- if (!strcmp(cpu_vendor, "GenuineIntel")) {
- printf(" Stepping=%ld", cpu_id & 0xf);
- if (cpu_high > 0) {
- printf("\n Features=0x%b", cpu_feature,
- "\020"
- "\001FPU"
- "\002VME"
- "\003DE"
- "\004PSE"
- "\005TSC"
- "\006MSR"
- "\007PAE"
- "\010MCE"
- "\011CX8"
- "\012APIC"
- "\013<b10>"
- "\014<b11>"
- "\015MTRR"
- "\016PGE"
- "\017MCA"
- "\020CMOV"
- );
- }
- }
- /* Avoid ugly blank lines: only print newline when we have to. */
- if (*cpu_vendor || cpu_id)
- printf("\n");
-#endif
- /*
- * Now that we have told the user what they have,
- * let them know if that machine type isn't configured.
- */
- switch (cpu_class) {
- case CPUCLASS_286: /* a 286 should not make it this far, anyway */
-#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
-#error This kernel is not configured for one of the supported CPUs
-#endif
-#if !defined(I386_CPU)
- case CPUCLASS_386:
-#endif
-#if !defined(I486_CPU)
- case CPUCLASS_486:
-#endif
-#if !defined(I586_CPU)
- case CPUCLASS_586:
-#endif
-#if !defined(I686_CPU)
- case CPUCLASS_686:
-#endif
- panic("CPU class not configured");
- default:
- break;
- }
-#ifdef PERFMON
- perfmon_init();
-#endif
- dev_attach(&kdc_cpu0);
-}
-
/*
* Send an interrupt to process.
*
@@ -884,66 +690,6 @@ sigreturn(p, uap, retval)
return(EJUSTRETURN);
}
-#ifdef PC98
-/*
- * disable screen saver
- */
-extern int scrn_blanked;
-extern void (*current_saver)(int blank);
-
-static void pc98_disable_screen_saver(void)
-{
- if (scrn_blanked)
- (*current_saver)(FALSE);
-}
-
-
-/*
- * change ralay on video card
- */
-static void pc98_change_relay(void)
-{
- /* mode register 2 */
- outb(0x6a, 0x07); /* enable to change FF */
- outb(0x6a, 0x8e);
- outb(0x6a, 0x06); /* disable to change FF */
- outb(0x7c, 0);
- outb(0x68, 0x0f); /* display */
-
- /* PWLB */
- *(int *)panic_kwin_pte = (0xf0c00000 & PG_FRAME) | PG_V | PG_RW ;
- pmap_update();
- *(long *)panic_kwin = 0;
- /* PowerWindow(C-Bus) */
- outb(0x0dc | 0x600, 0); /* XXX */
- /* PCHKB & PCSKB4 */
- outb(0x6e68, 0);
- /* PCSKB */
- outb(0x6ee8, 0);
- /* NEC-S3, Cirrus (local bus) */
- outb(0xfaa, 3);
- outb(0xfab, 1);
- outb(0xfaa, 6);
- outb(0xfab, 0xff);
- outb(0xfaa, 7);
- outb(0xfab, 0);
- /* NEC-S3 (C-bus) */
- outb(0xfa2, 3);
- outb(0xfa3, 0);
- /* GA-NB */
- outb(0x40e1, 0xc2);
- /* WAB-S & WAP */
- outb(0x40e1, 0xfa);
-
- /* stop G-GDC */
- outb(0xa2, 0x0c);
- /* XXX start T-GDC (which is true?)*/
- outb(0x62, 0x69);
- outb(0x62, 0x0d);
-}
-#endif
-
-
static int waittime = -1;
struct pcb dumppcb;
@@ -955,10 +701,6 @@ boot(howto)
register struct buf *bp;
int iter, nbusy;
-#ifdef PC98
- pc98_change_relay();
- pc98_disable_screen_saver();
-#endif
waittime = 0;
printf("\nsyncing disks... ");
@@ -1051,7 +793,7 @@ die:
* exported (symorder) and used at least by savecore(8)
*
*/
-u_long dumpmag = 0x8fca0101UL;
+static u_long const dumpmag = 0x8fca0101UL;
static int dumpsize = 0; /* also for savecore */
@@ -1406,6 +1148,13 @@ init386(first)
*/
cninit();
+#ifdef PC98
+ /*
+ * Initialize DMAC
+ */
+ init_pc98_dmac();
+#endif
+
/*
* make gdt memory segments, the code segment goes up to end of the
* page with etext in it, the data segment goes to the end of
@@ -1507,56 +1256,7 @@ init386(first)
#ifdef PC98
#ifdef EPSON_MEMWIN
- if (pc98_machine_type & M_EPSON_PC98) {
- if (Maxmem > 3840) {
- if (Maxmem == Maxmem_under16M) {
- Maxmem = 3840;
- Maxmem_under16M = 3840;
- } else if (Maxmem_under16M > 3840) {
- Maxmem_under16M = 3840;
- }
- }
-
- /* Disable 15MB-16MB caching */
- switch (epson_machine_id) {
- case 0x34: /* PC486HX */
- case 0x35: /* PC486HG */
- case 0x3B: /* PC486HA */
- /* Cache control start */
- outb(0x43f, 0x42);
- outw(0xc40, 0x0033);
-
- /* Disable 0xF00000-0xFFFFFF */
- outb(0xc48, 0x49); outb(0xc4c, 0x00);
- outb(0xc48, 0x48); outb(0xc4c, 0xf0);
- outb(0xc48, 0x4d); outb(0xc4c, 0x00);
- outb(0xc48, 0x4c); outb(0xc4c, 0xff);
- outb(0xc48, 0x4f); outb(0xc4c, 0x00);
-
- /* Cache control end */
- outb(0x43f, 0x40);
- break;
-
- case 0x2B: /* PC486GR/GF */
- case 0x30: /* PC486P */
- case 0x31: /* PC486GRSuper */
- case 0x32: /* PC486GR+ */
- case 0x37: /* PC486SE */
- case 0x38: /* PC486SR */
- /* Disable 0xF00000-0xFFFFFF */
- outb(0x43f, 0x42);
- outb(0x467, 0xe0);
- outb(0x567, 0xd8);
-
- outb(0x43f, 0x40);
- outb(0x467, 0xe0);
- outb(0x567, 0xe0);
- break;
- }
-
- /* Disable 15MB-16MB RAM and enable memory window */
- outb(0x43b, inb(0x43b) & 0xfd); /* clear bit1 */
- }
+ init_epson_memwin();
#endif
biosbasemem = 640; /* 640KB */
biosextmem = (Maxmem * PAGE_SIZE - 0x100000)/1024; /* extent memory */
@@ -1623,7 +1323,8 @@ init386(first)
/*
* Maxmem isn't the "maximum memory", it's one larger than the
- * highest page of of the physical address space. It
+ * highest page of the physical address space. It should be
+ * called something like "Maxphyspage".
*/
Maxmem = pagesinext + 0x100000/PAGE_SIZE;
@@ -1654,76 +1355,9 @@ init386(first)
}
#ifdef PC98
- /*
- * Certain 'CPU accelerator' supports over 16MB memory on
- * the machines whose BIOS doesn't store true size.
- * To support this, we don't trust BIOS values if Maxmem < 4096.
- */
- if (Maxmem < 4096) {
- for (target_page = ptoa(4096); /* 16MB */
- target_page < ptoa(32768); /* 128MB */
- target_page += 256 * PAGE_SIZE /* 1MB step */) {
- int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
-
- *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
- pmap_update();
-
- tmp = *(int *)CADDR1;
- /*
- * Test for alternating 1's and 0's
- */
- *(volatile int *)CADDR1 = 0xaaaaaaaa;
- if (*(volatile int *)CADDR1 != 0xaaaaaaaa) {
- page_bad = TRUE;
- }
- /*
- * Test for alternating 0's and 1's
- */
- *(volatile int *)CADDR1 = 0x55555555;
- if (*(volatile int *)CADDR1 != 0x55555555) {
- page_bad = TRUE;
- }
- /*
- * Test for all 1's
- */
- *(volatile int *)CADDR1 = 0xffffffff;
- if (*(volatile int *)CADDR1 != 0xffffffff) {
- page_bad = TRUE;
- }
- /*
- * Test for all 0's
- */
- *(volatile int *)CADDR1 = 0x0;
- if (*(volatile int *)CADDR1 != 0x0) {
- /*
- * test of page failed
- */
- page_bad = TRUE;
- }
- /*
- * Restore original value.
- */
- *(int *)CADDR1 = tmp;
- if (page_bad == TRUE) {
- if (target_page > ptoa(4096))
- Maxmem = atop(target_page);
- else
- Maxmem = OrigMaxmem;
-
- break;
- }
- }
- *(int *)CMAP1 = 0;
- pmap_update();
-
- /* XXX */
- if (Maxmem > 3840) {
- Maxmem_under16M = 3840;
- if (Maxmem < 4096) {
- Maxmem = 3840;
- }
- }
- }
+#ifdef notyet
+ init_cpu_accel_mem();
+#endif
#endif
for (target_page = avail_start; target_page < ptoa(Maxmem); target_page += PAGE_SIZE) {
diff --git a/sys/pc98/i386/microtime.s b/sys/pc98/i386/microtime.s
index cd08213..4731ecf 100644
--- a/sys/pc98/i386/microtime.s
+++ b/sys/pc98/i386/microtime.s
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* from: Steve McCanne's microtime code
- * $Id: microtime.s,v 1.13 1996/05/31 01:08:02 peter Exp $
+ * $Id: microtime.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
*/
#include <machine/asmacros.h>
@@ -60,6 +60,7 @@ ENTRY(microtime)
movb $TIMER_SEL0|TIMER_LATCH, %al /* prepare to latch */
+ pushfl
cli /* disable interrupts */
outb %al, $TIMER_MODE /* latch timer 0's counter */
@@ -218,7 +219,7 @@ overflow:
#endif /* !AUTO_CLOCK */
#else /* IBM-PC */
#if 0
- imul $27645, %edx /* 25 cycles on a 486 */
+ imul $27465, %edx /* 25 cycles on a 486 */
#else
leal (%edx,%edx,2), %eax /* a = 3 2 cycles on a 486 */
leal (%edx,%eax,4), %eax /* a = 13 2 */
@@ -235,7 +236,7 @@ common_microtime:
addl _time+4, %eax /* usec += time.tv_sec */
movl _time, %edx /* sec = time.tv_sec */
- sti /* enable interrupts */
+ popfl /* restore interrupt mask */
cmpl $1000000, %eax /* usec valid? */
jb 1f
@@ -251,6 +252,7 @@ common_microtime:
#if defined(I586_CPU) || defined(I686_CPU)
ALIGN_TEXT
pentium_microtime:
+ pushfl
cli
.byte 0x0f, 0x31 /* RDTSC */
subl _i586_ctr_bias, %eax
diff --git a/sys/pc98/i386/pmap.c b/sys/pc98/i386/pmap.c
index 4109f8c..557f584 100644
--- a/sys/pc98/i386/pmap.c
+++ b/sys/pc98/i386/pmap.c
@@ -39,17 +39,7 @@
* SUCH DAMAGE.
*
* from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
- * $Id: pmap.c,v 1.102 1996/06/08 06:48:27 dyson Exp $
- */
-
-/*
- * Derived from hp300 version by Mike Hibler, this version by William
- * Jolitz uses a recursive map [a pde points to the page directory] to
- * map the page tables using the pagetables themselves. This is done to
- * reduce the impact on kernel virtual memory for lots of sparse address
- * space, and to reduce the cost of memory to each process.
- *
- * Derived from: hp300/@(#)pmap.c 7.1 (Berkeley) 12/5/90
+ * $Id: pmap.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
*/
/*
@@ -97,17 +87,12 @@
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
#include <vm/vm_pageout.h>
+#include <vm/vm_pager.h>
#include <machine/pcb.h>
#include <machine/cputypes.h>
#include <machine/md_var.h>
-#ifdef PC98
-#include <pc98/pc98/pc98.h>
-#else
-#include <i386/isa/isa.h>
-#endif
-
#define PMAP_KEEP_PDIRS
#if defined(DIAGNOSTIC)
@@ -180,10 +165,8 @@ static caddr_t CADDR2;
static pt_entry_t *msgbufmap;
struct msgbuf *msgbufp;
-#ifdef PC98
-pt_entry_t *panic_kwin_pte;
-caddr_t panic_kwin;
-#endif
+pt_entry_t *PMAP1;
+unsigned *PADDR1;
static void free_pv_entry __P((pv_entry_t pv));
static __inline unsigned * get_ptbase __P((pmap_t pmap));
@@ -191,29 +174,184 @@ static pv_entry_t get_pv_entry __P((void));
static void i386_protection_init __P((void));
static void pmap_alloc_pv_entry __P((void));
static void pmap_changebit __P((vm_offset_t pa, int bit, boolean_t setem));
-static void pmap_enter_quick __P((pmap_t pmap, vm_offset_t va,
- vm_offset_t pa));
+
static int pmap_is_managed __P((vm_offset_t pa));
static void pmap_remove_all __P((vm_offset_t pa));
+static void pmap_enter_quick __P((pmap_t pmap, vm_offset_t va,
+ vm_offset_t pa));
+static int pmap_remove_pte __P((struct pmap *pmap, unsigned *ptq,
+ vm_offset_t sva));
static void pmap_remove_page __P((struct pmap *pmap, vm_offset_t va));
static __inline int pmap_remove_entry __P((struct pmap *pmap, pv_entry_t *pv,
vm_offset_t va));
-static int pmap_remove_pte __P((struct pmap *pmap, unsigned *ptq,
- vm_offset_t sva));
-static boolean_t
- pmap_testbit __P((vm_offset_t pa, int bit));
+static boolean_t pmap_testbit __P((vm_offset_t pa, int bit));
static __inline void pmap_insert_entry __P((pmap_t pmap, vm_offset_t va,
vm_page_t mpte, vm_offset_t pa));
static __inline vm_page_t pmap_allocpte __P((pmap_t pmap, vm_offset_t va));
-static void pmap_remove_pte_mapping __P((vm_offset_t pa));
+
static __inline int pmap_release_free_page __P((pmap_t pmap, vm_page_t p));
-static vm_page_t _pmap_allocpte __P((pmap_t pmap, vm_offset_t va, int ptepindex));
+static vm_page_t _pmap_allocpte __P((pmap_t pmap, int ptepindex));
+#define VATRACK 4
#define PDSTACKMAX 16
static vm_offset_t pdstack[PDSTACKMAX];
static int pdstackptr;
+/*
+ * Bootstrap the system enough to run with virtual memory.
+ *
+ * On the i386 this is called after mapping has already been enabled
+ * and just syncs the pmap module with what has already been done.
+ * [We can't call it easily with mapping off since the kernel is not
+ * mapped with PA == VA, hence we would have to relocate every address
+ * from the linked base (virtual) address "KERNBASE" to the actual
+ * (physical) address starting relative to 0]
+ */
+void
+pmap_bootstrap(firstaddr, loadaddr)
+ vm_offset_t firstaddr;
+ vm_offset_t loadaddr;
+{
+ vm_offset_t va;
+ pt_entry_t *pte;
+
+ avail_start = firstaddr;
+
+ /*
+ * XXX The calculation of virtual_avail is wrong. It's NKPT*PAGE_SIZE too
+ * large. It should instead be correctly calculated in locore.s and
+ * not based on 'first' (which is a physical address, not a virtual
+ * address, for the start of unused physical memory). The kernel
+ * page tables are NOT double mapped and thus should not be included
+ * in this calculation.
+ */
+ virtual_avail = (vm_offset_t) KERNBASE + firstaddr;
+ virtual_end = VM_MAX_KERNEL_ADDRESS;
+
+ /*
+ * Initialize protection array.
+ */
+ i386_protection_init();
+
+ /*
+ * The kernel's pmap is statically allocated so we don't have to use
+ * pmap_create, which is unlikely to work correctly at this part of
+ * the boot sequence (XXX and which no longer exists).
+ */
+ kernel_pmap = &kernel_pmap_store;
+
+ kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + IdlePTD);
+
+ kernel_pmap->pm_count = 1;
+ nkpt = NKPT;
+
+ /*
+ * Reserve some special page table entries/VA space for temporary
+ * mapping of pages.
+ */
+#define SYSMAP(c, p, v, n) \
+ v = (c)va; va += ((n)*PAGE_SIZE); p = pte; pte += (n);
+
+ va = virtual_avail;
+ pte = (pt_entry_t *) pmap_pte(kernel_pmap, va);
+
+ /*
+ * CMAP1/CMAP2 are used for zeroing and copying pages.
+ */
+ SYSMAP(caddr_t, CMAP1, CADDR1, 1)
+ SYSMAP(caddr_t, CMAP2, CADDR2, 1)
+
+ /*
+ * ptmmap is used for reading arbitrary physical pages via /dev/mem.
+ */
+ SYSMAP(caddr_t, ptmmap, ptvmmap, 1)
+
+ /*
+ * msgbufmap is used to map the system message buffer.
+ */
+ SYSMAP(struct msgbuf *, msgbufmap, msgbufp, 1)
+
+ /*
+ * ptemap is used for pmap_pte_quick
+ */
+ SYSMAP(unsigned *, PMAP1, PADDR1, 1);
+
+ virtual_avail = va;
+
+ *(int *) CMAP1 = *(int *) CMAP2 = *(int *) PTD = 0;
+ pmap_update();
+
+}
+
+/*
+ * 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)
+ vm_offset_t phys_start, phys_end;
+{
+ vm_offset_t addr;
+ vm_size_t npg, s;
+ int i;
+
+ /*
+ * calculate the number of pv_entries needed
+ */
+ vm_first_phys = phys_avail[0];
+ for (i = 0; phys_avail[i + 1]; i += 2);
+ npg = (phys_avail[(i - 2) + 1] - vm_first_phys) / PAGE_SIZE;
+
+ /*
+ * Allocate memory for random pmap data structures. Includes the
+ * pv_head_table.
+ */
+ s = (vm_size_t) (sizeof(struct pv_entry *) * npg);
+ s = round_page(s);
+ addr = (vm_offset_t) kmem_alloc(kernel_map, s);
+ pv_table = (pv_entry_t *) addr;
+
+ /*
+ * init the pv free list
+ */
+ init_pv_entries(npg);
+ /*
+ * Now it is safe to enable pv_table recording.
+ */
+ pmap_initialized = TRUE;
+}
+
+/*
+ * Used to map a range of physical addresses into kernel
+ * virtual address space.
+ *
+ * For now, VM is already on, we only need to map the
+ * specified memory.
+ */
+vm_offset_t
+pmap_map(virt, start, end, prot)
+ vm_offset_t virt;
+ vm_offset_t start;
+ vm_offset_t end;
+ int prot;
+{
+ while (start < end) {
+ pmap_enter(kernel_pmap, virt, start, prot, FALSE);
+ virt += PAGE_SIZE;
+ start += PAGE_SIZE;
+ }
+ return (virt);
+}
+
+
+/***************************************************
+ * Low level helper routines.....
+ ***************************************************/
+
#if defined(PMAP_DIAGNOSTIC)
/*
@@ -233,6 +371,19 @@ pmap_nw_modified(pt_entry_t ptea) {
}
#endif
+
+/*
+ * this routine defines the region(s) of memory that should
+ * not be tested for the modified bit.
+ */
+static __inline int
+pmap_track_modified( vm_offset_t va) {
+ if ((va < clean_sva) || (va >= clean_eva))
+ return 1;
+ else
+ return 0;
+}
+
/*
* The below are finer grained pmap_update routines. These eliminate
* the gratuitious tlb flushes on non-i386 architectures.
@@ -240,6 +391,7 @@ pmap_nw_modified(pt_entry_t ptea) {
static __inline void
pmap_update_1pg( vm_offset_t va) {
#if defined(I386_CPU) || defined(CYRIX_486DLC)
+ /* CYRIX Bug? */
if (cpu_class == CPUCLASS_386 || cpu == CPU_486DLC)
pmap_update();
else
@@ -250,6 +402,7 @@ pmap_update_1pg( vm_offset_t va) {
static __inline void
pmap_update_2pg( vm_offset_t va1, vm_offset_t va2) {
#if defined(I386_CPU) || defined(CYRIX_486DLC)
+ /* CYRIX Bug? */
if (cpu_class == CPUCLASS_386 || cpu == CPU_486DLC) {
pmap_update();
} else
@@ -260,7 +413,7 @@ pmap_update_2pg( vm_offset_t va1, vm_offset_t va2) {
}
}
-static __inline __pure unsigned *
+static __pure unsigned *
get_ptbase(pmap)
pmap_t pmap;
{
@@ -297,6 +450,31 @@ pmap_pte(pmap, va)
}
/*
+ * Super fast pmap_pte routine best used when scanning
+ * the pv lists. This eliminates many coarse-grained
+ * pmap_update calls.
+ */
+__inline unsigned * __pure
+pmap_pte_quick(pmap, va)
+ register pmap_t pmap;
+ vm_offset_t va;
+{
+ unsigned pde;
+ if (pde = (unsigned) pmap->pm_pdir[va >> PDRSHIFT]) {
+ unsigned frame = (unsigned) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
+ /* are we current address space or kernel? */
+ if (pmap == kernel_pmap || frame == (((unsigned) PTDpde) & PG_FRAME)) {
+ return (unsigned *) PTmap + i386_btop(va);
+ }
+ * (int *) PMAP1 = (pde & PG_FRAME) | PG_V | PG_RW;
+ pmap_update_1pg((vm_offset_t) PADDR1);
+ return PADDR1 + ((unsigned) i386_btop(va) & (NPTEPG - 1));
+ }
+ return (0);
+}
+
+
+/*
* Routine: pmap_extract
* Function:
* Extract the physical page address associated
@@ -317,6 +495,29 @@ pmap_extract(pmap, va)
}
/*
+ * determine if a page is managed (memory vs. device)
+ */
+static __inline __pure int
+pmap_is_managed(pa)
+ vm_offset_t pa;
+{
+ int i;
+
+ if (!pmap_initialized)
+ return 0;
+
+ for (i = 0; phys_avail[i + 1]; i += 2) {
+ if (pa < phys_avail[i + 1] && pa >= phys_avail[i])
+ return 1;
+ }
+ return 0;
+}
+
+/***************************************************
+ * Low level mapping routines.....
+ ***************************************************/
+
+/*
* Add a list of wired pages to the kva
* this routine is only used for temporary
* kernel mappings that do not need to have
@@ -399,47 +600,48 @@ pmap_kremove(va)
pmap_update_1pg(va);
}
-/*
- * determine if a page is managed (memory vs. device)
- */
-static __inline __pure int
-pmap_is_managed(pa)
- vm_offset_t pa;
-{
- int i;
-
- if (!pmap_initialized)
- return 0;
- for (i = 0; phys_avail[i + 1]; i += 2) {
- if (pa < phys_avail[i + 1] && pa >= phys_avail[i])
- return 1;
- }
- return 0;
-}
+/***************************************************
+ * Page table page management routines.....
+ ***************************************************/
/*
* This routine unholds page table pages, and if the hold count
* drops to zero, then it decrements the wire count.
*/
static __inline int
-pmap_unwire_pte_hold(vm_page_t m) {
+pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m) {
vm_page_unhold(m);
if (m->hold_count == 0) {
+ vm_offset_t pteva;
+ /*
+ * unmap the page table page
+ */
+ pmap->pm_pdir[m->pindex] = 0;
+ --pmap->pm_stats.resident_count;
+ /*
+ * Do a pmap_update to make the invalidated mapping
+ * take effect immediately.
+ */
+ pteva = UPT_MIN_ADDRESS + i386_ptob(m->pindex);
+ pmap_update_1pg(pteva);
+ /*
+ * If the page is finally unwired, simply free it.
+ */
--m->wire_count;
if (m->wire_count == 0) {
+ vm_page_free_zero(m);
--cnt.v_wire_count;
- m->dirty = 0;
- vm_page_deactivate(m);
}
return 1;
}
return 0;
}
-#if !defined(PMAP_DIAGNOSTIC)
-__inline
-#endif
+/*
+ * After removing a page table entry, this routine is used to
+ * conditionally free the page, and manage the hold/wire counts.
+ */
int
pmap_unuse_pt(pmap, va, mpte)
pmap_t pmap;
@@ -451,178 +653,27 @@ pmap_unuse_pt(pmap, va, mpte)
if (mpte == NULL) {
vm_offset_t ptepa;
- ptepa = ((vm_offset_t) *pmap_pde(pmap, va)) /* & PG_FRAME */;
+ ptepa = ((vm_offset_t) *pmap_pde(pmap, va));
#if defined(PMAP_DIAGNOSTIC)
if (!ptepa)
panic("pmap_unuse_pt: pagetable page missing, va: 0x%x", va);
#endif
+ if (!ptepa)
+ return 0;
mpte = PHYS_TO_VM_PAGE(ptepa);
}
#if defined(PMAP_DIAGNOSTIC)
+ if (mpte->pindex != (va >> PDRSHIFT))
+ panic("pmap_unuse_pt: pindex(0x%x) != va(0x%x)",
+ mpte->pindex, (va >> PDRSHIFT));
+
if (mpte->hold_count == 0) {
panic("pmap_unuse_pt: hold count < 0, va: 0x%x", va);
}
#endif
-/*
- * We don't free page-table-pages anymore because it can have a negative
- * impact on perf at times. Now we just deactivate, and it'll get cleaned
- * up if needed... Also, if the page ends up getting used, it will be
- * brought back into the process address space by pmap_allocpte and be
- * reactivated.
- */
- return pmap_unwire_pte_hold(mpte);
-}
-
-/*
- * Bootstrap the system enough to run with virtual memory.
- *
- * On the i386 this is called after mapping has already been enabled
- * and just syncs the pmap module with what has already been done.
- * [We can't call it easily with mapping off since the kernel is not
- * mapped with PA == VA, hence we would have to relocate every address
- * from the linked base (virtual) address "KERNBASE" to the actual
- * (physical) address starting relative to 0]
- */
-void
-pmap_bootstrap(firstaddr, loadaddr)
- vm_offset_t firstaddr;
- vm_offset_t loadaddr;
-{
- vm_offset_t va;
- pt_entry_t *pte;
-
- avail_start = firstaddr;
-
- /*
- * XXX The calculation of virtual_avail is wrong. It's NKPT*PAGE_SIZE too
- * large. It should instead be correctly calculated in locore.s and
- * not based on 'first' (which is a physical address, not a virtual
- * address, for the start of unused physical memory). The kernel
- * page tables are NOT double mapped and thus should not be included
- * in this calculation.
- */
- virtual_avail = (vm_offset_t) KERNBASE + firstaddr;
- virtual_end = VM_MAX_KERNEL_ADDRESS;
-
- /*
- * Initialize protection array.
- */
- i386_protection_init();
-
- /*
- * The kernel's pmap is statically allocated so we don't have to use
- * pmap_create, which is unlikely to work correctly at this part of
- * the boot sequence (XXX and which no longer exists).
- */
- kernel_pmap = &kernel_pmap_store;
-
- kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + IdlePTD);
-
- kernel_pmap->pm_count = 1;
- nkpt = NKPT;
-
- /*
- * Reserve some special page table entries/VA space for temporary
- * mapping of pages.
- */
-#define SYSMAP(c, p, v, n) \
- v = (c)va; va += ((n)*PAGE_SIZE); p = pte; pte += (n);
-
- va = virtual_avail;
- pte = (pt_entry_t *) pmap_pte(kernel_pmap, va);
-
- /*
- * CMAP1/CMAP2 are used for zeroing and copying pages.
- */
- SYSMAP(caddr_t, CMAP1, CADDR1, 1)
- SYSMAP(caddr_t, CMAP2, CADDR2, 1)
-
- /*
- * ptmmap is used for reading arbitrary physical pages via /dev/mem.
- */
- SYSMAP(caddr_t, ptmmap, ptvmmap, 1)
-
- /*
- * msgbufmap is used to map the system message buffer.
- */
- SYSMAP(struct msgbuf *, msgbufmap, msgbufp, 1)
-
-#ifdef PC98
- /*
- * panic_kwin is used for accessing phisical memory in boot()
- */
- SYSMAP(caddr_t, panic_kwin_pte, panic_kwin, 1)
-#endif
- virtual_avail = va;
-
- *(int *) CMAP1 = *(int *) CMAP2 = *(int *) PTD = 0;
- pmap_update();
-
-}
-
-/*
- * 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)
- vm_offset_t phys_start, phys_end;
-{
- vm_offset_t addr;
- vm_size_t npg, s;
- int i;
-
- /*
- * calculate the number of pv_entries needed
- */
- vm_first_phys = phys_avail[0];
- for (i = 0; phys_avail[i + 1]; i += 2);
- npg = (phys_avail[(i - 2) + 1] - vm_first_phys) / PAGE_SIZE;
-
- /*
- * Allocate memory for random pmap data structures. Includes the
- * pv_head_table.
- */
- s = (vm_size_t) (sizeof(struct pv_entry *) * npg);
- s = round_page(s);
- addr = (vm_offset_t) kmem_alloc(kernel_map, s);
- pv_table = (pv_entry_t *) addr;
-
- /*
- * init the pv free list
- */
- init_pv_entries(npg);
- /*
- * Now it is safe to enable pv_table recording.
- */
- pmap_initialized = TRUE;
-}
-
-/*
- * Used to map a range of physical addresses into kernel
- * virtual address space.
- *
- * For now, VM is already on, we only need to map the
- * specified memory.
- */
-vm_offset_t
-pmap_map(virt, start, end, prot)
- vm_offset_t virt;
- vm_offset_t start;
- vm_offset_t end;
- int prot;
-{
- while (start < end) {
- pmap_enter(kernel_pmap, virt, start, prot, FALSE);
- virt += PAGE_SIZE;
- start += PAGE_SIZE;
- }
- return (virt);
+ return pmap_unwire_pte_hold(pmap, mpte);
}
/*
@@ -641,8 +692,7 @@ pmap_pinit(pmap)
if (pdstackptr > 0) {
--pdstackptr;
- pmap->pm_pdir =
- (pd_entry_t *)pdstack[pdstackptr];
+ pmap->pm_pdir = (pd_entry_t *)pdstack[pdstackptr];
} else {
pmap->pm_pdir =
(pd_entry_t *)kmem_alloc_pageable(kernel_map, PAGE_SIZE);
@@ -686,6 +736,7 @@ pmap_release_free_page(pmap, p)
vm_page_t p;
{
int s;
+ unsigned *pde = (unsigned *) pmap->pm_pdir;
/*
* This code optimizes the case of freeing non-busy
* page-table pages. Those pages are zero now, and
@@ -699,12 +750,28 @@ pmap_release_free_page(pmap, p)
return 0;
}
- pmap_remove_pte_mapping(VM_PAGE_TO_PHYS(p));
+ /*
+ * Remove the page table page from the processes address space.
+ */
+ pde[p->pindex] = 0;
+ --pmap->pm_stats.resident_count;
if (p->hold_count) {
+ int *kvap;
+ int i;
#if defined(PMAP_DIAGNOSTIC)
panic("pmap_release: freeing held page table page");
+#else
+ printf("pmap_release: freeing held page table page:\n");
#endif
+ kvap = (int *)vm_pager_map_page(p);
+ for(i=0;i<NPTEPG;i++) {
+ if (kvap[i]) {
+ printf("pte: 0x%x, index: %d\n", kvap[i],i);
+ }
+ }
+ vm_pager_unmap_page((vm_offset_t)kvap);
+
/*
* HACK ALERT!!!
* If this failure happens, we must clear the page, because
@@ -721,10 +788,8 @@ pmap_release_free_page(pmap, p)
* stuff cleared, so they can go into the zero queue also.
*/
if (p->pindex == PTDPTDI) {
- unsigned *pde = (unsigned *) pmap->pm_pdir;
bzero(pde + KPTDI, nkpt * PTESIZE);
pde[APTDPTDI] = 0;
- pde[PTDPTDI] = 0;
pmap_kremove((vm_offset_t) pmap->pm_pdir);
}
@@ -734,6 +799,119 @@ pmap_release_free_page(pmap, p)
}
/*
+ * this routine is called if the page table page is not
+ * mapped correctly.
+ */
+static vm_page_t
+_pmap_allocpte(pmap, ptepindex)
+ pmap_t pmap;
+ int ptepindex;
+{
+ vm_offset_t pteva, ptepa;
+ vm_page_t m;
+
+ /*
+ * Find or fabricate a new pagetable page
+ */
+retry:
+ m = vm_page_lookup(pmap->pm_pteobj, ptepindex);
+ if (m == NULL) {
+ m = vm_page_alloc(pmap->pm_pteobj, ptepindex, VM_ALLOC_ZERO);
+ if (m == NULL) {
+ VM_WAIT;
+ goto retry;
+ }
+ if ((m->flags & PG_ZERO) == 0)
+ pmap_zero_page(VM_PAGE_TO_PHYS(m));
+ m->flags &= ~(PG_ZERO|PG_BUSY);
+ m->valid = VM_PAGE_BITS_ALL;
+ } else {
+ if ((m->flags & PG_BUSY) || m->busy) {
+ m->flags |= PG_WANTED;
+ tsleep(m, PVM, "ptewai", 0);
+ goto retry;
+ }
+ }
+
+ /*
+ * mark the object writeable
+ */
+ pmap->pm_pteobj->flags |= OBJ_WRITEABLE;
+
+ if (m->queue != PQ_NONE) {
+ int s = splvm();
+ vm_page_unqueue(m);
+ splx(s);
+ }
+
+ if (m->hold_count == 0) {
+ if (m->wire_count == 0)
+ ++cnt.v_wire_count;
+ ++m->wire_count;
+ }
+ /*
+ * Increment the hold count for the page table page
+ * (denoting a new mapping.)
+ */
+ ++m->hold_count;
+
+ /*
+ * Map the pagetable page into the process address space, if
+ * it isn't already there.
+ */
+
+ pmap->pm_stats.resident_count++;
+
+ ptepa = VM_PAGE_TO_PHYS(m);
+ pmap->pm_pdir[ptepindex] = (pd_entry_t) (ptepa | PG_U | PG_RW | PG_V);
+
+ pteva = UPT_MIN_ADDRESS + i386_ptob(ptepindex);
+ pmap_update_1pg(pteva);
+ m->flags |= PG_MAPPED;
+
+ return m;
+}
+
+static __inline vm_page_t
+pmap_allocpte(pmap, va)
+ pmap_t pmap;
+ vm_offset_t va;
+{
+ int ptepindex;
+ vm_offset_t ptepa;
+ vm_page_t m;
+
+ /*
+ * Calculate pagetable page index
+ */
+ ptepindex = va >> PDRSHIFT;
+
+ /*
+ * Get the page directory entry
+ */
+ ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
+
+ /*
+ * If the page table page is mapped, we just increment the
+ * hold count, and activate it.
+ */
+ if (ptepa) {
+ m = PHYS_TO_VM_PAGE(ptepa);
+ ++m->hold_count;
+ return m;
+ }
+ /*
+ * Here if the pte page isn't mapped, or if it has been deallocated.
+ */
+ return _pmap_allocpte(pmap, ptepindex);
+}
+
+
+/***************************************************
+* Pmap allocation/deallocation routines.
+ ***************************************************/
+
+/*
* Release any resources held by the given physical map.
* Called when a pmap initialized by pmap_pinit is being released.
* Should only be called if the map contains no valid mappings.
@@ -744,7 +922,6 @@ pmap_release(pmap)
{
vm_page_t p,n,ptdpg;
vm_object_t object = pmap->pm_pteobj;
- int s;
if (object->ref_count != 1)
panic("pmap_release: pteobj reference count != 1");
@@ -765,7 +942,7 @@ retry:
if (!pmap_release_free_page(pmap, ptdpg))
goto retry;
-
+
vm_object_deallocate(object);
if (pdstackptr < PDSTACKMAX) {
pdstack[pdstackptr] = (vm_offset_t) pmap->pm_pdir;
@@ -778,7 +955,6 @@ retry:
/*
* grow the number of kernel page table entries, if needed
*/
-
void
pmap_growkernel(vm_offset_t addr)
{
@@ -858,6 +1034,10 @@ pmap_reference(pmap)
}
}
+/***************************************************
+* page management routines.
+ ***************************************************/
+
/*
* free the pv_entry back to the free list
*/
@@ -1005,13 +1185,39 @@ pmap_remove_entry(pmap, ppv, va)
}
/*
+ * Create a pv entry for page at pa for
+ * (pmap, va).
+ */
+static __inline void
+pmap_insert_entry(pmap, va, mpte, pa)
+ pmap_t pmap;
+ vm_offset_t va;
+ vm_page_t mpte;
+ vm_offset_t pa;
+{
+
+ int s;
+ pv_entry_t *ppv, pv;
+
+ s = splvm();
+ pv = get_pv_entry();
+ pv->pv_va = va;
+ pv->pv_pmap = pmap;
+ pv->pv_ptem = mpte;
+
+ ppv = pa_to_pvh(pa);
+ if (*ppv)
+ pv->pv_next = *ppv;
+ else
+ pv->pv_next = NULL;
+ *ppv = pv;
+ splx(s);
+}
+
+/*
* pmap_remove_pte: do the things to unmap a page in a process
*/
-static
-#if !defined(PMAP_DIAGNOSTIC)
-__inline
-#endif
-int
+static int
pmap_remove_pte(pmap, ptq, va)
struct pmap *pmap;
unsigned *ptq;
@@ -1019,7 +1225,6 @@ pmap_remove_pte(pmap, ptq, va)
{
unsigned oldpte;
pv_entry_t *ppv;
- int rtval;
oldpte = *ptq;
*ptq = 0;
@@ -1033,20 +1238,11 @@ pmap_remove_pte(pmap, ptq, va)
printf("pmap_remove: modified page not writable: va: 0x%lx, pte: 0x%lx\n", va, (int) oldpte);
}
#endif
-
- if (va < clean_sva || va >= clean_eva) {
- if ((va < UPT_MIN_ADDRESS) || (va >= UPT_MAX_ADDRESS))
- PHYS_TO_VM_PAGE(oldpte)->dirty = VM_PAGE_BITS_ALL;
- }
+ if (pmap_track_modified(va))
+ PHYS_TO_VM_PAGE(oldpte)->dirty = VM_PAGE_BITS_ALL;
}
ppv = pa_to_pvh(oldpte);
- rtval = pmap_remove_entry(pmap, ppv, va);
-#if defined(notyet)
- if (*ppv == NULL) {
- PHYS_TO_VM_PAGE(oldpte)->flags &= ~PG_MAPPED;
- }
-#endif
- return rtval;
+ return pmap_remove_entry(pmap, ppv, va);
} else {
return pmap_unuse_pt(pmap, va, NULL);
}
@@ -1057,7 +1253,7 @@ pmap_remove_pte(pmap, ptq, va)
/*
* Remove a single page from a process address space
*/
-static __inline void
+static void
pmap_remove_page(pmap, va)
struct pmap *pmap;
register vm_offset_t va;
@@ -1100,6 +1296,7 @@ pmap_remove(pmap, sva, eva)
vm_offset_t sindex, eindex;
vm_page_t mpte;
int anyvalid;
+ vm_offset_t vachanged[VATRACK];
if (pmap == NULL)
return;
@@ -1168,7 +1365,10 @@ pmap_remove(pmap, sva, eva)
continue;
}
va = i386_ptob(sindex);
- anyvalid = 1;
+
+ if (anyvalid < VATRACK)
+ vachanged[anyvalid] = va;
+ anyvalid++;
if (pmap_remove_pte(pmap,
ptbase + sindex, va))
break;
@@ -1176,45 +1376,15 @@ pmap_remove(pmap, sva, eva)
}
if (anyvalid) {
- pmap_update();
- }
-}
-
-/*
- * Remove pte mapping, don't do everything that we would do
- * for normal pages because many things aren't necessary (like
- * pmap_update())...
- */
-void
-pmap_remove_pte_mapping(pa)
- vm_offset_t pa;
-{
- register pv_entry_t pv, *ppv, npv;
- register unsigned *pte;
- vm_offset_t va;
- int anyvalid = 0;
-
- ppv = pa_to_pvh(pa);
-
- for (pv = *ppv; pv; pv=pv->pv_next) {
- unsigned tpte;
- struct pmap *pmap;
-
- pmap = pv->pv_pmap;
- pte = get_ptbase(pmap) + i386_btop(pv->pv_va);
- if (tpte = *pte) {
- pmap->pm_stats.resident_count--;
- *pte = 0;
- if (tpte & PG_W)
- pmap->pm_stats.wired_count--;
+ if (anyvalid <= VATRACK) {
+ int i;
+ for(i=0;i<anyvalid;i++)
+ pmap_update_1pg(vachanged[i]);
+ } else {
+ pmap_update();
}
}
-
- for (pv = *ppv; pv; pv = npv) {
- npv = pv->pv_next;
- free_pv_entry(pv);
- }
- *ppv = NULL;
+
}
/*
@@ -1234,8 +1404,7 @@ pmap_remove_all(pa)
vm_offset_t pa;
{
register pv_entry_t pv, *ppv, npv;
- register unsigned *pte, *ptbase;
- vm_offset_t va;
+ register unsigned *pte, tpte;
vm_page_t m;
int s;
@@ -1249,39 +1418,28 @@ pmap_remove_all(pa)
}
#endif
- m = PHYS_TO_VM_PAGE(pa);
- ppv = pa_to_pvh(pa);
-
s = splvm();
+ m = NULL;
+ ppv = pa_to_pvh(pa);
for (pv = *ppv; pv; pv=pv->pv_next) {
- int tpte;
- struct pmap *pmap;
-
- pmap = pv->pv_pmap;
- ptbase = get_ptbase(pmap);
- va = pv->pv_va;
- if (*pmap_pde(pmap, va) == 0)
- continue;
- pte = ptbase + i386_btop(va);
- if (tpte = ((int) *pte)) {
- pmap->pm_stats.resident_count--;
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
+ if (tpte = *pte) {
+ pv->pv_pmap->pm_stats.resident_count--;
*pte = 0;
if (tpte & PG_W)
- pmap->pm_stats.wired_count--;
+ pv->pv_pmap->pm_stats.wired_count--;
/*
* Update the vm_page_t clean and reference bits.
*/
if (tpte & PG_M) {
#if defined(PMAP_DIAGNOSTIC)
if (pmap_nw_modified((pt_entry_t) tpte)) {
- printf("pmap_remove_all: modified page not writable: va: 0x%lx, pte: 0x%lx\n", va, tpte);
+ printf("pmap_remove_all: modified page not writable: va: 0x%lx, pte: 0x%lx\n", pv->pv_va, tpte);
}
#endif
- if ((va >= UPT_MIN_ADDRESS) &&
- (va < UPT_MAX_ADDRESS))
- continue;
-
- if (va < clean_sva || va >= clean_eva) {
+ if (pmap_track_modified(pv->pv_va)) {
+ if (m == NULL)
+ m = PHYS_TO_VM_PAGE(pa);
m->dirty = VM_PAGE_BITS_ALL;
}
}
@@ -1294,7 +1452,6 @@ pmap_remove_all(pa)
free_pv_entry(pv);
}
*ppv = NULL;
-
splx(s);
}
@@ -1308,8 +1465,6 @@ pmap_protect(pmap, sva, eva, prot)
vm_offset_t sva, eva;
vm_prot_t prot;
{
- register unsigned *pte;
- register vm_offset_t va;
register unsigned *ptbase;
vm_offset_t pdnxt;
vm_offset_t ptpaddr;
@@ -1348,7 +1503,9 @@ pmap_protect(pmap, sva, eva, prot)
continue;
/*
- * Don't look at kernel page table pages
+ * Skip page ranges, where the page table page isn't wired.
+ * If the page table page is not wired, there are no page mappings
+ * there.
*/
if (sindex < i386_btop(UPT_MIN_ADDRESS)) {
mpte = PHYS_TO_VM_PAGE(ptpaddr);
@@ -1367,8 +1524,11 @@ pmap_protect(pmap, sva, eva, prot)
if (pbits & PG_RW) {
if (pbits & PG_M) {
- vm_page_t m = PHYS_TO_VM_PAGE(pbits);
- m->dirty = VM_PAGE_BITS_ALL;
+ vm_offset_t sva = i386_ptob(sindex);
+ if (pmap_track_modified(sva)) {
+ vm_page_t m = PHYS_TO_VM_PAGE(pbits);
+ m->dirty = VM_PAGE_BITS_ALL;
+ }
}
ptbase[sindex] = pbits & ~(PG_M|PG_RW);
anyvalid = 1;
@@ -1380,170 +1540,6 @@ pmap_protect(pmap, sva, eva, prot)
}
/*
- * Create a pv entry for page at pa for
- * (pmap, va).
- */
-static __inline void
-pmap_insert_entry(pmap, va, mpte, pa)
- pmap_t pmap;
- vm_offset_t va;
- vm_page_t mpte;
- vm_offset_t pa;
-{
-
- int s;
- pv_entry_t *ppv, pv;
-
- s = splvm();
- pv = get_pv_entry();
- pv->pv_va = va;
- pv->pv_pmap = pmap;
- pv->pv_ptem = mpte;
-
- ppv = pa_to_pvh(pa);
- if (*ppv)
- pv->pv_next = *ppv;
- else
- pv->pv_next = NULL;
- *ppv = pv;
- splx(s);
-}
-
-/*
- * this routine is called if the page table page is not
- * mapped correctly.
- */
-static vm_page_t
-_pmap_allocpte(pmap, va, ptepindex)
- pmap_t pmap;
- vm_offset_t va;
- int ptepindex;
-{
- vm_offset_t pteva, ptepa;
- vm_page_t m;
- int s;
-
- /*
- * Find or fabricate a new pagetable page
- */
-retry:
- m = vm_page_lookup(pmap->pm_pteobj, ptepindex);
- if (m == NULL) {
- m = vm_page_alloc(pmap->pm_pteobj, ptepindex, VM_ALLOC_ZERO);
- if (m == NULL) {
- VM_WAIT;
- goto retry;
- }
- if ((m->flags & PG_ZERO) == 0)
- pmap_zero_page(VM_PAGE_TO_PHYS(m));
- m->flags &= ~(PG_ZERO|PG_BUSY);
- m->valid = VM_PAGE_BITS_ALL;
- } else {
- if ((m->flags & PG_BUSY) || m->busy) {
- m->flags |= PG_WANTED;
- tsleep(m, PVM, "ptewai", 0);
- goto retry;
- }
- }
-
- /*
- * mark the object writeable
- */
- pmap->pm_pteobj->flags |= OBJ_WRITEABLE;
-
- if (m->hold_count == 0) {
- s = splvm();
- vm_page_unqueue(m);
- splx(s);
- ++m->wire_count;
- ++cnt.v_wire_count;
- }
-
- /*
- * Increment the hold count for the page table page
- * (denoting a new mapping.)
- */
- ++m->hold_count;
-
- /*
- * Map the pagetable page into the process address space, if
- * it isn't already there.
- */
- pteva = ((vm_offset_t) vtopte(va)) & PG_FRAME;
- ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
- if (ptepa == 0) {
- pv_entry_t pv, *ppv;
-
- pmap->pm_stats.resident_count++;
-
- s = splvm();
- pv = get_pv_entry();
-
- pv->pv_va = pteva;
- pv->pv_pmap = pmap;
- pv->pv_next = NULL;
- pv->pv_ptem = NULL;
-
- ptepa = VM_PAGE_TO_PHYS(m);
- ppv = pa_to_pvh(ptepa);
-#if defined(PMAP_DIAGNOSTIC)
- if (*ppv)
- panic("pmap_allocpte: page is already mapped");
-#endif
- *ppv = pv;
- splx(s);
- pmap_update_1pg(pteva);
- } else {
-#if defined(PMAP_DIAGNOSTIC)
- if (VM_PAGE_TO_PHYS(m) != (ptepa & PG_FRAME))
- panic("pmap_allocpte: mismatch");
-#endif
- }
- pmap->pm_pdir[ptepindex] =
- (pd_entry_t) (ptepa | PG_U | PG_RW | PG_V | PG_MANAGED);
- m->flags |= PG_MAPPED;
- return m;
-}
-
-static __inline vm_page_t
-pmap_allocpte(pmap, va)
- pmap_t pmap;
- vm_offset_t va;
-{
- int ptepindex;
- vm_offset_t ptepa;
- vm_page_t m;
-
- /*
- * Calculate pagetable page index
- */
- ptepindex = va >> PDRSHIFT;
-
- /*
- * Get the page directory entry
- */
- ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
-
- /*
- * If the page table page is mapped, we just increment the
- * hold count, and activate it.
- */
- if ((ptepa & (PG_RW|PG_U|PG_V)) == (PG_RW|PG_U|PG_V)) {
- m = PHYS_TO_VM_PAGE(ptepa);
- if (m->hold_count == 0) {
- int s = splvm();
- vm_page_unqueue(m);
- splx(s);
- ++m->wire_count;
- ++cnt.v_wire_count;
- }
- ++m->hold_count;
- return m;
- }
- return _pmap_allocpte(pmap, va, ptepindex);
-}
-
-/*
* Insert the given physical page (p) at
* the specified virtual address (v) in the
* target physical map with the protection requested.
@@ -1572,8 +1568,12 @@ pmap_enter(pmap, va, pa, prot, wired)
return;
va &= PG_FRAME;
+#ifdef PMAP_DIAGNOSTIC
if (va > VM_MAX_KERNEL_ADDRESS)
panic("pmap_enter: toobig");
+ if ((va >= UPT_MIN_ADDRESS) && (va < UPT_MAX_ADDRESS))
+ panic("pmap_enter: invalid to pmap_enter page table pages (va: 0x%x)", va);
+#endif
mpte = NULL;
/*
@@ -1583,14 +1583,13 @@ pmap_enter(pmap, va, pa, prot, wired)
if (va < UPT_MIN_ADDRESS)
mpte = pmap_allocpte(pmap, va);
- pte = pmap_pte(pmap, va);
+ pte = pmap_pte_quick(pmap, va);
/*
* Page Directory table entry not valid, we need a new PT page
*/
if (pte == NULL) {
- printf("kernel page directory invalid pdir=%p, va=0x%lx\n",
+ panic("pmap_enter: invalid page directory, pdir=%p, va=0x%lx\n",
pmap->pm_pdir[PTDPTDI], va);
- panic("invalid kernel page directory");
}
origpte = *(vm_offset_t *)pte;
@@ -1625,8 +1624,10 @@ pmap_enter(pmap, va, pa, prot, wired)
if (origpte & PG_MANAGED) {
vm_page_t m;
if (origpte & PG_M) {
- m = PHYS_TO_VM_PAGE(pa);
- m->dirty = VM_PAGE_BITS_ALL;
+ if (pmap_track_modified(va)) {
+ m = PHYS_TO_VM_PAGE(pa);
+ m->dirty = VM_PAGE_BITS_ALL;
+ }
}
pa |= PG_MANAGED;
}
@@ -1635,13 +1636,17 @@ pmap_enter(pmap, va, pa, prot, wired)
--mpte->hold_count;
goto validate;
- }
+ }
/*
* Mapping has changed, invalidate old range and fall through to
* handle validating new mapping.
*/
- if (opa)
- (void) pmap_remove_pte(pmap, pte, va);
+ if (opa) {
+ int err;
+ err = pmap_remove_pte(pmap, pte, va);
+ if (err)
+ panic("pmap_enter: pte vanished, va: 0x%x", va);
+ }
/*
* Enter on the PV list if part of our managed memory Note that we
@@ -1710,9 +1715,18 @@ pmap_enter_quick(pmap, va, pa)
if (va < UPT_MIN_ADDRESS)
mpte = pmap_allocpte(pmap, va);
+ /*
+ * This call to vtopte makes the assumption that we are
+ * entering the page into the current pmap. In order to support
+ * quick entry into any pmap, one would likely use pmap_pte_quick.
+ * But that isn't as quick as vtopte.
+ */
pte = (unsigned *)vtopte(va);
- if (*pte)
- (void) pmap_remove_pte(pmap, pte, va);
+ if (*pte) {
+ if (mpte)
+ pmap_unwire_pte_hold(pmap, mpte);
+ return;
+ }
/*
* Enter on the PV list if part of our managed memory Note that we
@@ -1754,7 +1768,7 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
vm_page_t p;
int objpgs;
- psize = (size >> PAGE_SHIFT);
+ psize = i386_btop(size);
if (!pmap || (object->type != OBJT_VNODE) ||
(limit && (psize > MAX_INIT_PT) &&
@@ -1762,6 +1776,9 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
return;
}
+ if (psize + pindex > object->size)
+ psize = object->size - pindex;
+
/*
* if we are processing a major portion of the object, then scan the
* entire thing.
@@ -1788,7 +1805,7 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
vm_page_deactivate(p);
p->flags |= PG_BUSY;
pmap_enter_quick(pmap,
- addr + (tmpidx << PAGE_SHIFT),
+ addr + i386_ptob(tmpidx),
VM_PAGE_TO_PHYS(p));
p->flags |= PG_MAPPED;
PAGE_WAKEUP(p);
@@ -1809,7 +1826,7 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
vm_page_deactivate(p);
p->flags |= PG_BUSY;
pmap_enter_quick(pmap,
- addr + (tmpidx << PAGE_SHIFT),
+ addr + i386_ptob(tmpidx),
VM_PAGE_TO_PHYS(p));
p->flags |= PG_MAPPED;
PAGE_WAKEUP(p);
@@ -1977,6 +1994,8 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
vm_page_t dstmpte, srcmpte;
vm_offset_t srcptepaddr;
+ if (addr >= UPT_MIN_ADDRESS)
+ panic("pmap_copy: invalid to pmap_copy page tables\n");
pdnxt = ((addr + PAGE_SIZE*NPTEPG) & ~(PAGE_SIZE*NPTEPG - 1));
srcptepaddr = (vm_offset_t) src_pmap->pm_pdir[addr >> PDRSHIFT];
if (srcptepaddr == 0) {
@@ -2005,7 +2024,7 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
* block.
*/
dstmpte = pmap_allocpte(dst_pmap, addr);
- if (ptetemp = *src_pte) {
+ if ((*dst_pte == 0) && (ptetemp = *src_pte)) {
/*
* Simply clear the modified and accessed (referenced)
* bits.
@@ -2015,7 +2034,7 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
pmap_insert_entry(dst_pmap, addr, dstmpte,
(ptetemp & PG_FRAME));
} else {
- pmap_unwire_pte_hold(dstmpte);
+ pmap_unwire_pte_hold(dst_pmap, dstmpte);
}
if (dstmpte->hold_count >= srcmpte->hold_count)
break;
@@ -2074,11 +2093,8 @@ pmap_copy_page(src, dst)
*(int *) CMAP1 = PG_V | PG_RW | (src & PG_FRAME);
*(int *) CMAP2 = PG_V | PG_RW | (dst & PG_FRAME);
-#if __GNUC__ > 1
- memcpy(CADDR2, CADDR1, PAGE_SIZE);
-#else
bcopy(CADDR1, CADDR2, PAGE_SIZE);
-#endif
+
*(int *) CMAP1 = 0;
*(int *) CMAP2 = 0;
pmap_update_2pg( (vm_offset_t) CADDR1, (vm_offset_t) CADDR2);
@@ -2155,38 +2171,36 @@ pmap_testbit(pa, bit)
if (!pmap_is_managed(pa))
return FALSE;
- s = splvm();
-
ppv = pa_to_pvh(pa);
+ if (*ppv == NULL)
+ return FALSE;
+
+ s = splvm();
/*
* Not found, check current mappings returning immediately if found.
*/
for (pv = *ppv ;pv; pv = pv->pv_next) {
+
/*
* if the bit being tested is the modified bit, then
- * mark UPAGES as always modified, and ptes as never
+ * mark clean_map and ptes as never
* modified.
*/
if (bit & (PG_A|PG_M)) {
- if ((pv->pv_va >= UPT_MIN_ADDRESS) &&
- (pv->pv_va < UPT_MAX_ADDRESS)) {
+ if (!pmap_track_modified(pv->pv_va))
continue;
- }
- if ((pv->pv_va >= clean_sva) &&
- (pv->pv_va < clean_eva)) {
- continue;
- }
}
+
if (!pv->pv_pmap) {
#if defined(PMAP_DIAGNOSTIC)
printf("Null pmap (tb) at va: 0x%lx\n", pv->pv_va);
#endif
continue;
}
- pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
if (pte == NULL)
continue;
- if ((int) *pte & bit) {
+ if (*pte & bit) {
splx(s);
return TRUE;
}
@@ -2214,7 +2228,6 @@ pmap_changebit(pa, bit, setem)
return;
s = splvm();
-
changed = 0;
ppv = pa_to_pvh(pa);
/*
@@ -2238,7 +2251,7 @@ pmap_changebit(pa, bit, setem)
continue;
}
- pte = pmap_pte(pv->pv_pmap, va);
+ pte = pmap_pte_quick(pv->pv_pmap, va);
if (pte == NULL)
continue;
if (setem) {
@@ -2277,9 +2290,9 @@ pmap_page_protect(phys, prot)
vm_prot_t prot;
{
if ((prot & VM_PROT_WRITE) == 0) {
- if (prot & (VM_PROT_READ | VM_PROT_EXECUTE))
+ if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
pmap_changebit(phys, PG_RW, FALSE);
- else {
+ } else {
pmap_remove_all(phys);
pmap_update();
}
@@ -2302,7 +2315,110 @@ pmap_phys_address(ppn)
boolean_t
pmap_is_referenced(vm_offset_t pa)
{
- return pmap_testbit((pa), PG_A);
+ register pv_entry_t *ppv, pv, lpv;
+ unsigned *pte;
+ int s;
+
+ if (!pmap_is_managed(pa))
+ return FALSE;
+
+ ppv = pa_to_pvh(pa);
+
+ s = splvm();
+ /*
+ * Not found, check current mappings returning immediately if found.
+ */
+ for (lpv = NULL, pv = *ppv ;pv; lpv = pv, pv = pv->pv_next) {
+ /*
+ * if the bit being tested is the modified bit, then
+ * mark clean_map and ptes as never
+ * modified.
+ */
+ if (!pmap_track_modified(pv->pv_va))
+ continue;
+ if (!pv->pv_pmap) {
+ continue;
+ }
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
+ if (pte == NULL)
+ continue;
+ if ((int) *pte & PG_A) {
+ if (lpv) {
+ lpv->pv_next = pv->pv_next;
+ pv->pv_next = *ppv;
+ *ppv = pv;
+ }
+ splx(s);
+ return TRUE;
+ }
+ }
+ splx(s);
+ return (FALSE);
+}
+
+/*
+ * pmap_ts_referenced:
+ *
+ * Return the count of reference bits for a page, clearing all of them.
+ *
+ */
+int
+pmap_ts_referenced(vm_offset_t pa)
+{
+ register pv_entry_t *ppv, pv;
+ unsigned *pte;
+ int s;
+ int rtval = 0;
+ vm_offset_t vachanged[VATRACK];
+
+ if (!pmap_is_managed(pa))
+ return FALSE;
+
+ s = splvm();
+
+ ppv = pa_to_pvh(pa);
+
+ if (*ppv == NULL) {
+ splx(s);
+ return 0;
+ }
+
+ /*
+ * Not found, check current mappings returning immediately if found.
+ */
+ for (pv = *ppv ;pv; pv = pv->pv_next) {
+ /*
+ * if the bit being tested is the modified bit, then
+ * mark clean_map and ptes as never
+ * modified.
+ */
+ if (!pmap_track_modified(pv->pv_va))
+ continue;
+
+ if (!pv->pv_pmap) {
+ continue;
+ }
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
+ if (pte == NULL)
+ continue;
+ if (*pte & PG_A) {
+ if (rtval < VATRACK)
+ vachanged[rtval] = pv->pv_va;
+ rtval++;
+ *pte &= ~PG_A;
+ }
+ }
+ splx(s);
+ if (rtval) {
+ if (rtval <= VATRACK) {
+ int i;
+ for(i=0;i<rtval;i++)
+ pmap_update_1pg(vachanged[i]);
+ } else {
+ pmap_update();
+ }
+ }
+ return (rtval);
}
/*
@@ -2403,6 +2519,9 @@ pmap_mapdev(pa, size)
return ((void *) va);
}
+/*
+ * perform the pmap work for mincore
+ */
int
pmap_mincore(pmap, addr)
pmap_t pmap;
@@ -2417,7 +2536,7 @@ pmap_mincore(pmap, addr)
return 0;
}
- if ((pte = *ptep)) {
+ if (pte = *ptep) {
vm_offset_t pa;
val = MINCORE_INCORE;
pa = pte & PG_FRAME;
diff --git a/sys/pc98/i386/support.s b/sys/pc98/i386/support.s
index 9db2baf..3a86735 100644
--- a/sys/pc98/i386/support.s
+++ b/sys/pc98/i386/support.s
@@ -30,13 +30,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: support.s,v 1.36 1996/05/31 01:08:03 peter Exp $
+ * $Id: support.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
*/
#include "assym.s" /* system definitions */
#include "errno.h" /* error return codes */
#include "machine/asmacros.h" /* miscellaneous asm macros */
#include "machine/cputypes.h" /* types of CPUs */
+#include "machine/specialreg.h"
#define KDSEL 0x10 /* kernel data selector */
#define IDXSHIFT 10
@@ -453,6 +454,21 @@ ENTRY(copyout) /* copyout(from_kernel, to_user, len) */
/* bcopy(%esi, %edi, %ebx) */
3:
movl %ebx,%ecx
+#if defined(I586_CPU) && defined(I586_FAST_BCOPY)
+ cmpl $1024,%ecx
+ jbe slow_copyout
+
+#if defined(I386_CPU) || defined(I486_CPU) || defined(I686_CPU)
+ cmpl $CPUCLASS_586,_cpu_class
+ jne slow_copyout
+#endif /* I386_CPU || I486_CPU || I686_CPU */
+
+ call fastmove
+ jmp done_copyout
+
+ ALIGN_TEXT
+slow_copyout:
+#endif /* I586_CPU && I586_FAST_BCOPY */
shrl $2,%ecx
cld
rep
@@ -500,6 +516,21 @@ ENTRY(copyin)
cmpl $VM_MAXUSER_ADDRESS,%edx
ja copyin_fault
+#if defined(I586_CPU) && defined(I586_FAST_BCOPY)
+ cmpl $1024,%ecx
+ jbe slow_copyin
+
+#if defined(I386_CPU) || defined(I486_CPU) || defined(I686_CPU)
+ cmpl $CPUCLASS_586,_cpu_class
+ jne slow_copyin
+#endif /* I386_CPU || I486_CPU || I686_CPU */
+
+ call fastmove
+ jmp done_copyin
+
+ ALIGN_TEXT
+slow_copyin:
+#endif /* I586_CPU && I586_FAST_BCOPY */
movb %cl,%al
shrl $2,%ecx /* copy longword-wise */
cld
@@ -510,6 +541,10 @@ ENTRY(copyin)
rep
movsb
+#if defined(I586_CPU) && defined(I586_FAST_BCOPY)
+ ALIGN_TEXT
+done_copyin:
+#endif /* I586_CPU && I586_FAST_BCOPY */
popl %edi
popl %esi
xorl %eax,%eax
@@ -526,6 +561,161 @@ copyin_fault:
movl $EFAULT,%eax
ret
+#if defined(I586_CPU) && defined(I586_FAST_BCOPY)
+/* fastmove(src, dst, len)
+ src in %esi
+ dst in %edi
+ len in %ecx
+ uses %eax and %edx for tmp. storage
+ */
+ ALIGN_TEXT
+fastmove:
+ cmpl $63,%ecx
+ jbe 8f
+
+ testl $7,%esi /* check if src addr is multiple of 8 */
+ jnz 8f
+
+ testl $7,%edi /* check if dst addr is multiple of 8 */
+ jnz 8f
+
+ pushl %ebp
+ movl %esp,%ebp
+ subl $PCB_SAVEFPU_SIZE,%esp
+
+/* if (npxproc != NULL) { */
+ cmpl $0,_npxproc
+ je 6f
+/* fnsave(&curpcb->pcb_savefpu); */
+ movl _curpcb,%eax
+ fnsave PCB_SAVEFPU(%eax)
+/* npxproc = NULL; */
+ movl $0,_npxproc
+/* } */
+6:
+/* now we own the FPU. */
+
+/*
+ * The process' FP state is saved in the pcb, but if we get
+ * switched, the cpu_switch() will store our FP state in the
+ * pcb. It should be possible to avoid all the copying for
+ * this, e.g., by setting a flag to tell cpu_switch() to
+ * save the state somewhere else.
+ */
+/* tmp = curpcb->pcb_savefpu; */
+ pushl %edi
+ pushl %esi
+ pushl %ecx
+ leal -PCB_SAVEFPU_SIZE(%ebp),%edi
+ movl _curpcb,%esi
+ addl $PCB_SAVEFPU,%esi
+ cld
+ movl $PCB_SAVEFPU_SIZE>>2,%ecx
+ rep
+ movsl
+ popl %ecx
+ popl %esi
+ popl %edi
+/* stop_emulating(); */
+ clts
+/* npxproc = curproc; */
+ movl _curproc,%eax
+ movl %eax,_npxproc
+4:
+ pushl %ecx
+ cmpl $1792,%ecx
+ jbe 2f
+ movl $1792,%ecx
+2:
+ subl %ecx,0(%esp)
+ cmpl $256,%ecx
+ jb 5f
+ pushl %esi
+ pushl %ecx
+ ALIGN_TEXT
+3:
+ movl 0(%esi),%eax
+ movl 32(%esi),%eax
+ movl 64(%esi),%eax
+ movl 96(%esi),%eax
+ movl 128(%esi),%eax
+ movl 160(%esi),%eax
+ movl 192(%esi),%eax
+ movl 224(%esi),%eax
+ addl $256,%esi
+ subl $256,%ecx
+ cmpl $256,%ecx
+ jae 3b
+ popl %ecx
+ popl %esi
+5:
+ ALIGN_TEXT
+7:
+ fildq 0(%esi)
+ fildq 8(%esi)
+ fildq 16(%esi)
+ fildq 24(%esi)
+ fildq 32(%esi)
+ fildq 40(%esi)
+ fildq 48(%esi)
+ fildq 56(%esi)
+ fistpq 56(%edi)
+ fistpq 48(%edi)
+ fistpq 40(%edi)
+ fistpq 32(%edi)
+ fistpq 24(%edi)
+ fistpq 16(%edi)
+ fistpq 8(%edi)
+ fistpq 0(%edi)
+ addl $-64,%ecx
+ addl $64,%esi
+ addl $64,%edi
+ cmpl $63,%ecx
+ ja 7b
+ popl %eax
+ addl %eax,%ecx
+ cmpl $64,%ecx
+ jae 4b
+
+/* curpcb->pcb_savefpu = tmp; */
+ pushl %edi
+ pushl %esi
+ pushl %ecx
+ movl _curpcb,%edi
+ addl $PCB_SAVEFPU,%edi
+ leal -PCB_SAVEFPU_SIZE(%ebp),%esi
+ cld
+ movl $PCB_SAVEFPU_SIZE>>2,%ecx
+ rep
+ movsl
+ popl %ecx
+ popl %esi
+ popl %edi
+
+/* start_emulating(); */
+ smsw %ax
+ orb $CR0_TS,%al
+ lmsw %ax
+/* npxproc = NULL; */
+ movl $0,_npxproc
+ movl %ebp,%esp
+ popl %ebp
+
+ ALIGN_TEXT
+8:
+ movb %cl,%al
+ shrl $2,%ecx /* copy longword-wise */
+ cld
+ rep
+ movsl
+ movb %al,%cl
+ andb $3,%cl /* copy remaining bytes */
+ rep
+ movsb
+
+ ret
+#endif /* I586_CPU && I586_FAST_BCOPY */
+
/*
* fu{byte,sword,word} : fetch a byte (sword, word) from user memory
*/
diff --git a/sys/pc98/i386/trap.c b/sys/pc98/i386/trap.c
index 523fc14..29ecb2b 100644
--- a/sys/pc98/i386/trap.c
+++ b/sys/pc98/i386/trap.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.76 1996/05/18 03:36:19 dyson Exp $
+ * $Id: trap.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
*/
/*
@@ -175,19 +175,10 @@ userret(p, frame, oticks)
/*
* Charge system time if profiling.
*/
- if (p->p_flag & P_PROFIL) {
- u_quad_t ticks = p->p_sticks - oticks;
-
- 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
- }
- }
+ if (p->p_flag & P_PROFIL)
+ addupc_task(p, frame->tf_eip,
+ (u_int)(p->p_sticks - oticks) * psratio);
+
curpriority = p->p_priority;
}
@@ -255,8 +246,9 @@ trap(frame)
astoff();
cnt.v_soft++;
if (p->p_flag & P_OWEUPC) {
- addupc(frame.tf_eip, &p->p_stats->p_prof, 1);
p->p_flag &= ~P_OWEUPC;
+ addupc_task(p, p->p_stats->p_prof.pr_addr,
+ p->p_stats->p_prof.pr_ticks);
}
goto out;
@@ -325,8 +317,7 @@ trap(frame)
/* if a transparent fault (due to context switch "late") */
if (npxdna())
return;
-#endif /* NNPX > 0 */
-
+#endif
if (!pmath_emulate) {
i = SIGFPE;
ucode = FPE_FPU_NP_TRAP;
@@ -359,6 +350,18 @@ trap(frame)
#endif
return;
+ case T_DNA:
+#if NNPX > 0
+ /*
+ * The kernel is apparently using npx for copying.
+ * XXX this should be fatal unless the kernel has
+ * registered such use.
+ */
+ if (npxdna())
+ return;
+#endif
+ break;
+
case T_PROTFLT: /* general protection fault */
case T_SEGNPFLT: /* segment not present fault */
/*
@@ -672,9 +675,6 @@ trap_pfault(frame, usermode)
ftype = VM_PROT_READ;
if (map != kernel_map) {
- vm_offset_t v;
- vm_page_t mpte;
-
/*
* Keep swapout from messing with us during this
* critical time.
diff --git a/sys/pc98/i386/vm_machdep.c b/sys/pc98/i386/vm_machdep.c
index 98610a8..828191d 100644
--- a/sys/pc98/i386/vm_machdep.c
+++ b/sys/pc98/i386/vm_machdep.c
@@ -38,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.63 1996/05/18 03:36:22 dyson Exp $
+ * $Id: vm_machdep.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
*/
#include "npx.h"
@@ -235,13 +235,13 @@ more:
if( size == 0) {
splx(s);
- return NULL;
+ return 0;
}
if ((kva = kmem_alloc_pageable(io_map, size)) == 0) {
if( !waitok) {
splx(s);
- return NULL;
+ return 0;
}
bmwait = 1;
tsleep((caddr_t) io_map, PRIBIO, "bmwait", 0);
@@ -694,56 +694,31 @@ void
vmapbuf(bp)
register struct buf *bp;
{
- register int npf;
- register caddr_t addr;
- int off;
- vm_offset_t kva;
+ register caddr_t addr, v, kva;
vm_offset_t pa;
if ((bp->b_flags & B_PHYS) == 0)
panic("vmapbuf");
- /*
- * this is the kva that is to be used for
- * the temporary kernel mapping
- */
- kva = (vm_offset_t) bp->b_saveaddr;
-
- for (addr = (caddr_t)trunc_page(bp->b_data);
- addr < bp->b_data + bp->b_bufsize;
- addr += PAGE_SIZE) {
-
-/*
- * do the vm_fault if needed, do the copy-on-write thing when
- * reading stuff off device into memory.
- */
+ for (v = bp->b_saveaddr, addr = (caddr_t)trunc_page(bp->b_data);
+ addr < bp->b_data + bp->b_bufsize;
+ addr += PAGE_SIZE, v += PAGE_SIZE) {
+ /*
+ * Do the vm_fault if needed; do the copy-on-write thing
+ * when reading stuff off device into memory.
+ */
vm_fault_quick(addr,
(bp->b_flags&B_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
- pa = pmap_kextract((vm_offset_t) addr);
+ pa = trunc_page(pmap_kextract((vm_offset_t) addr));
if (pa == 0)
panic("vmapbuf: page not present");
-/*
- * hold the data page
- */
-#ifdef DIAGNOSTIC
- if( VM_PAGE_TO_PHYS(PHYS_TO_VM_PAGE(pa)) != pa)
- panic("vmapbuf: confused PHYS_TO_VM_PAGE mapping");
-#endif
vm_page_hold(PHYS_TO_VM_PAGE(pa));
+ pmap_kenter((vm_offset_t) v, pa);
}
- addr = bp->b_saveaddr = bp->b_data;
- off = (int)addr & PAGE_MASK;
- npf = btoc(round_page(bp->b_bufsize + off));
- bp->b_data = (caddr_t) (kva + off);
- while (npf--) {
- pa = pmap_kextract((vm_offset_t)addr);
- if (pa == 0)
- panic("vmapbuf: null page frame");
- pmap_kenter(kva, trunc_page(pa));
- addr += PAGE_SIZE;
- kva += PAGE_SIZE;
- }
+ kva = bp->b_saveaddr;
+ bp->b_saveaddr = bp->b_data;
+ bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK);
}
/*
@@ -760,26 +735,15 @@ vunmapbuf(bp)
if ((bp->b_flags & B_PHYS) == 0)
panic("vunmapbuf");
- for (addr = (caddr_t)trunc_page((vm_offset_t) bp->b_data);
- addr < bp->b_data + bp->b_bufsize;
- addr += PAGE_SIZE)
+ for (addr = (caddr_t)trunc_page(bp->b_data);
+ addr < bp->b_data + bp->b_bufsize;
+ addr += PAGE_SIZE) {
+ pa = trunc_page(pmap_kextract((vm_offset_t) addr));
pmap_kremove((vm_offset_t) addr);
-
- bp->b_data = bp->b_saveaddr;
- bp->b_saveaddr = NULL;
-
-/*
- * unhold the pde, and data pages
- */
- for (addr = (caddr_t)trunc_page((vm_offset_t) bp->b_data);
- addr < bp->b_data + bp->b_bufsize;
- addr += PAGE_SIZE) {
- /*
- * release the data page
- */
- pa = pmap_kextract((vm_offset_t) addr);
vm_page_unhold(PHYS_TO_VM_PAGE(pa));
}
+
+ bp->b_data = bp->b_saveaddr;
}
/*
diff --git a/sys/pc98/pc98/clock.c b/sys/pc98/pc98/clock.c
index b2befbf..071650c 100644
--- a/sys/pc98/pc98/clock.c
+++ b/sys/pc98/pc98/clock.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.58 1996/05/01 08:39:02 bde Exp $
+ * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
*/
/*
@@ -46,13 +46,14 @@
/*
* modified for PC98
- * $Id: clock.c,v 1.7 1994/03/26 22:56:13 kakefuda Exp kakefuda $
+ * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
*/
/*
* Primitive clock interrupt routines.
*/
#include "opt_ddb.h"
+#include "opt_clock.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -100,13 +101,13 @@
#define TIMER0_LATCH_COUNT 20
/*
- * Minimum maximum count that we are willing to program into timer0.
- * Must be large enough to guarantee that the timer interrupt handler
- * returns before the next timer interrupt. Must be larger than
- * TIMER0_LATCH_COUNT so that we don't have to worry about underflow in
- * the calculation of timer0_overflow_threshold.
+ * Maximum frequency that we are willing to allow for timer0. Must be
+ * low enough to guarantee that the timer interrupt handler returns
+ * before the next timer interrupt. Must result in a lower TIMER_DIV
+ * value than TIMER0_LATCH_COUNT so that we don't have to worry about
+ * underflow in the calculation of timer0_overflow_threshold.
*/
-#define TIMER0_MIN_MAX_COUNT TIMER_DIV(20000)
+#define TIMER0_MAX_FREQ 20000
int adjkerntz; /* local offset from GMT in seconds */
int disable_rtc_set; /* disable resettodr() if != 0 */
@@ -122,6 +123,23 @@ unsigned long i586_avg_tick;
#endif
int statclock_disable;
u_int stat_imask = SWI_CLOCK_MASK;
+#ifdef TIMER_FREQ
+static u_int timer_freq = TIMER_FREQ;
+#else
+#ifdef PC98
+#ifndef AUTO_CLOCK
+#ifndef PC98_8M
+static u_int timer_freq = 2457600;
+#else /* !PC98_8M */
+static u_int timer_freq = 1996800;
+#endif /* PC98_8M */
+#else /* AUTO_CLOCK */
+static u_int timer_freq = 2457600;
+#endif /* AUTO_CLOCK */
+#else /* IBM-PC */
+static u_int timer_freq = 1193182;
+#endif /* PC98 */
+#endif
int timer0_max_count;
u_int timer0_overflow_threshold;
u_int timer0_prescaler_count;
@@ -135,8 +153,6 @@ static u_int hardclock_max_count;
* timer_func currently needs to hold hardclock to handle the
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
* to switch between clkintr() and a slightly different timerintr().
- * This will require locking when acquiring and releasing timer0 - the
- * current (nonexistent) locking doesn't seem to be adequate even now.
*/
static void (*new_function) __P((struct clockframe *frame));
static u_int new_rate;
@@ -144,48 +160,32 @@ static u_int new_rate;
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
#endif
-#ifdef TIMER_FREQ
-static u_int timer_freq = TIMER_FREQ;
-#else
-#ifdef PC98
-#ifndef AUTO_CLOCK
-#ifndef PC98_8M
-static u_int timer_freq = 2457600;
-#else /* !PC98_8M */
-static u_int timer_freq = 1996800;
-#endif /* PC98_8M */
-#else /* AUTO_CLOCK */
-static u_int timer_freq = 2457600;
-#endif /* AUTO_CLOCK */
-#else /* IBM-PC */
-static u_int timer_freq = 1193182;
-#endif /* PC98 */
-#endif
-static char timer0_state = 0;
+
+/* Values for timerX_state: */
+#define RELEASED 0
+#define RELEASE_PENDING 1
+#define ACQUIRED 2
+#define ACQUIRE_PENDING 3
+
+static u_char timer0_state;
#ifdef PC98
-static char timer1_state = 0;
+static u_char timer1_state;
#endif
-static char timer2_state = 0;
+static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
int rtc_inb __P((void));
-#if 0
-void
-clkintr(struct clockframe frame)
-{
- hardclock(&frame);
- setdelayed();
-}
-#else
static void
clkintr(struct clockframe frame)
{
timer_func(&frame);
switch (timer0_state) {
- case 0:
+
+ case RELEASED:
setdelayed();
break;
- case 1:
+
+ case ACQUIRED:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
hardclock(&frame);
@@ -193,7 +193,8 @@ clkintr(struct clockframe frame)
timer0_prescaler_count -= hardclock_max_count;
}
break;
- case 2:
+
+ case ACQUIRE_PENDING:
setdelayed();
timer0_max_count = TIMER_DIV(new_rate);
timer0_overflow_threshold =
@@ -205,9 +206,10 @@ clkintr(struct clockframe frame)
enable_intr();
timer0_prescaler_count = 0;
timer_func = new_function;
- timer0_state = 1;
+ timer0_state = ACQUIRED;
break;
- case 3:
+
+ case RELEASE_PENDING:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
hardclock(&frame);
@@ -248,84 +250,140 @@ clkintr(struct clockframe frame)
}
#endif /* AUTO_CLOCK */
#else /* IBM-PC */
- time.tv_usec += (27645 *
+ time.tv_usec += (27465 *
(timer0_prescaler_count - hardclock_max_count))
>> 15;
#endif /* PC98 */
if (time.tv_usec >= 1000000)
time.tv_usec -= 1000000;
timer0_prescaler_count = 0;
- timer_func = hardclock;;
- timer0_state = 0;
+ timer_func = hardclock;
+ timer0_state = RELEASED;
}
break;
}
}
-#endif
+/*
+ * The acquire and release functions must be called at ipl >= splclock().
+ */
int
acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
{
- if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT ||
- !function)
- return -1;
+ static int old_rate;
+
+ if (rate <= 0 || rate > TIMER0_MAX_FREQ)
+ return (-1);
+ switch (timer0_state) {
+
+ case RELEASED:
+ timer0_state = ACQUIRE_PENDING;
+ break;
+
+ case RELEASE_PENDING:
+ if (rate != old_rate)
+ return (-1);
+ /*
+ * The timer has been released recently, but is being
+ * re-acquired before the release completed. In this
+ * case, we simply reclaim it as if it had not been
+ * released at all.
+ */
+ timer0_state = ACQUIRED;
+ break;
+
+ default:
+ return (-1); /* busy */
+ }
new_function = function;
- new_rate = rate;
- timer0_state = 2;
- return 0;
+ old_rate = new_rate = rate;
+ return (0);
}
#ifdef PC98
int
acquire_timer1(int mode)
{
- if (timer1_state)
- return -1;
- timer1_state = 1;
- outb(TIMER_MODE, TIMER_SEL1 | (mode &0x3f));
- return 0;
+
+ if (timer1_state != RELEASED)
+ return (-1);
+ timer1_state = ACQUIRED;
+
+ /*
+ * This access to the timer registers is as atomic as possible
+ * because it is a single instruction. We could do better if we
+ * knew the rate. Use of splclock() limits glitches to 10-100us,
+ * and this is probably good enough for timer2, so we aren't as
+ * careful with it as with timer0.
+ */
+ outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
+
+ return (0);
}
#endif
int
acquire_timer2(int mode)
{
- if (timer2_state)
- return -1;
- timer2_state = 1;
- outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
- return 0;
+
+ if (timer2_state != RELEASED)
+ return (-1);
+ timer2_state = ACQUIRED;
+
+ /*
+ * This access to the timer registers is as atomic as possible
+ * because it is a single instruction. We could do better if we
+ * knew the rate. Use of splclock() limits glitches to 10-100us,
+ * and this is probably good enough for timer2, so we aren't as
+ * careful with it as with timer0.
+ */
+ outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
+
+ return (0);
}
int
release_timer0()
{
- if (!timer0_state)
- return -1;
- timer0_state = 3;
- return 0;
+ switch (timer0_state) {
+
+ case ACQUIRED:
+ timer0_state = RELEASE_PENDING;
+ break;
+
+ case ACQUIRE_PENDING:
+ /* Nothing happened yet, release quickly. */
+ timer0_state = RELEASED;
+ break;
+
+ default:
+ return (-1);
+ }
+ return (0);
}
#ifdef PC98
int
release_timer1()
{
- if (!timer1_state)
- return -1;
- timer1_state = 0;
- outb(TIMER_MODE, TIMER_SEL1|TIMER_SQWAVE|TIMER_16BIT);
- return 0;
+
+ if (timer1_state != ACQUIRED)
+ return (-1);
+ timer1_state = RELEASED;
+ outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
+ return (0);
}
#endif
int
release_timer2()
{
- if (!timer2_state)
- return -1;
- timer2_state = 0;
- outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
- return 0;
+
+ if (timer2_state != ACQUIRED)
+ return (-1);
+ timer2_state = RELEASED;
+ outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
+ return (0);
}
#ifndef PC98
@@ -367,14 +425,19 @@ DDB_printrtc(void)
static int
getit(void)
{
+ u_long ef;
int high, low;
+ ef = read_eflags();
disable_intr();
- /* select timer0 and latch counter value */
+
+ /* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0);
+
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
- enable_intr();
+
+ write_eflags(ef);
return ((high << 8) | low);
}
@@ -459,33 +522,45 @@ sysbeepstop(void *chan)
int
sysbeep(int pitch, int period)
{
+ int x = splclock();
+
#ifdef PC98
if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
- return -1;
+ if (!beeping) {
+ /* Something else owns it. */
+ splx(x);
+ return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
+ }
disable_intr();
outb(0x3fdb, pitch);
outb(0x3fdb, (pitch>>8));
enable_intr();
if (!beeping) {
- outb(IO_PPI, (inb(IO_PPI) & 0xf7)); /* enable counter1 output to speaker */
+ /* enable counter1 output to speaker */
+ outb(IO_PPI, (inb(IO_PPI) & 0xf7));
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}
#else
-
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
- return -1;
+ if (!beeping) {
+ /* Something else owns it. */
+ splx(x);
+ return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
+ }
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 */
+ /* enable counter2 output to speaker */
+ outb(IO_PPI, inb(IO_PPI) | 3);
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}
#endif
- return 0;
+ splx(x);
+ return (0);
}
#ifndef PC98
@@ -546,7 +621,7 @@ calibrate_clocks(void)
u_int count, prev_count, tot_count;
int sec, start_sec, timeout;
- printf("Calibrating clock(s) relative to mc146818A clock ... ");
+ printf("Calibrating clock(s) relative to mc146818A clock...\n");
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
goto fail;
timeout = 100000000;
@@ -639,9 +714,10 @@ fail:
static void
set_timer_freq(u_int freq, int intr_freq)
{
- u_long ef;
+ u_long ef;
ef = read_eflags();
+ disable_intr();
timer_freq = freq;
timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
@@ -688,11 +764,7 @@ startrtclock()
#endif
#ifndef PC98
- /*
- * Temporarily calibrate with a high intr_freq to get a low
- * timer0_max_count to help detect bogus i8254 counts.
- */
- set_timer_freq(timer_freq, 20000);
+ set_timer_freq(timer_freq, hz);
freq = calibrate_clocks();
#ifdef CLK_CALIBRATION_LOOP
if (bootverbose) {
@@ -711,7 +783,8 @@ startrtclock()
delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
if (delta < timer_freq / 100) {
#ifndef CLK_USE_I8254_CALIBRATION
- printf(
+ if (bootverbose)
+ printf(
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
freq = timer_freq;
#endif
@@ -731,7 +804,8 @@ startrtclock()
#if defined(I586_CPU) || defined(I686_CPU)
#ifndef CLK_USE_I586_CALIBRATION
if (i586_ctr_rate != 0) {
- printf(
+ if (bootverbose)
+ printf(
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
i586_ctr_freq = 0;
i586_ctr_rate = 0;
@@ -750,7 +824,9 @@ startrtclock()
DELAY(1000000);
i586_count = rdtsc();
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
+#ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq);
+#endif
}
#endif
}
diff --git a/sys/pc98/pc98/diskslice_machdep.c b/sys/pc98/pc98/diskslice_machdep.c
index e8370db..aa6f48d 100644
--- a/sys/pc98/pc98/diskslice_machdep.c
+++ b/sys/pc98/pc98/diskslice_machdep.c
@@ -35,7 +35,7 @@
*
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
- * $Id: diskslice_machdep.c,v 1.20 1996/04/07 17:32:09 bde Exp $
+ * $Id: diskslice_machdep.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
*/
/*
@@ -238,14 +238,15 @@ dsinit(dname, dev, strat, lp, sspp)
sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
mbr_offset = DOSBBSECTOR;
-reread_mbr:
- /* Read master boot record. */
#ifdef PC98
+ /* Read master boot record. */
if ((int)lp->d_secsize < 1024)
bp = geteblk((int)1024);
else
bp = geteblk((int)lp->d_secsize);
#else
+reread_mbr:
+ /* Read master boot record. */
bp = geteblk((int)lp->d_secsize);
#endif
bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
diff --git a/sys/pc98/pc98/fd.c b/sys/pc98/pc98/fd.c
index 55a8354..843d469 100644
--- a/sys/pc98/pc98/fd.c
+++ b/sys/pc98/pc98/fd.c
@@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.89 1996/05/03 20:15:11 phk Exp $
+ * $Id: fd.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
*
*/
@@ -430,7 +430,7 @@ static int fdformat(dev_t, struct fd_formb *, struct proc *);
#define IOTIMEDOUT 11
#ifdef DEBUG
-char *fdstates[] =
+static char const * const fdstates[] =
{
"DEVIDLE",
"FINDWORK",
@@ -447,7 +447,7 @@ char *fdstates[] =
};
/* CAUTION: fd_debug causes huge amounts of logging output */
-int fd_debug = 0;
+static int volatile fd_debug = 0;
#define TRACE0(arg) if(fd_debug) printf(arg)
#define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2)
#else /* DEBUG */
@@ -786,7 +786,10 @@ fdattach(struct isa_device *dev)
fdcu_t fdcu = dev->id_unit;
fdc_p fdc = fdc_data + fdcu;
fd_p fd;
- int fdsu, st0, st3, i, unithasfd;
+ int fdsu, st0, st3, i;
+#if NFT > 0
+ int unithasfd;
+#endif
#ifdef PC98
struct pc98_device *fdup;
#else
diff --git a/sys/pc98/pc98/fd.c.new b/sys/pc98/pc98/fd.c.new
deleted file mode 100644
index 121cf8b..0000000
--- a/sys/pc98/pc98/fd.c.new
+++ /dev/null
@@ -1,2680 +0,0 @@
-/*
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Don Ahn.
- *
- * Copyright (c) 1993, 1994 by
- * jc@irbs.UUCP (John Capo)
- * vak@zebub.msk.su (Serge Vakulenko)
- * ache@astral.msk.su (Andrew A. Chernov)
- *
- * Copyright (c) 1993, 1994, 1995 by
- * joerg_wunsch@uriah.sax.de (Joerg Wunsch)
- * dufault@hda.com (Peter Dufault)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.87 1996/04/08 19:40:56 smpatel Exp $
- *
- */
-
-#include "ft.h"
-#if NFT < 1
-#undef NFDC
-#endif
-#include "fd.h"
-
-#if NFDC > 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <machine/clock.h>
-#include <machine/ioctl_fd.h>
-#include <sys/disklabel.h>
-#include <sys/diskslice.h>
-#include <sys/buf.h>
-#include <sys/uio.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <sys/syslog.h>
-#include <sys/devconf.h>
-#include <sys/dkstat.h>
-#ifdef PC98
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/pc98_device.h>
-#include <pc98/pc98/fdreg.h>
-#include <pc98/pc98/fdc.h>
-#include <machine/stdarg.h>
-#if NFT > 0
-#include <sys/ftape.h>
-#include <pc98/pc98/ftreg.h>
-#endif
-#else
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/fdreg.h>
-#include <i386/isa/fdc.h>
-#include <i386/isa/rtc.h>
-#include <machine/stdarg.h>
-#if NFT > 0
-#include <sys/ftape.h>
-#include <i386/isa/ftreg.h>
-#endif
-#endif
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif
-
-
-static int fd_goaway(struct kern_devconf *, int);
-static int fdc_goaway(struct kern_devconf *, int);
-static int fd_externalize(struct kern_devconf *, struct sysctl_req *);
-
-/*
- * Templates for the kern_devconf structures used when we attach.
- */
-static struct kern_devconf kdc_fd[NFD] = { {
- 0, 0, 0, /* filled in by kern_devconf.c */
- "fd", 0, { MDDT_DISK, 0 },
- fd_externalize, 0, fd_goaway, DISK_EXTERNALLEN,
- 0, /* parent */
- 0, /* parentdata */
- DC_UNCONFIGURED, /* state */
- "floppy disk",
- DC_CLS_DISK /* class */
-} };
-
-struct kern_devconf kdc_fdc[NFDC] = { {
- 0, 0, 0, /* filled in by kern_devconf.c */
-#ifdef PC98
- "fdc", 0, { MDDT_PC98, 0, "bio" },
- pc98_generic_externalize, 0, fdc_goaway, PC98_EXTERNALLEN,
-#else
- "fdc", 0, { MDDT_ISA, 0, "bio" },
- isa_generic_externalize, 0, fdc_goaway, ISA_EXTERNALLEN,
-#endif
- 0, /* parent */
- 0, /* parentdata */
- DC_UNCONFIGURED, /* state */
- "floppy disk/tape controller",
- DC_CLS_MISC /* class */
-} };
-
-static inline void
-fd_registerdev(int ctlr, int unit)
-{
- if(unit != 0)
- kdc_fd[unit] = kdc_fd[0];
-
- kdc_fd[unit].kdc_unit = unit;
- kdc_fd[unit].kdc_parent = &kdc_fdc[ctlr];
- kdc_fd[unit].kdc_parentdata = 0;
- dev_attach(&kdc_fd[unit]);
-}
-
-static inline void
-#ifdef PC98
-fdc_registerdev(struct pc98_device *dvp)
-#else
-fdc_registerdev(struct isa_device *dvp)
-#endif
-{
- int unit = dvp->id_unit;
-
- if(unit != 0)
- kdc_fdc[unit] = kdc_fdc[0];
-
- kdc_fdc[unit].kdc_unit = unit;
-#ifdef PC98
- kdc_fdc[unit].kdc_parent = &kdc_nec0;
-#else
- kdc_fdc[unit].kdc_parent = &kdc_isa0;
-#endif
- kdc_fdc[unit].kdc_parentdata = dvp;
- dev_attach(&kdc_fdc[unit]);
-}
-
-static int
-fdc_goaway(struct kern_devconf *kdc, int force)
-{
- if(force) {
- dev_detach(kdc);
- return 0;
- } else {
- return EBUSY; /* XXX fix */
- }
-}
-
-static int
-fd_goaway(struct kern_devconf *kdc, int force)
-{
- dev_detach(kdc);
- return 0;
-}
-
-#define b_cylin b_resid /* XXX now spelled b_cylinder elsewhere */
-
-/* misuse a flag to identify format operation */
-#define B_FORMAT B_XXX
-#ifdef PC98
-#define B_XXX3 0x08000000
-#define B_READID B_XXX3
-#endif
-
-/*
- * this biotab field doubles as a field for the physical unit number
- * on the controller
- */
-#define id_physid id_scsiid
-
-/* error returns for fd_cmd() */
-#define FD_FAILED -1
-#define FD_NOT_VALID -2
-#define FDC_ERRMAX 100 /* do not log more */
-
-#ifdef PC98
-#define NUMTYPES 14
-#define NUMDENS NUMTYPES
-#else
-#define NUMTYPES 14
-#define NUMDENS (NUMTYPES - 6)
-#endif
-
-/* 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 */
-#ifdef PC98
-#define FDT_NONE 0 /* none present */
-#define FDT_12M 1 /* 1M/640K FDD */
-#define FDT_144M 2 /* 1.44M/1M/640K FDD */
-
-#define FD_1200 1
-#define FD_1232 2
-#define FD_720 3
-#define FD_640 4
-#define FD_1440 5
-#define FD_997 6
-#define FD_988 7
-#define FD_250 8
-#define FD_640_256 9
-#define FD_800 10
-#define FD_360 11
-#define FD_320 12
-#define FD_320_256 13
-#define FD_400 14
-#else
-#define FD_1720 1
-#define FD_1480 2
-#define FD_1440 3
-#define FD_1200 4
-#define FD_820 5
-#define FD_800 6
-#define FD_720 7
-#define FD_360 8
-
-#define FD_1480in5_25 9
-#define FD_1440in5_25 10
-#define FD_820in5_25 11
-#define FD_800in5_25 12
-#define FD_720in5_25 13
-#define FD_360in5_25 14
-#endif
-
-
-static struct fd_type fd_types[NUMTYPES] =
-{
-#ifdef PC98
-{ 15,2,0xFF,0x1B,80,2400,1,0,2,0x54,1 }, /* 1200K in 3/5 2HD (512/sec) */
-{ 8,3,0xFF,0x35,77,1232,1,0,2,0x74,1 }, /* 1232K in 3/5/8 2HD (1024/sec) */
-{ 9,2,0xFF,0x20,80,1440,1,1,2,0x50,1 }, /* 720K in 3/5 2DD (512/sec) */
-{ 8,2,0xFF,0x2A,80,1280,1,1,2,0x50,1 }, /* 640K in 3/5 2DD (512/sec) */
-{ 18,2,0xFF,0x1B,80,2880,1,2,2,0x6C,1 }, /* 1440K in 3 2HD (512/sec) */
-{ 26,1,0xFF,0x0E,77,3991,1,0,2,0x36,1 }, /* 1M in 3/5/8 2HD (256/sec) */
-{ 26,1,0xFF,0x0E,76,3952,1,0,2,0x36,1 }, /* 1M in 3/5/8 2HD (256/sec) */
-{ 26,0,0xFF,0x07,77,2002,1,0,1,0x1B,1 }, /* 250K in 8 1S (128/sec) */
-{ 16,1,0xFF,0x0E,80,2560,1,1,2,0x36,1 }, /* 640K in 3/5 2DD (256/sec) */
-{ 5,3,0xFF,0x35,80, 800,1,1,2,0x74,1 }, /* 800K in 3/5 2DD (1024/sec) */
-{ 9,2,0xFF,0x23,40, 720,2,1,2,0x50,1 }, /* 360K in 5 2D (512/sec) */
-{ 8,2,0xFF,0x2A,40, 640,2,1,2,0x50,1 }, /* 320K in 5 2D (512/sec) */
-{ 16,1,0xFF,0x0E,40,1280,2,1,2,0x36,1 }, /* 320K in 5 2D (256/sec) */
-{ 5,3,0xFF,0x35,40, 400,2,1,2,0x74,1 }, /* 400K in 5 2D (1024/sec) */
-#else
-{ 21,2,0xFF,0x04,82,3444,1,FDC_500KBPS,2,0x0C,2 }, /* 1.72M in HD 3.5in */
-{ 18,2,0xFF,0x1B,82,2952,1,FDC_500KBPS,2,0x6C,1 }, /* 1.48M in HD 3.5in */
-{ 18,2,0xFF,0x1B,80,2880,1,FDC_500KBPS,2,0x6C,1 }, /* 1.44M in HD 3.5in */
-{ 15,2,0xFF,0x1B,80,2400,1,FDC_500KBPS,2,0x54,1 }, /* 1.2M in HD 5.25/3.5 */
-{ 10,2,0xFF,0x10,82,1640,1,FDC_250KBPS,2,0x2E,1 }, /* 820K in HD 3.5in */
-{ 10,2,0xFF,0x10,80,1600,1,FDC_250KBPS,2,0x2E,1 }, /* 800K in HD 3.5in */
-{ 9,2,0xFF,0x20,80,1440,1,FDC_250KBPS,2,0x50,1 }, /* 720K in HD 3.5in */
-{ 9,2,0xFF,0x2A,40, 720,1,FDC_250KBPS,2,0x50,1 }, /* 360K in DD 5.25in */
-
-{ 18,2,0xFF,0x02,82,2952,1,FDC_500KBPS,2,0x02,2 }, /* 1.48M in HD 5.25in */
-{ 18,2,0xFF,0x02,80,2880,1,FDC_500KBPS,2,0x02,2 }, /* 1.44M in HD 5.25in */
-{ 10,2,0xFF,0x10,82,1640,1,FDC_300KBPS,2,0x2E,1 }, /* 820K in HD 5.25in */
-{ 10,2,0xFF,0x10,80,1600,1,FDC_300KBPS,2,0x2E,1 }, /* 800K in HD 5.25in */
-{ 9,2,0xFF,0x20,80,1440,1,FDC_300KBPS,2,0x50,1 }, /* 720K in HD 5.25in */
-{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */
-#endif
-};
-
-#ifdef PC98
-#define DRVS_PER_CTLR 4 /* 4 floppies */
-#else
-#define DRVS_PER_CTLR 2 /* 2 floppies */
-#endif
-
-/***********************************************************************\
-* Per controller structure. *
-\***********************************************************************/
-struct fdc_data fdc_data[NFDC];
-
-#ifdef PC98
-struct fd_id {
- u_char cyl;
- u_char head;
- u_char sec;
- u_char secsize;
-};
-#endif
-
-/***********************************************************************\
-* Per drive structure. *
-* N per controller (DRVS_PER_CTLR) *
-\***********************************************************************/
-static struct fd_data {
- struct fdc_data *fdc; /* pointer to controller structure */
- int fdsu; /* this units number on this controller */
- 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 */
-#ifdef PC98
-#define FD_READ_ID_DONE 0x10 /* read id done */
-#endif
- int skip;
- int hddrv;
-#define FD_NO_TRACK -2
- int track; /* where we think the head is */
- int options; /* user configurable options, see ioctl_fd.h */
- int dkunit; /* disk stats unit number */
-#ifdef PC98
- struct fd_id id; /* sector id data */
-#endif
-#ifdef DEVFS
- void *bdevs[1 + NUMDENS + MAXPARTITIONS];
- void *cdevs[1 + NUMDENS + MAXPARTITIONS];
-#endif
-} fd_data[NFD];
-
-/***********************************************************************\
-* Throughout this file the following conventions will be used: *
-* fd is a pointer to the fd_data struct for the drive in question *
-* fdc is a pointer to the fdc_data struct for the controller *
-* fdu is the floppy drive unit number *
-* fdcu is the floppy controller unit number *
-* fdsu is the floppy drive unit number on that controller. (sub-unit) *
-\***********************************************************************/
-
-#if NFT > 0
-int ftopen(dev_t, int);
-int ftintr(ftu_t ftu);
-int ftclose(dev_t, int);
-void ftstrategy(struct buf *);
-int ftioctl(dev_t, int, caddr_t, int, struct proc *);
-int ftdump(dev_t);
-int ftsize(dev_t);
-#ifdef PC98
-int ftattach(struct pc98_device *, struct pc98_device *, int);
-#else
-int ftattach(struct isa_device *, struct isa_device *, int);
-#endif
-#endif
-
-/* autoconfig functions */
-#ifdef PC98
-static int fdprobe(struct pc98_device *);
-static int fdattach(struct pc98_device *);
-#else
-static int fdprobe(struct isa_device *);
-static int fdattach(struct isa_device *);
-#endif
-
-/* 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 timeout_t fd_turnoff;
-static timeout_t fd_motor_on;
-static void fd_turnon(fdu_t);
-static void fdc_reset(fdc_p);
-static int fd_in(fdcu_t, int *);
-static void fdstart(fdcu_t);
-static timeout_t fd_timeout;
-static timeout_t fd_pseudointr;
-static int fdstate(fdcu_t, fdc_p);
-static int retrier(fdcu_t);
-static int fdformat(dev_t, struct fd_formb *, struct proc *);
-
-
-#define DEVIDLE 0
-#define FINDWORK 1
-#define DOSEEK 2
-#define SEEKCOMPLETE 3
-#define IOCOMPLETE 4
-#define RECALCOMPLETE 5
-#define STARTRECAL 6
-#define RESETCTLR 7
-#define SEEKWAIT 8
-#define RECALWAIT 9
-#define MOTORWAIT 10
-#define IOTIMEDOUT 11
-
-#ifdef DEBUG
-char *fdstates[] =
-{
-"DEVIDLE",
-"FINDWORK",
-"DOSEEK",
-"SEEKCOMPLETE",
-"IOCOMPLETE",
-"RECALCOMPLETE",
-"STARTRECAL",
-"RESETCTLR",
-"SEEKWAIT",
-"RECALWAIT",
-"MOTORWAIT",
-"IOTIMEDOUT"
-};
-
-/* 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)
-#else /* DEBUG */
-#define TRACE0(arg)
-#define TRACE1(arg1, arg2)
-#endif /* DEBUG */
-
-/* autoconfig structure */
-
-#ifdef PC98
-struct pc98_driver fdcdriver = {
-#else
-struct isa_driver fdcdriver = {
-#endif
- fdprobe, fdattach, "fdc",
-};
-
-static d_open_t Fdopen; /* NOTE, not fdopen */
-static d_close_t fdclose;
-static d_ioctl_t fdioctl;
-static d_strategy_t fdstrategy;
-
-#define CDEV_MAJOR 9
-#define BDEV_MAJOR 2
-extern struct cdevsw fd_cdevsw;
-static struct bdevsw fd_bdevsw =
- { Fdopen, fdclose, fdstrategy, fdioctl, /*2*/
- nodump, nopsize, 0, "fd", &fd_cdevsw, -1 };
-
-static struct cdevsw fd_cdevsw =
- { Fdopen, fdclose, rawread, rawwrite, /*9*/
- fdioctl, nostop, nullreset, nodevtotty,
- seltrue, nommap, fdstrategy, "fd",
- &fd_bdevsw, -1 };
-
-#ifdef PC98
-static struct pc98_device *fdcdevs[NFDC];
-#else
-static struct isa_device *fdcdevs[NFDC];
-#endif
-
-/*
- * Provide hw.devconf information.
- */
-static int
-fd_externalize(struct kern_devconf *kdc, struct sysctl_req *req)
-{
- return disk_externalize(fd_data[kdc->kdc_unit].fdsu, req);
-}
-
-static int
-fdc_err(fdcu_t fdcu, const char *s)
-{
- fdc_data[fdcu].fdc_errs++;
- if(s) {
- if(fdc_data[fdcu].fdc_errs < FDC_ERRMAX)
- printf("fdc%d: %s", fdcu, s);
- else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX)
- printf("fdc%d: too many errors, not logging any more\n",
- fdcu);
- }
-
- return FD_FAILED;
-}
-
-/*
- * fd_cmd: Send a command to the chip. Takes a varargs with this structure:
- * Unit number,
- * # of output bytes, output bytes as ints ...,
- * # of input bytes, input bytes as ints ...
- */
-
-static int
-fd_cmd(fdcu_t fdcu, int n_out, ...)
-{
- u_char cmd;
- int n_in;
- int n;
- va_list ap;
-
- va_start(ap, n_out);
- cmd = (u_char)(va_arg(ap, int));
- va_end(ap);
- va_start(ap, n_out);
- for (n = 0; n < n_out; n++)
- {
- if (out_fdc(fdcu, va_arg(ap, int)) < 0)
- {
- char msg[50];
- sprintf(msg,
- "cmd %x failed at out byte %d of %d\n",
- cmd, n + 1, n_out);
- return fdc_err(fdcu, msg);
- }
- }
- n_in = va_arg(ap, int);
- for (n = 0; n < n_in; n++)
- {
- int *ptr = va_arg(ap, int *);
- if (fd_in(fdcu, ptr) < 0)
- {
- char msg[50];
- sprintf(msg,
- "cmd %02x failed at in byte %d of %d\n",
- cmd, n + 1, n_in);
- return fdc_err(fdcu, msg);
- }
- }
-
- return 0;
-}
-
-static int
-fd_sense_drive_status(fdc_p fdc, int *st3p)
-{
- int st3;
-
- if (fd_cmd(fdc->fdcu, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
- {
- return fdc_err(fdc->fdcu, "Sense Drive Status failed\n");
- }
- if (st3p)
- *st3p = st3;
-
- return 0;
-}
-
-static int
-fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
-{
- int st0, cyl;
-
- int ret = fd_cmd(fdc->fdcu, 1, NE7CMD_SENSEI, 1, &st0);
-
- if (ret)
- {
- (void)fdc_err(fdc->fdcu,
- "sense intr err reading stat reg 0\n");
- return ret;
- }
-
- if (st0p)
- *st0p = st0;
-
- if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV)
- {
- /*
- * There doesn't seem to have been an interrupt.
- */
- return FD_NOT_VALID;
- }
-
- if (fd_in(fdc->fdcu, &cyl) < 0)
- {
- return fdc_err(fdc->fdcu, "can't get cyl num\n");
- }
-
- if (cylp)
- *cylp = cyl;
-
- return 0;
-}
-
-
-static int
-fd_read_status(fdc_p fdc, int fdsu)
-{
- int i, ret;
-
- for (i = 0; i < 7; i++)
- {
- /*
- * XXX types are poorly chosen. Only bytes can by read
- * from the hardware, but fdc_status wants u_longs and
- * fd_in() gives ints.
- */
- int status;
-
- ret = fd_in(fdc->fdcu, &status);
- fdc->status[i] = status;
- if (ret != 0)
- break;
- }
-
- if (ret == 0)
- fdc->flags |= FDC_STAT_VALID;
- else
- fdc->flags &= ~FDC_STAT_VALID;
-
- return ret;
-}
-
-/****************************************************************************/
-/* autoconfiguration stuff */
-/****************************************************************************/
-#ifdef PC98
-static int pc98_trans = 0; /* 0 : HD , 1 : DD , 2 : 1.44 */
-static int pc98_trans_prev = 0;
-static int pc98_unit_type;
-
-static void set_density(fdcu_t, fdu_t);
-static int pc98_fd_check_ready(fdu_t);
-
-static void set_density(fdcu, fdu)
- fdcu_t fdcu;
- fdu_t fdu;
-{
-#if 0
- if (pc98_trans == 2 && pc98_trans_prev < 2) {
- outb(0x4be, (fdu << 5) || 0x11);
- } else if (pc98_trans < 2 && pc98_trans_prev == 2) {
- outb(0x4be, (fdu << 5) || 0x10);
- }
- DELAY(100);
-#endif
-
- /* always motor on */
- outb(IO_FDPORT, (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
- outb(fdc_data[fdcu].baseport + FDOUT, FDO_RST | FDO_DMAE);
- /* in the case of note W, always inhibit 100ms timer */
-}
-
-static int pc98_fd_check_ready(fdu)
- fdu_t fdu;
-{
- fd_p fd = fd_data + fdu;
- fdcu_t fdcu = fd->fdc->fdcu;
- int retry = 0;
-
- while (retry++ < 30000) {
- set_motor(fdcu, fd->fdsu, TURNON);
- out_fdc(fdcu, NE7CMD_SENSED); /* Sense Drive Status */
- out_fdc(fdcu, fdu); /* Drive number */
- if ((in_fdc(fdcu) & NE7_ST3_RD)){
- outb(fdc_data[fdcu].baseport + FDOUT,
- FDO_DMAE | FDO_MTON);
- return 0;
- }
- }
- return -1;
-}
-
-static int pc98_read_id( dev, type)
- dev_t dev;
- int type;
-{
- fdu_t fdu = FDUNIT(minor(dev));
- fd_p fd = &fd_data[fdu];
- struct buf *bp;
- int s;
- int rv = 0;
- int cyl = 2;
- size_t fdblk;
-
- fd->type = type;
- fd->ft = fd_types + type - 1;
- fdblk = 128 << fd->ft->secsize;
-
- if ((bp = (struct buf*)malloc(
- sizeof(struct buf), M_TEMP, M_NOWAIT)) == 0) {
- return( ENOBUFS);
- }
- bzero((void*)bp, sizeof(struct buf));
- bp->b_flags = B_BUSY | B_READ | B_READID;
- bp->b_dev = dev;
- bp->b_blkno = cyl * fd->ft->sectrac * fd->ft->heads * fdblk / DEV_BSIZE;
- bp->b_bcount = sizeof(struct fd_id);
- bp->b_un.b_addr = (caddr_t)&fd->id;
-
- fdstrategy(bp);
- s = splbio();
- while (!(bp->b_flags & B_DONE)) {
- if( (rv = tsleep( (caddr_t)bp,
- PRIBIO, "fdreadid", 4 * hz)) == EWOULDBLOCK) {
- break;
- }
- }
- splx(s);
-
- if (rv == EWOULDBLOCK) {
- rv = EIO;
- }
- if (bp->b_flags & B_ERROR) {
- rv = bp->b_error;
- }
- biodone(bp);
- free(bp, M_TEMP);
- return(rv);
-}
-#endif
-
-/*
- * probe for existance of controller
- */
-static int
-#ifdef PC98
-fdprobe(struct pc98_device *dev)
-#else
-fdprobe(struct isa_device *dev)
-#endif
-{
- fdcu_t fdcu = dev->id_unit;
- if(fdc_data[fdcu].flags & FDC_ATTACHED)
- {
- printf("fdc%d: unit used multiple times\n", fdcu);
- return 0;
- }
-
- fdcdevs[fdcu] = dev;
- fdc_data[fdcu].baseport = dev->id_iobase;
-
-#ifndef DEV_LKM
- fdc_registerdev(dev);
-#endif
-
-#ifndef PC98
- /* First - lets reset the floppy controller */
- outb(dev->id_iobase+FDOUT, 0);
- DELAY(100);
- outb(dev->id_iobase+FDOUT, FDO_FRST);
-#endif
-
- /* see if it can handle a command */
- if (fd_cmd(fdcu,
-#ifdef PC98
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
-#else
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
-#endif
- 0))
- {
- return(0);
- }
- kdc_fdc[fdcu].kdc_state = DC_IDLE;
- return (IO_FDCSIZE);
-}
-
-/*
- * wire controller into system, look for floppy units
- */
-static int
-#ifdef PC98
-fdattach(struct pc98_device *dev)
-#else
-fdattach(struct isa_device *dev)
-#endif
-{
- unsigned fdt;
- fdu_t fdu;
- fdcu_t fdcu = dev->id_unit;
- fdc_p fdc = fdc_data + fdcu;
- fd_p fd;
- int fdsu, st0, st3, i, unithasfd;
-#ifdef
- struct pc98_device *fdup;
-#else
- struct isa_device *fdup;
-#endif
- int ic_type = 0;
-#ifdef DEVFS
- int mynor;
- int typemynor;
- int typesize;
-#endif
-
- fdc->fdcu = fdcu;
- fdc->flags |= FDC_ATTACHED;
-#ifdef PC98
- fdc->dmachan = 2;
- if (fdc->dmachan != dev->id_drq) {
- dev->id_drq = fdc->dmachan;
- printf(" [dma is changed to #%d]", fdc->dmachan);
- }
- fdc->state = DEVIDLE;
- fdc_reset(fdc);
-#else
- fdc->dmachan = dev->id_drq;
- /* Acquire the DMA channel forever, The driver will do the rest */
- isa_dma_acquire(fdc->dmachan);
- isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
- fdc->state = DEVIDLE;
- /* reset controller, turn motor off, clear fdout mirror reg */
- outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
-#endif
-
- /* check for each floppy drive */
-#ifdef PC98
- for (fdup = pc98_biotab_fdc; fdup->id_driver != 0; fdup++) {
-#else
- for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) {
-#endif
- if (fdup->id_iobase != dev->id_iobase)
- continue;
- fdu = fdup->id_unit;
- fd = &fd_data[fdu];
- if (fdu >= (NFD+NFT))
- continue;
- fdsu = fdup->id_physid;
- /* look up what bios thinks we have */
- switch (fdu) {
-#ifdef PC98
- case 0:
- case 1:
- case 2:
- case 3:
- if ((PC98_SYSTEM_PARAMETER(0x5ae) >> fdu) & 0x01)
- fdt = FDT_144M;
- else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fdu) & 0x01)
- fdt = FDT_12M;
- else fdt = FDT_NONE;
- pc98_unit_type = fdt;
- break;
- default:
- fdt = FDT_NONE;
- break;
-#else
- case 0: fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
- break;
- case 1: fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
- break;
- default: fdt = RTCFDT_NONE;
- break;
-#endif
- }
- /* is there a unit? */
-#ifdef PC98
- if ((fdt == FDT_NONE)
-#else
- if ((fdt == RTCFDT_NONE)
-#endif
-#if NFT > 0
- || (fdsu >= DRVS_PER_CTLR)) {
-#else
- ) {
-#ifdef PC98
- fd->fdc = fdc;
-#endif
- fd->type = NO_TYPE;
-#endif
-#if NFT > 0
- /* If BIOS says no floppy, or > 2nd device */
- /* Probe for and attach a floppy tape. */
- /* Tell FT if there was already a disk */
- /* with this unit number found. */
-
- unithasfd = 0;
- if (fdu < NFD && fd->type != NO_TYPE)
- unithasfd = 1;
- if (ftattach(dev, fdup, unithasfd))
- continue;
- if (fdsu < DRVS_PER_CTLR)
- fd->type = NO_TYPE;
-#endif
- continue;
- }
-
-#ifdef PC98
- kdc_fdc[fdcu].kdc_description =
- "NEC 765 floppy disk/tape controller";
-#else
- /* select it */
- set_motor(fdcu, fdsu, TURNON);
- DELAY(1000000); /* 1 sec */
-
- if (ic_type == 0 &&
- fd_cmd(fdcu, 1, NE7CMD_VERSION, 1, &ic_type) == 0)
- {
- printf("fdc%d: ", fdcu);
- ic_type = (u_char)ic_type;
- switch( ic_type ) {
- case 0x80:
- printf("NEC 765\n");
- fdc->fdct = FDC_NE765;
- kdc_fdc[fdcu].kdc_description =
- "NEC 765 floppy disk/tape controller";
- break;
- case 0x81:
- printf("Intel 82077\n");
- fdc->fdct = FDC_I82077;
- kdc_fdc[fdcu].kdc_description =
- "Intel 82077 floppy disk/tape controller";
- break;
- case 0x90:
- printf("NEC 72065B\n");
- fdc->fdct = FDC_NE72065;
- kdc_fdc[fdcu].kdc_description =
- "NEC 72065B floppy disk/tape controller";
- break;
- default:
- printf("unknown IC type %02x\n", ic_type);
- fdc->fdct = FDC_UNKNOWN;
- break;
- }
- }
- if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&
- (st3 & NE7_ST3_T0)) {
- /* if at track 0, first seek inwards */
- /* seek some steps: */
- (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0);
- DELAY(300000); /* ...wait a moment... */
- (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
- }
-
- /* If we're at track 0 first seek inwards. */
- if ((fd_sense_drive_status(fdc, &st3) == 0) &&
- (st3 & NE7_ST3_T0)) {
- /* Seek some steps... */
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
- /* ...wait a moment... */
- DELAY(300000);
- /* make ctrlr happy: */
- (void)fd_sense_int(fdc, 0, 0);
- }
- }
-
- for(i = 0; i < 2; i++) {
- /*
- * we must recalibrate twice, just in case the
- * heads have been beyond cylinder 76, since most
- * FDCs still barf when attempting to recalibrate
- * more than 77 steps
- */
- /* go back to 0: */
- if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
- /* a second being enough for full stroke seek*/
- DELAY(i == 0? 1000000: 300000);
-
- /* anything responding? */
- if (fd_sense_int(fdc, &st0, 0) == 0 &&
- (st0 & NE7_ST0_EC) == 0)
- break; /* already probed succesfully */
- }
- }
-
- set_motor(fdcu, fdsu, TURNOFF);
-
- if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
- continue;
-#endif
-
- fd->track = FD_NO_TRACK;
- fd->fdc = fdc;
- fd->fdsu = fdsu;
- fd->options = 0;
- printf("fd%d: ", fdu);
-
- fd_registerdev(fdcu, fdu);
- switch (fdt) {
-#ifdef PC98
- case FDT_12M:
- printf("1M/640K FDD\n");
- fd->type = FD_1200;
- kdc_fd[fdu].kdc_description =
- "1M/640K floppy disk drive";
- break;
- case FDT_144M:
- printf("1.44M FDD\n");
- fd->type = FD_1200;
- kdc_fd[fdu].kdc_description =
- "1.44MB (1440K) 3.5in floppy disk drive";
- break;
-#else
- case RTCFDT_12M:
- printf("1.2MB 5.25in\n");
- fd->type = FD_1200;
- kdc_fd[fdu].kdc_description =
- "1.2MB (1200K) 5.25in floppy disk drive";
- break;
- case RTCFDT_144M:
- printf("1.44MB 3.5in\n");
- fd->type = FD_1440;
- kdc_fd[fdu].kdc_description =
- "1.44MB (1440K) 3.5in floppy disk drive";
- break;
- case RTCFDT_288M:
- case RTCFDT_288M_1:
- printf("2.88MB 3.5in - 1.44MB mode\n");
- fd->type = FD_1440;
- kdc_fd[fdu].kdc_description =
- "2.88MB (2880K) 3.5in floppy disk drive in 1.44 mode";
- break;
- case RTCFDT_360K:
- printf("360KB 5.25in\n");
- fd->type = FD_360;
- kdc_fd[fdu].kdc_description =
- "360KB 5.25in floppy disk drive";
- break;
- case RTCFDT_720K:
- printf("720KB 3.5in\n");
- fd->type = FD_720;
- kdc_fd[fdu].kdc_description =
- "720KB 3.5in floppy disk drive";
- break;
-#endif
- default:
- printf("unknown\n");
- fd->type = NO_TYPE;
- dev_detach(&kdc_fd[fdu]);
- continue;
- }
- kdc_fd[fdu].kdc_state = DC_IDLE;
-#ifdef DEVFS
- mynor = fdu << 6;
- fd->bdevs[0] = devfs_add_devswf(&fd_bdevsw, mynor, DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640,
- "fd%d", fdu);
- fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640,
- "rfd%d", fdu);
- for (i = 1; i < 1 + NUMDENS; i++) {
- /*
- * XXX this and the lookup in Fdopen() should be
- * data driven.
- */
- switch (fd->type) {
-#ifdef PC98
- case FD_1200:
- if (i != FD_1200)
- continue;
- break;
- case FD_1440:
- if (i != FD_1200 && i != FD_1440)
- continue;
- break;
-#else
- case FD_360:
- if (i != FD_360)
- continue;
- break;
- case FD_720:
- if (i != FD_720 && i != FD_800 && i != FD_820)
- continue;
- break;
- case FD_1200:
- if (i != FD_360 && i != FD_720 && i != FD_800
- && i != FD_820 && i != FD_1200
- && i != FD_1440 && i != FD_1480)
- continue;
- break;
- case FD_1440:
- if (i != FD_720 && i != FD_800 && i != FD_820
- && i != FD_1200 && i != FD_1440
- && i != FD_1480 && i != FD_1720)
- continue;
- break;
-#endif
- }
- typemynor = mynor | i;
- typesize = fd_types[i - 1].size / 2;
- /*
- * XXX all these conversions give bloated code and
- * confusing names.
- */
-#ifndef PC98
- if (typesize == 1476)
- typesize = 1480;
- if (typesize == 1722)
- typesize = 1720;
-#endif
- fd->bdevs[i] =
- devfs_add_devswf(&fd_bdevsw, typemynor, DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640,
- "fd%d.%d", fdu, typesize);
- fd->cdevs[i] =
- devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640,
- "rfd%d.%d", fdu, typesize);
- }
- for (i = 0; i < MAXPARTITIONS; i++) {
- fd->bdevs[1 + NUMDENS + i] =
- devfs_link(fd->bdevs[0],
- "fd%d%c", fdu, 'a' + i);
- fd->cdevs[1 + NUMDENS + i] =
- devfs_link(fd->cdevs[0],
- "rfd%d%c", fdu, 'a' + i);
- }
-#endif /* DEVFS */
- if (dk_ndrive < DK_NDRIVE) {
- sprintf(dk_names[dk_ndrive], "fd%d", fdu);
- fd->dkunit = dk_ndrive++;
- /*
- * XXX assume rate is FDC_500KBPS.
- */
- dk_wpms[dk_ndrive] = 500000 / 8 / 2;
- } else {
- fd->dkunit = -1;
- }
- }
-
- return (1);
-}
-
-#ifdef PC98
-int
-fdsize(dev_t dev)
-{
- return(0);
-}
-#endif
-
-/****************************************************************************/
-/* motor control stuff */
-/* remember to not deselect the drive we're working on */
-/****************************************************************************/
-static void
-set_motor(fdcu_t fdcu, int fdsu, int turnon)
-{
- int fdout = fdc_data[fdcu].fdout;
- int needspecify = 0;
-
-#ifdef PC98
- outb(IO_FDPORT, (pc98_trans != 1 ? FDP_FDDEXC : 0)|FDP_PORTEXC);
- fdout = FDO_DMAE|FDO_MTON;
-#else
- 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);
- }
-#endif
-
- outb(fdc_data[fdcu].baseport+FDOUT, fdout);
- fdc_data[fdcu].fdout = fdout;
-#ifndef PC98
- kdc_fdc[fdcu].kdc_state = (fdout & FDO_FRST)? DC_BUSY: DC_IDLE;
-#endif
- TRACE1("[0x%x->FDOUT]", fdout);
-
- if(needspecify) {
- /*
- * XXX
- * special case: since we have just woken up the FDC
- * from its sleep, we silently assume the command will
- * be accepted, and do not test for a timeout
- */
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
-#ifdef PC98
- NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
-#else
- NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
-#endif
- 0);
- }
-}
-
-static void
-fd_turnoff(void *arg1)
-{
- fdu_t fdu = (fdu_t)arg1;
- int s;
- fd_p fd = fd_data + fdu;
-
- TRACE1("[fd%d: turnoff]", fdu);
-
-#ifndef PC98
- /*
- * Don't turn off the motor yet if the drive is active.
- * XXX shouldn't even schedule turnoff until drive is inactive
- * and nothing is queued on it.
- */
- if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fdu) {
- timeout(fd_turnoff, arg1, 4 * hz);
- return;
- }
-#endif
-
- s = splbio();
- fd->flags &= ~FD_MOTOR;
- set_motor(fd->fdc->fdcu, fd->fdsu, TURNOFF);
- splx(s);
-}
-
-static void
-fd_motor_on(void *arg1)
-{
- fdu_t fdu = (fdu_t)arg1;
- int s;
-
- fd_p fd = fd_data + fdu;
- s = splbio();
- fd->flags &= ~FD_MOTOR_WAIT;
- if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT))
- {
- fdintr(fd->fdc->fdcu);
- }
- splx(s);
-}
-
-static void
-fd_turnon(fdu_t fdu)
-{
- fd_p fd = fd_data + fdu;
- if(!(fd->flags & FD_MOTOR))
- {
- 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
-fdc_reset(fdc_p fdc)
-{
- fdcu_t fdcu = fdc->fdcu;
-
- /* Try a reset, keep motor on */
-#ifdef PC98
- set_density(fdcu, 0);
- if (pc98_machine_type & M_EPSON_PC98)
- outb(fdc->baseport + FDOUT, 0xe8);
- else
- outb(fdc->baseport + FDOUT, 0xd8);
- DELAY(100);
- outb(fdc->baseport + FDOUT, 0x18);
-#else
- 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);
-#endif
-
- /* XXX after a reset, silently believe the FDC will accept commands */
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
-#ifdef PC98
- NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
-#else
- NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
-#endif
- 0);
-}
-
-/****************************************************************************/
-/* fdc in/out */
-/****************************************************************************/
-int
-in_fdc(fdcu_t fdcu)
-{
- int baseport = fdc_data[fdcu].baseport;
- int i, j = 100000;
- while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM))
- != (NE7_DIO|NE7_RQM) && j-- > 0)
- if (i == NE7_RQM)
- return fdc_err(fdcu, "ready for output in input\n");
- if (j <= 0)
- return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0);
-#ifdef DEBUG
- i = inb(baseport+FDDATA);
- TRACE1("[FDDATA->0x%x]", (unsigned char)i);
- return(i);
-#else
- return inb(baseport+FDDATA);
-#endif
-}
-
-/*
- * fd_in: Like in_fdc, but allows you to see if it worked.
- */
-static int
-fd_in(fdcu_t fdcu, int *ptr)
-{
- int baseport = fdc_data[fdcu].baseport;
- int i, j = 100000;
- while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM))
- != (NE7_DIO|NE7_RQM) && j-- > 0)
- if (i == NE7_RQM)
- return fdc_err(fdcu, "ready for output in input\n");
- if (j <= 0)
- return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0);
-#ifdef DEBUG
- i = inb(baseport+FDDATA);
- TRACE1("[FDDATA->0x%x]", (unsigned char)i);
- *ptr = i;
- return 0;
-#else
- i = inb(baseport+FDDATA);
- if (ptr)
- *ptr = i;
- return 0;
-#endif
-}
-
-int
-out_fdc(fdcu_t fdcu, int x)
-{
- int baseport = fdc_data[fdcu].baseport;
- int i;
-
- /* Check that the direction bit is set */
- i = 100000;
- while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0);
- if (i <= 0) return fdc_err(fdcu, "direction bit not set\n");
-
- /* Check that the floppy controller is ready for a command */
- i = 100000;
- while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0);
- if (i <= 0)
- return fdc_err(fdcu, bootverbose? "output ready timeout\n": 0);
-
- /* Send the command and return */
- outb(baseport+FDDATA, x);
- TRACE1("[0x%x->FDDATA]", x);
- return (0);
-}
-
-/****************************************************************************/
-/* fdopen/fdclose */
-/****************************************************************************/
-int
-Fdopen(dev_t dev, int flags, int mode, struct proc *p)
-{
- fdu_t fdu = FDUNIT(minor(dev));
- int type = FDTYPE(minor(dev));
- fdc_p fdc;
-
-#if NFT > 0
- /* check for a tape open */
- if (type & F_TAPE_TYPE)
- return(ftopen(dev, flags));
-#endif
- /* check bounds */
- if (fdu >= NFD)
- return(ENXIO);
- fdc = fd_data[fdu].fdc;
- if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE))
- return(ENXIO);
- if (type > NUMDENS)
- return(ENXIO);
-#ifdef PC98
- if (pc98_fd_check_ready(fdu) == -1)
- return(EIO);
-#endif
- if (type == 0)
-#ifdef PC98
- {
- struct fd_id *id = &fd_data[fdu].id;
-
- type = FD_1200;
- if (pc98_read_id(dev, FD_720) == 0) {
- if (id->secsize == 1) {
- type = (id->cyl == 1) ? FD_320_256 : FD_640_256;
- }
- else if (id->secsize == 2) {
- type = (id->cyl == 1) ? FD_360 : FD_720;
- }
- else if (id->secsize == 3) {
- type = (id->cyl == 1) ? FD_400 : FD_800;
- }
- if (id->cyl == 1) {
- fd_data[fdu].track = -2;
- }
- }
- else if (pc98_read_id(dev, FD_1200) == 0) {
- if (id->secsize == 1) {
- type = FD_997;
- }
- else if (id->secsize == 3) {
- type = FD_1232;
- }
- }
- else if (pc98_unit_type == FDT_144M
- && pc98_read_id(dev, FD_1440) == 0) {
- if (id->secsize == 2) {
- type = FD_1440;
- }
- }
- else if (pc98_read_id(dev, FD_250) == 0) {
- if (id->secsize == 0) {
- type = FD_250;
- }
- }
- }
-#else
- type = fd_data[fdu].type;
- else {
- if (type != fd_data[fdu].type) {
- switch (fd_data[fdu].type) {
- case FD_360:
- return(ENXIO);
- case FD_720:
- if ( type != FD_820
- && type != FD_800
- )
- return(ENXIO);
- break;
- case FD_1200:
- switch (type) {
- case FD_1480:
- type = FD_1480in5_25;
- break;
- case FD_1440:
- type = FD_1440in5_25;
- break;
- case FD_820:
- type = FD_820in5_25;
- break;
- case FD_800:
- type = FD_800in5_25;
- break;
- case FD_720:
- type = FD_720in5_25;
- break;
- case FD_360:
- type = FD_360in5_25;
- break;
- default:
- return(ENXIO);
- }
- break;
- case FD_1440:
- if ( type != FD_1720
- && type != FD_1480
- && type != FD_1200
- && type != FD_820
- && type != FD_800
- && type != FD_720
- )
- return(ENXIO);
- break;
- }
- }
- }
-#endif
-
-#ifdef PC98
- fd_data[fdu].type = type;
-#endif
- fd_data[fdu].ft = fd_types + type - 1;
- fd_data[fdu].flags |= FD_OPEN;
- kdc_fd[fdu].kdc_state = DC_BUSY;
-
- return 0;
-}
-
-int
-fdclose(dev_t dev, int flags, int mode, struct proc *p)
-{
- fdu_t fdu = FDUNIT(minor(dev));
-
-#if NFT > 0
- int type = FDTYPE(minor(dev));
-
- if (type & F_TAPE_TYPE)
- return ftclose(dev, flags);
-#endif
- fd_data[fdu].flags &= ~FD_OPEN;
- fd_data[fdu].options &= ~FDOPT_NORETRY;
- kdc_fd[fdu].kdc_state = DC_IDLE;
-
- 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;
-
-#if NFT > 0
- if (FDTYPE(minor(bp->b_dev)) & F_TAPE_TYPE) {
- /* ft tapes do not (yet) support strategy i/o */
- bp->b_error = ENODEV;
- 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
- fdblk = 128 << (fd->ft->secsize);
-#ifdef PC98
- if (!(bp->b_flags & (B_FORMAT | B_READID))) {
-#else
- if (!(bp->b_flags & B_FORMAT)) {
-#endif
- if ((fdu >= NFD) || (bp->b_blkno < 0)) {
- printf(
- "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n",
- fdu, (u_long)bp->b_blkno, bp->b_bcount);
- bp->b_error = EINVAL;
- bp->b_flags |= B_ERROR;
- goto bad;
- }
-#ifdef PC98
- if ((bp->b_blkno * DEV_BSIZE) % fdblk) {
- bp->b_error = EINVAL;
- bp->b_flags |= B_ERROR;
- goto bad;
- }
-#endif
- 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;
-#ifdef PC98
-#define B_XXX2 0x8000000
- if (bp->b_flags & B_XXX2) {
- blknum *= 2;
- bp->b_blkno *= 2;
- bp->b_flags &= ~B_XXX2;
- }
- if (fdblk < DEV_BSIZE) {
- nblocks -= nblocks % (DEV_BSIZE / fdblk);
- }
- if (blknum == nblocks) {
- bp->b_resid = bp->b_bcount;
- goto bad;
- }
- else if (blknum > nblocks) {
- bp->b_error = ENOSPC;
- bp->b_flags |= B_ERROR;
- goto bad;
- }
- if (fd->type == FD_997) {
- if (blknum < fd->ft->size - (fd->ft->sectrac >> 1)) {
- blknum += fd->ft->sectrac;
- }
- else {
- blknum = 0;
- }
- }
- else if (fd->type == FD_988) {
- blknum += fd->ft->sectrac * fd->ft->heads;
- }
-#else
- 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;
- }
-#endif
- bp->b_cylin = blknum / (fd->ft->sectrac * fd->ft->heads);
- bp->b_pblkno = bp->b_blkno;
- 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);
-}
-
-/***************************************************************\
-* fdstart *
-* We have just queued something.. if the controller is not busy *
-* then simulate the case where it has just finished a command *
-* So that it (the interrupt routine) looks on the queue for more*
-* work to do and picks up what we just added. *
-* If the controller is already busy, we need do nothing, as it *
-* will pick up our work when the present work completes *
-\***************************************************************/
-static void
-fdstart(fdcu_t fdcu)
-{
- int s;
-
- s = splbio();
- if(fdc_data[fdcu].state == DEVIDLE)
- {
- fdintr(fdcu);
- }
- splx(s);
-}
-
-static void
-fd_timeout(void *arg1)
-{
- fdcu_t fdcu = (fdcu_t)arg1;
- fdu_t fdu = fdc_data[fdcu].fdu;
- int baseport = fdc_data[fdcu].baseport;
- struct buf *dp, *bp;
- int s;
-
- dp = &fdc_data[fdcu].head;
- bp = dp->b_actf;
-
- /*
- * 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] = NE7_ST0_IC_RC;
- fdc_data[fdcu].state = IOTIMEDOUT;
- if( fdc_data[fdcu].retry < 6)
- fdc_data[fdcu].retry = 6;
- }
- else
- {
- fdc_data[fdcu].fd = (fd_p) 0;
- fdc_data[fdcu].fdu = -1;
- fdc_data[fdcu].state = DEVIDLE;
- }
- fdintr(fdcu);
- splx(s);
-}
-
-/* just ensure it has the right spl */
-static void
-fd_pseudointr(void *arg1)
-{
- fdcu_t fdcu = (fdcu_t)arg1;
- int s;
-
- s = splbio();
- fdintr(fdcu);
- splx(s);
-}
-
-/***********************************************************************\
-* fdintr *
-* keep calling the state machine until it returns a 0 *
-* ALWAYS called at SPLBIO *
-\***********************************************************************/
-void
-fdintr(fdcu_t fdcu)
-{
- fdc_p fdc = fdc_data + fdcu;
-#if NFT > 0
- fdu_t fdu = fdc->fdu;
-
- if (fdc->flags & FDC_TAPE_BUSY)
- (ftintr(fdu));
- else
-#endif
- while(fdstate(fdcu, fdc))
- ;
-}
-
-/***********************************************************************\
-* The controller state machine. *
-* if it returns a non zero value, it should be called again immediatly *
-\***********************************************************************/
-static int
-fdstate(fdcu_t fdcu, fdc_p fdc)
-{
- int read, format, head, sec = 0, sectrac, st0, cyl, st3;
- unsigned long blknum;
- fdu_t fdu = fdc->fdu;
- fd_p fd;
- register struct buf *dp, *bp;
- struct fd_formb *finfo = NULL;
- size_t fdblk;
-#ifdef PC98
- int readid;
- struct fd_id *id = NULL;
-#endif
-
- dp = &(fdc->head);
- bp = dp->b_actf;
- if(!bp)
- {
- /***********************************************\
- * nothing left for this controller to do *
- * Force into the IDLE state, *
- \***********************************************/
- fdc->state = DEVIDLE;
- if(fdc->fd)
- {
- printf("fd%d: unexpected valid fd pointer\n",
- fdc->fdu);
- fdc->fd = (fd_p) 0;
- fdc->fdu = -1;
- }
- TRACE1("[fdc%d IDLE]", fdcu);
- return(0);
- }
- fdu = FDUNIT(minor(bp->b_dev));
- fd = fd_data + fdu;
-#ifdef PC98
- sectrac = fd->ft->sectrac;
- if (readid = bp->b_flags & B_READID) {
- id = (struct fd_id*)bp->b_un.b_addr;
- }
-#endif
- fdblk = 128 << fd->ft->secsize;
- if (fdc->fd && (fd != fdc->fd))
- {
- printf("fd%d: confused fd pointers\n", fdu);
- }
- read = bp->b_flags & B_READ;
- 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);
- untimeout(fd_turnoff, (caddr_t)fdu);
- timeout(fd_turnoff, (caddr_t)fdu, 4 * hz);
- switch (fdc->state)
- {
- case DEVIDLE:
- case FINDWORK: /* we have found new work */
- fdc->retry = 0;
- fd->skip = 0;
- fdc->fd = fd;
- fdc->fdu = fdu;
-#ifdef PC98
- pc98_trans = fd->ft->trans;
- if (pc98_trans_prev != pc98_trans) {
- int i;
- set_density(fdcu, fdu);
- for (i = 0; i < 10; i++) {
- outb(0x5f, 0);
- }
- pc98_trans_prev = pc98_trans;
- }
-#else
- outb(fdc->baseport+FDCTL, fd->ft->trans);
-#endif
- 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 *
- \*******************************************************/
- if(fd->flags & FD_MOTOR_WAIT)
- {
- fdc->state = MOTORWAIT;
- return(0); /* come back later */
- }
- /*******************************************************\
- * Maybe if it's not starting, it SHOULD be starting *
- \*******************************************************/
- if (!(fd->flags & FD_MOTOR))
- {
- fdc->state = MOTORWAIT;
- fd_turnon(fdu);
- return(0);
- }
- else /* at least make sure we are selected */
- {
- set_motor(fdcu, fd->fdsu, TURNON);
- }
- fdc->state = DOSEEK;
- break;
- case DOSEEK:
- if (bp->b_cylin == fd->track)
- {
- fdc->state = SEEKCOMPLETE;
- break;
- }
-#ifdef PC98
- pc98_fd_check_ready(fdu);
-#endif
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK,
- fd->fdsu, bp->b_cylin * fd->ft->steptrac,
- 0))
- {
- /*
- * seek command not accepted, looks like
- * the FDC went off to the Saints...
- */
- fdc->retry = 6; /* try a reset */
- return(retrier(fdcu));
- }
- fd->track = FD_NO_TRACK;
- fdc->state = SEEKWAIT;
- return(0); /* will return later */
- case SEEKWAIT:
- /* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, hz / 16);
- fdc->state = SEEKCOMPLETE;
- return(0); /* will return later */
- case SEEKCOMPLETE : /* SEEK DONE, START DMA */
- /* Make sure seek really happened*/
- if(fd->track == FD_NO_TRACK)
- {
- int descyl = bp->b_cylin * fd->ft->steptrac;
- do {
- /*
- * This might be a "ready changed" interrupt,
- * which cannot really happen since the
- * RDY pin is hardwired to + 5 volts. This
- * generally indicates a "bouncing" intr
- * line, so do one of the following:
- *
- * When running on an enhanced FDC that is
- * known to not go stuck after responding
- * with INVALID, fetch all interrupt states
- * until seeing either an INVALID or a
- * real interrupt condition.
- *
- * When running on a dumb old NE765, give
- * up immediately. The controller will
- * provide up to four dummy RC interrupt
- * conditions right after reset (for the
- * corresponding four drives), so this is
- * our only chance to get notice that it
- * was not the FDC that caused the interrupt.
- */
- if (fd_sense_int(fdc, &st0, &cyl)
- == FD_NOT_VALID)
- return 0;
- if(fdc->fdct == FDC_NE765
- && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
- return 0; /* hope for a real intr */
- } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
-
- if (0 == descyl)
- {
- int failed = 0;
- /*
- * seek to cyl 0 requested; make sure we are
- * really there
- */
- if (fd_sense_drive_status(fdc, &st3))
- failed = 1;
- if ((st3 & NE7_ST3_T0) == 0) {
- printf(
- "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n",
- fdu, st3, NE7_ST3BITS);
- failed = 1;
- }
-
- if (failed)
- {
- 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, st0);
- return(retrier(fdcu));
- }
- }
-
- fd->track = bp->b_cylin;
-#ifdef PC98
- blknum = (unsigned long)bp->b_blkno * DEV_BSIZE + fd->skip;
- if (fd->type == FD_997) {
- long size = fdblk * (fd->ft->size - (sectrac >> 1));
-
- if (blknum < size) {
- blknum /= fdblk;
- blknum += sectrac;
- }
- else {
- blknum -= size;
- blknum /= (fdblk >>= 1);
- }
- }
- else if (fd->type == FD_988) {
- blknum /= fdblk;
- blknum += sectrac * fd->ft->heads;
- }
- else {
- blknum /= fdblk;
- }
-#endif
- if(format)
- fd->skip = (char *)&(finfo->fd_formb_cylno(0))
- - (char *)finfo;
-#ifdef PC98
- if (!readid)
- pc98_dmastart(bp->b_flags, bp->b_un.b_addr+fd->skip,
-#else
- isa_dmastart(bp->b_flags, bp->b_un.b_addr+fd->skip,
-#endif
- format ? bp->b_bcount : fdblk, fdc->dmachan);
-#ifndef PC98
- blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/fdblk
- + fd->skip/fdblk;
- sectrac = fd->ft->sectrac;
-#endif
- sec = blknum % (sectrac * fd->ft->heads);
- head = sec / sectrac;
- sec = sec % sectrac + 1;
- fd->hddrv = ((head&1)<<2)+fdu;
-
- if(format || !read)
- {
- /* make sure the drive is writable */
- if(fd_sense_drive_status(fdc, &st3) != 0)
- {
- /* stuck controller? */
- fdc->retry = 6; /* reset the beast */
- return(retrier(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 */
-#ifdef PC98
- int mask = ~0; /* MFM mode */
- int gaplen = finfo->fd_formb_gaplen;
-
- if (fd->type == FD_997 && blknum < sectrac) {
- gaplen = fd_types[FD_250-1].f_gap;
- mask = ~0x40; /* FM mode */
- }
- else if (fd->ft->heads == 1) {
- mask = ~0x40; /* FM mode */
- }
- if(fd_cmd(fdcu, 6,
- NE7CMD_FORMAT & mask,
- head << 2 | fdu,
- finfo->fd_formb_secshift,
- finfo->fd_formb_nsecs,
- gaplen,
- finfo->fd_formb_fillbyte,
- 0))
-#else
- if(fd_cmd(fdcu, 6,
- NE7CMD_FORMAT,
- head << 2 | fdu,
- finfo->fd_formb_secshift,
- finfo->fd_formb_nsecs,
- finfo->fd_formb_gaplen,
- finfo->fd_formb_fillbyte,
- 0))
-#endif
- {
- /* controller fell over */
- fdc->retry = 6;
- return(retrier(fdcu));
- }
- }
-#ifdef PC98
- else if (readid) {
- int mask = ~0; /* MFM mode */
-
- if( fd->ft->heads == 1) {
- mask = ~0x40; /* FM mode */
- }
- if( out_fdc( fdcu, NE7CMD_READID & mask) < 0) {
- bp->b_flags |= B_ERROR;
- bp->b_error = EIO;
- bp->b_resid = bp->b_bcount;
- dp->b_actf = bp->b_actf;
- biodone( bp);
- fdc->state = FINDWORK;
- fdc->fd = (fd_p)0;
- fdc->fdu = -1;
- return( 1);
- }
- out_fdc( fdcu, head << 2 | fdu);
- }
-#endif
- else
- {
-#ifdef PC98
- int mask = ~0; /* MFM mode */
- struct fd_type *ft = fd->ft;
-
- if (fd->type == FD_997 && blknum < sectrac) {
- ft = fd_types + FD_250 - 1;
- }
- if (ft->heads == 1) {
- mask = ~0x40; /* FM mode */
- }
- if ((read && out_fdc(fdcu, NE7CMD_READ & mask) < 0)
- || (!read /* i.e., write */
- && out_fdc(fdcu, NE7CMD_WRITE & mask) < 0))
- if (fd_cmd(fdcu, 9,
- (read ? NE7CMD_READ &mask :
- NE7CMD_WRITE & mask),
- head << 2 | fdu, /* head & unit */
- fd->track, /* track */
- head,
- sec, /* sector + 1 */
- ft->secsize, /* sector size */
- sectrac, /* sectors/track */
- ft->gap, /* gap size */
- ft->datalen, /* data length */
- 0))
-#else
- if (fd_cmd(fdcu, 9,
- (read ? NE7CMD_READ : NE7CMD_WRITE),
- head << 2 | fdu, /* head & unit */
- fd->track, /* track */
- head,
- sec, /* sector + 1 */
- fd->ft->secsize, /* sector size */
- sectrac, /* sectors/track */
- fd->ft->gap, /* gap size */
- fd->ft->datalen, /* data length */
- 0))
-#endif
- {
- /* the beast is sleeping again */
- fdc->retry = 6;
- return(retrier(fdcu));
- }
- }
- fdc->state = IOCOMPLETE;
- timeout(fd_timeout, (caddr_t)fdcu, hz);
- return(0); /* will return later */
- case IOCOMPLETE: /* IO DONE, post-analyze */
- untimeout(fd_timeout, (caddr_t)fdcu);
-
- if (fd_read_status(fdc, fd->fdsu))
- {
- if (fdc->retry < 6)
- fdc->retry = 6; /* force a reset */
- return retrier(fdcu);
- }
-
-#ifdef PC98
- if (readid) {
- id->cyl = fdc->status[3];
- id->head = fdc->status[4];
- id->sec = fdc->status[5];
- id->secsize = fdc->status[6];
- }
-#endif
- fdc->state = IOTIMEDOUT;
-
- /* FALLTHROUGH */
-
- case IOTIMEDOUT:
-#ifdef PC98
- blknum = (unsigned long)bp->b_blkno * DEV_BSIZE + fd->skip;
- if (fd->type == FD_997 && blknum
- >= fdblk * (fd->ft->size - (sectrac >> 1))) {
- fdblk >>= 1;
- }
- if (!readid)
- pc98_dmadone(bp->b_flags, bp->b_un.b_addr+fd->skip,
-#else
- isa_dmadone(bp->b_flags, bp->b_un.b_addr+fd->skip,
-#endif
- format ? bp->b_bcount : fdblk, fdc->dmachan);
-#ifdef PC98
- if (!readid && fdc->status[0] & NE7_ST0_IC)
-#else
- if (fdc->status[0] & NE7_ST0_IC)
-#endif
- {
- if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
- && fdc->status[1] & NE7_ST1_OR) {
- /*
- * 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;
-#ifdef PC98
- fdblk = 128 << fd->ft->secsize;
- blknum = (unsigned long)bp->b_blkno * DEV_BSIZE + fd->skip;
- if (!(format | readid) && fd->skip < bp->b_bcount
- && blknum < fdblk * fd->ft->size) {
- if (fd->type == FD_997) {
- long size = fdblk *
- (fd->ft->size - (sectrac >> 1));
-
- if (blknum < size) {
- blknum /= fdblk;
- blknum += sectrac;
- }
- else {
- blknum -= size;
- blknum /= (fdblk >>= 1);
- }
- }
- else if (fd->type == FD_988) {
- blknum /= fdblk;
- blknum += sectrac * fd->ft->heads;
- }
- else {
- blknum /= fdblk;
- }
-#else
- if (!format && fd->skip < bp->b_bcount)
- {
- /* set up next transfer */
- blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/fdblk
- + fd->skip/fdblk;
-#endif
- bp->b_cylin =
- (blknum / (fd->ft->sectrac * fd->ft->heads));
- fdc->state = DOSEEK;
- }
- else
- {
- /* ALL DONE */
-#ifdef PC98
- if (readid) {
- if (fdc->status[0] & NE7_ST0_IC) {
- bp->b_flags |= B_ERROR;
- bp->b_error = EIO;
- bp->b_resid = bp->b_bcount;
- }
- else {
- bp->b_resid = 0;
- }
- }
- if (format) {
- bp->b_resid = 0;
- }
- else {
- bp->b_resid = bp->b_bcount - fd->skip;
- }
- fd->skip = 0;
- if (readid) {
- fd->flags |= FD_READ_ID_DONE;
- fdc->state = STARTRECAL;
- }
- else {
- dp->b_actf = bp->b_actf;
- biodone(bp);
- fdc->fd = (fd_p) 0;
- fdc->fdu = -1;
- fdc->state = FINDWORK;
- }
-#else
- fd->skip = 0;
- bp->b_resid = 0;
- dp->b_actf = bp->b_actf;
- biodone(bp);
- fdc->fd = (fd_p) 0;
- fdc->fdu = -1;
- fdc->state = FINDWORK;
-#endif
- }
- return(1);
- case RESETCTLR:
- fdc_reset(fdc);
- fdc->retry++;
- fdc->state = STARTRECAL;
- break;
- case STARTRECAL:
- /* XXX clear the fdc results from the last reset, if any. */
- {
- int i;
- for (i = 0; i < 4; i++)
- (void)fd_sense_int(fdc, &st0, &cyl);
- }
-
-#ifdef PC98
- pc98_fd_check_ready(fdu);
-#endif
- if(fd_cmd(fdcu,
- 2, NE7CMD_RECAL, fdu,
- 0)) /* Recalibrate Function */
- {
- /* arrgl */
- fdc->retry = 6;
- return(retrier(fdcu));
- }
- fdc->state = RECALWAIT;
- return(0); /* will return later */
- case RECALWAIT:
- /* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, hz / 8);
- fdc->state = RECALCOMPLETE;
- return(0); /* will return later */
- case RECALCOMPLETE:
- do {
- /*
- * See SEEKCOMPLETE for a comment on this:
- */
- if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
- return 0;
- if(fdc->fdct == FDC_NE765
- && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
- return 0; /* hope for a real intr */
- } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
- if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0)
- {
- if(fdc->retry > 3)
- /*
- * a recalibrate from beyond cylinder 77
- * will "fail" due to the FDC limitations;
- * since people used to complain much about
- * the failure message, try not logging
- * this one if it seems to be the first
- * time in a line
- */
- 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 */
-#ifdef PC98
- if (readid && fd->flags & FD_READ_ID_DONE) {
- fd->flags &= ~FD_READ_ID_DONE;
- dp->b_actf = bp->b_actf;
- biodone(bp);
- fdc->fd = (fd_p)0;
- fdc->fdu = -1;
- fdc->state = FINDWORK;
- }
- else {
- fdc->state = DOSEEK;
- }
-#else
- fdc->state = DOSEEK;
-#endif
- return(1); /* will return immediatly */
- case MOTORWAIT:
- if(fd->flags & FD_MOTOR_WAIT)
- {
- return(0); /* time's not up yet */
- }
- /*
- * 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("fdc%d: Unexpected FD int->", fdcu);
- if (fd_read_status(fdc, fd->fdsu) == 0)
- printf("FDC 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] );
- else
- printf("No status available ");
- if (fd_sense_int(fdc, &st0, &cyl) != 0)
- {
- printf("[controller is dead now]\n");
- return(0);
- }
- printf("ST0 = %x, PCN = %x\n", st0, cyl);
- return(0);
- }
- /*XXX confusing: some branches return immediately, others end up here*/
- return(1); /* Come back immediatly to new state */
-}
-
-static int
-retrier(fdcu)
- fdcu_t fdcu;
-{
- fdc_p fdc = fdc_data + fdcu;
- 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:
- fdc->state = SEEKCOMPLETE;
- break;
- case 3: case 4: case 5:
- fdc->state = STARTRECAL;
- break;
- case 6:
- fdc->state = RESETCTLR;
- break;
- 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)|RAW_PART);
- diskerr(bp, "fd", "hard error", LOG_PRINTF,
- fdc->fd->skip / DEV_BSIZE,
- (struct disklabel *)NULL);
- bp->b_dev = sav_b_dev;
- if (fdc->flags & FDC_STAT_VALID)
- {
- printf(
- " (ST0 %b ST1 %b ST2 %b cyl %ld hd %ld sec %ld)\n",
- fdc->status[0], NE7_ST0BITS,
- fdc->status[1], NE7_ST1BITS,
- fdc->status[2], NE7_ST2BITS,
- fdc->status[3], fdc->status[4],
- fdc->status[5]);
- }
- else
- printf(" (No status)\n");
- }
- bp->b_flags |= B_ERROR;
- bp->b_error = EIO;
- bp->b_resid = bp->b_bcount - fdc->fd->skip;
- dp->b_actf = bp->b_actf;
- fdc->fd->skip = 0;
- biodone(bp);
- fdc->state = FINDWORK;
- fdc->fd = (fd_p) 0;
- fdc->fdu = -1;
- /* XXX abort current command, if any. */
- return(1);
- }
- fdc->retry++;
- return(1);
-}
-
-static int
-fdformat(dev, finfo, p)
- dev_t dev;
- struct fd_formb *finfo;
- struct proc *p;
-{
- fdu_t fdu;
- fd_p fd;
-
- struct buf *bp;
- int rv = 0, s;
- size_t fdblk;
-#ifdef PC98
- int cyl, head;
-#endif
-
- 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);
- if(bp == 0)
- return ENOBUFS;
- /*
- * keep the process from being swapped
- */
- p->p_flag |= P_PHYSIO;
- bzero((void *)bp, sizeof(struct buf));
- bp->b_flags = B_BUSY | B_PHYS | B_FORMAT;
- bp->b_proc = p;
- bp->b_dev = dev;
-
- /*
- * calculate a fake blkno, so fdstrategy() would initiate a
- * seek to the requested cylinder
- */
-#ifdef PC98
- cyl = finfo->cyl;
- head = finfo->head;
- if (fd->type == FD_997) {
- if (cyl == 0 && head == 0) {
- cyl = fd->ft->tracks - 1;
- head++;
- }
- else {
- int track = cyl * fd->ft->heads + head - 1;
-
- cyl = track / fd->ft->heads;
- head = track % fd->ft->heads;
- }
- }
- else if (fd->type == FD_988 && cyl > 0) {
- cyl--;
- }
- bp->b_blkno = ((cyl * fd->ft->sectrac * fd->ft->heads
- + head * fd->ft->sectrac) * fdblk - 1) / DEV_BSIZE + 1;
-#else
- bp->b_blkno = (finfo->cyl * (fd->ft->sectrac * fd->ft->heads)
- + finfo->head * fd->ft->sectrac) * fdblk / DEV_BSIZE;
-#endif
-
- bp->b_bcount = sizeof(struct fd_idfield_data) * finfo->fd_formb_nsecs;
- bp->b_un.b_addr = (caddr_t)finfo;
-
- /* now do the format */
- fdstrategy(bp);
-
- /* ...and wait for it to complete */
- s = splbio();
- while(!(bp->b_flags & B_DONE))
- {
- rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz);
- if(rv == EWOULDBLOCK)
- break;
- }
- splx(s);
-
- if(rv == EWOULDBLOCK) {
- /* timed out */
- rv = EIO;
- biodone(bp);
- }
- if(bp->b_flags & B_ERROR)
- rv = bp->b_error;
- /*
- * allow the process to be swapped
- */
- p->p_flag &= ~P_PHYSIO;
- free(bp, M_TEMP);
- return rv;
-}
-
-/*
- * TODO: don't allocate buffer on stack.
- */
-
-int
-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 = 0;
-
-#if NFT > 0
- int type = FDTYPE(minor(dev));
-
- /* check for a tape ioctl */
- if (type & F_TAPE_TYPE)
- return ftioctl(dev, cmd, addr, flag, p);
-#endif
-
- fdblk = 128 << fd->ft->secsize;
-#ifdef PC98
- pc98_fd_check_ready(fdu);
-#endif
-
- switch (cmd)
- {
- case DIOCGDINFO:
- bzero(buffer, sizeof (buffer));
- dl = (struct disklabel *)buffer;
- dl->d_secsize = fdblk;
- fdt = fd_data[FDUNIT(minor(dev))].ft;
-#ifdef PC98
- dl->d_secpercyl = fdt->size;
- if (fd_data[FDUNIT(minor(dev))].type == FD_997) {
- dl->d_secpercyl += (fdt->sectrac >> 1);
- }
- dl->d_secpercyl /= fdt->tracks;
-#else
- dl->d_secpercyl = fdt->size / fdt->tracks;
-#endif
- dl->d_type = DTYPE_FLOPPY;
-
- if (readdisklabel(dkmodpart(dev, RAW_PART), fdstrategy, dl)
- == NULL)
- error = 0;
- else
- error = EINVAL;
-
- *(struct disklabel *)addr = *dl;
- break;
-
- case DIOCSDINFO:
- if ((flag & FWRITE) == 0)
- error = EBADF;
- break;
-
- case DIOCWLABEL:
- if ((flag & FWRITE) == 0)
- error = EBADF;
- break;
-
- case DIOCWDINFO:
- if ((flag & FWRITE) == 0)
- {
- error = EBADF;
- break;
- }
-
- dl = (struct disklabel *)addr;
-
- if ((error = setdisklabel((struct disklabel *)buffer, dl,
- (u_long)0)) != 0)
- break;
-
- error = writedisklabel(dev, fdstrategy,
- (struct disklabel *)buffer);
- break;
-
- case FD_FORM:
- if((flag & FWRITE) == 0)
- error = EBADF; /* must be opened for writing */
- else if(((struct fd_formb *)addr)->format_version !=
- FD_FORMAT_VERSION)
- error = EINVAL; /* wrong version of formatting prog */
- else
- error = fdformat(dev, (struct fd_formb *)addr, p);
- break;
-
- case FD_GTYPE: /* get drive type */
- *(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 = ENOTTY;
- break;
- }
- return (error);
-}
-
-
-static fd_devsw_installed = 0;
-
-static void fd_drvinit(void *notused )
-{
- dev_t dev;
-
- if( ! fd_devsw_installed ) {
- dev = makedev(CDEV_MAJOR, 0);
- cdevsw_add(&dev,&fd_cdevsw, NULL);
- dev = makedev(BDEV_MAJOR, 0);
- bdevsw_add(&dev,&fd_bdevsw, NULL);
- fd_devsw_installed = 1;
- }
-}
-
-SYSINIT(fddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,fd_drvinit,NULL)
-
-#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/pc98/pc98/ft.c b/sys/pc98/pc98/ft.c
index 61d4723..e030e9c 100644
--- a/sys/pc98/pc98/ft.c
+++ b/sys/pc98/pc98/ft.c
@@ -17,7 +17,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*
* ft.c - QIC-40/80 floppy tape driver
- * $Id: ft.c,v 1.25 1995/12/15 00:53:58 bde Exp $
+ * $Id: ft.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
*
* 01/19/95 ++sg
* Cleaned up recalibrate/seek code at attach time for FreeBSD 2.x.
@@ -86,13 +86,11 @@
#include <pc98/pc98/pc98_device.h>
#include <pc98/pc98/fdreg.h>
#include <pc98/pc98/fdc.h>
-#include <pc98/pc98/icu.h>
#include <pc98/pc98/ftreg.h>
#else
#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>
#include <i386/isa/ftreg.h>
#endif
diff --git a/sys/pc98/pc98/ic/mb86960.h b/sys/pc98/pc98/ic/mb86960.h
index c87101c..d1f6f64 100644
--- a/sys/pc98/pc98/ic/mb86960.h
+++ b/sys/pc98/pc98/ic/mb86960.h
@@ -44,57 +44,6 @@
* documents..
*/
-/*
- * Modified for Allied-Telesis RE1000 series.
- */
-
-#ifdef PC98
-/* Data Link Control Registrs, on invaliant port addresses. */
-#define FE_DLCR0 0
-#define FE_DLCR1 1
-#define FE_DLCR2 0x200
-#define FE_DLCR3 0x201
-#define FE_DLCR4 0x400
-#define FE_DLCR5 0x401
-#define FE_DLCR6 0x600
-#define FE_DLCR7 0x601
-
-/* More DLCRs, on register bank #0. */
-#define FE_DLCR8 0x800
-#define FE_DLCR9 0x801
-#define FE_DLCR10 0xA00
-#define FE_DLCR11 0xA01
-#define FE_DLCR12 0xC00
-#define FE_DLCR13 0xC01
-#define FE_DLCR14 0xE00
-#define FE_DLCR15 0xE01
-
-/* Malticast Address Registers. On register bank #1. */
-#define FE_MAR8 0x800
-#define FE_MAR9 0x801
-#define FE_MAR10 0xA00
-#define FE_MAR11 0xA01
-#define FE_MAR12 0xC00
-#define FE_MAR13 0xC01
-#define FE_MAR14 0xE00
-#define FE_MAR15 0xE01
-
-/* Buffer Memory Port Registers. On register back #2. */
-#define FE_BMPR8 0x800
-#define FE_BMPR9 0x801
-#define FE_BMPR10 0xA00
-#define FE_BMPR11 0xA01
-#define FE_BMPR12 0xC00
-#define FE_BMPR13 0xC01
-#define FE_BMPR14 0xE00
-#define FE_BMPR15 0xE01
-
-/* More BMPRs, only on MB86965A, accessible only when JLI mode. */
-#define FE_BMPR16 0x1000
-#define FE_BMPR17 0x1001
-#define FE_BMPR18 0x1200
-#define FE_BMPR19 0x1201
-#else /* not PC98 */
/* Data Link Control Registrs, on invaliant port addresses. */
#define FE_DLCR0 0
#define FE_DLCR1 1
@@ -140,7 +89,6 @@
#define FE_BMPR17 17
#define FE_BMPR18 18
#define FE_BMPR19 19
-#endif /* PC98 */
/*
* Definitions of registers.
diff --git a/sys/pc98/pc98/if_ed.c b/sys/pc98/pc98/if_ed.c
index 40b9169..adf3c4d 100644
--- a/sys/pc98/pc98/if_ed.c
+++ b/sys/pc98/pc98/if_ed.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_ed.c,v 1.99 1996/05/27 22:32:23 gpalmer Exp $
+ * $Id: if_ed.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
*/
/*
@@ -38,8 +38,16 @@
*/
/*
- * FreeBSD(98) supports the LGY-98 series, EGY-98 series, LGH-98 series,
- * IF_2766ET, AD-ET2-T, SIC-98 series, LD-BDN and LPC-T.
+ * FreeBSD(98) supports:
+ * Allied Telesis CenterCom LA-98-T, SIC-98
+ * D-Link DE-298P, DE-298
+ * ELECOM LANEED LD-BDN
+ * ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF_2711ET
+ * IO-DATA PCLA/T, LA/T-98
+ * MACNICA NE2098
+ * NEC PC-9801-108
+ * MELCO LPC-TJ, LPC-TS, LGY-98, LGH-98, IND-SP, IND-SS, EGY-98
+ * PLANET SMART COM CREDITCARD/2000 PCMCIA, EN-2298
*
* Modified for FreeBSD(98) 2.2 by KATO T. of Nagoya University.
*
@@ -90,17 +98,19 @@
#endif
#include <machine/clock.h>
+#include <machine/md_var.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
#include <pc98/pc98/icu.h>
-#include <pc98/pc98/if_edreg.h>
#else
-#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/icu.h>
+#endif
#include <i386/isa/if_edreg.h>
+
+#ifdef PC98
+#include <pc98/pc98/if_ed98.h>
#endif
/*
@@ -331,120 +341,6 @@ card_intr(struct pccard_dev *dp)
#endif /* NCRD > 0 */
#ifdef PC98
-/* LPC-T support */
-#define LPCT_1d0_ON() \
-{ \
- outb(0x2a8e, 0x84); \
- outw(0x4a8e, 0x1d0); \
- outw(0x5a8e, 0x0310); \
-}
-
-#define LPCT_1d0_OFF() \
-{ \
- outb(0x2a8e, 0xa4); \
- outw(0x4a8e, 0xd0); \
- outw(0x5a8e, 0x0300); \
-}
-
-/* register offsets */
-static unsigned int *edp[NED];
-static unsigned int pc98_io_skip[NED];
-static int ed_novell_nic_offset[NED];
-static int ed_novell_asic_offset[NED];
-static int ed_novell_data[NED];
-static int ed_novell_reset[NED];
-
-/* NE2000, LGY-98, ICM, LPC-T */
-static unsigned int edp_generic[16] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-
-/* EGY-98 */
-static unsigned int edp_egy98[16] = {
- 0, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
- 0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e
-};
-
-/* LD-BDN */
-static unsigned int edp_bdn98[16] = {
- 0x00000, 0x01000, 0x02000, 0x03000, 0x04000, 0x05000, 0x06000, 0x07000,
- 0x08000, 0x0a000, 0x0b000, 0x0c000, 0x0d000, 0x0d000, 0x0e000, 0x0f000
-};
-
-/* SIC-98 */
-static unsigned int edp_sic98[16] = {
- 0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00, 0x0c00, 0x0e00,
- 0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1a00, 0x1c00, 0x1e00
-};
-
-
-static void pc98_set_register(int unit, int type)
-{
- switch (type) {
- case ED_TYPE98_GENERIC:
- edp[unit] = edp_generic;
- pc98_io_skip[unit] = 1;
- ED_NOVELL_NIC_OFFSET = 0x0000;
- ED_NOVELL_ASIC_OFFSET = 0x0010;
- ED_NOVELL_DATA = 0x0000;
- ED_NOVELL_RESET = 0x000f;
- break;
-
- case ED_TYPE98_LGY:
- edp[unit] = edp_generic;
- pc98_io_skip[unit] = 1;
- ED_NOVELL_NIC_OFFSET = 0x0000;
- ED_NOVELL_ASIC_OFFSET = 0x0200;
- ED_NOVELL_DATA = 0x0000;
- ED_NOVELL_RESET = 0x0100;
- break;
-
- case ED_TYPE98_EGY:
- edp[unit] = edp_egy98;
- pc98_io_skip[unit] = 2;
- ED_NOVELL_NIC_OFFSET = 0;
- ED_NOVELL_ASIC_OFFSET = 0x0200;
- ED_NOVELL_DATA = 0x0000;
- ED_NOVELL_RESET = 0x0100;
- break;
-
- case ED_TYPE98_ICM:
- edp[unit] = edp_generic;
- pc98_io_skip[unit] = 1;
- ED_NOVELL_NIC_OFFSET = 0;
- ED_NOVELL_ASIC_OFFSET = 0x0100;
- ED_NOVELL_DATA = 0x0000;
- ED_NOVELL_RESET = 0x000f;
- break;
-
- case ED_TYPE98_BDN:
- edp[unit] = edp_bdn98;
- pc98_io_skip[unit] = 0x1000;
- ED_NOVELL_NIC_OFFSET = 0x0000;
- ED_NOVELL_ASIC_OFFSET = 0x0100;
- ED_NOVELL_DATA = 0;
- ED_NOVELL_RESET = 0xc100;
- break;
-
- case ED_TYPE98_SIC:
- edp[unit] = edp_sic98;
- pc98_io_skip[unit] = 0x200;
- ED_NOVELL_NIC_OFFSET = 0x0000;
- ED_NOVELL_ASIC_OFFSET = 0x2000;
- ED_NOVELL_DATA = 0x00; /* dummy */
- ED_NOVELL_RESET = 0x00;
- break;
-
- case ED_TYPE98_LPC:
- edp[unit] = edp_generic;
- pc98_io_skip[unit] = 0x1;
- ED_NOVELL_NIC_OFFSET = 0x0000;
- ED_NOVELL_ASIC_OFFSET = 0x0100;
- ED_NOVELL_DATA = 0x0000;
- ED_NOVELL_RESET = 0x0200;
- }
-}
-
struct pc98_driver eddriver = {
#else
struct isa_driver eddriver = {
@@ -553,18 +449,33 @@ ed_probe(isa_dev)
#endif /* not DEV_LKM */
#ifdef PC98
- ed_softc[isa_dev->id_unit].unit = isa_dev->id_unit;
-
- ed_softc[isa_dev->id_unit].type = ED_TYPE98_LPC;
- pc98_set_register(isa_dev->id_unit, ED_TYPE98_LPC);
- nports = ed_probe_Novell(isa_dev);
- if (nports)
- return (nports);
+ /*
+ * XXX
+ * MELCO LPC-TJ, LPC-TS
+ * PLANET SMART COM CREDITCARD/2000 PCMCIA
+ * IO-DATA PCLA/T
+ */
+ if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
+ (ED_TYPE98(isa_dev) == ED_TYPE98_LPC)) {
+ ed_softc[isa_dev->id_unit].unit = isa_dev->id_unit;
+ ed_softc[isa_dev->id_unit].type = ED_TYPE98_LPC;
+ pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LPC);
+ nports = ed_probe_Novell(isa_dev);
+ if (nports)
+ return (nports);
+ }
+ /*
+ * Generic probe routine
+ * Allied Telesis CenterCom LA-98-T
+ */
ed_softc[isa_dev->id_unit].type = ED_TYPE98_GENERIC;
- pc98_set_register(isa_dev->id_unit, ED_TYPE98_GENERIC);
+ pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_GENERIC);
#endif
+#ifdef PC98
+ if (ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) {
+#endif
nports = ed_probe_WD80x3(isa_dev);
if (nports)
return (nports);
@@ -576,36 +487,102 @@ ed_probe(isa_dev)
nports = ed_probe_Novell(isa_dev);
if (nports)
return (nports);
+#ifdef PC98
+ }
+#endif
- ed_softc[isa_dev->id_unit].type = ED_TYPE98_SIC;
- pc98_set_register(isa_dev->id_unit, ED_TYPE98_SIC);
- nports = ed_probe_SIC98(isa_dev);
- if (nports)
- return (nports);
+ /*
+ * Allied Telesis SIC-98
+ */
+ if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
+ (ED_TYPE98(isa_dev) == ED_TYPE98_SIC)) {
+ ed_softc[isa_dev->id_unit].type = ED_TYPE98_SIC;
+ pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_SIC);
+ nports = ed_probe_SIC98(isa_dev);
+ if (nports)
+ return (nports);
+ }
- ed_softc[isa_dev->id_unit].type = ED_TYPE98_BDN;
- pc98_set_register(isa_dev->id_unit, ED_TYPE98_BDN);
- nports = ed_probe_Novell(isa_dev);
- if (nports)
- return (nports);
+ /*
+ * ELECOM LANEED LD-BDN
+ * PLANET SMART COM 98 EN-2298
+ */
+ if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
+ (ED_TYPE98(isa_dev) == ED_TYPE98_BDN)) {
+ /* LD-BDN */
+ ed_softc[isa_dev->id_unit].type = ED_TYPE98_BDN;
+ pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_BDN);
+ nports = ed_probe_Novell(isa_dev);
+ if (nports)
+ return (nports);
+ }
- ed_softc[isa_dev->id_unit].type = ED_TYPE98_LGY;
- pc98_set_register(isa_dev->id_unit, ED_TYPE98_LGY);
- nports = ed_probe_Novell(isa_dev);
- if (nports)
- return (nports);
+ /*
+ * MELCO LGY-98, IND-SP, IND-SS
+ * MACNICA NE2098
+ */
+ if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
+ (ED_TYPE98(isa_dev) == ED_TYPE98_LGY)) {
+ /* LGY-98 */
+ ed_softc[isa_dev->id_unit].type = ED_TYPE98_LGY;
+ pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LGY);
+ nports = ed_probe_Novell(isa_dev);
+ if (nports)
+ return (nports);
+ }
- ed_softc[isa_dev->id_unit].type = ED_TYPE98_ICM;
- pc98_set_register(isa_dev->id_unit, ED_TYPE98_ICM);
- nports = ed_probe_Novell(isa_dev);
- if (nports)
- return (nports);
+ /*
+ * ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET
+ * D-Link DE-298P, DE-298
+ */
+ if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
+ (ED_TYPE98(isa_dev) == ED_TYPE98_ICM)) {
+ /* ICM */
+ ed_softc[isa_dev->id_unit].type = ED_TYPE98_ICM;
+ pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_ICM);
+ nports = ed_probe_Novell(isa_dev);
+ if (nports)
+ return (nports);
+ }
- ed_softc[isa_dev->id_unit].type = ED_TYPE98_EGY;
- pc98_set_register(isa_dev->id_unit, ED_TYPE98_EGY);
- nports = ed_probe_Novell(isa_dev);
- if (nports)
- return (nports);
+ /*
+ * MELCO EGY-98
+ */
+ if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
+ (ED_TYPE98(isa_dev) == ED_TYPE98_EGY)) {
+ /* EGY-98 */
+ ed_softc[isa_dev->id_unit].type = ED_TYPE98_EGY;
+ pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_EGY);
+ nports = ed_probe_Novell(isa_dev);
+ if (nports)
+ return (nports);
+ }
+
+ /*
+ * IO-DATA LA/T-98
+ */
+ if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
+ (ED_TYPE98(isa_dev) == ED_TYPE98_LA98)) {
+ /* LA-98 */
+ ed_softc[isa_dev->id_unit].type = ED_TYPE98_LA98;
+ pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LA98);
+ nports = ed_probe_Novell(isa_dev);
+ if (nports)
+ return (nports);
+ }
+
+ /*
+ * NEC PC-9801-108
+ */
+ if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
+ (ED_TYPE98(isa_dev) == ED_TYPE98_108)) {
+ /* PC-9801-108 */
+ ed_softc[isa_dev->id_unit].type = ED_TYPE98_108;
+ pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_108);
+ nports = ed_probe_Novell(isa_dev);
+ if (nports)
+ return (nports);
+ }
return (0);
}
@@ -1481,22 +1458,38 @@ ed_probe_Novell_generic(sc, port, unit, flags)
sc->type_str = "NE2000";
sc->kdc.kdc_description = "Ethernet adapter: NE2000";
break;
- case ED_TYPE98_LGY:
- sc->type_str = "LGY-98";
- sc->kdc.kdc_description = "Ethernet adapter: LGY-98";
+ case ED_TYPE98_LPC:
+ sc->type_str = "LPC-T";
+ sc->kdc.kdc_description = "Ethernet adapter: LPC-T";
+ break;
+ case ED_TYPE98_BDN:
+ sc->type_str = "LD-BDN";
+ sc->kdc.kdc_description = "Ethernet adapter: LD-BDN";
break;
case ED_TYPE98_EGY:
sc->type_str = "EGY-98";
sc->kdc.kdc_description = "Ethernet adapter: EGY-98";
break;
+ case ED_TYPE98_LGY:
+ sc->type_str = "LGY-98";
+ sc->kdc.kdc_description = "Ethernet adapter: LGY-98";
+ break;
case ED_TYPE98_ICM:
sc->type_str = "ICM";
sc->kdc.kdc_description = "Ethernet adapter: ICM";
break;
- case ED_TYPE98_BDN:
- sc->type_str = "LD-BDN";
- sc->kdc.kdc_description = "Ethernet adapter: LD-BDN";
+ case ED_TYPE98_SIC:
+ sc->type_str = "SIC-98";
+ sc->kdc.kdc_description = "Ethernet adapter: SIC-98";
break;
+ case ED_TYPE98_108:
+ sc->type_str = "PC-9801-108";
+ sc->kdc.kdc_description = "Ethernet adapter: PC-9801-108";
+ break;
+ case ED_TYPE98_LA98:
+ sc->type_str = "LA-98";
+ sc->kdc.kdc_description = "Ethernet adapter: LA-98";
+ break;
default:
sc->type_str = "Unknown";
sc->kdc.kdc_description = "Ethernet adapter: Unkonwn";
diff --git a/sys/pc98/pc98/if_edreg.h b/sys/pc98/pc98/if_edreg.h
index fae62f8..e69de29 100644
--- a/sys/pc98/pc98/if_edreg.h
+++ b/sys/pc98/pc98/if_edreg.h
@@ -1,1162 +0,0 @@
-/*
- * Copyright (C) 1993, David Greenman. This software may be used, modified,
- * copied, distributed, and sold, in both source and binary form provided
- * that the above copyright and these terms are retained. Under no
- * circumstances is the author responsible for the proper functioning
- * of this software, nor does the author assume any responsibility
- * for damages incurred with its use.
- *
- * $Id: if_edreg.h,v 1.20 1996/01/30 22:55:38 mpp Exp $
- */
-/*
- * National Semiconductor DS8390 NIC register definitions
- *
- *
- * Modification history
- *
- * Revision 2.2 1993/11/29 16:33:39 davidg
- * From Thomas Sandford <t.d.g.sandford@comp.brad.ac.uk>
- * Add support for the 8013W board type
- *
- * Revision 2.1 1993/11/22 10:52:33 davidg
- * patch to add support for SMC8216 (Elite-Ultra) boards
- * from Glen H. Lowe
- *
- * Revision 2.0 93/09/29 00:37:15 davidg
- * changed double buffering flag to multi buffering
- * made changes/additions for 3c503 multi-buffering
- * ...companion to Rev. 2.0 of 'ed' driver.
- *
- * Revision 1.1 93/06/23 03:01:07 davidg
- * Initial revision
- *
- */
-
-/*
- * Page 0 register offsets
- */
-#define ED_P0_CR 0x00 /* Command Register */
-
-#define ED_P0_CLDA0 0x01 /* Current Local DMA Addr low (read) */
-#define ED_P0_PSTART 0x01 /* Page Start register (write) */
-
-#define ED_P0_CLDA1 0x02 /* Current Local DMA Addr high (read) */
-#define ED_P0_PSTOP 0x02 /* Page Stop register (write) */
-
-#define ED_P0_BNRY 0x03 /* Boundary Pointer */
-
-#define ED_P0_TSR 0x04 /* Transmit Status Register (read) */
-#define ED_P0_TPSR 0x04 /* Transmit Page Start (write) */
-
-#define ED_P0_NCR 0x05 /* Number of Collisions Reg (read) */
-#define ED_P0_TBCR0 0x05 /* Transmit Byte count, low (write) */
-
-#define ED_P0_FIFO 0x06 /* FIFO register (read) */
-#define ED_P0_TBCR1 0x06 /* Transmit Byte count, high (write) */
-
-#define ED_P0_ISR 0x07 /* Interrupt Status Register */
-
-#define ED_P0_CRDA0 0x08 /* Current Remote DMA Addr low (read) */
-#define ED_P0_RSAR0 0x08 /* Remote Start Address low (write) */
-
-#define ED_P0_CRDA1 0x09 /* Current Remote DMA Addr high (read) */
-#define ED_P0_RSAR1 0x09 /* Remote Start Address high (write) */
-
-#define ED_P0_RBCR0 0x0a /* Remote Byte Count low (write) */
-
-#define ED_P0_RBCR1 0x0b /* Remote Byte Count high (write) */
-
-#define ED_P0_RSR 0x0c /* Receive Status (read) */
-#define ED_P0_RCR 0x0c /* Receive Configuration Reg (write) */
-
-#define ED_P0_CNTR0 0x0d /* frame alignment error counter (read) */
-#define ED_P0_TCR 0x0d /* Transmit Configuration Reg (write) */
-
-#define ED_P0_CNTR1 0x0e /* CRC error counter (read) */
-#define ED_P0_DCR 0x0e /* Data Configuration Reg (write) */
-
-#define ED_P0_CNTR2 0x0f /* missed packet counter (read) */
-#define ED_P0_IMR 0x0f /* Interrupt Mask Register (write) */
-
-/*
- * Page 1 register offsets
- */
-#define ED_P1_CR 0x00 /* Command Register */
-#define ED_P1_PAR0 0x01 /* Physical Address Register 0 */
-#define ED_P1_PAR1 0x02 /* Physical Address Register 1 */
-#define ED_P1_PAR2 0x03 /* Physical Address Register 2 */
-#define ED_P1_PAR3 0x04 /* Physical Address Register 3 */
-#define ED_P1_PAR4 0x05 /* Physical Address Register 4 */
-#define ED_P1_PAR5 0x06 /* Physical Address Register 5 */
-#define ED_P1_CURR 0x07 /* Current RX ring-buffer page */
-#define ED_P1_MAR0 0x08 /* Multicast Address Register 0 */
-#define ED_P1_MAR1 0x09 /* Multicast Address Register 1 */
-#define ED_P1_MAR2 0x0a /* Multicast Address Register 2 */
-#define ED_P1_MAR3 0x0b /* Multicast Address Register 3 */
-#define ED_P1_MAR4 0x0c /* Multicast Address Register 4 */
-#define ED_P1_MAR5 0x0d /* Multicast Address Register 5 */
-#define ED_P1_MAR6 0x0e /* Multicast Address Register 6 */
-#define ED_P1_MAR7 0x0f /* Multicast Address Register 7 */
-
-/*
- * Page 2 register offsets
- */
-#define ED_P2_CR 0x00 /* Command Register */
-#define ED_P2_PSTART 0x01 /* Page Start (read) */
-#define ED_P2_CLDA0 0x01 /* Current Local DMA Addr 0 (write) */
-#define ED_P2_PSTOP 0x02 /* Page Stop (read) */
-#define ED_P2_CLDA1 0x02 /* Current Local DMA Addr 1 (write) */
-#define ED_P2_RNPP 0x03 /* Remote Next Packet Pointer */
-#define ED_P2_TPSR 0x04 /* Transmit Page Start (read) */
-#define ED_P2_LNPP 0x05 /* Local Next Packet Pointer */
-#define ED_P2_ACU 0x06 /* Address Counter Upper */
-#define ED_P2_ACL 0x07 /* Address Counter Lower */
-#define ED_P2_RCR 0x0c /* Receive Configuration Register (read) */
-#define ED_P2_TCR 0x0d /* Transmit Configuration Register (read) */
-#define ED_P2_DCR 0x0e /* Data Configuration Register (read) */
-#define ED_P2_IMR 0x0f /* Interrupt Mask Register (read) */
-
-/*
- * Command Register (CR) definitions
- */
-
-/*
- * STP: SToP. Software reset command. Takes the controller offline. No
- * packets will be received or transmitted. Any reception or
- * transmission in progress will continue to completion before
- * entering reset state. To exit this state, the STP bit must
- * reset and the STA bit must be set. The software reset has
- * executed only when indicated by the RST bit in the ISR being
- * set.
- */
-#define ED_CR_STP 0x01
-
-/*
- * STA: STArt. This bit is used to activate the NIC after either power-up,
- * or when the NIC has been put in reset mode by software command
- * or error.
- */
-#define ED_CR_STA 0x02
-
-/*
- * TXP: Transmit Packet. This bit must be set to indicate transmission of
- * a packet. TXP is internally reset either after the transmission is
- * completed or aborted. This bit should be set only after the Transmit
- * Byte Count and Transmit Page Start register have been programmed.
- */
-#define ED_CR_TXP 0x04
-
-/*
- * RD0, RD1, RD2: Remote DMA Command. These three bits control the operation
- * of the remote DMA channel. RD2 can be set to abort any remote DMA
- * command in progress. The Remote Byte Count registers should be cleared
- * when a remote DMA has been aborted. The Remote Start Addresses are not
- * restored to the starting address if the remote DMA is aborted.
- *
- * RD2 RD1 RD0 function
- * 0 0 0 not allowed
- * 0 0 1 remote read
- * 0 1 0 remote write
- * 0 1 1 send packet
- * 1 X X abort
- */
-#define ED_CR_RD0 0x08
-#define ED_CR_RD1 0x10
-#define ED_CR_RD2 0x20
-
-/*
- * PS0, PS1: Page Select. The two bits select which register set or 'page' to
- * access.
- *
- * PS1 PS0 page
- * 0 0 0
- * 0 1 1
- * 1 0 2
- * 1 1 reserved
- */
-#define ED_CR_PS0 0x40
-#define ED_CR_PS1 0x80
-/* bit encoded aliases */
-#define ED_CR_PAGE_0 0x00 /* (for consistency) */
-#define ED_CR_PAGE_1 0x40
-#define ED_CR_PAGE_2 0x80
-
-/*
- * Interrupt Status Register (ISR) definitions
- */
-
-/*
- * PRX: Packet Received. Indicates packet received with no errors.
- */
-#define ED_ISR_PRX 0x01
-
-/*
- * PTX: Packet Transmitted. Indicates packet transmitted with no errors.
- */
-#define ED_ISR_PTX 0x02
-
-/*
- * RXE: Receive Error. Indicates that a packet was received with one or more
- * the following errors: CRC error, frame alignment error, FIFO overrun,
- * missed packet.
- */
-#define ED_ISR_RXE 0x04
-
-/*
- * TXE: Transmission Error. Indicates that an attempt to transmit a packet
- * resulted in one or more of the following errors: excessive
- * collisions, FIFO underrun.
- */
-#define ED_ISR_TXE 0x08
-
-/*
- * OVW: OverWrite. Indicates a receive ring-buffer overrun. Incoming network
- * would exceed (has exceeded?) the boundary pointer, resulting in data
- * that was previously received and not yet read from the buffer to be
- * overwritten.
- */
-#define ED_ISR_OVW 0x10
-
-/*
- * CNT: Counter Overflow. Set when the MSB of one or more of the Network Talley
- * Counters has been set.
- */
-#define ED_ISR_CNT 0x20
-
-/*
- * RDC: Remote Data Complete. Indicates that a Remote DMA operation has completed.
- */
-#define ED_ISR_RDC 0x40
-
-/*
- * RST: Reset status. Set when the NIC enters the reset state and cleared when a
- * Start Command is issued to the CR. This bit is also set when a receive
- * ring-buffer overrun (OverWrite) occurs and is cleared when one or more
- * packets have been removed from the ring. This is a read-only bit.
- */
-#define ED_ISR_RST 0x80
-
-/*
- * Interrupt Mask Register (IMR) definitions
- */
-
-/*
- * PRXE: Packet Received interrupt Enable. If set, a received packet will cause
- * an interrupt.
- */
-#define ED_IMR_PRXE 0x01
-
-/*
- * PTXE: Packet Transmit interrupt Enable. If set, an interrupt is generated when
- * a packet transmission completes.
- */
-#define ED_IMR_PTXE 0x02
-
-/*
- * RXEE: Receive Error interrupt Enable. If set, an interrupt will occur whenever a
- * packet is received with an error.
- */
-#define ED_IMR_RXEE 0x04
-
-/*
- * TXEE: Transmit Error interrupt Enable. If set, an interrupt will occur whenever
- * a transmission results in an error.
- */
-#define ED_IMR_TXEE 0x08
-
-/*
- * OVWE: OverWrite error interrupt Enable. If set, an interrupt is generated whenever
- * the receive ring-buffer is overrun. i.e. when the boundary pointer is exceeded.
- */
-#define ED_IMR_OVWE 0x10
-
-/*
- * CNTE: Counter overflow interrupt Enable. If set, an interrupt is generated whenever
- * the MSB of one or more of the Network Statistics counters has been set.
- */
-#define ED_IMR_CNTE 0x20
-
-/*
- * RDCE: Remote DMA Complete interrupt Enable. If set, an interrupt is generated
- * when a remote DMA transfer has completed.
- */
-#define ED_IMR_RDCE 0x40
-
-/*
- * bit 7 is unused/reserved
- */
-
-/*
- * Data Configuration Register (DCR) definitions
- */
-
-/*
- * WTS: Word Transfer Select. WTS establishes byte or word transfers for
- * both remote and local DMA transfers
- */
-#define ED_DCR_WTS 0x01
-
-/*
- * BOS: Byte Order Select. BOS sets the byte order for the host.
- * Should be 0 for 80x86, and 1 for 68000 series processors
- */
-#define ED_DCR_BOS 0x02
-
-/*
- * LAS: Long Address Select. When LAS is 1, the contents of the remote
- * DMA registers RSAR0 and RSAR1 are used to provide A16-A31
- */
-#define ED_DCR_LAS 0x04
-
-/*
- * LS: Loopback Select. When 0, loopback mode is selected. Bits D1 and D2
- * of the TCR must also be programmed for loopback operation.
- * When 1, normal operation is selected.
- */
-#define ED_DCR_LS 0x08
-
-/*
- * AR: Auto-initialize Remote. When 0, data must be removed from ring-buffer
- * under program control. When 1, remote DMA is automatically initiated
- * and the boundary pointer is automatically updated
- */
-#define ED_DCR_AR 0x10
-
-/*
- * FT0, FT1: Fifo Threshold select.
- * FT1 FT0 Word-width Byte-width
- * 0 0 1 word 2 bytes
- * 0 1 2 words 4 bytes
- * 1 0 4 words 8 bytes
- * 1 1 8 words 12 bytes
- *
- * During transmission, the FIFO threshold indicates the number of bytes
- * or words that the FIFO has filled from the local DMA before BREQ is
- * asserted. The transmission threshold is 16 bytes minus the receiver
- * threshold.
- */
-#define ED_DCR_FT0 0x20
-#define ED_DCR_FT1 0x40
-
-/*
- * bit 7 (0x80) is unused/reserved
- */
-
-/*
- * Transmit Configuration Register (TCR) definitions
- */
-
-/*
- * CRC: Inhibit CRC. If 0, CRC will be appended by the transmitter, if 0, CRC
- * is not appended by the transmitter.
- */
-#define ED_TCR_CRC 0x01
-
-/*
- * LB0, LB1: Loopback control. These two bits set the type of loopback that is
- * to be performed.
- *
- * LB1 LB0 mode
- * 0 0 0 - normal operation (DCR_LS = 0)
- * 0 1 1 - internal loopback (DCR_LS = 0)
- * 1 0 2 - external loopback (DCR_LS = 1)
- * 1 1 3 - external loopback (DCR_LS = 0)
- */
-#define ED_TCR_LB0 0x02
-#define ED_TCR_LB1 0x04
-
-/*
- * ATD: Auto Transmit Disable. Clear for normal operation. When set, allows
- * another station to disable the NIC's transmitter by transmitting to
- * a multicast address hashing to bit 62. Reception of a multicast address
- * hashing to bit 63 enables the transmitter.
- */
-#define ED_TCR_ATD 0x08
-
-/*
- * OFST: Collision Offset enable. This bit when set modifies the backoff
- * algorithm to allow prioritization of nodes.
- */
-#define ED_TCR_OFST 0x10
-
-/*
- * bits 5, 6, and 7 are unused/reserved
- */
-
-/*
- * Transmit Status Register (TSR) definitions
- */
-
-/*
- * PTX: Packet Transmitted. Indicates successful transmission of packet.
- */
-#define ED_TSR_PTX 0x01
-
-/*
- * bit 1 (0x02) is unused/reserved
- */
-
-/*
- * COL: Transmit Collided. Indicates that the transmission collided at least
- * once with another station on the network.
- */
-#define ED_TSR_COL 0x04
-
-/*
- * ABT: Transmit aborted. Indicates that the transmission was aborted due to
- * excessive collisions.
- */
-#define ED_TSR_ABT 0x08
-
-/*
- * CRS: Carrier Sense Lost. Indicates that carrier was lost during the
- * transmission of the packet. (Transmission is not aborted because
- * of a loss of carrier)
- */
-#define ED_TSR_CRS 0x10
-
-/*
- * FU: FIFO Underrun. Indicates that the NIC wasn't able to access bus/
- * transmission memory before the FIFO emptied. Transmission of the
- * packet was aborted.
- */
-#define ED_TSR_FU 0x20
-
-/*
- * CDH: CD Heartbeat. Indicates that the collision detection circuitry
- * isn't working correctly during a collision heartbeat test.
- */
-#define ED_TSR_CDH 0x40
-
-/*
- * OWC: Out of Window Collision: Indicates that a collision occurred after
- * a slot time (51.2us). The transmission is rescheduled just as in
- * normal collisions.
- */
-#define ED_TSR_OWC 0x80
-
-/*
- * Receiver Configuration Register (RCR) definitions
- */
-
-/*
- * SEP: Save Errored Packets. If 0, error packets are discarded. If set to 1,
- * packets with CRC and frame errors are not discarded.
- */
-#define ED_RCR_SEP 0x01
-
-/*
- * AR: Accept Runt packet. If 0, packet with less than 64 byte are discarded.
- * If set to 1, packets with less than 64 byte are not discarded.
- */
-#define ED_RCR_AR 0x02
-
-/*
- * AB: Accept Broadcast. If set, packets sent to the broadcast address will be
- * accepted.
- */
-#define ED_RCR_AB 0x04
-
-/*
- * AM: Accept Multicast. If set, packets sent to a multicast address are checked
- * for a match in the hashing array. If clear, multicast packets are ignored.
- */
-#define ED_RCR_AM 0x08
-
-/*
- * PRO: Promiscuous Physical. If set, all packets with a physical addresses are
- * accepted. If clear, a physical destination address must match this
- * station's address. Note: for full promiscuous mode, RCR_AB and RCR_AM
- * must also be set. In addition, the multicast hashing array must be set
- * to all 1's so that all multicast addresses are accepted.
- */
-#define ED_RCR_PRO 0x10
-
-/*
- * MON: Monitor Mode. If set, packets will be checked for good CRC and framing,
- * but are not stored in the ring-buffer. If clear, packets are stored (normal
- * operation).
- */
-#define ED_RCR_MON 0x20
-
-/*
- * bits 6 and 7 are unused/reserved.
- */
-
-/*
- * Receiver Status Register (RSR) definitions
- */
-
-/*
- * PRX: Packet Received without error.
- */
-#define ED_RSR_PRX 0x01
-
-/*
- * CRC: CRC error. Indicates that a packet has a CRC error. Also set for frame
- * alignment errors.
- */
-#define ED_RSR_CRC 0x02
-
-/*
- * FAE: Frame Alignment Error. Indicates that the incoming packet did not end on
- * a byte boundary and the CRC did not match at the last byte boundary.
- */
-#define ED_RSR_FAE 0x04
-
-/*
- * FO: FIFO Overrun. Indicates that the FIFO was not serviced (during local DMA)
- * causing it to overrun. Reception of the packet is aborted.
- */
-#define ED_RSR_FO 0x08
-
-/*
- * MPA: Missed Packet. Indicates that the received packet couldn't be stored in
- * the ring-buffer because of insufficient buffer space (exceeding the
- * boundary pointer), or because the transfer to the ring-buffer was inhibited
- * by RCR_MON - monitor mode.
- */
-#define ED_RSR_MPA 0x10
-
-/*
- * PHY: Physical address. If 0, the packet received was sent to a physical address.
- * If 1, the packet was accepted because of a multicast/broadcast address
- * match.
- */
-#define ED_RSR_PHY 0x20
-
-/*
- * DIS: Receiver Disabled. Set to indicate that the receiver has entered monitor
- * mode. Cleared when the receiver exits monitor mode.
- */
-#define ED_RSR_DIS 0x40
-
-/*
- * DFR: Deferring. Set to indicate a 'jabber' condition. The CRS and COL inputs
- * are active, and the transceiver has set the CD line as a result of the
- * jabber.
- */
-#define ED_RSR_DFR 0x80
-
-/*
- * receive ring descriptor
- *
- * The National Semiconductor DS8390 Network interface controller uses
- * the following receive ring headers. The way this works is that the
- * memory on the interface card is chopped up into 256 bytes blocks.
- * A contiguous portion of those blocks are marked for receive packets
- * by setting start and end block #'s in the NIC. For each packet that
- * is put into the receive ring, one of these headers (4 bytes each) is
- * tacked onto the front. The first byte is a copy of the receiver status
- * register at the time the packet was received.
- */
-struct ed_ring {
- u_char rsr; /* receiver status */
- u_char next_packet; /* pointer to next packet */
- u_short count; /* bytes in packet (length + 4) */
-};
-
-/*
- * Common constants
- */
-#define ED_PAGE_SIZE 256 /* Size of RAM pages in bytes */
-#define ED_TXBUF_SIZE 6 /* Size of TX buffer in pages */
-
-/*
- * Vendor types
- */
-#define ED_VENDOR_WD_SMC 0x00 /* Western Digital/SMC */
-#define ED_VENDOR_3COM 0x01 /* 3Com */
-#define ED_VENDOR_NOVELL 0x02 /* Novell */
-#define ED_VENDOR_PCCARD 0x03 /* PCMCIA/PCCARD */
-#ifdef PC98
-#define ED_VENDOR_MISC 0xf0 /* others */
-#endif
-
-/*
- * Compile-time config flags
- */
-/*
- * this sets the default for enabling/disabling the transceiver
- */
-#define ED_FLAGS_DISABLE_TRANCEIVER 0x0001
-
-/*
- * This forces the board to be used in 8/16bit mode even if it
- * autoconfigs differently
- */
-#define ED_FLAGS_FORCE_8BIT_MODE 0x0002
-#define ED_FLAGS_FORCE_16BIT_MODE 0x0004
-
-/*
- * This disables the use of double transmit buffers.
- */
-#define ED_FLAGS_NO_MULTI_BUFFERING 0x0008
-
-/*
- * This forces all operations with the NIC memory to use Programmed
- * I/O (i.e. not via shared memory)
- */
-#define ED_FLAGS_FORCE_PIO 0x0010
-
-/*
- * Definitions for Western digital/SMC WD80x3 series ASIC
- */
-/*
- * Memory Select Register (MSR)
- */
-#define ED_WD_MSR 0
-
-/* next three definitions for Toshiba */
-#define ED_WD_MSR_POW 0x02 /* 0 = power save, 1 = normal (R/W) */
-#define ED_WD_MSR_BSY 0x04 /* gate array busy (R) */
-#define ED_WD_MSR_LEN 0x20 /* data bus width, 0 = 16 bits,
- 1 = 8 bits (R/W) */
-#define ED_WD_MSR_ADDR 0x3f /* Memory decode bits 18-13 */
-#define ED_WD_MSR_MENB 0x40 /* Memory enable */
-#define ED_WD_MSR_RST 0x80 /* Reset board */
-
-/*
- * Interface Configuration Register (ICR)
- */
-#define ED_WD_ICR 1
-
-#define ED_WD_ICR_16BIT 0x01 /* 16-bit interface */
-#define ED_WD_ICR_OAR 0x02 /* select register. 0=BIO 1=EAR */
-#define ED_WD_ICR_IR2 0x04 /* high order bit of encoded IRQ */
-#define ED_WD_ICR_MSZ 0x08 /* memory size (0=8k 1=32k) */
-#define ED_WD_ICR_RLA 0x10 /* recall LAN address */
-#define ED_WD_ICR_RX7 0x20 /* recall all but i/o and LAN address */
-#define ED_WD_ICR_RIO 0x40 /* recall i/o address */
-#define ED_WD_ICR_STO 0x80 /* store to non-volatile memory */
-#ifdef TOSH_ETHER
-#define ED_WD_ICR_MEM 0xe0 /* shared mem address A15-A13 (R/W) */
-#define ED_WD_ICR_MSZ1 0x0f /* memory size, 0x08 = 64K, 0x04 = 32K,
- 0x02 = 16K, 0x01 = 8K */
- /* 64K can only be used if mem address
- above 1Mb */
- /* IAR holds address A23-A16 (R/W) */
-#endif
-
-/*
- * IO Address Register (IAR)
- */
-#define ED_WD_IAR 2
-
-/*
- * EEROM Address Register
- */
-#define ED_WD_EAR 3
-
-/*
- * Interrupt Request Register (IRR)
- */
-#define ED_WD_IRR 4
-
-#define ED_WD_IRR_0WS 0x01 /* use 0 wait-states on 8 bit bus */
-#define ED_WD_IRR_OUT1 0x02 /* WD83C584 pin 1 output */
-#define ED_WD_IRR_OUT2 0x04 /* WD83C584 pin 2 output */
-#define ED_WD_IRR_OUT3 0x08 /* WD83C584 pin 3 output */
-#define ED_WD_IRR_FLASH 0x10 /* Flash RAM is in the ROM socket */
-
-/*
- * The three bits of the encoded IRQ are decoded as follows:
- *
- * IR2 IR1 IR0 IRQ
- * 0 0 0 2/9
- * 0 0 1 3
- * 0 1 0 5
- * 0 1 1 7
- * 1 0 0 10
- * 1 0 1 11
- * 1 1 0 15
- * 1 1 1 4
- */
-#define ED_WD_IRR_IR0 0x20 /* bit 0 of encoded IRQ */
-#define ED_WD_IRR_IR1 0x40 /* bit 1 of encoded IRQ */
-#define ED_WD_IRR_IEN 0x80 /* Interrupt enable */
-
-/*
- * LA Address Register (LAAR)
- */
-#define ED_WD_LAAR 5
-
-#define ED_WD_LAAR_ADDRHI 0x1f /* bits 23-19 of RAM address */
-#define ED_WD_LAAR_0WS16 0x20 /* enable 0 wait-states on 16 bit bus */
-#define ED_WD_LAAR_L16EN 0x40 /* enable 16-bit operation */
-#define ED_WD_LAAR_M16EN 0x80 /* enable 16-bit memory access */
-
-/* i/o base offset to station address/card-ID PROM */
-#define ED_WD_PROM 8
-
-/*
- * 83C790 specific registers
- */
-/*
- * Hardware Support Register (HWR) ('790)
- */
-#define ED_WD790_HWR 4
-
-#define WD_WD790_HWR_NUKE 0x10 /* hardware reset */
-#define ED_WD790_HWR_LPRM 0x40 /* LAN PROM select */
-#define ED_WD790_HWR_SWH 0x80 /* switch register set */
-
-/*
- * ICR790 Interrupt Control Register for the 83C790
- */
-#define ED_WD790_ICR 6
-
-#define ED_WD790_ICR_EIL 0x01 /* enable interrupts */
-
-/*
- * REV/IOPA Revision / I/O Pipe register for the 83C79X
- */
-#define ED_WD790_REV 7
-
-#define ED_WD790 0x20
-#define ED_WD795 0x40
-
-/*
- * 79X RAM Address Register (RAR)
- * Enabled with SWH bit=1 in HWR register
- */
-#define ED_WD790_RAR 0x0b
-
-#define ED_WD790_RAR_SZ8 0x00 /* 8k memory buffer */
-#define ED_WD790_RAR_SZ16 0x10 /* 16k memory buffer */
-#define ED_WD790_RAR_SZ32 0x20 /* 32k memory buffer */
-#define ED_WD790_RAR_SZ64 0x30 /* 64k memory buffer */
-
-/*
- * General Control Register (GCR)
- * Enabled with SWH bit=1 in HWR register
- */
-#define ED_WD790_GCR 0x0d
-
-#define ED_WD790_GCR_IR0 0x04 /* bit 0 of encoded IRQ */
-#define ED_WD790_GCR_IR1 0x08 /* bit 1 of encoded IRQ */
-#define ED_WD790_GCR_ZWSEN 0x20 /* zero wait state enable */
-#define ED_WD790_GCR_IR2 0x40 /* bit 2 of encoded IRQ */
-#define ED_WD790_GCR_LIT 0x01 /* Link Integrity Test Enable */
-/*
- * The three bits of the encoded IRQ are decoded as follows:
- *
- * IR2 IR1 IR0 IRQ
- * 0 0 0 none
- * 0 0 1 9
- * 0 1 0 3
- * 0 1 1 5
- * 1 0 0 7
- * 1 0 1 10
- * 1 1 0 11
- * 1 1 1 15
- */
-
-/* i/o base offset to CARD ID */
-#define ED_WD_CARD_ID ED_WD_PROM+6
-
-/* Board type codes in card ID */
-#define ED_TYPE_WD8003S 0x02
-#define ED_TYPE_WD8003E 0x03
-#define ED_TYPE_WD8013EBT 0x05
-#define ED_TYPE_TOSHIBA1 0x11 /* named PCETA1 */
-#define ED_TYPE_TOSHIBA2 0x12 /* named PCETA2 */
-#define ED_TYPE_TOSHIBA3 0x13 /* named PCETB */
-#define ED_TYPE_TOSHIBA4 0x14 /* named PCETC */
-#define ED_TYPE_WD8003W 0x24
-#define ED_TYPE_WD8003EB 0x25
-#define ED_TYPE_WD8013W 0x26
-#define ED_TYPE_WD8013EP 0x27
-#define ED_TYPE_WD8013WC 0x28
-#define ED_TYPE_WD8013EPC 0x29
-#define ED_TYPE_SMC8216T 0x2a
-#define ED_TYPE_SMC8216C 0x2b
-#define ED_TYPE_WD8013EBP 0x2c
-
-/* Bit definitions in card ID */
-#define ED_WD_REV_MASK 0x1f /* Revision mask */
-#define ED_WD_SOFTCONFIG 0x20 /* Soft config */
-#define ED_WD_LARGERAM 0x40 /* Large RAM */
-#define ED_MICROCHANEL 0x80 /* Microchannel bus (vs. isa) */
-
-/*
- * Checksum total. All 8 bytes in station address PROM will add up to this
- */
-#ifdef TOSH_ETHER
-#define ED_WD_ROM_CHECKSUM_TOTAL 0xA5
-#else
-#define ED_WD_ROM_CHECKSUM_TOTAL 0xFF
-#endif
-
-#define ED_WD_NIC_OFFSET 0x10 /* I/O base offset to NIC */
-#define ED_WD_ASIC_OFFSET 0 /* I/O base offset to ASIC */
-#define ED_WD_IO_PORTS 32 /* # of i/o addresses used */
-
-#define ED_WD_PAGE_OFFSET 0 /* page offset for NIC access to mem */
-
-/*
- * Definitions for 3Com 3c503
- */
-#define ED_3COM_NIC_OFFSET 0
-#define ED_3COM_ASIC_OFFSET 0x400 /* offset to nic i/o regs */
-
-/*
- * XXX - The I/O address range is fragmented in the 3c503; this is the
- * number of regs at iobase.
- */
-#define ED_3COM_IO_PORTS 16 /* # of i/o addresses used */
-
-/* tx memory starts in second bank on 8bit cards */
-#define ED_3COM_TX_PAGE_OFFSET_8BIT 0x20
-
-/* tx memory starts in first bank on 16bit cards */
-#define ED_3COM_TX_PAGE_OFFSET_16BIT 0x0
-
-/* ...and rx memory starts in second bank */
-#define ED_3COM_RX_PAGE_OFFSET_16BIT 0x20
-
-
-/*
- * Page Start Register. Must match PSTART in NIC
- */
-#define ED_3COM_PSTR 0
-
-/*
- * Page Stop Register. Must match PSTOP in NIC
- */
-#define ED_3COM_PSPR 1
-
-/*
- * Drq Timer Register. Determines number of bytes to be transfered during
- * a DMA burst.
- */
-#define ED_3COM_DQTR 2
-
-/*
- * Base Configuration Register. Read-only register which contains the
- * board-configured I/O base address of the adapter. Bit encoded.
- */
-#define ED_3COM_BCFR 3
-
-#define ED_3COM_BCFR_2E0 0x01
-#define ED_3COM_BCFR_2A0 0x02
-#define ED_3COM_BCFR_280 0x04
-#define ED_3COM_BCFR_250 0x08
-#define ED_3COM_BCFR_350 0x10
-#define ED_3COM_BCFR_330 0x20
-#define ED_3COM_BCFR_310 0x40
-#define ED_3COM_BCFR_300 0x80
-
-/*
- * EPROM Configuration Register. Read-only register which contains the
- * board-configured memory base address. Bit encoded.
- */
-#define ED_3COM_PCFR 4
-
-#define ED_3COM_PCFR_C8000 0x10
-#define ED_3COM_PCFR_CC000 0x20
-#define ED_3COM_PCFR_D8000 0x40
-#define ED_3COM_PCFR_DC000 0x80
-
-/*
- * GA Configuration Register. Gate-Array Configuration Register.
- */
-#define ED_3COM_GACFR 5
-
-/*
- * mbs2 mbs1 mbs0 start address
- * 0 0 0 0x0000
- * 0 0 1 0x2000
- * 0 1 0 0x4000
- * 0 1 1 0x6000
- *
- * Note that with adapters with only 8K, the setting for 0x2000 must
- * always be used.
- */
-#define ED_3COM_GACFR_MBS0 0x01
-#define ED_3COM_GACFR_MBS1 0x02
-#define ED_3COM_GACFR_MBS2 0x04
-
-#define ED_3COM_GACFR_RSEL 0x08 /* enable shared memory */
-#define ED_3COM_GACFR_TEST 0x10 /* for GA testing */
-#define ED_3COM_GACFR_OWS 0x20 /* select 0WS access to GA */
-#define ED_3COM_GACFR_TCM 0x40 /* Mask DMA interrupts */
-#define ED_3COM_GACFR_NIM 0x80 /* Mask NIC interrupts */
-
-/*
- * Control Register. Miscellaneous control functions.
- */
-#define ED_3COM_CR 6
-
-#define ED_3COM_CR_RST 0x01 /* Reset GA and NIC */
-#define ED_3COM_CR_XSEL 0x02 /* Transceiver select. BNC=1(def) AUI=0 */
-#define ED_3COM_CR_EALO 0x04 /* window EA PROM 0-15 to I/O base */
-#define ED_3COM_CR_EAHI 0x08 /* window EA PROM 16-31 to I/O base */
-#define ED_3COM_CR_SHARE 0x10 /* select interrupt sharing option */
-#define ED_3COM_CR_DBSEL 0x20 /* Double buffer select */
-#define ED_3COM_CR_DDIR 0x40 /* DMA direction select */
-#define ED_3COM_CR_START 0x80 /* Start DMA controller */
-
-/*
- * Status Register. Miscellaneous status information.
- */
-#define ED_3COM_STREG 7
-
-#define ED_3COM_STREG_REV 0x07 /* GA revision */
-#define ED_3COM_STREG_DIP 0x08 /* DMA in progress */
-#define ED_3COM_STREG_DTC 0x10 /* DMA terminal count */
-#define ED_3COM_STREG_OFLW 0x20 /* Overflow */
-#define ED_3COM_STREG_UFLW 0x40 /* Underflow */
-#define ED_3COM_STREG_DPRDY 0x80 /* Data port ready */
-
-/*
- * Interrupt/DMA Configuration Register
- */
-#define ED_3COM_IDCFR 8
-
-#define ED_3COM_IDCFR_DRQ0 0x01 /* DMA request 1 select */
-#define ED_3COM_IDCFR_DRQ1 0x02 /* DMA request 2 select */
-#define ED_3COM_IDCFR_DRQ2 0x04 /* DMA request 3 select */
-#define ED_3COM_IDCFR_UNUSED 0x08 /* not used */
-#define ED_3COM_IDCFR_IRQ2 0x10 /* Interrupt request 2 select */
-#define ED_3COM_IDCFR_IRQ3 0x20 /* Interrupt request 3 select */
-#define ED_3COM_IDCFR_IRQ4 0x40 /* Interrupt request 4 select */
-#define ED_3COM_IDCFR_IRQ5 0x80 /* Interrupt request 5 select */
-
-/*
- * DMA Address Register MSB
- */
-#define ED_3COM_DAMSB 9
-
-/*
- * DMA Address Register LSB
- */
-#define ED_3COM_DALSB 0x0a
-
-/*
- * Vector Pointer Register 2
- */
-#define ED_3COM_VPTR2 0x0b
-
-/*
- * Vector Pointer Register 1
- */
-#define ED_3COM_VPTR1 0x0c
-
-/*
- * Vector Pointer Register 0
- */
-#define ED_3COM_VPTR0 0x0d
-
-/*
- * Register File Access MSB
- */
-#define ED_3COM_RFMSB 0x0e
-
-/*
- * Register File Access LSB
- */
-#define ED_3COM_RFLSB 0x0f
-
-/*
- * Definitions for Novell NE1000/2000 boards
- */
-
-/*
- * Board type codes
- */
-#define ED_TYPE_NE1000 0x01
-#define ED_TYPE_NE2000 0x02
-
-/*
- * Register offsets/total
- */
-#ifdef PC98 /* PC98 (LGY-98) */
-#define ED_NOVELL_NIC_OFFSET ed_novell_nic_offset[unit]
-#define ED_NOVELL_ASIC_OFFSET ed_novell_asic_offset[unit]
-#else
-#define ED_NOVELL_NIC_OFFSET 0x00
-#define ED_NOVELL_ASIC_OFFSET 0x10
-#endif
-#define ED_NOVELL_IO_PORTS 32
-
-/*
- * Remote DMA data register; for reading or writing to the NIC mem
- * via programmed I/O (offset from ASIC base)
- */
-#ifdef PC98 /* PC98 (LGY-98) */
-
-/*
- * Definitions for PCCARD
- */
-#define ED_PC_PAGE_OFFSET 0x40 /* page offset for NIC access to mem */
-#define ED_PC_IO_PORTS 32
-#define ED_PC_RESET 0x1f
-#define ED_PC_MISC 0x18
-
-/*
- * if_ze.h constants
- */
-
-#define ZE_PAGE_OFFSET 0x40 /* mem buffer starts at 0x4000 */
-
-#define ZE_DATA_IO 0x10
-#define ZE_MISC 0x18
-#define ZE_RESET 0x1F
-
-#define ED_NOVELL_DATA ed_novell_data[unit]
-#else
-#define ED_NOVELL_DATA 0x00
-#endif
-
-/*
- * Reset register; reading from this register causes a board reset
- */
-#ifdef PC98 /* PC98 (LGY-98) */
-#define ED_NOVELL_RESET ed_novell_reset[unit]
-#else
-#define ED_NOVELL_RESET 0x0f
-#endif
-
-#ifdef PC98
-#define ED_TYPE98_GENERIC 0x10
-#define ED_TYPE98_LGY 0x11
-#define ED_TYPE98_EGY 0x12
-#define ED_TYPE98_ICM 0x13
-#define ED_TYPE98_BDN 0x14
-#define ED_TYPE98_SIC 0x15
-#define ED_TYPE98_LPC 0x16
-
-
-#undef ED_P0_CR
-#define ED_P0_CR edp[unit][0x00]
-
-#undef ED_P0_CLDA0
-#define ED_P0_CLDA0 edp[unit][0x01]
-#undef ED_P0_PSTART
-#define ED_P0_PSTART edp[unit][0x01]
-
-#undef ED_P0_CLDA1
-#define ED_P0_CLDA1 edp[unit][0x02]
-#undef ED_P0_PSTOP
-#define ED_P0_PSTOP edp[unit][0x02]
-
-#undef ED_P0_BNRY
-#define ED_P0_BNRY edp[unit][0x03]
-
-#undef ED_P0_TSR
-#define ED_P0_TSR edp[unit][0x04]
-#undef ED_P0_TPSR
-#define ED_P0_TPSR edp[unit][0x04]
-
-#undef ED_P0_NCR
-#define ED_P0_NCR edp[unit][0x05]
-#undef ED_P0_TBCR0
-#define ED_P0_TBCR0 edp[unit][0x05]
-
-#undef ED_P0_FIFO
-#define ED_P0_FIFO edp[unit][0x06]
-#undef ED_P0_TBCR1
-#define ED_P0_TBCR1 edp[unit][0x06]
-
-#undef ED_P0_ISR
-#define ED_P0_ISR edp[unit][0x07]
-
-#undef ED_P0_CRDA0
-#define ED_P0_CRDA0 edp[unit][0x08]
-#undef ED_P0_RSAR0
-#define ED_P0_RSAR0 edp[unit][0x08]
-
-#undef ED_P0_CRDA1
-#define ED_P0_CRDA1 edp[unit][0x09]
-#undef ED_P0_RSAR1
-#define ED_P0_RSAR1 edp[unit][0x09]
-
-#undef ED_P0_RBCR0
-#define ED_P0_RBCR0 edp[unit][0x0a]
-
-#undef ED_P0_RBCR1
-#define ED_P0_RBCR1 edp[unit][0x0b]
-
-#undef ED_P0_RSR
-#define ED_P0_RSR edp[unit][0x0c]
-#undef ED_P0_RCR
-#define ED_P0_RCR edp[unit][0x0c]
-
-#undef ED_P0_CNTR0
-#define ED_P0_CNTR0 edp[unit][0x0d]
-#undef ED_P0_TCR
-#define ED_P0_TCR edp[unit][0x0d]
-
-#undef ED_P0_CNTR1
-#define ED_P0_CNTR1 edp[unit][0x0e]
-#undef ED_P0_DCR
-#define ED_P0_DCR edp[unit][0x0e]
-
-#undef ED_P0_CNTR2
-#define ED_P0_CNTR2 edp[unit][0x0f]
-#undef ED_P0_IMR
-#define ED_P0_IMR edp[unit][0x0f]
-
-#undef ED_P1_CR
-#define ED_P1_CR edp[unit][0x00]
-#undef ED_P1_PAR0
-#define ED_P1_PAR0 edp[unit][0x01]
-#undef ED_P1_PAR1
-#define ED_P1_PAR1 edp[unit][0x02]
-#undef ED_P1_PAR2
-#define ED_P1_PAR2 edp[unit][0x03]
-#undef ED_P1_PAR3
-#define ED_P1_PAR3 edp[unit][0x04]
-#undef ED_P1_PAR4
-#define ED_P1_PAR4 edp[unit][0x05]
-#undef ED_P1_PAR5
-#define ED_P1_PAR5 edp[unit][0x06]
-#undef ED_P1_CURR
-#define ED_P1_CURR edp[unit][0x07]
-#undef ED_P1_MAR0
-#define ED_P1_MAR0 edp[unit][0x08]
-#undef ED_P1_MAR1
-#define ED_P1_MAR1 edp[unit][0x09]
-#undef ED_P1_MAR2
-#define ED_P1_MAR2 edp[unit][0x0a]
-#undef ED_P1_MAR3
-#define ED_P1_MAR3 edp[unit][0x0b]
-#undef ED_P1_MAR4
-#define ED_P1_MAR4 edp[unit][0x0c]
-#undef ED_P1_MAR5
-#define ED_P1_MAR5 edp[unit][0x0d]
-#undef ED_P1_MAR6
-#define ED_P1_MAR6 edp[unit][0x0e]
-#undef ED_P1_MAR7
-#define ED_P1_MAR7 edp[unit][0x0f]
-
-#undef ED_P2_CR
-#define ED_P2_CR edp[unit][0x00]
-#undef ED_P2_PSTART
-#define ED_P2_PSTART edp[unit][0x01]
-#undef ED_P2_CLDA0
-#define ED_P2_CLDA0 edp[unit][0x01]
-#undef ED_P2_PSTOP
-#define ED_P2_PSTOP edp[unit][0x02]
-#undef ED_P2_CLDA1
-#define ED_P2_CLDA1 edp[unit][0x02]
-#undef ED_P2_RNPP
-#define ED_P2_RNPP edp[unit][0x03]
-#undef ED_P2_TPSR
-#define ED_P2_TPSR edp[unit][0x04]
-#undef ED_P2_LNPP
-#define ED_P2_LNPP edp[unit][0x05]
-#undef ED_P2_ACU
-#define ED_P2_ACU edp[unit][0x06]
-#undef ED_P2_ACL
-#define ED_P2_ACL edp[unit][0x07]
-#undef ED_P2_RCR
-#define ED_P2_RCR edp[unit][0x0c]
-#undef ED_P2_TCR
-#define ED_P2_TCR edp[unit][0x0d]
-#undef ED_P2_DCR
-#define ED_P2_DCR edp[unit][0x0e]
-#undef ED_P2_IMR
-#define ED_P2_IMR edp[unit][0x0f]
-#endif /* PC98 */
diff --git a/sys/pc98/pc98/if_ep.c b/sys/pc98/pc98/if_ep.c
index c8dd62f..c9d7b22 100644
--- a/sys/pc98/pc98/if_ep.c
+++ b/sys/pc98/pc98/if_ep.c
@@ -38,7 +38,7 @@
*/
/*
- * $Id: if_ep.c,v 1.44 1996/05/24 15:22:36 gibbs Exp $
+ * $Id: if_ep.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
@@ -50,6 +50,12 @@
* babkin@hq.icb.chel.su
*/
+/*
+ * Pccard support for 3C589 by:
+ * HAMADA Naoki
+ * nao@tom-yam.or.jp
+ */
+
#include "ep.h"
#if NEP > 0
@@ -103,14 +109,10 @@
#endif
#ifdef PC98
-#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
-#include <pc98/pc98/icu.h>
#include <pc98/pc98/if_epreg.h>
#else
-#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
-#include <i386/isa/icu.h>
#include <i386/isa/if_epreg.h>
#endif
#include <i386/isa/elink.h>
@@ -146,7 +148,9 @@ static void epstart __P((struct ifnet *));
static void epstop __P((struct ep_softc *));
static void epwatchdog __P((struct ifnet *));
+#if 0
static int send_ID_sequence __P((int));
+#endif
static int get_eeprom_data __P((int, int));
static struct ep_softc* ep_softc[NEP];
@@ -185,6 +189,179 @@ static struct kern_devconf kdc_isa_ep = {
DC_CLS_NETIF /* class */
};
+#include "crd.h"
+
+#if NCRD > 0
+#include "apm.h"
+#include <sys/select.h>
+#include <pccard/card.h>
+#include <pccard/driver.h>
+#include <pccard/slot.h>
+
+/*
+ * PC-Card (PCMCIA) specific code.
+ */
+static int card_intr __P((struct pccard_dev *));
+static void ep_unload __P((struct pccard_dev *));
+static void ep_suspend __P((struct pccard_dev *));
+static int ep_pccard_init __P((struct pccard_dev *, int));
+static int ep_pccard_attach __P((struct pccard_dev *));
+
+static struct pccard_drv ep_info = {
+ "ep",
+ card_intr,
+ ep_unload,
+ ep_suspend,
+ ep_pccard_init,
+ 0, /* Attributes - presently unused */
+ &net_imask
+};
+
+/* Resume is done by executing ep_pccard_init(dp, 0). */
+static void
+ep_suspend(dp)
+ struct pccard_dev *dp;
+{
+ struct ep_softc *sc = ep_softc[dp->isahd.id_unit];
+
+ printf("ep%d: suspending\n", dp->isahd.id_unit);
+ sc->gone = 1;
+}
+
+/*
+ *
+ */
+static int
+ep_pccard_init(dp, first)
+ struct pccard_dev *dp;
+ int first;
+{
+#ifdef PC98
+ struct pc98_device *is = &dp->isahd;
+#else
+ struct isa_device *is = &dp->isahd;
+#endif
+ struct ep_softc *sc = ep_softc[is->id_unit];
+ struct ep_board *epb;
+ int i;
+
+ epb = &ep_board[is->id_unit];
+
+ if (sc == 0) {
+ if ((sc = ep_alloc(is->id_unit, epb)) == 0) {
+ return (ENXIO);
+ }
+ ep_unit++;
+ ep_isa_registerdev(sc, is);
+ }
+
+ /* get_e() requires these. */
+ sc->ep_io_addr = is->id_iobase;
+ sc->unit = is->id_unit;
+
+ epb->epb_addr = is->id_iobase;
+ epb->epb_used = 1;
+ epb->prod_id = get_e(sc, EEPROM_PROD_ID);
+
+ if (epb->prod_id != 0x9058) { /* 3C589's product id */
+ if (first) {
+ printf("ep%d: failed to come ready.\n", is->id_unit);
+ } else {
+ printf("ep%d: failed to resume.\n", is->id_unit);
+ }
+ return (ENXIO);
+ }
+
+ epb->res_cfg = get_e(sc, EEPROM_RESOURCE_CFG);
+ for (i = 0; i < 3; i++) {
+ sc->epb->eth_addr[i] = get_e(sc, EEPROM_NODE_ADDR_0 + i);
+ }
+
+ if (first) {
+ if (ep_pccard_attach(dp) == 0) {
+ return (ENXIO);
+ }
+ sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen;
+ }
+
+ if (!first) {
+ sc->kdc->kdc_state = DC_IDLE;
+ sc->gone = 0;
+ printf("ep%d: resumed.\n", is->id_unit);
+ epinit(sc);
+ }
+
+ return (0);
+}
+
+static int
+ep_pccard_attach(dp)
+ struct pccard_dev *dp;
+{
+#ifdef PC98
+ struct pc98_device *is = &dp->isahd;
+#else
+ struct isa_device *is = &dp->isahd;
+#endif
+ struct ep_softc *sc = ep_softc[is->id_unit];
+ u_short config;
+
+ sc->ep_connectors = 0;
+ config = inw(IS_BASE + EP_W0_CONFIG_CTRL);
+ if (config & IS_BNC) {
+ sc->ep_connectors |= BNC;
+ }
+ if (config & IS_UTP) {
+ sc->ep_connectors |= UTP;
+ }
+ if (!(sc->ep_connectors & 7))
+ printf("no connectors!");
+ sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
+
+ /* ROM size = 0, ROM base = 0 */
+ /* For now, ignore AUTO SELECT feature of 3C589B and later. */
+ outw(BASE + EP_W0_ADDRESS_CFG, get_e(sc, EEPROM_ADDR_CFG) & 0xc000);
+
+ /* Fake IRQ must be 3 */
+ outw(BASE + EP_W0_RESOURCE_CFG, (sc->epb->res_cfg & 0x0fff) | 0x3000);
+
+ outw(BASE + EP_W0_PRODUCT_ID, sc->epb->prod_id);
+
+ ep_attach(sc);
+
+ return 1;
+}
+
+static void
+ep_unload(dp)
+ struct pccard_dev *dp;
+{
+ struct ep_softc *sc = ep_softc[dp->isahd.id_unit];
+
+ if (sc->kdc->kdc_state == DC_UNCONFIGURED) {
+ printf("ep%d: already unloaded\n", dp->isahd.id_unit);
+ return;
+ }
+ sc->kdc->kdc_state = DC_UNCONFIGURED;
+ sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
+ sc->gone = 1;
+ printf("ep%d: unload\n", dp->isahd.id_unit);
+}
+
+/*
+ * card_intr - Shared interrupt called from
+ * front end of PC-Card handler.
+ */
+static int
+card_intr(dp)
+ struct pccard_dev *dp;
+{
+ epintr(dp->isahd.id_unit);
+ return(1);
+}
+
+#endif /* NCRD > 0 */
+
static void
ep_isa_registerdev(sc, id)
struct ep_softc *sc;
@@ -229,7 +406,7 @@ ep_look_for_board_at(is)
struct isa_device *is;
#endif
{
- int data, i, j, io_base, id_port = ELINK_ID_PORT;
+ int data, i, j, id_port = ELINK_ID_PORT;
int count = 0;
if (ep_current_tag == (EP_LAST_TAG + 1)) {
@@ -401,7 +578,10 @@ ep_isa_probe(is)
struct ep_softc *sc;
struct ep_board *epb;
u_short k;
- int i;
+
+#if NCRD > 0
+ pccard_add_driver(&ep_info);
+#endif /* NCRD > 0 */
if(( epb=ep_look_for_board_at(is) )==0)
return (0);
@@ -493,7 +673,7 @@ ep_isa_attach(is)
GO_WINDOW(0);
if(irq == 9)
irq = 2;
- outw(BASE + EP_W0_RESOURCE_CFG, SET_IRQ(irq));
+ SET_IRQ(BASE, irq);
ep_attach(sc);
return 1;
@@ -508,6 +688,10 @@ ep_attach(sc)
struct sockaddr_dl *sdl;
u_short *p;
int i;
+ int attached;
+
+ sc->gone = 0;
+ attached = (ifp->if_softc != 0);
printf("ep%d: ", sc->unit);
/*
@@ -550,8 +734,10 @@ ep_attach(sc)
ifp->if_ioctl = epioctl;
ifp->if_watchdog = epwatchdog;
+ if (!attached) {
if_attach(ifp);
ether_ifattach(ifp);
+ }
/* device attach does transition from UNCONFIGURED to IDLE state */
sc->kdc->kdc_state=DC_IDLE;
@@ -599,7 +785,9 @@ ep_attach(sc)
sc->top = sc->mcur = 0;
#if NBPFILTER > 0
+ if (!attached) {
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
+ }
#endif
return 0;
}
@@ -616,6 +804,9 @@ epinit(sc)
register struct ifnet *ifp = &sc->arpcom.ac_if;
int s, i, j;
+ if (sc->gone)
+ return;
+
/*
if (ifp->if_addrlist == (struct ifaddr *) 0)
return;
@@ -682,39 +873,40 @@ epinit(sc)
*
*/
+ /* Set the xcvr. */
if(ifp->if_flags & IFF_LINK0 && sc->ep_connectors & AUI) {
- /* nothing */
+ i = ACF_CONNECTOR_AUI;
} else if(ifp->if_flags & IFF_LINK1 && sc->ep_connectors & BNC) {
- outw(BASE + EP_COMMAND, START_TRANSCEIVER);
- DELAY(1000);
+ i = ACF_CONNECTOR_BNC;
} else if(ifp->if_flags & IFF_LINK2 && sc->ep_connectors & UTP) {
- GO_WINDOW(4);
- outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
- GO_WINDOW(1);
+ i = ACF_CONNECTOR_UTP;
} else {
- GO_WINDOW(1);
- switch(sc->ep_connector) {
- case ACF_CONNECTOR_UTP:
- if(sc->ep_connectors & UTP) {
- GO_WINDOW(4);
- outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
- GO_WINDOW(1);
- }
- break;
- case ACF_CONNECTOR_BNC:
- if(sc->ep_connectors & BNC) {
- outw(BASE + EP_COMMAND, START_TRANSCEIVER);
- DELAY(1000);
- }
- break;
- case ACF_CONNECTOR_AUI:
- /* nothing to do */
- break;
- default:
- printf("ep%d: strange connector type in EEPROM: assuming AUI\n",
- sc->unit);
- break;
+ i = sc->ep_connector;
+ }
+ GO_WINDOW(0);
+ j = inw(BASE + EP_W0_ADDRESS_CFG) & 0x3fff;
+ outw(BASE + EP_W0_ADDRESS_CFG, j | (i << ACF_CONNECTOR_BITS));
+
+ switch(i) {
+ case ACF_CONNECTOR_UTP:
+ if(sc->ep_connectors & UTP) {
+ GO_WINDOW(4);
+ outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
}
+ break;
+ case ACF_CONNECTOR_BNC:
+ if(sc->ep_connectors & BNC) {
+ outw(BASE + EP_COMMAND, START_TRANSCEIVER);
+ DELAY(1000);
+ }
+ break;
+ case ACF_CONNECTOR_AUI:
+ /* nothing to do */
+ break;
+ default:
+ printf("ep%d: strange connector type in EEPROM: assuming AUI\n",
+ sc->unit);
+ break;
}
outw(BASE + EP_COMMAND, RX_ENABLE);
@@ -759,6 +951,7 @@ epinit(sc)
sc->next_mb = 0;
epmbuffill((caddr_t) sc, 0);
+ GO_WINDOW(1);
epstart(ifp);
splx(s);
@@ -776,6 +969,10 @@ epstart(ifp)
struct mbuf *top;
int s, pad;
+ if (sc->gone) {
+ return;
+ }
+
s = splimp();
if (ifp->if_flags & IFF_OACTIVE) {
splx(s);
@@ -814,7 +1011,7 @@ startagain:
}
IF_DEQUEUE(&ifp->if_snd, m);
- outw(BASE + EP_W1_TX_PIO_WR_1, len);
+ outw(BASE + EP_W1_TX_PIO_WR_1, len | 0x8000); /* XXX */
outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */
/* compute the Tx start threshold for this packet */
@@ -890,6 +1087,11 @@ epintr(unit)
int unit;
{
register struct ep_softc *sc = ep_softc[unit];
+
+ if (sc->gone) {
+ return;
+ }
+
ep_intr(sc);
}
@@ -1389,6 +1591,8 @@ static void
epwatchdog(ifp)
struct ifnet *ifp;
{
+ struct ep_softc *sc = ifp->if_softc;
+
/*
printf("ep: watchdog\n");
@@ -1396,6 +1600,10 @@ epwatchdog(ifp)
ifp->if_oerrors++;
*/
+ if (sc->gone) {
+ return;
+ }
+
ifp->if_flags &= ~IFF_OACTIVE;
epstart(ifp);
ep_intr(ifp->if_softc);
@@ -1405,6 +1613,10 @@ static void
epstop(sc)
struct ep_softc *sc;
{
+ if (sc->gone) {
+ return;
+ }
+
outw(BASE + EP_COMMAND, RX_DISABLE);
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
@@ -1419,6 +1631,7 @@ epstop(sc)
}
+#if 0
static int
send_ID_sequence(port)
int port;
@@ -1433,6 +1646,7 @@ send_ID_sequence(port)
}
return (1);
}
+#endif
/*
diff --git a/sys/pc98/pc98/if_epreg.h b/sys/pc98/pc98/if_epreg.h
index 3235c95..0744644 100644
--- a/sys/pc98/pc98/if_epreg.h
+++ b/sys/pc98/pc98/if_epreg.h
@@ -31,7 +31,7 @@
*/
/*
- * $Id: if_epreg.h,v 1.13 1996/02/28 17:19:04 gibbs Exp $
+ * $Id: if_epreg.h,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
@@ -44,6 +44,12 @@
*/
/*
+ * Pccard support for 3C589 by:
+ * HAMADA Naoki
+ * nao@tom-yam.or.jp
+ */
+
+/*
* Ethernet software status per interface.
*/
struct ep_softc {
@@ -64,6 +70,7 @@ struct ep_softc {
u_short ep_connectors; /* Connectors on this card. */
u_char ep_connector; /* Configured connector. */
int stat; /* some flags */
+ int gone; /* adapter is not present (for PCCARD) */
#define F_RX_FIRST 0x1
#define F_WAIT_TRAIL 0x2
#define F_RX_TRAILER 0x4
@@ -363,7 +370,9 @@ struct ep_board {
*
*/
-#define SET_IRQ(i) (((i)<<12) | 0xF00) /* set IRQ i */
+#define SET_IRQ(base,irq) outw((base) + EP_W0_RESOURCE_CFG, \
+ ((inw((base) + EP_W0_RESOURCE_CFG) & 0x0fff) | \
+ ((u_short)(irq)<<12)) ) /* set IRQ i */
/*
* FIFO Registers.
diff --git a/sys/pc98/pc98/if_fe.c b/sys/pc98/pc98/if_fe.c
index a3dd7ac..b27b02c 100644
--- a/sys/pc98/pc98/if_fe.c
+++ b/sys/pc98/pc98/if_fe.c
@@ -21,7 +21,7 @@
*/
/*
- * $Id: if_fe.c,v 1.14 1996/04/23 18:36:55 nate Exp $
+ * $Id: if_fe.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
*
* Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards.
* To be used with FreeBSD 2.x
@@ -128,11 +128,9 @@
#include <machine/clock.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
#include <pc98/pc98/icu.h>
#else
-#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/icu.h>
#endif
@@ -264,13 +262,8 @@ static struct fe_softc {
#define sc_description kdc.kdc_description
/* Standard driver entry points. These can be static. */
-#ifdef PC98
-static int fe_probe ( struct pc98_device * );
-static int fe_attach ( struct pc98_device * );
-#else
-static int fe_probe ( struct isa_device * );
-static int fe_attach ( struct isa_device * );
-#endif
+static int fe_probe ( DEVICE * );
+static int fe_attach ( DEVICE * );
static void fe_init ( int );
static int fe_ioctl ( struct ifnet *, int, caddr_t );
static void fe_start ( struct ifnet * );
@@ -281,6 +274,7 @@ static void fe_watchdog ( struct ifnet * );
static void fe_registerdev ( struct fe_softc *, DEVICE * );
#ifdef PC98
static int fe_probe_re1000 ( DEVICE *, struct fe_softc * );
+static int fe_probe_re1000p( DEVICE *, struct fe_softc * );
#else
static int fe_probe_fmv ( DEVICE *, struct fe_softc * );
static int fe_probe_ati ( DEVICE *, struct fe_softc * );
@@ -369,40 +363,16 @@ static struct kern_devconf const fe_kdc_template =
static void
inblk ( struct fe_softc * sc, int offs, u_char * mem, int len )
{
-#ifdef PC98
- u_short addr = sc->ioaddr[offs];
-#endif
-
while ( --len >= 0 ) {
-#ifdef PC98
- *mem++ = inb( addr );
- if (addr & 1)
- addr+=0x1FF;
- else
- addr++;
-#else
*mem++ = inb( sc->ioaddr[ offs++ ] );
-#endif
}
}
static void
outblk ( struct fe_softc * sc, int offs, u_char const * mem, int len )
{
-#ifdef PC98
- u_short addr = sc->ioaddr[offs];
-#endif
-
while ( --len >= 0 ) {
-#ifdef PC98
- outb( addr, *mem++ );
- if (addr & 1)
- addr+=0x1FF;
- else
- addr++;
-#else
outb( sc->ioaddr[ offs++ ], *mem++ );
-#endif
}
}
@@ -521,7 +491,10 @@ struct fe_probe_list
/* Lists of possible addresses. */
#ifdef PC98
static u_short const fe_re1000_addr [] =
- { 0xD0, 0xD2, 0xD4, 0xD8, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0 };
+ { 0x0D0, 0x0D2, 0x0D4, 0x0D6, 0x0D8, 0x0DA, 0x0DC, 0x0DE,
+ 0x1D0, 0x1D2, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0x1DC, 0x1DE, 0 };
+static u_short const fe_re1000p_addr [] =
+ { 0x0D0, 0x0D2, 0x0D4, 0x0D8, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0 };
#else
static u_short const fe_fmv_addr [] =
{ 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x300, 0x340, 0 };
@@ -533,6 +506,7 @@ static struct fe_probe_list const fe_probe_list [] =
{
#ifdef PC98
{ fe_probe_re1000, fe_re1000_addr },
+ { fe_probe_re1000p, fe_re1000p_addr },
#else
{ fe_probe_fmv, fe_fmv_addr },
{ fe_probe_ati, fe_ati_addr },
@@ -661,11 +635,7 @@ fe_probe ( DEVICE * dev )
*/
struct fe_simple_probe_struct
{
-#ifdef PC98
- u_short port; /* Offset from the base I/O address. */
-#else
u_char port; /* Offset from the base I/O address. */
-#endif
u_char mask; /* Bits to be checked. */
u_char bits; /* Values to be compared against. */
};
@@ -794,202 +764,85 @@ fe_read_eeprom ( struct fe_softc * sc, u_char * data )
/*
* Probe and initialization for Allied-Telesis RE1000 series.
*/
-#if 1
static int
-fe_probe_re1000 ( struct pc98_device * isa_dev, struct fe_softc * sc )
+fe_probe_re1000 ( DEVICE * isa_dev, struct fe_softc * sc )
{
- int i, n, signature;
+ int i, n;
int dlcr6, dlcr7;
- u_char eeprom [ FE_EEPROM_SIZE ];
+ u_char c = 0;
static u_short const irqmap [ 4 ] =
{ IRQ3, IRQ5, IRQ6, IRQ12 };
- static struct fe_simple_probe_struct const probe_signature1 [] = {
- { FE_DLCR0, 0xBF, 0x00 },
- { FE_DLCR2, 0xFF, 0x00 },
- { FE_DLCR4, 0x0F, 0x06 },
- { FE_DLCR6, 0x0F, 0x06 },
- { 0 }
- };
- static struct fe_simple_probe_struct const probe_signature2 [] = {
- { FE_DLCR1, 0xFF, 0x00 },
- { FE_DLCR3, 0xFF, 0x00 },
- { FE_DLCR5, 0xFF, 0x41 },
- { 0 }
- };
- static struct fe_simple_probe_struct const probe_table [] = {
- { FE_DLCR2, 0x71, 0x00 },
- { FE_DLCR4, 0x08, 0x00 },
- { FE_DLCR5, 0x80, 0x00 },
- { 0 }
- };
- static struct fe_simple_probe_struct const vendor_code [] = {
- { FE_DLCR8, 0xFF, 0x00 },
- { FE_DLCR9, 0xFF, 0x00 },
- { FE_DLCR10, 0xFF, 0xF4 },
- { 0 }
- };
- static struct fe_simple_probe_struct const re1000_check [] = {
- { FE_RE1000_MAC0, 0xff, 0x00 },
- { FE_RE1000_MAC1, 0xff, 0x00 },
- { FE_RE1000_MAC2, 0xff, 0xf4 }, /* ATI vendor code */
- { 0 }
- };
#if FE_DEBUG >= 3
- log( LOG_INFO, "fe%d: probe (0x%x) for RE1000/RE1000Plus/ME1500\n", sc->sc_unit, sc->iobase );
+ log( LOG_INFO, "fe%d: probe (0x%x) for RE1000\n", sc->sc_unit, sc->iobase );
fe_dump( LOG_INFO, sc, NULL );
#endif
- /* First, check the "signature" */
- signature = 0;
- if (fe_simple_probe(sc, probe_signature1)) {
-
- outb(sc->iobase+FE_DLCR6, (inb(sc->iobase+FE_DLCR6) & 0xCF) | 0x16);
- if (fe_simple_probe(sc, probe_signature2))
- signature = 1;
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + (i/2)*0x200 + (i%2);
}
/*
- * If the "signature" not detected, 86965 *might* be previously
- * initialized. So, check the Ethernet address here.
- *
- * Allied-Telesis uses 00 00 F4 ?? ?? ??.
+ * RE1000 does not use 86965 EEPROM interface.
*/
- if (signature == 0) {
- /* Simple check */
- if (!fe_simple_probe(sc, probe_table)) return 0;
-
- /* Disable DLC */
- dlcr6 = inb(sc->iobase + FE_DLCR6);
- outb(sc->iobase + FE_DLCR6, dlcr6 | FE_D6_DLC_DISABLE);
- /* Select register bank for DLCR */
- dlcr7 = inb(sc->iobase + FE_DLCR7);
- outb(sc->iobase + FE_DLCR7, dlcr7 & 0xF3 | FE_D7_RBS_DLCR);
-
- /* Check the Ethernet address */
- if (!fe_simple_probe(sc, vendor_code)) return 0;
-
- /* Restore configuration registers */
- DELAY(200);
- outb(sc->iobase + FE_DLCR6, dlcr6);
- outb(sc->iobase + FE_DLCR7, dlcr7);
- }
+ c ^= sc->sc_enaddr[0] = inb(sc->ioaddr[FE_RE1000_MAC0]);
+ c ^= sc->sc_enaddr[1] = inb(sc->ioaddr[FE_RE1000_MAC1]);
+ c ^= sc->sc_enaddr[2] = inb(sc->ioaddr[FE_RE1000_MAC2]);
+ c ^= sc->sc_enaddr[3] = inb(sc->ioaddr[FE_RE1000_MAC3]);
+ c ^= sc->sc_enaddr[4] = inb(sc->ioaddr[FE_RE1000_MAC4]);
+ c ^= sc->sc_enaddr[5] = inb(sc->ioaddr[FE_RE1000_MAC5]);
+ c ^= inb(sc->ioaddr[FE_RE1000_MACCHK]);
+ if (c != 0) return 0;
-#if 1
- /*
- * This test doesn't work well for RE1000 look-alike by
- * other vendors.
- */
- if ( fe_simple_probe( sc, re1000_check )){
- /*
- * RE1000 does not use 86965 EEPROM interface.
- */
- u_char c = 0;
- c ^= sc->sc_enaddr[0] = inb(sc->iobase + FE_RE1000_MAC0);
- c ^= sc->sc_enaddr[1] = inb(sc->iobase + FE_RE1000_MAC1);
- c ^= sc->sc_enaddr[2] = inb(sc->iobase + FE_RE1000_MAC2);
- c ^= sc->sc_enaddr[3] = inb(sc->iobase + FE_RE1000_MAC3);
- c ^= sc->sc_enaddr[4] = inb(sc->iobase + FE_RE1000_MAC4);
- c ^= sc->sc_enaddr[5] = inb(sc->iobase + FE_RE1000_MAC5);
- c ^= inb(sc->iobase + FE_RE1000_MACCHK);
- if (c != 0) return 0;
-
- if ( sc->sc_enaddr[ 0 ] != 0x00
+ if ( sc->sc_enaddr[ 0 ] != 0x00
|| sc->sc_enaddr[ 1 ] != 0x00
|| sc->sc_enaddr[ 2 ] != 0xF4 ) return 0;
- /*
- * check interrupt configure
- */
- for (n=0; n<4; n++) {
+ /*
+ * check interrupt configure
+ */
+ for (n=0; n<4; n++) {
if (isa_dev->id_irq == irqmap[n]) break;
- }
- if (n == 4) return 0;
-
- /*
- * set irq
- */
- c = inb(sc->iobase + FE_RE1000_IRQCONF);
- c &= (~ FE_RE1000_IRQCONF_IRQ);
- c |= (1 << (n + FE_RE1000_IRQCONF_IRQSHIFT));
- outb(sc->iobase + FE_RE1000_IRQCONF, c);
-#if 0
- PC98WAIT; PC98WAIT;
- if (c == (inb(sc->iobase + FE_RE1000_IRQCONF)
- & FE_RE1000_IRQCONF_IRQ)) return 0;
-#endif
-
- sc->typestr = "RE1000";
- sc->sc_description = "Ethernet adapter: RE1000";
-
- } else {
- /*
- * We are now almost sure we have an 86965 at the given
- * address. So, read EEPROM through 86965. We have to write
- * into LSI registers to read from EEPROM. I want to avoid it
- * at this stage, but I cannot test the presense of the chip
- * any further without reading EEPROM. FIXME.
- */
- fe_read_eeprom( sc, eeprom );
-
- /* Make sure that config info in EEPROM and 86965 agree. */
- if ( eeprom[ FE_EEPROM_CONF ] != inb( sc->iobase + FE_BMPR19 ) ) {
- return 0;
- }
-
- /*
- * Initialize constants in the per-line structure.
- */
-
- /* Get our station address from EEPROM. */
- bcopy( eeprom + FE_ATI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
-
- sc->typestr = "RE1000Plus/ME1500";
- sc->sc_description = "Ethernet adapter: RE1000Plus/ME1500";
- /*
- * Read IRQ configuration.
- */
- n = (inb(sc->iobase + FE_BMPR19) & FE_B19_IRQ ) >> FE_B19_IRQ_SHIFT;
- isa_dev->id_irq = irqmap[n];
}
+ if (n == 4) return 0;
-#else
- /* Make sure we got a valid station address. */
- if ( ( sc->sc_enaddr[ 0 ] & 0x03 ) != 0x00
- || ( sc->sc_enaddr[ 0 ] == 0x00
- && sc->sc_enaddr[ 1 ] == 0x00
- && sc->sc_enaddr[ 2 ] == 0x00 ) ) return 0;
-#endif
+ /*
+ * set irq
+ */
+ c = inb(sc->ioaddr[FE_RE1000_IRQCONF]);
+ c &= (~ FE_RE1000_IRQCONF_IRQ);
+ c |= (1 << (n + FE_RE1000_IRQCONF_IRQSHIFT));
+ outb(sc->ioaddr[FE_RE1000_IRQCONF], c);
- /* Should find all register prototypes here. FIXME. */
- sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
- sc->proto_dlcr5 = 0;
- sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
+ sc->typestr = "RE1000";
+ sc->sc_description = "Ethernet adapter: RE1000";
/*
* Program the 86965 as follows:
* SRAM: 32KB, 100ns, byte-wide access.
* Transmission buffer: 4KB x 2.
* System bus interface: 16 bits.
- * We cannot change these values but TXBSIZE, because they
- * are hard-wired on the board. Modifying TXBSIZE will affect
- * the driver performance.
*/
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
+ sc->proto_dlcr5 = 0;
sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
| FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
#if FE_DEBUG >= 3
fe_dump( LOG_INFO, sc, "RE1000 found" );
#endif
/* Initialize 86965. */
- outb( sc->iobase + FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ outb( sc->ioaddr[FE_DLCR6], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
DELAY(200);
/* Disable all interrupts. */
- outb( sc->iobase + FE_DLCR2, 0 );
- outb( sc->iobase + FE_DLCR3, 0 );
+ outb( sc->ioaddr[FE_DLCR2], 0 );
+ outb( sc->ioaddr[FE_DLCR3], 0 );
#if FE_DEBUG >= 3
fe_dump( LOG_INFO, sc, "end of fe_probe_re1000()" );
@@ -1000,9 +853,12 @@ fe_probe_re1000 ( struct pc98_device * isa_dev, struct fe_softc * sc )
*/
return 2; /* ??? */
}
-#else
+
+/*
+ * Probe and initialization for Allied-Telesis RE1000Plus/ME1500 series.
+ */
static int
-fe_probe_re1000 ( struct pc98_device * isa_dev, struct fe_softc * sc )
+fe_probe_re1000p ( DEVICE * isa_dev, struct fe_softc * sc )
{
int i, n, signature;
int dlcr6, dlcr7;
@@ -1035,29 +891,30 @@ fe_probe_re1000 ( struct pc98_device * isa_dev, struct fe_softc * sc )
{ FE_DLCR10, 0xFF, 0xF4 },
{ 0 }
};
- static struct fe_simple_probe_struct const re1000_check [] = {
- { FE_RE1000_MAC0, 0xff, 0x00 },
- { FE_RE1000_MAC1, 0xff, 0x00 },
- { FE_RE1000_MAC2, 0xff, 0xf4 }, /* ATI vendor code */
- { 0 }
- };
#if FE_DEBUG >= 3
- log( LOG_INFO, "fe%d: probe (0x%x) for RE1000\n", sc->sc_unit, sc->iobase );
+ log( LOG_INFO, "fe%d: probe (0x%x) for RE1000Plus/ME1500\n", sc->sc_unit, sc->iobase );
fe_dump( LOG_INFO, sc, NULL );
#endif
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < 16; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + (i/2)*0x200 + (i%2);
+ }
+ for ( i = 16; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + i*0x200 - 0x1000;
+ }
+
/* First, check the "signature" */
signature = 0;
if (fe_simple_probe(sc, probe_signature1)) {
-
- outb(sc->iobase+FE_DLCR6, (inb(sc->iobase+FE_DLCR6) & 0xCF) | 0x16);
+ outb(sc->ioaddr[FE_DLCR6], (inb(sc->ioaddr[FE_DLCR6]) & 0xCF) | 0x16);
if (fe_simple_probe(sc, probe_signature2))
signature = 1;
}
/*
- * If the "signature" not detected, RE1000 *might* be previously
+ * If the "signature" not detected, 86965 *might* be previously
* initialized. So, check the Ethernet address here.
*
* Allied-Telesis uses 00 00 F4 ?? ?? ??.
@@ -1067,84 +924,85 @@ fe_probe_re1000 ( struct pc98_device * isa_dev, struct fe_softc * sc )
if (!fe_simple_probe(sc, probe_table)) return 0;
/* Disable DLC */
- dlcr6 = inb(sc->iobase + FE_DLCR6);
- outb(sc->iobase + FE_DLCR6, dlcr6 | FE_D6_DLC_DISABLE);
+ dlcr6 = inb(sc->ioaddr[FE_DLCR6]);
+ outb(sc->ioaddr[FE_DLCR6], dlcr6 | FE_D6_DLC_DISABLE);
/* Select register bank for DLCR */
- dlcr7 = inb(sc->iobase + FE_DLCR7);
- outb(sc->iobase + FE_DLCR7, dlcr7 & 0xF3 | FE_D7_RBS_DLCR);
+ dlcr7 = inb(sc->ioaddr[FE_DLCR7]);
+ outb(sc->ioaddr[FE_DLCR7], dlcr7 & 0xF3 | FE_D7_RBS_DLCR);
/* Check the Ethernet address */
if (!fe_simple_probe(sc, vendor_code)) return 0;
/* Restore configuration registers */
DELAY(200);
- outb(sc->iobase + FE_DLCR6, dlcr6);
- outb(sc->iobase + FE_DLCR7, dlcr7);
+ outb(sc->ioaddr[FE_DLCR6], dlcr6);
+ outb(sc->ioaddr[FE_DLCR7], dlcr7);
}
/*
- * Read IRQ configuration.
+ * We are now almost sure we have an 86965 at the given
+ * address. So, read EEPROM through 86965. We have to write
+ * into LSI registers to read from EEPROM. I want to avoid it
+ * at this stage, but I cannot test the presense of the chip
+ * any further without reading EEPROM. FIXME.
*/
- n = (inb(sc->iobase + 0x1600) & FE_B19_IRQ ) >> FE_B19_IRQ_SHIFT;
- isa_dev->id_irq = irqmap[n];
+ fe_read_eeprom( sc, eeprom );
+
+ /* Make sure that config info in EEPROM and 86965 agree. */
+ if ( eeprom[ FE_EEPROM_CONF ] != inb( sc->ioaddr[FE_BMPR19] ) ) {
+ return 0;
+ }
-#if 1
/*
- * This test doesn't work well for RE1000 look-alike by
- * other vendors.
+ * Initialize constants in the per-line structure.
*/
- /* Make sure the vendor part is for Allied-Telesis. */
- if ( sc->sc_enaddr[ 0 ] != 0x00
- || sc->sc_enaddr[ 1 ] != 0x00
- || sc->sc_enaddr[ 2 ] != 0xF4 ) return 0;
+
+ /* Get our station address from EEPROM. */
+ bcopy( eeprom + FE_ATI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
-#else
- /* Make sure we got a valid station address. */
- if ( ( sc->sc_enaddr[ 0 ] & 0x03 ) != 0x00
- || ( sc->sc_enaddr[ 0 ] == 0x00
- && sc->sc_enaddr[ 1 ] == 0x00
- && sc->sc_enaddr[ 2 ] == 0x00 ) ) return 0;
-#endif
+ sc->typestr = "RE1000Plus/ME1500";
+ sc->sc_description = "Ethernet adapter: RE1000Plus/ME1500";
- /* Should find all register prototypes here. FIXME. */
- sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
- sc->proto_dlcr5 = 0;
- sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
+ /*
+ * Read IRQ configuration.
+ */
+ n = (inb(sc->ioaddr[FE_BMPR19]) & FE_B19_IRQ ) >> FE_B19_IRQ_SHIFT;
+ isa_dev->id_irq = irqmap[n];
/*
* Program the 86965 as follows:
* SRAM: 32KB, 100ns, byte-wide access.
* Transmission buffer: 4KB x 2.
* System bus interface: 16 bits.
- * We cannot change these values but TXBSIZE, because they
- * are hard-wired on the board. Modifying TXBSIZE will affect
- * the driver performance.
*/
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
+ sc->proto_dlcr5 = 0;
sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
| FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
#if FE_DEBUG >= 3
- fe_dump( LOG_INFO, sc, "RE1000 found" );
+ fe_dump( LOG_INFO, sc, "RE1000Plus/ME1500 found" );
#endif
/* Initialize 86965. */
- outb( sc->iobase + FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ outb( sc->ioaddr[FE_DLCR6], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
DELAY(200);
/* Disable all interrupts. */
- outb( sc->iobase + FE_DLCR2, 0 );
- outb( sc->iobase + FE_DLCR3, 0 );
+ outb( sc->ioaddr[FE_DLCR2], 0 );
+ outb( sc->ioaddr[FE_DLCR3], 0 );
#if FE_DEBUG >= 3
- fe_dump( LOG_INFO, sc, "end of fe_probe_re1000()" );
+ fe_dump( LOG_INFO, sc, "end of fe_probe_re1000p()" );
#endif
/*
- * That's all. AT1700 occupies 2*16 I/O addresses, by the way.
+ * That's all. RE1000Plus/ME1500 occupies 2*16 I/O addresses, by the way.
*/
return 2; /* ??? */
}
-#endif
#else
/*
* Probe and initialization for Fujitsu FMV-180 series boards
@@ -1519,7 +1377,7 @@ fe_probe_ati ( DEVICE * dev, struct fe_softc * sc )
*/
/* Get our station address from EEPROM. */
- bcopy( eeprom + FE_EEP_ATI_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
+ bcopy( eeprom + FE_ATI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
#if 1
/*
@@ -3065,7 +2923,6 @@ fe_write_mbufs ( struct fe_softc *sc, struct mbuf *m )
{
u_short addr_bmpr8 = sc->ioaddr[ FE_BMPR8 ];
u_short length, len;
- short pad;
struct mbuf *mp;
u_char *data;
u_short savebyte; /* WARNING: Architecture dependent! */
diff --git a/sys/pc98/pc98/if_fereg.h b/sys/pc98/pc98/if_fereg.h
index 63c4216..4a34f26 100644
--- a/sys/pc98/pc98/if_fereg.h
+++ b/sys/pc98/pc98/if_fereg.h
@@ -24,7 +24,7 @@
* SUCH DAMAGE.
*/
-/* $Id: if_fereg.h,v 1.3 1996/03/17 08:36:38 jkh Exp $ */
+/* $Id: if_fereg.h,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $ */
/*
* Registers on FMV-180 series' ISA bus interface ASIC.
@@ -115,35 +115,18 @@
*/
/* IRQ configuration. */
-#ifdef PC98
-#define FE_RE1000_IRQCONF 0x1000
-#else
#define FE_RE1000_IRQCONF 0x10
-#endif
#define FE_RE1000_IRQCONF_IRQ 0xf0
#define FE_RE1000_IRQCONF_IRQSHIFT 4
/* MAC (station) address. */
-#ifdef PC98
-#define FE_RE1000_MAC0 0x1001
-#define FE_RE1000_MAC1 0x1201
-#define FE_RE1000_MAC2 0x1401
-#define FE_RE1000_MAC3 0x1601
-#define FE_RE1000_MAC4 0x1801
-#define FE_RE1000_MAC5 0x1a01
-#else
#define FE_RE1000_MAC0 0x11
#define FE_RE1000_MAC1 0x13
#define FE_RE1000_MAC2 0x15
#define FE_RE1000_MAC3 0x17
#define FE_RE1000_MAC4 0x19
#define FE_RE1000_MAC5 0x1B
-#endif
/* "Check sum" -- an xor of MAC0 through MAC5 */
-#ifdef PC98
-#define FE_RE1000_MACCHK 0x1c01 /* xor data MAC0 through MAC5 */
-#else
#define FE_RE1000_MACCHK 0x1D
-#endif
diff --git a/sys/pc98/pc98/if_zp.c b/sys/pc98/pc98/if_zp.c
index 1b32c6b..ce7c705 100644
--- a/sys/pc98/pc98/if_zp.c
+++ b/sys/pc98/pc98/if_zp.c
@@ -34,7 +34,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* From: if_ep.c,v 1.9 1994/01/25 10:46:29 deraadt Exp $
- * $Id: if_zp.c,v 1.19 1996/06/04 21:41:01 nate Exp $
+ * $Id: if_zp.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
*/
/*-
* TODO:
@@ -144,17 +144,14 @@
#endif
#include <machine/clock.h>
+#include <machine/md_var.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
-#include <pc98/pc98/icu.h>
#include <pc98/pc98/if_zpreg.h>
#include <pc98/pc98/pcic.h>
#else
-#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
-#include <i386/isa/icu.h>
#include <i386/isa/if_zpreg.h>
#include <i386/isa/pcic.h>
#endif
@@ -361,7 +358,7 @@ zpprobe(struct isa_device * isa_dev)
int re_init_flag;
if ((slot = zp_find_adapter(isa_dev->id_maddr, isa_dev->id_reconfig)) < 0)
- return NULL;
+ return 0;
/* okay, we found a card, so set it up */
/* Inhibit 16 bit memory delay. POINTETH.SYS apparently does this, for
@@ -510,8 +507,6 @@ zpattach(isa_dev)
struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
struct ifnet *ifp = &sc->arpcom.ac_if;
u_short i;
- struct ifaddr *ifa;
- struct sockaddr_dl *sdl;
int pl;
/* PCMCIA card can be offlined. Reconfiguration is required */
diff --git a/sys/pc98/pc98/lpt.c b/sys/pc98/pc98/lpt.c
index 33a3822..fb174de 100644
--- a/sys/pc98/pc98/lpt.c
+++ b/sys/pc98/pc98/lpt.c
@@ -46,7 +46,7 @@
* SUCH DAMAGE.
*
* from: unknown origin, 386BSD 0.1
- * $Id: lpt.c,v 1.53 1996/04/04 12:28:36 joerg Exp $
+ * $Id: lpt.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
*/
/*
@@ -203,7 +203,7 @@
#define lprintf (void)
#else
#define lprintf if (lptflag) printf
-int lptflag = 1;
+static int volatile lptflag = 1;
#endif
#define LPTUNIT(s) ((s)&0x03)
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 029bbf5..78b2de4 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -35,13 +35,10 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.192 1996/06/08 11:03:01 bde Exp $
+ * $Id: machdep.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
*/
#include "npx.h"
-#ifndef PC98
-#include "isa.h"
-#endif
#include "opt_sysvipc.h"
#include "opt_ddb.h"
#include "opt_bounce.h"
@@ -117,10 +114,9 @@
#endif
#ifdef PC98
-#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
+#include <pc98/pc98/pc98_machdep.h>
#else
-#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/rtc.h>
#endif
@@ -132,31 +128,12 @@ extern int ptrace_single_step __P((struct proc *p));
extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data));
extern void dblfault_handler __P((void));
-extern void i486_bzero __P((void *, size_t));
-extern void i586_bzero __P((void *, size_t));
-extern void i686_bzero __P((void *, size_t));
+extern void identifycpu(void); /* XXX header file */
+extern void earlysetcpuclass(void); /* same header file */
static void cpu_startup __P((void *));
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
-static void identifycpu(void);
-
-char machine[] = "i386";
-SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
-
-static char cpu_model[128];
-SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "");
-
-struct kern_devconf kdc_cpu0 = {
- 0, 0, 0, /* filled in by dev_attach */
- "cpu", 0, { MDDT_CPU },
- 0, 0, 0, CPU_EXTERNALLEN,
- 0, /* CPU has no parent */
- 0, /* no parentdata */
- DC_BUSY, /* the CPU is always busy */
- cpu_model, /* no sense in duplication */
- DC_CLS_CPU /* class */
-};
#ifndef PANIC_REBOOT_WAIT_TIME
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
@@ -206,8 +183,6 @@ int boothowto = 0, bootverbose = 0, Maxmem = 0;
static int badpages = 0;
#ifdef PC98
int Maxmem_under16M = 0;
-extern pt_entry_t *panic_kwin_pte;
-extern caddr_t panic_kwin;
#endif
long dumplo;
extern int bootdev;
@@ -217,8 +192,6 @@ vm_offset_t phys_avail[10];
/* must be 2 less so 0 0 can signal end of chunks */
#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2)
-int cpu_class = CPUCLASS_386; /* smallest common denominator */
-
static void dumpsys __P((void));
static void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */
@@ -258,9 +231,12 @@ cpu_startup(dummy)
* Good {morning,afternoon,evening,night}.
*/
printf(version);
- cpu_class = i386_cpus[cpu].cpu_class;
+ earlysetcpuclass();
startrtclock();
identifycpu();
+#ifdef PERFMON
+ perfmon_init();
+#endif
printf("real memory = %d (%dK bytes)\n", ptoa(Maxmem), ptoa(Maxmem) / 1024);
/*
* Display any holes after the first chunk of extended memory.
@@ -499,176 +475,6 @@ setup_netisrs(ls)
}
}
-static struct cpu_nameclass i386_cpus[] = {
- { "Intel 80286", CPUCLASS_286 }, /* CPU_286 */
- { "i386SX", CPUCLASS_386 }, /* CPU_386SX */
- { "i386DX", CPUCLASS_386 }, /* CPU_386 */
- { "i486SX", CPUCLASS_486 }, /* CPU_486SX */
- { "i486DX", CPUCLASS_486 }, /* CPU_486 */
- { "Pentium", CPUCLASS_586 }, /* CPU_586 */
- { "Cy486DLC", CPUCLASS_486 }, /* CPU_486DLC */
- { "Pentium Pro", CPUCLASS_686 }, /* CPU_686 */
-};
-
-static void
-identifycpu()
-{
- printf("CPU: ");
- strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof cpu_model);
-
-#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
- if (!strcmp(cpu_vendor,"GenuineIntel")) {
- if ((cpu_id & 0xf00) > 3) {
- cpu_model[0] = '\0';
-
- switch (cpu_id & 0x3000) {
- case 0x1000:
- strcpy(cpu_model, "Overdrive ");
- break;
- case 0x2000:
- strcpy(cpu_model, "Dual ");
- break;
- }
-
- switch (cpu_id & 0xf00) {
- case 0x400:
- strcat(cpu_model, "i486 ");
- break;
- case 0x500:
- strcat(cpu_model, "Pentium"); /* nb no space */
- break;
- case 0x600:
- strcat(cpu_model, "Pentium Pro");
- break;
- default:
- strcat(cpu_model, "unknown");
- break;
- }
-
- switch (cpu_id & 0xff0) {
- case 0x400:
- strcat(cpu_model, "DX"); break;
- case 0x410:
- strcat(cpu_model, "DX"); break;
- case 0x420:
- strcat(cpu_model, "SX"); break;
- case 0x430:
- strcat(cpu_model, "DX2"); break;
- case 0x440:
- strcat(cpu_model, "SL"); break;
- case 0x450:
- strcat(cpu_model, "SX2"); break;
- case 0x470:
- strcat(cpu_model, "DX2 Write-Back Enhanced");
- break;
- case 0x480:
- strcat(cpu_model, "DX4"); break;
- break;
- }
- }
- }
-#endif
- printf("%s (", cpu_model);
- switch(cpu_class) {
- case CPUCLASS_286:
- printf("286");
- break;
-#if defined(I386_CPU)
- case CPUCLASS_386:
- printf("386");
- break;
-#endif
-#if defined(I486_CPU)
- case CPUCLASS_486:
- printf("486");
- bzero = i486_bzero;
- break;
-#endif
-#if defined(I586_CPU)
- case CPUCLASS_586:
- printf("%d.%02d-MHz ",
- ((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) / 100,
- ((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) % 100);
- printf("586");
- break;
-#endif
-#if defined(I686_CPU)
- case CPUCLASS_686:
- printf("%d.%02d-MHz ",
- ((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) / 100,
- ((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) % 100);
- printf("686");
- break;
-#endif
- default:
- printf("unknown"); /* will panic below... */
- }
- printf("-class CPU)\n");
-#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
- if(*cpu_vendor)
- printf(" Origin = \"%s\"",cpu_vendor);
- if(cpu_id)
- printf(" Id = 0x%lx",cpu_id);
-
- if (!strcmp(cpu_vendor, "GenuineIntel")) {
- printf(" Stepping=%ld", cpu_id & 0xf);
- if (cpu_high > 0) {
- printf("\n Features=0x%b", cpu_feature,
- "\020"
- "\001FPU"
- "\002VME"
- "\003DE"
- "\004PSE"
- "\005TSC"
- "\006MSR"
- "\007PAE"
- "\010MCE"
- "\011CX8"
- "\012APIC"
- "\013<b10>"
- "\014<b11>"
- "\015MTRR"
- "\016PGE"
- "\017MCA"
- "\020CMOV"
- );
- }
- }
- /* Avoid ugly blank lines: only print newline when we have to. */
- if (*cpu_vendor || cpu_id)
- printf("\n");
-#endif
- /*
- * Now that we have told the user what they have,
- * let them know if that machine type isn't configured.
- */
- switch (cpu_class) {
- case CPUCLASS_286: /* a 286 should not make it this far, anyway */
-#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
-#error This kernel is not configured for one of the supported CPUs
-#endif
-#if !defined(I386_CPU)
- case CPUCLASS_386:
-#endif
-#if !defined(I486_CPU)
- case CPUCLASS_486:
-#endif
-#if !defined(I586_CPU)
- case CPUCLASS_586:
-#endif
-#if !defined(I686_CPU)
- case CPUCLASS_686:
-#endif
- panic("CPU class not configured");
- default:
- break;
- }
-#ifdef PERFMON
- perfmon_init();
-#endif
- dev_attach(&kdc_cpu0);
-}
-
/*
* Send an interrupt to process.
*
@@ -884,66 +690,6 @@ sigreturn(p, uap, retval)
return(EJUSTRETURN);
}
-#ifdef PC98
-/*
- * disable screen saver
- */
-extern int scrn_blanked;
-extern void (*current_saver)(int blank);
-
-static void pc98_disable_screen_saver(void)
-{
- if (scrn_blanked)
- (*current_saver)(FALSE);
-}
-
-
-/*
- * change ralay on video card
- */
-static void pc98_change_relay(void)
-{
- /* mode register 2 */
- outb(0x6a, 0x07); /* enable to change FF */
- outb(0x6a, 0x8e);
- outb(0x6a, 0x06); /* disable to change FF */
- outb(0x7c, 0);
- outb(0x68, 0x0f); /* display */
-
- /* PWLB */
- *(int *)panic_kwin_pte = (0xf0c00000 & PG_FRAME) | PG_V | PG_RW ;
- pmap_update();
- *(long *)panic_kwin = 0;
- /* PowerWindow(C-Bus) */
- outb(0x0dc | 0x600, 0); /* XXX */
- /* PCHKB & PCSKB4 */
- outb(0x6e68, 0);
- /* PCSKB */
- outb(0x6ee8, 0);
- /* NEC-S3, Cirrus (local bus) */
- outb(0xfaa, 3);
- outb(0xfab, 1);
- outb(0xfaa, 6);
- outb(0xfab, 0xff);
- outb(0xfaa, 7);
- outb(0xfab, 0);
- /* NEC-S3 (C-bus) */
- outb(0xfa2, 3);
- outb(0xfa3, 0);
- /* GA-NB */
- outb(0x40e1, 0xc2);
- /* WAB-S & WAP */
- outb(0x40e1, 0xfa);
-
- /* stop G-GDC */
- outb(0xa2, 0x0c);
- /* XXX start T-GDC (which is true?)*/
- outb(0x62, 0x69);
- outb(0x62, 0x0d);
-}
-#endif
-
-
static int waittime = -1;
struct pcb dumppcb;
@@ -955,10 +701,6 @@ boot(howto)
register struct buf *bp;
int iter, nbusy;
-#ifdef PC98
- pc98_change_relay();
- pc98_disable_screen_saver();
-#endif
waittime = 0;
printf("\nsyncing disks... ");
@@ -1051,7 +793,7 @@ die:
* exported (symorder) and used at least by savecore(8)
*
*/
-u_long dumpmag = 0x8fca0101UL;
+static u_long const dumpmag = 0x8fca0101UL;
static int dumpsize = 0; /* also for savecore */
@@ -1406,6 +1148,13 @@ init386(first)
*/
cninit();
+#ifdef PC98
+ /*
+ * Initialize DMAC
+ */
+ init_pc98_dmac();
+#endif
+
/*
* make gdt memory segments, the code segment goes up to end of the
* page with etext in it, the data segment goes to the end of
@@ -1507,56 +1256,7 @@ init386(first)
#ifdef PC98
#ifdef EPSON_MEMWIN
- if (pc98_machine_type & M_EPSON_PC98) {
- if (Maxmem > 3840) {
- if (Maxmem == Maxmem_under16M) {
- Maxmem = 3840;
- Maxmem_under16M = 3840;
- } else if (Maxmem_under16M > 3840) {
- Maxmem_under16M = 3840;
- }
- }
-
- /* Disable 15MB-16MB caching */
- switch (epson_machine_id) {
- case 0x34: /* PC486HX */
- case 0x35: /* PC486HG */
- case 0x3B: /* PC486HA */
- /* Cache control start */
- outb(0x43f, 0x42);
- outw(0xc40, 0x0033);
-
- /* Disable 0xF00000-0xFFFFFF */
- outb(0xc48, 0x49); outb(0xc4c, 0x00);
- outb(0xc48, 0x48); outb(0xc4c, 0xf0);
- outb(0xc48, 0x4d); outb(0xc4c, 0x00);
- outb(0xc48, 0x4c); outb(0xc4c, 0xff);
- outb(0xc48, 0x4f); outb(0xc4c, 0x00);
-
- /* Cache control end */
- outb(0x43f, 0x40);
- break;
-
- case 0x2B: /* PC486GR/GF */
- case 0x30: /* PC486P */
- case 0x31: /* PC486GRSuper */
- case 0x32: /* PC486GR+ */
- case 0x37: /* PC486SE */
- case 0x38: /* PC486SR */
- /* Disable 0xF00000-0xFFFFFF */
- outb(0x43f, 0x42);
- outb(0x467, 0xe0);
- outb(0x567, 0xd8);
-
- outb(0x43f, 0x40);
- outb(0x467, 0xe0);
- outb(0x567, 0xe0);
- break;
- }
-
- /* Disable 15MB-16MB RAM and enable memory window */
- outb(0x43b, inb(0x43b) & 0xfd); /* clear bit1 */
- }
+ init_epson_memwin();
#endif
biosbasemem = 640; /* 640KB */
biosextmem = (Maxmem * PAGE_SIZE - 0x100000)/1024; /* extent memory */
@@ -1623,7 +1323,8 @@ init386(first)
/*
* Maxmem isn't the "maximum memory", it's one larger than the
- * highest page of of the physical address space. It
+ * highest page of the physical address space. It should be
+ * called something like "Maxphyspage".
*/
Maxmem = pagesinext + 0x100000/PAGE_SIZE;
@@ -1654,76 +1355,9 @@ init386(first)
}
#ifdef PC98
- /*
- * Certain 'CPU accelerator' supports over 16MB memory on
- * the machines whose BIOS doesn't store true size.
- * To support this, we don't trust BIOS values if Maxmem < 4096.
- */
- if (Maxmem < 4096) {
- for (target_page = ptoa(4096); /* 16MB */
- target_page < ptoa(32768); /* 128MB */
- target_page += 256 * PAGE_SIZE /* 1MB step */) {
- int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
-
- *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
- pmap_update();
-
- tmp = *(int *)CADDR1;
- /*
- * Test for alternating 1's and 0's
- */
- *(volatile int *)CADDR1 = 0xaaaaaaaa;
- if (*(volatile int *)CADDR1 != 0xaaaaaaaa) {
- page_bad = TRUE;
- }
- /*
- * Test for alternating 0's and 1's
- */
- *(volatile int *)CADDR1 = 0x55555555;
- if (*(volatile int *)CADDR1 != 0x55555555) {
- page_bad = TRUE;
- }
- /*
- * Test for all 1's
- */
- *(volatile int *)CADDR1 = 0xffffffff;
- if (*(volatile int *)CADDR1 != 0xffffffff) {
- page_bad = TRUE;
- }
- /*
- * Test for all 0's
- */
- *(volatile int *)CADDR1 = 0x0;
- if (*(volatile int *)CADDR1 != 0x0) {
- /*
- * test of page failed
- */
- page_bad = TRUE;
- }
- /*
- * Restore original value.
- */
- *(int *)CADDR1 = tmp;
- if (page_bad == TRUE) {
- if (target_page > ptoa(4096))
- Maxmem = atop(target_page);
- else
- Maxmem = OrigMaxmem;
-
- break;
- }
- }
- *(int *)CMAP1 = 0;
- pmap_update();
-
- /* XXX */
- if (Maxmem > 3840) {
- Maxmem_under16M = 3840;
- if (Maxmem < 4096) {
- Maxmem = 3840;
- }
- }
- }
+#ifdef notyet
+ init_cpu_accel_mem();
+#endif
#endif
for (target_page = avail_start; target_page < ptoa(Maxmem); target_page += PAGE_SIZE) {
diff --git a/sys/pc98/pc98/npx.c b/sys/pc98/pc98/npx.c
index 822db67..e94b17b 100644
--- a/sys/pc98/pc98/npx.c
+++ b/sys/pc98/pc98/npx.c
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
- * $Id: npx.c,v 1.29 1996/01/06 23:10:52 peter Exp $
+ * $Id: npx.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
*/
#include "npx.h"
@@ -54,6 +54,7 @@
#include <machine/cpu.h>
#include <machine/pcb.h>
+#include <machine/md_var.h>
#include <machine/trap.h>
#include <machine/clock.h>
#include <machine/specialreg.h>
diff --git a/sys/pc98/pc98/pc98.c b/sys/pc98/pc98/pc98.c
index 43d7e5b..2ce956e 100644
--- a/sys/pc98/pc98/pc98.c
+++ b/sys/pc98/pc98/pc98.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id: isa.c,v 1.70 1996/05/02 10:43:09 phk Exp $
+ * $Id: pc98.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
*/
/*
@@ -50,7 +50,7 @@
/*
* modified for PC9801 by A.Kojima F.Ukai M.Ishii
* Kyoto University Microcomputer Club (KMC)
- * $Id: pc98.c,v 1.3 1994/03/17 23:24:40 kakefuda Exp $
+ * $Id: pc98.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
*/
#include "opt_auto_eoi.h"
@@ -62,6 +62,7 @@
#include <sys/buf.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
+#include <machine/md_var.h>
#include <machine/segments.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -106,6 +107,11 @@ u_int intr_mask[ICU_LEN];
u_int* intr_mptr[ICU_LEN];
int intr_unit[ICU_LEN];
+#ifdef DDB
+unsigned int ddb_inb __P((unsigned int addr));
+void ddb_outb __P((unsigned int addr, unsigned char dt));
+#endif
+
extern struct kern_devconf kdc_cpu0;
#ifdef PC98
@@ -778,8 +784,6 @@ void pc98_dmacascade(chan)
* pc98_dmastart(): program 8237 DMA controller channel, avoid page alignment
* problems by using a bounce buffer.
*/
-int dma_init_flag = 0;
-
void pc98_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
{
vm_offset_t phys;
@@ -825,16 +829,6 @@ void pc98_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
asm("wbinvd"); /* wbinvd (WB cache flush) */
#endif
- if (!dma_init_flag) {
- dma_init_flag = 1;
- outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */
- outb(0x29, (0x0c | 0)); /* Bank Mode Reg. 16M mode */
- outb(0x29, (0x0c | 1)); /* Bank Mode Reg. 16M mode */
- outb(0x29, (0x0c | 2)); /* Bank Mode Reg. 16M mode */
- outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */
- outb(0x11, 0x50); /* PC98 must be 0x40 */
- }
-
/* mask channel */
mskport = IO_DMA + 0x14; /* 0x15 */
outb(mskport, chan & 3 | 0x04);
diff --git a/sys/pc98/pc98/pcaudio.c b/sys/pc98/pc98/pcaudio.c
index caa0cd4..8971f9c 100644
--- a/sys/pc98/pc98/pcaudio.c
+++ b/sys/pc98/pc98/pcaudio.c
@@ -25,7 +25,7 @@
* (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: pcaudio.c,v 1.27 1996/03/28 14:28:47 scrappy Exp $
+ * $Id: pcaudio.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
*/
#include "pca.h"
@@ -183,6 +183,9 @@ pca_init()
static int
pca_start(void)
{
+ int x = splhigh();
+ int rv = 0;
+
/* use the first buffer */
pca_status.current = 0;
pca_status.index = 0;
@@ -195,28 +198,31 @@ pca_start(void)
#endif
/* acquire the timers */
#ifdef PC98
- if (acquire_timer1(TIMER_LSB|TIMER_ONESHOT)) {
+ if (acquire_timer1(TIMER_LSB|TIMER_ONESHOT))
#else
- if (acquire_timer2(TIMER_LSB|TIMER_ONESHOT)) {
+ if (acquire_timer2(TIMER_LSB|TIMER_ONESHOT))
#endif
- return -1;
- }
- if (acquire_timer0(INTERRUPT_RATE, pcaintr)) {
+ rv = -1;
+ else if (acquire_timer0(INTERRUPT_RATE, pcaintr)) {
#ifdef PC98
release_timer1();
#else
release_timer2();
#endif
- return -1;
- }
- pca_status.timer_on = 1;
- return 0;
+ rv = -1;
+ } else
+ pca_status.timer_on = 1;
+
+ splx(x);
+ return rv;
}
static void
pca_stop(void)
{
+ int x = splhigh();
+
/* release the timers */
release_timer0();
#ifdef PC98
@@ -231,12 +237,15 @@ pca_stop(void)
pca_status.current = 0;
pca_status.buffer = pca_status.buf[pca_status.current];
pca_status.timer_on = 0;
+ splx(x);
}
static void
pca_pause()
{
+ int x = splhigh();
+
release_timer0();
#ifdef PC98
release_timer1();
@@ -244,12 +253,15 @@ pca_pause()
release_timer2();
#endif
pca_status.timer_on = 0;
+ splx(x);
}
static void
pca_continue()
{
+ int x = splhigh();
+
#ifdef PC98
pca_status.oldval = inb(IO_PPI) & ~0x08;
acquire_timer1(TIMER_LSB|TIMER_ONESHOT);
@@ -259,18 +271,24 @@ pca_continue()
#endif
acquire_timer0(INTERRUPT_RATE, pcaintr);
pca_status.timer_on = 1;
+ splx(x);
}
static int
pca_wait(void)
{
- int error;
+ int error, x;
+
+ if (!pca_status.timer_on)
+ return 0;
while (pca_status.in_use[0] || pca_status.in_use[1]) {
+ x = spltty();
pca_sleep = 1;
error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_drain", 0);
pca_sleep = 0;
+ splx(x);
if (error != 0 && error != ERESTART) {
pca_stop();
return error;
@@ -396,7 +414,7 @@ pcaclose(dev_t dev, int flags, int fmt, struct proc *p)
static int
pcawrite(dev_t dev, struct uio *uio, int flag)
{
- int count, error, which;
+ int count, error, which, x;
/* only audio device can be written */
if (minor(dev) > 0)
@@ -404,9 +422,11 @@ pcawrite(dev_t dev, struct uio *uio, int flag)
while ((count = min(BUF_SIZE, uio->uio_resid)) > 0) {
if (pca_status.in_use[0] && pca_status.in_use[1]) {
+ x = spltty();
pca_sleep = 1;
error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_wait", 0);
pca_sleep = 0;
+ splx(x);
if (error != 0 && error != ERESTART) {
pca_stop();
return error;
@@ -488,9 +508,11 @@ pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
return 0;
case AUDIO_DRAIN:
+ case AUDIO_COMPAT_DRAIN:
return pca_wait();
case AUDIO_FLUSH:
+ case AUDIO_COMPAT_FLUSH:
pca_stop();
return 0;
@@ -531,10 +553,8 @@ pcaintr(struct clockframe *frame)
pca_status.in_use[pca_status.current] = 0;
pca_status.current ^= 1;
pca_status.buffer = pca_status.buf[pca_status.current];
- if (pca_sleep) {
+ if (pca_sleep)
wakeup(&pca_sleep);
- pca_sleep = 0;
- }
if (pca_status.wsel.si_pid) {
selwakeup((struct selinfo *)&pca_status.wsel.si_pid);
pca_status.wsel.si_pid = 0;
diff --git a/sys/pc98/pc98/pcibus.c b/sys/pc98/pc98/pcibus.c
index a5c4395..7a22655 100644
--- a/sys/pc98/pc98/pcibus.c
+++ b/sys/pc98/pc98/pcibus.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pcibus.c,v 1.24 1996/04/30 21:37:21 se Exp $
+** $Id: pcibus.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
**
** pci bus subroutines for i386 architecture.
**
@@ -43,11 +43,9 @@
#ifdef PC98
#include <pc98/pc98/icu.h>
-#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
#else
#include <i386/isa/icu.h>
-#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#endif
@@ -152,7 +150,7 @@ DATA_SET (pcibus_set, i386pci);
#define CONF1_ENABLE 0x80000000ul
#define CONF1_ENABLE_CHK 0x80000000ul
-#define CONF1_ENABLE_MSK 0x00ff0700ul
+#define CONF1_ENABLE_MSK 0x7ff00000ul
#define CONF1_ENABLE_CHK1 0xff000001ul
#define CONF1_ENABLE_MSK1 0x80000001ul
#define CONF1_ENABLE_RES1 0x80000000ul
diff --git a/sys/pc98/pc98/pcicx.c b/sys/pc98/pc98/pcicx.c
index fbed452..28afae9 100644
--- a/sys/pc98/pc98/pcicx.c
+++ b/sys/pc98/pc98/pcicx.c
@@ -43,14 +43,10 @@
#include <machine/clock.h>
#endif
#ifdef PC98
-#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
-#include <pc98/pc98/icu.h>
#include <pc98/pc98/pcic.h>
#else
-#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
-#include <i386/isa/icu.h>
#include <i386/isa/pcic.h>
#endif
diff --git a/sys/pc98/pc98/random_machdep.c b/sys/pc98/pc98/random_machdep.c
index 61b99b5..c9fce34 100644
--- a/sys/pc98/pc98/random_machdep.c
+++ b/sys/pc98/pc98/random_machdep.c
@@ -1,7 +1,7 @@
/*
* random_machdep.c -- A strong random number generator
*
- * $Id: random_machdep.c,v 1.7 1996/06/08 08:18:00 bde Exp $
+ * $Id: random_machdep.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
*
* Version 0.95, last modified 18-Oct-95
*
@@ -53,10 +53,12 @@
#include <machine/random.h>
#ifdef PC98
+#include <pc98/pc98/icu.h>
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
#include <pc98/pc98/timerreg.h>
#else
+#include <i386/isa/icu.h>
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/timerreg.h>
@@ -108,7 +110,9 @@ static u_int32_t random_pool[POOLWORDS];
static struct timer_rand_state keyboard_timer_state;
static struct timer_rand_state extract_timer_state;
static struct timer_rand_state irq_timer_state[ICU_LEN];
+#ifdef notyet
static struct timer_rand_state blkdev_timer_state[MAX_BLKDEV];
+#endif
static struct wait_queue *random_wait;
inthand2_t *sec_intr_handler[ICU_LEN];
diff --git a/sys/pc98/pc98/sbic55.c b/sys/pc98/pc98/sbic55.c
index 9bfd4b4..dee18e3 100644
--- a/sys/pc98/pc98/sbic55.c
+++ b/sys/pc98/pc98/sbic55.c
@@ -96,7 +96,6 @@
#define MAXSIMUL 8
#define SBIC_RESET_TIMEOUT 2000 /* time to wait for reset */
-extern int dma_init_flag;
extern short dmapageport[];
@@ -904,15 +903,6 @@ sbic_dmastart(int flags, int phys, unsigned nbytes, unsigned chan)
#ifdef CYRIX_5X86
asm("wbinvd"); /* wbinvd (WB cache flush) */
#endif
- if (!dma_init_flag) {
- dma_init_flag = 1;
- outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */
- outb(0x29, (0x0c | 0)); /* Bank Mode Reg. 16M mode */
- outb(0x29, (0x0c | 1)); /* Bank Mode Reg. 16M mode */
- outb(0x29, (0x0c | 2)); /* Bank Mode Reg. 16M mode */
- outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */
- outb(0x11, 0x50); /* PC98 must be 0x40 */
- }
/* mask channel */
mskport = IO_DMA + 0x14; /* 0x15 */
diff --git a/sys/pc98/pc98/sbic55.c.new b/sys/pc98/pc98/sbic55.c.new
index a139449..ccc3cb3 100644
--- a/sys/pc98/pc98/sbic55.c.new
+++ b/sys/pc98/pc98/sbic55.c.new
@@ -80,7 +80,6 @@
#include <pc98/pc98/sbicreg.h>
#include <pc98/pc98/sbicvar.h>
-extern int dma_init_flag;
extern short dmapageport[];
/*
@@ -1721,16 +1720,6 @@ sbic_dmastart(sbic)
}
#endif
- if (!dma_init_flag) {
- dma_init_flag = 1;
- outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */
- outb(0x29, (0x0c | 0)); /* Bank Mode Reg. 16M mode */
- outb(0x29, (0x0c | 1)); /* Bank Mode Reg. 16M mode */
- outb(0x29, (0x0c | 2)); /* Bank Mode Reg. 16M mode */
- outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */
- outb(0x11, 0x50); /* PC98 must be 0x40 */
- }
-
/* mask channel */
outb(DMA_SMSK, sbic->sc_dma | DMA37SM_SET);
diff --git a/sys/pc98/pc98/scd.c b/sys/pc98/pc98/scd.c
index b018e3f..4504f5e 100644
--- a/sys/pc98/pc98/scd.c
+++ b/sys/pc98/pc98/scd.c
@@ -41,7 +41,7 @@
*/
-/* $Id: scd.c,v 1.21 1996/06/08 09:18:23 bde Exp $ */
+/* $Id: scd.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $ */
/* Please send any comments to micke@dynas.se */
@@ -73,10 +73,8 @@
#include <machine/stdarg.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_device.h>
#else
-#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#endif
#include <i386/isa/scdreg.h>
@@ -1193,7 +1191,7 @@ spin_up(unsigned unit)
int loop_count = 0;
again:
- rc = send_cmd(unit, CMD_SPIN_UP, NULL, 0, res_reg, &res_size);
+ rc = send_cmd(unit, CMD_SPIN_UP, 0, 0, res_reg, &res_size);
if (rc != 0) {
XDEBUG(2, ("scd%d: CMD_SPIN_UP error 0x%x\n", unit, rc));
return rc;
diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c
index b16d153..66a8d71 100644
--- a/sys/pc98/pc98/sio.c
+++ b/sys/pc98/pc98/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.142 1996/05/02 09:34:40 phk Exp $
+ * $Id: sio.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
*/
#include "opt_comconsole.h"
@@ -138,14 +138,13 @@
#include <machine/clock.h>
#ifdef PC98
-#include <pc98/pc98/icu.h> /* XXX just to get at `imen' */
#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/icu.h>
#include <pc98/pc98/pc98_device.h>
#include <pc98/pc98/sioreg.h>
#include <pc98/pc98/ic/i8251.h>
#include <pc98/pc98/ic/ns16550.h>
#else
-#include <i386/isa/icu.h> /* XXX just to get at `imen' */
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/sioreg.h>
@@ -330,7 +329,9 @@ struct com_s {
struct termios lt_out;
bool_t do_timestamp;
+ bool_t do_dcd_timestamp;
struct timeval timestamp;
+ struct timeval dcd_timestamp;
u_long bytes_in; /* statistics */
u_long bytes_out;
@@ -366,8 +367,7 @@ struct com_s {
* by `config', not here.
*/
-/* Interrupt handling entry points. */
-inthand2_t siointrts;
+/* Interrupt handling entry point. */
void siopoll __P((void));
/* Device switch entry points. */
@@ -417,8 +417,6 @@ static char driver_name[] = "sio";
static struct com_s *p_com_addr[NSIO];
#define com_addr(unit) (p_com_addr[unit])
-static struct timeval intr_timestamp;
-
#ifdef PC98
struct pc98_driver siodriver = {
#else
@@ -958,18 +956,6 @@ sioprobe(dev)
/* EXTRA DELAY? */
/*
- * XXX DELAY() reenables CPU interrupts. This is a problem for
- * shared interrupts after the first device using one has been
- * successfully probed - config_isadev() has enabled the interrupt
- * in the ICU.
- */
-#ifdef PC98
- outb(IO_ICU1 + 2, 0xff);
-#else
- outb(IO_ICU1 + 1, 0xff);
-#endif
-
- /*
* Initialize the speed and the word size and wait long enough to
* drain the maximum of 16 bytes of junk in device output queues.
* The speed is undefined after a master reset and must be set
@@ -1042,7 +1028,7 @@ sioprobe(dev)
failures[0] = inb(iobase + com_cfcr) - CFCR_8BITS;
failures[1] = inb(iobase + com_ier) - IER_ETXRDY;
failures[2] = inb(iobase + com_mcr) - mcr_image;
- DELAY(1000); /* XXX */
+ DELAY(10000); /* Some internal modems need this time */
if (idev->id_irq != 0)
#ifdef PC98
failures[3] = pc98_irq_pending(idev) ? 0 : 1;
@@ -1082,11 +1068,6 @@ sioprobe(dev)
#endif
failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
-#ifdef PC98
- outb(IO_ICU1 + 2, imen); /* XXX */
-#else
- outb(IO_ICU1 + 1, imen); /* XXX */
-#endif
enable_intr();
result = IO_COMSIZE;
@@ -1868,32 +1849,6 @@ siodtrwakeup(chan)
wakeup(&com->dtr_wait);
}
-/* Interrupt routine for timekeeping purposes */
-void
-siointrts(unit)
- int unit;
-{
- /*
- * XXX microtime() reenables CPU interrupts. We can't afford to
- * be interrupted and don't want to slow down microtime(), so lock
- * out interrupts in another way.
- */
-#ifdef PC98
- outb(IO_ICU1 + 2, 0xff);
-#else /* IBM-PC */
- outb(IO_ICU1 + 1, 0xff);
-#endif /* PC98 */
- microtime(&intr_timestamp);
- disable_intr();
-#ifdef PC98
- outb(IO_ICU1 + 2, imen);
-#else /* IBM_PC */
- outb(IO_ICU1 + 1, imen);
-#endif /* PC98 */
-
- siointr(unit);
-}
-
void
siointr(unit)
int unit;
@@ -1947,9 +1902,6 @@ siointr1(com)
recv_data=0;
#endif /* PC98 */
- if (com->do_timestamp)
- /* XXX a little bloat here... */
- com->timestamp = intr_timestamp;
while (TRUE) {
#ifdef PC98
status_read:;
@@ -2024,6 +1976,8 @@ more_intr:
if (ioptr >= com->ibufend)
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
else {
+ if (com->do_timestamp)
+ microtime(&com->timestamp);
++com_events;
schedsofttty();
#if 0 /* for testing input latency vs efficiency */
@@ -2064,6 +2018,11 @@ cont:
#endif
modem_status = inb(com->modem_status_port);
if (modem_status != com->last_modem_status) {
+ if (com->do_dcd_timestamp
+ && !(com->last_modem_status & MSR_DCD)
+ && modem_status & MSR_DCD)
+ microtime(&com->dcd_timestamp);
+
/*
* Schedule high level to handle DCD changes. Note
* that we don't use the delta bits anywhere. Some
@@ -2115,11 +2074,7 @@ cont:
com->obufq.l_head = ioptr;
if (ioptr >= com->obufq.l_tail) {
struct lbq *qp;
-#ifdef PC98
- if(IS_8251(com->pc98_if_type))
- if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
- com_int_Tx_disable(com);
-#endif
+
qp = com->obufq.l_next;
qp->l_queued = FALSE;
qp = qp->l_next;
@@ -2130,6 +2085,11 @@ cont:
} else {
/* output just completed */
com->state &= ~CS_BUSY;
+#if defined(PC98)
+ if(IS_8251(com->pc98_if_type))
+ if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
+ com_int_Tx_disable(com);
+#endif
}
if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS;
@@ -2331,6 +2291,10 @@ sioioctl(dev, cmd, data, flag, p)
com->do_timestamp = TRUE;
*(struct timeval *)data = com->timestamp;
break;
+ case TIOCDCDTIMESTAMP:
+ com->do_dcd_timestamp = TRUE;
+ *(struct timeval *)data = com->dcd_timestamp;
+ break;
default:
splx(s);
return (ENOTTY);
@@ -3199,9 +3163,6 @@ static void
siocntxwait()
{
int timo;
-#ifdef PC98
- int tmp;
-#endif
/*
* Wait for any pending transmission to finish. Required to avoid
@@ -3551,8 +3512,6 @@ pc98_get_modem_status(struct com_s *com)
int stat, stat2;
register int msr;
- int ret;
-
stat = inb(com->sts_port);
stat2 = inb(com->in_modem_port);
msr = com->pc98_prev_modem_status
@@ -3763,7 +3722,7 @@ static void
com_cflag_and_speed_set( struct com_s *com, int cflag, int speed)
{
int cfcr=0, count;
- int s, previnterrupt;
+ int previnterrupt;
count = pc98_ttspeedtab( com, speed );
if ( count < 0 ) return;
diff --git a/sys/pc98/pc98/sound/dmabuf.c b/sys/pc98/pc98/sound/dmabuf.c
index ee88219..259f781 100644
--- a/sys/pc98/pc98/sound/dmabuf.c
+++ b/sys/pc98/pc98/sound/dmabuf.c
@@ -678,8 +678,9 @@ DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
{
int chan = audio_devs[dev]->dmachan;
struct dma_buffparms *dmap = audio_devs[dev]->dmap;
+#ifdef linux
unsigned long flags;
-
+#endif
/*
* This function is not as portable as it should be.
*/
diff --git a/sys/pc98/pc98/spkr.c b/sys/pc98/pc98/spkr.c
index ac1d3c3..f931d86 100644
--- a/sys/pc98/pc98/spkr.c
+++ b/sys/pc98/pc98/spkr.c
@@ -4,12 +4,12 @@
* v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993
* modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su>
*
- * $Id: spkr.c,v 1.24 1996/03/27 19:07:33 bde Exp $
+ * $Id: spkr.c,v 1.1.1.1 1996/06/14 10:04:46 asami Exp $
*/
/*
* modified for PC98
- * $Id: spkr.c,v 1.2 1994/03/14 09:53:38 kakefuda Exp $
+ * $Id: spkr.c,v 1.1.1.1 1996/06/14 10:04:46 asami Exp $
*/
#include "speaker.h"
@@ -115,9 +115,10 @@ static void playtone __P((int pitch, int value, int sustain));
static int abs __P((int n));
static void playstring __P((char *cp, size_t slen));
-static void tone(thz, ticks)
/* emit tone of frequency thz for given number of ticks */
-unsigned int thz, ticks;
+static void
+tone(thz, ticks)
+ unsigned int thz, ticks;
{
unsigned int divisor;
int sps;
@@ -139,7 +140,7 @@ unsigned int thz, ticks;
#endif /* DEBUG */
/* set timer to generate clicks at given frequency in Hertz */
- sps = spltty();
+ sps = splclock();
#ifdef PC98
if (acquire_timer1(PIT_MODE)) {
@@ -147,8 +148,11 @@ unsigned int thz, ticks;
if (acquire_timer2(PIT_MODE)) {
#endif
/* enter list of waiting procs ??? */
+ splx(sps);
return;
}
+ splx(sps);
+ disable_intr();
#ifdef PC98
outb(PIT_COUNT, (divisor & 0xff)); /* send lo byte */
outb(PIT_COUNT, (divisor >> 8)); /* send hi byte */
@@ -156,7 +160,7 @@ unsigned int thz, ticks;
outb(TIMER_CNTR2, (divisor & 0xff)); /* send lo byte */
outb(TIMER_CNTR2, (divisor >> 8)); /* send hi byte */
#endif
- splx(sps);
+ enable_intr();
/* turn the speaker on */
#ifdef PC98
@@ -174,16 +178,21 @@ unsigned int thz, ticks;
tsleep((caddr_t)&endtone, SPKRPRI | PCATCH, "spkrtn", ticks);
#ifdef PC98
outb(IO_PPI, inb(IO_PPI) | PPI_SPKR);
+ sps = splclock();
release_timer1();
+ splx(sps);
#else
outb(IO_PPI, inb(IO_PPI) & ~PPI_SPKR);
+ sps = splclock();
release_timer2();
+ splx(sps);
#endif
}
-static void rest(ticks)
/* rest for given number of ticks */
-int ticks;
+static void
+rest(ticks)
+ int ticks;
{
/*
* Set timeout to endrest function, then give up the timeslice.
@@ -260,7 +269,8 @@ static int pitchtab[] =
/* 6 */ 4186, 4435, 4698, 4978, 5274, 5588, 5920, 6272, 6644, 7040, 7459, 7902,
};
-static void playinit()
+static void
+playinit()
{
octave = DFLT_OCTAVE;
whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
@@ -270,9 +280,10 @@ static void playinit()
octprefix = TRUE; /* act as though there was an initial O(n) */
}
-static void playtone(pitch, value, sustain)
/* play tone of proper duration for current rhythm signature */
-int pitch, value, sustain;
+static void
+playtone(pitch, value, sustain)
+ int pitch, value, sustain;
{
register int sound, silence, snum = 1, sdenom = 1;
@@ -306,8 +317,9 @@ int pitch, value, sustain;
}
}
-static int abs(n)
-int n;
+static int
+abs(n)
+ int n;
{
if (n < 0)
return(-n);
@@ -315,10 +327,11 @@ int n;
return(n);
}
-static void playstring(cp, slen)
/* interpret and play an item from a notation string */
-char *cp;
-size_t slen;
+static void
+playstring(cp, slen)
+ char *cp;
+ size_t slen;
{
int pitch, oldfill, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
@@ -515,11 +528,12 @@ size_t slen;
static int spkr_active = FALSE; /* exclusion flag */
static struct buf *spkr_inbuf; /* incoming buf */
-int spkropen(dev, flags, fmt, p)
-dev_t dev;
-int flags;
-int fmt;
-struct proc *p;
+int
+spkropen(dev, flags, fmt, p)
+ dev_t dev;
+ int flags;
+ int fmt;
+ struct proc *p;
{
#ifdef DEBUG
(void) printf("spkropen: entering with dev = %x\n", dev);
@@ -541,10 +555,11 @@ struct proc *p;
}
}
-int spkrwrite(dev, uio, ioflag)
-dev_t dev;
-struct uio *uio;
-int ioflag;
+int
+spkrwrite(dev, uio, ioflag)
+ dev_t dev;
+ struct uio *uio;
+ int ioflag;
{
#ifdef DEBUG
printf("spkrwrite: entering with dev = %x, count = %d\n",
@@ -569,11 +584,12 @@ int ioflag;
}
}
-int spkrclose(dev, flags, fmt, p)
-dev_t dev;
-int flags;
-int fmt;
-struct proc *p;
+int
+spkrclose(dev, flags, fmt, p)
+ dev_t dev;
+ int flags;
+ int fmt;
+ struct proc *p;
{
#ifdef DEBUG
(void) printf("spkrclose: entering with dev = %x\n", dev);
@@ -591,12 +607,13 @@ struct proc *p;
}
}
-int spkrioctl(dev, cmd, cmdarg, flags, p)
-dev_t dev;
-int cmd;
-caddr_t cmdarg;
-int flags;
-struct proc *p;
+int
+spkrioctl(dev, cmd, cmdarg, flags, p)
+ dev_t dev;
+ int cmd;
+ caddr_t cmdarg;
+ int flags;
+ struct proc *p;
{
#ifdef DEBUG
(void) printf("spkrioctl: entering with dev = %x, cmd = %x\n");
@@ -639,7 +656,8 @@ struct proc *p;
static spkr_devsw_installed = 0;
-static void spkr_drvinit(void *unused)
+static void
+spkr_drvinit(void *unused)
{
dev_t dev;
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c
index 706a8e1..a22252a 100644
--- a/sys/pc98/pc98/syscons.c
+++ b/sys/pc98/pc98/syscons.c
@@ -25,7 +25,7 @@
* (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: syscons.c,v 1.150 1996/05/27 06:02:52 peter Exp $
+ * $Id: syscons.c,v 1.1.1.1 1996/06/14 10:04:47 asami Exp $
*/
#include "sc.h"
@@ -54,6 +54,7 @@
#include <machine/clock.h>
#include <machine/cons.h>
#include <machine/console.h>
+#include <machine/md_var.h>
#include <machine/psl.h>
#include <machine/frame.h>
#include <machine/pc/display.h>
@@ -110,7 +111,9 @@ static default_attr kernel_default = {
static scr_stat main_console;
static scr_stat *console[MAXCONS];
+#ifdef DEVFS
static void *sc_devfs_token[MAXCONS];
+#endif
scr_stat *cur_console;
static scr_stat *new_scp, *old_scp;
static term_stat kernel_console;
@@ -142,10 +145,7 @@ static long scrn_time_stamp;
#ifndef PC98
static char *video_mode_ptr = NULL;
#endif
-#if ASYNCH
-static u_char kbd_reply = 0;
-#endif
-
+static char *cut_buffer;
static u_short mouse_and_mask[16] = {
0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80,
0xfe00, 0x1e00, 0x1f00, 0x0f00, 0x0f00, 0x0000, 0x0000, 0x0000
@@ -159,19 +159,6 @@ static void none_saver(int blank) { }
void (*current_saver) __P((int blank)) = none_saver;
-#ifdef PC98
-static int scattach(struct pc98_device *dev);
-#else
-static int scattach(struct isa_device *dev);
-#endif
-static int scparam(struct tty *tp, struct termios *t);
-#ifdef PC98
-static int scprobe(struct pc98_device *dev);
-#else
-static int scprobe(struct isa_device *dev);
-#endif
-static void scstart(struct tty *tp);
-
/* OS specific stuff */
#ifdef not_yet_done
#define VIRTUAL_TTY(x) (sccons[x] = ttymalloc(sccons[x]))
@@ -202,6 +189,56 @@ u_short *Crtat;
+ (offset)) % (scp->history_size)))
#endif
+/* prototypes */
+#ifdef PC98
+static int scattach(struct pc98_device *dev);
+#else
+static int scattach(struct isa_device *dev);
+#endif
+static int scparam(struct tty *tp, struct termios *t);
+#ifdef PC98
+static int scprobe(struct pc98_device *dev);
+#else
+static int scprobe(struct isa_device *dev);
+#endif
+static void scstart(struct tty *tp);
+static void scinit(void);
+static u_int scgetc(int noblock);
+static scr_stat *get_scr_stat(dev_t dev);
+static scr_stat *alloc_scp(void);
+static void init_scp(scr_stat *scp);
+static int get_scr_num(void);
+static void scrn_timer(void);
+static void clear_screen(scr_stat *scp);
+static int switch_scr(scr_stat *scp, u_int next_scr);
+static void exchange_scr(void);
+static inline void move_crsr(scr_stat *scp, int x, int y);
+static void scan_esc(scr_stat *scp, u_char c);
+static inline void draw_cursor(scr_stat *scp, int show);
+static void ansi_put(scr_stat *scp, u_char *buf, int len);
+static u_char *get_fstr(u_int c, u_int *len);
+static void update_leds(int which);
+static void history_to_screen(scr_stat *scp);
+static int history_up_line(scr_stat *scp);
+static int history_down_line(scr_stat *scp);
+static void kbd_wait(void);
+static void kbd_cmd(u_char command);
+static void set_mode(scr_stat *scp);
+static void set_vgaregs(char *modetable);
+static void set_font_mode(void);
+static void set_normal_mode(void);
+static void copy_font(int operation, int font_type, char* font_image);
+static void set_destructive_cursor(scr_stat *scp, int force);
+static void set_mouse_pos(scr_stat *scp);
+static void reverse_mouse_cut(scr_stat *scp, int cut);
+static void mouse_cut_start(scr_stat *scp);
+static void mouse_cut_end(scr_stat *scp);
+static void mouse_paste(scr_stat *scp);
+static void draw_mouse_image(scr_stat *scp);
+static void save_palette(void);
+static void do_bell(scr_stat *scp, int pitch, int duration);
+static void blink_screen(scr_stat *scp);
+
#ifdef PC98
struct pc98_driver scdriver = {
#else
@@ -346,8 +383,14 @@ draw_cursor(scr_stat *scp, int show)
static inline void
move_crsr(scr_stat *scp, int x, int y)
{
- if (x < 0 || y < 0 || x >= scp->xsize || y >= scp->ysize)
- return;
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+ if (x >= scp->xsize)
+ x = scp->xsize-1;
+ if (y >= scp->ysize)
+ y = scp->ysize-1;
scp->xpos = x;
scp->ypos = y;
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
@@ -371,12 +414,12 @@ scprobe(struct pc98_device *dev)
scprobe(struct isa_device *dev)
#endif
{
- int i, j, retries = 5;
- unsigned char val;
-
#ifdef PC98
return(16);
#else
+ int i, j, retries = 5;
+ unsigned char val;
+
/* Enable interrupts and keyboard controller */
kbd_wait();
outb(KB_STAT, KB_WRITE);
@@ -385,7 +428,7 @@ scprobe(struct isa_device *dev)
/* flush any noise in the buffer */
while (inb(KB_STAT) & KB_BUF_FULL) {
- DELAY(10);
+ DELAY(100);
(void) inb(KB_DATA);
}
@@ -393,8 +436,8 @@ scprobe(struct isa_device *dev)
while (retries--) {
kbd_wait();
outb(KB_DATA, KB_RESET);
- for (i=0; i<100000; i++) {
- DELAY(10);
+ for (i=0; i<10000; i++) {
+ DELAY(100);
val = inb(KB_DATA);
if (val == KB_ACK || val == KB_ECHO)
goto gotres;
@@ -408,10 +451,10 @@ gotres:
else {
i = 10; /* At most 10 retries. */
gotack:
- DELAY(10);
- j = 1000; /* Wait at most 10 ms (supposedly). */
- while ((inb(KB_STAT) & KB_BUF_FULL) == 0 && --j > 0) DELAY(10);
- DELAY(10);
+ DELAY(100);
+ j = 1000; /* Wait at most 1 s. */
+ while ((inb(KB_STAT) & KB_BUF_FULL) == 0 && --j > 0) DELAY(1000);
+ DELAY(1000);
val = inb(KB_DATA);
if (val == KB_ACK && --i > 0)
goto gotack;
@@ -496,12 +539,13 @@ scattach(struct isa_device *dev)
#ifndef PC98
if (crtc_vga) {
+ cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT);
font_8 = (char *)malloc(8*256, M_DEVBUF, M_NOWAIT);
font_14 = (char *)malloc(14*256, M_DEVBUF, M_NOWAIT);
font_16 = (char *)malloc(16*256, M_DEVBUF, M_NOWAIT);
copy_font(SAVE, FONT_16, font_16);
fonts_loaded = FONT_16;
- scp->font = FONT_16;
+ scp->font_size = FONT_16;
save_palette();
}
#endif
@@ -873,22 +917,26 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
case CONS_MOUSECTL: /* control mouse arrow */
{
mouse_info_t *mouse = (mouse_info_t*)data;
- int fontsize;
-
- switch (scp->font) {
- default:
- case FONT_8:
- fontsize = 8; break;
- case FONT_14:
- fontsize = 14; break;
- case FONT_16:
- fontsize = 16; break;
- }
+
switch (mouse->operation) {
+ case MOUSE_MODE:
+ if (mouse->u.mode.signal > 0 && mouse->u.mode.signal < NSIG) {
+ scp->mouse_signal = mouse->u.mode.signal;
+ scp->mouse_proc = p;
+ scp->mouse_pid = p->p_pid;
+ }
+ else {
+ scp->mouse_signal = 0;
+ scp->mouse_proc = NULL;
+ scp->mouse_pid = 0;
+ }
+ return 0;
+
case MOUSE_SHOW:
if (!(scp->status & MOUSE_ENABLED)) {
+ scp->status |= MOUSE_ENABLED;
scp->mouse_oldpos = Crtat + (scp->mouse_pos - scp->scr_buf);
- scp->status |= (UPDATE_MOUSE | MOUSE_ENABLED);
+ mark_all(scp);
}
else
return EINVAL;
@@ -897,40 +945,64 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
case MOUSE_HIDE:
if (scp->status & MOUSE_ENABLED) {
scp->status &= ~MOUSE_ENABLED;
- scp->status |= UPDATE_MOUSE;
+ mark_all(scp);
}
else
return EINVAL;
break;
case MOUSE_MOVEABS:
- scp->mouse_xpos = mouse->x;
- scp->mouse_ypos = mouse->y;
- goto set_mouse_pos;
+ scp->mouse_xpos = mouse->u.data.x;
+ scp->mouse_ypos = mouse->u.data.y;
+ set_mouse_pos(scp);
+ break;
case MOUSE_MOVEREL:
- scp->mouse_xpos += mouse->x;
- scp->mouse_ypos += mouse->y;
-set_mouse_pos:
- if (scp->mouse_xpos < 0)
- scp->mouse_xpos = 0;
- if (scp->mouse_ypos < 0)
- scp->mouse_ypos = 0;
- if (scp->mouse_xpos >= scp->xsize*8)
- scp->mouse_xpos = (scp->xsize*8)-1;
- if (scp->mouse_ypos >= scp->ysize*fontsize)
- scp->mouse_ypos = (scp->ysize*fontsize)-1;
- scp->mouse_pos = scp->scr_buf +
- (scp->mouse_ypos/fontsize)*scp->xsize + scp->mouse_xpos/8;
- if (scp->status & MOUSE_ENABLED)
- scp->status |= UPDATE_MOUSE;
+ scp->mouse_xpos += mouse->u.data.x;
+ scp->mouse_ypos += mouse->u.data.y;
+ set_mouse_pos(scp);
break;
- case MOUSE_GETPOS:
- mouse->x = scp->mouse_xpos;
- mouse->y = scp->mouse_ypos;
+ case MOUSE_GETINFO:
+ mouse->u.data.x = scp->mouse_xpos;
+ mouse->u.data.y = scp->mouse_ypos;
+ mouse->u.data.buttons = scp->mouse_buttons;
return 0;
+ case MOUSE_ACTION:
+ /* this should maybe only be settable from /dev/console SOS */
+ cur_console->mouse_xpos += mouse->u.data.x;
+ cur_console->mouse_ypos += mouse->u.data.y;
+ if (cur_console->mouse_signal) {
+ cur_console->mouse_buttons = mouse->u.data.buttons;
+ /* has controlling process died? */
+ if (cur_console->mouse_proc &&
+ (cur_console->mouse_proc != pfind(cur_console->mouse_pid))){
+ cur_console->mouse_signal = 0;
+ cur_console->mouse_proc = NULL;
+ cur_console->mouse_pid = 0;
+ }
+ else
+ psignal(cur_console->mouse_proc, cur_console->mouse_signal);
+ }
+ else {
+ /* process button presses*/
+ if (cur_console->mouse_buttons != mouse->u.data.buttons) {
+ cur_console->mouse_buttons = mouse->u.data.buttons;
+ if (!(scp->status & UNKNOWN_MODE)) {
+ if (cur_console->mouse_buttons & LEFT_BUTTON)
+ mouse_cut_start(cur_console);
+ else
+ mouse_cut_end(cur_console);
+ if (cur_console->mouse_buttons & RIGHT_BUTTON)
+ mouse_paste(cur_console);
+ }
+ }
+ }
+ if (mouse->u.data.x != 0 || mouse->u.data.y != 0)
+ set_mouse_pos(cur_console);
+ break;
+
default:
return EINVAL;
}
@@ -1053,10 +1125,13 @@ set_mouse_pos:
break;
}
scp->mode = cmd & 0xff;
- scp->status &= ~UNKNOWN_MODE; /* text mode */
+ scp->status &= ~UNKNOWN_MODE;
free(scp->scr_buf, M_DEVBUF);
scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
M_DEVBUF, M_WAITOK);
+ free(cut_buffer, M_DEVBUF);
+ cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT);
+ cut_buffer[0] = 0x00;
if (scp == cur_console)
set_mode(scp);
clear_screen(scp);
@@ -1538,7 +1613,7 @@ sccnputc(dev_t dev, int c)
kernel_console = scp->term;
current_default = &user_default;
scp->term = save;
- s = splclock(); /* XXX stop scrn_timer */
+ s = splclock();
if (scp == cur_console) {
if (scp->scr_buf != Crtat && (scp->start <= scp->end)) {
bcopyw(scp->scr_buf + scp->start, Crtat + scp->start,
@@ -1575,6 +1650,7 @@ static void
scrn_timer()
{
static int cursor_blinkrate;
+ static int last_mouse_x = -1, last_mouse_y = -1;
scr_stat *scp = cur_console;
/* should we just return ? */
@@ -1595,10 +1671,15 @@ scrn_timer()
scp->status &= ~CURSOR_SHOWN;
scp->start = scp->xsize * scp->ysize;
scp->end = 0;
+ last_mouse_x = last_mouse_y = -1;
}
/* update "pseudo" mouse arrow */
- if ((scp->status & MOUSE_ENABLED) && (scp->status & UPDATE_MOUSE))
+ if ((scp->status & MOUSE_ENABLED) &&
+ (scp->mouse_xpos!=last_mouse_x || scp->mouse_xpos!=last_mouse_x)) {
+ last_mouse_x = scp->mouse_xpos;
+ last_mouse_y = scp->mouse_ypos;
draw_mouse_image(scp);
+ }
/* update cursor image */
if (scp->status & CURSOR_ENABLED)
@@ -1716,13 +1797,7 @@ exchange_scr(void)
shfts = ctls = alts = agrs = metas = 0;
update_leds(new_scp->status);
delayed_next_scr = FALSE;
- bcopyw(new_scp->scr_buf, Crtat,
- (new_scp->xsize*new_scp->ysize)*sizeof(u_short));
-#ifdef PC98
- bcopyw(new_scp->atr_buf, Atrat,
- (new_scp->xsize*new_scp->ysize)*sizeof(u_short));
-#endif
- new_scp->status &= ~CURSOR_SHOWN;
+ mark_all(new_scp);
}
static void
@@ -2175,15 +2250,12 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->xsize - scp->xpos;
#ifdef PC98
fillw(scr_map[0x20],
- scp->scr_buf + scp->xpos +
- ((scp->xsize*scp->ypos) * sizeof(u_short)), n);
+ scp->cursor_pos, n);
fillw(at2pc98(scp->term.cur_color),
- scp->atr_buf + scp->xpos +
- ((scp->xsize*scp->ypos) * sizeof(u_short)), n);
+ scp->cursor_atr, n);
#else
fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf + scp->xpos +
- ((scp->xsize*scp->ypos) * sizeof(u_short)), n);
+ scp->cursor_pos, n);
#endif
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
#ifdef PC98
@@ -2790,6 +2862,9 @@ kanji_end:
}
/* do we have to scroll ?? */
if (scp->cursor_pos >= scp->scr_buf + scp->ysize * scp->xsize) {
+ reverse_mouse_cut(scp, 0);
+ scp->mouse_cut_start = scp->mouse_cut_end = NULL;
+ scp->status &= ~MOUSE_CUTTING;
if (scp->history) {
bcopyw(scp->scr_buf, scp->history_head,
scp->xsize * sizeof(u_short));
@@ -2982,7 +3057,7 @@ static scr_stat
scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
init_scp(scp);
- scp->scr_buf = scp->cursor_pos = scp->scr_buf = scp->mouse_pos =
+ scp->scr_buf = scp->cursor_pos = scp->mouse_pos =
(u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
M_DEVBUF, M_WAITOK);
#ifdef PC98
@@ -3014,7 +3089,7 @@ init_scp(scr_stat *scp)
#else
scp->mode = M_PC98_80x25;
#endif
- scp->font = FONT_16;
+ scp->font_size = FONT_16;
scp->xsize = COL;
scp->ysize = ROW;
scp->start = COL * ROW;
@@ -3034,6 +3109,10 @@ init_scp(scr_stat *scp)
scp->cursor_end = *(char *)pa_to_va(0x460);
#endif
scp->mouse_xpos = scp->mouse_ypos = 0;
+ scp->mouse_cut_start = scp->mouse_cut_end = NULL;
+ scp->mouse_signal = 0;
+ scp->mouse_pid = 0;
+ scp->mouse_proc = NULL;
scp->bell_pitch = BELL_PITCH;
scp->bell_duration = BELL_DURATION;
#ifdef PC98
@@ -3180,14 +3259,7 @@ next_code:
if (cur_console->status & KBD_RAW_MODE)
return scancode;
-#if ASYNCH
- if (scancode == KB_ACK || scancode == KB_RESEND) {
- kbd_reply = scancode;
- if (noblock)
- return(NOKEY);
- goto next_code;
- }
-#endif
+
keycode = scancode & 0x7F;
switch (esc_flag) {
case 0x00: /* normal scancode */
@@ -3682,40 +3754,29 @@ kbd_wait(void)
#ifdef PC98
DELAY(30);
#else
- int i = 1000;
+ int i = 500;
while (i--) {
if ((inb(KB_STAT) & KB_READY) == 0)
break;
- DELAY (10);
+ DELAY (25);
}
#endif
}
+#ifndef PC98
static void
kbd_cmd(u_char command)
{
-#ifndef PC98
- int retry = 5;
+ int i, retry = 5;
do {
- int i = 100000;
-
kbd_wait();
-#if ASYNCH
- kbd_reply = 0;
- outb(KB_DATA, command);
- while (i--) {
- if (kbd_reply == KB_ACK)
- return;
- if (kbd_reply == KB_RESEND)
- break;
- }
-#else
outb(KB_DATA, command);
+ i = 50000;
while (i--) {
if (inb(KB_STAT) & KB_BUF_FULL) {
int val;
- DELAY(10);
+ DELAY(25);
val = inb(KB_DATA);
if (val == KB_ACK)
return;
@@ -3723,10 +3784,9 @@ kbd_cmd(u_char command)
break;
}
}
-#endif
} while (retry--);
-#endif
}
+#endif
static void
set_mode(scr_stat *scp)
@@ -3831,16 +3891,16 @@ setup_mode:
switch (font_size) {
case 0x10:
outb(TSIDX, 0x03); outb(TSREG, 0x00); /* font 0 */
- scp->font = FONT_16;
+ scp->font_size = FONT_16;
break;
case 0x0E:
outb(TSIDX, 0x03); outb(TSREG, 0x05); /* font 1 */
- scp->font = FONT_14;
+ scp->font_size = FONT_14;
break;
default:
case 0x08:
outb(TSIDX, 0x03); outb(TSREG, 0x0A); /* font 2 */
- scp->font = FONT_8;
+ scp->font_size = FONT_8;
break;
}
if (configuration & CHAR_CURSOR)
@@ -3853,6 +3913,7 @@ setup_mode:
case M_BG640x480: case M_CG640x480: case M_VGA_CG320:
set_vgaregs(video_mode_ptr + (scp->mode * 64));
+ scp->font_size = FONT_NONE;
break;
default:
@@ -3879,10 +3940,10 @@ set_border(int color)
#endif
}
+#ifndef PC98
static void
set_vgaregs(char *modetable)
{
-#ifndef PC98
int i, s = splhigh();
outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
@@ -3914,13 +3975,11 @@ set_vgaregs(char *modetable)
inb(crtc_addr+6); /* reset flip-flop */
outb(ATC ,0x20); /* enable palette */
splx(s);
-#endif
}
static void
set_font_mode()
{
-#ifndef PC98
/* setup vga for loading fonts (graphics plane mode) */
inb(crtc_addr+6);
outb(ATC, 0x30); outb(ATC, 0x01);
@@ -3937,13 +3996,11 @@ set_font_mode()
outw(GDCIDX, 0x0005);
outw(GDCIDX, 0x0506); /* addr = a0000, 64kb */
#endif
-#endif
}
static void
set_normal_mode()
{
-#ifndef PC98
int s = splhigh();
/* setup vga for normal operation mode again */
@@ -3971,8 +4028,8 @@ set_normal_mode()
outw(GDCIDX, 0x0E06); /* addr = b8000, 32kb */
#endif
splx(s);
-#endif
}
+#endif
static void
copy_font(int operation, int font_type, char* font_image)
@@ -4018,36 +4075,50 @@ set_destructive_cursor(scr_stat *scp, int force)
#ifndef PC98
u_char cursor[32];
caddr_t address;
- int i, font_size;
+ int i;
char *font_buffer;
static u_char old_saveunder = DEAD_CHAR;
+ u_short new_saveunder;
- if (!force && (scp->cursor_saveunder & 0xFF) == old_saveunder)
+ if (!force && !(scp->status & MOUSE_ENABLED) &&
+ (scp->cursor_saveunder & 0xFF) == old_saveunder)
return;
old_saveunder = force ? DEAD_CHAR : scp->cursor_saveunder & 0xFF;
- switch (scp->font) {
+ new_saveunder = scp->cursor_saveunder;
+ switch (scp->font_size) {
default:
case FONT_8:
- font_size = 8;
font_buffer = font_8;
address = (caddr_t)VIDEOMEM + 0x8000;
break;
case FONT_14:
- font_size = 14;
font_buffer = font_14;
address = (caddr_t)VIDEOMEM + 0x4000;
break;
case FONT_16:
- font_size = 16;
font_buffer = font_16;
address = (caddr_t)VIDEOMEM;
break;
}
- bcopyw(font_buffer + ((scp->cursor_saveunder & 0xff) * font_size),
- cursor, font_size);
+ if (scp->status & MOUSE_ENABLED) {
+ if ((scp->cursor_saveunder & 0xff) == 0xd0)
+ bcopyw(&scp->mouse_cursor[0], cursor, scp->font_size);
+ else if ((scp->cursor_saveunder & 0xff) == 0xd1)
+ bcopyw(&scp->mouse_cursor[32], cursor, scp->font_size);
+ else if ((scp->cursor_saveunder & 0xff) == 0xd2)
+ bcopyw(&scp->mouse_cursor[64], cursor, scp->font_size);
+ else if ((scp->cursor_saveunder & 0xff) == 0xd3)
+ bcopyw(&scp->mouse_cursor[96], cursor, scp->font_size);
+ else
+ bcopyw(font_buffer + ((scp->cursor_saveunder&0xff)*scp->font_size),
+ cursor, scp->font_size);
+ }
+ else
+ bcopyw(font_buffer + ((scp->cursor_saveunder&0xff) * scp->font_size),
+ cursor, scp->font_size);
for (i=0; i<32; i++)
if ((i >= scp->cursor_start && i <= scp->cursor_end) ||
- (scp->cursor_start >= font_size && i == font_size - 1))
+ (scp->cursor_start >= scp->font_size && i == scp->font_size - 1))
cursor[i] |= 0xff;
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
set_font_mode();
@@ -4057,39 +4128,151 @@ set_destructive_cursor(scr_stat *scp, int force)
}
static void
+set_mouse_pos(scr_stat *scp)
+{
+ /*
+ * the margins imposed here are not ideal, we loose
+ * a couble of pixels on the borders..
+ */
+ if (scp->mouse_xpos < 0)
+ scp->mouse_xpos = 0;
+ if (scp->mouse_ypos < 0)
+ scp->mouse_ypos = 0;
+ if (scp->mouse_xpos > (scp->xsize*8)-2)
+ scp->mouse_xpos = (scp->xsize*8)-2;
+ if (scp->mouse_ypos > (scp->ysize*scp->font_size)-2)
+ scp->mouse_ypos = (scp->ysize*scp->font_size)-2;
+
+ if (scp->status & UNKNOWN_MODE)
+ return;
+
+ scp->mouse_pos = scp->scr_buf +
+ ((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8);
+
+ if ((scp->status & MOUSE_ENABLED) && (scp->status & MOUSE_CUTTING)) {
+ int s = splclock();
+ reverse_mouse_cut(scp, 0);
+ scp->mouse_cut_end = scp->mouse_pos;
+ reverse_mouse_cut(scp, 1);
+ mark_all(scp);
+ splx(s);
+ }
+}
+
+static void
+reverse_mouse_cut(scr_stat *scp, int cut)
+{
+ ushort *ptr;
+ int i = 0;
+
+ if (scp->mouse_cut_start != NULL && scp->mouse_cut_end != NULL) {
+ for (ptr = (scp->mouse_cut_start > scp->mouse_cut_end
+ ? scp->mouse_cut_end : scp->mouse_cut_start);
+ ptr <= (scp->mouse_cut_start > scp->mouse_cut_end
+ ? scp->mouse_cut_start : scp->mouse_cut_end);
+ ptr++) {
+ *ptr = (*ptr & 0x88ff) | (*ptr & 0x7000)>>4 | (*ptr & 0x0700)<<4;
+ if (cut) {
+ cut_buffer[i++] = *ptr & 0xff;
+ if (((ptr - scp->scr_buf) % scp->xsize) == (scp->xsize - 1)) {
+ cut_buffer[i++] = '\n';
+ }
+ }
+ }
+ if (cut)
+ cut_buffer[i] = 0x00;
+ }
+}
+
+static void
+mouse_cut_start(scr_stat *scp)
+{
+ int i;
+
+ if (scp->status & MOUSE_ENABLED) {
+ reverse_mouse_cut(scp, 0);
+ if (scp->mouse_pos == scp->mouse_cut_start &&
+ scp->mouse_cut_start == scp->mouse_cut_end) {
+ scp->mouse_cut_end = NULL;
+ cut_buffer[0] = 0x00;
+ scp->status &= ~MOUSE_CUTTING;
+ mark_all(scp);
+ }
+ else {
+ scp->mouse_cut_start = scp->mouse_cut_end = scp->mouse_pos;
+ *scp->mouse_cut_start = (*scp->mouse_cut_start & 0x88ff) |
+ (*scp->mouse_cut_start & 0x7000) >> 4 |
+ (*scp->mouse_cut_start & 0x0700) << 4;
+ cut_buffer[0] = *scp->mouse_cut_start & 0xff;
+ cut_buffer[1] = 0x00;
+ scp->status |= MOUSE_CUTTING;
+ mark_for_update(scp, scp->mouse_cut_start - scp->scr_buf);
+ set_mouse_pos(scp);
+ }
+ /* delete all other screens cut markings */
+ for (i=0; i<MAXCONS; i++) {
+ if (console[i] == NULL || console[i] == scp)
+ continue;
+ reverse_mouse_cut(console[i], 0);
+ console[i]->status &= ~MOUSE_CUTTING;
+ console[i]->mouse_cut_start = console[i]->mouse_cut_end = NULL;
+ }
+ }
+}
+
+static void
+mouse_cut_end(scr_stat *scp)
+{
+ if (scp->status & MOUSE_ENABLED) {
+ scp->status &= ~MOUSE_CUTTING;
+ }
+}
+
+static void
+mouse_paste(scr_stat *scp)
+{
+ if (scp->status & MOUSE_ENABLED) {
+ struct tty *tp;
+ u_char *ptr = cut_buffer;
+
+ tp = VIRTUAL_TTY(get_scr_num());
+ while (*ptr)
+ (*linesw[tp->t_line].l_rint)(*ptr++, tp);
+ }
+}
+
+static void
draw_mouse_image(scr_stat *scp)
{
#ifndef PC98
caddr_t address;
- int i, font_size;
+ int i;
char *font_buffer;
u_short buffer[32];
u_short xoffset, yoffset;
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
+ u_short *ptr = scp->scr_buf + (scp->mouse_oldpos - Crtat);
+ int font_size = scp->font_size;
xoffset = scp->mouse_xpos % 8;
- switch (scp->font) {
+ switch (font_size) {
default:
case FONT_8:
- font_size = 8;
font_buffer = font_8;
yoffset = scp->mouse_ypos % 8;
address = (caddr_t)VIDEOMEM + 0x8000;
break;
case FONT_14:
- font_size = 14;
font_buffer = font_14;
yoffset = scp->mouse_ypos % 14;
address = (caddr_t)VIDEOMEM + 0x4000;
break;
case FONT_16:
- font_size = 16;
font_buffer = font_16;
yoffset = scp->mouse_ypos % 16;
address = (caddr_t)VIDEOMEM;
break;
}
-
bcopyw(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size),
&scp->mouse_cursor[0], font_size);
bcopyw(font_buffer + ((*(scp->mouse_pos+1) & 0xff) * font_size),
@@ -4098,7 +4281,6 @@ draw_mouse_image(scr_stat *scp)
&scp->mouse_cursor[64], font_size);
bcopyw(font_buffer + ((*(scp->mouse_pos+scp->xsize+1) & 0xff) * font_size),
&scp->mouse_cursor[96], font_size);
-
for (i=0; i<font_size; i++) {
buffer[i] = scp->mouse_cursor[i]<<8 | scp->mouse_cursor[i+32];
buffer[i+font_size]=scp->mouse_cursor[i+64]<<8|scp->mouse_cursor[i+96];
@@ -4114,53 +4296,51 @@ draw_mouse_image(scr_stat *scp)
scp->mouse_cursor[i+64] = (buffer[i+font_size] & 0xff00) >> 8;
scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff;
}
- if (scp->status & UPDATE_MOUSE) {
- u_short *ptr = scp->scr_buf + (scp->mouse_oldpos - Crtat);
-
- if (crt_pos != scp->mouse_oldpos) {
- *(scp->mouse_oldpos) = scp->mouse_saveunder[0];
- *(scp->mouse_oldpos+1) = scp->mouse_saveunder[1];
- *(scp->mouse_oldpos+scp->xsize) = scp->mouse_saveunder[2];
- *(scp->mouse_oldpos+scp->xsize+1) = scp->mouse_saveunder[3];
- }
- scp->mouse_saveunder[0] = *(scp->mouse_pos);
- scp->mouse_saveunder[1] = *(scp->mouse_pos+1);
- scp->mouse_saveunder[2] = *(scp->mouse_pos+scp->xsize);
- scp->mouse_saveunder[3] = *(scp->mouse_pos+scp->xsize+1);
- if ((scp->cursor_pos == (ptr)) ||
- (scp->cursor_pos == (ptr+1)) ||
- (scp->cursor_pos == (ptr+scp->xsize)) ||
- (scp->cursor_pos == (ptr+scp->xsize+1)) ||
- (scp->cursor_pos == (scp->mouse_pos)) ||
- (scp->cursor_pos == (scp->mouse_pos+1)) ||
- (scp->cursor_pos == (scp->mouse_pos+scp->xsize)) ||
- (scp->cursor_pos == (scp->mouse_pos+scp->xsize+1)))
- scp->status &= ~CURSOR_SHOWN;
+ if (crt_pos != scp->mouse_oldpos) {
+ *(scp->mouse_oldpos) = scp->mouse_saveunder[0];
+ *(scp->mouse_oldpos+1) = scp->mouse_saveunder[1];
+ *(scp->mouse_oldpos+scp->xsize) = scp->mouse_saveunder[2];
+ *(scp->mouse_oldpos+scp->xsize+1) = scp->mouse_saveunder[3];
}
+ scp->mouse_saveunder[0] = *(scp->mouse_pos);
+ scp->mouse_saveunder[1] = *(scp->mouse_pos+1);
+ scp->mouse_saveunder[2] = *(scp->mouse_pos+scp->xsize);
+ scp->mouse_saveunder[3] = *(scp->mouse_pos+scp->xsize+1);
+ if ((scp->cursor_pos == (ptr)) ||
+ (scp->cursor_pos == (ptr+1)) ||
+ (scp->cursor_pos == (ptr+scp->xsize)) ||
+ (scp->cursor_pos == (ptr+scp->xsize+1)) ||
+ (scp->cursor_pos == (scp->mouse_pos)) ||
+ (scp->cursor_pos == (scp->mouse_pos+1)) ||
+ (scp->cursor_pos == (scp->mouse_pos+scp->xsize)) ||
+ (scp->cursor_pos == (scp->mouse_pos+scp->xsize+1)))
+ scp->status &= ~CURSOR_SHOWN;
scp->mouse_oldpos = crt_pos;
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
- *(crt_pos) = (*(scp->mouse_pos)&0xff00)|0xd0;
- *(crt_pos+1) = (*(scp->mouse_pos+1)&0xff00)|0xd1;
- *(crt_pos+scp->xsize) = (*(scp->mouse_pos+scp->xsize)&0xff00)|0xd2;
- *(crt_pos+scp->xsize+1) = (*(scp->mouse_pos+scp->xsize+1)&0xff00)|0xd3;
set_font_mode();
bcopy(scp->mouse_cursor, (char *)pa_to_va(address) + 0xd0 * 32, 128);
set_normal_mode();
+ *(crt_pos) = (*(scp->mouse_pos)&0xff00)|0xd0;
+ *(crt_pos+scp->xsize) = (*(scp->mouse_pos+scp->xsize)&0xff00)|0xd2;
+ if (scp->mouse_xpos < (scp->xsize-1)*8) {
+ *(crt_pos+1) = (*(scp->mouse_pos+1)&0xff00)|0xd1;
+ *(crt_pos+scp->xsize+1) = (*(scp->mouse_pos+scp->xsize+1)&0xff00)|0xd3;
+ }
#endif
}
+#ifndef PC98
static void
save_palette(void)
{
-#ifndef PC98
int i;
outb(PALRADR, 0x00);
for (i=0x00; i<0x300; i++)
palette[i] = inb(PALDATA);
inb(crtc_addr+6); /* reset flip/flop */
-#endif
}
+#endif
void
load_palette(void)
diff --git a/sys/pc98/pc98/syscons.h b/sys/pc98/pc98/syscons.h
index ee80404..986b7cb 100644
--- a/sys/pc98/pc98/syscons.h
+++ b/sys/pc98/pc98/syscons.h
@@ -25,7 +25,7 @@
* (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: syscons.h,v 1.15 1996/01/30 22:56:11 mpp Exp $
+ * $Id: syscons.h,v 1.1.1.1 1996/06/14 10:04:47 asami Exp $
*/
#ifndef _PC98_PC98_SYSCONS_H_
@@ -62,7 +62,7 @@
#define CURSOR_ENABLED 0x00200
#define CURSOR_SHOWN 0x00400
#define MOUSE_ENABLED 0x00800
-#define UPDATE_MOUSE 0x01000
+#define MOUSE_CUTTING 0x01000
/* configuration flags */
#define VISUAL_BELL 0x00001
@@ -112,9 +112,10 @@ static unsigned int TIMER_FREQ = 2457600;
#define CONSOLE_BUFSIZE 1024
#define PCBURST 128
-#define FONT_8 0x001
-#define FONT_14 0x002
-#define FONT_16 0x004
+#define FONT_NONE 1
+#define FONT_8 8
+#define FONT_14 14
+#define FONT_16 16
#define HISTORY_SIZE 100*80
/* defines related to hardware addresses */
@@ -152,8 +153,8 @@ typedef struct term_stat {
int num_param; /* # of parameters to ESC */
int last_param; /* last parameter # */
int param[MAX_ESC_PAR]; /* contains ESC parameters */
- int cur_attr; /* current hardware attributes word */
- int attr_mask; /* current logical attributes mask */
+ int cur_attr; /* current hardware attr word */
+ int attr_mask; /* current logical attr mask */
int cur_color; /* current hardware color */
int std_color; /* normal hardware color */
int rev_color; /* reverse hardware color */
@@ -169,6 +170,7 @@ typedef struct scr_stat {
int ypos; /* current Y position */
int xsize; /* X size */
int ysize; /* Y size */
+ int font_size; /* fontsize in Y direction */
int start; /* modified area start */
int end; /* modified area end */
term_stat term; /* terminal emulation stuff */
@@ -182,12 +184,17 @@ typedef struct scr_stat {
u_short mouse_saveunder[4]; /* saved chars under mouse */
short mouse_xpos; /* mouse x coordinate */
short mouse_ypos; /* mouse y coordinate */
+ short mouse_buttons; /* mouse buttons */
u_char mouse_cursor[128]; /* mouse cursor bitmap store */
+ u_short *mouse_cut_start; /* mouse cut start pos */
+ u_short *mouse_cut_end; /* mouse cut end pos */
+ struct proc *mouse_proc; /* proc* of controlling proc */
+ pid_t mouse_pid; /* pid of controlling proc */
+ int mouse_signal; /* signal # to report with */
u_short bell_duration;
u_short bell_pitch;
u_char border; /* border color */
u_char mode; /* mode */
- u_char font; /* font on this screen */
pid_t pid; /* pid of controlling proc */
struct proc *proc; /* proc* of controlling proc */
struct vt_mode smode; /* switch mode */
@@ -216,48 +223,9 @@ typedef struct default_attr {
int rev_color; /* reverse hardware color */
} default_attr;
-/* function prototypes */
-static void scinit(void);
-static u_int scgetc(int noblock);
-static scr_stat *get_scr_stat(dev_t dev);
-static scr_stat *alloc_scp(void);
-static void init_scp(scr_stat *scp);
-static int get_scr_num(void);
-static void scrn_timer(void);
-static void clear_screen(scr_stat *scp);
-static int switch_scr(scr_stat *scp, u_int next_scr);
-static void exchange_scr(void);
-#ifdef PC98
-static void move_crsr(scr_stat *scp, int x, int y);
-#else
-static inline void move_crsr(scr_stat *scp, int x, int y);
-#endif
-static void scan_esc(scr_stat *scp, u_char c);
-#ifdef PC98
-static void draw_cursor(scr_stat *scp, int show);
-#else
-static inline void draw_cursor(scr_stat *scp, int show);
-#endif
-static void ansi_put(scr_stat *scp, u_char *buf, int len);
-static u_char *get_fstr(u_int c, u_int *len);
-static void update_leds(int which);
-static void history_to_screen(scr_stat *scp);
-static int history_up_line(scr_stat *scp);
-static int history_down_line(scr_stat *scp);
-static void kbd_wait(void);
-static void kbd_cmd(u_char command);
-static void set_mode(scr_stat *scp);
- void set_border(int color);
-static void set_vgaregs(char *modetable);
-static void set_font_mode(void);
-static void set_normal_mode(void);
-static void copy_font(int operation, int font_type, char* font_image);
-static void set_destructive_cursor(scr_stat *scp, int force);
-static void draw_mouse_image(scr_stat *scp);
-static void save_palette(void);
- void load_palette(void);
-static void do_bell(scr_stat *scp, int pitch, int duration);
-static void blink_screen(scr_stat *scp);
+void load_palette(void);
+void set_border(int color);
+
#ifdef PC98
unsigned int at2pc98(unsigned int attr);
#endif
diff --git a/sys/pc98/pc98/wcd.c b/sys/pc98/pc98/wcd.c
index 675fd55..541b28e 100644
--- a/sys/pc98/pc98/wcd.c
+++ b/sys/pc98/pc98/wcd.c
@@ -254,7 +254,7 @@ static void wcd_describe (struct wcd *t);
static int wcd_open(dev_t dev, int rawflag);
static int wcd_setchan (struct wcd *t,
u_char c0, u_char c1, u_char c2, u_char c3);
-static int wcd_eject (struct wcd *t);
+static int wcd_eject (struct wcd *t, int closeit);
static struct kern_devconf cftemplate = {
0, 0, 0, "wcd", 0, { MDDT_DISK, 0 },
@@ -744,7 +744,12 @@ int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
* by somebody (not us) in block mode. */
if ((t->flags & F_BOPEN) && t->refcnt)
return (EBUSY);
- return wcd_eject (t);
+ return wcd_eject (t, 0);
+
+ case CDIOCCLOSE:
+ if ((t->flags & F_BOPEN) && t->refcnt)
+ return (0);
+ return wcd_eject (t, 1);
case CDIOREADTOCHEADER:
if (! t->toc.hdr.ending_track)
@@ -1072,7 +1077,7 @@ static int wcd_setchan (struct wcd *t,
0, (char*) &t->au, - sizeof (t->au));
}
-static int wcd_eject (struct wcd *t)
+static int wcd_eject (struct wcd *t, int closeit)
{
struct atapires result;
@@ -1085,12 +1090,16 @@ static int wcd_eject (struct wcd *t)
if (result.code == RES_ERR &&
((result.error & AER_SKEY) == AER_SK_NOT_READY ||
(result.error & AER_SKEY) == AER_SK_UNIT_ATTENTION)) {
+ int err;
+
+ if (!closeit)
+ return (0);
/*
* The disc was unloaded.
* Load it (close tray).
* Read the table of contents.
*/
- int err = wcd_request_wait (t, ATAPI_START_STOP,
+ err = wcd_request_wait (t, ATAPI_START_STOP,
0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0);
if (err)
return (err);
@@ -1110,6 +1119,9 @@ static int wcd_eject (struct wcd *t)
return (EIO);
}
+ if (closeit)
+ return (0);
+
/* Give it some time to stop spinning. */
tsleep ((caddr_t)&lbolt, PRIBIO, "wcdej1", 0);
tsleep ((caddr_t)&lbolt, PRIBIO, "wcdej2", 0);
diff --git a/sys/pc98/pc98/wd.c b/sys/pc98/pc98/wd.c
index d7db1ea..d2bf5ae 100644
--- a/sys/pc98/pc98/wd.c
+++ b/sys/pc98/pc98/wd.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
- * $Id: wd.c,v 1.109 1996/06/08 10:03:35 bde Exp $
+ * $Id: wd.c,v 1.1.1.1 1996/06/14 10:04:48 asami Exp $
*/
/* TODO:
@@ -120,6 +120,7 @@ extern void wdstart(int ctrlr);
/* can't handle that in all cases */
#define WDOPT_32BIT 0x8000
#define WDOPT_SLEEPHACK 0x4000
+#define WDOPT_FORCEHD(x) (((x)&0x0f00)>>8)
#define WDOPT_MULTIMASK 0x00ff
@@ -334,7 +335,9 @@ static int wdcontrol(struct buf *bp);
static int wdcommand(struct disk *du, u_int cylinder, u_int head,
u_int sector, u_int count, u_int command);
static int wdsetctlr(struct disk *du);
+#if 0
static int wdwsetctlr(struct disk *du);
+#endif
static int wdgetctlr(struct disk *du);
static void wderror(struct buf *bp, struct disk *du, char *mesg);
static void wdflushirq(struct disk *du, int old_ipl);
@@ -849,7 +852,6 @@ wdstart(int ctrlr)
if (wdtab[ctrlr].b_active)
return;
#endif
-loop:
/* is there a drive for the controller to do a transfer with? */
bp = wdtab[ctrlr].controller_queue.tqh_first;
if (bp == NULL) {
@@ -1660,6 +1662,7 @@ wdsetctlr(struct disk *du)
return (0);
}
+#if 0
/*
* Wait until driver is inactive, then set up controller.
*/
@@ -1676,6 +1679,7 @@ wdwsetctlr(struct disk *du)
splx(x);
return (stat);
}
+#endif
/*
* issue READP to drive to ask it what it is.
@@ -1859,9 +1863,8 @@ failed:
#ifdef PC98
/* for larger than 40MB */
{
- long cyl = wp->wdp_fixedcyl * wp->wdp_heads * wp->wdp_sectors;
- wp->wdp_removcyl = 0; /* XXX ukai */
-#ifdef PC98
+ long cyl = wp->wdp_cylinders * wp->wdp_heads * wp->wdp_sectors;
+
if ( du->dk_unit > 1 ) {
wp->wdp_sectors = 17;
wp->wdp_heads = 8;
@@ -1869,8 +1872,8 @@ failed:
wp->wdp_sectors = bootinfo.bi_bios_geom[du->dk_unit] & 0xff;
wp->wdp_heads = (bootinfo.bi_bios_geom[du->dk_unit] >> 8) & 0xff;
}
-#endif
- wp->wdp_fixedcyl = cyl / (wp->wdp_heads * wp->wdp_sectors);
+
+ wp->wdp_cylinders = cyl / (wp->wdp_heads * wp->wdp_sectors);
}
#endif
@@ -1881,6 +1884,13 @@ failed:
du->dk_dd.d_nsectors = wp->wdp_sectors;
du->dk_dd.d_secpercyl = du->dk_dd.d_ntracks * du->dk_dd.d_nsectors;
du->dk_dd.d_secperunit = du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders;
+ if (WDOPT_FORCEHD(du->cfg_flags)) {
+ du->dk_dd.d_ntracks = WDOPT_FORCEHD(du->cfg_flags);
+ du->dk_dd.d_secpercyl =
+ du->dk_dd.d_ntracks * du->dk_dd.d_nsectors;
+ du->dk_dd.d_ncylinders =
+ du->dk_dd.d_secperunit / du->dk_dd.d_secpercyl;
+ }
#if 0
du->dk_dd.d_partitions[RAW_PART].p_size = du->dk_dd.d_secperunit;
/* dubious ... */
diff --git a/sys/sys/diskslice.h b/sys/sys/diskslice.h
index 5f8b600..0d1820a 100644
--- a/sys/sys/diskslice.h
+++ b/sys/sys/diskslice.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: diskslice.h,v 1.12 1996/01/30 23:00:31 mpp Exp $
+ * $Id: diskslice.h,v 1.13 1996/06/14 11:02:28 asami Exp $
*/
#ifndef _SYS_DISKSLICE_H_
@@ -85,6 +85,10 @@ struct diskslice {
u_long ds_offset; /* starting sector */
u_long ds_size; /* number of sectors */
int ds_type; /* (foreign) slice type */
+#ifdef PC98
+ int ds_subtype; /* sub slice type */
+ u_char ds_name[16]; /* slice name */
+#endif
struct dkbad_intern *ds_bad; /* bad sector table, if any */
void *ds_date; /* Slice type specific data */
struct slice_switch *switch; /* switch table for type handler */
OpenPOWER on IntegriCloud