From 4f3d818c123f1c8723a308e1380e902a667c5ab5 Mon Sep 17 00:00:00 2001 From: Satoshi Asami Date: Wed, 23 Oct 1996 07:25:35 +0000 Subject: [PATCH] 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 --- sys/conf/Makefile.pc98 | 14 +- sys/conf/files.pc98 | 7 +- sys/conf/options.pc98 | 13 +- sys/pc98/boot/biosboot/Makefile | 34 +- sys/pc98/boot/biosboot/boot.c | 16 +- sys/pc98/boot/biosboot/boot.h | 3 +- sys/pc98/boot/biosboot/boot2.S | 1 + sys/pc98/boot/biosboot/disk.c | 14 +- sys/pc98/boot/biosboot/io.c | 7 +- sys/pc98/boot/rawboot/Makefile | 36 +- sys/pc98/cbus/cbus.h | 49 +- sys/pc98/cbus/clock.c | 56 +- sys/pc98/cbus/fdc.c | 3 +- sys/pc98/cbus/pcrtc.c | 56 +- sys/pc98/conf/GENERIC | 18 +- sys/pc98/conf/GENERIC98 | 18 +- sys/pc98/conf/Makefile.pc98 | 14 +- sys/pc98/conf/files.pc98 | 7 +- sys/pc98/conf/majors.pc98 | 5 +- sys/pc98/conf/options.pc98 | 13 +- sys/pc98/i386/locore.s | 3 +- sys/pc98/i386/machdep.c | 5 +- sys/pc98/i386/pmap.c | 2990 ------------------------------- sys/pc98/i386/trap.c | 25 +- sys/pc98/i386/userconfig.c | 175 +- sys/pc98/i386/vm_machdep.c | 6 +- sys/pc98/pc98/aic6360.c | 56 +- sys/pc98/pc98/aic_98.h | 93 + sys/pc98/pc98/clock.c | 56 +- sys/pc98/pc98/epsonio.h | 79 + sys/pc98/pc98/fd.c | 3 +- sys/pc98/pc98/if_ed.c | 193 +- sys/pc98/pc98/machdep.c | 5 +- sys/pc98/pc98/pc98.c | 13 +- sys/pc98/pc98/pc98.h | 49 +- sys/pc98/pc98/pc98_machdep.c | 31 +- sys/pc98/pc98/random_machdep.c | 4 +- sys/pc98/pc98/syscons.c | 65 +- sys/pc98/pc98/syscons.h | 6 +- sys/pc98/pc98/wd.c | 6 +- 40 files changed, 705 insertions(+), 3542 deletions(-) delete mode 100644 sys/pc98/i386/pmap.c create mode 100644 sys/pc98/pc98/aic_98.h create mode 100644 sys/pc98/pc98/epsonio.h diff --git a/sys/conf/Makefile.pc98 b/sys/conf/Makefile.pc98 index 03e5ac7a8d7..335b6540020 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 + %RULES # DO NOT DELETE THIS LINE -- make depend uses it diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 1d02c572541..fef4b976af7 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 9a589f3148e..4374f029d4e 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 dbc0a49be7e..61f5c043f5b 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 .include diff --git a/sys/pc98/boot/biosboot/boot.c b/sys/pc98/boot/biosboot/boot.c index f0253a966e8..70b4a3121b8 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 #include #include +#ifdef PROBE_KEYBOARD_LOCK +#include +#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 c9ab1b24e18..b17f1354328 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 @@ -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 48ca7226c1a..63f518148ee 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 ef6239fd444..2f415ca7be2 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 437bc3542d5..31609843ee4 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 4f12ed4e403..dbe0837c7ff 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 .include diff --git a/sys/pc98/cbus/cbus.h b/sys/pc98/cbus/cbus.h index 5d79e74726b..84c77b4efbd 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 - -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 d9b34d189dc..d96f6619035 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 e8ad1b22428..be8751cc2c4 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 #ifdef PC98 #include +#include #include #include #include diff --git a/sys/pc98/cbus/pcrtc.c b/sys/pc98/cbus/pcrtc.c index d9b34d189dc..d96f6619035 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 d33ece90552..5bd1821892c 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 d33ece90552..5bd1821892c 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 03e5ac7a8d7..335b6540020 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 + %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 1d02c572541..fef4b976af7 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 702c9ad8c7c..e13c5d7b25b 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 9a589f3148e..4374f029d4e 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 b39d0e981bc..725b4780861 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 01b3b48328f..73725c7f928 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 842004d33b6..00000000000 --- 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#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= 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 72f5badca07..de45a14d985 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 #include -#include "isa.h" - #ifdef POWERFAIL_NMI #include #include #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 @@ trap(frame) * 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 @@ trap_pfault(frame, usermode) #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 6bccd742356..9022390b673 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 #include -#include +#include #include #include @@ -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 3f5eb39de50..4e1581ce4d5 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 +#include #else #include #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 f4ec852e473..cbec0c0fbf7 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 +#include "aic.h" #include #include @@ -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 #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 00000000000..8a311011364 --- /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 d9b34d189dc..d96f6619035 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 00000000000..317b4b302c7 --- /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 +#include + +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 e8ad1b22428..be8751cc2c4 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 #ifdef PC98 #include +#include #include #include #include diff --git a/sys/pc98/pc98/if_ed.c b/sys/pc98/pc98/if_ed.c index ebb47491d6a..0b1b8801478 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 #include +#include #include #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 01b3b48328f..73725c7f928 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 fa07580c590..b9f900bcbd5 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 #ifdef PC98 #include +#include #else #include #endif @@ -75,10 +76,6 @@ #include #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 5d79e74726b..84c77b4efbd 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 - -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 ef476da2e6c..af9e7024dae 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 0c7f797f656..13ced6fab8b 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 #ifdef PC98 #include -#include #include #else #include -#include #include #endif diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c index 53b70edfed4..576ec7a2428 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)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 5504b48c41b..38e4fb9cf1c 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 192e5a46c46..970a5448370 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 #ifdef PC98 #include +#include #include #include #else @@ -1048,8 +1049,7 @@ wdintr(int unit) } } 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; -- 2.45.2