summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorasami <asami@FreeBSD.org>1996-10-23 07:25:35 +0000
committerasami <asami@FreeBSD.org>1996-10-23 07:25:35 +0000
commitda2957207b1d3dec86dcf8334bc11b75a9113b84 (patch)
tree59a2eda3deec512d26d8ccb3951fd2db2f76dab6
parent326b6b4bd810b639513bd0adabaeed761886bd77 (diff)
downloadFreeBSD-src-da2957207b1d3dec86dcf8334bc11b75a9113b84.zip
FreeBSD-src-da2957207b1d3dec86dcf8334bc11b75a9113b84.tar.gz
Another round of merge.
(1) Bug fix (pass boot drive): pc98/boot/biosboot/boot2.S (2) Delete code for unsupported high-resolution modes and move old Epson notebook code to epsonio.h: pc98/boot/biosboot/io.c pc98/i386/vm_machdep.c pc98/pc98/fd.c pc98/pc98/pc98.c pc98/pc98/pc98.h pc98/pc98/epsonio.h (new) (3) Change aic driver so that PCMCIA cards (I/O port same as PC/AT) and PC-9801-100 cards can be selected with a flag in kernel config file: pc98/pc98/aic6360.c pc98/pc98/aic_98.h (new) (4) Fix wcd entry (it was broken). Delete mcd, it doesn't work on 98. Change aic entry according to above: pc98/conf/GENERIC98 (5) Move pc98_machdep.c to top of files in pc98/pc98: pc98/conf/files.pc98 (6) Delete empty lines: pc98/i386/locore.s (7) Fix (it didn't work if I586 was specified): pc98/pc98/clock.c (8) Staticize: pc98/pc98/pc98_machdep.c (9) Enable workaround for Cyrix bug for 5x86 also: pc98/i386/machdep.c pc98/i386/trap.c All the above deletes this file too: pc98/i386/pmap.c (phew!) Submitted by: The FreeBSD(98) Development Team
-rw-r--r--sys/conf/Makefile.pc9814
-rw-r--r--sys/conf/files.pc987
-rw-r--r--sys/conf/options.pc9813
-rw-r--r--sys/pc98/boot/biosboot/Makefile34
-rw-r--r--sys/pc98/boot/biosboot/boot.c16
-rw-r--r--sys/pc98/boot/biosboot/boot.h3
-rw-r--r--sys/pc98/boot/biosboot/boot2.S1
-rw-r--r--sys/pc98/boot/biosboot/disk.c14
-rw-r--r--sys/pc98/boot/biosboot/io.c7
-rw-r--r--sys/pc98/boot/rawboot/Makefile36
-rw-r--r--sys/pc98/cbus/cbus.h49
-rw-r--r--sys/pc98/cbus/clock.c56
-rw-r--r--sys/pc98/cbus/fdc.c3
-rw-r--r--sys/pc98/cbus/pcrtc.c56
-rw-r--r--sys/pc98/conf/GENERIC18
-rw-r--r--sys/pc98/conf/GENERIC9818
-rw-r--r--sys/pc98/conf/Makefile.pc9814
-rw-r--r--sys/pc98/conf/files.pc987
-rw-r--r--sys/pc98/conf/majors.pc985
-rw-r--r--sys/pc98/conf/options.pc9813
-rw-r--r--sys/pc98/i386/locore.s3
-rw-r--r--sys/pc98/i386/machdep.c5
-rw-r--r--sys/pc98/i386/pmap.c2990
-rw-r--r--sys/pc98/i386/trap.c25
-rw-r--r--sys/pc98/i386/userconfig.c175
-rw-r--r--sys/pc98/i386/vm_machdep.c6
-rw-r--r--sys/pc98/pc98/aic6360.c56
-rw-r--r--sys/pc98/pc98/aic_98.h93
-rw-r--r--sys/pc98/pc98/clock.c56
-rw-r--r--sys/pc98/pc98/epsonio.h79
-rw-r--r--sys/pc98/pc98/fd.c3
-rw-r--r--sys/pc98/pc98/if_ed.c193
-rw-r--r--sys/pc98/pc98/machdep.c5
-rw-r--r--sys/pc98/pc98/pc98.c13
-rw-r--r--sys/pc98/pc98/pc98.h49
-rw-r--r--sys/pc98/pc98/pc98_machdep.c31
-rw-r--r--sys/pc98/pc98/random_machdep.c4
-rw-r--r--sys/pc98/pc98/syscons.c65
-rw-r--r--sys/pc98/pc98/syscons.h6
-rw-r--r--sys/pc98/pc98/wd.c6
40 files changed, 705 insertions, 3542 deletions
diff --git a/sys/conf/Makefile.pc98 b/sys/conf/Makefile.pc98
index 03e5ac7..335b654 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.pc98,v 1.5 1996/09/07 02:13:25 asami Exp $
+# $Id: Makefile.pc98,v 1.6 1996/10/09 21:45:45 asami Exp $
#
# Makefile for FreeBSD
#
@@ -29,16 +29,6 @@ S= ../..
PC98= ${S}/pc98
I386= ${S}/i386
-CWARNFLAGS?= -W -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit \
- -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes \
- -Winline -Wunused -Wpointer-arith
-#
-# The following flags are next up for working on:
-# -Wall
-#
-# When working on removing warnings from code, the `-Werror' flag should be
-# of material assistance.
-#
COPTFLAGS?=-O
INCLUDES= -nostdinc -I- -I. -I$S
# This hack is to allow kernel compiles to succeed on machines w/out srcdist
@@ -190,6 +180,8 @@ vnode_if.c: $S/kern/vnode_if.sh $S/kern/vnode_if.src
vnode_if.h: $S/kern/vnode_if.sh $S/kern/vnode_if.src
sh $S/kern/vnode_if.sh $S/kern/vnode_if.src
+.include <bsd.kern.mk>
+
%RULES
# DO NOT DELETE THIS LINE -- make depend uses it
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index 1d02c57..fef4b97 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.i386,v 1.140 1996/09/11 19:53:30 phk Exp $
+# $Id: files.pc98,v 1.7 1996/09/12 11:09:18 asami Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -50,12 +50,12 @@ i386/i386/in_cksum.c optional inet
# 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
+i386/i386/perfmon.c optional perfmon profiling-routine
i386/i386/perfmon.c optional perfmon
-pc98/i386/pmap.c standard
+i386/i386/pmap.c standard
i386/i386/procfs_machdep.c standard
i386/i386/support.s standard
i386/i386/swtch.s standard
@@ -82,6 +82,7 @@ i386/ibcs2/ibcs2_errno.c optional ibcs2
i386/ibcs2/ibcs2_sysent.c optional ibcs2
i386/ibcs2/ibcs2_sysvec.c optional ibcs2
i386/ibcs2/imgact_coff.c optional ibcs2
+pc98/pc98/pc98_machdep.c standard
pc98/pc98/bs/bs.c optional bs device-driver
pc98/pc98/bs/bsfunc.c optional bs device-driver
pc98/pc98/bs/bshw.c optional bs device-driver
diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98
index 9a589f3..4374f02 100644
--- a/sys/conf/options.pc98
+++ b/sys/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.4 1996/09/12 11:09:21 asami Exp $
+# $Id: options.pc98,v 1.5 1996/10/09 21:45:47 asami Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -18,6 +18,8 @@ COMCONSOLE opt_comconsole.h
COM_ESP opt_sio.h
COM_MULTIPORT opt_sio.h
DSI_SOFT_MODEM opt_sio.h
+I586_CTR_GUPROF opt_i586_guprof.h
+I586_PMC_GUPROF opt_i586_guprof.h
FAT_CURSOR opt_pcvt.h
PCVT_FREEBSD opt_pcvt.h
PCVT_SCANSET opt_pcvt.h
@@ -30,6 +32,15 @@ CLK_CALIBRATION_LOOP opt_clock.h
CLK_USE_I8254_CALIBRATION opt_clock.h
CLK_USE_I586_CALIBRATION opt_clock.h
+I386_CPU opt_cpu.h
+I486_CPU opt_cpu.h
+I586_CPU opt_cpu.h
+I686_CPU opt_cpu.h
+
+I586_FAST_BCOPY opt_temporary.h
+I586_OPTIMIZED_BCOPY opt_temporary.h
+I586_OPTIMIZED_BZERO opt_temporary.h
+
SC_KBD_PROBE_WORKS opt_syscons.h
SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
diff --git a/sys/pc98/boot/biosboot/Makefile b/sys/pc98/boot/biosboot/Makefile
index dbc0a49..61f5c04 100644
--- a/sys/pc98/boot/biosboot/Makefile
+++ b/sys/pc98/boot/biosboot/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.2 1996/07/23 07:45:33 asami Exp $
+# $Id: Makefile,v 1.3 1996/09/12 11:08:41 asami Exp $
#
PROG= boot
@@ -8,17 +8,34 @@ SRCS+= probe_keyboard.c io.c disk.c sys.c
BINDIR= /usr/mdec
BINMODE= 444
-CFLAGS= -O2 \
+CFLAGS= -O2 -malign-functions=0 -malign-jumps=0 -malign-loops=0 \
-DPC98 -DBOOTWAIT=${BOOTWAIT} -DTIMEOUT=${TIMEOUT}
CFLAGS+= -DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK}
-CFLAGS+= -DCOMCONSOLE=0x30 -DCOMCONSOLE_CLK=16 -DCOMCONSOLE_MODE=0x0c
+CFLAGS+= ${CWARNFLAGS}
# Probe the keyboard and use the serial console if the keyboard isn't found.
-#CFLAGS+= -DPROBE_KEYBOARD
-
-# Force use of the serial console (after probing the keyboard if
-# PROBE_KEYBOARD is defined).
-#CFLAGS+= -DFORCE_COMCONSOLE
+.if defined(BOOT_PROBE_KEYBOARD)
+CFLAGS+= -DPROBE_KEYBOARD
+.endif
+
+# Probe the keyboard lock and use the serial console if the keyboard is locked.
+.if defined(BOOT_PROBE_KEYBOARD_LOCK)
+CFLAGS+= -DPROBE_KEYBOARD_LOCK
+.endif
+
+# Force use of the serial console.
+.if defined(BOOT_FORCE_COMCONSOLE)
+CFLAGS+= -DFORCE_COMCONSOLE
+.endif
+
+# By default, if a serial port is going to be used as console, use COM1
+# (aka /dev/ttyd0).
+BOOT_COMCONSOLE_PORT?=0x30
+BOOT_COMCONSOLE_CLK?=16
+BOOT_COMCONSOLE_MODE=0x0c
+CFLAGS+= -DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \
+ -DCOMCONSOLE_CLK=${BOOT_COMCONSOLE_CLK} \
+ -DCOMCONSOLE_MODE=${BOOT_COMCONSOLE_MODE}
# Enable code to take the default boot string from a fixed location on the
# disk. See nextboot(8) and README.386BSD for more info.
@@ -96,4 +113,5 @@ install:
ln -s boot2 boot$${i} ; ) \
done
+.include <bsd.kern.mk>
.include <bsd.prog.mk>
diff --git a/sys/pc98/boot/biosboot/boot.c b/sys/pc98/boot/biosboot/boot.c
index f0253a9..70b4a31 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.4 1996/09/12 11:08:45 asami Exp $
+ * $Id: boot.c,v 1.5 1996/10/09 21:45:21 asami Exp $
*/
@@ -56,6 +56,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <a.out.h>
#include <sys/reboot.h>
#include <machine/bootinfo.h>
+#ifdef PROBE_KEYBOARD_LOCK
+#include <machine/cpufunc.h>
+#endif
#define ouraddr (BOOTSEG << 4) /* XXX */
@@ -86,6 +89,17 @@ boot(int drive)
}
#endif
+#ifndef PC98
+/* notyet */
+#ifdef PROBE_KEYBOARD_LOCK
+ if (!(inb(0x64) & 0x10)) {
+ init_serial();
+ loadflags |= RB_SERIAL;
+ printf("\nKeyboard locked.");
+ }
+#endif
+#endif
+
#ifdef FORCE_COMCONSOLE
init_serial();
loadflags |= RB_SERIAL;
diff --git a/sys/pc98/boot/biosboot/boot.h b/sys/pc98/boot/biosboot/boot.h
index c9ab1b2..b17f135 100644
--- a/sys/pc98/boot/biosboot/boot.h
+++ b/sys/pc98/boot/biosboot/boot.h
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:03 rpd
- * $Id: boot.h,v 1.13 1996/09/14 07:38:14 bde Exp $
+ * $Id: boot.h,v 1.3 1996/10/09 21:45:24 asami Exp $
*/
#include <sys/param.h>
@@ -71,7 +71,6 @@ void boot2(void);
int devopen(void);
void devread(char *iodest, int sector, int cnt);
char * Bread(int dosdev, int sector);
-int badsect(int dosdev, int sector);
/* io.c */
void gateA20(void);
diff --git a/sys/pc98/boot/biosboot/boot2.S b/sys/pc98/boot/biosboot/boot2.S
index 48ca722..63f5181 100644
--- a/sys/pc98/boot/biosboot/boot2.S
+++ b/sys/pc98/boot/biosboot/boot2.S
@@ -172,6 +172,7 @@ ENTRY(boot2)
movl %esp, EXT(dflt_name)
#endif
+ movb 0x11584, %dl
movzbl %dl, %edx /* discard head (%dh) and random high bits */
pushl %edx
call EXT(boot)
diff --git a/sys/pc98/boot/biosboot/disk.c b/sys/pc98/boot/biosboot/disk.c
index ef6239f..2f415ca 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.3 1996/09/12 11:08:53 asami Exp $
+ * $Id: disk.c,v 1.4 1996/10/09 21:45:26 asami Exp $
*/
/*
@@ -79,6 +79,7 @@ static int ra_dev;
static int ra_end;
static int ra_first;
+static int badsect(int sector);
int
devopen(void)
@@ -196,7 +197,7 @@ devopen(void)
break;
}
i += 2;
- } while (i < 10 && i < dl->d_nsectors);
+ } while (i < 10 && (unsigned)i < dl->d_nsectors);
if (!do_bad144)
printf("Bad bad sector table\n");
else
@@ -222,7 +223,7 @@ devread(char *iodest, int sector, int cnt)
for (offset = 0; offset < cnt; offset += BPS)
{
dosdev_copy = dosdev;
- p = Bread(dosdev_copy, badsect(dosdev_copy, sector++));
+ p = Bread(dosdev_copy, badsect(sector++));
bcopy(p, iodest+offset, BPS);
}
}
@@ -253,7 +254,8 @@ Bread(int dosdev, int sector)
nsec = 1;
twiddle();
while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0) {
- printf("Error: C:%d H:%d S:%d\n", cyl, head, sec);
+ printf("Error: D:0x%x C:%d H:%d S:%d\n",
+ dosdev, cyl, head, sec);
twiddle();
}
}
@@ -264,8 +266,8 @@ Bread(int dosdev, int sector)
return (ra_buf + (sector - ra_first) * BPS);
}
-int
-badsect(int dosdev, int sector)
+static int
+badsect(int sector)
{
#if defined(DO_BAD144) && !defined(RAWBOOT)
int i;
diff --git a/sys/pc98/boot/biosboot/io.c b/sys/pc98/boot/biosboot/io.c
index 437bc35..3160984 100644
--- a/sys/pc98/boot/biosboot/io.c
+++ b/sys/pc98/boot/biosboot/io.c
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:57 rpd
- * $Id: io.c,v 1.3 1996/09/12 11:08:55 asami Exp $
+ * $Id: io.c,v 1.4 1996/10/09 21:45:29 asami Exp $
*/
#include "boot.h"
@@ -350,9 +350,9 @@ void machine_check(void)
u_char epson_machine_id = *(unsigned char *)(0x11624);
/* PC98_SYSTEM_PARAMETER(0x501) */
- ret = ((*(unsigned char*)0x11501) & 0x08) ? M_HIGHRESO : M_NORMAL;
+ ret = ((*(unsigned char*)0x11501) & 0x08) >> 3;
- /* wait V-SYNC */
+ /* Wait V-SYNC */
while (inb(0x60) & 0x20) {}
while (!(inb(0x60) & 0x20)) {}
@@ -390,7 +390,6 @@ void machine_check(void)
case 0x22: /* note W */
case 0x27: /* note AE */
case 0x2a: /* note WR */
- /*case 0x2: /* note AR */
ret |= M_NOTE;
break;
default:
diff --git a/sys/pc98/boot/rawboot/Makefile b/sys/pc98/boot/rawboot/Makefile
index 4f12ed4..dbe0837 100644
--- a/sys/pc98/boot/rawboot/Makefile
+++ b/sys/pc98/boot/rawboot/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.1 1996/09/11 19:25:11 phk Exp $
+# $Id: Makefile,v 1.1 1996/09/12 11:09:14 asami Exp $
#
PROG= boot
@@ -11,20 +11,37 @@ SRCS+= probe_keyboard.c io.c disk.c sys.c
BINDIR= /usr/mdec
BINMODE= 444
-CFLAGS= -O2 \
+CFLAGS= -O2 -malign-functions=0 -malign-jumps=0 -malign-loops=0 \
-DPC98 \
-DRAWBOOT \
-I${.CURDIR}/../biosboot \
-DBOOTWAIT=${BOOTWAIT} -DTIMEOUT=${TIMEOUT}
-CFLAGS+= -DCOMCONSOLE=0x30 -DCOMCONSOLE_CLK=16 -DCOMCONSOLE_MODE=0x0c
CFLAGS+= -DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK}
+CFLAGS+= ${CWARNFLAGS}
# Probe the keyboard and use the serial console if the keyboard isn't found.
-#CFLAGS+= -DPROBE_KEYBOARD
-
-# Force use of the serial console (after probing the keyboard if
-# PROBE_KEYBOARD is defined).
-#CFLAGS+= -DFORCE_COMCONSOLE
+.if defined(BOOT_PROBE_KEYBOARD)
+CFLAGS+= -DPROBE_KEYBOARD
+.endif
+
+# Probe the keyboard lock and use the serial console if the keyboard is locked.
+.if defined(BOOT_PROBE_KEYBOARD_LOCK)
+CFLAGS+= -DPROBE_KEYBOARD_LOCK
+.endif
+
+# Force use of the serial console.
+.if defined(BOOT_FORCE_COMCONSOLE)
+CFLAGS+= -DFORCE_COMCONSOLE
+.endif
+
+# By default, if a serial port is going to be used as console, use COM1
+# (aka /dev/ttyd0).
+BOOT_COMCONSOLE_PORT?=0x30
+BOOT_COMCONSOLE_CLK?=16
+BOOT_COMCONSOLE_MODE=0x0c
+CFLAGS+= -DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \
+ -DCOMCONSOLE_CLK=${BOOT_COMCONSOLE_CLK} \
+ -DCOMCONSOLE_MODE=${BOOT_COMCONSOLE_MODE}
# Enable code to take the default boot string from a fixed location on the
# disk. See nextboot(8) and README.386BSD for more info.
@@ -75,10 +92,11 @@ boot.nohdr: boot.strip
rawboot: boot.nohdr
dd if=boot.nohdr of=rawboot bs=8k count=1 conv=sync
-all: rawboot
+all: rawboot
install:
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE}\
rawboot ${DESTDIR}${BINDIR}/rawboot
+.include <bsd.kern.mk>
.include <bsd.prog.mk>
diff --git a/sys/pc98/cbus/cbus.h b/sys/pc98/cbus/cbus.h
index 5d79e74..84c77b4 100644
--- a/sys/pc98/cbus/cbus.h
+++ b/sys/pc98/cbus/cbus.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.h 5.7 (Berkeley) 5/9/91
- * $Id: pc98.h,v 1.4 1996/09/12 11:09:54 asami Exp $
+ * $Id: pc98.h,v 1.5 1996/10/09 21:46:34 asami Exp $
*/
#ifndef _PC98_PC98_PC98_H_
@@ -193,7 +193,6 @@
#define M_H98 0x0020
#define M_NOTE 0x0040
#define M_NORMAL 0x1000
-#define M_HIGHRESO 0x2000
#define M_8M 0x8000
#if defined(KERNEL) && !defined(LOCORE)
@@ -214,52 +213,6 @@ extern unsigned char pc98_system_parameter[]; /* in locore.c */
# define PC98_TYPE_CHECK(x) ((pc98_machine_type & (x)) == (x))
-#include <machine/spl.h>
-
-static inline u_char
-epson_inb(u_int port)
-{
- u_char data;
-
- outb(0x43f, 0x42);
- data = inb(port);
- outb(0x43f, 0x40);
- return (data);
-}
-
-static inline void
-epson_outb(u_int port, u_char data)
-{
- outb(0x43f, 0x42);
- outb(port,data);
- outb(0x43f, 0x40);
-}
-
-static inline void
-epson_insw(u_int port, void *addr, size_t cnt)
-{
- int s;
-
- s = splbio();
- outb(0x43f, 0x42);
- disable_intr();
- insw((u_int)port, (void *)addr, (size_t)cnt);
- outb(0x43f, 0x40);
- splx(s);
-}
-
-static inline void
-epson_outsw(u_int port, void *addr, size_t cnt)
-{
- int s;
-
- s = splbio();
- outb(0x43f, 0x42);
- disable_intr();
- outsw((u_int)port, (void *)addr, (size_t)cnt);
- outb(0x43f, 0x40);
- splx(s);
-}
#endif /* KERNEL */
/*
diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c
index d9b34d1..d96f6619 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.6 1996/10/09 19:47:43 bde Exp $
+ * $Id: clock.c,v 1.7 1996/10/09 21:46:11 asami Exp $
*/
/*
@@ -46,7 +46,7 @@
/*
* modified for PC98
- * $Id: clock.c,v 1.6 1996/10/09 19:47:43 bde Exp $
+ * $Id: clock.c,v 1.7 1996/10/09 21:46:11 asami Exp $
*/
/*
@@ -1127,6 +1127,32 @@ cpu_initclocks()
writertc(RTC_STATUSA, rtc_statusa);
writertc(RTC_STATUSB, RTCSB_24HR);
+ /* Don't bother enabling the statistics clock. */
+ if (statclock_disable)
+ return;
+ diag = rtcin(RTC_DIAG);
+ if (diag != 0)
+ printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
+ register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
+ /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
+ /* unit */ 0);
+ INTREN(IRQ8);
+ writertc(RTC_STATUSB, rtc_statusb);
+#endif
+}
+
+void
+setstatclockrate(int newhz)
+{
+#ifndef PC98
+ if (newhz == RTC_PROFRATE)
+ rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
+ else
+ rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
+ writertc(RTC_STATUSA, rtc_statusa);
+#endif
+}
+
static int
sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
{
@@ -1193,29 +1219,3 @@ sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i586_freq, "I", "");
#endif /* defined(I586_CPU) || defined(I686_CPU) */
-
- /* Don't bother enabling the statistics clock. */
- if (statclock_disable)
- return;
- diag = rtcin(RTC_DIAG);
- if (diag != 0)
- printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
- register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
- /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
- /* unit */ 0);
- INTREN(IRQ8);
- writertc(RTC_STATUSB, rtc_statusb);
-#endif
-}
-
-void
-setstatclockrate(int newhz)
-{
-#ifndef PC98
- if (newhz == RTC_PROFRATE)
- rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
- else
- rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
- writertc(RTC_STATUSA, rtc_statusa);
-#endif
-}
diff --git a/sys/pc98/cbus/fdc.c b/sys/pc98/cbus/fdc.c
index e8ad1b2..be8751c 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.5 1996/09/03 10:23:25 asami Exp $
+ * $Id: fd.c,v 1.6 1996/09/10 09:37:50 asami Exp $
*
*/
@@ -72,6 +72,7 @@
#include <sys/dkstat.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/epsonio.h>
#include <i386/isa/isa_device.h>
#include <pc98/pc98/fdreg.h>
#include <pc98/pc98/fdc.h>
diff --git a/sys/pc98/cbus/pcrtc.c b/sys/pc98/cbus/pcrtc.c
index d9b34d1..d96f6619 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.6 1996/10/09 19:47:43 bde Exp $
+ * $Id: clock.c,v 1.7 1996/10/09 21:46:11 asami Exp $
*/
/*
@@ -46,7 +46,7 @@
/*
* modified for PC98
- * $Id: clock.c,v 1.6 1996/10/09 19:47:43 bde Exp $
+ * $Id: clock.c,v 1.7 1996/10/09 21:46:11 asami Exp $
*/
/*
@@ -1127,6 +1127,32 @@ cpu_initclocks()
writertc(RTC_STATUSA, rtc_statusa);
writertc(RTC_STATUSB, RTCSB_24HR);
+ /* Don't bother enabling the statistics clock. */
+ if (statclock_disable)
+ return;
+ diag = rtcin(RTC_DIAG);
+ if (diag != 0)
+ printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
+ register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
+ /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
+ /* unit */ 0);
+ INTREN(IRQ8);
+ writertc(RTC_STATUSB, rtc_statusb);
+#endif
+}
+
+void
+setstatclockrate(int newhz)
+{
+#ifndef PC98
+ if (newhz == RTC_PROFRATE)
+ rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
+ else
+ rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
+ writertc(RTC_STATUSA, rtc_statusa);
+#endif
+}
+
static int
sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
{
@@ -1193,29 +1219,3 @@ sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i586_freq, "I", "");
#endif /* defined(I586_CPU) || defined(I686_CPU) */
-
- /* Don't bother enabling the statistics clock. */
- if (statclock_disable)
- return;
- diag = rtcin(RTC_DIAG);
- if (diag != 0)
- printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
- register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
- /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
- /* unit */ 0);
- INTREN(IRQ8);
- writertc(RTC_STATUSB, rtc_statusb);
-#endif
-}
-
-void
-setstatclockrate(int newhz)
-{
-#ifndef PC98
- if (newhz == RTC_PROFRATE)
- rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
- else
- rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
- writertc(RTC_STATUSA, rtc_statusa);
-#endif
-}
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index d33ece9..5bd1821 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
-# $Id: GENERIC98,v 1.5 1996/09/12 11:09:16 asami Exp $
+# $Id: GENERIC98,v 1.6 1996/10/09 21:45:41 asami Exp $
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
@@ -54,21 +54,18 @@ options COM_MULTIPORT
#
#options "IBM_486SLC" # IBM486SLC/SLC2 support
#options "CYRIX_486DLC" # Cyrix 486DLC/SLC/DLC2/SLC2 support
-#option "CYRIX_5X86" # Cyrix 5x86 support
+#options "CYRIX_5X86" # Cyrix 5x86 support
#options SUSP_HLT # CPU enters suspend mode when HALT
#options "DISABLE_5X86_LSSER" # Load-Store reordering enable
-
#
# sbic55.c.new
#
#options SCSI_SYNC # synchronous transfer mode
#options FORCE_BUSMASTER
#options "HA55BS_ID=0"
-
#
# IBM-PC HDD support
#options COMPAT_ATDISK
-
#
# FreeBSD(98)-current is a *TEST VERSION*.
# It is highly recomended to compile with following options, and to
@@ -97,7 +94,7 @@ disk wd0 at wdc0 drive 0
options ATAPI # Enable ATAPI support for IDE bus
options ATAPI_STATIC #Don't do it as an LKM
-device wcd #IDE CD-ROM
+device wcd0 #IDE CD-ROM
# A single entry for any of these controllers (ncr, ahb, ahc) is sufficient
# for any number of installed devices.
@@ -105,21 +102,20 @@ controller ncr0
controller ahc0
controller sbic0 at isa? port "IO_SCSI" bio irq 5 drq 3 vector sbicintr
+# sbic55.c.new
#controller sbic0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0xff vector sbicintr
-controller aic0 at isa? port 0x1840 bio irq 5 vector aicintr
+controller aic0 at isa? port 0x1840 bio irq 5 flags 0x10000 vector aicintr
controller scbus0
device sd0
+device od0 #See LINT for possible `od' options.
+
device st0
device cd0 #Only need one of these, the code dynamically grows
-device od0
-
-device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
-
controller matcd0 at isa? port? bio
# syscons is the default console driver, resembling an SCO console
diff --git a/sys/pc98/conf/GENERIC98 b/sys/pc98/conf/GENERIC98
index d33ece9..5bd1821 100644
--- a/sys/pc98/conf/GENERIC98
+++ b/sys/pc98/conf/GENERIC98
@@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
-# $Id: GENERIC98,v 1.5 1996/09/12 11:09:16 asami Exp $
+# $Id: GENERIC98,v 1.6 1996/10/09 21:45:41 asami Exp $
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
@@ -54,21 +54,18 @@ options COM_MULTIPORT
#
#options "IBM_486SLC" # IBM486SLC/SLC2 support
#options "CYRIX_486DLC" # Cyrix 486DLC/SLC/DLC2/SLC2 support
-#option "CYRIX_5X86" # Cyrix 5x86 support
+#options "CYRIX_5X86" # Cyrix 5x86 support
#options SUSP_HLT # CPU enters suspend mode when HALT
#options "DISABLE_5X86_LSSER" # Load-Store reordering enable
-
#
# sbic55.c.new
#
#options SCSI_SYNC # synchronous transfer mode
#options FORCE_BUSMASTER
#options "HA55BS_ID=0"
-
#
# IBM-PC HDD support
#options COMPAT_ATDISK
-
#
# FreeBSD(98)-current is a *TEST VERSION*.
# It is highly recomended to compile with following options, and to
@@ -97,7 +94,7 @@ disk wd0 at wdc0 drive 0
options ATAPI # Enable ATAPI support for IDE bus
options ATAPI_STATIC #Don't do it as an LKM
-device wcd #IDE CD-ROM
+device wcd0 #IDE CD-ROM
# A single entry for any of these controllers (ncr, ahb, ahc) is sufficient
# for any number of installed devices.
@@ -105,21 +102,20 @@ controller ncr0
controller ahc0
controller sbic0 at isa? port "IO_SCSI" bio irq 5 drq 3 vector sbicintr
+# sbic55.c.new
#controller sbic0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0xff vector sbicintr
-controller aic0 at isa? port 0x1840 bio irq 5 vector aicintr
+controller aic0 at isa? port 0x1840 bio irq 5 flags 0x10000 vector aicintr
controller scbus0
device sd0
+device od0 #See LINT for possible `od' options.
+
device st0
device cd0 #Only need one of these, the code dynamically grows
-device od0
-
-device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
-
controller matcd0 at isa? port? bio
# syscons is the default console driver, resembling an SCO console
diff --git a/sys/pc98/conf/Makefile.pc98 b/sys/pc98/conf/Makefile.pc98
index 03e5ac7..335b654 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.pc98,v 1.5 1996/09/07 02:13:25 asami Exp $
+# $Id: Makefile.pc98,v 1.6 1996/10/09 21:45:45 asami Exp $
#
# Makefile for FreeBSD
#
@@ -29,16 +29,6 @@ S= ../..
PC98= ${S}/pc98
I386= ${S}/i386
-CWARNFLAGS?= -W -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit \
- -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes \
- -Winline -Wunused -Wpointer-arith
-#
-# The following flags are next up for working on:
-# -Wall
-#
-# When working on removing warnings from code, the `-Werror' flag should be
-# of material assistance.
-#
COPTFLAGS?=-O
INCLUDES= -nostdinc -I- -I. -I$S
# This hack is to allow kernel compiles to succeed on machines w/out srcdist
@@ -190,6 +180,8 @@ vnode_if.c: $S/kern/vnode_if.sh $S/kern/vnode_if.src
vnode_if.h: $S/kern/vnode_if.sh $S/kern/vnode_if.src
sh $S/kern/vnode_if.sh $S/kern/vnode_if.src
+.include <bsd.kern.mk>
+
%RULES
# DO NOT DELETE THIS LINE -- make depend uses it
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index 1d02c57..fef4b97 100644
--- a/sys/pc98/conf/files.pc98
+++ b/sys/pc98/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.i386,v 1.140 1996/09/11 19:53:30 phk Exp $
+# $Id: files.pc98,v 1.7 1996/09/12 11:09:18 asami Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -50,12 +50,12 @@ i386/i386/in_cksum.c optional inet
# 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
+i386/i386/perfmon.c optional perfmon profiling-routine
i386/i386/perfmon.c optional perfmon
-pc98/i386/pmap.c standard
+i386/i386/pmap.c standard
i386/i386/procfs_machdep.c standard
i386/i386/support.s standard
i386/i386/swtch.s standard
@@ -82,6 +82,7 @@ i386/ibcs2/ibcs2_errno.c optional ibcs2
i386/ibcs2/ibcs2_sysent.c optional ibcs2
i386/ibcs2/ibcs2_sysvec.c optional ibcs2
i386/ibcs2/imgact_coff.c optional ibcs2
+pc98/pc98/pc98_machdep.c standard
pc98/pc98/bs/bs.c optional bs device-driver
pc98/pc98/bs/bsfunc.c optional bs device-driver
pc98/pc98/bs/bshw.c optional bs device-driver
diff --git a/sys/pc98/conf/majors.pc98 b/sys/pc98/conf/majors.pc98
index 702c9ad..e13c5d7 100644
--- a/sys/pc98/conf/majors.pc98
+++ b/sys/pc98/conf/majors.pc98
@@ -1,4 +1,4 @@
-$Id: majors.pc98,v 1.2 1996/07/23 07:45:50 asami Exp $
+$Id: majors.pc98,v 1.3 1996/09/03 10:23:13 asami Exp $
Hopefully, this list will one day be obsoleted by DEVFS, but for now
this is the current allocation of device major numbers.
@@ -35,7 +35,7 @@ blkdev name comments
19 wcdb ATAPI CDROM client of "ata"
20 od SCSI "magneto-optical" disk
21 ccd concatenated disk
-
+22 gd Geometry disk.
chrdev name comments
0 cn console
1 ctty /dev/tty
@@ -115,3 +115,4 @@ chrdev name comments
75 stli Stallion (intelligent cdk based) (gerg@stallion.oz.au)
76 scc IBM Smart Capture Card (ohashi@mickey.ai.kyutech.ac.jp)
77 cyy Cyclades Ye/PCI serial card
+78 gd Geometry disk
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index 9a589f3..4374f02 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.4 1996/09/12 11:09:21 asami Exp $
+# $Id: options.pc98,v 1.5 1996/10/09 21:45:47 asami Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -18,6 +18,8 @@ COMCONSOLE opt_comconsole.h
COM_ESP opt_sio.h
COM_MULTIPORT opt_sio.h
DSI_SOFT_MODEM opt_sio.h
+I586_CTR_GUPROF opt_i586_guprof.h
+I586_PMC_GUPROF opt_i586_guprof.h
FAT_CURSOR opt_pcvt.h
PCVT_FREEBSD opt_pcvt.h
PCVT_SCANSET opt_pcvt.h
@@ -30,6 +32,15 @@ CLK_CALIBRATION_LOOP opt_clock.h
CLK_USE_I8254_CALIBRATION opt_clock.h
CLK_USE_I586_CALIBRATION opt_clock.h
+I386_CPU opt_cpu.h
+I486_CPU opt_cpu.h
+I586_CPU opt_cpu.h
+I686_CPU opt_cpu.h
+
+I586_FAST_BCOPY opt_temporary.h
+I586_OPTIMIZED_BCOPY opt_temporary.h
+I586_OPTIMIZED_BZERO opt_temporary.h
+
SC_KBD_PROBE_WORKS opt_syscons.h
SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
diff --git a/sys/pc98/i386/locore.s b/sys/pc98/i386/locore.s
index b39d0e9..725b478 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.3 1996/10/09 19:47:37 bde Exp $
+ * $Id: locore.s,v 1.4 1996/10/09 21:45:53 asami Exp $
*
* originally from: locore.s, by William F. Jolitz
*
@@ -334,7 +334,6 @@ _pc98_system_parameter:
/* now running relocated at KERNBASE where the system is linked to run */
begin:
-
/* set up bootstrap stack */
movl $_kstack+UPAGES*PAGE_SIZE,%esp /* bootstrap stack end location */
xorl %eax,%eax /* mark end of frames */
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
index 01b3b48..73725c7 100644
--- a/sys/pc98/i386/machdep.c
+++ b/sys/pc98/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.8 1996/09/12 11:09:26 asami Exp $
+ * $Id: machdep.c,v 1.9 1996/10/09 21:45:56 asami Exp $
*/
#include "npx.h"
@@ -1063,7 +1063,7 @@ init386(first)
setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
setidt(14, &IDTVEC(page), SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#else
setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@@ -1140,6 +1140,7 @@ init386(first)
printf(
"BIOS basemem (%ldK) != RTC basemem (%dK), setting to BIOS value\n",
+ bootinfo.bi_basemem, biosbasemem);
biosbasemem = bootinfo.bi_basemem;
/*
diff --git a/sys/pc98/i386/pmap.c b/sys/pc98/i386/pmap.c
deleted file mode 100644
index 842004d..0000000
--- a/sys/pc98/i386/pmap.c
+++ /dev/null
@@ -1,2990 +0,0 @@
-/*
- * Copyright (c) 1991 Regents of the University of California.
- * All rights reserved.
- * Copyright (c) 1994 John S. Dyson
- * All rights reserved.
- * Copyright (c) 1994 David Greenman
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department and William Jolitz of UUNET Technologies Inc.
- *
- * 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: @(#)pmap.c 7.7 (Berkeley) 5/12/91
- * $Id: pmap.c,v 1.4 1996/10/09 19:47:39 bde Exp $
- */
-
-/*
- * Manages physical address maps.
- *
- * In addition to hardware address maps, this
- * module is called upon to provide software-use-only
- * maps which may or may not be stored in the same
- * form as hardware maps. These pseudo-maps are
- * used to store intermediate results from copy
- * operations to and from address spaces.
- *
- * Since the information managed by this module is
- * also stored by the logical address mapping module,
- * this module may throw away valid virtual-to-physical
- * mappings at almost any time. However, invalidations
- * of virtual-to-physical mappings must be done as
- * requested.
- *
- * In order to cope with hardware architectures which
- * make virtual-to-physical map invalidates expensive,
- * this module may delay invalidate or reduced protection
- * operations until such time as they are actually
- * necessary. This module is given full information as
- * to which processors are currently using which maps,
- * and to when physical maps must be made correct.
- */
-
-#include "opt_cpu.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/malloc.h>
-#include <sys/msgbuf.h>
-#include <sys/queue.h>
-#include <sys/vmmeter.h>
-#include <sys/mman.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_prot.h>
-#include <vm/lock.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-#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>
-
-#define PMAP_KEEP_PDIRS
-
-#if defined(DIAGNOSTIC)
-#define PMAP_DIAGNOSTIC
-#endif
-
-#if !defined(PMAP_DIAGNOSTIC)
-#define PMAP_INLINE __inline
-#else
-#define PMAP_INLINE
-#endif
-
-#define PTPHINT
-
-static void init_pv_entries __P((int));
-
-/*
- * Get PDEs and PTEs for user/kernel address space
- */
-#define pmap_pde(m, v) (&((m)->pm_pdir[(vm_offset_t)(v) >> PDRSHIFT]))
-#define pdir_pde(m, v) (m[(vm_offset_t)(v) >> PDRSHIFT])
-
-#define pmap_pde_v(pte) ((*(int *)pte & PG_V) != 0)
-#define pmap_pte_w(pte) ((*(int *)pte & PG_W) != 0)
-#define pmap_pte_m(pte) ((*(int *)pte & PG_M) != 0)
-#define pmap_pte_u(pte) ((*(int *)pte & PG_A) != 0)
-#define pmap_pte_v(pte) ((*(int *)pte & PG_V) != 0)
-
-#define pmap_pte_set_w(pte, v) ((v)?(*(int *)pte |= PG_W):(*(int *)pte &= ~PG_W))
-#define pmap_pte_set_prot(pte, v) ((*(int *)pte &= ~PG_PROT), (*(int *)pte |= (v)))
-
-/*
- * Given a map and a machine independent protection code,
- * convert to a vax protection code.
- */
-#define pte_prot(m, p) (protection_codes[p])
-static int protection_codes[8];
-
-static struct pmap kernel_pmap_store;
-pmap_t kernel_pmap;
-
-vm_offset_t avail_start; /* PA of first available physical page */
-vm_offset_t avail_end; /* PA of last available physical page */
-vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss) */
-vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */
-static boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */
-static vm_offset_t vm_first_phys;
-
-static int nkpt;
-static vm_page_t nkpg;
-vm_offset_t kernel_vm_end;
-
-extern vm_offset_t clean_sva, clean_eva;
-extern int cpu_class;
-
-#if defined(I386_CPU) || defined(CYRIX_486DLC)
-extern int cpu;
-#endif
-
-#define PV_FREELIST_MIN ((PAGE_SIZE / sizeof (struct pv_entry)) / 2)
-
-/*
- * Data for the pv entry allocation mechanism
- */
-static int pv_freelistcnt;
-TAILQ_HEAD (,pv_entry) pv_freelist;
-static vm_offset_t pvva;
-static int npvvapg;
-
-/*
- * All those kernel PT submaps that BSD is so fond of
- */
-pt_entry_t *CMAP1;
-static pt_entry_t *CMAP2, *ptmmap;
-caddr_t CADDR1, ptvmmap;
-static caddr_t CADDR2;
-static pt_entry_t *msgbufmap;
-struct msgbuf *msgbufp;
-
-pt_entry_t *PMAP1;
-unsigned *PADDR1;
-
-static void free_pv_entry __P((pv_entry_t pv));
-static unsigned * get_ptbase __P((pmap_t pmap));
-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 int pmap_is_managed __P((vm_offset_t pa));
-static void pmap_remove_all __P((vm_offset_t pa));
-static vm_page_t pmap_enter_quick __P((pmap_t pmap, vm_offset_t va,
- vm_offset_t pa, vm_page_t mpte));
-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 int pmap_remove_entry __P((struct pmap *pmap, pv_table_t *pv,
- vm_offset_t va));
-static boolean_t pmap_testbit __P((vm_offset_t pa, int bit));
-static void pmap_insert_entry __P((pmap_t pmap, vm_offset_t va,
- vm_page_t mpte, vm_offset_t pa));
-
-static vm_page_t pmap_allocpte __P((pmap_t pmap, vm_offset_t va));
-
-static int pmap_release_free_page __P((pmap_t pmap, vm_page_t p));
-static vm_page_t _pmap_allocpte __P((pmap_t pmap, unsigned ptepindex));
-static unsigned * pmap_pte_quick __P((pmap_t pmap, vm_offset_t va));
-static vm_page_t pmap_page_alloc __P((vm_object_t object, vm_pindex_t pindex));
-static PMAP_INLINE void pmap_lock __P((pmap_t pmap));
-static PMAP_INLINE void pmap_unlock __P((pmap_t pmap));
-static void pmap_lock2 __P((pmap_t pmap1, pmap_t pmap2));
-
-#define PDSTACKMAX 6
-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;
- TAILQ_INIT(&kernel_pmap->pm_pvlist);
- 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;
- invltlb();
-
-}
-
-/*
- * 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(pv_table_t) * npg);
- s = round_page(s);
-
- addr = (vm_offset_t) kmem_alloc(kernel_map, s);
- pv_table = (pv_table_t *) addr;
- for(i=0;i<npg;i++) {
- vm_offset_t pa;
- TAILQ_INIT(&pv_table[i].pv_list);
- pv_table[i].pv_list_count = 0;
- pa = vm_first_phys + i * PAGE_SIZE;
- pv_table[i].pv_vm_page = PHYS_TO_VM_PAGE(pa);
- }
- TAILQ_INIT(&pv_freelist);
-
- /*
- * 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)
-
-/*
- * This code checks for non-writeable/modified pages.
- * This should be an invalid condition.
- */
-static int
-pmap_nw_modified(pt_entry_t ptea) {
- int pte;
-
- pte = (int) ptea;
-
- if ((pte & (PG_M|PG_RW)) == PG_M)
- return 1;
- else
- return 0;
-}
-#endif
-
-
-/*
- * this routine defines the region(s) of memory that should
- * not be tested for the modified bit.
- */
-static PMAP_INLINE int
-pmap_track_modified( vm_offset_t va) {
- if ((va < clean_sva) || (va >= clean_eva))
- return 1;
- else
- return 0;
-}
-
-static PMAP_INLINE void
-invltlb_1pg( vm_offset_t va) {
-#if defined(I386_CPU)
- if (cpu_class == CPUCLASS_386) {
- invltlb();
- } else
-#endif
- {
- invlpg(va);
- }
-}
-
-static PMAP_INLINE void
-invltlb_2pg( vm_offset_t va1, vm_offset_t va2) {
-#if defined(I386_CPU)
- if (cpu_class == CPUCLASS_386) {
- invltlb();
- } else
-#endif
- {
- invlpg(va1);
- invlpg(va2);
- }
-}
-
-
-static PMAP_INLINE void
-pmap_lock(pmap)
-pmap_t pmap;
-{
- int s;
- if (pmap == kernel_pmap)
- return;
- s = splhigh();
- while (pmap->pm_flags & PM_FLAG_LOCKED) {
- pmap->pm_flags |= PM_FLAG_WANTED;
- tsleep(pmap, PVM - 1, "pmaplk", 0);
- }
- splx(s);
-}
-
-static PMAP_INLINE void
-pmap_unlock(pmap)
-pmap_t pmap;
-{
- int s;
- if (pmap == kernel_pmap)
- return;
- s = splhigh();
- pmap->pm_flags &= ~PM_FLAG_LOCKED;
- if (pmap->pm_flags & PM_FLAG_WANTED) {
- pmap->pm_flags &= ~PM_FLAG_WANTED;
- wakeup(pmap);
- }
-}
-
-static void
-pmap_lock2(pmap1, pmap2)
-pmap_t pmap1, pmap2;
-{
- int s;
- if (pmap1 == kernel_pmap || pmap2 == kernel_pmap)
- return;
- s = splhigh();
- while ((pmap1->pm_flags | pmap2->pm_flags) & PM_FLAG_LOCKED) {
- while (pmap1->pm_flags & PM_FLAG_LOCKED) {
- pmap1->pm_flags |= PM_FLAG_WANTED;
- tsleep(pmap1, PVM - 1, "pmapl1", 0);
- }
- while (pmap2->pm_flags & PM_FLAG_LOCKED) {
- pmap2->pm_flags |= PM_FLAG_WANTED;
- tsleep(pmap2, PVM - 1, "pmapl2", 0);
- }
- }
- splx(s);
-}
-
-static unsigned *
-get_ptbase(pmap)
- pmap_t pmap;
-{
- 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;
- }
- /* otherwise, we are alternate address space */
- if (frame != (((unsigned) APTDpde) & PG_FRAME)) {
- APTDpde = (pd_entry_t) (frame | PG_RW | PG_V);
- invltlb();
- }
- return (unsigned *) APTmap;
-}
-
-/*
- * Routine: pmap_pte
- * Function:
- * Extract the page table entry associated
- * with the given map/virtual_address pair.
- */
-
-PMAP_INLINE unsigned *
-pmap_pte(pmap, va)
- register pmap_t pmap;
- vm_offset_t va;
-{
- if (pmap && *pmap_pde(pmap, va)) {
- return get_ptbase(pmap) + i386_btop(va);
- }
- return (0);
-}
-
-/*
- * Super fast pmap_pte routine best used when scanning
- * the pv lists. This eliminates many coarse-grained
- * invltlb calls. Note that many of the pv list
- * scans are across different pmaps. It is very wasteful
- * to do an entire invltlb for checking a single mapping.
- */
-
-unsigned *
-pmap_pte_quick(pmap, va)
- register pmap_t pmap;
- vm_offset_t va;
-{
- unsigned pde, newpf;
- if (pde = (unsigned) pmap->pm_pdir[va >> PDRSHIFT]) {
- unsigned frame = (unsigned) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
- unsigned index = i386_btop(va);
- /* are we current address space or kernel? */
- if ((pmap == kernel_pmap) ||
- (frame == (((unsigned) PTDpde) & PG_FRAME))) {
- return (unsigned *) PTmap + index;
- }
- newpf = pde & PG_FRAME;
- if ( ((* (unsigned *) PMAP1) & PG_FRAME) != newpf) {
- * (unsigned *) PMAP1 = newpf | PG_RW | PG_V;
- invltlb_1pg((vm_offset_t) PADDR1);
- }
- return PADDR1 + ((unsigned) index & (NPTEPG - 1));
- }
- return (0);
-}
-
-/*
- * Routine: pmap_extract
- * Function:
- * Extract the physical page address associated
- * with the given map/virtual_address pair.
- */
-vm_offset_t
-pmap_extract(pmap, va)
- register pmap_t pmap;
- vm_offset_t va;
-{
- vm_offset_t rtval;
- pmap_lock(pmap);
- if (pmap && *pmap_pde(pmap, va)) {
- unsigned *pte;
- pte = get_ptbase(pmap) + i386_btop(va);
- rtval = ((*pte & PG_FRAME) | (va & PAGE_MASK));
- pmap_unlock(pmap);
- return rtval;
- }
- pmap_unlock(pmap);
- return 0;
-
-}
-
-/*
- * determine if a page is managed (memory vs. device)
- */
-static PMAP_INLINE 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
- * page modification or references recorded.
- * Note that old mappings are simply written
- * over. The page *must* be wired.
- */
-void
-pmap_qenter(va, m, count)
- vm_offset_t va;
- vm_page_t *m;
- int count;
-{
- int i;
- register unsigned *pte;
-
- for (i = 0; i < count; i++) {
- vm_offset_t tva = va + i * PAGE_SIZE;
- unsigned npte = VM_PAGE_TO_PHYS(m[i]) | PG_RW | PG_V;
- unsigned opte;
- pte = (unsigned *)vtopte(tva);
- opte = *pte;
- *pte = npte;
- if (opte)
- invltlb_1pg(tva);
- }
-}
-
-/*
- * this routine jerks page mappings from the
- * kernel -- it is meant only for temporary mappings.
- */
-void
-pmap_qremove(va, count)
- vm_offset_t va;
- int count;
-{
- int i;
- register unsigned *pte;
-
- for (i = 0; i < count; i++) {
- pte = (unsigned *)vtopte(va);
- *pte = 0;
- invltlb_1pg(va);
- va += PAGE_SIZE;
- }
-}
-
-/*
- * add a wired page to the kva
- * note that in order for the mapping to take effect -- you
- * should do a invltlb after doing the pmap_kenter...
- */
-PMAP_INLINE void
-pmap_kenter(va, pa)
- vm_offset_t va;
- register vm_offset_t pa;
-{
- register unsigned *pte;
- unsigned npte, opte;
-
- npte = pa | PG_RW | PG_V;
- pte = (unsigned *)vtopte(va);
- opte = *pte;
- *pte = npte;
- if (opte)
- invltlb_1pg(va);
-}
-
-/*
- * remove a page from the kernel pagetables
- */
-PMAP_INLINE void
-pmap_kremove(va)
- vm_offset_t va;
-{
- register unsigned *pte;
-
- pte = (unsigned *)vtopte(va);
- *pte = 0;
- invltlb_1pg(va);
-}
-
-static vm_page_t
-pmap_page_alloc(object, pindex)
- vm_object_t object;
- vm_pindex_t pindex;
-{
- vm_page_t m;
- m = vm_page_alloc(object, pindex, VM_ALLOC_ZERO);
- if (m == NULL) {
- VM_WAIT;
- }
- return m;
-}
-
-vm_page_t
-pmap_page_lookup(object, pindex)
- vm_object_t object;
- vm_pindex_t pindex;
-{
- vm_page_t m;
-retry:
- m = vm_page_lookup(object, pindex);
- if (m) {
- if (m->flags & PG_BUSY) {
- m->flags |= PG_WANTED;
- tsleep(m, PVM, "pplookp", 0);
- goto retry;
- }
- }
-
- return m;
-}
-
-
-
-
-/***************************************************
- * 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 int
-pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m) {
- int s;
-
- vm_page_unhold(m);
-
- s = splvm();
- while (m->flags & PG_BUSY) {
- m->flags |= PG_WANTED;
- tsleep(m, PVM, "pmuwpt", 0);
- }
- splx(s);
-
- 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;
- if ((((unsigned)pmap->pm_pdir[PTDPTDI]) & PG_FRAME) ==
- (((unsigned) PTDpde) & PG_FRAME)) {
- /*
- * Do a invltlb to make the invalidated mapping
- * take effect immediately.
- */
- pteva = UPT_MIN_ADDRESS + i386_ptob(m->pindex);
- invltlb_1pg(pteva);
- }
-
-#if defined(PTPHINT)
- if (pmap->pm_ptphint == m)
- pmap->pm_ptphint = NULL;
-#endif
-
- /*
- * If the page is finally unwired, simply free it.
- */
- --m->wire_count;
- if (m->wire_count == 0) {
-
- if (m->flags & PG_WANTED) {
- m->flags &= ~PG_WANTED;
- wakeup(m);
- }
-
- vm_page_free_zero(m);
- --cnt.v_wire_count;
- }
- return 1;
- }
- return 0;
-}
-
-/*
- * 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;
- vm_offset_t va;
- vm_page_t mpte;
-{
- unsigned ptepindex;
- if (va >= UPT_MIN_ADDRESS)
- return 0;
-
- if (mpte == NULL) {
- ptepindex = (va >> PDRSHIFT);
-#if defined(PTPHINT)
- if (pmap->pm_ptphint &&
- (pmap->pm_ptphint->pindex == ptepindex)) {
- mpte = pmap->pm_ptphint;
- } else {
- mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
- pmap->pm_ptphint = mpte;
- }
-#else
- mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
-#endif
- }
-
- return pmap_unwire_pte_hold(pmap, mpte);
-}
-
-/*
- * Initialize a preallocated and zeroed pmap structure,
- * such as one in a vmspace structure.
- */
-void
-pmap_pinit(pmap)
- register struct pmap *pmap;
-{
- vm_page_t ptdpg;
- /*
- * No need to allocate page table space yet but we do need a valid
- * page directory table.
- */
-
- if (pdstackptr > 0) {
- --pdstackptr;
- pmap->pm_pdir = (pd_entry_t *)pdstack[pdstackptr];
- } else {
- pmap->pm_pdir =
- (pd_entry_t *)kmem_alloc_pageable(kernel_map, PAGE_SIZE);
- }
-
- /*
- * allocate object for the ptes
- */
- pmap->pm_pteobj = vm_object_allocate( OBJT_DEFAULT, PTDPTDI + 1);
-
- /*
- * allocate the page directory page
- */
-retry:
- ptdpg = pmap_page_alloc( pmap->pm_pteobj, PTDPTDI);
- if (ptdpg == NULL)
- goto retry;
-
- ptdpg->wire_count = 1;
- ++cnt.v_wire_count;
-
- ptdpg->flags &= ~(PG_MAPPED|PG_BUSY); /* not mapped normally */
- ptdpg->valid = VM_PAGE_BITS_ALL;
-
- pmap_kenter((vm_offset_t) pmap->pm_pdir, VM_PAGE_TO_PHYS(ptdpg));
- if ((ptdpg->flags & PG_ZERO) == 0)
- bzero(pmap->pm_pdir, PAGE_SIZE);
-
- /* wire in kernel global address entries */
- bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * PTESIZE);
-
- /* install self-referential address mapping entry */
- *(unsigned *) (pmap->pm_pdir + PTDPTDI) =
- VM_PAGE_TO_PHYS(ptdpg) | PG_V | PG_RW;
-
- pmap->pm_flags = 0;
- pmap->pm_count = 1;
- pmap->pm_ptphint = NULL;
- TAILQ_INIT(&pmap->pm_pvlist);
-}
-
-static int
-pmap_release_free_page(pmap, p)
- struct pmap *pmap;
- 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
- * might as well be placed directly into the zero queue.
- */
- s = splvm();
- if (p->flags & PG_BUSY) {
- p->flags |= PG_WANTED;
- tsleep(p, PVM, "pmaprl", 0);
- splx(s);
- return 0;
- }
-
- if (p->flags & PG_WANTED) {
- p->flags &= ~PG_WANTED;
- wakeup(p);
- }
-
- /*
- * Remove the page table page from the processes address space.
- */
- pde[p->pindex] = 0;
- --pmap->pm_stats.resident_count;
-
- if (p->hold_count) {
- panic("pmap_release: freeing held page table page");
- }
- /*
- * Page directory pages need to have the kernel
- * stuff cleared, so they can go into the zero queue also.
- */
- if (p->pindex == PTDPTDI) {
- bzero(pde + KPTDI, nkpt * PTESIZE);
- pde[APTDPTDI] = 0;
- pmap_kremove((vm_offset_t) pmap->pm_pdir);
- }
-
-#if defined(PTPHINT)
- if (pmap->pm_ptphint &&
- (pmap->pm_ptphint->pindex == p->pindex))
- pmap->pm_ptphint = NULL;
-#endif
-
- vm_page_free_zero(p);
- splx(s);
- return 1;
-}
-
-/*
- * this routine is called if the page table page is not
- * mapped correctly.
- */
-static vm_page_t
-_pmap_allocpte(pmap, ptepindex)
- pmap_t pmap;
- unsigned ptepindex;
-{
- vm_offset_t pteva, ptepa;
- vm_page_t m;
- int needszero = 0;
-
- /*
- * Find or fabricate a new pagetable page
- */
-retry:
- m = vm_page_lookup(pmap->pm_pteobj, ptepindex);
- if (m == NULL) {
- m = pmap_page_alloc(pmap->pm_pteobj, ptepindex);
- if (m == NULL)
- goto retry;
- if ((m->flags & PG_ZERO) == 0)
- needszero = 1;
- 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;
- }
- }
-
- if (m->queue != PQ_NONE) {
- int s = splvm();
- vm_page_unqueue(m);
- splx(s);
- }
-
- 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);
-
-#if defined(PTPHINT)
- /*
- * Set the page table hint
- */
- pmap->pm_ptphint = m;
-#endif
-
- /*
- * Try to use the new mapping, but if we cannot, then
- * do it with the routine that maps the page explicitly.
- */
- if (needszero) {
- if ((((unsigned)pmap->pm_pdir[PTDPTDI]) & PG_FRAME) ==
- (((unsigned) PTDpde) & PG_FRAME)) {
- pteva = UPT_MIN_ADDRESS + i386_ptob(ptepindex);
- bzero((caddr_t) pteva, PAGE_SIZE);
- } else {
- pmap_zero_page(ptepa);
- }
- }
-
- m->valid = VM_PAGE_BITS_ALL;
- m->flags |= PG_MAPPED;
-
- return m;
-}
-
-static vm_page_t
-pmap_allocpte(pmap, va)
- pmap_t pmap;
- vm_offset_t va;
-{
- unsigned 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) {
-#if defined(PTPHINT)
- /*
- * In order to get the page table page, try the
- * hint first.
- */
- if (pmap->pm_ptphint &&
- (pmap->pm_ptphint->pindex == ptepindex)) {
- m = pmap->pm_ptphint;
- } else {
- m = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
- pmap->pm_ptphint = m;
- }
-#else
- m = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
-#endif
- ++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.
- */
-void
-pmap_release(pmap)
- register struct pmap *pmap;
-{
- vm_page_t p,n,ptdpg;
- vm_object_t object = pmap->pm_pteobj;
-
- if (object->ref_count != 1)
- panic("pmap_release: pteobj reference count != 1");
-
- pmap_lock(pmap);
- ptdpg = NULL;
-retry:
- for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) {
- n = TAILQ_NEXT(p, listq);
- if (p->pindex == PTDPTDI) {
- ptdpg = p;
- continue;
- }
- if (!pmap_release_free_page(pmap, p))
- goto retry;
- }
-
- if (ptdpg && !pmap_release_free_page(pmap, ptdpg))
- goto retry;
-
- vm_object_deallocate(object);
- if (pdstackptr < PDSTACKMAX) {
- pdstack[pdstackptr] = (vm_offset_t) pmap->pm_pdir;
- ++pdstackptr;
- } else {
- kmem_free(kernel_map, (vm_offset_t) pmap->pm_pdir, PAGE_SIZE);
- }
- pmap->pm_pdir = 0;
-}
-
-/*
- * grow the number of kernel page table entries, if needed
- */
-void
-pmap_growkernel(vm_offset_t addr)
-{
- struct proc *p;
- struct pmap *pmap;
- int s;
-
- s = splhigh();
- if (kernel_vm_end == 0) {
- kernel_vm_end = KERNBASE;
- nkpt = 0;
- while (pdir_pde(PTD, kernel_vm_end)) {
- kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
- ++nkpt;
- }
- }
- addr = (addr + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
- while (kernel_vm_end < addr) {
- if (pdir_pde(PTD, kernel_vm_end)) {
- kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
- continue;
- }
- ++nkpt;
- if (!nkpg) {
- vm_offset_t ptpkva = (vm_offset_t) vtopte(addr);
- /*
- * This index is bogus, but out of the way
- */
- vm_pindex_t ptpidx = (ptpkva >> PAGE_SHIFT);
- nkpg = vm_page_alloc(kernel_object,
- ptpidx, VM_ALLOC_SYSTEM);
- if (!nkpg)
- panic("pmap_growkernel: no memory to grow kernel");
- vm_page_wire(nkpg);
- vm_page_remove(nkpg);
- pmap_zero_page(VM_PAGE_TO_PHYS(nkpg));
- }
- pdir_pde(PTD, kernel_vm_end) = (pd_entry_t) (VM_PAGE_TO_PHYS(nkpg) | PG_V | PG_RW);
- nkpg = NULL;
-
- for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
- if (p->p_vmspace) {
- pmap = &p->p_vmspace->vm_pmap;
- *pmap_pde(pmap, kernel_vm_end) = pdir_pde(PTD, kernel_vm_end);
- }
- }
- *pmap_pde(kernel_pmap, kernel_vm_end) = pdir_pde(PTD, kernel_vm_end);
- kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
- }
- splx(s);
-}
-
-/*
- * Retire the given physical map from service.
- * Should only be called if the map contains
- * no valid mappings.
- */
-void
-pmap_destroy(pmap)
- register pmap_t pmap;
-{
- int count;
-
- if (pmap == NULL)
- return;
-
- count = --pmap->pm_count;
- if (count == 0) {
- pmap_release(pmap);
- free((caddr_t) pmap, M_VMPMAP);
- }
-}
-
-/*
- * Add a reference to the specified pmap.
- */
-void
-pmap_reference(pmap)
- pmap_t pmap;
-{
- if (pmap != NULL) {
- pmap->pm_count++;
- }
-}
-
-/***************************************************
-* page management routines.
- ***************************************************/
-
-/*
- * free the pv_entry back to the free list
- */
-static PMAP_INLINE void
-free_pv_entry(pv)
- pv_entry_t pv;
-{
- ++pv_freelistcnt;
- TAILQ_INSERT_HEAD(&pv_freelist, pv, pv_list);
-}
-
-/*
- * get a new pv_entry, allocating a block from the system
- * when needed.
- * the memory allocation is performed bypassing the malloc code
- * because of the possibility of allocations at interrupt time.
- */
-static pv_entry_t
-get_pv_entry()
-{
- pv_entry_t tmp;
-
- /*
- * get more pv_entry pages if needed
- */
- if (pv_freelistcnt < PV_FREELIST_MIN || !TAILQ_FIRST(&pv_freelist)) {
- pmap_alloc_pv_entry();
- }
- /*
- * get a pv_entry off of the free list
- */
- --pv_freelistcnt;
- tmp = TAILQ_FIRST(&pv_freelist);
- TAILQ_REMOVE(&pv_freelist, tmp, pv_list);
- return tmp;
-}
-
-/*
- * This *strange* allocation routine eliminates the possibility of a malloc
- * failure (*FATAL*) for a pv_entry_t data structure.
- * also -- this code is MUCH MUCH faster than the malloc equiv...
- * We really need to do the slab allocator thingie here.
- */
-static void
-pmap_alloc_pv_entry()
-{
- /*
- * do we have any pre-allocated map-pages left?
- */
- if (npvvapg) {
- vm_page_t m;
-
- /*
- * allocate a physical page out of the vm system
- */
- m = vm_page_alloc(kernel_object,
- OFF_TO_IDX(pvva - vm_map_min(kernel_map)),
- VM_ALLOC_INTERRUPT);
- if (m) {
- int newentries;
- int i;
- pv_entry_t entry;
-
- newentries = (PAGE_SIZE / sizeof(struct pv_entry));
- /*
- * wire the page
- */
- vm_page_wire(m);
- m->flags &= ~PG_BUSY;
- /*
- * let the kernel see it
- */
- pmap_kenter(pvva, VM_PAGE_TO_PHYS(m));
-
- entry = (pv_entry_t) pvva;
- /*
- * update the allocation pointers
- */
- pvva += PAGE_SIZE;
- --npvvapg;
-
- /*
- * free the entries into the free list
- */
- for (i = 0; i < newentries; i++) {
- free_pv_entry(entry);
- entry++;
- }
- }
- }
- if (!TAILQ_FIRST(&pv_freelist))
- panic("get_pv_entry: cannot get a pv_entry_t");
-}
-
-/*
- * init the pv_entry allocation system
- */
-#define PVSPERPAGE 64
-void
-init_pv_entries(npg)
- int npg;
-{
- /*
- * allocate enough kvm space for PVSPERPAGE entries per page (lots)
- * kvm space is fairly cheap, be generous!!! (the system can panic if
- * this is too small.)
- */
- npvvapg = ((npg * PVSPERPAGE) * sizeof(struct pv_entry)
- + PAGE_SIZE - 1) / PAGE_SIZE;
- pvva = kmem_alloc_pageable(kernel_map, npvvapg * PAGE_SIZE);
- /*
- * get the first batch of entries
- */
- pmap_alloc_pv_entry();
-}
-
-/*
- * If it is the first entry on the list, it is actually
- * in the header and we must copy the following entry up
- * to the header. Otherwise we must search the list for
- * the entry. In either case we free the now unused entry.
- */
-
-static int
-pmap_remove_entry(pmap, ppv, va)
- struct pmap *pmap;
- pv_table_t *ppv;
- vm_offset_t va;
-{
- pv_entry_t pv;
- int rtval;
- int s;
-
- s = splvm();
- if (ppv->pv_list_count < pmap->pm_stats.resident_count) {
- for (pv = TAILQ_FIRST(&ppv->pv_list);
- pv;
- pv = TAILQ_NEXT(pv, pv_list)) {
- if (pmap == pv->pv_pmap && va == pv->pv_va)
- break;
- }
- } else {
- for (pv = TAILQ_FIRST(&pmap->pm_pvlist);
- pv;
- pv = TAILQ_NEXT(pv, pv_plist)) {
- if (va == pv->pv_va)
- break;
- }
- }
-
- rtval = 0;
- if (pv) {
- rtval = pmap_unuse_pt(pmap, va, pv->pv_ptem);
- TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
- --ppv->pv_list_count;
- TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
- free_pv_entry(pv);
- }
-
- splx(s);
- return rtval;
-}
-
-/*
- * Create a pv entry for page at pa for
- * (pmap, va).
- */
-static 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 pv;
- pv_table_t *ppv;
-
- s = splvm();
- pv = get_pv_entry();
- pv->pv_va = va;
- pv->pv_pmap = pmap;
- pv->pv_ptem = mpte;
-
- TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
-
- ppv = pa_to_pvh(pa);
- TAILQ_INSERT_TAIL(&ppv->pv_list, pv, pv_list);
- ++ppv->pv_list_count;
-
- splx(s);
-}
-
-/*
- * pmap_remove_pte: do the things to unmap a page in a process
- */
-static int
-pmap_remove_pte(pmap, ptq, va)
- struct pmap *pmap;
- unsigned *ptq;
- vm_offset_t va;
-{
- unsigned oldpte;
- pv_table_t *ppv;
-
- oldpte = *ptq;
- *ptq = 0;
- if (oldpte & PG_W)
- pmap->pm_stats.wired_count -= 1;
- pmap->pm_stats.resident_count -= 1;
- if (oldpte & PG_MANAGED) {
- ppv = pa_to_pvh(oldpte);
- if (oldpte & PG_M) {
-#if defined(PMAP_DIAGNOSTIC)
- if (pmap_nw_modified((pt_entry_t) oldpte)) {
- printf("pmap_remove: modified page not writable: va: 0x%lx, pte: 0x%lx\n", va, (int) oldpte);
- }
-#endif
- if (pmap_track_modified(va))
- ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
- }
- return pmap_remove_entry(pmap, ppv, va);
- } else {
- return pmap_unuse_pt(pmap, va, NULL);
- }
-
- return 0;
-}
-
-/*
- * Remove a single page from a process address space
- */
-static void
-pmap_remove_page(pmap, va)
- struct pmap *pmap;
- register vm_offset_t va;
-{
- register unsigned *ptq;
-
- /*
- * if there is no pte for this address, just skip it!!!
- */
- if (*pmap_pde(pmap, va) == 0) {
- return;
- }
-
- /*
- * get a local va for mappings for this pmap.
- */
- ptq = get_ptbase(pmap) + i386_btop(va);
- if (*ptq) {
- (void) pmap_remove_pte(pmap, ptq, va);
- invltlb_1pg(va);
- }
- return;
-}
-
-/*
- * Remove the given range of addresses from the specified map.
- *
- * It is assumed that the start and end are properly
- * rounded to the page size.
- */
-void
-pmap_remove(pmap, sva, eva)
- struct pmap *pmap;
- register vm_offset_t sva;
- register vm_offset_t eva;
-{
- register unsigned *ptbase;
- vm_offset_t pdnxt;
- vm_offset_t ptpaddr;
- vm_offset_t sindex, eindex;
- int anyvalid;
-
- if (pmap == NULL)
- return;
-
- pmap_lock(pmap);
- /*
- * special handling of removing one page. a very
- * common operation and easy to short circuit some
- * code.
- */
- if ((sva + PAGE_SIZE) == eva) {
- pmap_remove_page(pmap, sva);
- pmap_unlock(pmap);
- return;
- }
-
- anyvalid = 0;
-
- /*
- * Get a local virtual address for the mappings that are being
- * worked with.
- */
- ptbase = get_ptbase(pmap);
-
- sindex = i386_btop(sva);
- eindex = i386_btop(eva);
-
- for (; sindex < eindex; sindex = pdnxt) {
-
- /*
- * Calculate index for next page table.
- */
- pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
- ptpaddr = (vm_offset_t) *pmap_pde(pmap, i386_ptob(sindex));
-
- /*
- * Weed out invalid mappings. Note: we assume that the page
- * directory table is always allocated, and in kernel virtual.
- */
- if (ptpaddr == 0)
- continue;
-
- /*
- * Limit our scan to either the end of the va represented
- * by the current page table page, or to the end of the
- * range being removed.
- */
- if (pdnxt > eindex) {
- pdnxt = eindex;
- }
-
- for ( ;sindex != pdnxt; sindex++) {
- vm_offset_t va;
- if (ptbase[sindex] == 0) {
- continue;
- }
- va = i386_ptob(sindex);
-
- anyvalid++;
- if (pmap_remove_pte(pmap,
- ptbase + sindex, va))
- break;
- }
- }
-
- if (anyvalid) {
- invltlb();
- }
- pmap_unlock(pmap);
-}
-
-/*
- * Routine: pmap_remove_all
- * Function:
- * Removes this physical page from
- * all physical maps in which it resides.
- * Reflects back modify bits to the pager.
- *
- * Notes:
- * Original versions of this routine were very
- * inefficient because they iteratively called
- * pmap_remove (slow...)
- */
-
-static void
-pmap_remove_all(pa)
- vm_offset_t pa;
-{
- register pv_entry_t pv;
- pv_table_t *ppv;
- register unsigned *pte, tpte;
- int nmodify;
- int update_needed;
- int s;
-
- nmodify = 0;
- update_needed = 0;
-#if defined(PMAP_DIAGNOSTIC)
- /*
- * XXX this makes pmap_page_protect(NONE) illegal for non-managed
- * pages!
- */
- if (!pmap_is_managed(pa)) {
- panic("pmap_page_protect: illegal for unmanaged page, va: 0x%lx", pa);
- }
-#endif
-
- s = splvm();
- ppv = pa_to_pvh(pa);
- while ((pv = TAILQ_FIRST(&ppv->pv_list)) != NULL) {
- pmap_lock(pv->pv_pmap);
- pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
-
- pv->pv_pmap->pm_stats.resident_count--;
-
- tpte = *pte;
- *pte = 0;
- if (tpte & PG_W)
- 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", pv->pv_va, tpte);
- }
-#endif
- if (pmap_track_modified(pv->pv_va))
- ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
- }
- if (!update_needed &&
- ((!curproc || (&curproc->p_vmspace->vm_pmap == pv->pv_pmap)) ||
- (pv->pv_pmap == kernel_pmap))) {
- update_needed = 1;
- }
-
- TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
- TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
- --ppv->pv_list_count;
- pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
- pmap_unlock(pv->pv_pmap);
- free_pv_entry(pv);
- }
-
- if (update_needed)
- invltlb();
- splx(s);
- return;
-}
-
-/*
- * Set the physical protection on the
- * specified range of this map as requested.
- */
-void
-pmap_protect(pmap, sva, eva, prot)
- register pmap_t pmap;
- vm_offset_t sva, eva;
- vm_prot_t prot;
-{
- register unsigned *ptbase;
- vm_offset_t pdnxt;
- vm_offset_t ptpaddr;
- vm_offset_t sindex, eindex;
- int anychanged;
-
-
- if (pmap == NULL)
- return;
-
- if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
- pmap_remove(pmap, sva, eva);
- return;
- }
- if (prot & VM_PROT_WRITE) {
- return;
- }
-
- pmap_lock(pmap);
- anychanged = 0;
-
- ptbase = get_ptbase(pmap);
-
- sindex = i386_btop(sva);
- eindex = i386_btop(eva);
-
- for (; sindex < eindex; sindex = pdnxt) {
-
- pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
- ptpaddr = (vm_offset_t) *pmap_pde(pmap, i386_ptob(sindex));
-
- /*
- * Weed out invalid mappings. Note: we assume that the page
- * directory table is always allocated, and in kernel virtual.
- */
- if (ptpaddr == 0)
- continue;
-
- if (pdnxt > eindex) {
- pdnxt = eindex;
- }
-
- for (; sindex != pdnxt; sindex++) {
-
- unsigned pbits = ptbase[sindex];
-
- if (pbits & PG_RW) {
- if (pbits & PG_M) {
- 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);
- anychanged = 1;
- }
- }
- }
- pmap_unlock(pmap);
- if (anychanged)
- invltlb();
-}
-
-/*
- * Insert the given physical page (p) at
- * the specified virtual address (v) in the
- * target physical map with the protection requested.
- *
- * If specified, the page will be wired down, meaning
- * that the related pte can not be reclaimed.
- *
- * NB: This is the only routine which MAY NOT lazy-evaluate
- * or lose information. That is, this routine must actually
- * insert this page into the given map NOW.
- */
-void
-pmap_enter(pmap, va, pa, prot, wired)
- register pmap_t pmap;
- vm_offset_t va;
- register vm_offset_t pa;
- vm_prot_t prot;
- boolean_t wired;
-{
- register unsigned *pte;
- vm_offset_t opa;
- vm_offset_t origpte, newpte;
- vm_page_t mpte;
-
- if (pmap == NULL)
- return;
-
- pmap_lock(pmap);
- 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;
- /*
- * In the case that a page table page is not
- * resident, we are creating it here.
- */
- if (va < UPT_MIN_ADDRESS)
- mpte = pmap_allocpte(pmap, va);
-
- pte = pmap_pte(pmap, va);
- /*
- * Page Directory table entry not valid, we need a new PT page
- */
- if (pte == NULL) {
- panic("pmap_enter: invalid page directory, pdir=%p, va=0x%lx\n",
- pmap->pm_pdir[PTDPTDI], va);
- }
-
- origpte = *(vm_offset_t *)pte;
- pa &= PG_FRAME;
- opa = origpte & PG_FRAME;
-
- /*
- * Mapping has not changed, must be protection or wiring change.
- */
- if (origpte && (opa == pa)) {
- /*
- * Wiring change, just update stats. We don't worry about
- * wiring PT pages as they remain resident as long as there
- * are valid mappings in them. Hence, if a user page is wired,
- * the PT page will be also.
- */
- if (wired && ((origpte & PG_W) == 0))
- pmap->pm_stats.wired_count++;
- else if (!wired && (origpte & PG_W))
- pmap->pm_stats.wired_count--;
-
-#if defined(PMAP_DIAGNOSTIC)
- if (pmap_nw_modified((pt_entry_t) origpte)) {
- printf("pmap_enter: modified page not writable: va: 0x%lx, pte: 0x%lx\n", va, origpte);
- }
-#endif
-
- /*
- * We might be turning off write access to the page,
- * so we go ahead and sense modify status.
- */
- if (origpte & PG_MANAGED) {
- vm_page_t m;
- if (origpte & PG_M) {
- if (pmap_track_modified(va)) {
- m = PHYS_TO_VM_PAGE(pa);
- m->dirty = VM_PAGE_BITS_ALL;
- }
- }
- pa |= PG_MANAGED;
- }
-
- if (mpte)
- --mpte->hold_count;
-
- goto validate;
- }
- /*
- * Mapping has changed, invalidate old range and fall through to
- * handle validating new mapping.
- */
- 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
- * raise IPL while manipulating pv_table since pmap_enter can be
- * called at interrupt time.
- */
- if (pmap_is_managed(pa)) {
- pmap_insert_entry(pmap, va, mpte, pa);
- pa |= PG_MANAGED;
- }
-
- /*
- * Increment counters
- */
- pmap->pm_stats.resident_count++;
- if (wired)
- pmap->pm_stats.wired_count++;
-
-validate:
- /*
- * Now validate mapping with desired protection/wiring.
- */
- newpte = (vm_offset_t) (pa | pte_prot(pmap, prot) | PG_V);
-
- if (wired)
- newpte |= PG_W;
- if (va < UPT_MIN_ADDRESS)
- newpte |= PG_U;
-
- /*
- * if the mapping or permission bits are different, we need
- * to update the pte.
- */
- if ((origpte & ~(PG_M|PG_A)) != newpte) {
- *pte = newpte;
- if (origpte)
- invltlb_1pg(va);
- }
- pmap_unlock(pmap);
-}
-
-/*
- * this code makes some *MAJOR* assumptions:
- * 1. Current pmap & pmap exists.
- * 2. Not wired.
- * 3. Read access.
- * 4. No page table pages.
- * 5. Tlbflush is deferred to calling procedure.
- * 6. Page IS managed.
- * but is *MUCH* faster than pmap_enter...
- */
-
-static vm_page_t
-pmap_enter_quick(pmap, va, pa, mpte)
- register pmap_t pmap;
- vm_offset_t va;
- register vm_offset_t pa;
- vm_page_t mpte;
-{
- register unsigned *pte;
-
- /*
- * In the case that a page table page is not
- * resident, we are creating it here.
- */
- if (va < UPT_MIN_ADDRESS) {
- unsigned ptepindex;
- vm_offset_t ptepa;
-
- /*
- * Calculate pagetable page index
- */
- ptepindex = va >> PDRSHIFT;
- if (mpte && (mpte->pindex == ptepindex)) {
- ++mpte->hold_count;
- } else {
-retry:
- /*
- * 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) {
-#if defined(PTPHINT)
- if (pmap->pm_ptphint &&
- (pmap->pm_ptphint->pindex == ptepindex)) {
- mpte = pmap->pm_ptphint;
- } else {
- mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
- pmap->pm_ptphint = mpte;
- }
-#else
- mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
-#endif
- if (mpte == NULL)
- goto retry;
- ++mpte->hold_count;
- } else {
- mpte = _pmap_allocpte(pmap, ptepindex);
- }
- }
- } else {
- mpte = NULL;
- }
-
- /*
- * 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) {
- if (mpte)
- pmap_unwire_pte_hold(pmap, mpte);
- return 0;
- }
-
- /*
- * Enter on the PV list if part of our managed memory Note that we
- * raise IPL while manipulating pv_table since pmap_enter can be
- * called at interrupt time.
- */
- pmap_insert_entry(pmap, va, mpte, pa);
-
- /*
- * Increment counters
- */
- pmap->pm_stats.resident_count++;
-
- /*
- * Now validate mapping with RO protection
- */
- *pte = pa | PG_V | PG_U | PG_MANAGED;
-
- return mpte;
-}
-
-#define MAX_INIT_PT (96)
-/*
- * pmap_object_init_pt preloads the ptes for a given object
- * into the specified pmap. This eliminates the blast of soft
- * faults on process startup and immediately after an mmap.
- */
-void
-pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
- pmap_t pmap;
- vm_offset_t addr;
- vm_object_t object;
- vm_pindex_t pindex;
- vm_size_t size;
- int limit;
-{
- vm_offset_t tmpidx;
- int psize;
- vm_page_t p, mpte;
- int objpgs;
-
- psize = i386_btop(size);
-
- if (!pmap || (object->type != OBJT_VNODE) ||
- (limit && (psize > MAX_INIT_PT) &&
- (object->resident_page_count > MAX_INIT_PT))) {
- return;
- }
-
- pmap_lock(pmap);
- if (psize + pindex > object->size)
- psize = object->size - pindex;
-
- mpte = NULL;
- /*
- * if we are processing a major portion of the object, then scan the
- * entire thing.
- */
- if (psize > (object->size >> 2)) {
- objpgs = psize;
-
- for (p = TAILQ_FIRST(&object->memq);
- ((objpgs > 0) && (p != NULL));
- p = TAILQ_NEXT(p, listq)) {
-
- tmpidx = p->pindex;
- if (tmpidx < pindex) {
- continue;
- }
- tmpidx -= pindex;
- if (tmpidx >= psize) {
- continue;
- }
- if (((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
- (p->busy == 0) &&
- (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
- if ((p->queue - p->pc) == PQ_CACHE)
- vm_page_deactivate(p);
- p->flags |= PG_BUSY;
- mpte = pmap_enter_quick(pmap,
- addr + i386_ptob(tmpidx),
- VM_PAGE_TO_PHYS(p), mpte);
- p->flags |= PG_MAPPED;
- PAGE_WAKEUP(p);
- }
- objpgs -= 1;
- }
- } else {
- /*
- * else lookup the pages one-by-one.
- */
- for (tmpidx = 0; tmpidx < psize; tmpidx += 1) {
- p = vm_page_lookup(object, tmpidx + pindex);
- if (p &&
- ((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
- (p->busy == 0) &&
- (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
- if ((p->queue - p->pc) == PQ_CACHE)
- vm_page_deactivate(p);
- p->flags |= PG_BUSY;
- mpte = pmap_enter_quick(pmap,
- addr + i386_ptob(tmpidx),
- VM_PAGE_TO_PHYS(p), mpte);
- p->flags |= PG_MAPPED;
- PAGE_WAKEUP(p);
- }
- }
- }
- pmap_unlock(pmap);
- return;
-}
-
-/*
- * pmap_prefault provides a quick way of clustering
- * pagefaults into a processes address space. It is a "cousin"
- * of pmap_object_init_pt, except it runs at page fault time instead
- * of mmap time.
- */
-#define PFBAK 2
-#define PFFOR 2
-#define PAGEORDER_SIZE (PFBAK+PFFOR)
-
-static int pmap_prefault_pageorder[] = {
- -PAGE_SIZE, PAGE_SIZE, -2 * PAGE_SIZE, 2 * PAGE_SIZE
-};
-
-void
-pmap_prefault(pmap, addra, entry, object)
- pmap_t pmap;
- vm_offset_t addra;
- vm_map_entry_t entry;
- vm_object_t object;
-{
- int i;
- vm_offset_t starta;
- vm_offset_t addr;
- vm_pindex_t pindex;
- vm_page_t m, mpte;
-
- if (entry->object.vm_object != object)
- return;
-
- if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap))
- return;
-
- pmap_lock(pmap);
- starta = addra - PFBAK * PAGE_SIZE;
- if (starta < entry->start) {
- starta = entry->start;
- } else if (starta > addra) {
- starta = 0;
- }
-
- mpte = NULL;
- for (i = 0; i < PAGEORDER_SIZE; i++) {
- vm_object_t lobject;
- unsigned *pte;
-
- addr = addra + pmap_prefault_pageorder[i];
- if (addr < starta || addr >= entry->end)
- continue;
-
- if ((*pmap_pde(pmap, addr)) == NULL)
- continue;
-
- pte = (unsigned *) vtopte(addr);
- if (*pte)
- continue;
-
- pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;
- lobject = object;
- for (m = vm_page_lookup(lobject, pindex);
- (!m && (lobject->type == OBJT_DEFAULT) && (lobject->backing_object));
- lobject = lobject->backing_object) {
- if (lobject->backing_object_offset & PAGE_MASK)
- break;
- pindex += (lobject->backing_object_offset >> PAGE_SHIFT);
- m = vm_page_lookup(lobject->backing_object, pindex);
- }
-
- /*
- * give-up when a page is not in memory
- */
- if (m == NULL)
- break;
-
- if (((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
- (m->busy == 0) &&
- (m->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
-
- if ((m->queue - m->pc) == PQ_CACHE) {
- vm_page_deactivate(m);
- }
- m->flags |= PG_BUSY;
- mpte = pmap_enter_quick(pmap, addr,
- VM_PAGE_TO_PHYS(m), mpte);
- m->flags |= PG_MAPPED;
- PAGE_WAKEUP(m);
- }
- }
- pmap_unlock(pmap);
-}
-
-/*
- * Routine: pmap_change_wiring
- * Function: Change the wiring attribute for a map/virtual-address
- * pair.
- * In/out conditions:
- * The mapping must already exist in the pmap.
- */
-void
-pmap_change_wiring(pmap, va, wired)
- register pmap_t pmap;
- vm_offset_t va;
- boolean_t wired;
-{
- register unsigned *pte;
-
- if (pmap == NULL)
- return;
-
- pmap_lock(pmap);
- pte = pmap_pte(pmap, va);
-
- if (wired && !pmap_pte_w(pte))
- pmap->pm_stats.wired_count++;
- else if (!wired && pmap_pte_w(pte))
- pmap->pm_stats.wired_count--;
-
- /*
- * Wiring is not a hardware characteristic so there is no need to
- * invalidate TLB.
- */
- pmap_pte_set_w(pte, wired);
- pmap_unlock(pmap);
-}
-
-
-
-/*
- * Copy the range specified by src_addr/len
- * from the source map to the range dst_addr/len
- * in the destination map.
- *
- * This routine is only advisory and need not do anything.
- */
-
-void
-pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
- pmap_t dst_pmap, src_pmap;
- vm_offset_t dst_addr;
- vm_size_t len;
- vm_offset_t src_addr;
-{
- vm_offset_t addr;
- vm_offset_t end_addr = src_addr + len;
- vm_offset_t pdnxt;
- unsigned src_frame, dst_frame;
-
- if (dst_addr != src_addr)
- return;
-
- pmap_lock2(src_pmap, dst_pmap);
- src_frame = ((unsigned) src_pmap->pm_pdir[PTDPTDI]) & PG_FRAME;
- if (src_frame != (((unsigned) PTDpde) & PG_FRAME)) {
- pmap_unlock(src_pmap);
- pmap_unlock(dst_pmap);
- return;
- }
-
- dst_frame = ((unsigned) dst_pmap->pm_pdir[PTDPTDI]) & PG_FRAME;
- if (dst_frame != (((unsigned) APTDpde) & PG_FRAME)) {
- APTDpde = (pd_entry_t) (dst_frame | PG_RW | PG_V);
- invltlb();
- }
-
- for(addr = src_addr; addr < end_addr; addr = pdnxt) {
- unsigned *src_pte, *dst_pte;
- vm_page_t dstmpte, srcmpte;
- vm_offset_t srcptepaddr;
- unsigned ptepindex;
-
- if (addr >= UPT_MIN_ADDRESS)
- panic("pmap_copy: invalid to pmap_copy page tables\n");
-
- pdnxt = ((addr + PAGE_SIZE*NPTEPG) & ~(PAGE_SIZE*NPTEPG - 1));
- ptepindex = addr >> PDRSHIFT;
-
- srcptepaddr = (vm_offset_t) src_pmap->pm_pdir[ptepindex];
- if (srcptepaddr == 0)
- continue;
-
- srcmpte = vm_page_lookup(src_pmap->pm_pteobj, ptepindex);
- if ((srcmpte->hold_count == 0) || (srcmpte->flags & PG_BUSY))
- continue;
-
- if (pdnxt > end_addr)
- pdnxt = end_addr;
-
- src_pte = (unsigned *) vtopte(addr);
- dst_pte = (unsigned *) avtopte(addr);
- while (addr < pdnxt) {
- unsigned ptetemp;
- ptetemp = *src_pte;
- /*
- * we only virtual copy managed pages
- */
- if ((ptetemp & PG_MANAGED) != 0) {
- /*
- * We have to check after allocpte for the
- * pte still being around... allocpte can
- * block.
- */
- dstmpte = pmap_allocpte(dst_pmap, addr);
- if ((*dst_pte == 0) && (ptetemp = *src_pte)) {
- /*
- * Clear the modified and
- * accessed (referenced) bits
- * during the copy.
- */
- *dst_pte = ptetemp & ~(PG_M|PG_A);
- dst_pmap->pm_stats.resident_count++;
- pmap_insert_entry(dst_pmap, addr,
- dstmpte,
- (ptetemp & PG_FRAME));
- } else {
- pmap_unwire_pte_hold(dst_pmap, dstmpte);
- }
- if (dstmpte->hold_count >= srcmpte->hold_count)
- break;
- }
- addr += PAGE_SIZE;
- ++src_pte;
- ++dst_pte;
- }
- }
- pmap_unlock(src_pmap);
- pmap_unlock(dst_pmap);
-}
-
-/*
- * Routine: pmap_kernel
- * Function:
- * Returns the physical map handle for the kernel.
- */
-pmap_t
-pmap_kernel()
-{
- return (kernel_pmap);
-}
-
-/*
- * pmap_zero_page zeros the specified (machine independent)
- * page by mapping the page into virtual memory and using
- * bzero to clear its contents, one machine dependent page
- * at a time.
- */
-void
-pmap_zero_page(phys)
- vm_offset_t phys;
-{
- if (*(int *) CMAP2)
- panic("pmap_zero_page: CMAP busy");
-
- *(int *) CMAP2 = PG_V | PG_RW | (phys & PG_FRAME);
- bzero(CADDR2, PAGE_SIZE);
- *(int *) CMAP2 = 0;
- invltlb_1pg((vm_offset_t) CADDR2);
-}
-
-/*
- * pmap_copy_page copies the specified (machine independent)
- * page by mapping the page into virtual memory and using
- * bcopy to copy the page, one machine dependent page at a
- * time.
- */
-void
-pmap_copy_page(src, dst)
- vm_offset_t src;
- vm_offset_t dst;
-{
- if (*(int *) CMAP1 || *(int *) CMAP2)
- panic("pmap_copy_page: CMAP busy");
-
- *(int *) CMAP1 = PG_V | PG_RW | (src & PG_FRAME);
- *(int *) CMAP2 = PG_V | PG_RW | (dst & PG_FRAME);
-
- bcopy(CADDR1, CADDR2, PAGE_SIZE);
-
- *(int *) CMAP1 = 0;
- *(int *) CMAP2 = 0;
- invltlb_2pg( (vm_offset_t) CADDR1, (vm_offset_t) CADDR2);
-}
-
-
-/*
- * Routine: pmap_pageable
- * Function:
- * Make the specified pages (by pmap, offset)
- * pageable (or not) as requested.
- *
- * A page which is not pageable may not take
- * a fault; therefore, its page table entry
- * must remain valid for the duration.
- *
- * This routine is merely advisory; pmap_enter
- * will specify that these pages are to be wired
- * down (or not) as appropriate.
- */
-void
-pmap_pageable(pmap, sva, eva, pageable)
- pmap_t pmap;
- vm_offset_t sva, eva;
- boolean_t pageable;
-{
-}
-
-/*
- * this routine returns true if a physical page resides
- * in the given pmap.
- */
-boolean_t
-pmap_page_exists(pmap, pa)
- pmap_t pmap;
- vm_offset_t pa;
-{
- register pv_entry_t pv;
- pv_table_t *ppv;
- int s;
-
- if (!pmap_is_managed(pa))
- return FALSE;
-
- s = splvm();
-
- ppv = pa_to_pvh(pa);
- /*
- * Not found, check current mappings returning immediately if found.
- */
- for (pv = TAILQ_FIRST(&ppv->pv_list);
- pv;
- pv = TAILQ_NEXT(pv, pv_list)) {
- if (pv->pv_pmap == pmap) {
- splx(s);
- return TRUE;
- }
- }
- splx(s);
- return (FALSE);
-}
-
-#define PMAP_REMOVE_PAGES_CURPROC_ONLY
-/*
- * Remove all pages from specified address space
- * this aids process exit speeds. Also, this code
- * is special cased for current process only, but
- * can have the more generic (and slightly slower)
- * mode enabled. This is much faster than pmap_remove
- * in the case of running down an entire address space.
- */
-void
-pmap_remove_pages(pmap, sva, eva)
- pmap_t pmap;
- vm_offset_t sva, eva;
-{
- unsigned *pte, tpte;
- pv_table_t *ppv;
- pv_entry_t pv, npv;
- int s;
-
-#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
- if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap)) {
- printf("warning: pmap_remove_pages called with non-current pmap\n");
- return;
- }
-#endif
-
- pmap_lock(pmap);
- s = splhigh();
-
- for(pv = TAILQ_FIRST(&pmap->pm_pvlist);
- pv;
- pv = npv) {
-
- if (pv->pv_va >= eva || pv->pv_va < sva) {
- npv = TAILQ_NEXT(pv, pv_plist);
- continue;
- }
-
-#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
- pte = (unsigned *)vtopte(pv->pv_va);
-#else
- pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
-#endif
- tpte = *pte;
- *pte = 0;
-
- ppv = pa_to_pvh(tpte);
-
- if (tpte) {
- pv->pv_pmap->pm_stats.resident_count--;
- if (tpte & PG_W)
- pv->pv_pmap->pm_stats.wired_count--;
- /*
- * Update the vm_page_t clean and reference bits.
- */
- if (tpte & PG_M) {
- ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
- }
- }
-
- npv = TAILQ_NEXT(pv, pv_plist);
- TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
-
- --ppv->pv_list_count;
- TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
-
- pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
- free_pv_entry(pv);
- }
- splx(s);
- invltlb();
- pmap_unlock(pmap);
-}
-
-/*
- * pmap_testbit tests bits in pte's
- * note that the testbit/changebit routines are inline,
- * and a lot of things compile-time evaluate.
- */
-static boolean_t
-pmap_testbit(pa, bit)
- register vm_offset_t pa;
- int bit;
-{
- register pv_entry_t pv;
- pv_table_t *ppv;
- unsigned *pte;
- int s;
-
- if (!pmap_is_managed(pa))
- return FALSE;
-
- ppv = pa_to_pvh(pa);
- if (TAILQ_FIRST(&ppv->pv_list) == NULL)
- return FALSE;
-
- s = splvm();
-
- for (pv = TAILQ_FIRST(&ppv->pv_list);
- pv;
- pv = TAILQ_NEXT(pv, pv_list)) {
-
- /*
- * if the bit being tested is the modified bit, then
- * mark clean_map and ptes as never
- * modified.
- */
- if (bit & (PG_A|PG_M)) {
- if (!pmap_track_modified(pv->pv_va))
- continue;
- }
-
-#if defined(PMAP_DIAGNOSTIC)
- if (!pv->pv_pmap) {
- printf("Null pmap (tb) at va: 0x%lx\n", pv->pv_va);
- continue;
- }
-#endif
- pmap_lock(pv->pv_pmap);
- pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
- if (*pte & bit) {
- pmap_unlock(pv->pv_pmap);
- splx(s);
- return TRUE;
- }
- pmap_unlock(pv->pv_pmap);
- }
- splx(s);
- return (FALSE);
-}
-
-/*
- * this routine is used to modify bits in ptes
- */
-static void
-pmap_changebit(pa, bit, setem)
- vm_offset_t pa;
- int bit;
- boolean_t setem;
-{
- register pv_entry_t pv;
- pv_table_t *ppv;
- register unsigned *pte;
- int changed;
- int s;
-
- if (!pmap_is_managed(pa))
- return;
-
- s = splvm();
- changed = 0;
- ppv = pa_to_pvh(pa);
-
- /*
- * Loop over all current mappings setting/clearing as appropos If
- * setting RO do we need to clear the VAC?
- */
- for (pv = TAILQ_FIRST(&ppv->pv_list);
- pv;
- pv = TAILQ_NEXT(pv, pv_list)) {
-
- /*
- * don't write protect pager mappings
- */
- if (!setem && (bit == PG_RW)) {
- if (!pmap_track_modified(pv->pv_va))
- continue;
- }
-
-#if defined(PMAP_DIAGNOSTIC)
- if (!pv->pv_pmap) {
- printf("Null pmap (cb) at va: 0x%lx\n", pv->pv_va);
- continue;
- }
-#endif
-
- pmap_lock(pv->pv_pmap);
- pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
- if (setem) {
- *(int *)pte |= bit;
- changed = 1;
- } else {
- vm_offset_t pbits = *(vm_offset_t *)pte;
- if (pbits & bit) {
- changed = 1;
- if (bit == PG_RW) {
- if (pbits & PG_M) {
- ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
- }
- *(int *)pte = pbits & ~(PG_M|PG_RW);
- } else {
- *(int *)pte = pbits & ~bit;
- }
- }
- }
- pmap_unlock(pv->pv_pmap);
- }
- splx(s);
- if (changed)
- invltlb();
-}
-
-/*
- * pmap_page_protect:
- *
- * Lower the permission for all mappings to a given page.
- */
-void
-pmap_page_protect(phys, prot)
- vm_offset_t phys;
- vm_prot_t prot;
-{
- if ((prot & VM_PROT_WRITE) == 0) {
- if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
- pmap_changebit(phys, PG_RW, FALSE);
- } else {
- pmap_remove_all(phys);
- }
- }
-}
-
-vm_offset_t
-pmap_phys_address(ppn)
- int ppn;
-{
- return (i386_ptob(ppn));
-}
-
-/*
- * pmap_is_referenced:
- *
- * Return whether or not the specified physical page was referenced
- * by any physical maps.
- */
-boolean_t
-pmap_is_referenced(vm_offset_t pa)
-{
- register pv_entry_t pv;
- pv_table_t *ppv;
- 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 (pv = TAILQ_FIRST(&ppv->pv_list);
- pv;
- pv = TAILQ_NEXT(pv, pv_list)) {
-
- /*
- * 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;
-
- pmap_lock(pv->pv_pmap);
- pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
- if ((int) *pte & PG_A) {
- pmap_unlock(pv->pv_pmap);
- splx(s);
- return TRUE;
- }
- pmap_unlock(pv->pv_pmap);
- }
- 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 pv;
- pv_table_t *ppv;
- unsigned *pte;
- int s;
- int rtval = 0;
-
- if (!pmap_is_managed(pa))
- return FALSE;
-
- s = splvm();
-
- ppv = pa_to_pvh(pa);
-
- if (TAILQ_FIRST(&ppv->pv_list) == NULL) {
- splx(s);
- return 0;
- }
-
- /*
- * Not found, check current mappings returning immediately if found.
- */
- for (pv = TAILQ_FIRST(&ppv->pv_list);
- pv;
- pv = TAILQ_NEXT(pv, pv_list)) {
- /*
- * 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;
-
- pmap_lock(pv->pv_pmap);
- pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
- if (pte == NULL) {
- pmap_unlock(pv->pv_pmap);
- continue;
- }
- if (*pte & PG_A) {
- rtval++;
- *pte &= ~PG_A;
- }
- pmap_unlock(pv->pv_pmap);
- }
- splx(s);
- if (rtval) {
- invltlb();
- }
- return (rtval);
-}
-
-/*
- * pmap_is_modified:
- *
- * Return whether or not the specified physical page was modified
- * in any physical maps.
- */
-boolean_t
-pmap_is_modified(vm_offset_t pa)
-{
- return pmap_testbit((pa), PG_M);
-}
-
-/*
- * Clear the modify bits on the specified physical page.
- */
-void
-pmap_clear_modify(vm_offset_t pa)
-{
- pmap_changebit((pa), PG_M, FALSE);
-}
-
-/*
- * pmap_clear_reference:
- *
- * Clear the reference bit on the specified physical page.
- */
-void
-pmap_clear_reference(vm_offset_t pa)
-{
- pmap_changebit((pa), PG_A, FALSE);
-}
-
-/*
- * Miscellaneous support routines follow
- */
-
-static void
-i386_protection_init()
-{
- register int *kp, prot;
-
- kp = protection_codes;
- for (prot = 0; prot < 8; prot++) {
- switch (prot) {
- case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
- /*
- * Read access is also 0. There isn't any execute bit,
- * so just make it readable.
- */
- case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
- case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
- case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
- *kp++ = 0;
- break;
- case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
- case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
- case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
- case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
- *kp++ = PG_RW;
- break;
- }
- }
-}
-
-/*
- * Map a set of physical memory pages into the kernel virtual
- * address space. Return a pointer to where it is mapped. This
- * routine is intended to be used for mapping device memory,
- * NOT real memory. The non-cacheable bits are set on each
- * mapped page.
- */
-void *
-pmap_mapdev(pa, size)
- vm_offset_t pa;
- vm_size_t size;
-{
- vm_offset_t va, tmpva;
- unsigned *pte;
-
- size = roundup(size, PAGE_SIZE);
-
- va = kmem_alloc_pageable(kernel_map, size);
- if (!va)
- panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
-
- pa = pa & PG_FRAME;
- for (tmpva = va; size > 0;) {
- pte = (unsigned *)vtopte(tmpva);
- *pte = pa | PG_RW | PG_V | PG_N;
- size -= PAGE_SIZE;
- tmpva += PAGE_SIZE;
- pa += PAGE_SIZE;
- }
- invltlb();
-
- return ((void *) va);
-}
-
-/*
- * perform the pmap work for mincore
- */
-int
-pmap_mincore(pmap, addr)
- pmap_t pmap;
- vm_offset_t addr;
-{
-
- unsigned *ptep, pte;
- int val = 0;
-
- pmap_lock(pmap);
- ptep = pmap_pte(pmap, addr);
- if (ptep == 0) {
- pmap_unlock(pmap);
- return 0;
- }
-
- if (pte = *ptep) {
- vm_offset_t pa;
- val = MINCORE_INCORE;
- pa = pte & PG_FRAME;
-
- /*
- * Modified by us
- */
- if (pte & PG_M)
- val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
- /*
- * Modified by someone
- */
- else if (PHYS_TO_VM_PAGE(pa)->dirty ||
- pmap_is_modified(pa))
- val |= MINCORE_MODIFIED_OTHER;
- /*
- * Referenced by us
- */
- if (pte & PG_U)
- val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
-
- /*
- * Referenced by someone
- */
- else if ((PHYS_TO_VM_PAGE(pa)->flags & PG_REFERENCED) ||
- pmap_is_referenced(pa))
- val |= MINCORE_REFERENCED_OTHER;
- }
- pmap_unlock(pmap);
- return val;
-}
-
-#if defined(PMAP_DEBUG)
-pmap_pid_dump(int pid) {
- pmap_t pmap;
- struct proc *p;
- int npte = 0;
- int index;
- for (p = allproc.lh_first; p != NULL; p = p->p_list.le_next) {
- if (p->p_pid != pid)
- continue;
-
- if (p->p_vmspace) {
- int i,j;
- index = 0;
- pmap = &p->p_vmspace->vm_pmap;
- for(i=0;i<1024;i++) {
- pd_entry_t *pde;
- unsigned *pte;
- unsigned base = i << PDRSHIFT;
-
- pde = &pmap->pm_pdir[i];
- if (pde && pmap_pde_v(pde)) {
- for(j=0;j<1024;j++) {
- unsigned va = base + (j << PAGE_SHIFT);
- if (va >= (vm_offset_t) VM_MIN_KERNEL_ADDRESS) {
- if (index) {
- index = 0;
- printf("\n");
- }
- return npte;
- }
- pte = pmap_pte_quick( pmap, va);
- if (pte && pmap_pte_v(pte)) {
- vm_offset_t pa;
- vm_page_t m;
- pa = *(int *)pte;
- m = PHYS_TO_VM_PAGE((pa & PG_FRAME));
- printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x",
- va, pa, m->hold_count, m->wire_count, m->flags);
- npte++;
- index++;
- if (index >= 2) {
- index = 0;
- printf("\n");
- } else {
- printf(" ");
- }
- }
- }
- }
- }
- }
- }
- return npte;
-}
-#endif
-
-#if defined(DEBUG)
-
-static void pads __P((pmap_t pm));
-static void pmap_pvdump __P((vm_offset_t pa));
-
-/* print address space of pmap*/
-static void
-pads(pm)
- pmap_t pm;
-{
- unsigned va, i, j;
- unsigned *ptep;
-
- if (pm == kernel_pmap)
- return;
- for (i = 0; i < 1024; i++)
- if (pm->pm_pdir[i])
- for (j = 0; j < 1024; j++) {
- va = (i << PDRSHIFT) + (j << PAGE_SHIFT);
- if (pm == kernel_pmap && va < KERNBASE)
- continue;
- if (pm != kernel_pmap && va > UPT_MAX_ADDRESS)
- continue;
- ptep = pmap_pte_quick(pm, va);
- if (pmap_pte_v(ptep))
- printf("%x:%x ", va, *(int *) ptep);
- };
-
-}
-
-static void
-pmap_pvdump(pa)
- vm_offset_t pa;
-{
- pv_table_t *ppv;
- register pv_entry_t pv;
-
- printf("pa %x", pa);
- ppv = pa_to_pvh(pa);
- for (pv = TAILQ_FIRST(&ppv->pv_list);
- pv;
- pv = TAILQ_NEXT(pv, pv_list)) {
-#ifdef used_to_be
- printf(" -> pmap %x, va %x, flags %x",
- pv->pv_pmap, pv->pv_va, pv->pv_flags);
-#endif
- printf(" -> pmap %x, va %x",
- pv->pv_pmap, pv->pv_va);
- pads(pv->pv_pmap);
- }
- printf(" ");
-}
-#endif
diff --git a/sys/pc98/i386/trap.c b/sys/pc98/i386/trap.c
index 72f5bad..de45a14 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.6 1996/09/07 02:13:36 asami Exp $
+ * $Id: trap.c,v 1.7 1996/09/12 11:09:36 asami Exp $
*/
/*
@@ -77,13 +77,12 @@
#include <machine/trap.h>
#include <machine/../isa/isa_device.h>
-#include "isa.h"
-
#ifdef POWERFAIL_NMI
#include <sys/syslog.h>
#include <machine/clock.h>
#endif
+#include "isa.h"
#include "npx.h"
int (*pmath_emulate) __P((struct trapframe *));
@@ -92,7 +91,7 @@ extern void trap __P((struct trapframe frame));
extern int trapwrite __P((unsigned addr));
extern void syscall __P((struct trapframe frame));
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
static int trap_pfault __P((struct trapframe *, int, vm_offset_t));
#else
static int trap_pfault __P((struct trapframe *, int));
@@ -193,14 +192,14 @@ trap(frame)
#ifdef DEBUG
u_long eva;
#endif
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
vm_offset_t va;
#endif
type = frame.tf_trapno;
code = frame.tf_err;
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
/* XXX:
* CYRIX 486 CPU FIX.
* If you use cyrix cpu, you often encouter strange signal 11's?
@@ -211,7 +210,7 @@ trap(frame)
va = (vm_offset_t)(rcr2());
if( type == T_PAGEFLT && ( frame.tf_eflags & PSL_I ) )
asm("sti");
-#endif /* CYRIX_486DLC */
+#endif /* CYRIX_486DLC || CYRIX_5X86 */
if (ISPL(frame.tf_cs) == SEL_UPL) {
/* user trap */
@@ -257,7 +256,7 @@ trap(frame)
break;
case T_PAGEFLT: /* page fault */
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
i = trap_pfault(&frame, TRUE, va);
#else
i = trap_pfault(&frame, TRUE);
@@ -333,7 +332,7 @@ trap(frame)
switch (type) {
case T_PAGEFLT: /* page fault */
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
(void) trap_pfault(&frame, FALSE, va);
#else
(void) trap_pfault(&frame, FALSE);
@@ -496,7 +495,7 @@ out:
* debugging code.
*/
static int
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
trap_pfault(frame, usermode,faultva)
struct trapframe *frame;
int usermode;
@@ -520,7 +519,7 @@ trap_pfault(frame, usermode)
else
ftype = VM_PROT_READ;
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
eva = faultva;
#else
eva = rcr2();
@@ -606,7 +605,7 @@ nogo:
#endif
int
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
trap_pfault(frame, usermode,faultva)
struct trapframe *frame;
int usermode;
@@ -625,7 +624,7 @@ trap_pfault(frame, usermode)
int eva;
struct proc *p = curproc;
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
eva = faultva;
#else
eva = rcr2();
diff --git a/sys/pc98/i386/userconfig.c b/sys/pc98/i386/userconfig.c
index 6bccd74..9022390 100644
--- a/sys/pc98/i386/userconfig.c
+++ b/sys/pc98/i386/userconfig.c
@@ -46,7 +46,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: userconfig.c,v 1.6 1996/09/12 11:09:38 asami Exp $
+ ** $Id: userconfig.c,v 1.7 1996/10/09 21:46:01 asami Exp $
**/
/**
@@ -116,7 +116,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
-#include <machine/clock.h>
+#include <machine/cons.h>
#include <machine/md_var.h>
#include <i386/isa/isa_device.h>
@@ -229,52 +229,14 @@ static DEV_INFO device_info[] = {
#ifdef PC98
{"sbic", "PC-9801-55 SCSI Interface", 0, CLS_STORAGE},
{"bs", "PC-9801-55 SCSI Interface", 0, CLS_STORAGE},
-{"aic", "Adaptec 152x SCSI and compatible sound cards", 0, CLS_STORAGE},
{"ahc", "Adaptec 274x/284x/294x SCSI controller", 0, CLS_STORAGE},
+{"aic", "Adaptec 152x SCSI and compatible sound cards", 0, CLS_STORAGE},
{"ncr", "NCR 53C810 SCSI controller", FLG_FIXED, CLS_STORAGE},
{"wdc", "IDE/ESDI/MFM disk controller", 0, CLS_STORAGE},
{"fdc", "Floppy disk controller", FLG_FIXED, CLS_STORAGE},
{"mcd", "Mitsumi CD-ROM", 0, CLS_STORAGE},
{"scd", "Sony CD-ROM", 0, CLS_STORAGE},
{"matcdc", "Matsushita/Panasonic/Creative CDROM", 0, CLS_STORAGE},
-
-{"ed", "NS8390 Ethernet adapters", 0, CLS_NETWORK},
-{"el", "3C501 Ethernet adapter", 0, CLS_NETWORK},
-{"ep", "3C509 Ethernet adapter", 0, CLS_NETWORK},
-{"fe", "Fujitsu MD86960A/MB869685A Ethernet adapters", 0, CLS_NETWORK},
-{"fea", "DEC DEFEA EISA FDDI adapter", 0, CLS_NETWORK},
-{"fxp", "Intel EtherExpress Pro/100B Ethernet adapter", 0, CLS_NETWORK},
-{"ie", "AT&T Starlan 10 and EN100, 3C507, NI5210 Ethernet adapters",0,CLS_NETWORK},
-{"ix", "Intel EtherExpress Ethernet adapter", 0, CLS_NETWORK},
-{"le", "DEC Etherworks 2 and 3 Ethernet adapters", 0, CLS_NETWORK},
-{"lnc", "Isolan, Novell NE2100/NE32-VL Ethernet adapters", 0,CLS_NETWORK},
-{"vx", "3COM 3C590/3C595 Ethernet adapters", 0, CLS_NETWORK},
-{"ze", "IBM/National Semiconductor PCMCIA Ethernet adapter",0, CLS_NETWORK},
-{"zp", "3COM PCMCIA Etherlink III Ethernet adapter", 0, CLS_NETWORK},
-{"de", "DEC DC21040 Ethernet adapter", FLG_FIXED, CLS_NETWORK},
-{"fpa", "DEC DEFPA PCI FDDI adapter", FLG_FIXED, CLS_NETWORK},
-
-{"sio", "8250/16450/16550 Serial port", 0, CLS_COMMS},
-
-{"lpt", "Parallel printer port", 0, CLS_COMMS},
-
-{"mse", "PC-9801 Bus Mouse", 0, CLS_INPUT},
-{"sc", "Syscons console driver", FLG_FIXED, CLS_INPUT},
-
-{"pcm", "PC-9801-86 Sound Board", 0, CLS_MMEDIA},
-{"sb", "Soundblaster PCM (SB, SBPro, SB16, ProAudio Spectrum)",0,CLS_MMEDIA},
-{"sbxvi", "Soundblaster 16", 0, CLS_MMEDIA},
-{"sbmidi", "Soundblaster MIDI interface", 0, CLS_MMEDIA},
-{"mss", "Microsoft Sound System", 0, CLS_MMEDIA},
-{"opl", "OPL-2/3 FM, Soundblaster, SBPro, SB16, ProAudio Spectrum",0,CLS_MMEDIA},
-{"mpu", "Roland MPU401 MIDI", 0, CLS_MMEDIA},
-{"pca", "PC speaker PCM audio driver", FLG_FIXED, CLS_MMEDIA},
-
-{"apm", "Advanced Power Management", FLG_FIXED, CLS_MISC},
-{"npx", "Math coprocessor", FLG_INVISIBLE, CLS_MISC},
-{"lkm", "Loadable PCI driver support", FLG_INVISIBLE, CLS_MISC},
-{"vga", "Catchall PCI VGA driver", FLG_INVISIBLE, CLS_MISC},
-{"chip", "PCI chipset support", FLG_INVISIBLE, CLS_MISC},
#else
{"bt", "Buslogic SCSI controller", 0, CLS_STORAGE},
{"ahc", "Adaptec 274x/284x/294x SCSI controller", 0, CLS_STORAGE},
@@ -292,8 +254,13 @@ static DEV_INFO device_info[] = {
{"scd", "Sony CD-ROM", 0, CLS_STORAGE},
{"matcdc", "Matsushita/Panasonic/Creative CDROM", 0, CLS_STORAGE},
{"wt", "Wangtek/Archive QIC-02 Tape drive", 0, CLS_STORAGE},
+#endif
+#ifdef PC98
+{"ed", "NS8390 Ethernet adapters", 0, CLS_NETWORK},
+#else
{"ed", "NE1000,NE2000,3C503,WD/SMC80xx Ethernet adapters",0, CLS_NETWORK},
+#endif
{"el", "3C501 Ethernet adapter", 0, CLS_NETWORK},
{"ep", "3C509 Ethernet adapter", 0, CLS_NETWORK},
{"fe", "Fujitsu MD86960A/MB869685A Ethernet adapters", 0, CLS_NETWORK},
@@ -310,20 +277,31 @@ static DEV_INFO device_info[] = {
{"fpa", "DEC DEFPA PCI FDDI adapter", FLG_FIXED, CLS_NETWORK},
{"sio", "8250/16450/16550 Serial port", 0, CLS_COMMS},
+#ifndef PC98
{"cx", "Cronyx/Sigma multiport sync/async adapter",0, CLS_COMMS},
{"rc", "RISCom/8 multiport async adapter", 0, CLS_COMMS},
{"cy", "Cyclades multiport async adapter", 0, CLS_COMMS},
+#endif
{"lpt", "Parallel printer port", 0, CLS_COMMS},
{"nic", "ISDN driver", 0, CLS_COMMS},
{"nnic", "ISDN driver", 0, CLS_COMMS},
+#ifndef PC98
{"gp", "National Instruments AT-GPIB/TNT driver", 0, CLS_COMMS},
+#endif
+#ifdef PC98
+{"mse", "Bus Mouse", 0, CLS_INPUT},
+#else
{"mse", "Microsoft Bus Mouse", 0, CLS_INPUT},
{"psm", "PS/2 Mouse", 0, CLS_INPUT},
+#endif
{"joy", "Joystick", FLG_FIXED, CLS_INPUT},
{"vt", "PCVT console driver", FLG_FIXED, CLS_INPUT},
{"sc", "Syscons console driver", FLG_FIXED, CLS_INPUT},
+#ifdef PC98
+{"pcm", "PC-9801-86 Sound Board", 0, CLS_MMEDIA},
+#endif
{"sb", "Soundblaster PCM (SB, SBPro, SB16, ProAudio Spectrum)",0,CLS_MMEDIA},
{"sbxvi", "Soundblaster 16", 0, CLS_MMEDIA},
{"sbmidi", "Soundblaster MIDI interface", 0, CLS_MMEDIA},
@@ -347,7 +325,6 @@ static DEV_INFO device_info[] = {
{"lkm", "Loadable PCI driver support", FLG_INVISIBLE, CLS_MISC},
{"vga", "Catchall PCI VGA driver", FLG_INVISIBLE, CLS_MISC},
{"chip", "PCI chipset support", FLG_INVISIBLE, CLS_MISC},
-#endif
{"","",0,0}};
@@ -2272,7 +2249,7 @@ visuserconfig(void)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: userconfig.c,v 1.6 1996/09/12 11:09:38 asami Exp $
+ * $Id: userconfig.c,v 1.7 1996/10/09 21:46:01 asami Exp $
*/
#include "scbus.h"
@@ -2633,30 +2610,98 @@ center(int y, char *str)
static int
introfunc(CmdParm *parms)
{
- int y = 3;
+ int curr_item, first_time;
+ static char *choices[] = {
+ " Skip kernel configuration and continue with installation ",
+ " Start kernel configuration in Visual mode ",
+ " Start kernel configuration in CLI mode (experts only) ",
+ };
clear();
- center(y, "!iKernel Configuration Editor!n");
- y += 2;
- putxy(2, y++, "In this next screen, you will be shown a full list of all the device");
- putxy(2, y++, "drivers which are available in this copy of the OS kernel. This is");
- putxy(2, y++, "!inot!n a list of devices which you necessarily have, simply those");
- putxy(2, y++, "which this kernel is capable of supporting.");
- ++y;
- putxy(2, y++, "You should go through each device category and delete all entries");
- putxy(2, y++, "(using the DELETE key) for devices that you do not have. This is an");
- putxy(2, y++, "important step since it minimizes the chance of conflicts and also");
- putxy(2, y++, "makes the kernel boot faster since there's no time wasted in trying to");
- putxy(2, y++, "detect non-existant hardware. If you see an entry for a device which you");
- putxy(2, y++, "you !ido!n have and it's not a PCI device (which will be auto-configured),");
- putxy(2, y++, "be sure that its configuration parameters match your actual hardware.");
- putxy(2, y++, "To edit a device's configuration, simply press ENTER while over it.");
- putxy(2, y++, "Once you are satisfied with your device configuration, press Q to");
- putxy(2, y++, "proceed with the booting process.");
- ++y;
- center(y, "!iPress a key to continue!n");
- cngetc();
- return 0;
+ center(2, "!bKernel Configuration Menu!n");
+
+ curr_item = 0;
+ first_time = 1;
+ while (1) {
+ char tmp[80];
+ int c, i, extended = 0;
+
+ for (i = 0; i < 3; i++) {
+ tmp[0] = '\0';
+ if (curr_item == i)
+ strcpy(tmp, "!i");
+ strcat(tmp, choices[i]);
+ if (curr_item == i)
+ strcat(tmp, "!n");
+ putxy(10, 5 + i, tmp);
+ }
+
+ if (first_time) {
+ putxy(2, 10, "Here you have the chance to go into kernel configuration mode, making");
+ putxy(2, 11, "any changes which may be necessary to properly adjust the kernel to");
+ putxy(2, 12, "match your hardware configuration.");
+ putxy(2, 14, "If you are installing FreeBSD for the first time, select Visual Mode");
+ putxy(2, 15, "(press Down-Arrow then ENTER).");
+ putxy(2, 17, "If you need to do more specialized kernel configuration and are an");
+ putxy(2, 18, "experienced FreeBSD user, select CLI mode.");
+ putxy(2, 20, "If you are !icertain!n that you do not need to configure your kernel");
+ putxy(2, 21, "then simply press ENTER or Q now.");
+ first_time = 0;
+ }
+
+ move(0, 0); /* move the cursor out of the way */
+ c = getchar();
+ if ((extended == 2) || (c == 588) || (c == 596)) { /* console gives "alternative" codes */
+ extended = 0; /* no longer */
+ switch (c) {
+ case 588:
+ case 'A': /* up */
+ if (curr_item > 0)
+ --curr_item;
+ break;
+
+ case 596:
+ case 'B': /* down */
+ if (curr_item < 2)
+ ++curr_item;
+ break;
+ }
+ }
+ else {
+ switch(c) {
+ case '\033':
+ extended = 1;
+ break;
+
+ case '[': /* cheat : always preceeds cursor move */
+ case 'O': /* ANSI application key mode */
+ if (extended == 1)
+ extended = 2;
+ else
+ extended = 0;
+ break;
+
+ case 'Q':
+ case 'q':
+ clear();
+ return 1; /* user requests exit */
+
+ case '\r':
+ case '\n':
+ clear();
+ if (!curr_item)
+ return 1;
+ else if (curr_item == 1)
+ return visuserconfig();
+ else {
+ putxy(0, 1, "Type \"help\" for help or \"quit\" to exit.");
+ move (0, 3);
+ return 0;
+ }
+ break;
+ }
+ }
+ }
}
#endif
diff --git a/sys/pc98/i386/vm_machdep.c b/sys/pc98/i386/vm_machdep.c
index 3f5eb39..4e1581c 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.4 1996/09/12 11:09:41 asami Exp $
+ * $Id: vm_machdep.c,v 1.5 1996/10/09 21:46:03 asami Exp $
*/
#include "npx.h"
@@ -68,6 +68,7 @@
#ifdef PC98
#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/epsonio.h>
#else
#include <i386/isa/isa.h>
#endif
@@ -631,8 +632,7 @@ cpu_wait(p)
struct proc *p;
{
/* drop per-process resources */
- pmap_qremove((vm_offset_t) p->p_addr, UPAGES);
- kmem_free(u_map, (vm_offset_t)p->p_addr, ctob(UPAGES));
+ pmap_dispose_proc(p);
vmspace_free(p->p_vmspace);
}
diff --git a/sys/pc98/pc98/aic6360.c b/sys/pc98/pc98/aic6360.c
index f4ec852..cbec0c0 100644
--- a/sys/pc98/pc98/aic6360.c
+++ b/sys/pc98/pc98/aic6360.c
@@ -31,7 +31,7 @@
*/
/*
- * $Id: aic6360.c,v 1.3 1996/09/03 10:23:23 asami Exp $
+ * $Id: aic6360.c,v 1.4 1996/09/10 09:37:43 asami Exp $
*
* Acknowledgements: Many of the algorithms used in this driver are
* inspired by the work of Julian Elischer (julian@tfs.com) and
@@ -113,7 +113,7 @@
#endif
#include "opt_ddb.h"
-#include <aic.h>
+#include "aic.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -188,45 +188,7 @@
/* AIC6360 definitions */
#ifdef PC98
-#define SCSISEQ (iobase + 0x00) /* SCSI sequence control */
-#define SXFRCTL0 (iobase + 0x02) /* SCSI transfer control 0 */
-#define SXFRCTL1 (iobase + 0x04) /* SCSI transfer control 1 */
-#define SCSISIGI (iobase + 0x06) /* SCSI signal in */
-#define SCSISIGO (iobase + 0x06) /* SCSI signal out */
-#define SCSIRATE (iobase + 0x08) /* SCSI rate control */
-#define SCSIID (iobase + 0x0a) /* SCSI ID */
-#define SELID (iobase + 0x0a) /* Selection/Reselection ID */
-#define SCSIDAT (iobase + 0x0c) /* SCSI Latched Data */
-#define SCSIBUS (iobase + 0x0e) /* SCSI Data Bus*/
-#define STCNT0 (iobase + 0x10) /* SCSI transfer count */
-#define STCNT1 (iobase + 0x12)
-#define STCNT2 (iobase + 0x14)
-#define CLRSINT0 (iobase + 0x16) /* Clear SCSI interrupts 0 */
-#define SSTAT0 (iobase + 0x16) /* SCSI interrupt status 0 */
-#define CLRSINT1 (iobase + 0x18) /* Clear SCSI interrupts 1 */
-#define SSTAT1 (iobase + 0x18) /* SCSI status 1 */
-#define SSTAT2 (iobase + 0x1a) /* SCSI status 2 */
-#define SCSITEST (iobase + 0x1c) /* SCSI test control */
-#define SSTAT3 (iobase + 0x1c) /* SCSI status 3 */
-#define CLRSERR (iobase + 0x1e) /* Clear SCSI errors */
-#define SSTAT4 (iobase + 0x1e) /* SCSI status 4 */
-#define SIMODE0 (iobase + 0x20) /* SCSI interrupt mode 0 */
-#define SIMODE1 (iobase + 0x22) /* SCSI interrupt mode 1 */
-#define DMACNTRL0 (iobase + 0x24) /* DMA control 0 */
-#define DMACNTRL1 (iobase + 0x26) /* DMA control 1 */
-#define DMASTAT (iobase + 0x28) /* DMA status */
-#define FIFOSTAT (iobase + 0x2a) /* FIFO status */
-#define DMADATA (iobase + 0x2c) /* DMA data */
-#define DMADATAL (iobase + 0x2c) /* DMA data low byte */
-#define DMADATAH (iobase + 0x2e) /* DMA data high byte */
-#define BRSTCNTRL (iobase + 0x30) /* Burst Control */
-#define DMADATALONG (iobase + 0x30)
-#define PORTA (iobase + 0x34) /* Port A */
-#define PORTB (iobase + 0x36) /* Port B */
-#define REV (iobase + 0x38) /* Revision (001 for 6360) */
-#define STACK (iobase + 0x3a) /* Stack */
-#define TEST (iobase + 0x3c) /* Test register */
-#define ID (iobase + 0x3e) /* ID register */
+#include <pc98/pc98/aic_98.h>
#else
#define SCSISEQ (iobase + 0x00) /* SCSI sequence control */
#define SXFRCTL0 (iobase + 0x01) /* SCSI transfer control 0 */
@@ -655,6 +617,9 @@ static struct aic_data { /* One of these per adapter */
u_char imess[AIC_MAX_MSG_LEN + 1];
u_char *imp; /* Message pointer (for multibyte messages) */
u_char imlen;
+#ifdef PC98
+ int *aicport; /* I/O port information */
+#endif
} *aicdata[NAIC];
#define AIC_SHOWACBS 0x01
@@ -769,6 +734,15 @@ aicprobe(dev)
bzero(aic, sizeof(struct aic_data));
aicdata[unit] = aic;
aic->iobase = dev->id_iobase;
+#ifdef PC98
+ if (AIC_TYPE98(dev->id_flags) == AIC98_100) {
+ /* PC-9801-100 */
+ aic->aicport = aicport_100;
+ } else {
+ /* generic card */
+ aic->aicport = aicport_generic;
+ }
+#endif
if (aic_find(aic) != 0) {
aicdata[unit] = NULL;
diff --git a/sys/pc98/pc98/aic_98.h b/sys/pc98/pc98/aic_98.h
new file mode 100644
index 0000000..8a31101
--- /dev/null
+++ b/sys/pc98/pc98/aic_98.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) KATO Takenori, 1996. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PC98_PC98_AIC_98_H__
+#define __PC98_PC98_AIC_98_H__
+
+
+
+/* generic card */
+static int aicport_generic[32] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
+};
+
+/* PC-9801-100 */
+static int aicport_100[32] = {
+ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
+ 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+ 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
+ 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e
+};
+
+#define AIC98_GENERIC 0x00
+#define AIC98_100 0x01
+
+#define AIC_TYPE98(x) ((x >> 16) & 0xff)
+
+#define SCSISEQ (iobase + aic->aicport[0x00]) /* SCSI sequence control */
+#define SXFRCTL0 (iobase + aic->aicport[0x01]) /* SCSI transfer control 0 */
+#define SXFRCTL1 (iobase + aic->aicport[0x02]) /* SCSI transfer control 1 */
+#define SCSISIGI (iobase + aic->aicport[0x03]) /* SCSI signal in */
+#define SCSISIGO (iobase + aic->aicport[0x03]) /* SCSI signal out */
+#define SCSIRATE (iobase + aic->aicport[0x04]) /* SCSI rate control */
+#define SCSIID (iobase + aic->aicport[0x05]) /* SCSI ID */
+#define SELID (iobase + aic->aicport[0x05]) /* Selection/Reselection ID */
+#define SCSIDAT (iobase + aic->aicport[0x06]) /* SCSI Latched Data */
+#define SCSIBUS (iobase + aic->aicport[0x07]) /* SCSI Data Bus*/
+#define STCNT0 (iobase + aic->aicport[0x08]) /* SCSI transfer count */
+#define STCNT1 (iobase + aic->aicport[0x09)
+#define STCNT2 (iobase + aic->aicport[0x0a)
+#define CLRSINT0 (iobase + aic->aicport[0x0b]) /* Clear SCSI interrupts 0 */
+#define SSTAT0 (iobase + aic->aicport[0x0b]) /* SCSI interrupt status 0 */
+#define CLRSINT1 (iobase + aic->aicport[0x0c]) /* Clear SCSI interrupts 1 */
+#define SSTAT1 (iobase + aic->aicport[0x0c]) /* SCSI status 1 */
+#define SSTAT2 (iobase + aic->aicport[0x0d]) /* SCSI status 2 */
+#define SCSITEST (iobase + aic->aicport[0x0e]) /* SCSI test control */
+#define SSTAT3 (iobase + aic->aicport[0x0e]) /* SCSI status 3 */
+#define CLRSERR (iobase + aic->aicport[0x0f]) /* Clear SCSI errors */
+#define SSTAT4 (iobase + aic->aicport[0x0f]) /* SCSI status 4 */
+#define SIMODE0 (iobase + aic->aicport[0x10]) /* SCSI interrupt mode 0 */
+#define SIMODE1 (iobase + aic->aicport[0x11]) /* SCSI interrupt mode 1 */
+#define DMACNTRL0 (iobase + aic->aicport[0x12]) /* DMA control 0 */
+#define DMACNTRL1 (iobase + aic->aicport[0x13]) /* DMA control 1 */
+#define DMASTAT (iobase + aic->aicport[0x14]) /* DMA status */
+#define FIFOSTAT (iobase + aic->aicport[0x15]) /* FIFO status */
+#define DMADATA (iobase + aic->aicport[0x16]) /* DMA data */
+#define DMADATAL (iobase + aic->aicport[0x16]) /* DMA data low byte */
+#define DMADATAH (iobase + aic->aicport[0x17]) /* DMA data high byte */
+#define BRSTCNTRL (iobase + aic->aicport[0x18]) /* Burst Control */
+#define DMADATALONG (iobase + aic->aicport[0x18)
+#define PORTA (iobase + aic->aicport[0x1a]) /* Port A */
+#define PORTB (iobase + aic->aicport[0x1b]) /* Port B */
+#define REV (iobase + aic->aicport[0x1c]) /* Revision (001 for 6360) */
+#define STACK (iobase + aic->aicport[0x1d]) /* Stack */
+#define TEST (iobase + aic->aicport[0x1e]) /* Test register */
+#define ID (iobase + aic->aicport[0x1f]) /* ID register */
+#endif
diff --git a/sys/pc98/pc98/clock.c b/sys/pc98/pc98/clock.c
index d9b34d1..d96f6619 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.6 1996/10/09 19:47:43 bde Exp $
+ * $Id: clock.c,v 1.7 1996/10/09 21:46:11 asami Exp $
*/
/*
@@ -46,7 +46,7 @@
/*
* modified for PC98
- * $Id: clock.c,v 1.6 1996/10/09 19:47:43 bde Exp $
+ * $Id: clock.c,v 1.7 1996/10/09 21:46:11 asami Exp $
*/
/*
@@ -1127,6 +1127,32 @@ cpu_initclocks()
writertc(RTC_STATUSA, rtc_statusa);
writertc(RTC_STATUSB, RTCSB_24HR);
+ /* Don't bother enabling the statistics clock. */
+ if (statclock_disable)
+ return;
+ diag = rtcin(RTC_DIAG);
+ if (diag != 0)
+ printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
+ register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
+ /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
+ /* unit */ 0);
+ INTREN(IRQ8);
+ writertc(RTC_STATUSB, rtc_statusb);
+#endif
+}
+
+void
+setstatclockrate(int newhz)
+{
+#ifndef PC98
+ if (newhz == RTC_PROFRATE)
+ rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
+ else
+ rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
+ writertc(RTC_STATUSA, rtc_statusa);
+#endif
+}
+
static int
sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
{
@@ -1193,29 +1219,3 @@ sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i586_freq, "I", "");
#endif /* defined(I586_CPU) || defined(I686_CPU) */
-
- /* Don't bother enabling the statistics clock. */
- if (statclock_disable)
- return;
- diag = rtcin(RTC_DIAG);
- if (diag != 0)
- printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
- register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
- /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
- /* unit */ 0);
- INTREN(IRQ8);
- writertc(RTC_STATUSB, rtc_statusb);
-#endif
-}
-
-void
-setstatclockrate(int newhz)
-{
-#ifndef PC98
- if (newhz == RTC_PROFRATE)
- rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
- else
- rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
- writertc(RTC_STATUSA, rtc_statusa);
-#endif
-}
diff --git a/sys/pc98/pc98/epsonio.h b/sys/pc98/pc98/epsonio.h
new file mode 100644
index 0000000..317b4b3
--- /dev/null
+++ b/sys/pc98/pc98/epsonio.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) KATO Takenori, 1996. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PC98_PC98_EPSONIO_H__
+#define __PC98_PC98_EPSONIO_H__
+
+#include <machine/cpufunc.h>
+#include <machine/spl.h>
+
+static inline u_char
+epson_inb(u_int port)
+{
+ u_char data;
+
+ outb(0x43f, 0x42);
+ data = inb(port);
+ outb(0x43f, 0x40);
+ return (data);
+}
+
+static inline void
+epson_outb(u_int port, u_char data)
+{
+ outb(0x43f, 0x42);
+ outb(port,data);
+ outb(0x43f, 0x40);
+}
+
+static inline void
+epson_insw(u_int port, void *addr, size_t cnt)
+{
+ int s;
+
+ s = splbio();
+ outb(0x43f, 0x42);
+ disable_intr();
+ insw((u_int)port, (void *)addr, (size_t)cnt);
+ outb(0x43f, 0x40);
+ splx(s);
+}
+
+static inline void
+epson_outsw(u_int port, void *addr, size_t cnt)
+{
+ int s;
+
+ s = splbio();
+ outb(0x43f, 0x42);
+ disable_intr();
+ outsw((u_int)port, (void *)addr, (size_t)cnt);
+ outb(0x43f, 0x40);
+ splx(s);
+}
+
+#endif
diff --git a/sys/pc98/pc98/fd.c b/sys/pc98/pc98/fd.c
index e8ad1b2..be8751c 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.5 1996/09/03 10:23:25 asami Exp $
+ * $Id: fd.c,v 1.6 1996/09/10 09:37:50 asami Exp $
*
*/
@@ -72,6 +72,7 @@
#include <sys/dkstat.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/epsonio.h>
#include <i386/isa/isa_device.h>
#include <pc98/pc98/fdreg.h>
#include <pc98/pc98/fdc.h>
diff --git a/sys/pc98/pc98/if_ed.c b/sys/pc98/pc98/if_ed.c
index ebb4749..0b1b880 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.7 1996/09/10 09:38:04 asami Exp $
+ * $Id: if_ed.c,v 1.8 1996/10/09 21:46:18 asami Exp $
*/
/*
@@ -72,6 +72,7 @@
#include <net/if.h>
#include <net/if_dl.h>
+#include <net/if_mib.h>
#include <net/if_types.h>
#ifdef INET
@@ -157,6 +158,7 @@ struct ed_softc {
u_char rec_page_start; /* first page of RX ring-buffer */
u_char rec_page_stop; /* last page of RX ring-buffer */
u_char next_packet; /* pointer to next unread RX packet */
+ struct ifmib_iso_8802_3 mibdata; /* stuff for network mgmt */
#ifdef PC98
int unit;
#endif
@@ -167,7 +169,7 @@ static struct ed_softc ed_softc[NED];
static int ed_attach __P((struct ed_softc *, int, int));
static int ed_attach_isa __P((struct isa_device *));
-static void ed_init __P((struct ed_softc *));
+static void ed_init __P((void *));
static int ed_ioctl __P((struct ifnet *, int, caddr_t));
static int ed_probe __P((struct isa_device *));
static void ed_start __P((struct ifnet *));
@@ -258,6 +260,16 @@ static struct pccard_drv ed_info = {
static void
edsuspend(struct pccard_dev *dp)
{
+ struct ed_softc *sc = &ed_softc[dp->isahd.id_unit];
+ /*
+ * Some 'ed' cards will generate a interrupt as they go away,
+ * and by the time the interrupt handler gets to the card,
+ * the interrupt can't be cleared.
+ * By setting gone here, we tell the handler to ignore the
+ * interrupt when it happens.
+ */
+ sc->gone = 1; /* avoid spinning endlessly in interrupt handler */
+
printf("ed%d: suspending\n", dp->isahd.id_unit);
}
@@ -285,6 +297,8 @@ edinit(struct pccard_dev *dp, int first)
return(ENXIO);
if (ed_attach_isa(&dp->isahd)==0)
return(ENXIO);
+ } else {
+ sc->gone = 0; /* reenable after a suspend */
}
/*
* XXX TODO:
@@ -1578,115 +1592,28 @@ ed_probe_Novell(isa_dev)
}
#if NCRD > 0
-
+
/*
- * Probe and vendor-specific initialization routine for PCCARDs
+ * Probe framework for pccards. Replicates the standard framework,
+ * minus the pccard driver registration and ignores the ether address
+ * supplied (from the CIS), relying on the probe to find it instead.
*/
static int
ed_probe_pccard(isa_dev, ether)
struct isa_device *isa_dev;
u_char *ether;
{
- struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
- int i;
- u_int memsize;
- u_char isa16bit;
-#ifdef PC98
- int unit = isa_dev->id_unit;
-#endif
-
- sc->nic_addr = isa_dev->id_iobase;
- sc->gone = 0;
- sc->is790 = 0;
- sc->cr_proto = ED_CR_RD2;
- sc->vendor = ED_VENDOR_PCCARD;
- sc->type = 0;
- sc->type_str = "PCCARD";
- sc->mem_size = isa_dev->id_msize = memsize = 16384;
- sc->isa16bit = isa16bit = 1;
-
- for (i = 0; i < ETHER_ADDR_LEN; ++i)
- sc->arpcom.ac_enaddr[i] = ether[i];
-
-#if ED_DEBUG
- printf("type = %x type_str=%s isa16bit=%d memsize=%d id_msize=%d\n",
- sc->type, sc->type_str, isa16bit, memsize, isa_dev->id_msize);
-#endif
-
- i = inb(sc->nic_addr + ED_PC_RESET);
- DELAY(100000);
- outb(sc->nic_addr + ED_PC_RESET,i);
- DELAY(100000);
- i = inb(sc->nic_addr + ED_PC_MISC);
- if (!i) {
- int j;
- printf("ed_probe_pccard: possible failure\n");
- for (j=0;j<20 && !i;j++) {
- printf(".");
- DELAY(100000);
- i = inb(sc->nic_addr + ED_PC_MISC);
- }
- if (!i) {
- printf("dead :-(\n");
- return 0;
- }
- printf("\n");
- }
- /*
- * Set initial values for width/size.
- */
-
- /* Make sure that we really have an 8390 based board */
- if (!ed_probe_generic8390(sc)) {
- printf("ed_probe_generic8390 failed\n");
- return (0);
- }
- sc->txb_cnt = 2;
- sc->tx_page_start = ED_PC_PAGE_OFFSET;
- sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE * sc->txb_cnt;
- sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
-
- sc->mem_shared = 1;
- sc->mem_start = (caddr_t) isa_dev->id_maddr;
- sc->mem_size = memsize;
- sc->mem_end = sc->mem_start + memsize;
-
- sc->mem_ring = sc->mem_start +
- sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
-
- /*
- * Now zero memory and verify that it is clear
- */
- bzero(sc->mem_start, memsize);
-
- for (i = 0; i < memsize; ++i) {
- if (sc->mem_start[i]) {
- printf("ed%d: failed to clear shared memory at %lx - check configuration\n",
- isa_dev->id_unit, kvtop(sc->mem_start + i));
-
- return (0);
- }
- sc->mem_start[i] = (i - 5) & 0xff;
- }
- for (i = 0; i < memsize; ++i) {
- if ((sc->mem_start[i] & 0xff) != ((i - 5) & 0xff)) {
- printf("ed%d: shared memory failed at %lx (%x != %x) - check configuration\n",
- isa_dev->id_unit, kvtop(sc->mem_start + i),
- sc->mem_start[i], (i-5) & 0xff);
- return (0);
-
- }
- }
+ int nports;
- i = inb(sc->nic_addr + ED_PC_MISC);
- if (!i) {
- printf("ed_probe_pccard: possible failure(2)\n");
- }
+ nports = ed_probe_WD80x3(isa_dev);
+ if (nports)
+ return (nports);
- /* clear any pending interupts that we may have caused */
- outb(sc->nic_addr + ED_P0_ISR, 0xff);
+ nports = ed_probe_Novell(isa_dev);
+ if (nports)
+ return (nports);
- return (ED_PC_IO_PORTS);
+ return (0);
}
#endif /* NCRD > 0 */
@@ -2445,8 +2372,22 @@ ed_attach(sc, unit, flags)
ifp->if_start = ed_start;
ifp->if_ioctl = ed_ioctl;
ifp->if_watchdog = ed_watchdog;
- ifp->if_init = (if_init_f_t *)ed_init;
+ ifp->if_init = ed_init;
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
+ ifp->if_linkmib = &sc->mibdata;
+ ifp->if_linkmiblen = sizeof sc->mibdata;
+ /*
+ * XXX - should do a better job.
+ */
+ if (sc->is790)
+ sc->mibdata.dot3StatsEtherChipSet =
+ DOT3CHIPSET(dot3VendorWesternDigital,
+ dot3ChipSetWesternDigital83C790);
+ else
+ sc->mibdata.dot3StatsEtherChipSet =
+ DOT3CHIPSET(dot3VendorNational,
+ dot3ChipSetNational8390);
+ sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS;
/*
* Set default state for ALTPHYS flag (used to disable the
@@ -2603,9 +2544,10 @@ ed_watchdog(ifp)
* Initialize device.
*/
static void
-ed_init(sc)
- struct ed_softc *sc;
+ed_init(xsc)
+ void *xsc;
{
+ struct ed_softc *sc = xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
int i, s;
#ifdef PC98
@@ -3043,6 +2985,9 @@ ed_rint(sc)
len += ((packet_hdr.next_packet - sc->rec_page_start) +
(sc->rec_page_stop - sc->next_packet)) * ED_PAGE_SIZE;
}
+ if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN
+ + sizeof(struct ed_ring)))
+ sc->mibdata.dot3StatsFrameTooLongs++;
}
/*
* Be fairly liberal about what we allow as a "reasonable" length
@@ -3152,11 +3097,13 @@ edintr_sc(sc)
*/
(void) inb(sc->nic_addr + ED_P0_TSR);
if (isr & ED_ISR_TXE) {
+ u_char tsr;
/*
* Excessive collisions (16)
*/
- if ((inb(sc->nic_addr + ED_P0_TSR) & ED_TSR_ABT)
+ tsr = inb(sc->nic_addr + ED_P0_TSR);
+ if ((tsr & ED_TSR_ABT)
&& (collisions == 0)) {
/*
@@ -3165,7 +3112,18 @@ edintr_sc(sc)
* TSR_ABT is set.
*/
collisions = 16;
+ sc->mibdata.dot3StatsMultipleCollisionFrames++;
+ sc->mibdata.dot3StatsExcessiveCollisions++;
+ sc->mibdata.dot3StatsCollFrequencies[15]++;
}
+ if (tsr & ED_TSR_OWC)
+ sc->mibdata.dot3StatsLateCollisions++;
+ if (tsr & ED_TSR_CDH)
+ sc->mibdata.dot3StatsSQETestErrors++;
+ if (tsr & ED_TSR_CRS)
+ sc->mibdata.dot3StatsCarrierSenseErrors++;
+ if (tsr & ED_TSR_FU)
+ sc->mibdata.dot3StatsInternalMacTransmitErrors++;
/*
* update output errors counter
@@ -3196,6 +3154,23 @@ edintr_sc(sc)
* transmission.
*/
ifp->if_collisions += collisions;
+ switch(collisions) {
+ case 0:
+ case 16:
+ break;
+ case 1:
+ sc->mibdata.dot3StatsSingleCollisionFrames++;
+ sc->mibdata.dot3StatsDeferredTransmissions++;
+ sc->mibdata.dot3StatsCollFrequencies[0]++;
+ break;
+ default:
+ sc->mibdata.dot3StatsMultipleCollisionFrames++;
+ sc->mibdata.dot3StatsDeferredTransmissions++;
+ sc->mibdata.
+ dot3StatsCollFrequencies[collisions-1]
+ ++;
+ break;
+ }
/*
* Decrement buffer in-use count if not zero (can only
@@ -3242,6 +3217,14 @@ edintr_sc(sc)
* missed packet.
*/
if (isr & ED_ISR_RXE) {
+ u_char rsr;
+ rsr = inb(sc->nic_addr + ED_P0_RSR);
+ if (rsr & ED_RSR_CRC)
+ sc->mibdata.dot3StatsFCSErrors++;
+ if (rsr & ED_RSR_FAE)
+ sc->mibdata.dot3StatsAlignmentErrors++;
+ if (rsr & ED_RSR_FO)
+ sc->mibdata.dot3StatsInternalMacReceiveErrors++;
ifp->if_ierrors++;
#ifdef ED_DEBUG
printf("ed%d: receive error %x\n", ifp->if_unit,
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 01b3b48..73725c7 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.8 1996/09/12 11:09:26 asami Exp $
+ * $Id: machdep.c,v 1.9 1996/10/09 21:45:56 asami Exp $
*/
#include "npx.h"
@@ -1063,7 +1063,7 @@ init386(first)
setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
-#ifdef CYRIX_486DLC
+#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
setidt(14, &IDTVEC(page), SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#else
setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@@ -1140,6 +1140,7 @@ init386(first)
printf(
"BIOS basemem (%ldK) != RTC basemem (%dK), setting to BIOS value\n",
+ bootinfo.bi_basemem, biosbasemem);
biosbasemem = bootinfo.bi_basemem;
/*
diff --git a/sys/pc98/pc98/pc98.c b/sys/pc98/pc98/pc98.c
index fa07580..b9f900b 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: pc98.c,v 1.7 1996/09/12 11:09:51 asami Exp $
+ * $Id: pc98.c,v 1.8 1996/10/09 21:46:31 asami Exp $
*/
/*
@@ -68,6 +68,7 @@
#include <i386/isa/isa_device.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/epsonio.h>
#else
#include <i386/isa/isa.h>
#endif
@@ -75,10 +76,6 @@
#include <i386/isa/ic/i8237.h>
#include "vector.h"
-#ifdef PC98
-unsigned char hireso = 0;
-#endif
-
/*
** Register definitions for DMA controller 1 (channels 0..3):
*/
@@ -576,11 +573,9 @@ static u_int8_t dma_inuse = 0; /* User for acquire/release */
/* high byte of address is stored in this port for i-th dma channel */
#ifdef PC98
-short dmapageport[4] =
- { 0x27, 0x21, 0x23, 0x25 };
+static int dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };
#else /* IBM-PC */
-static short dmapageport[8] =
- { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
+static int dmapageport[8] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
#endif
/*
diff --git a/sys/pc98/pc98/pc98.h b/sys/pc98/pc98/pc98.h
index 5d79e74..84c77b4 100644
--- a/sys/pc98/pc98/pc98.h
+++ b/sys/pc98/pc98/pc98.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.h 5.7 (Berkeley) 5/9/91
- * $Id: pc98.h,v 1.4 1996/09/12 11:09:54 asami Exp $
+ * $Id: pc98.h,v 1.5 1996/10/09 21:46:34 asami Exp $
*/
#ifndef _PC98_PC98_PC98_H_
@@ -193,7 +193,6 @@
#define M_H98 0x0020
#define M_NOTE 0x0040
#define M_NORMAL 0x1000
-#define M_HIGHRESO 0x2000
#define M_8M 0x8000
#if defined(KERNEL) && !defined(LOCORE)
@@ -214,52 +213,6 @@ extern unsigned char pc98_system_parameter[]; /* in locore.c */
# define PC98_TYPE_CHECK(x) ((pc98_machine_type & (x)) == (x))
-#include <machine/spl.h>
-
-static inline u_char
-epson_inb(u_int port)
-{
- u_char data;
-
- outb(0x43f, 0x42);
- data = inb(port);
- outb(0x43f, 0x40);
- return (data);
-}
-
-static inline void
-epson_outb(u_int port, u_char data)
-{
- outb(0x43f, 0x42);
- outb(port,data);
- outb(0x43f, 0x40);
-}
-
-static inline void
-epson_insw(u_int port, void *addr, size_t cnt)
-{
- int s;
-
- s = splbio();
- outb(0x43f, 0x42);
- disable_intr();
- insw((u_int)port, (void *)addr, (size_t)cnt);
- outb(0x43f, 0x40);
- splx(s);
-}
-
-static inline void
-epson_outsw(u_int port, void *addr, size_t cnt)
-{
- int s;
-
- s = splbio();
- outb(0x43f, 0x42);
- disable_intr();
- outsw((u_int)port, (void *)addr, (size_t)cnt);
- outb(0x43f, 0x40);
- splx(s);
-}
#endif /* KERNEL */
/*
diff --git a/sys/pc98/pc98/pc98_machdep.c b/sys/pc98/pc98/pc98_machdep.c
index ef476da..af9e702 100644
--- a/sys/pc98/pc98/pc98_machdep.c
+++ b/sys/pc98/pc98/pc98_machdep.c
@@ -46,8 +46,8 @@
extern int Maxmem;
extern int Maxmem_under16M;
-void init_cpu_accel_mem __P((void));
-void init_pc98_dmac __P((void));
+static void init_cpu_accel_mem __P((void));
+void pc98_init_dmac __P((void));
#ifdef EPSON_MEMWIN
static void init_epson_memwin __P((void));
@@ -107,9 +107,9 @@ static void init_epson_memwin(void)
}
#endif
-void init_cpu_accel_mem(void)
+static void init_cpu_accel_mem(void)
{
- int target_page;
+ u_int target_page;
/*
* Certain 'CPU accelerator' supports over 16MB memory on
* the machines whose BIOS doesn't store true size.
@@ -119,38 +119,38 @@ void init_cpu_accel_mem(void)
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;
+ u_int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
*(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
invltlb();
- tmp = *(int *)CADDR1;
+ tmp = *(u_int *)CADDR1;
/*
* Test for alternating 1's and 0's
*/
- *(volatile int *)CADDR1 = 0xaaaaaaaa;
- if (*(volatile int *)CADDR1 != 0xaaaaaaaa) {
+ *(volatile u_int *)CADDR1 = 0xaaaaaaaa;
+ if (*(volatile u_int *)CADDR1 != 0xaaaaaaaa) {
page_bad = TRUE;
}
/*
* Test for alternating 0's and 1's
*/
- *(volatile int *)CADDR1 = 0x55555555;
- if (*(volatile int *)CADDR1 != 0x55555555) {
+ *(volatile u_int *)CADDR1 = 0x55555555;
+ if (*(volatile u_int *)CADDR1 != 0x55555555) {
page_bad = TRUE;
}
/*
* Test for all 1's
*/
- *(volatile int *)CADDR1 = 0xffffffff;
- if (*(volatile int *)CADDR1 != 0xffffffff) {
+ *(volatile u_int *)CADDR1 = 0xffffffff;
+ if (*(volatile u_int *)CADDR1 != 0xffffffff) {
page_bad = TRUE;
}
/*
* Test for all 0's
*/
- *(volatile int *)CADDR1 = 0x0;
- if (*(volatile int *)CADDR1 != 0x0) {
+ *(volatile u_int *)CADDR1 = 0x0;
+ if (*(volatile u_int *)CADDR1 != 0x0) {
/*
* test of page failed
*/
@@ -159,7 +159,7 @@ void init_cpu_accel_mem(void)
/*
* Restore original value.
*/
- *(int *)CADDR1 = tmp;
+ *(u_int *)CADDR1 = tmp;
if (page_bad == TRUE) {
Maxmem = atop(target_page) + 256;
} else
@@ -170,7 +170,6 @@ void init_cpu_accel_mem(void)
}
}
-int dma_init_flag = 1; /* dummy */
void pc98_init_dmac(void)
{
diff --git a/sys/pc98/pc98/random_machdep.c b/sys/pc98/pc98/random_machdep.c
index 0c7f797..13ced6f 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.6 1996/10/09 19:47:44 bde Exp $
+ * $Id: random_machdep.c,v 1.7 1996/10/09 21:46:41 asami Exp $
*
* Version 0.95, last modified 18-Oct-95
*
@@ -57,11 +57,9 @@
#include <i386/isa/icu.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
-#include <i386/isa/isa_device.h>
#include <pc98/pc98/timerreg.h>
#else
#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
#include <i386/isa/timerreg.h>
#endif
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c
index 53b70ed..576ec7a 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.9 1996/09/12 11:10:00 asami Exp $
+ * $Id: syscons.c,v 1.10 1996/10/09 21:46:49 asami Exp $
*/
#include "sc.h"
@@ -164,7 +164,9 @@ static u_short mouse_or_mask[16] = {
};
static void none_saver(int blank) { }
-void (*current_saver) __P((int blank)) = none_saver;
+void (*current_saver)(int blank) = none_saver;
+int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data,
+ int flag, struct proc *p) = NULL;
/* OS specific stuff */
#ifdef not_yet_done
@@ -392,7 +394,7 @@ scprobe(struct isa_device *dev)
return(16);
#else
int i, j, retries = 5;
- unsigned char val;
+ u_char val;
/* Enable interrupts and keyboard controller */
kbd_wait();
@@ -507,7 +509,9 @@ scattach(struct isa_device *dev)
scp->cursor_atr =
scp->atr_buf + scp->xpos + scp->ypos * scp->xsize;
#endif
- scp->mouse_pos = scp->mouse_oldpos = scp->scr_buf;
+ scp->mouse_pos = scp->mouse_oldpos =
+ scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
+ scp->mouse_xpos/8);
/* initialize history buffer & pointers */
scp->history_head = scp->history_pos = scp->history =
@@ -612,6 +616,10 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
if (minor(dev) < MAXCONS && !console[minor(dev)]) {
console[minor(dev)] = alloc_scp();
}
+ if (minor(dev)<MAXCONS && !tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
+ tp->t_winsize.ws_col = console[minor(dev)]->xsize;
+ tp->t_winsize.ws_row = console[minor(dev)]->ysize;
+ }
return ((*linesw[tp->t_line].l_open)(dev, tp));
}
@@ -700,7 +708,7 @@ scintr(int unit)
(*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty);
break;
case NOKEY: /* nothing there */
- break;
+ return;
case FKEY: /* function key, return string */
if (cp = get_fstr((u_int)c, (u_int *)&len)) {
while (len-- > 0)
@@ -717,6 +725,10 @@ scintr(int unit)
(*linesw[cur_tty->t_line].l_rint)('Z', cur_tty);
break;
}
+ if (cur_console->status & MOUSE_ENABLED) {
+ cur_console->status &= ~MOUSE_VISIBLE;
+ remove_mouse_image(cur_console);
+ }
}
static int
@@ -731,7 +743,8 @@ scparam(struct tty *tp, struct termios *t)
int
scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
{
- int i, error;
+ int error;
+ u_int i;
struct tty *tp;
struct trapframe *fp;
scr_stat *scp;
@@ -741,6 +754,12 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
return ENXIO;
scp = get_scr_stat(tp->t_dev);
+ /* If there is a user_ioctl function call that first */
+ if (sc_user_ioctl) {
+ if (error = (*sc_user_ioctl)(dev, cmd, data, flag, p))
+ return error;
+ }
+
switch (cmd) { /* process console hardware related ioctl's */
case GIO_ATTR: /* get current attributes */
@@ -857,7 +876,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
case MOUSE_SHOW:
if (!(scp->status & MOUSE_ENABLED)) {
- scp->status |= MOUSE_ENABLED;
+ scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE);
scp->mouse_oldpos = scp->mouse_pos;
mark_all(scp);
}
@@ -867,7 +886,7 @@ 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 &= ~(MOUSE_ENABLED | MOUSE_VISIBLE);
mark_all(scp);
}
else
@@ -895,6 +914,8 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
case MOUSE_ACTION:
/* this should maybe only be settable from /dev/consolectl SOS */
/* send out mouse event on /dev/sysmouse */
+ if (cur_console->status & MOUSE_ENABLED)
+ cur_console->status |= MOUSE_VISIBLE;
if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
u_char buf[5];
int i;
@@ -1554,7 +1575,7 @@ sccnprobe(struct consdev *cp)
* Take control if we are the highest priority enabled display device.
*/
dvp = find_display();
- if (dvp != NULL && dvp->id_driver != &scdriver) {
+ if (dvp == NULL || dvp->id_driver != &scdriver) {
cp->cn_pri = CN_DEAD;
return;
}
@@ -1673,7 +1694,7 @@ scrn_timer()
}
/* update "pseudo" mouse pointer image */
- if ((scp->status & MOUSE_ENABLED) && crtc_vga) {
+ if ((scp->status & MOUSE_VISIBLE) && crtc_vga) {
/* did mouse move since last time ? */
if (scp->status & MOUSE_MOVED) {
/* do we need to remove old mouse pointer image ? */
@@ -2954,8 +2975,8 @@ scinit(void)
u_short volatile *cp;
u_short was;
#endif
- unsigned hw_cursor;
- int i;
+ u_int hw_cursor;
+ u_int i;
if (init_done != COLD)
return;
@@ -3090,9 +3111,12 @@ static scr_stat
scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
init_scp(scp);
- scp->scr_buf = scp->cursor_pos = scp->cursor_oldpos = scp->mouse_pos =
+ scp->scr_buf = scp->cursor_pos = scp->cursor_oldpos =
(u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
M_DEVBUF, M_WAITOK);
+ scp->mouse_pos = scp->mouse_oldpos =
+ scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
+ scp->mouse_xpos/8);
scp->history_head = scp->history_pos = scp->history =
(u_short *)malloc(scp->history_size*sizeof(u_short),
M_DEVBUF, M_WAITOK);
@@ -3127,7 +3151,7 @@ init_scp(scr_stat *scp)
scp->font_size = FONT_16;
scp->xsize = COL;
scp->ysize = ROW;
- scp->start = COL * ROW;
+ scp->start = scp->xsize * scp->ysize;
scp->end = 0;
scp->term.esc = 0;
scp->term.attr_mask = NORMAL_ATTR;
@@ -3143,7 +3167,8 @@ init_scp(scr_stat *scp)
scp->cursor_start = *(char *)pa_to_va(0x461);
scp->cursor_end = *(char *)pa_to_va(0x460);
#endif
- scp->mouse_xpos = scp->mouse_ypos = 0;
+ scp->mouse_xpos = scp->xsize*8/2;
+ scp->mouse_ypos = scp->ysize*scp->font_size/2;
scp->mouse_cut_start = scp->mouse_cut_end = NULL;
scp->mouse_signal = 0;
scp->mouse_pid = 0;
@@ -4230,7 +4255,7 @@ set_destructive_cursor(scr_stat *scp)
address = (caddr_t)VIDEOMEM + 0x4000;
}
- if (scp->status & MOUSE_ENABLED) {
+ if (scp->status & MOUSE_VISIBLE) {
if ((scp->cursor_saveunder & 0xff) == 0xd0)
bcopyw(&scp->mouse_cursor[0], cursor, scp->font_size);
else if ((scp->cursor_saveunder & 0xff) == 0xd1)
@@ -4284,7 +4309,7 @@ set_mouse_pos(scr_stat *scp)
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)) {
+ if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING)) {
u_short *ptr;
int i = 0;
@@ -4313,7 +4338,7 @@ mouse_cut_start(scr_stat *scp)
#ifndef PC98
int i;
- if (scp->status & MOUSE_ENABLED) {
+ if (scp->status & MOUSE_VISIBLE) {
if (scp->mouse_pos == scp->mouse_cut_start &&
scp->mouse_cut_start == scp->mouse_cut_end) {
cut_buffer[0] = 0x00;
@@ -4340,7 +4365,7 @@ static void
mouse_cut_end(scr_stat *scp)
{
#ifndef PC98
- if (scp->status & MOUSE_ENABLED) {
+ if (scp->status & MOUSE_VISIBLE) {
scp->status &= ~MOUSE_CUTTING;
}
#endif
@@ -4350,7 +4375,7 @@ static void
mouse_paste(scr_stat *scp)
{
#ifndef PC98
- if (scp->status & MOUSE_ENABLED) {
+ if (scp->status & MOUSE_VISIBLE) {
struct tty *tp;
u_char *ptr = cut_buffer;
diff --git a/sys/pc98/pc98/syscons.h b/sys/pc98/pc98/syscons.h
index 5504b48..38e4fb9 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.3 1996/09/04 09:52:31 asami Exp $
+ * $Id: syscons.h,v 1.4 1996/10/09 21:46:51 asami Exp $
*/
#ifndef _PC98_PC98_SYSCONS_H_
@@ -63,6 +63,7 @@
#define MOUSE_ENABLED 0x00400
#define MOUSE_MOVED 0x00800
#define MOUSE_CUTTING 0x01000
+#define MOUSE_VISIBLE 0x02000
/* configuration flags */
#define VISUAL_BELL 0x00001
@@ -225,10 +226,11 @@ typedef struct default_attr {
int rev_color; /* reverse hardware color */
} default_attr;
-void load_palette(void);
+/* misc prototypes used by different syscons related LKM's */
void set_border(u_char color);
void set_mode(scr_stat *scp);
void copy_font(int operation, int font_type, char* font_image);
+void load_palette(void);
#ifdef PC98
unsigned int at2pc98(unsigned int attr);
diff --git a/sys/pc98/pc98/wd.c b/sys/pc98/pc98/wd.c
index 192e5a4..970a544 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.7 1996/09/10 09:38:45 asami Exp $
+ * $Id: wd.c,v 1.8 1996/10/09 21:46:52 asami Exp $
*/
/* TODO:
@@ -88,6 +88,7 @@
#include <machine/md_var.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
+#include <pc98/pc98/epsonio.h>
#include <i386/isa/isa_device.h>
#include <pc98/pc98/wdreg.h>
#else
@@ -1048,8 +1049,7 @@ oops:
}
}
else {
- if( (du->dk_status & DKFL_MULTI)
- && (inb(du->dk_port) & WDERR_ABORT)) {
+ if( (du->dk_flags & DKFL_MULTI) && (inb(du->dk_port) & WDERR_ABORT)) {
wderror(bp, du,
"reverting to non-multi sector mode");
du->dk_multi = 1;
OpenPOWER on IntegriCloud