summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/boot/pc98/boot2/io.c2
-rw-r--r--sys/conf/files.pc9838
-rw-r--r--sys/dev/ct/ct_isa.c2
-rw-r--r--sys/dev/speaker/spkr.c2
-rw-r--r--sys/dev/syscons/syscons.h2
-rw-r--r--sys/i386/i386/nexus.c2
-rw-r--r--sys/i386/i386/vm_machdep.c2
-rw-r--r--sys/i386/isa/atpic.c2
-rw-r--r--sys/i386/isa/npx.c2
-rw-r--r--sys/i386/isa/prof_machdep.c2
-rw-r--r--sys/i386/isa/spkr.c2
-rw-r--r--sys/modules/fdc/Makefile4
-rw-r--r--sys/modules/pmc/Makefile2
-rw-r--r--sys/modules/sio/Makefile2
-rw-r--r--sys/pc98/cbus/cbus_dma.c2
-rw-r--r--sys/pc98/cbus/clock.c2
-rw-r--r--sys/pc98/cbus/fdc.c8
-rw-r--r--sys/pc98/cbus/fdc_cbus.c6
-rw-r--r--sys/pc98/cbus/gdc.c4
-rw-r--r--sys/pc98/cbus/pckbd.c3
-rw-r--r--sys/pc98/cbus/pcrtc.c2
-rw-r--r--sys/pc98/cbus/ppc.c4
-rw-r--r--sys/pc98/cbus/sio.c2
-rw-r--r--sys/pc98/cbus/syscons_cbus.c2
-rw-r--r--sys/pc98/i386/busio.s1774
-rw-r--r--sys/pc98/i386/busiosubr.c281
-rw-r--r--sys/pc98/i386/machdep.c2779
-rw-r--r--sys/pc98/pc98/30line.h130
-rw-r--r--sys/pc98/pc98/clock.c885
-rw-r--r--sys/pc98/pc98/fd.c2794
-rw-r--r--sys/pc98/pc98/fdc_cbus.c174
-rw-r--r--sys/pc98/pc98/fdcvar.h167
-rw-r--r--sys/pc98/pc98/fdreg.h88
-rw-r--r--sys/pc98/pc98/isa_dma.c497
-rw-r--r--sys/pc98/pc98/machdep.c2
-rw-r--r--sys/pc98/pc98/nmi.c74
-rw-r--r--sys/pc98/pc98/olpt.c653
-rw-r--r--sys/pc98/pc98/pc98.h128
-rw-r--r--sys/pc98/pc98/pc98_machdep.c2
-rw-r--r--sys/pc98/pc98/pc98gdc.c1500
-rw-r--r--sys/pc98/pc98/pc98kbd.c964
-rw-r--r--sys/pc98/pc98/pmc.c245
-rw-r--r--sys/pc98/pc98/ppc.c2212
-rw-r--r--sys/pc98/pc98/ppcreg.h280
-rw-r--r--sys/pc98/pc98/sc_machdep.h56
-rw-r--r--sys/pc98/pc98/scgdcrndr.c208
-rw-r--r--sys/pc98/pc98/scterm-sck.c1216
-rw-r--r--sys/pc98/pc98/scvtbpc98.c399
-rw-r--r--sys/pc98/pc98/sio.c4413
-rw-r--r--sys/pc98/pc98/sio_cbus.c118
-rw-r--r--sys/pc98/pc98/syscons_pc98.c265
-rw-r--r--sys/pccard/pccard_nbk.c2
52 files changed, 53 insertions, 22354 deletions
diff --git a/sys/boot/pc98/boot2/io.c b/sys/boot/pc98/boot2/io.c
index d4657a2..4d03246 100644
--- a/sys/boot/pc98/boot2/io.c
+++ b/sys/boot/pc98/boot2/io.c
@@ -32,7 +32,7 @@ __FBSDID("$FreeBSD$");
#include "boot.h"
#include <machine/cpufunc.h>
#include <sys/reboot.h>
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
static int getchar(int in_buf);
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index fc4de01..5435444 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -347,29 +347,29 @@ libkern/ucmpdi2.c standard
libkern/udivdi3.c standard
libkern/umoddi3.c standard
pc98/apm/apm_bioscall.S optional apm
-pc98/i386/busio.s standard
-pc98/i386/busiosubr.c standard
-pc98/i386/machdep.c standard
+pc98/cbus/cbus_dma.c optional isa
+pc98/cbus/clock.c standard
+pc98/cbus/fdc.c optional fdc
+pc98/cbus/fdc_cbus.c optional fdc isa
+pc98/cbus/gdc.c optional gdc
+pc98/cbus/nmi.c standard
+pc98/cbus/olpt.c optional olpt
+pc98/cbus/pckbd.c optional pckbd
+pc98/cbus/pmc.c optional pmc
+pc98/cbus/ppc.c optional ppc
+pc98/cbus/scgdcrndr.c optional sc gdc
+pc98/cbus/scterm-sck.c optional sc
+pc98/cbus/scvtb.c optional sc
+pc98/cbus/sio.c optional sio
+pc98/cbus/sio_cbus.c optional sio isa
+pc98/cbus/syscons_cbus.c optional sc
+pc98/pc98/busio.s standard
+pc98/pc98/busiosubr.c standard
pc98/pc98/canbepm.c optional canbepm
pc98/pc98/canbus.c optional canbus
pc98/pc98/canbus_if.m optional canbus
-pc98/pc98/clock.c standard
-pc98/pc98/fd.c optional fdc
-pc98/pc98/fdc_cbus.c optional fdc isa
-pc98/pc98/isa_dma.c optional isa
-pc98/pc98/nmi.c standard
-pc98/pc98/olpt.c optional olpt
+pc98/pc98/machdep.c standard
pc98/pc98/pc98_machdep.c standard
-pc98/pc98/pc98gdc.c optional gdc
-pc98/pc98/pc98kbd.c optional pckbd
-pc98/pc98/pmc.c optional pmc
-pc98/pc98/ppc.c optional ppc
-pc98/pc98/scgdcrndr.c optional sc gdc
-pc98/pc98/scterm-sck.c optional sc
-pc98/pc98/scvtbpc98.c optional sc
-pc98/pc98/sio.c optional sio
-pc98/pc98/sio_cbus.c optional sio isa
-pc98/pc98/syscons_pc98.c optional sc
pccard/pccard.c optional card
pccard/pccard_beep.c optional card
pccard/pccard_nbk.c optional card
diff --git a/sys/dev/ct/ct_isa.c b/sys/dev/ct/ct_isa.c
index b16b1d8..7d6dad6 100644
--- a/sys/dev/ct/ct_isa.c
+++ b/sys/dev/ct/ct_isa.c
@@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/md_var.h>
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#include <isa/isavar.h>
#include <compat/netbsd/dvcfg.h>
diff --git a/sys/dev/speaker/spkr.c b/sys/dev/speaker/spkr.c
index 7b41f25..321b2cb 100644
--- a/sys/dev/speaker/spkr.c
+++ b/sys/dev/speaker/spkr.c
@@ -20,7 +20,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <isa/isavar.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index 99bf8a4..b5fb872 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -34,7 +34,7 @@
/* machine-dependent part of the header */
#ifdef PC98
-#include <pc98/pc98/sc_machdep.h>
+#include <pc98/cbus/sc_machdep.h>
#elif defined(__i386__)
/* nothing for the moment */
#elif defined(__alpha__)
diff --git a/sys/i386/i386/nexus.c b/sys/i386/i386/nexus.c
index e8d1406..15751bd 100644
--- a/sys/i386/i386/nexus.c
+++ b/sys/i386/i386/nexus.c
@@ -64,7 +64,7 @@ __FBSDID("$FreeBSD$");
#ifdef DEV_ISA
#include <isa/isavar.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index ab9eb81..df01592 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -91,7 +91,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
diff --git a/sys/i386/isa/atpic.c b/sys/i386/isa/atpic.c
index d326c68..8d17ec1 100644
--- a/sys/i386/isa/atpic.c
+++ b/sys/i386/isa/atpic.c
@@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ic/i8259.h>
#include <i386/isa/icu.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index 9e65106..9a7ba17 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$");
#include <machine/ucontext.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
diff --git a/sys/i386/isa/prof_machdep.c b/sys/i386/isa/prof_machdep.c
index 616be3e..981727c 100644
--- a/sys/i386/isa/prof_machdep.c
+++ b/sys/i386/isa/prof_machdep.c
@@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
#include <machine/asmacros.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
diff --git a/sys/i386/isa/spkr.c b/sys/i386/isa/spkr.c
index 7b41f25..321b2cb 100644
--- a/sys/i386/isa/spkr.c
+++ b/sys/i386/isa/spkr.c
@@ -20,7 +20,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <isa/isavar.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
diff --git a/sys/modules/fdc/Makefile b/sys/modules/fdc/Makefile
index de92183..b632dcd 100644
--- a/sys/modules/fdc/Makefile
+++ b/sys/modules/fdc/Makefile
@@ -4,8 +4,8 @@ KMOD= fdc
WARNS?= 2
.if ${MACHINE} == "pc98"
-.PATH: ${.CURDIR}/../../pc98/pc98
-SRCS= fd.c fdc_cbus.c
+.PATH: ${.CURDIR}/../../pc98/cbus
+SRCS= fdc.c fdc_cbus.c
.else
.PATH: ${.CURDIR}/../../dev/fdc
SRCS= fdc.c fdc_isa.c fdc_pccard.c
diff --git a/sys/modules/pmc/Makefile b/sys/modules/pmc/Makefile
index 30c1581..60dd350 100644
--- a/sys/modules/pmc/Makefile
+++ b/sys/modules/pmc/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/../../pc98/pc98
+.PATH: ${.CURDIR}/../../pc98/cbus
KMOD= pmc
SRCS= pmc.c
diff --git a/sys/modules/sio/Makefile b/sys/modules/sio/Makefile
index a0c02bb..8ec6b4e 100644
--- a/sys/modules/sio/Makefile
+++ b/sys/modules/sio/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
.if ${MACHINE} == "pc98"
-.PATH: ${.CURDIR}/../../pc98/pc98
+.PATH: ${.CURDIR}/../../pc98/cbus
.endif
.PATH: ${.CURDIR}/../../dev/sio
diff --git a/sys/pc98/cbus/cbus_dma.c b/sys/pc98/cbus/cbus_dma.c
index 5bf2c88..f85e3c7 100644
--- a/sys/pc98/cbus/cbus_dma.c
+++ b/sys/pc98/cbus/cbus_dma.c
@@ -60,9 +60,9 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
-#include <pc98/pc98/pc98.h>
#include <dev/ic/i8237.h>
#include <isa/isavar.h>
+#include <pc98/cbus/cbus.h>
/*
** Register definitions for DMA controller 1 (channels 0..3):
diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c
index 484e8df..f3d956b 100644
--- a/sys/pc98/cbus/clock.c
+++ b/sys/pc98/cbus/clock.c
@@ -81,7 +81,7 @@
#include <machine/specialreg.h>
#include <i386/isa/icu.h>
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#include <pc98/pc98/pc98_machdep.h>
#ifdef DEV_ISA
#include <isa/isavar.h>
diff --git a/sys/pc98/cbus/fdc.c b/sys/pc98/cbus/fdc.c
index d2ead23..3b366a1 100644
--- a/sys/pc98/cbus/fdc.c
+++ b/sys/pc98/cbus/fdc.c
@@ -78,11 +78,11 @@
#ifdef PC98
#include <isa/isavar.h>
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/pc98_machdep.h>
+#include <pc98/cbus/cbus.h>
+#include <pc98/cbus/fdcreg.h>
+#include <pc98/cbus/fdcvar.h>
#include <pc98/pc98/epsonio.h>
-#include <pc98/pc98/fdreg.h>
-#include <pc98/pc98/fdcvar.h>
+#include <pc98/pc98/pc98_machdep.h>
#else
#include <isa/isavar.h>
#include <isa/isareg.h>
diff --git a/sys/pc98/cbus/fdc_cbus.c b/sys/pc98/cbus/fdc_cbus.c
index 0980e00..de60a43 100644
--- a/sys/pc98/cbus/fdc_cbus.c
+++ b/sys/pc98/cbus/fdc_cbus.c
@@ -39,11 +39,11 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
-#include <pc98/pc98/fdcvar.h>
-#include <pc98/pc98/fdreg.h>
+#include <pc98/cbus/cbus.h>
+#include <pc98/cbus/fdcreg.h>
+#include <pc98/cbus/fdcvar.h>
#include <isa/isavar.h>
-#include <pc98/pc98/pc98.h>
static bus_addr_t fdc_iat[] = {0, 2, 4};
diff --git a/sys/pc98/cbus/gdc.c b/sys/pc98/cbus/gdc.c
index 9df28d5..f9c2f58 100644
--- a/sys/pc98/cbus/gdc.c
+++ b/sys/pc98/cbus/gdc.c
@@ -55,7 +55,7 @@
#include <dev/fb/fbreg.h>
#ifdef LINE30
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#endif
#include <pc98/pc98/pc98_machdep.h>
#include <isa/isavar.h>
@@ -423,7 +423,7 @@ DRIVER_MODULE(gdc, isa, gdcdriver, gdc_devclass, 0, 0);
/* LOW-LEVEL */
-#include <pc98/pc98/30line.h>
+#include <pc98/cbus/30line.h>
#define TEXT_BUF_BASE 0x000a0000
#define TEXT_BUF_SIZE 0x00008000
diff --git a/sys/pc98/cbus/pckbd.c b/sys/pc98/cbus/pckbd.c
index f33b8c2..3d3587f 100644
--- a/sys/pc98/cbus/pckbd.c
+++ b/sys/pc98/cbus/pckbd.c
@@ -43,8 +43,7 @@
#include <dev/kbd/kbdreg.h>
-#include <pc98/pc98/pc98.h>
-
+#include <pc98/cbus/cbus.h>
#include <isa/isavar.h>
#define DRIVER_NAME "pckbd"
diff --git a/sys/pc98/cbus/pcrtc.c b/sys/pc98/cbus/pcrtc.c
index 484e8df..f3d956b 100644
--- a/sys/pc98/cbus/pcrtc.c
+++ b/sys/pc98/cbus/pcrtc.c
@@ -81,7 +81,7 @@
#include <machine/specialreg.h>
#include <i386/isa/icu.h>
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#include <pc98/pc98/pc98_machdep.h>
#ifdef DEV_ISA
#include <isa/isavar.h>
diff --git a/sys/pc98/cbus/ppc.c b/sys/pc98/cbus/ppc.c
index 67adef3..e04e3fb 100644
--- a/sys/pc98/cbus/ppc.c
+++ b/sys/pc98/cbus/ppc.c
@@ -44,7 +44,7 @@
#include <sys/rman.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#else
#include <isa/isareg.h>
#endif
@@ -55,7 +55,7 @@
#include <dev/ppc/ppcvar.h>
#ifdef PC98
-#include <pc98/pc98/ppcreg.h>
+#include <pc98/cbus/ppcreg.h>
#else
#include <dev/ppc/ppcreg.h>
#endif
diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c
index 297f61d..007e1b2 100644
--- a/sys/pc98/cbus/sio.c
+++ b/sys/pc98/cbus/sio.c
@@ -111,7 +111,7 @@
#include <dev/sio/siovar.h>
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#include <pc98/pc98/pc98_machdep.h>
#endif
diff --git a/sys/pc98/cbus/syscons_cbus.c b/sys/pc98/cbus/syscons_cbus.c
index df8934e..fc430e9 100644
--- a/sys/pc98/cbus/syscons_cbus.c
+++ b/sys/pc98/cbus/syscons_cbus.c
@@ -39,7 +39,7 @@
#include <machine/clock.h>
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#include <pc98/pc98/pc98_machdep.h>
#include <dev/syscons/syscons.h>
diff --git a/sys/pc98/i386/busio.s b/sys/pc98/i386/busio.s
deleted file mode 100644
index 915dcae..0000000
--- a/sys/pc98/i386/busio.s
+++ /dev/null
@@ -1,1774 +0,0 @@
-/* $FreeBSD$ */
-/* $NecBSD: busio.s,v 1.16.4.1 1999/08/16 09:06:08 kmatsuda Exp $ */
-/* $NetBSD$ */
-
-/*-
- * [NetBSD for NEC PC-98 series]
- * Copyright (c) 1996, 1997, 1998
- * NetBSD/pc98 porting staff. All rights reserved.
- *
- * [Ported for FreeBSD]
- * Copyright (c) 2001
- * TAKAHASHI Yoshihiro. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software 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.
- */
-
-/*
- * Copyright (c) 1997, 1998
- * Naofumi HONDA. All rights reserved.
- */
-
-#include <machine/asmacros.h>
-
-#include "assym.s"
-
-/***********************************************************
- * Bus IO access methods (Direct Access)
- ***********************************************************/
-#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \
- addl BUS_SPACE_HANDLE_BASE/**/(%/**/BSHREG/**/),%/**/ADDRREG
-
-/*
- * read_N
- * IN: edx port
- * OUT: eax data
- */
-ENTRY(SBUS_DA_io_space_read_1)
- BUS_ACCESS_ADDR(ebx,edx)
- inb %dx,%al
- ret
-
-ENTRY(SBUS_DA_io_space_read_2)
- BUS_ACCESS_ADDR(ebx,edx)
- inw %dx,%ax
- ret
-
-ENTRY(SBUS_DA_io_space_read_4)
- BUS_ACCESS_ADDR(ebx,edx)
- inl %dx,%eax
- ret
-
-/*
- * write_N
- * IN:eax DATA
- * edx PORT
- */
-ENTRY(SBUS_DA_io_space_write_1)
- BUS_ACCESS_ADDR(ebx,edx)
- outb %al,%dx
- ret
-
-ENTRY(SBUS_DA_io_space_write_2)
- BUS_ACCESS_ADDR(ebx,edx)
- outw %ax,%dx
- ret
-
-ENTRY(SBUS_DA_io_space_write_4)
- BUS_ACCESS_ADDR(ebx,edx)
- outl %eax,%dx
- ret
-
-/*
- * read_multi_N
- * IN: ecx COUNT
- * edx PORT
- * edi BUFP
- */
-ENTRY(SBUS_DA_io_space_read_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- insb
- ret
-
-ENTRY(SBUS_DA_io_space_read_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- insw
- ret
-
-ENTRY(SBUS_DA_io_space_read_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- insl
- ret
-
-/*
- * write_multi_N
- * IN: ecx COUNT
- * edx PORT
- * esi BUFP
- */
-ENTRY(SBUS_DA_io_space_write_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- outsb
- ret
-
-ENTRY(SBUS_DA_io_space_write_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- outsw
- ret
-
-ENTRY(SBUS_DA_io_space_write_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- outsl
- ret
-
-/*
- * read_region_N
- * IN: ecx COUNT
- * edx PORT
- * edi BUFP
- */
-ENTRY(SBUS_DA_io_space_read_region_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- inb %dx,%al
- stosb
- incl %edx
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_DA_io_space_read_region_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- inw %dx,%ax
- stosw
- addl $2,%edx
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_DA_io_space_read_region_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- inl %dx,%eax
- stosl
- addl $4,%edx
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-/*
- * write_region_N
- * IN: ecx COUNT
- * edx PORT
- * esi BUFP
- */
-ENTRY(SBUS_DA_io_space_write_region_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- lodsb
- outb %al,%dx
- incl %edx
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_DA_io_space_write_region_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- lodsw
- outw %ax,%dx
- addl $2,%edx
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_DA_io_space_write_region_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- lodsl
- outl %eax,%dx
- addl $4,%edx
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-/*
- * set_multi_N
- * IN: eax DATA
- * ecx COUNT
- * edx PORT
- */
-ENTRY(SBUS_DA_io_space_set_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- outb %al,%dx
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_DA_io_space_set_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- outw %ax,%dx
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_DA_io_space_set_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- outl %eax,%dx
- decl %ecx
- jnz 1b
-2:
- ret
-
-/*
- * set_region_N
- * IN: eax DATA
- * ecx COUNT
- * edx PORT
- */
-ENTRY(SBUS_DA_io_space_set_region_1)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- outb %al,%dx
- incl %edx
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_DA_io_space_set_region_2)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- outw %ax,%dx
- addl $2,%edx
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_DA_io_space_set_region_4)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- outl %eax,%dx
- addl $4,%edx
- decl %ecx
- jnz 1b
-2:
- ret
-
-/*
- * copy_region_N
- * IN: ecx COUNT
- * esi SPORT
- * edi DPORT
- */
-ENTRY(SBUS_DA_io_space_copy_region_1)
- BUS_ACCESS_ADDR(eax,esi)
- BUS_ACCESS_ADDR(ebx,edi)
- pushl %eax
- pushl %edx
- orl %ecx,%ecx
- jz 2f
-1:
- movl %esi,%edx
- inb %dx,%al
- incl %esi
-
- movl %edi,%edx
- outb %al,%dx
- incl %edi
-
- decl %ecx
- jnz 1b
-2:
- popl %edx
- popl %eax
- ret
-
-ENTRY(SBUS_DA_io_space_copy_region_2)
- BUS_ACCESS_ADDR(eax,esi)
- BUS_ACCESS_ADDR(ebx,edi)
- pushl %eax
- pushl %edx
- orl %ecx,%ecx
- jz 2f
-1:
- movl %esi,%edx
- inw %dx,%ax
- addl $2,%esi
-
- movl %edi,%edx
- outw %ax,%dx
- addl $2,%edi
-
- decl %ecx
- jnz 1b
-2:
- popl %edx
- popl %eax
- ret
-
-ENTRY(SBUS_DA_io_space_copy_region_4)
- BUS_ACCESS_ADDR(eax,esi)
- BUS_ACCESS_ADDR(ebx,edi)
- pushl %eax
- pushl %edx
- orl %ecx,%ecx
- jz 2f
-1:
- movl %esi,%edx
- inl %dx,%eax
- addl $4,%esi
-
- movl %edi,%edx
- outl %eax,%dx
- addl $4,%edi
-
- decl %ecx
- jnz 1b
-2:
- popl %edx
- popl %eax
- ret
-
-/***********************************************************
- * Bus Memory access methods (Direct Access)
- ***********************************************************/
-/*
- * read_N
- */
-ENTRY(SBUS_DA_mem_space_read_1)
- BUS_ACCESS_ADDR(ebx,edx)
- movb (%edx),%al
- ret
-
-ENTRY(SBUS_DA_mem_space_read_2)
- BUS_ACCESS_ADDR(ebx,edx)
- movw (%edx),%ax
- ret
-
-ENTRY(SBUS_DA_mem_space_read_4)
- BUS_ACCESS_ADDR(ebx,edx)
- movl (%edx),%eax
- ret
-
-/*
- * write_N
- */
-ENTRY(SBUS_DA_mem_space_write_1)
- BUS_ACCESS_ADDR(ebx,edx)
- movb %al,(%edx)
- ret
-
-ENTRY(SBUS_DA_mem_space_write_2)
- BUS_ACCESS_ADDR(ebx,edx)
- movw %ax,(%edx)
- ret
-
-ENTRY(SBUS_DA_mem_space_write_4)
- BUS_ACCESS_ADDR(ebx,edx)
- movl %eax,(%edx)
- ret
-
-/*
- * read_multi_N
- */
-ENTRY(SBUS_DA_mem_space_read_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- movb (%edx),%al
- stosb
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_DA_mem_space_read_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- movw (%edx),%ax
- stosw
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_DA_mem_space_read_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- movl (%edx),%eax
- stosl
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-/*
- * write_multi_N
- */
-ENTRY(SBUS_DA_mem_space_write_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- lodsb
- movb %al,(%edx)
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_DA_mem_space_write_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- lodsw
- movw %ax,(%edx)
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_DA_mem_space_write_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- lodsl
- movl %eax,(%edx)
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-/*
- * read_region_N
- */
-ENTRY(SBUS_DA_mem_space_read_region_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %esi
- movl %edx,%esi
- rep
- movsb
- popl %esi
- ret
-
-ENTRY(SBUS_DA_mem_space_read_region_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %esi
- movl %edx,%esi
- rep
- movsw
- popl %esi
- ret
-
-ENTRY(SBUS_DA_mem_space_read_region_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %esi
- movl %edx,%esi
- rep
- movsl
- popl %esi
- ret
-
-/*
- * write_region_N
- */
-ENTRY(SBUS_DA_mem_space_write_region_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %edi
- movl %edx,%edi
- rep
- movsb
- popl %edi
- ret
-
-ENTRY(SBUS_DA_mem_space_write_region_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %edi
- movl %edx,%edi
- rep
- movsw
- popl %edi
- ret
-
-ENTRY(SBUS_DA_mem_space_write_region_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %edi
- movl %edx,%edi
- rep
- movsl
- popl %edi
- ret
-
-/*
- * set_multi_N
- */
-ENTRY(SBUS_DA_mem_space_set_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- movb %al,(%edx)
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_DA_mem_space_set_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- movw %ax,(%edx)
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_DA_mem_space_set_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- movl %eax,(%edx)
- decl %ecx
- jnz 1b
-2:
- ret
-
-/*
- * set_region_N
- */
-ENTRY(SBUS_DA_mem_space_set_region_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %edi
- movl %edx,%edi
- rep
- stosb
- popl %edi
- ret
-
-ENTRY(SBUS_DA_mem_space_set_region_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %edi
- movl %edx,%edi
- rep
- stosw
- popl %edi
- ret
-
-ENTRY(SBUS_DA_mem_space_set_region_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %edi
- movl %edx,%edi
- rep
- stosl
- popl %edi
- ret
-
-/*
- * copy_region_N
- */
-ENTRY(SBUS_DA_mem_space_copy_region_1)
- BUS_ACCESS_ADDR(eax,esi)
- BUS_ACCESS_ADDR(ebx,edi)
- cld
- rep
- movsb
- ret
-
-ENTRY(SBUS_DA_mem_space_copy_region_2)
- BUS_ACCESS_ADDR(eax,esi)
- BUS_ACCESS_ADDR(ebx,edi)
- cld
- rep
- movsw
- ret
-
-ENTRY(SBUS_DA_mem_space_copy_region_4)
- BUS_ACCESS_ADDR(eax,esi)
- BUS_ACCESS_ADDR(ebx,edi)
- cld
- rep
- movsl
- ret
-
-#undef BUS_ACCESS_ADDR
-
-/***********************************************************
- * Bus IO access methods (Relocate Access)
- ***********************************************************/
-#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \
- movl BUS_SPACE_HANDLE_IAT/**/(%/**/BSHREG/**/, %/**/ADDRREG/**/, 4), \
- %/**/ADDRREG
-#define BUS_ACCESS_ADDR2(BSHREG,ADDRREG,DSTREG) \
- movl BUS_SPACE_HANDLE_IAT/**/(%/**/BSHREG/**/, %/**/ADDRREG/**/, 4), \
- %/**/DSTREG
-/*
- * read_N
- * IN: edx port
- * OUT: eax data
- */
-ENTRY(SBUS_RA_io_space_read_1)
- BUS_ACCESS_ADDR(ebx,edx)
- inb %dx,%al
- ret
-
-ENTRY(SBUS_RA_io_space_read_2)
- BUS_ACCESS_ADDR(ebx,edx)
- inw %dx,%ax
- ret
-
-ENTRY(SBUS_RA_io_space_read_4)
- BUS_ACCESS_ADDR(ebx,edx)
- inl %dx,%eax
- ret
-
-/*
- * write_N
- * IN:eax DATA
- * edx PORT
- */
-ENTRY(SBUS_RA_io_space_write_1)
- BUS_ACCESS_ADDR(ebx,edx)
- outb %al,%dx
- ret
-
-ENTRY(SBUS_RA_io_space_write_2)
- BUS_ACCESS_ADDR(ebx,edx)
- outw %ax,%dx
- ret
-
-ENTRY(SBUS_RA_io_space_write_4)
- BUS_ACCESS_ADDR(ebx,edx)
- outl %eax,%dx
- ret
-
-/*
- * read_multi_N
- * IN: ecx COUNT
- * edx PORT
- * edi BUFP
- */
-ENTRY(SBUS_RA_io_space_read_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- insb
- ret
-
-ENTRY(SBUS_RA_io_space_read_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- insw
- ret
-
-ENTRY(SBUS_RA_io_space_read_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- insl
- ret
-
-/*
- * write_multi_N
- * IN: ecx COUNT
- * edx PORT
- * esi BUFP
- */
-ENTRY(SBUS_RA_io_space_write_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- outsb
- ret
-
-ENTRY(SBUS_RA_io_space_write_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- outsw
- ret
-
-ENTRY(SBUS_RA_io_space_write_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- rep
- outsl
- ret
-
-/*
- * read_region_N
- * IN: ecx COUNT
- * edx PORT
- * edi BUFP
- */
-ENTRY(SBUS_RA_io_space_read_region_1)
- cld
- pushl %eax
- pushl %esi
- orl %ecx,%ecx
- jz 2f
- movl %edx,%esi
-1:
- BUS_ACCESS_ADDR2(ebx,esi,edx)
- inb %dx,%al
- stosb
- incl %esi
- decl %ecx
- jnz 1b
-2:
- popl %esi
- popl %eax
- ret
-
-ENTRY(SBUS_RA_io_space_read_region_2)
- cld
- pushl %eax
- pushl %esi
- orl %ecx,%ecx
- jz 2f
- movl %edx,%esi
-1:
- BUS_ACCESS_ADDR2(ebx,esi,edx)
- inw %dx,%ax
- stosw
- addl $2,%esi
- decl %ecx
- jnz 1b
-2:
- popl %esi
- popl %eax
- ret
-
-ENTRY(SBUS_RA_io_space_read_region_4)
- cld
- pushl %eax
- pushl %esi
- orl %ecx,%ecx
- jz 2f
- movl %edx,%esi
-1:
- BUS_ACCESS_ADDR2(ebx,esi,edx)
- inl %dx,%eax
- stosl
- addl $4,%esi
- decl %ecx
- jnz 1b
-2:
- popl %esi
- popl %eax
- ret
-
-/*
- * write_region_N
- * IN: ecx COUNT
- * edx PORT
- * esi BUFP
- */
-ENTRY(SBUS_RA_io_space_write_region_1)
- cld
- pushl %eax
- pushl %edi
- orl %ecx,%ecx
- jz 2f
- movl %edx,%edi
-1:
- BUS_ACCESS_ADDR2(ebx,edi,edx)
- lodsb
- outb %al,%dx
- incl %edi
- decl %ecx
- jnz 1b
-2:
- popl %edi
- popl %eax
- ret
-
-ENTRY(SBUS_RA_io_space_write_region_2)
- cld
- pushl %eax
- pushl %edi
- orl %ecx,%ecx
- jz 2f
- movl %edx,%edi
-1:
- BUS_ACCESS_ADDR2(ebx,edi,edx)
- lodsw
- outw %ax,%dx
- addl $2,%edi
- decl %ecx
- jnz 1b
-2:
- popl %edi
- popl %eax
- ret
-
-ENTRY(SBUS_RA_io_space_write_region_4)
- cld
- pushl %eax
- pushl %edi
- orl %ecx,%ecx
- jz 2f
- movl %edx,%edi
-1:
- BUS_ACCESS_ADDR2(ebx,edi,edx)
- lodsl
- outl %eax,%dx
- addl $4,%edi
- decl %ecx
- jnz 1b
-2:
- popl %edi
- popl %eax
- ret
-
-/*
- * set_multi_N
- * IN: eax DATA
- * ecx COUNT
- * edx PORT
- */
-ENTRY(SBUS_RA_io_space_set_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- outb %al,%dx
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_RA_io_space_set_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- outw %ax,%dx
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_RA_io_space_set_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- outl %eax,%dx
- decl %ecx
- jnz 1b
-2:
- ret
-
-/*
- * set_region_N
- * IN: eax DATA
- * ecx COUNT
- * edx PORT
- */
-ENTRY(SBUS_RA_io_space_set_region_1)
- pushl %edi
- orl %ecx,%ecx
- jz 2f
- movl %edx,%edi
-1:
- BUS_ACCESS_ADDR2(ebx,edi,edx)
- outb %al,%dx
- incl %edi
- decl %ecx
- jnz 1b
-2:
- popl %edi
- ret
-
-ENTRY(SBUS_RA_io_space_set_region_2)
- pushl %edi
- orl %ecx,%ecx
- jz 2f
- movl %edx,%edi
-1:
- BUS_ACCESS_ADDR2(ebx,edi,edx)
- outw %ax,%dx
- addl $2,%edi
- decl %ecx
- jnz 1b
-2:
- popl %edi
- ret
-
-ENTRY(SBUS_RA_io_space_set_region_4)
- pushl %edi
- orl %ecx,%ecx
- jz 2f
- movl %edx,%edi
-1:
- BUS_ACCESS_ADDR2(ebx,edi,edx)
- outl %eax,%dx
- addl $4,%edi
- decl %ecx
- jnz 1b
-2:
- popl %edi
- ret
-
-/*
- * copy_region_N
- * IN: ecx COUNT
- * esi SPORT
- * edi DPORT
- */
-ENTRY(SBUS_RA_io_space_copy_region_1)
- pushl %eax
- pushl %edx
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,esi,edx)
- inb %dx,%al
- incl %esi
-
- BUS_ACCESS_ADDR2(ebx,edi,edx)
- outb %al,%dx
- incl %edi
-
- decl %ecx
- jnz 1b
-2:
- popl %edx
- popl %eax
- ret
-
-ENTRY(SBUS_RA_io_space_copy_region_2)
- pushl %eax
- pushl %edx
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,esi,edx)
- inw %dx,%ax
- addl $2,%esi
-
- BUS_ACCESS_ADDR2(ebx,edi,edx)
- outw %ax,%dx
- addl $2,%edi
-
- decl %ecx
- jnz 1b
-2:
- popl %edx
- popl %eax
- ret
-
-ENTRY(SBUS_RA_io_space_copy_region_4)
- pushl %eax
- pushl %edx
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,esi,edx)
- inl %dx,%eax
- addl $4,%esi
-
- BUS_ACCESS_ADDR2(ebx,edi,edx)
- outl %eax,%dx
- addl $4,%edi
-
- decl %ecx
- jnz 1b
-2:
- popl %edx
- popl %eax
- ret
-
-/***********************************************************
- * Bus Memory access methods
- ***********************************************************/
-/*
- * read_N
- */
-ENTRY(SBUS_RA_mem_space_read_1)
- BUS_ACCESS_ADDR(ebx,edx)
- movb (%edx),%al
- ret
-
-ENTRY(SBUS_RA_mem_space_read_2)
- BUS_ACCESS_ADDR(ebx,edx)
- movw (%edx),%ax
- ret
-
-ENTRY(SBUS_RA_mem_space_read_4)
- BUS_ACCESS_ADDR(ebx,edx)
- movl (%edx),%eax
- ret
-
-/*
- * write_N
- */
-ENTRY(SBUS_RA_mem_space_write_1)
- BUS_ACCESS_ADDR(ebx,edx)
- movb %al,(%edx)
- ret
-
-ENTRY(SBUS_RA_mem_space_write_2)
- BUS_ACCESS_ADDR(ebx,edx)
- movw %ax,(%edx)
- ret
-
-ENTRY(SBUS_RA_mem_space_write_4)
- BUS_ACCESS_ADDR(ebx,edx)
- movl %eax,(%edx)
- ret
-
-/*
- * read_multi_N
- */
-ENTRY(SBUS_RA_mem_space_read_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- movb (%edx),%al
- stosb
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_RA_mem_space_read_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- movw (%edx),%ax
- stosw
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_RA_mem_space_read_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- movl (%edx),%eax
- stosl
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-/*
- * write_multi_N
- */
-ENTRY(SBUS_RA_mem_space_write_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- lodsb
- movb %al,(%edx)
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_RA_mem_space_write_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- lodsw
- movw %ax,(%edx)
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-ENTRY(SBUS_RA_mem_space_write_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- cld
- pushl %eax
- orl %ecx,%ecx
- jz 2f
-1:
- lodsl
- movl %eax,(%edx)
- decl %ecx
- jnz 1b
-2:
- popl %eax
- ret
-
-/*
- * read_region_N
- */
-ENTRY(SBUS_RA_mem_space_read_region_1)
- cld
- pushl %esi
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,edx,esi)
- movsb
- incl %edx
- decl %ecx
- jnz 1b
-2:
- popl %esi
- ret
-
-ENTRY(SBUS_RA_mem_space_read_region_2)
- cld
- pushl %esi
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,edx,esi)
- movsw
- addl $2,%edx
- decl %ecx
- jnz 1b
-2:
- popl %esi
- ret
-
-ENTRY(SBUS_RA_mem_space_read_region_4)
- cld
- pushl %esi
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,edx,esi)
- movsl
- addl $4,%edx
- decl %ecx
- jnz 1b
-2:
- popl %esi
- ret
-
-/*
- * write_region_N
- */
-ENTRY(SBUS_RA_mem_space_write_region_1)
- cld
- pushl %edi
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,edx,edi)
- movsb
- incl %edx
- decl %ecx
- jnz 1b
-2:
- popl %edi
- ret
-
-ENTRY(SBUS_RA_mem_space_write_region_2)
- cld
- pushl %edi
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,edx,edi)
- movsw
- addl $2,%edx
- decl %ecx
- jnz 1b
-2:
- popl %edi
- ret
-
-ENTRY(SBUS_RA_mem_space_write_region_4)
- cld
- pushl %edi
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,edx,edi)
- movsl
- addl $4,%edx
- decl %ecx
- jnz 1b
-2:
- popl %edi
- ret
-
-/*
- * set_multi_N
- */
-ENTRY(SBUS_RA_mem_space_set_multi_1)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- movb %al,(%edx)
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_RA_mem_space_set_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- movw %ax,(%edx)
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_RA_mem_space_set_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- orl %ecx,%ecx
- jz 2f
-1:
- movl %eax,(%edx)
- decl %ecx
- jnz 1b
-2:
- ret
-
-/*
- * set_region_N
- */
-ENTRY(SBUS_RA_mem_space_set_region_1)
- cld
- pushl %edi
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,edx,edi)
- stosb
- incl %edx
- decl %ecx
- jnz 1b
-2:
- popl %edi
- ret
-
-ENTRY(SBUS_RA_mem_space_set_region_2)
- cld
- pushl %edi
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,edx,edi)
- stosw
- addl $2,%edx
- decl %ecx
- jnz 1b
-2:
- popl %edi
- ret
-
-ENTRY(SBUS_RA_mem_space_set_region_4)
- cld
- pushl %edi
- orl %ecx,%ecx
- jz 2f
-1:
- BUS_ACCESS_ADDR2(ebx,edx,edi)
- stosl
- addl $4,%edx
- decl %ecx
- jnz 1b
-2:
- popl %edi
- ret
-
-/*
- * copy_region_N
- */
-ENTRY(SBUS_RA_mem_space_copy_region_1)
- cld
- orl %ecx,%ecx
- jz 2f
-1:
- pushl %esi
- pushl %edi
- BUS_ACCESS_ADDR(eax,esi)
- BUS_ACCESS_ADDR(ebx,edi)
- movsb
- popl %edi
- popl %esi
- incl %esi
- incl %edi
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_RA_mem_space_copy_region_2)
- cld
- orl %ecx,%ecx
- jz 2f
-1:
- pushl %esi
- pushl %edi
- BUS_ACCESS_ADDR(eax,esi)
- BUS_ACCESS_ADDR(ebx,edi)
- movsw
- popl %edi
- popl %esi
- addl $2,%esi
- addl $2,%edi
- decl %ecx
- jnz 1b
-2:
- ret
-
-ENTRY(SBUS_RA_mem_space_copy_region_4)
- cld
- orl %ecx,%ecx
- jz 2f
-1:
- pushl %esi
- pushl %edi
- BUS_ACCESS_ADDR(eax,esi)
- BUS_ACCESS_ADDR(ebx,edi)
- movsl
- popl %edi
- popl %esi
- addl $4,%esi
- addl $4,%edi
- decl %ecx
- jnz 1b
-2:
- ret
-
-#undef BUS_ACCESS_ADDR
-#undef BUS_ACCESS_ADDR2
-
-
-#include "opt_mecia.h"
-#ifdef DEV_MECIA
-
-/***********************************************************
- * NEPC pcmcia 16 bits bus access
- ***********************************************************/
-#define NEPC_SWITCH_BUS16 \
- pushl %ebp ;\
- pushl %eax ;\
- pushl %edx ;\
- movl $0x2a8e,%edx ;\
- inb %dx,%al ;\
- movl %eax,%ebp ;\
- andl $~0x20,%eax ;\
- outb %al,%dx ;\
- popl %edx ;\
- popl %eax
-
-#define NEPC_BUS_RESTORE \
- pushl %eax ;\
- movl %ebp,%eax ;\
- xchgl %edx,%ebp ;\
- movl $0x2a8e,%edx ;\
- outb %al,%dx ;\
- xchgl %ebp,%edx ;\
- popl %eax ;\
- popl %ebp
-
-/***********************************************************
- * NEPC pcmcia 16 bits bus acces (Direct Access)
- ***********************************************************/
-#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \
- addl BUS_SPACE_HANDLE_BASE/**/(%/**/BSHREG/**/),%/**/ADDRREG
-
-ENTRY(NEPC_DA_io_space_read_2)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- inw %dx,%ax
- NEPC_BUS_RESTORE
- ret
-
-
-ENTRY(NEPC_DA_io_space_write_2)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- outw %ax,%dx
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_read_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- cld
- rep
- insw
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_write_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- cld
- rep
- outsw
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_read_region_2)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_read_region_2
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_write_region_2)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_write_region_2
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_set_multi_2)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_set_multi_2
- NEPC_BUS_RESTORE
- ret
-
-
-ENTRY(NEPC_DA_io_space_set_region_2)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_set_region_2
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_copy_region_2)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_copy_region_2
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_read_4)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- inl %dx,%eax
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_write_4)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- outl %eax,%dx
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_read_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- cld
- rep
- insl
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_write_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- cld
- rep
- outsl
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_read_region_4)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_read_region_4
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_write_region_4)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_write_region_4
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_set_multi_4)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_set_multi_4
- NEPC_BUS_RESTORE
- ret
-
-
-ENTRY(NEPC_DA_io_space_set_region_4)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_set_region_4
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_DA_io_space_copy_region_4)
- NEPC_SWITCH_BUS16
- call SBUS_DA_io_space_copy_region_4
- NEPC_BUS_RESTORE
- ret
-
-#undef BUS_ACCESS_ADDR
-
-/***********************************************************
- * NEPC pcmcia 16 bits bus acces (Relocate Access)
- ***********************************************************/
-#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \
- movl BUS_SPACE_HANDLE_IAT/**/(%/**/BSHREG/**/, %/**/ADDRREG/**/, 4), \
- %/**/ADDRREG
-
-ENTRY(NEPC_RA_io_space_read_2)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- inw %dx,%ax
- NEPC_BUS_RESTORE
- ret
-
-
-ENTRY(NEPC_RA_io_space_write_2)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- outw %ax,%dx
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_read_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- cld
- rep
- insw
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_write_multi_2)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- cld
- rep
- outsw
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_read_region_2)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_read_region_2
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_write_region_2)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_write_region_2
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_set_multi_2)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_set_multi_2
- NEPC_BUS_RESTORE
- ret
-
-
-ENTRY(NEPC_RA_io_space_set_region_2)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_set_region_2
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_copy_region_2)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_copy_region_2
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_read_4)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- inl %dx,%eax
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_write_4)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- outl %eax,%dx
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_read_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- cld
- rep
- insl
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_write_multi_4)
- BUS_ACCESS_ADDR(ebx,edx)
- NEPC_SWITCH_BUS16
- cld
- rep
- outsl
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_read_region_4)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_read_region_4
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_write_region_4)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_write_region_4
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_set_multi_4)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_set_multi_4
- NEPC_BUS_RESTORE
- ret
-
-
-ENTRY(NEPC_RA_io_space_set_region_4)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_set_region_4
- NEPC_BUS_RESTORE
- ret
-
-ENTRY(NEPC_RA_io_space_copy_region_4)
- NEPC_SWITCH_BUS16
- call SBUS_RA_io_space_copy_region_4
- NEPC_BUS_RESTORE
- ret
-
-#endif /* DEV_MECIA */
diff --git a/sys/pc98/i386/busiosubr.c b/sys/pc98/i386/busiosubr.c
deleted file mode 100644
index 8776d3f..0000000
--- a/sys/pc98/i386/busiosubr.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* $FreeBSD$ */
-/* $NecBSD: busiosubr.c,v 1.30.4.4 1999/08/28 02:25:35 honda Exp $ */
-/* $NetBSD$ */
-
-/*-
- * [NetBSD for NEC PC-98 series]
- * Copyright (c) 1996, 1997, 1998
- * NetBSD/pc98 porting staff. All rights reserved.
- *
- * [Ported for FreeBSD]
- * Copyright (c) 2001
- * TAKAHASHI Yoshihiro. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software 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.
- */
-
-/*
- * Copyright (c) 1997, 1998
- * Naofumi HONDA. All rights reserved.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <machine/bus.h>
-
-static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle");
-
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int8_t,1)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int16_t,2)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int32_t,4)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int8_t,1)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int16_t,2)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int32_t,4)
-
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int8_t,1)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int16_t,2)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int32_t,4)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int8_t,1)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int16_t,2)
-_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int32_t,4)
-
-struct bus_space_tag SBUS_io_space_tag = {
- BUS_SPACE_IO,
-
- /* direct bus access methods */
- {
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int16_t,2),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int32_t,4),
- },
-
- /* relocate bus access methods */
- {
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int16_t,2),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int32_t,4),
- }
-};
-
-struct bus_space_tag SBUS_mem_space_tag = {
- BUS_SPACE_MEM,
-
- /* direct bus access methods */
- {
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4),
- },
-
- /* relocate bus access methods */
- {
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4),
- }
-};
-
-
-#include "opt_mecia.h"
-#ifdef DEV_MECIA
-
-_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int16_t,2)
-_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int32_t,4)
-
-_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int16_t,2)
-_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int32_t,4)
-
-struct bus_space_tag NEPC_io_space_tag = {
- BUS_SPACE_IO,
-
- /* direct bus access methods */
- {
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1),
- _BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int16_t,2),
- _BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int32_t,4),
- },
-
- /* relocate bus access methods */
- {
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1),
- _BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int16_t,2),
- _BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int32_t,4),
- }
-};
-
-struct bus_space_tag NEPC_mem_space_tag = {
- BUS_SPACE_MEM,
-
- /* direct bus access methods */
- {
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4),
- },
-
- /* relocate bus access methods */
- {
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2),
- _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4),
- }
-};
-
-#endif /* DEV_MECIA */
-
-/*************************************************************************
- * map init
- *************************************************************************/
-static __inline void
-bus_space_iat_init(bus_space_handle_t bsh)
-{
- int i;
-
- for (i = 0; i < bsh->bsh_maxiatsz; i++)
- bsh->bsh_iat[i] = bsh->bsh_base + i;
-}
-
-/*************************************************************************
- * handle allocation
- *************************************************************************/
-int
-i386_bus_space_handle_alloc(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
- bus_space_handle_t *bshp)
-{
- bus_space_handle_t bsh;
-
- bsh = (bus_space_handle_t) malloc(sizeof (*bsh), M_BUSSPACEHANDLE,
- M_NOWAIT | M_ZERO);
- if (bsh == NULL)
- return ENOMEM;
-
- bsh->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
- bsh->bsh_iatsz = 0;
- bsh->bsh_base = bpa;
- bsh->bsh_sz = size;
- bsh->bsh_res = NULL;
- bsh->bsh_ressz = 0;
- bus_space_iat_init(bsh);
-
- bsh->bsh_bam = t->bs_da; /* default: direct access */
-
- *bshp = bsh;
- return 0;
-}
-
-void
-i386_bus_space_handle_free(bus_space_tag_t t, bus_space_handle_t bsh,
- size_t size)
-{
-
- free(bsh, M_BUSSPACEHANDLE);
-}
-
-/*************************************************************************
- * map
- *************************************************************************/
-int
-i386_memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
- bus_space_handle_t *bshp)
-{
-
- return i386_bus_space_handle_alloc(t, bpa, size, bshp);
-}
-
-void
-i386_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
-{
-
- i386_bus_space_handle_free(t, bsh, bsh->bsh_sz);
-}
-
-void
-i386_memio_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
-{
-
- /* i386_memio_unmap() does all that we need to do. */
- i386_memio_unmap(t, bsh, bsh->bsh_sz);
-}
-
-int
-i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
- bus_size_t offset, bus_size_t size,
- bus_space_handle_t *tbshp)
-{
- int i, error = 0;
- bus_space_handle_t bsh;
- bus_addr_t pbase;
-
- pbase = pbsh->bsh_base + offset;
- switch (t->bs_tag) {
- case BUS_SPACE_IO:
- if (pbsh->bsh_iatsz > 0) {
- if (offset >= pbsh->bsh_iatsz ||
- offset + size > pbsh->bsh_iatsz)
- return EINVAL;
- pbase = pbsh->bsh_base;
- }
- break;
-
- case BUS_SPACE_MEM:
- if (pbsh->bsh_iatsz > 0)
- return EINVAL;
- if (offset > pbsh->bsh_sz || offset + size > pbsh->bsh_sz)
- return EINVAL;
- break;
-
- default:
- panic("i386_memio_subregion: bad bus space tag");
- break;
- }
-
- error = i386_bus_space_handle_alloc(t, pbase, size, &bsh);
- if (error != 0)
- return error;
-
- switch (t->bs_tag) {
- case BUS_SPACE_IO:
- if (pbsh->bsh_iatsz > 0) {
- for (i = 0; i < size; i ++)
- bsh->bsh_iat[i] = pbsh->bsh_iat[i + offset];
- bsh->bsh_iatsz = size;
- } else if (pbsh->bsh_base > bsh->bsh_base ||
- pbsh->bsh_base + pbsh->bsh_sz <
- bsh->bsh_base + bsh->bsh_sz) {
- i386_bus_space_handle_free(t, bsh, size);
- return EINVAL;
- }
- break;
-
- case BUS_SPACE_MEM:
- break;
- }
-
- if (pbsh->bsh_iatsz > 0)
- bsh->bsh_bam = t->bs_ra; /* relocate access */
- *tbshp = bsh;
- return error;
-}
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
deleted file mode 100644
index ab6c5c9..0000000
--- a/sys/pc98/i386/machdep.c
+++ /dev/null
@@ -1,2779 +0,0 @@
-/*-
- * Copyright (c) 1992 Terrence R. Lambert.
- * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_atalk.h"
-#include "opt_compat.h"
-#include "opt_cpu.h"
-#include "opt_ddb.h"
-#include "opt_inet.h"
-#include "opt_ipx.h"
-#include "opt_isa.h"
-#include "opt_kstack_pages.h"
-#include "opt_maxmem.h"
-#include "opt_msgbuf.h"
-#include "opt_npx.h"
-#include "opt_perfmon.h"
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/bus.h>
-#include <sys/callout.h>
-#include <sys/cons.h>
-#include <sys/cpu.h>
-#include <sys/eventhandler.h>
-#include <sys/exec.h>
-#include <sys/imgact.h>
-#include <sys/kdb.h>
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/linker.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/memrange.h>
-#include <sys/msgbuf.h>
-#include <sys/mutex.h>
-#include <sys/pcpu.h>
-#include <sys/ptrace.h>
-#include <sys/reboot.h>
-#include <sys/sched.h>
-#include <sys/signalvar.h>
-#include <sys/sysctl.h>
-#include <sys/sysent.h>
-#include <sys/sysproto.h>
-#include <sys/ucontext.h>
-#include <sys/vmmeter.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-#include <vm/vm_object.h>
-#include <vm/vm_pager.h>
-#include <vm/vm_param.h>
-
-#ifdef DDB
-#ifndef KDB
-#error KDB must be enabled in order for DDB to work!
-#endif
-#include <ddb/ddb.h>
-#include <ddb/db_sym.h>
-#endif
-
-#include <pc98/pc98/pc98_machdep.h>
-#include <pc98/pc98/pc98.h>
-
-#include <net/netisr.h>
-
-#include <machine/bootinfo.h>
-#include <machine/clock.h>
-#include <machine/cpu.h>
-#include <machine/cputypes.h>
-#include <machine/intr_machdep.h>
-#include <machine/md_var.h>
-#include <machine/pc/bios.h>
-#include <machine/pcb.h>
-#include <machine/pcb_ext.h>
-#include <machine/proc.h>
-#include <machine/reg.h>
-#include <machine/sigframe.h>
-#include <machine/specialreg.h>
-#include <machine/vm86.h>
-#ifdef PERFMON
-#include <machine/perfmon.h>
-#endif
-#ifdef SMP
-#include <machine/privatespace.h>
-#include <machine/smp.h>
-#endif
-
-#ifdef DEV_ISA
-#include <i386/isa/icu.h>
-#endif
-
-/* Sanity check for __curthread() */
-CTASSERT(offsetof(struct pcpu, pc_curthread) == 0);
-
-extern void init386(int first);
-extern void dblfault_handler(void);
-
-extern void printcpuinfo(void); /* XXX header file */
-extern void finishidentcpu(void);
-extern void panicifcpuunsupported(void);
-extern void initializecpu(void);
-
-#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
-#define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
-
-#if !defined(CPU_ENABLE_SSE) && defined(I686_CPU)
-#define CPU_ENABLE_SSE
-#endif
-#if defined(CPU_DISABLE_SSE)
-#undef CPU_ENABLE_SSE
-#endif
-
-static void cpu_startup(void *);
-static void fpstate_drop(struct thread *td);
-static void get_fpcontext(struct thread *td, mcontext_t *mcp);
-static int set_fpcontext(struct thread *td, const mcontext_t *mcp);
-#ifdef CPU_ENABLE_SSE
-static void set_fpregs_xmm(struct save87 *, struct savexmm *);
-static void fill_fpregs_xmm(struct savexmm *, struct save87 *);
-#endif /* CPU_ENABLE_SSE */
-SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
-
-int need_pre_dma_flush; /* If 1, use wbinvd befor DMA transfer. */
-int need_post_dma_flush; /* If 1, use invd after DMA transfer. */
-
-#ifdef DDB
-extern vm_offset_t ksym_start, ksym_end;
-#endif
-
-int _udatasel, _ucodesel;
-u_int basemem;
-
-static int ispc98 = 1;
-SYSCTL_INT(_machdep, OID_AUTO, ispc98, CTLFLAG_RD, &ispc98, 0, "");
-
-int cold = 1;
-
-#ifdef COMPAT_43
-static void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
-#endif
-#ifdef COMPAT_FREEBSD4
-static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask,
- u_long code);
-#endif
-
-long Maxmem = 0;
-long realmem = 0;
-
-vm_paddr_t phys_avail[10];
-
-/* must be 2 less so 0 0 can signal end of chunks */
-#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2)
-
-struct kva_md_info kmi;
-
-static struct trapframe proc0_tf;
-#ifndef SMP
-static struct pcpu __pcpu;
-#endif
-
-struct mtx icu_lock;
-
-struct mem_range_softc mem_range_softc;
-
-static void
-cpu_startup(dummy)
- void *dummy;
-{
- /*
- * Good {morning,afternoon,evening,night}.
- */
- startrtclock();
- printcpuinfo();
- panicifcpuunsupported();
-#ifdef PERFMON
- perfmon_init();
-#endif
- printf("real memory = %ju (%ju MB)\n", ptoa((uintmax_t)Maxmem),
- ptoa((uintmax_t)Maxmem) / 1048576);
- realmem = Maxmem;
- /*
- * Display any holes after the first chunk of extended memory.
- */
- if (bootverbose) {
- int indx;
-
- printf("Physical memory chunk(s):\n");
- for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
- vm_paddr_t size;
-
- size = phys_avail[indx + 1] - phys_avail[indx];
- printf(
- "0x%016jx - 0x%016jx, %ju bytes (%ju pages)\n",
- (uintmax_t)phys_avail[indx],
- (uintmax_t)phys_avail[indx + 1] - 1,
- (uintmax_t)size, (uintmax_t)size / PAGE_SIZE);
- }
- }
-
- vm_ksubmap_init(&kmi);
-
- printf("avail memory = %ju (%ju MB)\n",
- ptoa((uintmax_t)cnt.v_free_count),
- ptoa((uintmax_t)cnt.v_free_count) / 1048576);
-
- /*
- * Set up buffers, so they can be used to read disk labels.
- */
- bufinit();
- vm_pager_bufferinit();
-
- cpu_setregs();
-}
-
-/*
- * Send an interrupt to process.
- *
- * Stack is set up to allow sigcode stored
- * at top to call routine, followed by kcall
- * to sigreturn routine below. After sigreturn
- * resets the signal mask, the stack, and the
- * frame pointer, it returns to the user
- * specified pc, psl.
- */
-#ifdef COMPAT_43
-static void
-osendsig(catcher, sig, mask, code)
- sig_t catcher;
- int sig;
- sigset_t *mask;
- u_long code;
-{
- struct osigframe sf, *fp;
- struct proc *p;
- struct thread *td;
- struct sigacts *psp;
- struct trapframe *regs;
- int oonstack;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
- psp = p->p_sigacts;
- mtx_assert(&psp->ps_mtx, MA_OWNED);
- regs = td->td_frame;
- oonstack = sigonstack(regs->tf_esp);
-
- /* Allocate space for the signal handler context. */
- if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
- SIGISMEMBER(psp->ps_sigonstack, sig)) {
- fp = (struct osigframe *)(td->td_sigstk.ss_sp +
- td->td_sigstk.ss_size - sizeof(struct osigframe));
-#if defined(COMPAT_43)
- td->td_sigstk.ss_flags |= SS_ONSTACK;
-#endif
- } else
- fp = (struct osigframe *)regs->tf_esp - 1;
-
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
- /* Build the argument list for the signal handler. */
- sf.sf_signum = sig;
- sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
- if (SIGISMEMBER(psp->ps_siginfo, sig)) {
- /* Signal handler installed with SA_SIGINFO. */
- sf.sf_arg2 = (register_t)&fp->sf_siginfo;
- sf.sf_siginfo.si_signo = sig;
- sf.sf_siginfo.si_code = code;
- sf.sf_ahu.sf_action = (__osiginfohandler_t *)catcher;
- } else {
- /* Old FreeBSD-style arguments. */
- sf.sf_arg2 = code;
- sf.sf_addr = regs->tf_err;
- sf.sf_ahu.sf_handler = catcher;
- }
- mtx_unlock(&psp->ps_mtx);
- PROC_UNLOCK(p);
-
- /* Save most if not all of trap frame. */
- sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax;
- sf.sf_siginfo.si_sc.sc_ebx = regs->tf_ebx;
- sf.sf_siginfo.si_sc.sc_ecx = regs->tf_ecx;
- sf.sf_siginfo.si_sc.sc_edx = regs->tf_edx;
- sf.sf_siginfo.si_sc.sc_esi = regs->tf_esi;
- sf.sf_siginfo.si_sc.sc_edi = regs->tf_edi;
- sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs;
- sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds;
- sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss;
- sf.sf_siginfo.si_sc.sc_es = regs->tf_es;
- sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs;
- sf.sf_siginfo.si_sc.sc_gs = rgs();
- sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp;
-
- /* Build the signal context to be used by osigreturn(). */
- sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0;
- SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask);
- sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp;
- sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp;
- sf.sf_siginfo.si_sc.sc_pc = regs->tf_eip;
- sf.sf_siginfo.si_sc.sc_ps = regs->tf_eflags;
- sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno;
- sf.sf_siginfo.si_sc.sc_err = regs->tf_err;
-
- /*
- * If we're a vm86 process, we want to save the segment registers.
- * We also change eflags to be our emulated eflags, not the actual
- * eflags.
- */
- if (regs->tf_eflags & PSL_VM) {
- /* XXX confusing names: `tf' isn't a trapframe; `regs' is. */
- struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
- struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
-
- sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
- sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
- sf.sf_siginfo.si_sc.sc_es = tf->tf_vm86_es;
- sf.sf_siginfo.si_sc.sc_ds = tf->tf_vm86_ds;
-
- if (vm86->vm86_has_vme == 0)
- sf.sf_siginfo.si_sc.sc_ps =
- (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) |
- (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
-
- /* See sendsig() for comments. */
- tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
- }
-
- /*
- * Copy the sigframe out to the user's stack.
- */
- if (copyout(&sf, fp, sizeof(*fp)) != 0) {
-#ifdef DEBUG
- printf("process %ld has trashed its stack\n", (long)p->p_pid);
-#endif
- PROC_LOCK(p);
- sigexit(td, SIGILL);
- }
-
- regs->tf_esp = (int)fp;
- regs->tf_eip = PS_STRINGS - szosigcode;
- regs->tf_eflags &= ~PSL_T;
- regs->tf_cs = _ucodesel;
- regs->tf_ds = _udatasel;
- regs->tf_es = _udatasel;
- regs->tf_fs = _udatasel;
- load_gs(_udatasel);
- regs->tf_ss = _udatasel;
- PROC_LOCK(p);
- mtx_lock(&psp->ps_mtx);
-}
-#endif /* COMPAT_43 */
-
-#ifdef COMPAT_FREEBSD4
-static void
-freebsd4_sendsig(catcher, sig, mask, code)
- sig_t catcher;
- int sig;
- sigset_t *mask;
- u_long code;
-{
- struct sigframe4 sf, *sfp;
- struct proc *p;
- struct thread *td;
- struct sigacts *psp;
- struct trapframe *regs;
- int oonstack;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
- psp = p->p_sigacts;
- mtx_assert(&psp->ps_mtx, MA_OWNED);
- regs = td->td_frame;
- oonstack = sigonstack(regs->tf_esp);
-
- /* Save user context. */
- bzero(&sf, sizeof(sf));
- sf.sf_uc.uc_sigmask = *mask;
- sf.sf_uc.uc_stack = td->td_sigstk;
- sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
- ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
- sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
- sf.sf_uc.uc_mcontext.mc_gs = rgs();
- bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
-
- /* Allocate space for the signal handler context. */
- if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
- SIGISMEMBER(psp->ps_sigonstack, sig)) {
- sfp = (struct sigframe4 *)(td->td_sigstk.ss_sp +
- td->td_sigstk.ss_size - sizeof(struct sigframe4));
-#if defined(COMPAT_43)
- td->td_sigstk.ss_flags |= SS_ONSTACK;
-#endif
- } else
- sfp = (struct sigframe4 *)regs->tf_esp - 1;
-
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
- /* Build the argument list for the signal handler. */
- sf.sf_signum = sig;
- sf.sf_ucontext = (register_t)&sfp->sf_uc;
- if (SIGISMEMBER(psp->ps_siginfo, sig)) {
- /* Signal handler installed with SA_SIGINFO. */
- sf.sf_siginfo = (register_t)&sfp->sf_si;
- sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
-
- /* Fill in POSIX parts */
- sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = (void *)regs->tf_err;
- } else {
- /* Old FreeBSD-style arguments. */
- sf.sf_siginfo = code;
- sf.sf_addr = regs->tf_err;
- sf.sf_ahu.sf_handler = catcher;
- }
- mtx_unlock(&psp->ps_mtx);
- PROC_UNLOCK(p);
-
- /*
- * If we're a vm86 process, we want to save the segment registers.
- * We also change eflags to be our emulated eflags, not the actual
- * eflags.
- */
- if (regs->tf_eflags & PSL_VM) {
- struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
- struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
-
- sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
- sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
- sf.sf_uc.uc_mcontext.mc_es = tf->tf_vm86_es;
- sf.sf_uc.uc_mcontext.mc_ds = tf->tf_vm86_ds;
-
- if (vm86->vm86_has_vme == 0)
- sf.sf_uc.uc_mcontext.mc_eflags =
- (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) |
- (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
-
- /*
- * Clear PSL_NT to inhibit T_TSSFLT faults on return from
- * syscalls made by the signal handler. This just avoids
- * wasting time for our lazy fixup of such faults. PSL_NT
- * does nothing in vm86 mode, but vm86 programs can set it
- * almost legitimately in probes for old cpu types.
- */
- tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
- }
-
- /*
- * Copy the sigframe out to the user's stack.
- */
- if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
-#ifdef DEBUG
- printf("process %ld has trashed its stack\n", (long)p->p_pid);
-#endif
- PROC_LOCK(p);
- sigexit(td, SIGILL);
- }
-
- regs->tf_esp = (int)sfp;
- regs->tf_eip = PS_STRINGS - szfreebsd4_sigcode;
- regs->tf_eflags &= ~PSL_T;
- regs->tf_cs = _ucodesel;
- regs->tf_ds = _udatasel;
- regs->tf_es = _udatasel;
- regs->tf_fs = _udatasel;
- regs->tf_ss = _udatasel;
- PROC_LOCK(p);
- mtx_lock(&psp->ps_mtx);
-}
-#endif /* COMPAT_FREEBSD4 */
-
-void
-sendsig(catcher, sig, mask, code)
- sig_t catcher;
- int sig;
- sigset_t *mask;
- u_long code;
-{
- struct sigframe sf, *sfp;
- struct proc *p;
- struct thread *td;
- struct sigacts *psp;
- char *sp;
- struct trapframe *regs;
- int oonstack;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
- psp = p->p_sigacts;
- mtx_assert(&psp->ps_mtx, MA_OWNED);
-#ifdef COMPAT_FREEBSD4
- if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
- freebsd4_sendsig(catcher, sig, mask, code);
- return;
- }
-#endif
-#ifdef COMPAT_43
- if (SIGISMEMBER(psp->ps_osigset, sig)) {
- osendsig(catcher, sig, mask, code);
- return;
- }
-#endif
- regs = td->td_frame;
- oonstack = sigonstack(regs->tf_esp);
-
- /* Save user context. */
- bzero(&sf, sizeof(sf));
- sf.sf_uc.uc_sigmask = *mask;
- sf.sf_uc.uc_stack = td->td_sigstk;
- sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
- ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
- sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
- sf.sf_uc.uc_mcontext.mc_gs = rgs();
- bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
- sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */
- get_fpcontext(td, &sf.sf_uc.uc_mcontext);
- fpstate_drop(td);
-
- /* Allocate space for the signal handler context. */
- if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
- SIGISMEMBER(psp->ps_sigonstack, sig)) {
- sp = td->td_sigstk.ss_sp +
- td->td_sigstk.ss_size - sizeof(struct sigframe);
-#if defined(COMPAT_43)
- td->td_sigstk.ss_flags |= SS_ONSTACK;
-#endif
- } else
- sp = (char *)regs->tf_esp - sizeof(struct sigframe);
- /* Align to 16 bytes. */
- sfp = (struct sigframe *)((unsigned int)sp & ~0xF);
-
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
- /* Build the argument list for the signal handler. */
- sf.sf_signum = sig;
- sf.sf_ucontext = (register_t)&sfp->sf_uc;
- if (SIGISMEMBER(psp->ps_siginfo, sig)) {
- /* Signal handler installed with SA_SIGINFO. */
- sf.sf_siginfo = (register_t)&sfp->sf_si;
- sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
-
- /* Fill in POSIX parts */
- sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = (void *)regs->tf_err;
- } else {
- /* Old FreeBSD-style arguments. */
- sf.sf_siginfo = code;
- sf.sf_addr = regs->tf_err;
- sf.sf_ahu.sf_handler = catcher;
- }
- mtx_unlock(&psp->ps_mtx);
- PROC_UNLOCK(p);
-
- /*
- * If we're a vm86 process, we want to save the segment registers.
- * We also change eflags to be our emulated eflags, not the actual
- * eflags.
- */
- if (regs->tf_eflags & PSL_VM) {
- struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
- struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
-
- sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
- sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
- sf.sf_uc.uc_mcontext.mc_es = tf->tf_vm86_es;
- sf.sf_uc.uc_mcontext.mc_ds = tf->tf_vm86_ds;
-
- if (vm86->vm86_has_vme == 0)
- sf.sf_uc.uc_mcontext.mc_eflags =
- (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) |
- (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
-
- /*
- * Clear PSL_NT to inhibit T_TSSFLT faults on return from
- * syscalls made by the signal handler. This just avoids
- * wasting time for our lazy fixup of such faults. PSL_NT
- * does nothing in vm86 mode, but vm86 programs can set it
- * almost legitimately in probes for old cpu types.
- */
- tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
- }
-
- /*
- * Copy the sigframe out to the user's stack.
- */
- if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
-#ifdef DEBUG
- printf("process %ld has trashed its stack\n", (long)p->p_pid);
-#endif
- PROC_LOCK(p);
- sigexit(td, SIGILL);
- }
-
- regs->tf_esp = (int)sfp;
- regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
- regs->tf_eflags &= ~PSL_T;
- regs->tf_cs = _ucodesel;
- regs->tf_ds = _udatasel;
- regs->tf_es = _udatasel;
- regs->tf_fs = _udatasel;
- regs->tf_ss = _udatasel;
- PROC_LOCK(p);
- mtx_lock(&psp->ps_mtx);
-}
-
-/*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
- struct proc *p;
- struct thread *td;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
-
- bzero(si, sizeof(*si));
- si->si_signo = sig;
- si->si_code = code;
- si->si_addr = (void *)td->td_frame->tf_err;
- /* XXXKSE fill other fields */
-}
-
-/*
- * System call to cleanup state after a signal
- * has been taken. Reset signal mask and
- * stack state from context left by sendsig (above).
- * Return to previous pc and psl as specified by
- * context left by sendsig. Check carefully to
- * make sure that the user has not modified the
- * state to gain improper privileges.
- *
- * MPSAFE
- */
-#ifdef COMPAT_43
-int
-osigreturn(td, uap)
- struct thread *td;
- struct osigreturn_args /* {
- struct osigcontext *sigcntxp;
- } */ *uap;
-{
- struct osigcontext sc;
- struct trapframe *regs;
- struct osigcontext *scp;
- struct proc *p = td->td_proc;
- int eflags, error;
-
- regs = td->td_frame;
- error = copyin(uap->sigcntxp, &sc, sizeof(sc));
- if (error != 0)
- return (error);
- scp = &sc;
- eflags = scp->sc_ps;
- if (eflags & PSL_VM) {
- struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
- struct vm86_kernel *vm86;
-
- /*
- * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
- * set up the vm86 area, and we can't enter vm86 mode.
- */
- if (td->td_pcb->pcb_ext == 0)
- return (EINVAL);
- vm86 = &td->td_pcb->pcb_ext->ext_vm86;
- if (vm86->vm86_inited == 0)
- return (EINVAL);
-
- /* Go back to user mode if both flags are set. */
- if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
- trapsignal(td, SIGBUS, 0);
-
- if (vm86->vm86_has_vme) {
- eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
- (eflags & VME_USERCHANGE) | PSL_VM;
- } else {
- vm86->vm86_eflags = eflags; /* save VIF, VIP */
- eflags = (tf->tf_eflags & ~VM_USERCHANGE) |
- (eflags & VM_USERCHANGE) | PSL_VM;
- }
- tf->tf_vm86_ds = scp->sc_ds;
- tf->tf_vm86_es = scp->sc_es;
- tf->tf_vm86_fs = scp->sc_fs;
- tf->tf_vm86_gs = scp->sc_gs;
- tf->tf_ds = _udatasel;
- tf->tf_es = _udatasel;
- tf->tf_fs = _udatasel;
- } else {
- /*
- * Don't allow users to change privileged or reserved flags.
- */
- /*
- * XXX do allow users to change the privileged flag PSL_RF.
- * The cpu sets PSL_RF in tf_eflags for faults. Debuggers
- * should sometimes set it there too. tf_eflags is kept in
- * the signal context during signal handling and there is no
- * other place to remember it, so the PSL_RF bit may be
- * corrupted by the signal handler without us knowing.
- * Corruption of the PSL_RF bit at worst causes one more or
- * one less debugger trap, so allowing it is fairly harmless.
- */
- if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
- return (EINVAL);
- }
-
- /*
- * Don't allow users to load a valid privileged %cs. Let the
- * hardware check for invalid selectors, excess privilege in
- * other selectors, invalid %eip's and invalid %esp's.
- */
- if (!CS_SECURE(scp->sc_cs)) {
- trapsignal(td, SIGBUS, T_PROTFLT);
- return (EINVAL);
- }
- regs->tf_ds = scp->sc_ds;
- regs->tf_es = scp->sc_es;
- regs->tf_fs = scp->sc_fs;
- }
-
- /* Restore remaining registers. */
- regs->tf_eax = scp->sc_eax;
- regs->tf_ebx = scp->sc_ebx;
- regs->tf_ecx = scp->sc_ecx;
- regs->tf_edx = scp->sc_edx;
- regs->tf_esi = scp->sc_esi;
- regs->tf_edi = scp->sc_edi;
- regs->tf_cs = scp->sc_cs;
- regs->tf_ss = scp->sc_ss;
- regs->tf_isp = scp->sc_isp;
- regs->tf_ebp = scp->sc_fp;
- regs->tf_esp = scp->sc_sp;
- regs->tf_eip = scp->sc_pc;
- regs->tf_eflags = eflags;
-
- PROC_LOCK(p);
-#if defined(COMPAT_43)
- if (scp->sc_onstack & 1)
- td->td_sigstk.ss_flags |= SS_ONSTACK;
- else
- td->td_sigstk.ss_flags &= ~SS_ONSTACK;
-#endif
- SIGSETOLD(td->td_sigmask, scp->sc_mask);
- SIG_CANTMASK(td->td_sigmask);
- signotify(td);
- PROC_UNLOCK(p);
- return (EJUSTRETURN);
-}
-#endif /* COMPAT_43 */
-
-#ifdef COMPAT_FREEBSD4
-/*
- * MPSAFE
- */
-int
-freebsd4_sigreturn(td, uap)
- struct thread *td;
- struct freebsd4_sigreturn_args /* {
- const ucontext4 *sigcntxp;
- } */ *uap;
-{
- struct ucontext4 uc;
- struct proc *p = td->td_proc;
- struct trapframe *regs;
- const struct ucontext4 *ucp;
- int cs, eflags, error;
-
- error = copyin(uap->sigcntxp, &uc, sizeof(uc));
- if (error != 0)
- return (error);
- ucp = &uc;
- regs = td->td_frame;
- eflags = ucp->uc_mcontext.mc_eflags;
- if (eflags & PSL_VM) {
- struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
- struct vm86_kernel *vm86;
-
- /*
- * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
- * set up the vm86 area, and we can't enter vm86 mode.
- */
- if (td->td_pcb->pcb_ext == 0)
- return (EINVAL);
- vm86 = &td->td_pcb->pcb_ext->ext_vm86;
- if (vm86->vm86_inited == 0)
- return (EINVAL);
-
- /* Go back to user mode if both flags are set. */
- if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
- trapsignal(td, SIGBUS, 0);
-
- if (vm86->vm86_has_vme) {
- eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
- (eflags & VME_USERCHANGE) | PSL_VM;
- } else {
- vm86->vm86_eflags = eflags; /* save VIF, VIP */
- eflags = (tf->tf_eflags & ~VM_USERCHANGE) |
- (eflags & VM_USERCHANGE) | PSL_VM;
- }
- bcopy(&ucp->uc_mcontext.mc_fs, tf, sizeof(struct trapframe));
- tf->tf_eflags = eflags;
- tf->tf_vm86_ds = tf->tf_ds;
- tf->tf_vm86_es = tf->tf_es;
- tf->tf_vm86_fs = tf->tf_fs;
- tf->tf_vm86_gs = ucp->uc_mcontext.mc_gs;
- tf->tf_ds = _udatasel;
- tf->tf_es = _udatasel;
- tf->tf_fs = _udatasel;
- } else {
- /*
- * Don't allow users to change privileged or reserved flags.
- */
- /*
- * XXX do allow users to change the privileged flag PSL_RF.
- * The cpu sets PSL_RF in tf_eflags for faults. Debuggers
- * should sometimes set it there too. tf_eflags is kept in
- * the signal context during signal handling and there is no
- * other place to remember it, so the PSL_RF bit may be
- * corrupted by the signal handler without us knowing.
- * Corruption of the PSL_RF bit at worst causes one more or
- * one less debugger trap, so allowing it is fairly harmless.
- */
- if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
- printf("freebsd4_sigreturn: eflags = 0x%x\n", eflags);
- return (EINVAL);
- }
-
- /*
- * Don't allow users to load a valid privileged %cs. Let the
- * hardware check for invalid selectors, excess privilege in
- * other selectors, invalid %eip's and invalid %esp's.
- */
- cs = ucp->uc_mcontext.mc_cs;
- if (!CS_SECURE(cs)) {
- printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
- trapsignal(td, SIGBUS, T_PROTFLT);
- return (EINVAL);
- }
-
- bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
- }
-
- PROC_LOCK(p);
-#if defined(COMPAT_43)
- if (ucp->uc_mcontext.mc_onstack & 1)
- td->td_sigstk.ss_flags |= SS_ONSTACK;
- else
- td->td_sigstk.ss_flags &= ~SS_ONSTACK;
-#endif
-
- td->td_sigmask = ucp->uc_sigmask;
- SIG_CANTMASK(td->td_sigmask);
- signotify(td);
- PROC_UNLOCK(p);
- return (EJUSTRETURN);
-}
-#endif /* COMPAT_FREEBSD4 */
-
-/*
- * MPSAFE
- */
-int
-sigreturn(td, uap)
- struct thread *td;
- struct sigreturn_args /* {
- const __ucontext *sigcntxp;
- } */ *uap;
-{
- ucontext_t uc;
- struct proc *p = td->td_proc;
- struct trapframe *regs;
- const ucontext_t *ucp;
- int cs, eflags, error, ret;
-
- error = copyin(uap->sigcntxp, &uc, sizeof(uc));
- if (error != 0)
- return (error);
- ucp = &uc;
- regs = td->td_frame;
- eflags = ucp->uc_mcontext.mc_eflags;
- if (eflags & PSL_VM) {
- struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
- struct vm86_kernel *vm86;
-
- /*
- * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
- * set up the vm86 area, and we can't enter vm86 mode.
- */
- if (td->td_pcb->pcb_ext == 0)
- return (EINVAL);
- vm86 = &td->td_pcb->pcb_ext->ext_vm86;
- if (vm86->vm86_inited == 0)
- return (EINVAL);
-
- /* Go back to user mode if both flags are set. */
- if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
- trapsignal(td, SIGBUS, 0);
-
- if (vm86->vm86_has_vme) {
- eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
- (eflags & VME_USERCHANGE) | PSL_VM;
- } else {
- vm86->vm86_eflags = eflags; /* save VIF, VIP */
- eflags = (tf->tf_eflags & ~VM_USERCHANGE) |
- (eflags & VM_USERCHANGE) | PSL_VM;
- }
- bcopy(&ucp->uc_mcontext.mc_fs, tf, sizeof(struct trapframe));
- tf->tf_eflags = eflags;
- tf->tf_vm86_ds = tf->tf_ds;
- tf->tf_vm86_es = tf->tf_es;
- tf->tf_vm86_fs = tf->tf_fs;
- tf->tf_vm86_gs = ucp->uc_mcontext.mc_gs;
- tf->tf_ds = _udatasel;
- tf->tf_es = _udatasel;
- tf->tf_fs = _udatasel;
- } else {
- /*
- * Don't allow users to change privileged or reserved flags.
- */
- /*
- * XXX do allow users to change the privileged flag PSL_RF.
- * The cpu sets PSL_RF in tf_eflags for faults. Debuggers
- * should sometimes set it there too. tf_eflags is kept in
- * the signal context during signal handling and there is no
- * other place to remember it, so the PSL_RF bit may be
- * corrupted by the signal handler without us knowing.
- * Corruption of the PSL_RF bit at worst causes one more or
- * one less debugger trap, so allowing it is fairly harmless.
- */
- if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
- printf("sigreturn: eflags = 0x%x\n", eflags);
- return (EINVAL);
- }
-
- /*
- * Don't allow users to load a valid privileged %cs. Let the
- * hardware check for invalid selectors, excess privilege in
- * other selectors, invalid %eip's and invalid %esp's.
- */
- cs = ucp->uc_mcontext.mc_cs;
- if (!CS_SECURE(cs)) {
- printf("sigreturn: cs = 0x%x\n", cs);
- trapsignal(td, SIGBUS, T_PROTFLT);
- return (EINVAL);
- }
-
- ret = set_fpcontext(td, &ucp->uc_mcontext);
- if (ret != 0)
- return (ret);
- bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
- }
-
- PROC_LOCK(p);
-#if defined(COMPAT_43)
- if (ucp->uc_mcontext.mc_onstack & 1)
- td->td_sigstk.ss_flags |= SS_ONSTACK;
- else
- td->td_sigstk.ss_flags &= ~SS_ONSTACK;
-#endif
-
- td->td_sigmask = ucp->uc_sigmask;
- SIG_CANTMASK(td->td_sigmask);
- signotify(td);
- PROC_UNLOCK(p);
- return (EJUSTRETURN);
-}
-
-/*
- * Machine dependent boot() routine
- *
- * I haven't seen anything to put here yet
- * Possibly some stuff might be grafted back here from boot()
- */
-void
-cpu_boot(int howto)
-{
-}
-
-/* Get current clock frequency for the given cpu id. */
-int
-cpu_est_clockrate(int cpu_id, uint64_t *rate)
-{
- register_t reg;
- uint64_t tsc1, tsc2;
-
- if (pcpu_find(cpu_id) == NULL || rate == NULL)
- return (EINVAL);
- if (!tsc_present)
- return (EOPNOTSUPP);
-
- /* If we're booting, trust the rate calibrated moments ago. */
- if (cold) {
- *rate = tsc_freq;
- return (0);
- }
-
-#ifdef SMP
- /* Schedule ourselves on the indicated cpu. */
- mtx_lock_spin(&sched_lock);
- sched_bind(curthread, cpu_id);
- mtx_unlock_spin(&sched_lock);
-#endif
-
- /* Calibrate by measuring a short delay. */
- reg = intr_disable();
- tsc1 = rdtsc();
- DELAY(1000);
- tsc2 = rdtsc();
- intr_restore(reg);
-
-#ifdef SMP
- mtx_lock_spin(&sched_lock);
- sched_unbind(curthread);
- mtx_unlock_spin(&sched_lock);
-#endif
-
- /*
- * Calculate the difference in readings, convert to Mhz, and
- * subtract 0.5% of the total. Empirical testing has shown that
- * overhead in DELAY() works out to approximately this value.
- */
- tsc2 -= tsc1;
- *rate = tsc2 * 1000 - tsc2 * 5;
- return (0);
-}
-
-/*
- * Shutdown the CPU as much as possible
- */
-void
-cpu_halt(void)
-{
- for (;;)
- __asm__ ("hlt");
-}
-
-/*
- * Hook to idle the CPU when possible. In the SMP case we default to
- * off because a halted cpu will not currently pick up a new thread in the
- * run queue until the next timer tick. If turned on this will result in
- * approximately a 4.2% loss in real time performance in buildworld tests
- * (but improves user and sys times oddly enough), and saves approximately
- * 5% in power consumption on an idle machine (tests w/2xCPU 1.1GHz P3).
- *
- * XXX we need to have a cpu mask of idle cpus and generate an IPI or
- * otherwise generate some sort of interrupt to wake up cpus sitting in HLT.
- * Then we can have our cake and eat it too.
- *
- * XXX I'm turning it on for SMP as well by default for now. It seems to
- * help lock contention somewhat, and this is critical for HTT. -Peter
- */
-static int cpu_idle_hlt = 1;
-SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW,
- &cpu_idle_hlt, 0, "Idle loop HLT enable");
-
-static void
-cpu_idle_default(void)
-{
- /*
- * we must absolutely guarentee that hlt is the
- * absolute next instruction after sti or we
- * introduce a timing window.
- */
- __asm __volatile("sti; hlt");
-}
-
-/*
- * Note that we have to be careful here to avoid a race between checking
- * sched_runnable() and actually halting. If we don't do this, we may waste
- * the time between calling hlt and the next interrupt even though there
- * is a runnable process.
- */
-void
-cpu_idle(void)
-{
-
-#ifdef SMP
- if (mp_grab_cpu_hlt())
- return;
-#endif
-
- if (cpu_idle_hlt) {
- disable_intr();
- if (sched_runnable())
- enable_intr();
- else
- (*cpu_idle_hook)();
- }
-}
-
-/* Other subsystems (e.g., ACPI) can hook this later. */
-void (*cpu_idle_hook)(void) = cpu_idle_default;
-
-/*
- * Clear registers on exec
- */
-void
-exec_setregs(td, entry, stack, ps_strings)
- struct thread *td;
- u_long entry;
- u_long stack;
- u_long ps_strings;
-{
- struct trapframe *regs = td->td_frame;
- struct pcb *pcb = td->td_pcb;
-
- /* Reset pc->pcb_gs and %gs before possibly invalidating it. */
- pcb->pcb_gs = _udatasel;
- load_gs(_udatasel);
-
- if (td->td_proc->p_md.md_ldt)
- user_ldt_free(td);
-
- bzero((char *)regs, sizeof(struct trapframe));
- regs->tf_eip = entry;
- regs->tf_esp = stack;
- regs->tf_eflags = PSL_USER | (regs->tf_eflags & PSL_T);
- regs->tf_ss = _udatasel;
- regs->tf_ds = _udatasel;
- regs->tf_es = _udatasel;
- regs->tf_fs = _udatasel;
- regs->tf_cs = _ucodesel;
-
- /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */
- regs->tf_ebx = ps_strings;
-
- /*
- * Reset the hardware debug registers if they were in use.
- * They won't have any meaning for the newly exec'd process.
- */
- if (pcb->pcb_flags & PCB_DBREGS) {
- pcb->pcb_dr0 = 0;
- pcb->pcb_dr1 = 0;
- pcb->pcb_dr2 = 0;
- pcb->pcb_dr3 = 0;
- pcb->pcb_dr6 = 0;
- pcb->pcb_dr7 = 0;
- if (pcb == PCPU_GET(curpcb)) {
- /*
- * Clear the debug registers on the running
- * CPU, otherwise they will end up affecting
- * the next process we switch to.
- */
- reset_dbregs();
- }
- pcb->pcb_flags &= ~PCB_DBREGS;
- }
-
- /*
- * Initialize the math emulator (if any) for the current process.
- * Actually, just clear the bit that says that the emulator has
- * been initialized. Initialization is delayed until the process
- * traps to the emulator (if it is done at all) mainly because
- * emulators don't provide an entry point for initialization.
- */
- td->td_pcb->pcb_flags &= ~FP_SOFTFP;
-
- /*
- * Drop the FP state if we hold it, so that the process gets a
- * clean FP state if it uses the FPU again.
- */
- fpstate_drop(td);
-
- /*
- * XXX - Linux emulator
- * Make sure sure edx is 0x0 on entry. Linux binaries depend
- * on it.
- */
- td->td_retval[1] = 0;
-}
-
-void
-cpu_setregs(void)
-{
- unsigned int cr0;
-
- cr0 = rcr0();
- /*
- * CR0_MP, CR0_NE and CR0_TS are also set by npx_probe() for the
- * BSP. See the comments there about why we set them.
- */
- cr0 |= CR0_MP | CR0_NE | CR0_TS | CR0_WP | CR0_AM;
- load_cr0(cr0);
- load_gs(_udatasel);
-}
-
-static int
-sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS)
-{
- int error;
- error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2,
- req);
- if (!error && req->newptr)
- resettodr();
- return (error);
-}
-
-SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW,
- &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", "");
-
-SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set,
- CTLFLAG_RW, &disable_rtc_set, 0, "");
-
-SYSCTL_STRUCT(_machdep, CPU_BOOTINFO, bootinfo,
- CTLFLAG_RD, &bootinfo, bootinfo, "");
-
-SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock,
- CTLFLAG_RW, &wall_cmos_clock, 0, "");
-
-u_long bootdev; /* not a struct cdev *- encoding is different */
-SYSCTL_ULONG(_machdep, OID_AUTO, guessed_bootdev,
- CTLFLAG_RD, &bootdev, 0, "Maybe the Boot device (not in struct cdev *format)");
-
-/*
- * Initialize 386 and configure to run kernel
- */
-
-/*
- * Initialize segments & interrupt table
- */
-
-int _default_ldt;
-union descriptor gdt[NGDT * MAXCPU]; /* global descriptor table */
-static struct gate_descriptor idt0[NIDT];
-struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */
-union descriptor ldt[NLDT]; /* local descriptor table */
-struct region_descriptor r_gdt, r_idt; /* table descriptors */
-
-int private_tss; /* flag indicating private tss */
-
-#if defined(I586_CPU) && !defined(NO_F00F_HACK)
-extern int has_f00f_bug;
-#endif
-
-static struct i386tss dblfault_tss;
-static char dblfault_stack[PAGE_SIZE];
-
-extern vm_offset_t proc0kstack;
-
-
-/*
- * software prototypes -- in more palatable form.
- *
- * GCODE_SEL through GUDATA_SEL must be in this order for syscall/sysret
- * GUFS_SEL and GUGS_SEL must be in this order (swtch.s knows it)
- */
-struct soft_segment_descriptor gdt_segs[] = {
-/* GNULL_SEL 0 Null Descriptor */
-{ 0x0, /* segment base address */
- 0x0, /* length */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
-/* GPRIV_SEL 1 SMP Per-Processor Private Data Descriptor */
-{ 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GUFS_SEL 2 %fs Descriptor for user */
-{ 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMRWA, /* segment type */
- SEL_UPL, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GUGS_SEL 3 %gs Descriptor for user */
-{ 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMRWA, /* segment type */
- SEL_UPL, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GCODE_SEL 4 Code Descriptor for kernel */
-{ 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMERA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GDATA_SEL 5 Data Descriptor for kernel */
-{ 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GUCODE_SEL 6 Code Descriptor for user */
-{ 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMERA, /* segment type */
- SEL_UPL, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GUDATA_SEL 7 Data Descriptor for user */
-{ 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMRWA, /* segment type */
- SEL_UPL, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GBIOSLOWMEM_SEL 8 BIOS access to realmode segment 0x40, must be #8 in GDT */
-{ 0x400, /* segment base address */
- 0xfffff, /* length */
- SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GPROC0_SEL 9 Proc 0 Tss Descriptor */
-{
- 0x0, /* segment base address */
- sizeof(struct i386tss)-1,/* length */
- SDT_SYS386TSS, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 0, /* unused - default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
-/* GLDT_SEL 10 LDT Descriptor */
-{ (int) ldt, /* segment base address */
- sizeof(ldt)-1, /* length - all address space */
- SDT_SYSLDT, /* segment type */
- SEL_UPL, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 0, /* unused - default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
-/* GUSERLDT_SEL 11 User LDT Descriptor per process */
-{ (int) ldt, /* segment base address */
- (512 * sizeof(union descriptor)-1), /* length */
- SDT_SYSLDT, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 0, /* unused - default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
-/* GPANIC_SEL 12 Panic Tss Descriptor */
-{ (int) &dblfault_tss, /* segment base address */
- sizeof(struct i386tss)-1,/* length - all address space */
- SDT_SYS386TSS, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 0, /* unused - default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
-/* GBIOSCODE32_SEL 13 BIOS 32-bit interface (32bit Code) */
-{ 0, /* segment base address (overwritten) */
- 0xfffff, /* length */
- SDT_MEMERA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GBIOSCODE16_SEL 14 BIOS 32-bit interface (16bit Code) */
-{ 0, /* segment base address (overwritten) */
- 0xfffff, /* length */
- SDT_MEMERA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GBIOSDATA_SEL 15 BIOS 32-bit interface (Data) */
-{ 0, /* segment base address (overwritten) */
- 0xfffff, /* length */
- SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GBIOSUTIL_SEL 16 BIOS 16-bit interface (Utility) */
-{ 0, /* segment base address (overwritten) */
- 0xfffff, /* length */
- SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GBIOSARGS_SEL 17 BIOS 16-bit interface (Arguments) */
-{ 0, /* segment base address (overwritten) */
- 0xfffff, /* length */
- SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-/* GNDIS_SEL 18 NDIS Descriptor */
-{ 0x0, /* segment base address */
- 0x0, /* length */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
-};
-
-static struct soft_segment_descriptor ldt_segs[] = {
- /* Null Descriptor - overwritten by call gate */
-{ 0x0, /* segment base address */
- 0x0, /* length - all address space */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Null Descriptor - overwritten by call gate */
-{ 0x0, /* segment base address */
- 0x0, /* length - all address space */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Null Descriptor - overwritten by call gate */
-{ 0x0, /* segment base address */
- 0x0, /* length - all address space */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Code Descriptor for user */
-{ 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMERA, /* segment type */
- SEL_UPL, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
- /* Null Descriptor - overwritten by call gate */
-{ 0x0, /* segment base address */
- 0x0, /* length - all address space */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0, 0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Data Descriptor for user */
-{ 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMRWA, /* segment type */
- SEL_UPL, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0, 0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
-};
-
-void
-setidt(idx, func, typ, dpl, selec)
- int idx;
- inthand_t *func;
- int typ;
- int dpl;
- int selec;
-{
- struct gate_descriptor *ip;
-
- ip = idt + idx;
- ip->gd_looffset = (int)func;
- ip->gd_selector = selec;
- ip->gd_stkcpy = 0;
- ip->gd_xx = 0;
- ip->gd_type = typ;
- ip->gd_dpl = dpl;
- ip->gd_p = 1;
- ip->gd_hioffset = ((int)func)>>16 ;
-}
-
-#define IDTVEC(name) __CONCAT(X,name)
-
-extern inthand_t
- IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
- IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm),
- IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
- IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align),
- IDTVEC(xmm), IDTVEC(lcall_syscall), IDTVEC(int0x80_syscall);
-
-#ifdef DDB
-/*
- * Display the index and function name of any IDT entries that don't use
- * the default 'rsvd' entry point.
- */
-DB_SHOW_COMMAND(idt, db_show_idt)
-{
- struct gate_descriptor *ip;
- int idx, quit;
- uintptr_t func;
-
- ip = idt;
- db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
- for (idx = 0, quit = 0; idx < NIDT; idx++) {
- func = (ip->gd_hioffset << 16 | ip->gd_looffset);
- if (func != (uintptr_t)&IDTVEC(rsvd)) {
- db_printf("%3d\t", idx);
- db_printsym(func, DB_STGY_PROC);
- db_printf("\n");
- }
- ip++;
- }
-}
-#endif
-
-void
-sdtossd(sd, ssd)
- struct segment_descriptor *sd;
- struct soft_segment_descriptor *ssd;
-{
- ssd->ssd_base = (sd->sd_hibase << 24) | sd->sd_lobase;
- ssd->ssd_limit = (sd->sd_hilimit << 16) | sd->sd_lolimit;
- ssd->ssd_type = sd->sd_type;
- ssd->ssd_dpl = sd->sd_dpl;
- ssd->ssd_p = sd->sd_p;
- ssd->ssd_def32 = sd->sd_def32;
- ssd->ssd_gran = sd->sd_gran;
-}
-
-#define PHYSMAP_SIZE (2 * 8)
-
-/*
- * Populate the (physmap) array with base/bound pairs describing the
- * available physical memory in the system, then test this memory and
- * build the phys_avail array describing the actually-available memory.
- *
- * If we cannot accurately determine the physical memory map, then use
- * value from the 0xE801 call, and failing that, the RTC.
- *
- * Total memory size may be set by the kernel environment variable
- * hw.physmem or the compile-time define MAXMEM.
- *
- * XXX first should be vm_paddr_t.
- */
-static void
-getmemsize(int first)
-{
- int i, physmap_idx, pa_indx, pg_n;
- u_long physmem_tunable;
- u_int extmem, under16;
- vm_offset_t pa, physmap[PHYSMAP_SIZE];
- pt_entry_t *pte;
- quad_t dcons_addr, dcons_size;
-
- /* XXX - some of EPSON machines can't use PG_N */
- pg_n = PG_N;
- if (pc98_machine_type & M_EPSON_PC98) {
- switch (epson_machine_id) {
-#ifdef WB_CACHE
- default:
-#endif
- case 0x34: /* PC-486HX */
- case 0x35: /* PC-486HG */
- case 0x3B: /* PC-486HA */
- pg_n = 0;
- break;
- }
- }
- bzero(physmap, sizeof(physmap));
-
- /*
- * Perform "base memory" related probes & setup
- */
- under16 = pc98_getmemsize(&basemem, &extmem);
- if (basemem > 640) {
- printf("Preposterous BIOS basemem of %uK, truncating to 640K\n",
- basemem);
- basemem = 640;
- }
-
- /*
- * XXX if biosbasemem is now < 640, there is a `hole'
- * between the end of base memory and the start of
- * ISA memory. The hole may be empty or it may
- * contain BIOS code or data. Map it read/write so
- * that the BIOS can write to it. (Memory from 0 to
- * the physical end of the kernel is mapped read-only
- * to begin with and then parts of it are remapped.
- * The parts that aren't remapped form holes that
- * remain read-only and are unused by the kernel.
- * The base memory area is below the physical end of
- * the kernel and right now forms a read-only hole.
- * The part of it from PAGE_SIZE to
- * (trunc_page(biosbasemem * 1024) - 1) will be
- * remapped and used by the kernel later.)
- *
- * This code is similar to the code used in
- * pmap_mapdev, but since no memory needs to be
- * allocated we simply change the mapping.
- */
- for (pa = trunc_page(basemem * 1024);
- pa < ISA_HOLE_START; pa += PAGE_SIZE)
- pmap_kenter(KERNBASE + pa, pa);
-
- /*
- * if basemem != 640, map pages r/w into vm86 page table so
- * that the bios can scribble on it.
- */
- pte = (pt_entry_t *)vm86paddr;
- for (i = basemem / 4; i < 160; i++)
- pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U;
-
- physmap[0] = 0;
- physmap[1] = basemem * 1024;
- physmap_idx = 2;
- physmap[physmap_idx] = 0x100000;
- physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
-
- /*
- * Now, physmap contains a map of physical memory.
- */
-
-#ifdef SMP
- /* make hole for AP bootstrap code */
- physmap[1] = mp_bootaddress(physmap[1]);
-#endif
-
- /*
- * Maxmem isn't the "maximum memory", it's one larger than the
- * highest page of the physical address space. It should be
- * called something like "Maxphyspage". We may adjust this
- * based on ``hw.physmem'' and the results of the memory test.
- */
- Maxmem = atop(physmap[physmap_idx + 1]);
-
-#ifdef MAXMEM
- Maxmem = MAXMEM / 4;
-#endif
-
- if (TUNABLE_ULONG_FETCH("hw.physmem", &physmem_tunable))
- Maxmem = atop(physmem_tunable);
-
- if (atop(physmap[physmap_idx + 1]) != Maxmem &&
- (boothowto & RB_VERBOSE))
- printf("Physical memory use set to %ldK\n", Maxmem * 4);
-
- /*
- * If Maxmem has been increased beyond what the system has detected,
- * extend the last memory segment to the new limit.
- */
- if (atop(physmap[physmap_idx + 1]) < Maxmem)
- physmap[physmap_idx + 1] = ptoa((vm_paddr_t)Maxmem);
-
- /*
- * We need to divide chunk if Maxmem is larger than 16MB and
- * under 16MB area is not full of memory.
- * (1) system area (15-16MB region) is cut off
- * (2) extended memory is only over 16MB area (ex. Melco "HYPERMEMORY")
- */
- if ((under16 != 16 * 1024) && (extmem > 15 * 1024)) {
- /* 15M - 16M region is cut off, so need to divide chunk */
- physmap[physmap_idx + 1] = under16 * 1024;
- physmap_idx += 2;
- physmap[physmap_idx] = 0x1000000;
- physmap[physmap_idx + 1] = physmap[2] + extmem * 1024;
- }
-
- /* call pmap initialization to make new kernel address space */
- pmap_bootstrap(first, 0);
-
- /*
- * Size up each available chunk of physical memory.
- */
- physmap[0] = PAGE_SIZE; /* mask off page 0 */
- pa_indx = 0;
- phys_avail[pa_indx++] = physmap[0];
- phys_avail[pa_indx] = physmap[0];
- pte = CMAP1;
-
- /*
- * Get dcons buffer address
- */
- if (getenv_quad("dcons.addr", &dcons_addr) == 0 ||
- getenv_quad("dcons.size", &dcons_size) == 0)
- dcons_addr = 0;
-
- /*
- * physmap is in bytes, so when converting to page boundaries,
- * round up the start address and round down the end address.
- */
- for (i = 0; i <= physmap_idx; i += 2) {
- vm_paddr_t end;
-
- end = ptoa((vm_paddr_t)Maxmem);
- if (physmap[i + 1] < end)
- end = trunc_page(physmap[i + 1]);
- for (pa = round_page(physmap[i]); pa < end; pa += PAGE_SIZE) {
- int tmp, page_bad;
- int *ptr = (int *)CADDR1;
-
- /*
- * block out kernel memory as not available.
- */
- if (pa >= KERNLOAD && pa < first)
- continue;
-
- /*
- * block out dcons buffer
- */
- if (dcons_addr > 0
- && pa >= trunc_page(dcons_addr)
- && pa < dcons_addr + dcons_size)
- continue;
-
- page_bad = FALSE;
-
- /*
- * map page into kernel: valid, read/write,non-cacheable
- */
- *pte = pa | PG_V | PG_RW | pg_n;
- invltlb();
-
- tmp = *(int *)ptr;
- /*
- * Test for alternating 1's and 0's
- */
- *(volatile int *)ptr = 0xaaaaaaaa;
- if (*(volatile int *)ptr != 0xaaaaaaaa) {
- page_bad = TRUE;
- }
- /*
- * Test for alternating 0's and 1's
- */
- *(volatile int *)ptr = 0x55555555;
- if (*(volatile int *)ptr != 0x55555555) {
- page_bad = TRUE;
- }
- /*
- * Test for all 1's
- */
- *(volatile int *)ptr = 0xffffffff;
- if (*(volatile int *)ptr != 0xffffffff) {
- page_bad = TRUE;
- }
- /*
- * Test for all 0's
- */
- *(volatile int *)ptr = 0x0;
- if (*(volatile int *)ptr != 0x0) {
- page_bad = TRUE;
- }
- /*
- * Restore original value.
- */
- *(int *)ptr = tmp;
-
- /*
- * Adjust array of valid/good pages.
- */
- if (page_bad == TRUE) {
- continue;
- }
- /*
- * If this good page is a continuation of the
- * previous set of good pages, then just increase
- * the end pointer. Otherwise start a new chunk.
- * Note that "end" points one higher than end,
- * making the range >= start and < end.
- * If we're also doing a speculative memory
- * test and we at or past the end, bump up Maxmem
- * so that we keep going. The first bad page
- * will terminate the loop.
- */
- if (phys_avail[pa_indx] == pa) {
- phys_avail[pa_indx] += PAGE_SIZE;
- } else {
- pa_indx++;
- if (pa_indx == PHYS_AVAIL_ARRAY_END) {
- printf(
- "Too many holes in the physical address space, giving up\n");
- pa_indx--;
- break;
- }
- phys_avail[pa_indx++] = pa; /* start */
- phys_avail[pa_indx] = pa + PAGE_SIZE; /* end */
- }
- physmem++;
- }
- }
- *pte = 0;
- invltlb();
-
- /*
- * XXX
- * The last chunk must contain at least one page plus the message
- * buffer to avoid complicating other code (message buffer address
- * calculation, etc.).
- */
- while (phys_avail[pa_indx - 1] + PAGE_SIZE +
- round_page(MSGBUF_SIZE) >= phys_avail[pa_indx]) {
- physmem -= atop(phys_avail[pa_indx] - phys_avail[pa_indx - 1]);
- phys_avail[pa_indx--] = 0;
- phys_avail[pa_indx--] = 0;
- }
-
- Maxmem = atop(phys_avail[pa_indx]);
-
- /* Trim off space for the message buffer. */
- phys_avail[pa_indx] -= round_page(MSGBUF_SIZE);
-
- avail_end = phys_avail[pa_indx];
-}
-
-void
-init386(first)
- int first;
-{
- struct gate_descriptor *gdp;
- int gsel_tss, metadata_missing, off, x;
- struct pcpu *pc;
-
- thread0.td_kstack = proc0kstack;
- thread0.td_pcb = (struct pcb *)
- (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
-
- /*
- * This may be done better later if it gets more high level
- * components in it. If so just link td->td_proc here.
- */
- proc_linkup(&proc0, &ksegrp0, &thread0);
-
- /*
- * Initialize DMAC
- */
- pc98_init_dmac();
-
- metadata_missing = 0;
- if (bootinfo.bi_modulep) {
- preload_metadata = (caddr_t)bootinfo.bi_modulep + KERNBASE;
- preload_bootstrap_relocate(KERNBASE);
- } else {
- metadata_missing = 1;
- }
- if (envmode == 1)
- kern_envp = static_env;
- else if (bootinfo.bi_envp)
- kern_envp = (caddr_t)bootinfo.bi_envp + KERNBASE;
-
- /* Init basic tunables, hz etc */
- init_param1();
-
- /*
- * Make gdt memory segments. All segments cover the full 4GB
- * of address space and permissions are enforced at page level.
- */
- gdt_segs[GCODE_SEL].ssd_limit = atop(0 - 1);
- gdt_segs[GDATA_SEL].ssd_limit = atop(0 - 1);
- gdt_segs[GUCODE_SEL].ssd_limit = atop(0 - 1);
- gdt_segs[GUDATA_SEL].ssd_limit = atop(0 - 1);
- gdt_segs[GUFS_SEL].ssd_limit = atop(0 - 1);
- gdt_segs[GUGS_SEL].ssd_limit = atop(0 - 1);
-
-#ifdef SMP
- pc = &SMP_prvspace[0].pcpu;
-#else
- pc = &__pcpu;
-#endif
- gdt_segs[GPRIV_SEL].ssd_limit = atop(0 - 1);
- gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
- gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
-
- for (x = 0; x < NGDT; x++)
- ssdtosd(&gdt_segs[x], &gdt[x].sd);
-
- r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
- r_gdt.rd_base = (int) gdt;
- lgdt(&r_gdt);
-
- pcpu_init(pc, 0, sizeof(struct pcpu));
- PCPU_SET(prvspace, pc);
- PCPU_SET(curthread, &thread0);
- PCPU_SET(curpcb, thread0.td_pcb);
-
- /*
- * Initialize mutexes.
- *
- * icu_lock: in order to allow an interrupt to occur in a critical
- * section, to set pcpu->ipending (etc...) properly, we
- * must be able to get the icu lock, so it can't be
- * under witness.
- */
- mutex_init();
- mtx_init(&clock_lock, "clk", NULL, MTX_SPIN);
- mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS);
-
- /* make ldt memory segments */
- ldt_segs[LUCODE_SEL].ssd_limit = atop(0 - 1);
- ldt_segs[LUDATA_SEL].ssd_limit = atop(0 - 1);
- for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++)
- ssdtosd(&ldt_segs[x], &ldt[x].sd);
-
- _default_ldt = GSEL(GLDT_SEL, SEL_KPL);
- lldt(_default_ldt);
- PCPU_SET(currentldt, _default_ldt);
-
- /* exceptions */
- for (x = 0; x < NIDT; x++)
- setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_DE, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_DB, &IDTVEC(dbg), SDT_SYS386IGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_NMI, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_BP, &IDTVEC(bpt), SDT_SYS386IGT, SEL_UPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_OF, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_BR, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_NM, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL
- , GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_DF, 0, SDT_SYSTASKGT, SEL_KPL, GSEL(GPANIC_SEL, SEL_KPL));
- setidt(IDT_FPUGP, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_TS, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_NP, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_SS, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_PF, &IDTVEC(page), SDT_SYS386IGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_MF, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_AC, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_MC, &IDTVEC(mchk), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_XF, &IDTVEC(xmm), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_SYSCALL, &IDTVEC(int0x80_syscall), SDT_SYS386TGT, SEL_UPL,
- GSEL(GCODE_SEL, SEL_KPL));
-
- r_idt.rd_limit = sizeof(idt0) - 1;
- r_idt.rd_base = (int) idt;
- lidt(&r_idt);
-
- /*
- * Initialize the console before we print anything out.
- */
- cninit();
-
- if (metadata_missing)
- printf("WARNING: loader(8) metadata is missing!\n");
-
-#ifdef DEV_ISA
- atpic_startup();
-#endif
-
-#ifdef DDB
- ksym_start = bootinfo.bi_symtab;
- ksym_end = bootinfo.bi_esymtab;
-#endif
-
- kdb_init();
-
-#ifdef KDB
- if (boothowto & RB_KDB)
- kdb_enter("Boot flags requested debugger");
-#endif
-
- finishidentcpu(); /* Final stage of CPU initialization */
- setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- initializecpu(); /* Initialize CPU registers */
-
- /* make an initial tss so cpu can get interrupt stack on syscall! */
- /* Note: -16 is so we can grow the trapframe if we came from vm86 */
- PCPU_SET(common_tss.tss_esp0, thread0.td_kstack +
- KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
- PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
- gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
- private_tss = 0;
- PCPU_SET(tss_gdt, &gdt[GPROC0_SEL].sd);
- PCPU_SET(common_tssd, *PCPU_GET(tss_gdt));
- PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16);
- ltr(gsel_tss);
-
- /* pointer to selector slot for %fs/%gs */
- PCPU_SET(fsgs_gdt, &gdt[GUFS_SEL].sd);
-
- dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 =
- dblfault_tss.tss_esp2 = (int)&dblfault_stack[sizeof(dblfault_stack)];
- dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 =
- dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL);
- dblfault_tss.tss_cr3 = (int)IdlePTD;
- dblfault_tss.tss_eip = (int)dblfault_handler;
- dblfault_tss.tss_eflags = PSL_KERNEL;
- dblfault_tss.tss_ds = dblfault_tss.tss_es =
- dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL);
- dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL);
- dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL);
- dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
-
- vm86_initialize();
- getmemsize(first);
- init_param2(physmem);
-
- /* now running on new page tables, configured,and u/iom is accessible */
-
- /* Map the message buffer. */
- for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE)
- pmap_kenter((vm_offset_t)msgbufp + off, avail_end + off);
-
- msgbufinit(msgbufp, MSGBUF_SIZE);
-
- /* make a call gate to reenter kernel with */
- gdp = &ldt[LSYS5CALLS_SEL].gd;
-
- x = (int) &IDTVEC(lcall_syscall);
- gdp->gd_looffset = x;
- gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL);
- gdp->gd_stkcpy = 1;
- gdp->gd_type = SDT_SYS386CGT;
- gdp->gd_dpl = SEL_UPL;
- gdp->gd_p = 1;
- gdp->gd_hioffset = x >> 16;
-
- /* XXX does this work? */
- /* XXX yes! */
- ldt[LBSDICALLS_SEL] = ldt[LSYS5CALLS_SEL];
- ldt[LSOL26CALLS_SEL] = ldt[LSYS5CALLS_SEL];
-
- /* transfer to user mode */
-
- _ucodesel = GSEL(GUCODE_SEL, SEL_UPL);
- _udatasel = GSEL(GUDATA_SEL, SEL_UPL);
-
- /* setup proc 0's pcb */
- thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
- thread0.td_pcb->pcb_cr3 = (int)IdlePTD;
- thread0.td_pcb->pcb_ext = 0;
- thread0.td_frame = &proc0_tf;
-}
-
-void
-cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
-{
-
-}
-
-void
-spinlock_enter(void)
-{
- struct thread *td;
-
- td = curthread;
- if (td->td_md.md_spinlock_count == 0)
- td->td_md.md_saved_flags = intr_disable();
- td->td_md.md_spinlock_count++;
- critical_enter();
-}
-
-void
-spinlock_exit(void)
-{
- struct thread *td;
-
- td = curthread;
- critical_exit();
- td->td_md.md_spinlock_count--;
- if (td->td_md.md_spinlock_count == 0)
- intr_restore(td->td_md.md_saved_flags);
-}
-
-#if defined(I586_CPU) && !defined(NO_F00F_HACK)
-static void f00f_hack(void *unused);
-SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL)
-
-static void
-f00f_hack(void *unused)
-{
- struct gate_descriptor *new_idt;
- vm_offset_t tmp;
-
- if (!has_f00f_bug)
- return;
-
- GIANT_REQUIRED;
-
- printf("Intel Pentium detected, installing workaround for F00F bug\n");
-
- tmp = kmem_alloc(kernel_map, PAGE_SIZE * 2);
- if (tmp == 0)
- panic("kmem_alloc returned 0");
-
- /* Put the problematic entry (#6) at the end of the lower page. */
- new_idt = (struct gate_descriptor*)
- (tmp + PAGE_SIZE - 7 * sizeof(struct gate_descriptor));
- bcopy(idt, new_idt, sizeof(idt0));
- r_idt.rd_base = (u_int)new_idt;
- lidt(&r_idt);
- idt = new_idt;
- if (vm_map_protect(kernel_map, tmp, tmp + PAGE_SIZE,
- VM_PROT_READ, FALSE) != KERN_SUCCESS)
- panic("vm_map_protect failed");
-}
-#endif /* defined(I586_CPU) && !NO_F00F_HACK */
-
-/*
- * Construct a PCB from a trapframe. This is called from kdb_trap() where
- * we want to start a backtrace from the function that caused us to enter
- * the debugger. We have the context in the trapframe, but base the trace
- * on the PCB. The PCB doesn't have to be perfect, as long as it contains
- * enough for a backtrace.
- */
-void
-makectx(struct trapframe *tf, struct pcb *pcb)
-{
-
- pcb->pcb_edi = tf->tf_edi;
- pcb->pcb_esi = tf->tf_esi;
- pcb->pcb_ebp = tf->tf_ebp;
- pcb->pcb_ebx = tf->tf_ebx;
- pcb->pcb_eip = tf->tf_eip;
- pcb->pcb_esp = (ISPL(tf->tf_cs)) ? tf->tf_esp : (int)(tf + 1) - 8;
-}
-
-int
-ptrace_set_pc(struct thread *td, u_long addr)
-{
-
- td->td_frame->tf_eip = addr;
- return (0);
-}
-
-int
-ptrace_single_step(struct thread *td)
-{
- td->td_frame->tf_eflags |= PSL_T;
- return (0);
-}
-
-int
-ptrace_clear_single_step(struct thread *td)
-{
- td->td_frame->tf_eflags &= ~PSL_T;
- return (0);
-}
-
-int
-fill_regs(struct thread *td, struct reg *regs)
-{
- struct pcb *pcb;
- struct trapframe *tp;
-
- tp = td->td_frame;
- regs->r_fs = tp->tf_fs;
- regs->r_es = tp->tf_es;
- regs->r_ds = tp->tf_ds;
- regs->r_edi = tp->tf_edi;
- regs->r_esi = tp->tf_esi;
- regs->r_ebp = tp->tf_ebp;
- regs->r_ebx = tp->tf_ebx;
- regs->r_edx = tp->tf_edx;
- regs->r_ecx = tp->tf_ecx;
- regs->r_eax = tp->tf_eax;
- regs->r_eip = tp->tf_eip;
- regs->r_cs = tp->tf_cs;
- regs->r_eflags = tp->tf_eflags;
- regs->r_esp = tp->tf_esp;
- regs->r_ss = tp->tf_ss;
- pcb = td->td_pcb;
- regs->r_gs = pcb->pcb_gs;
- return (0);
-}
-
-int
-set_regs(struct thread *td, struct reg *regs)
-{
- struct pcb *pcb;
- struct trapframe *tp;
-
- tp = td->td_frame;
- if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
- !CS_SECURE(regs->r_cs))
- return (EINVAL);
- tp->tf_fs = regs->r_fs;
- tp->tf_es = regs->r_es;
- tp->tf_ds = regs->r_ds;
- tp->tf_edi = regs->r_edi;
- tp->tf_esi = regs->r_esi;
- tp->tf_ebp = regs->r_ebp;
- tp->tf_ebx = regs->r_ebx;
- tp->tf_edx = regs->r_edx;
- tp->tf_ecx = regs->r_ecx;
- tp->tf_eax = regs->r_eax;
- tp->tf_eip = regs->r_eip;
- tp->tf_cs = regs->r_cs;
- tp->tf_eflags = regs->r_eflags;
- tp->tf_esp = regs->r_esp;
- tp->tf_ss = regs->r_ss;
- pcb = td->td_pcb;
- pcb->pcb_gs = regs->r_gs;
- return (0);
-}
-
-#ifdef CPU_ENABLE_SSE
-static void
-fill_fpregs_xmm(sv_xmm, sv_87)
- struct savexmm *sv_xmm;
- struct save87 *sv_87;
-{
- register struct env87 *penv_87 = &sv_87->sv_env;
- register struct envxmm *penv_xmm = &sv_xmm->sv_env;
- int i;
-
- bzero(sv_87, sizeof(*sv_87));
-
- /* FPU control/status */
- penv_87->en_cw = penv_xmm->en_cw;
- penv_87->en_sw = penv_xmm->en_sw;
- penv_87->en_tw = penv_xmm->en_tw;
- penv_87->en_fip = penv_xmm->en_fip;
- penv_87->en_fcs = penv_xmm->en_fcs;
- penv_87->en_opcode = penv_xmm->en_opcode;
- penv_87->en_foo = penv_xmm->en_foo;
- penv_87->en_fos = penv_xmm->en_fos;
-
- /* FPU registers */
- for (i = 0; i < 8; ++i)
- sv_87->sv_ac[i] = sv_xmm->sv_fp[i].fp_acc;
-}
-
-static void
-set_fpregs_xmm(sv_87, sv_xmm)
- struct save87 *sv_87;
- struct savexmm *sv_xmm;
-{
- register struct env87 *penv_87 = &sv_87->sv_env;
- register struct envxmm *penv_xmm = &sv_xmm->sv_env;
- int i;
-
- /* FPU control/status */
- penv_xmm->en_cw = penv_87->en_cw;
- penv_xmm->en_sw = penv_87->en_sw;
- penv_xmm->en_tw = penv_87->en_tw;
- penv_xmm->en_fip = penv_87->en_fip;
- penv_xmm->en_fcs = penv_87->en_fcs;
- penv_xmm->en_opcode = penv_87->en_opcode;
- penv_xmm->en_foo = penv_87->en_foo;
- penv_xmm->en_fos = penv_87->en_fos;
-
- /* FPU registers */
- for (i = 0; i < 8; ++i)
- sv_xmm->sv_fp[i].fp_acc = sv_87->sv_ac[i];
-}
-#endif /* CPU_ENABLE_SSE */
-
-int
-fill_fpregs(struct thread *td, struct fpreg *fpregs)
-{
-#ifdef CPU_ENABLE_SSE
- if (cpu_fxsr) {
- fill_fpregs_xmm(&td->td_pcb->pcb_save.sv_xmm,
- (struct save87 *)fpregs);
- return (0);
- }
-#endif /* CPU_ENABLE_SSE */
- bcopy(&td->td_pcb->pcb_save.sv_87, fpregs, sizeof *fpregs);
- return (0);
-}
-
-int
-set_fpregs(struct thread *td, struct fpreg *fpregs)
-{
-#ifdef CPU_ENABLE_SSE
- if (cpu_fxsr) {
- set_fpregs_xmm((struct save87 *)fpregs,
- &td->td_pcb->pcb_save.sv_xmm);
- return (0);
- }
-#endif /* CPU_ENABLE_SSE */
- bcopy(fpregs, &td->td_pcb->pcb_save.sv_87, sizeof *fpregs);
- return (0);
-}
-
-/*
- * Get machine context.
- */
-int
-get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
-{
- struct trapframe *tp;
-
- tp = td->td_frame;
-
- PROC_LOCK(curthread->td_proc);
- mcp->mc_onstack = sigonstack(tp->tf_esp);
- PROC_UNLOCK(curthread->td_proc);
- mcp->mc_gs = td->td_pcb->pcb_gs;
- mcp->mc_fs = tp->tf_fs;
- mcp->mc_es = tp->tf_es;
- mcp->mc_ds = tp->tf_ds;
- mcp->mc_edi = tp->tf_edi;
- mcp->mc_esi = tp->tf_esi;
- mcp->mc_ebp = tp->tf_ebp;
- mcp->mc_isp = tp->tf_isp;
- if (flags & GET_MC_CLEAR_RET) {
- mcp->mc_eax = 0;
- mcp->mc_edx = 0;
- } else {
- mcp->mc_eax = tp->tf_eax;
- mcp->mc_edx = tp->tf_edx;
- }
- mcp->mc_ebx = tp->tf_ebx;
- mcp->mc_ecx = tp->tf_ecx;
- mcp->mc_eip = tp->tf_eip;
- mcp->mc_cs = tp->tf_cs;
- mcp->mc_eflags = tp->tf_eflags;
- mcp->mc_esp = tp->tf_esp;
- mcp->mc_ss = tp->tf_ss;
- mcp->mc_len = sizeof(*mcp);
- get_fpcontext(td, mcp);
- return (0);
-}
-
-/*
- * Set machine context.
- *
- * However, we don't set any but the user modifiable flags, and we won't
- * touch the cs selector.
- */
-int
-set_mcontext(struct thread *td, const mcontext_t *mcp)
-{
- struct trapframe *tp;
- int eflags, ret;
-
- tp = td->td_frame;
- if (mcp->mc_len != sizeof(*mcp))
- return (EINVAL);
- eflags = (mcp->mc_eflags & PSL_USERCHANGE) |
- (tp->tf_eflags & ~PSL_USERCHANGE);
- if ((ret = set_fpcontext(td, mcp)) == 0) {
- tp->tf_fs = mcp->mc_fs;
- tp->tf_es = mcp->mc_es;
- tp->tf_ds = mcp->mc_ds;
- tp->tf_edi = mcp->mc_edi;
- tp->tf_esi = mcp->mc_esi;
- tp->tf_ebp = mcp->mc_ebp;
- tp->tf_ebx = mcp->mc_ebx;
- tp->tf_edx = mcp->mc_edx;
- tp->tf_ecx = mcp->mc_ecx;
- tp->tf_eax = mcp->mc_eax;
- tp->tf_eip = mcp->mc_eip;
- tp->tf_eflags = eflags;
- tp->tf_esp = mcp->mc_esp;
- tp->tf_ss = mcp->mc_ss;
- td->td_pcb->pcb_gs = mcp->mc_gs;
- ret = 0;
- }
- return (ret);
-}
-
-static void
-get_fpcontext(struct thread *td, mcontext_t *mcp)
-{
-#ifndef DEV_NPX
- mcp->mc_fpformat = _MC_FPFMT_NODEV;
- mcp->mc_ownedfp = _MC_FPOWNED_NONE;
-#else
- union savefpu *addr;
-
- /*
- * XXX mc_fpstate might be misaligned, since its declaration is not
- * unportabilized using __attribute__((aligned(16))) like the
- * declaration of struct savemm, and anyway, alignment doesn't work
- * for auto variables since we don't use gcc's pessimal stack
- * alignment. Work around this by abusing the spare fields after
- * mcp->mc_fpstate.
- *
- * XXX unpessimize most cases by only aligning when fxsave might be
- * called, although this requires knowing too much about
- * npxgetregs()'s internals.
- */
- addr = (union savefpu *)&mcp->mc_fpstate;
- if (td == PCPU_GET(fpcurthread) &&
-#ifdef CPU_ENABLE_SSE
- cpu_fxsr &&
-#endif
- ((uintptr_t)(void *)addr & 0xF)) {
- do
- addr = (void *)((char *)addr + 4);
- while ((uintptr_t)(void *)addr & 0xF);
- }
- mcp->mc_ownedfp = npxgetregs(td, addr);
- if (addr != (union savefpu *)&mcp->mc_fpstate) {
- bcopy(addr, &mcp->mc_fpstate, sizeof(mcp->mc_fpstate));
- bzero(&mcp->mc_spare2, sizeof(mcp->mc_spare2));
- }
- mcp->mc_fpformat = npxformat();
-#endif
-}
-
-static int
-set_fpcontext(struct thread *td, const mcontext_t *mcp)
-{
- union savefpu *addr;
-
- if (mcp->mc_fpformat == _MC_FPFMT_NODEV)
- return (0);
- else if (mcp->mc_fpformat != _MC_FPFMT_387 &&
- mcp->mc_fpformat != _MC_FPFMT_XMM)
- return (EINVAL);
- else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE)
- /* We don't care what state is left in the FPU or PCB. */
- fpstate_drop(td);
- else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU ||
- mcp->mc_ownedfp == _MC_FPOWNED_PCB) {
- /* XXX align as above. */
- addr = (union savefpu *)&mcp->mc_fpstate;
- if (td == PCPU_GET(fpcurthread) &&
-#ifdef CPU_ENABLE_SSE
- cpu_fxsr &&
-#endif
- ((uintptr_t)(void *)addr & 0xF)) {
- do
- addr = (void *)((char *)addr + 4);
- while ((uintptr_t)(void *)addr & 0xF);
- bcopy(&mcp->mc_fpstate, addr, sizeof(mcp->mc_fpstate));
- }
-#ifdef DEV_NPX
- /*
- * XXX we violate the dubious requirement that npxsetregs()
- * be called with interrupts disabled.
- */
- npxsetregs(td, addr);
-#endif
- /*
- * Don't bother putting things back where they were in the
- * misaligned case, since we know that the caller won't use
- * them again.
- */
- } else
- return (EINVAL);
- return (0);
-}
-
-static void
-fpstate_drop(struct thread *td)
-{
- register_t s;
-
- s = intr_disable();
-#ifdef DEV_NPX
- if (PCPU_GET(fpcurthread) == td)
- npxdrop();
-#endif
- /*
- * XXX force a full drop of the npx. The above only drops it if we
- * owned it. npxgetregs() has the same bug in the !cpu_fxsr case.
- *
- * XXX I don't much like npxgetregs()'s semantics of doing a full
- * drop. Dropping only to the pcb matches fnsave's behaviour.
- * We only need to drop to !PCB_INITDONE in sendsig(). But
- * sendsig() is the only caller of npxgetregs()... perhaps we just
- * have too many layers.
- */
- curthread->td_pcb->pcb_flags &= ~PCB_NPXINITDONE;
- intr_restore(s);
-}
-
-int
-fill_dbregs(struct thread *td, struct dbreg *dbregs)
-{
- struct pcb *pcb;
-
- if (td == NULL) {
- dbregs->dr[0] = rdr0();
- dbregs->dr[1] = rdr1();
- dbregs->dr[2] = rdr2();
- dbregs->dr[3] = rdr3();
- dbregs->dr[4] = rdr4();
- dbregs->dr[5] = rdr5();
- dbregs->dr[6] = rdr6();
- dbregs->dr[7] = rdr7();
- } else {
- pcb = td->td_pcb;
- dbregs->dr[0] = pcb->pcb_dr0;
- dbregs->dr[1] = pcb->pcb_dr1;
- dbregs->dr[2] = pcb->pcb_dr2;
- dbregs->dr[3] = pcb->pcb_dr3;
- dbregs->dr[4] = 0;
- dbregs->dr[5] = 0;
- dbregs->dr[6] = pcb->pcb_dr6;
- dbregs->dr[7] = pcb->pcb_dr7;
- }
- return (0);
-}
-
-int
-set_dbregs(struct thread *td, struct dbreg *dbregs)
-{
- struct pcb *pcb;
- int i;
- u_int32_t mask1, mask2;
-
- if (td == NULL) {
- load_dr0(dbregs->dr[0]);
- load_dr1(dbregs->dr[1]);
- load_dr2(dbregs->dr[2]);
- load_dr3(dbregs->dr[3]);
- load_dr4(dbregs->dr[4]);
- load_dr5(dbregs->dr[5]);
- load_dr6(dbregs->dr[6]);
- load_dr7(dbregs->dr[7]);
- } else {
- /*
- * Don't let an illegal value for dr7 get set. Specifically,
- * check for undefined settings. Setting these bit patterns
- * result in undefined behaviour and can lead to an unexpected
- * TRCTRAP.
- */
- for (i = 0, mask1 = 0x3<<16, mask2 = 0x2<<16; i < 8;
- i++, mask1 <<= 2, mask2 <<= 2)
- if ((dbregs->dr[7] & mask1) == mask2)
- return (EINVAL);
-
- pcb = td->td_pcb;
-
- /*
- * Don't let a process set a breakpoint that is not within the
- * process's address space. If a process could do this, it
- * could halt the system by setting a breakpoint in the kernel
- * (if ddb was enabled). Thus, we need to check to make sure
- * that no breakpoints are being enabled for addresses outside
- * process's address space, unless, perhaps, we were called by
- * uid 0.
- *
- * XXX - what about when the watched area of the user's
- * address space is written into from within the kernel
- * ... wouldn't that still cause a breakpoint to be generated
- * from within kernel mode?
- */
-
- if (suser(td) != 0) {
- if (dbregs->dr[7] & 0x3) {
- /* dr0 is enabled */
- if (dbregs->dr[0] >= VM_MAXUSER_ADDRESS)
- return (EINVAL);
- }
-
- if (dbregs->dr[7] & (0x3<<2)) {
- /* dr1 is enabled */
- if (dbregs->dr[1] >= VM_MAXUSER_ADDRESS)
- return (EINVAL);
- }
-
- if (dbregs->dr[7] & (0x3<<4)) {
- /* dr2 is enabled */
- if (dbregs->dr[2] >= VM_MAXUSER_ADDRESS)
- return (EINVAL);
- }
-
- if (dbregs->dr[7] & (0x3<<6)) {
- /* dr3 is enabled */
- if (dbregs->dr[3] >= VM_MAXUSER_ADDRESS)
- return (EINVAL);
- }
- }
-
- pcb->pcb_dr0 = dbregs->dr[0];
- pcb->pcb_dr1 = dbregs->dr[1];
- pcb->pcb_dr2 = dbregs->dr[2];
- pcb->pcb_dr3 = dbregs->dr[3];
- pcb->pcb_dr6 = dbregs->dr[6];
- pcb->pcb_dr7 = dbregs->dr[7];
-
- pcb->pcb_flags |= PCB_DBREGS;
- }
-
- return (0);
-}
-
-/*
- * Return > 0 if a hardware breakpoint has been hit, and the
- * breakpoint was in user space. Return 0, otherwise.
- */
-int
-user_dbreg_trap(void)
-{
- u_int32_t dr7, dr6; /* debug registers dr6 and dr7 */
- u_int32_t bp; /* breakpoint bits extracted from dr6 */
- int nbp; /* number of breakpoints that triggered */
- caddr_t addr[4]; /* breakpoint addresses */
- int i;
-
- dr7 = rdr7();
- if ((dr7 & 0x000000ff) == 0) {
- /*
- * all GE and LE bits in the dr7 register are zero,
- * thus the trap couldn't have been caused by the
- * hardware debug registers
- */
- return 0;
- }
-
- nbp = 0;
- dr6 = rdr6();
- bp = dr6 & 0x0000000f;
-
- if (!bp) {
- /*
- * None of the breakpoint bits are set meaning this
- * trap was not caused by any of the debug registers
- */
- return 0;
- }
-
- /*
- * at least one of the breakpoints were hit, check to see
- * which ones and if any of them are user space addresses
- */
-
- if (bp & 0x01) {
- addr[nbp++] = (caddr_t)rdr0();
- }
- if (bp & 0x02) {
- addr[nbp++] = (caddr_t)rdr1();
- }
- if (bp & 0x04) {
- addr[nbp++] = (caddr_t)rdr2();
- }
- if (bp & 0x08) {
- addr[nbp++] = (caddr_t)rdr3();
- }
-
- for (i=0; i<nbp; i++) {
- if (addr[i] <
- (caddr_t)VM_MAXUSER_ADDRESS) {
- /*
- * addr[i] is in user space
- */
- return nbp;
- }
- }
-
- /*
- * None of the breakpoints are in user space.
- */
- return 0;
-}
-
-#ifdef KDB
-
-/*
- * Provide inb() and outb() as functions. They are normally only
- * available as macros calling inlined functions, thus cannot be
- * called from the debugger.
- *
- * The actual code is stolen from <machine/cpufunc.h>, and de-inlined.
- */
-
-#undef inb
-#undef outb
-
-/* silence compiler warnings */
-u_char inb(u_int);
-void outb(u_int, u_char);
-
-u_char
-inb(u_int port)
-{
- u_char data;
- /*
- * We use %%dx and not %1 here because i/o is done at %dx and not at
- * %edx, while gcc generates inferior code (movw instead of movl)
- * if we tell it to load (u_short) port.
- */
- __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
- return (data);
-}
-
-void
-outb(u_int port, u_char data)
-{
- u_char al;
- /*
- * Use an unnecessary assignment to help gcc's register allocator.
- * This make a large difference for gcc-1.40 and a tiny difference
- * for gcc-2.6.0. For gcc-1.40, al had to be ``asm("ax")'' for
- * best results. gcc-2.6.0 can't handle this.
- */
- al = data;
- __asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
-}
-
-#endif /* KDB */
diff --git a/sys/pc98/pc98/30line.h b/sys/pc98/pc98/30line.h
deleted file mode 100644
index c2e0f10..0000000
--- a/sys/pc98/pc98/30line.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*-
- * Copyright (c) 1994, 1995, 1996. FreeBSD(98) porting team.
- * 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.
- *
- * $FreeBSD$
- */
-
-#ifndef __PC98_PC98_30LINE_H__
-#define __PC98_PC98_30LINE_H__
-
-#define LINE30_ROW 30
-#define _HS 1 + 1
-#define _VS 2
-#define _HFP 3 + 1
-#define _HBP 14 + 1
-#define _VFP 11
-#define _VBP 44
-
-#define _CR 80
-#define _LF LINE30_ROW*16
-
-#define _GDC_RESET 0x00
-#define _GDC_SYNC 0x0e
-#define _GDC_MASTER 0x6f
-#define _GDC_SLAVE 0x6e
-#define _GDC_START 0x0d
-#define _GDC_STOP 0x0c
-#define _GDC_SCROLL 0x70
-#define _GDC_PITCH 0x47
-
-#define GDC_CR 0
-#define GDC_VS 1
-#define GDC_HS 2
-#define GDC_HFP 3
-#define GDC_HBP 4
-#define GDC_VFP 5
-#define GDC_VBP 6
-#define GDC_LF 7
-
-
-#define _24KHZ 0
-#define _31KHZ 1
-
-#define _2_5MHZ 0
-#define _5MHZ 1
-
-#define _25L 0
-#define _30L 1
-
-#define T25_G400 0
-#define T30_G400 1
-#define T30_G480 2
-
-static void master_gdc_cmd(unsigned int);
-static void master_gdc_prm(unsigned int);
-static void master_gdc_word_prm(unsigned int);
-#ifdef LINE30
-static void master_gdc_fifo_empty(void);
-#endif
-static void master_gdc_wait_vsync(void);
-
-static void gdc_cmd(unsigned int);
-#ifdef LINE30
-static void gdc_prm(unsigned int);
-static void gdc_word_prm(unsigned int);
-static void gdc_fifo_empty(void);
-#endif
-static void gdc_wait_vsync(void);
-
-#ifdef LINE30
-static int check_gdc_clock(void);
-
-static int gdc_INFO = _25L;
-#endif
-static int gdc_FH = _24KHZ;
-static void initialize_gdc(unsigned int, int);
-
-#ifdef LINE30
-static unsigned int master_param[2][2][8] = {
-{{78, 8, 7, 9, 7, 7, 25, 400}, /* 400/24k */
- {_CR-2, _VS, _HS-1, _HFP-1, _HBP-1, _VFP, _VBP, _LF}}, /* 480/24k */
-{{78, 2, 7, 3, 7, 13, 34, 400}, /* 400/31k */
- {78, 2, 11, 3, 3, 6, 37, 480}}}; /* 480/31k */
-
-static unsigned int slave_param[2][6][8] = {
-{{38, 8, 3, 4, 3, 7, 25, 400}, /* normal */
- {78, 8, 7, 9, 7, 7, 25, 400},
- {_CR/2-2, _VS, (_HS)/2-1, (_HFP)/2-1, (_HBP)/2-1,
- _VFP+(_LF-400)/2+8, _VBP+(_LF-400)/2-8, 400}, /* 30 & 400 */
- {_CR-2, _VS, _HS-1, _HFP-1, _HBP-1,
- _VFP+(_LF-400)/2+8, _VBP+(_LF-400)/2-8, 400},
- {_CR/2-2, _VS, (_HS)/2-1, (_HFP)/2-1, (_HBP)/2-1,
- _VFP, _VBP, _LF}, /* 30 & 480 */
- {_CR-2, _VS, _HS-1, _HFP-1, _HBP-1, _VFP, _VBP, _LF}},
-{{38, 2, 3, 1, 3, 13, 34, 400}, /* normal */
- {78, 2, 7, 3, 7, 13, 34, 400},
- {38, 2, 5, 1, 1, 6+48, 37+32, 400}, /* 30 & 400 */
- {78, 2, 11, 3, 3, 6+48, 37+32, 400},
- {38, 2, 5, 1, 1, 6, 37, 480}, /* 30 & 480 */
- {78, 2, 11, 3, 3, 6, 37, 480}}};
-
-static int SlavePCH[2] = {40,80};
-static int MasterPCH = 80;
-static int SlaveScrlLF[3] = {400,400,_LF};
-#endif
-
-#endif /* __PC98_PC98_30LINE_H__ */
diff --git a/sys/pc98/pc98/clock.c b/sys/pc98/pc98/clock.c
deleted file mode 100644
index 484e8df..0000000
--- a/sys/pc98/pc98/clock.c
+++ /dev/null
@@ -1,885 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz and Don Ahn.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 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: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $FreeBSD$
- */
-
-/*
- * Routines to handle clock hardware.
- */
-
-/*
- * inittodr, settodr and support routines written
- * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
- *
- * reintroduced and updated by Chris Stenton <chris@gnome.co.uk> 8/10/94
- */
-
-/*
- * modified for PC98 by Kakefuda
- */
-
-#include "opt_apic.h"
-#include "opt_clock.h"
-#include "opt_isa.h"
-#include "opt_mca.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/kdb.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/time.h>
-#include <sys/timetc.h>
-#include <sys/kernel.h>
-#include <sys/limits.h>
-#include <sys/module.h>
-#include <sys/sysctl.h>
-#include <sys/cons.h>
-#include <sys/power.h>
-
-#include <machine/clock.h>
-#include <machine/cputypes.h>
-#include <machine/frame.h>
-#include <machine/intr_machdep.h>
-#include <machine/md_var.h>
-#include <machine/psl.h>
-#ifdef DEV_APIC
-#include <machine/apicvar.h>
-#endif
-#include <machine/specialreg.h>
-
-#include <i386/isa/icu.h>
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/pc98_machdep.h>
-#ifdef DEV_ISA
-#include <isa/isavar.h>
-#endif
-#include <i386/isa/timerreg.h>
-
-/*
- * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
- * can use a simple formula for leap years.
- */
-#define LEAPYEAR(y) (((u_int)(y) % 4 == 0) ? 1 : 0)
-#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31)
-
-#define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
-
-int adjkerntz; /* local offset from GMT in seconds */
-int clkintr_pending;
-int disable_rtc_set; /* disable resettodr() if != 0 */
-int pscnt = 1;
-int psdiv = 1;
-int statclock_disable;
-#ifndef TIMER_FREQ
-#define TIMER_FREQ 2457600
-#endif
-u_int timer_freq = TIMER_FREQ;
-int timer0_max_count;
-int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
-struct mtx clock_lock;
-
-static int beeping = 0;
-static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
-static u_int hardclock_max_count;
-static struct intsrc *i8254_intsrc;
-static u_int32_t i8254_lastcount;
-static u_int32_t i8254_offset;
-static int (*i8254_pending)(struct intsrc *);
-static int i8254_ticked;
-static int using_lapic_timer;
-
-/* Values for timerX_state: */
-#define RELEASED 0
-#define RELEASE_PENDING 1
-#define ACQUIRED 2
-#define ACQUIRE_PENDING 3
-
-static u_char timer1_state;
-static u_char timer2_state;
-static void rtc_serialcombit(int);
-static void rtc_serialcom(int);
-static int rtc_inb(void);
-static void rtc_outb(int);
-
-static unsigned i8254_get_timecount(struct timecounter *tc);
-static void set_timer_freq(u_int freq, int intr_freq);
-
-static struct timecounter i8254_timecounter = {
- i8254_get_timecount, /* get_timecount */
- 0, /* no poll_pps */
- ~0u, /* counter_mask */
- 0, /* frequency */
- "i8254", /* name */
- 0 /* quality */
-};
-
-static void
-clkintr(struct clockframe *frame)
-{
-
- if (timecounter->tc_get_timecount == i8254_get_timecount) {
- mtx_lock_spin(&clock_lock);
- if (i8254_ticked)
- i8254_ticked = 0;
- else {
- i8254_offset += timer0_max_count;
- i8254_lastcount = 0;
- }
- clkintr_pending = 0;
- mtx_unlock_spin(&clock_lock);
- }
- if (!using_lapic_timer)
- hardclock(frame);
-}
-
-int
-acquire_timer1(int mode)
-{
-
- if (timer1_state != RELEASED)
- return (-1);
- timer1_state = ACQUIRED;
-
- /*
- * This access to the timer registers is as atomic as possible
- * because it is a single instruction. We could do better if we
- * knew the rate. Use of splclock() limits glitches to 10-100us,
- * and this is probably good enough for timer2, so we aren't as
- * careful with it as with timer0.
- */
- outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
-
- return (0);
-}
-
-int
-acquire_timer2(int mode)
-{
-
- if (timer2_state != RELEASED)
- return (-1);
- timer2_state = ACQUIRED;
-
- /*
- * This access to the timer registers is as atomic as possible
- * because it is a single instruction. We could do better if we
- * knew the rate. Use of splclock() limits glitches to 10-100us,
- * and this is probably good enough for timer2, so we aren't as
- * careful with it as with timer0.
- */
- outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
-
- return (0);
-}
-
-int
-release_timer1()
-{
-
- if (timer1_state != ACQUIRED)
- return (-1);
- timer1_state = RELEASED;
- outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
- return (0);
-}
-
-int
-release_timer2()
-{
-
- if (timer2_state != ACQUIRED)
- return (-1);
- timer2_state = RELEASED;
- outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
- return (0);
-}
-
-
-static int
-getit(void)
-{
- int high, low;
-
- mtx_lock_spin(&clock_lock);
-
- /* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
-
- low = inb(TIMER_CNTR0);
- high = inb(TIMER_CNTR0);
-
- mtx_unlock_spin(&clock_lock);
- return ((high << 8) | low);
-}
-
-/*
- * Wait "n" microseconds.
- * Relies on timer 1 counting down from (timer_freq / hz)
- * Note: timer had better have been programmed before this is first used!
- */
-void
-DELAY(int n)
-{
- int delta, prev_tick, tick, ticks_left;
-
-#ifdef DELAYDEBUG
- int getit_calls = 1;
- int n1;
- static int state = 0;
-
- if (state == 0) {
- state = 1;
- for (n1 = 1; n1 <= 10000000; n1 *= 10)
- DELAY(n1);
- state = 2;
- }
- if (state == 1)
- printf("DELAY(%d)...", n);
-#endif
- /*
- * Guard against the timer being uninitialized if we are called
- * early for console i/o.
- */
- if (timer0_max_count == 0)
- set_timer_freq(timer_freq, hz);
-
- /*
- * Read the counter first, so that the rest of the setup overhead is
- * counted. Guess the initial overhead is 20 usec (on most systems it
- * takes about 1.5 usec for each of the i/o's in getit(). The loop
- * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The
- * multiplications and divisions to scale the count take a while).
- *
- * However, if ddb is active then use a fake counter since reading
- * the i8254 counter involves acquiring a lock. ddb must not do
- * locking for many reasons, but it calls here for at least atkbd
- * input.
- */
-#ifdef KDB
- if (kdb_active)
- prev_tick = 1;
- else
-#endif
- prev_tick = getit();
- n -= 0; /* XXX actually guess no initial overhead */
- /*
- * Calculate (n * (timer_freq / 1e6)) without using floating point
- * and without any avoidable overflows.
- */
- if (n <= 0)
- ticks_left = 0;
- else if (n < 256)
- /*
- * Use fixed point to avoid a slow division by 1000000.
- * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
- * 2^15 is the first power of 2 that gives exact results
- * for n between 0 and 256.
- */
- ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
- else
- /*
- * Don't bother using fixed point, although gcc-2.7.2
- * generates particularly poor code for the long long
- * division, since even the slow way will complete long
- * before the delay is up (unless we're interrupted).
- */
- ticks_left = ((u_int)n * (long long)timer_freq + 999999)
- / 1000000;
-
- while (ticks_left > 0) {
-#ifdef KDB
- if (kdb_active) {
- outb(0x5f, 0);
- tick = prev_tick - 1;
- if (tick <= 0)
- tick = timer0_max_count;
- } else
-#endif
- tick = getit();
-#ifdef DELAYDEBUG
- ++getit_calls;
-#endif
- delta = prev_tick - tick;
- prev_tick = tick;
- if (delta < 0) {
- delta += timer0_max_count;
- /*
- * Guard against timer0_max_count being wrong.
- * This shouldn't happen in normal operation,
- * but it may happen if set_timer_freq() is
- * traced.
- */
- if (delta < 0)
- delta = 0;
- }
- ticks_left -= delta;
- }
-#ifdef DELAYDEBUG
- if (state == 1)
- printf(" %d calls to getit() at %d usec each\n",
- getit_calls, (n + 5) / getit_calls);
-#endif
-}
-
-static void
-sysbeepstop(void *chan)
-{
- outb(IO_PPI, inb(IO_PPI)|0x08); /* disable counter1 output to speaker */
- release_timer1();
- beeping = 0;
-}
-
-int
-sysbeep(int pitch, int period)
-{
- int x = splclock();
-
- if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
- if (!beeping) {
- /* Something else owns it. */
- splx(x);
- return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
- }
- disable_intr();
- outb(0x3fdb, pitch);
- outb(0x3fdb, (pitch>>8));
- enable_intr();
- if (!beeping) {
- /* enable counter1 output to speaker */
- outb(IO_PPI, (inb(IO_PPI) & 0xf7));
- beeping = period;
- timeout(sysbeepstop, (void *)NULL, period);
- }
- splx(x);
- return (0);
-}
-
-
-unsigned int delaycount;
-#define FIRST_GUESS 0x2000
-static void findcpuspeed(void)
-{
- int i;
- int remainder;
-
- /* Put counter in count down mode */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
- outb(TIMER_CNTR0, 0xff);
- outb(TIMER_CNTR0, 0xff);
- for (i = FIRST_GUESS; i; i--)
- ;
- remainder = getit();
- delaycount = (FIRST_GUESS * TIMER_DIV(1000)) / (0xffff - remainder);
-}
-
-static u_int
-calibrate_clocks(void)
-{
- int timeout;
- u_int count, prev_count, tot_count;
- u_short sec, start_sec;
-
- if (bootverbose)
- printf("Calibrating clock(s) ... ");
- /* Check ARTIC. */
- if (!(PC98_SYSTEM_PARAMETER(0x458) & 0x80) &&
- !(PC98_SYSTEM_PARAMETER(0x45b) & 0x04))
- goto fail;
- timeout = 100000000;
-
- /* Read the ARTIC. */
- sec = inw(0x5e);
-
- /* Wait for the ARTIC to changes. */
- start_sec = sec;
- for (;;) {
- sec = inw(0x5e);
- if (sec != start_sec)
- break;
- if (--timeout == 0)
- goto fail;
- }
- prev_count = getit();
- if (prev_count == 0 || prev_count > timer0_max_count)
- goto fail;
- tot_count = 0;
-
- start_sec = sec;
- for (;;) {
- sec = inw(0x5e);
- count = getit();
- if (count == 0 || count > timer0_max_count)
- goto fail;
- if (count > prev_count)
- tot_count += prev_count - (count - timer0_max_count);
- else
- tot_count += prev_count - count;
- prev_count = count;
- if ((sec == start_sec + 1200) || /* 1200 = 307.2KHz >> 8 */
- (sec < start_sec &&
- (u_int)sec + 0x10000 == (u_int)start_sec + 1200))
- break;
- if (--timeout == 0)
- goto fail;
- }
-
- if (bootverbose) {
- printf("i8254 clock: %u Hz\n", tot_count);
- }
- return (tot_count);
-
-fail:
- if (bootverbose)
- printf("failed, using default i8254 clock of %u Hz\n",
- timer_freq);
- return (timer_freq);
-}
-
-static void
-set_timer_freq(u_int freq, int intr_freq)
-{
- int new_timer0_max_count;
-
- mtx_lock_spin(&clock_lock);
- timer_freq = freq;
- new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
- if (new_timer0_max_count != timer0_max_count) {
- timer0_max_count = new_timer0_max_count;
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, timer0_max_count & 0xff);
- outb(TIMER_CNTR0, timer0_max_count >> 8);
- }
- mtx_unlock_spin(&clock_lock);
-}
-
-static void
-i8254_restore(void)
-{
-
- mtx_lock_spin(&clock_lock);
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, timer0_max_count & 0xff);
- outb(TIMER_CNTR0, timer0_max_count >> 8);
- mtx_unlock_spin(&clock_lock);
-}
-
-
-/*
- * Restore all the timers non-atomically (XXX: should be atomically).
- *
- * This function is called from pmtimer_resume() to restore all the timers.
- * This should not be necessary, but there are broken laptops that do not
- * restore all the timers on resume.
- */
-void
-timer_restore(void)
-{
-
- i8254_restore(); /* restore timer_freq and hz */
-}
-
-/*
- * Initialize 8254 timer 0 early so that it can be used in DELAY().
- * XXX initialization of other timers is unintentionally left blank.
- */
-void
-startrtclock()
-{
- u_int delta, freq;
-
- findcpuspeed();
- if (pc98_machine_type & M_8M)
- timer_freq = 1996800L; /* 1.9968 MHz */
- else
- timer_freq = 2457600L; /* 2.4576 MHz */
-
- set_timer_freq(timer_freq, hz);
- freq = calibrate_clocks();
-#ifdef CLK_CALIBRATION_LOOP
- if (bootverbose) {
- printf(
- "Press a key on the console to abort clock calibration\n");
- while (cncheckc() == -1)
- calibrate_clocks();
- }
-#endif
-
- /*
- * Use the calibrated i8254 frequency if it seems reasonable.
- * Otherwise use the default, and don't use the calibrated i586
- * frequency.
- */
- delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
- if (delta < timer_freq / 100) {
-#ifndef CLK_USE_I8254_CALIBRATION
- if (bootverbose)
- printf(
-"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
- freq = timer_freq;
-#endif
- timer_freq = freq;
- } else {
- if (bootverbose)
- printf(
- "%d Hz differs from default of %d Hz by more than 1%%\n",
- freq, timer_freq);
- }
-
- set_timer_freq(timer_freq, hz);
- i8254_timecounter.tc_frequency = timer_freq;
- tc_init(&i8254_timecounter);
-
- init_TSC();
-}
-
-static void
-rtc_serialcombit(int i)
-{
- outb(IO_RTC, ((i&0x01)<<5)|0x07);
- DELAY(1);
- outb(IO_RTC, ((i&0x01)<<5)|0x17);
- DELAY(1);
- outb(IO_RTC, ((i&0x01)<<5)|0x07);
- DELAY(1);
-}
-
-static void
-rtc_serialcom(int i)
-{
- rtc_serialcombit(i&0x01);
- rtc_serialcombit((i&0x02)>>1);
- rtc_serialcombit((i&0x04)>>2);
- rtc_serialcombit((i&0x08)>>3);
- outb(IO_RTC, 0x07);
- DELAY(1);
- outb(IO_RTC, 0x0f);
- DELAY(1);
- outb(IO_RTC, 0x07);
- DELAY(1);
-}
-
-static void
-rtc_outb(int val)
-{
- int s;
- int sa = 0;
-
- for (s=0;s<8;s++) {
- sa = ((val >> s) & 0x01) ? 0x27 : 0x07;
- outb(IO_RTC, sa); /* set DI & CLK 0 */
- DELAY(1);
- outb(IO_RTC, sa | 0x10); /* CLK 1 */
- DELAY(1);
- }
- outb(IO_RTC, sa & 0xef); /* CLK 0 */
-}
-
-static int
-rtc_inb(void)
-{
- int s;
- int sa = 0;
-
- for (s=0;s<8;s++) {
- sa |= ((inb(0x33) & 0x01) << s);
- outb(IO_RTC, 0x17); /* CLK 1 */
- DELAY(1);
- outb(IO_RTC, 0x07); /* CLK 0 */
- DELAY(2);
- }
- return sa;
-}
-
-/*
- * Initialize the time of day register, based on the time base which is, e.g.
- * from a filesystem.
- */
-void
-inittodr(time_t base)
-{
- unsigned long sec, days;
- int year, month;
- int y, m, s;
- struct timespec ts;
- int second, min, hour;
-
- if (base) {
- s = splclock();
- ts.tv_sec = base;
- ts.tv_nsec = 0;
- tc_setclock(&ts);
- splx(s);
- }
-
- rtc_serialcom(0x03); /* Time Read */
- rtc_serialcom(0x01); /* Register shift command. */
- DELAY(20);
-
- second = bcd2bin(rtc_inb() & 0xff); /* sec */
- min = bcd2bin(rtc_inb() & 0xff); /* min */
- hour = bcd2bin(rtc_inb() & 0xff); /* hour */
- days = bcd2bin(rtc_inb() & 0xff) - 1; /* date */
-
- month = (rtc_inb() >> 4) & 0x0f; /* month */
- for (m = 1; m < month; m++)
- days += daysinmonth[m-1];
- year = bcd2bin(rtc_inb() & 0xff) + 1900; /* year */
- /* 2000 year problem */
- if (year < 1995)
- year += 100;
- if (year < 1970)
- goto wrong_time;
- for (y = 1970; y < year; y++)
- days += DAYSPERYEAR + LEAPYEAR(y);
- if ((month > 2) && LEAPYEAR(year))
- days ++;
- sec = ((( days * 24 +
- hour) * 60 +
- min) * 60 +
- second);
- /* sec now contains the number of seconds, since Jan 1 1970,
- in the local time zone */
-
- s = splhigh();
-
- sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
-
- y = time_second - sec;
- if (y <= -2 || y >= 2) {
- /* badly off, adjust it */
- ts.tv_sec = sec;
- ts.tv_nsec = 0;
- tc_setclock(&ts);
- }
- splx(s);
- return;
-
-wrong_time:
- printf("Invalid time in real time clock.\n");
- printf("Check and reset the date immediately!\n");
-}
-
-/*
- * Write system time back to RTC
- */
-void
-resettodr()
-{
- unsigned long tm;
- int y, m, s;
- int wd;
-
- if (disable_rtc_set)
- return;
-
- s = splclock();
- tm = time_second;
- splx(s);
-
- rtc_serialcom(0x01); /* Register shift command. */
-
- /* Calculate local time to put in RTC */
-
- tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
-
- rtc_outb(bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */
- rtc_outb(bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */
- rtc_outb(bin2bcd(tm%24)); tm /= 24; /* Write back Hours */
-
- /* We have now the days since 01-01-1970 in tm */
- wd = (tm + 4) % 7 + 1; /* Write back Weekday */
- for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
- tm >= m;
- y++, m = DAYSPERYEAR + LEAPYEAR(y))
- tm -= m;
-
- /* Now we have the years in y and the day-of-the-year in tm */
- for (m = 0; ; m++) {
- int ml;
-
- ml = daysinmonth[m];
- if (m == 1 && LEAPYEAR(y))
- ml++;
- if (tm < ml)
- break;
- tm -= ml;
- }
-
- m++;
- rtc_outb(bin2bcd(tm+1)); /* Write back Day */
- rtc_outb((m << 4) | wd); /* Write back Month & Weekday */
- rtc_outb(bin2bcd(y%100)); /* Write back Year */
-
- rtc_serialcom(0x02); /* Time set & Counter hold command. */
- rtc_serialcom(0x00); /* Register hold command. */
-}
-
-
-/*
- * Start both clocks running.
- */
-void
-cpu_initclocks()
-{
-
-#ifdef DEV_APIC
- using_lapic_timer = lapic_setup_clock();
-#endif
- /*
- * If we aren't using the local APIC timer to drive the kernel
- * clocks, setup the interrupt handler for the 8254 timer 0 so
- * that it can drive hardclock().
- */
- if (!using_lapic_timer) {
- intr_add_handler("clk", 0, (driver_intr_t *)clkintr, NULL,
- INTR_TYPE_CLK | INTR_FAST, NULL);
- i8254_intsrc = intr_lookup_source(0);
- if (i8254_intsrc != NULL)
- i8254_pending =
- i8254_intsrc->is_pic->pic_source_pending;
- }
-
- init_TSC_tc();
-}
-
-void
-cpu_startprofclock(void)
-{
-}
-
-void
-cpu_stopprofclock(void)
-{
-}
-
-static int
-sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
-{
- int error;
- u_int freq;
-
- /*
- * Use `i8254' instead of `timer' in external names because `timer'
- * is is too generic. Should use it everywhere.
- */
- freq = timer_freq;
- error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
- if (error == 0 && req->newptr != NULL) {
- set_timer_freq(freq, hz);
- i8254_timecounter.tc_frequency = freq;
- }
- return (error);
-}
-
-SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof(u_int), sysctl_machdep_i8254_freq, "IU", "");
-
-static unsigned
-i8254_get_timecount(struct timecounter *tc)
-{
- u_int count;
- u_int high, low;
- u_int eflags;
-
- eflags = read_eflags();
- mtx_lock_spin(&clock_lock);
-
- /* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
-
- low = inb(TIMER_CNTR0);
- high = inb(TIMER_CNTR0);
- count = timer0_max_count - ((high << 8) | low);
- if (count < i8254_lastcount ||
- (!i8254_ticked && (clkintr_pending ||
- ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
- i8254_pending != NULL && i8254_pending(i8254_intsrc))))) {
- i8254_ticked = 1;
- i8254_offset += timer0_max_count;
- }
- i8254_lastcount = count;
- count += i8254_offset;
- mtx_unlock_spin(&clock_lock);
- return (count);
-}
-
-#ifdef DEV_ISA
-/*
- * Attach to the ISA PnP descriptors for the timer and realtime clock.
- */
-static struct isa_pnp_id attimer_ids[] = {
- { 0x0001d041 /* PNP0100 */, "AT timer" },
- { 0x000bd041 /* PNP0B00 */, "AT realtime clock" },
- { 0 }
-};
-
-static int
-attimer_probe(device_t dev)
-{
- int result;
-
- if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids)) <= 0)
- device_quiet(dev);
- return(result);
-}
-
-static int
-attimer_attach(device_t dev)
-{
- return(0);
-}
-
-static device_method_t attimer_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, attimer_probe),
- DEVMETHOD(device_attach, attimer_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX stop statclock? */
- DEVMETHOD(device_resume, bus_generic_resume), /* XXX restart statclock? */
- { 0, 0 }
-};
-
-static driver_t attimer_driver = {
- "attimer",
- attimer_methods,
- 1, /* no softc */
-};
-
-static devclass_t attimer_devclass;
-
-DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
-#endif /* DEV_ISA */
diff --git a/sys/pc98/pc98/fd.c b/sys/pc98/pc98/fd.c
deleted file mode 100644
index d2ead23..0000000
--- a/sys/pc98/pc98/fd.c
+++ /dev/null
@@ -1,2794 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Don Ahn.
- *
- * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu)
- * aided by the Linux floppy driver modifications from David Bateman
- * (dbateman@eng.uts.edu.au).
- *
- * Copyright (c) 1993, 1994 by
- * jc@irbs.UUCP (John Capo)
- * vak@zebub.msk.su (Serge Vakulenko)
- * ache@astral.msk.su (Andrew A. Chernov)
- *
- * Copyright (c) 1993, 1994, 1995 by
- * joerg_wunsch@uriah.sax.de (Joerg Wunsch)
- * dufault@hda.com (Peter Dufault)
- *
- * Copyright (c) 2001 Joerg Wunsch,
- * joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $FreeBSD$
- */
-
-#include "opt_fdc.h"
-
-#include <sys/param.h>
-#include <sys/bio.h>
-#include <sys/bus.h>
-#include <sys/devicestat.h>
-#include <sys/disk.h>
-#include <sys/fcntl.h>
-#include <sys/fdcio.h>
-#include <sys/filio.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/rman.h>
-#include <sys/systm.h>
-
-#include <machine/bus.h>
-#include <machine/clock.h>
-#include <machine/stdarg.h>
-
-#ifdef PC98
-#include <isa/isavar.h>
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/pc98_machdep.h>
-#include <pc98/pc98/epsonio.h>
-#include <pc98/pc98/fdreg.h>
-#include <pc98/pc98/fdcvar.h>
-#else
-#include <isa/isavar.h>
-#include <isa/isareg.h>
-#include <dev/fdc/fdcreg.h>
-#include <dev/fdc/fdcvar.h>
-#include <isa/rtc.h>
-#endif
-
-#define FDBIO_FORMAT BIO_CMD2
-
-/* configuration flags for fdc */
-#define FDC_NO_FIFO (1 << 2) /* do not enable FIFO */
-
-/*
- * Stop retrying after this many DMA overruns. Since each retry takes
- * one revolution, with 300 rpm., 25 retries take approximately 5
- * seconds which the read attempt will block in case the DMA overrun
- * is persistent.
- */
-#define FDC_DMAOV_MAX 25
-
-/*
- * Timeout value for the PIO loops to wait until the FDC main status
- * register matches our expectations (request for master, direction
- * bit). This is supposed to be a number of microseconds, although
- * timing might actually not be very accurate.
- *
- * Timeouts of 100 msec are believed to be required for some broken
- * (old) hardware.
- */
-#define FDSTS_TIMEOUT 100000
-
-/*
- * Number of subdevices that can be used for different density types.
- */
-#ifdef PC98
-#define NUMDENS 12
-#else
-#define NUMDENS 16
-#endif
-
-#define FDBIO_RDSECTID BIO_CMD1
-
-/*
- * List of native drive densities. Order must match enum fd_drivetype
- * in <sys/fdcio.h>. Upon attaching the drive, each of the
- * programmable subdevices is initialized with the native density
- * definition.
- */
-#ifdef PC98
-static struct fd_type fd_native_types[] =
-{
-{ 0 }, /* FDT_NONE */
-{ 0 }, /* FDT_360K */
-{ 15,2,0xFF,0x1B,80,2400,0,2,0x54,1,0,FL_MFM }, /* FDT_12M */
-{ 0 }, /* FDT_720K */
-{ 18,2,0xFF,0x1B,80,2880,2,2,0x54,1,0,FL_MFM }, /* FDT_144M */
-{ 0 }, /* FDT_288M */
-};
-
-static struct fd_type fd_searchlist_12m[] = {
-{ 15,2,0xFF,0x1B,80,2400,0,2,0x54,1,0,FL_MFM }, /* 1.2M */
-#if 0
-{ 10,2,0xFF,0x10,82,1640,1,2,0x30,1,0,FL_MFM }, /* 820K */
-{ 10,2,0xFF,0x10,80,1600,1,2,0x30,1,0,FL_MFM }, /* 800K */
-#endif
-{ 9,2,0xFF,0x20,80,1440,1,2,0x50,1,0,FL_MFM }, /* 720K */
-{ 9,2,0xFF,0x20,40, 720,1,2,0x50,1,0,FL_MFM|FL_2STEP },/* 360K */
-{ 8,2,0xFF,0x2A,80,1280,1,2,0x50,1,0,FL_MFM }, /* 640K */
-{ 8,3,0xFF,0x35,77,1232,0,2,0x74,1,0,FL_MFM }, /* 1.23M 1024/sec */
-#if 0
-{ 8,3,0xFF,0x35,80,1280,0,2,0x74,1,0,FL_MFM }, /* 1.28M 1024/sec */
-#endif
-};
-static struct fd_type fd_searchlist_144m[] = {
-#if 0
-{ 21,2,0xFF,0x04,82,3444,2,2,0x0C,2,0,FL_MFM }, /* 1.72M in 3mode */
-{ 18,2,0xFF,0x1B,82,2952,2,2,0x54,1,0,FL_MFM }, /* 1.48M in 3mode */
-#endif
-{ 18,2,0xFF,0x1B,80,2880,2,2,0x54,1,0,FL_MFM }, /* 1.44M in 3mode */
-{ 15,2,0xFF,0x1B,80,2400,0,2,0x54,1,0,FL_MFM }, /* 1.2M */
-#if 0
-{ 10,2,0xFF,0x10,82,1640,1,2,0x30,1,0,FL_MFM }, /* 820K */
-{ 10,2,0xFF,0x10,80,1600,1,2,0x30,1,0,FL_MFM }, /* 800K */
-#endif
-{ 9,2,0xFF,0x20,80,1440,1,2,0x50,1,0,FL_MFM }, /* 720K */
-{ 9,2,0xFF,0x20,40, 720,1,2,0x50,1,0,FL_MFM|FL_2STEP },/* 360K */
-{ 8,2,0xFF,0x2A,80,1280,1,2,0x50,1,0,FL_MFM }, /* 640K */
-{ 8,3,0xFF,0x35,77,1232,0,2,0x74,1,0,FL_MFM }, /* 1.23M 1024/sec */
-#if 0
-{ 8,3,0xFF,0x35,80,1280,0,2,0x74,1,0,FL_MFM }, /* 1.28M 1024/sec */
-{ 9,3,0xFF,0x35,82,1476,0,2,0x47,1,0,FL_MFM }, /* 1.48M 1024/sec 9sec */
-{ 10,3,0xFF,0x1B,82,1640,2,2,0x54,1,0,FL_MFM }, /* 1.64M in 3mode - Reserve */
-#endif
-};
-#else /* PC98 */
-static struct fd_type fd_native_types[] =
-{
-{ 0 }, /* FDT_NONE */
-{ 9,2,0xFF,0x2A,40, 720,FDC_250KBPS,2,0x50,1,0,FL_MFM }, /* FDT_360K */
-{ 15,2,0xFF,0x1B,80,2400,FDC_500KBPS,2,0x54,1,0,FL_MFM }, /* FDT_12M */
-{ 9,2,0xFF,0x20,80,1440,FDC_250KBPS,2,0x50,1,0,FL_MFM }, /* FDT_720K */
-{ 18,2,0xFF,0x1B,80,2880,FDC_500KBPS,2,0x6C,1,0,FL_MFM }, /* FDT_144M */
-#if 0 /* we currently don't handle 2.88 MB */
-{ 36,2,0xFF,0x1B,80,5760,FDC_1MBPS, 2,0x4C,1,1,FL_MFM|FL_PERPND } /*FDT_288M*/
-#else
-{ 18,2,0xFF,0x1B,80,2880,FDC_500KBPS,2,0x6C,1,0,FL_MFM }, /* FDT_144M */
-#endif
-};
-
-/*
- * 360 KB 5.25" and 720 KB 3.5" drives don't have automatic density
- * selection, they just start out with their native density (or lose).
- * So 1.2 MB 5.25", 1.44 MB 3.5", and 2.88 MB 3.5" drives have their
- * respective lists of densities to search for.
- */
-static struct fd_type fd_searchlist_12m[] = {
-{ 15,2,0xFF,0x1B,80,2400,FDC_500KBPS,2,0x54,1,0,FL_MFM }, /* 1.2M */
-{ 9,2,0xFF,0x23,40, 720,FDC_300KBPS,2,0x50,1,0,FL_MFM|FL_2STEP }, /* 360K */
-{ 9,2,0xFF,0x20,80,1440,FDC_300KBPS,2,0x50,1,0,FL_MFM }, /* 720K */
-};
-
-static struct fd_type fd_searchlist_144m[] = {
-{ 18,2,0xFF,0x1B,80,2880,FDC_500KBPS,2,0x6C,1,0,FL_MFM }, /* 1.44M */
-{ 9,2,0xFF,0x20,80,1440,FDC_250KBPS,2,0x50,1,0,FL_MFM }, /* 720K */
-};
-
-/* We search for 1.44M first since this is the most common case. */
-static struct fd_type fd_searchlist_288m[] = {
-{ 18,2,0xFF,0x1B,80,2880,FDC_500KBPS,2,0x6C,1,0,FL_MFM }, /* 1.44M */
-#if 0
-{ 36,2,0xFF,0x1B,80,5760,FDC_1MBPS, 2,0x4C,1,1,FL_MFM|FL_PERPND } /* 2.88M */
-#endif
-{ 9,2,0xFF,0x20,80,1440,FDC_250KBPS,2,0x50,1,0,FL_MFM }, /* 720K */
-};
-#endif /* PC98 */
-
-#define MAX_SEC_SIZE (128 << 3)
-#define MAX_CYLINDER 85 /* some people really stress their drives
- * up to cyl 82 */
-#define MAX_HEAD 1
-
-devclass_t fdc_devclass;
-
-/*
- * Per drive structure (softc).
- */
-struct fd_data {
- struct fdc_data *fdc; /* pointer to controller structure */
- int fdsu; /* this units number on this controller */
- enum fd_drivetype type; /* drive type */
- struct fd_type *ft; /* pointer to current type descriptor */
- struct fd_type fts[NUMDENS]; /* type descriptors */
- int flags;
-#define FD_OPEN 0x01 /* it's open */
-#define FD_NONBLOCK 0x02 /* O_NONBLOCK set */
-#define FD_ACTIVE 0x04 /* it's active */
-#define FD_MOTOR 0x08 /* motor should be on */
-#define FD_MOTOR_WAIT 0x10 /* motor coming up */
-#define FD_UA 0x20 /* force unit attention */
- int skip;
- int hddrv;
-#define FD_NO_TRACK -2
- int track; /* where we think the head is */
- int options; /* user configurable options, see fdcio.h */
- struct callout_handle toffhandle;
- struct callout_handle tohandle;
- struct devstat *device_stats;
- struct cdev *masterdev;
- device_t dev;
- fdu_t fdu;
-#ifdef PC98
- int pc98_trans;
-#endif
-};
-
-struct fdc_ivars {
- int fdunit;
- int fdtype;
-};
-
-static devclass_t fd_devclass;
-
-/* configuration flags for fd */
-#define FD_TYPEMASK 0x0f /* drive type, matches enum
- * fd_drivetype; on i386 machines, if
- * given as 0, use RTC type for fd0
- * and fd1 */
-#define FD_DTYPE(flags) ((flags) & FD_TYPEMASK)
-#define FD_NO_CHLINE 0x10 /* drive does not support changeline
- * aka. unit attention */
-#define FD_NO_PROBE 0x20 /* don't probe drive (seek test), just
- * assume it is there */
-
-#ifdef EPSON_NRDISK
-typedef unsigned int nrd_t;
-
-#define P_NRD_ADDRH 0xc24
-#define P_NRD_ADDRM 0xc22
-#define P_NRD_ADDRL 0xc20
-#define P_NRD_CHECK 0xc20
-#define P_NRD_DATA 0xc26
-#define P_NRD_LED 0xc36
-#define B_NRD_CHK 0x80
-#define B_NRD_LED 0x40
-#define A_NRD_INFO 0x2
-#define A_NRD_BASE 0x400
-#define NRD_STATUS 0x0
-#define NRD_ST0_HD 0x04
-
-static fdu_t nrdu=-1;
-static int nrdsec=0;
-static nrd_t nrdblkn=0;
-static nrd_t nrdaddr=0x0;
-
-#define nrd_check_ready() ({ \
- (epson_inb(P_NRD_CHECK) & B_NRD_CHK) ? 0 : 1; \
- })
-#define nrd_LED_on() epson_outb(P_NRD_LED, B_NRD_LED)
-#define nrd_LED_off() epson_outb(P_NRD_LED, ~B_NRD_LED)
-#define nrd_trac() ((int)(nrd_info(nrdaddr) & 0xff))
-#define nrd_head() ((int)((nrd_info(nrdaddr) >> 8) & 0xff))
-#define nrd_sec() ((int)(nrd_info(nrdaddr + 2) & 0xff))
-#define nrd_secsize() ((int)((nrd_info(A_NRD_INFO) >> 8) & 0xff))
-#define nrd_addrset(p) nrd_addr((nrd_t)((nrd_t)p+A_NRD_BASE))
-
-static inline void
-nrd_addr(addr)
- nrd_t addr;
-{
- epson_outb(P_NRD_ADDRH, (u_char)((addr >> 16) & 0x1f));
- epson_outb(P_NRD_ADDRM, (u_char)((addr >> 8) & 0xff));
- epson_outb(P_NRD_ADDRL, (u_char)(addr & 0xff));
-}
-
-static inline u_short
-nrd_info(addr)
- nrd_t addr;
-{
- nrd_addr(addr);
- return (epson_inw(P_NRD_DATA));
-}
-#endif /* EPSON_NRDISK */
-
-/*
- * Throughout this file the following conventions will be used:
- *
- * fd is a pointer to the fd_data struct for the drive in question
- * fdc is a pointer to the fdc_data struct for the controller
- * fdu is the floppy drive unit number
- * fdcu is the floppy controller unit number
- * fdsu is the floppy drive unit number on that controller. (sub-unit)
- */
-
-/*
- * Function declarations, same (chaotic) order as they appear in the
- * file. Re-ordering is too late now, it would only obfuscate the
- * diffs against old and offspring versions (like the PC98 one).
- *
- * Anyone adding functions here, please keep this sequence the same
- * as below -- makes locating a particular function in the body much
- * easier.
- */
-static u_int8_t fdsts_rd(fdc_p);
-static void fddata_wr(fdc_p, u_int8_t);
-static u_int8_t fddata_rd(fdc_p);
-static int fdc_err(struct fdc_data *, const char *);
-static int enable_fifo(fdc_p fdc);
-static int fd_sense_drive_status(fdc_p, int *);
-static int fd_sense_int(fdc_p, int *, int *);
-static int fd_read_status(fdc_p);
-static int fd_probe(device_t);
-static int fd_attach(device_t);
-static int fd_detach(device_t);
-static void set_motor(struct fdc_data *, int, int);
-# define TURNON 1
-# define TURNOFF 0
-static timeout_t fd_turnoff;
-static timeout_t fd_motor_on;
-static void fd_turnon(struct fd_data *);
-static void fdc_reset(fdc_p);
-static int fd_in(struct fdc_data *, int *);
-static int out_fdc(struct fdc_data *, int);
-static d_open_t fdopen;
-static d_close_t fdclose;
-static d_strategy_t fdstrategy;
-static void fdstart(struct fdc_data *);
-static timeout_t fd_iotimeout;
-static timeout_t fd_pseudointr;
-static driver_intr_t fdc_intr;
-static int fdcpio(fdc_p, long, caddr_t, u_int);
-static int fdautoselect(struct cdev *);
-static int fdstate(struct fdc_data *);
-static int retrier(struct fdc_data *);
-static void fdbiodone(struct bio *);
-static int fdmisccmd(struct cdev *, u_int, void *);
-static d_ioctl_t fdioctl;
-
-static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */
-
-#ifdef FDC_DEBUG
-/* CAUTION: fd_debug causes huge amounts of logging output */
-static int volatile fd_debug = 0;
-#define TRACE0(arg) do { if (fd_debug) printf(arg); } while (0)
-#define TRACE1(arg1, arg2) do { if (fd_debug) printf(arg1, arg2); } while (0)
-#else /* FDC_DEBUG */
-#define TRACE0(arg) do { } while (0)
-#define TRACE1(arg1, arg2) do { } while (0)
-#endif /* FDC_DEBUG */
-
-/*
- * Bus space handling (access to low-level IO).
- */
-#ifndef PC98
-void
-fdout_wr(fdc_p fdc, u_int8_t v)
-{
- bus_space_write_1(fdc->portt, fdc->porth, FDOUT+fdc->port_off, v);
-}
-#endif
-
-static u_int8_t
-fdsts_rd(fdc_p fdc)
-{
- return bus_space_read_1(fdc->portt, fdc->porth, FDSTS+fdc->port_off);
-}
-
-static void
-fddata_wr(fdc_p fdc, u_int8_t v)
-{
- bus_space_write_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off, v);
-}
-
-static u_int8_t
-fddata_rd(fdc_p fdc)
-{
- return bus_space_read_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off);
-}
-
-#ifdef PC98
-static void
-fdctl_wr(fdc_p fdc, u_int8_t v)
-{
- bus_space_write_1(fdc->portt, fdc->porth, FDCTL, v);
-}
-#endif
-
-#ifndef PC98
-static u_int8_t
-fdin_rd(fdc_p fdc)
-{
- return bus_space_read_1(fdc->portt, fdc->porth, FDIN);
-}
-#endif /* PC98 */
-
-static struct cdevsw fd_cdevsw = {
- .d_version = D_VERSION,
- .d_open = fdopen,
- .d_close = fdclose,
- .d_read = physread,
- .d_write = physwrite,
- .d_ioctl = fdioctl,
- .d_strategy = fdstrategy,
- .d_name = "fd",
- .d_flags = D_DISK | D_NEEDGIANT,
-};
-
-/*
- * Auxiliary functions. Well, some only. Others are scattered
- * throughout the entire file.
- */
-static int
-fdc_err(struct fdc_data *fdc, const char *s)
-{
- fdc->fdc_errs++;
- if (s) {
- if (fdc->fdc_errs < FDC_ERRMAX)
- device_printf(fdc->fdc_dev, "%s", s);
- else if (fdc->fdc_errs == FDC_ERRMAX)
- device_printf(fdc->fdc_dev, "too many errors, not "
- "logging any more\n");
- }
-
- return FD_FAILED;
-}
-
-/*
- * fd_cmd: Send a command to the chip. Takes a varargs with this structure:
- * Unit number,
- * # of output bytes, output bytes as ints ...,
- * # of input bytes, input bytes as ints ...
- */
-int
-fd_cmd(struct fdc_data *fdc, int n_out, ...)
-{
- u_char cmd;
- int n_in;
- int n;
- va_list ap;
-
- va_start(ap, n_out);
- cmd = (u_char)(va_arg(ap, int));
- va_end(ap);
- va_start(ap, n_out);
- for (n = 0; n < n_out; n++)
- {
- if (out_fdc(fdc, va_arg(ap, int)) < 0)
- {
- char msg[50];
- snprintf(msg, sizeof(msg),
- "cmd %x failed at out byte %d of %d\n",
- cmd, n + 1, n_out);
- return fdc_err(fdc, msg);
- }
- }
- n_in = va_arg(ap, int);
- for (n = 0; n < n_in; n++)
- {
- int *ptr = va_arg(ap, int *);
- if (fd_in(fdc, ptr) < 0)
- {
- char msg[50];
- snprintf(msg, sizeof(msg),
- "cmd %02x failed at in byte %d of %d\n",
- cmd, n + 1, n_in);
- return fdc_err(fdc, msg);
- }
- }
-
- return 0;
-}
-
-static int
-enable_fifo(fdc_p fdc)
-{
- int i, j;
-
- if ((fdc->flags & FDC_HAS_FIFO) == 0) {
-
- /*
- * Cannot use fd_cmd the normal way here, since
- * this might be an invalid command. Thus we send the
- * first byte, and check for an early turn of data directon.
- */
-
- if (out_fdc(fdc, I8207X_CONFIGURE) < 0)
- return fdc_err(fdc, "Enable FIFO failed\n");
-
- /* If command is invalid, return */
- j = FDSTS_TIMEOUT;
- while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM))
- != NE7_RQM && j-- > 0) {
- if (i == (NE7_DIO | NE7_RQM)) {
- fdc_reset(fdc);
- return FD_FAILED;
- }
- DELAY(1);
- }
- if (j<0 ||
- fd_cmd(fdc, 3,
- 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
- fdc_reset(fdc);
- return fdc_err(fdc, "Enable FIFO failed\n");
- }
- fdc->flags |= FDC_HAS_FIFO;
- return 0;
- }
- if (fd_cmd(fdc, 4,
- I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0)
- return fdc_err(fdc, "Re-enable FIFO failed\n");
- return 0;
-}
-
-static int
-fd_sense_drive_status(fdc_p fdc, int *st3p)
-{
- int st3;
-
- if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
- {
- return fdc_err(fdc, "Sense Drive Status failed\n");
- }
- if (st3p)
- *st3p = st3;
-
- return 0;
-}
-
-static int
-fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
-{
- int cyl, st0, ret;
-
-#ifdef EPSON_NRDISK
- if (fdc->fdu == nrdu) {
- if (fdc->fd->track >= 0) nrdaddr = (fdc->fd->track + 1) * 8;
- else nrdaddr = 0x0;
- *st0p = nrd_head() ? NRD_ST0_HD : NRD_STATUS;
- *cylp = nrd_trac();
- }
- else {
-#endif /* EPSON_NRDISK */
- ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0);
- if (ret) {
- (void)fdc_err(fdc,
- "sense intr err reading stat reg 0\n");
- return ret;
- }
-
- if (st0p)
- *st0p = st0;
-
- if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) {
- /*
- * There doesn't seem to have been an interrupt.
- */
- return FD_NOT_VALID;
- }
-
- if (fd_in(fdc, &cyl) < 0) {
- return fdc_err(fdc, "can't get cyl num\n");
- }
-
- if (cylp)
- *cylp = cyl;
-
-#ifdef EPSON_NRDISK
- }
-#endif /* EPSON_NRDISK */
- return 0;
-}
-
-
-static int
-fd_read_status(fdc_p fdc)
-{
- int i, ret;
-
- for (i = ret = 0; i < 7; i++) {
- /*
- * XXX types are poorly chosen. Only bytes can be read
- * from the hardware, but fdc->status[] wants u_ints and
- * fd_in() gives ints.
- */
- int status;
-
-#ifdef EPSON_NRDISK
- if (fdc->fdu == nrdu) {
- switch (i) {
- case 0: fdc->status[i] = nrd_head()
- ? NRD_ST0_HD : NRD_STATUS; break;
- case 1: fdc->status[i] = NRD_STATUS; break;
- case 2: fdc->status[i] = NRD_STATUS; break;
- case 3: fdc->status[i] = nrd_trac(); break;
- case 4: fdc->status[i] = nrd_head(); break;
- case 5: fdc->status[i] = nrdsec; break;
- case 6: fdc->status[i] = nrd_secsize(); break;
- }
- ret = 0;
- }
- else {
-#endif /* EPSON_NRDISK */
- ret = fd_in(fdc, &status);
- fdc->status[i] = status;
- if (ret != 0)
- break;
-#ifdef EPSON_NRDISK
- }
-#endif /* EPSON_NRDISK */
- }
-
- if (ret == 0)
- fdc->flags |= FDC_STAT_VALID;
- else
- fdc->flags &= ~FDC_STAT_VALID;
-
- return ret;
-}
-
-#ifdef PC98
-static int pc98_trans = 0; /* 0 : HD , 1 : DD , 2 : 1.44 */
-static int pc98_trans_prev = -1;
-
-static void set_density(fdc_p fdc)
-{
- /* always motor on */
- bus_space_write_1(fdc->sc_fdsiot, fdc->sc_fdsioh, 0,
- (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
- DELAY(100);
- fdctl_wr(fdc, FDC_RST | FDC_DMAE);
- /* in the case of note W, always inhibit 100ms timer */
-}
-
-static int pc98_fd_check_ready(fdu_t fdu)
-{
- fd_p fd = devclass_get_softc(fd_devclass, fdu);
- struct fdc_data *fdc = fd->fdc;
- int retry = 0, status;
-
-#ifdef EPSON_NRDISK
- if (fdu == nrdu) {
- if (nrd_check_ready()) return 0;
- else return -1;
- }
-#endif
- while (retry++ < 30000) {
- set_motor(fdc, fd->fdsu, TURNON);
- out_fdc(fdc, NE7CMD_SENSED); /* Sense Drive Status */
- DELAY(100);
- out_fdc(fdc, fdu); /* Drive number */
- DELAY(100);
- if ((fd_in(fdc, &status) == 0) && (status & NE7_ST3_RD)) {
- fdctl_wr(fdc, FDC_DMAE | FDC_MTON);
- DELAY(10);
- return 0;
- }
- }
- return -1;
-}
-
-static void pc98_fd_check_type(struct fd_data *fd)
-{
- struct fdc_data *fdc;
-
- if (fd->type != FDT_NONE || fd->fdu < 0 || fd->fdu > 3)
- return;
-
- fdc = fd->fdc;
-
- /* Look up what the BIOS thinks we have. */
- if (!((PC98_SYSTEM_PARAMETER(0x55c) >> fd->fdu) & 0x01)) {
- fd->type = FDT_NONE;
- return;
- }
- if ((PC98_SYSTEM_PARAMETER(0x5ae) >> fd->fdu) & 0x01) {
- /* Check 3mode I/F */
- fd->pc98_trans = 0;
- bus_space_write_1(fdc->sc_fdemsiot, fdc->sc_fdemsioh, 0,
- (fd->fdu << 5) | 0x10);
- if (!(bus_space_read_1(fdc->sc_fdemsiot, fdc->sc_fdemsioh, 0) &
- 0x01)) {
- fd->type = FDT_144M;
- return;
- }
- device_printf(fd->dev,
- "Warning: can't control 3mode I/F, fallback to 2mode.\n");
- }
-
- fd->type = FDT_12M;
-
- switch (epson_machine_id) {
- case 0x20:
- case 0x27:
- if ((PC98_SYSTEM_PARAMETER(0x488) >> fd->fdu) & 0x01) {
-#ifdef EPSON_NRDISK
- if (nrd_check_ready()) {
- nrd_LED_on();
- nrdu = fd->fdu;
- } else
-#endif
- fd->type = FDT_NONE;
- }
- break;
- }
-}
-#endif /* PC98 */
-
-void
-fdc_release_resources(struct fdc_data *fdc)
-{
- device_t dev;
-
- dev = fdc->fdc_dev;
- if (fdc->fdc_intr) {
- BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
- fdc->fdc_intr);
- fdc->fdc_intr = NULL;
- }
- if (fdc->res_irq != 0) {
- bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
- fdc->res_irq);
- bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
- fdc->res_irq);
- fdc->res_irq = NULL;
- }
-#ifndef PC98
- if (fdc->res_ctl != 0) {
- bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
- fdc->res_ctl);
- bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
- fdc->res_ctl);
- fdc->res_ctl = NULL;
- }
-#endif
-#ifdef PC98
- if (fdc->res_fdsio != 0) {
- bus_deactivate_resource(dev, SYS_RES_IOPORT, 3,
- fdc->res_fdsio);
- bus_release_resource(dev, SYS_RES_IOPORT, 3, fdc->res_fdsio);
- fdc->res_fdsio = NULL;
- }
- if (fdc->res_fdemsio != 0) {
- bus_deactivate_resource(dev, SYS_RES_IOPORT, 4,
- fdc->res_fdemsio);
- bus_release_resource(dev, SYS_RES_IOPORT, 4, fdc->res_fdemsio);
- fdc->res_fdemsio = NULL;
- }
-#endif
- if (fdc->res_ioport != 0) {
- bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
- fdc->res_ioport);
- bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
- fdc->res_ioport);
- fdc->res_ioport = NULL;
- }
- if (fdc->res_drq != 0) {
- bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
- fdc->res_drq);
- bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
- fdc->res_drq);
- fdc->res_drq = NULL;
- }
-}
-
-/*
- * Configuration/initialization stuff, per controller.
- */
-
-int
-fdc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
- struct fdc_ivars *ivars = device_get_ivars(child);
-
- switch (which) {
- case FDC_IVAR_FDUNIT:
- *result = ivars->fdunit;
- break;
- case FDC_IVAR_FDTYPE:
- *result = ivars->fdtype;
- break;
- default:
- return (ENOENT);
- }
- return (0);
-}
-
-int
-fdc_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
-{
- struct fdc_ivars *ivars = device_get_ivars(child);
-
- switch (which) {
- case FDC_IVAR_FDUNIT:
- ivars->fdunit = value;
- break;
- case FDC_IVAR_FDTYPE:
- ivars->fdtype = value;
- break;
- default:
- return (ENOENT);
- }
- return (0);
-}
-
-int
-fdc_initial_reset(struct fdc_data *fdc)
-{
-#ifdef PC98
- /* see if it can handle a command */
- if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240),
- NE7_SPEC_2(2, 0), 0))
- return (ENXIO);
-#else
- /* First, reset the floppy controller. */
- fdout_wr(fdc, 0);
- DELAY(100);
- fdout_wr(fdc, FDO_FRST);
-
- /* Then, see if it can handle a command. */
- if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
- NE7_SPEC_2(2, 0), 0))
- return (ENXIO);
-#endif
- return (0);
-}
-
-int
-fdc_detach(device_t dev)
-{
- struct fdc_data *fdc;
- int error;
-
- fdc = device_get_softc(dev);
-
- /* have our children detached first */
- if ((error = bus_generic_detach(dev)))
- return (error);
-
-#ifdef PC98
- /* reset controller, turn motor off */
- fdc_reset(fdc);
-#else
- /* reset controller, turn motor off */
- fdout_wr(fdc, 0);
-#endif
-
- fdc_release_resources(fdc);
- return (0);
-}
-
-/*
- * Add a child device to the fdc controller. It will then be probed etc.
- */
-device_t
-fdc_add_child(device_t dev, const char *name, int unit)
-{
- struct fdc_ivars *ivar;
- device_t child;
-
- ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO);
- if (ivar == NULL)
- return (NULL);
- child = device_add_child(dev, name, unit);
- if (child == NULL) {
- free(ivar, M_DEVBUF);
- return (NULL);
- }
- device_set_ivars(child, ivar);
- ivar->fdunit = unit;
- ivar->fdtype = FDT_NONE;
- if (resource_disabled(name, unit))
- device_disable(child);
- return (child);
-}
-
-int
-fdc_attach(device_t dev)
-{
- struct fdc_data *fdc;
- int error;
-
- fdc = device_get_softc(dev);
- fdc->fdc_dev = dev;
- error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq,
- INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc,
- &fdc->fdc_intr);
- if (error) {
- device_printf(dev, "cannot setup interrupt\n");
- return error;
- }
- fdc->fdcu = device_get_unit(dev);
- fdc->flags |= FDC_NEEDS_RESET;
-
- fdc->state = DEVIDLE;
-
-#ifdef PC98
- /* reset controller, turn motor off, clear fdout mirror reg */
- fdc_reset(fdc);
-#else
- /* reset controller, turn motor off, clear fdout mirror reg */
- fdout_wr(fdc, fdc->fdout = 0);
-#endif
- bioq_init(&fdc->head);
-
- return (0);
-}
-
-int
-fdc_hints_probe(device_t dev)
-{
- const char *name, *dname;
- int i, error, dunit;
-
- /*
- * Probe and attach any children. We should probably detect
- * devices from the BIOS unless overridden.
- */
- name = device_get_nameunit(dev);
- i = 0;
- while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) {
- resource_int_value(dname, dunit, "drive", &dunit);
- fdc_add_child(dev, dname, dunit);
- }
-
- if ((error = bus_generic_attach(dev)) != 0)
- return (error);
- return (0);
-}
-
-int
-fdc_print_child(device_t me, device_t child)
-{
- int retval = 0, flags;
-
- retval += bus_print_child_header(me, child);
- retval += printf(" on %s drive %d", device_get_nameunit(me),
- fdc_get_fdunit(child));
- if ((flags = device_get_flags(me)) != 0)
- retval += printf(" flags %#x", flags);
- retval += printf("\n");
-
- return (retval);
-}
-
-/*
- * Configuration/initialization, per drive.
- */
-static int
-fd_probe(device_t dev)
-{
- int i;
-#ifndef PC98
- u_int st0, st3;
-#endif
- struct fd_data *fd;
- struct fdc_data *fdc;
- fdsu_t fdsu;
- int flags, type;
-
- fdsu = fdc_get_fdunit(dev);
- fd = device_get_softc(dev);
- fdc = device_get_softc(device_get_parent(dev));
- flags = device_get_flags(dev);
-
- fd->dev = dev;
- fd->fdc = fdc;
- fd->fdsu = fdsu;
- fd->fdu = device_get_unit(dev);
-
- /* Auto-probe if fdinfo is present, but always allow override. */
- type = FD_DTYPE(flags);
- if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) {
- fd->type = type;
- goto done;
- } else {
- /* make sure fdautoselect() will be called */
- fd->flags = FD_UA;
- fd->type = type;
- }
-
-#ifdef PC98
- pc98_fd_check_type(fd);
-#else
-/*
- * XXX I think using __i386__ is wrong here since we actually want to probe
- * for the machine type, not the CPU type (so non-PC arch's like the PC98 will
- * fail the probe). However, for whatever reason, testing for _MACHINE_ARCH
- * == i386 breaks the test on FreeBSD/Alpha.
- */
-#ifdef __i386__
- if (fd->type == FDT_NONE && (fd->fdu == 0 || fd->fdu == 1)) {
- /* Look up what the BIOS thinks we have. */
- if (fd->fdu == 0) {
- if ((fdc->flags & FDC_ISPCMCIA))
- /*
- * Somewhat special. No need to force the
- * user to set device flags, since the Y-E
- * Data PCMCIA floppy is always a 1.44 MB
- * device.
- */
- fd->type = FDT_144M;
- else
- fd->type = (rtcin(RTC_FDISKETTE) & 0xf0) >> 4;
- } else {
- fd->type = rtcin(RTC_FDISKETTE) & 0x0f;
- }
- if (fd->type == FDT_288M_1)
- fd->type = FDT_288M;
- }
-#endif /* __i386__ */
-#endif /* PC98 */
-
- /* is there a unit? */
- if (fd->type == FDT_NONE)
- return (ENXIO);
-
-#ifndef PC98
- /* select it */
- set_motor(fdc, fdsu, TURNON);
- fdc_reset(fdc); /* XXX reset, then unreset, etc. */
- DELAY(1000000); /* 1 sec */
-
- if ((flags & FD_NO_PROBE) == 0) {
- /* If we're at track 0 first seek inwards. */
- if ((fd_sense_drive_status(fdc, &st3) == 0) &&
- (st3 & NE7_ST3_T0)) {
- /* Seek some steps... */
- if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
- /* ...wait a moment... */
- DELAY(300000);
- /* make ctrlr happy: */
- fd_sense_int(fdc, 0, 0);
- }
- }
-
- for (i = 0; i < 2; i++) {
- /*
- * we must recalibrate twice, just in case the
- * heads have been beyond cylinder 76, since
- * most FDCs still barf when attempting to
- * recalibrate more than 77 steps
- */
- /* go back to 0: */
- if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
- /* a second being enough for full stroke seek*/
- DELAY(i == 0 ? 1000000 : 300000);
-
- /* anything responding? */
- if (fd_sense_int(fdc, &st0, 0) == 0 &&
- (st0 & NE7_ST0_EC) == 0)
- break; /* already probed succesfully */
- }
- }
- }
-
- set_motor(fdc, fdsu, TURNOFF);
-
- if ((flags & FD_NO_PROBE) == 0 &&
- (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */
- return (ENXIO);
-#endif /* PC98 */
-
-done:
-#ifndef PC98
- /* This doesn't work before the first reset. */
- if ((fdc->flags & FDC_HAS_FIFO) == 0 &&
- fdc->fdct == FDC_ENHANCED &&
- (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 &&
- enable_fifo(fdc) == 0) {
- device_printf(device_get_parent(dev),
- "FIFO enabled, %d bytes threshold\n", fifo_threshold);
- }
-#endif /* PC98 */
-
-#ifdef PC98
- switch (fd->type) {
- case FDT_144M:
- device_set_desc(dev, "1.44M FDD");
- break;
- case FDT_12M:
-#ifdef EPSON_NRDISK
- if (fd->fdu == nrdu) {
- device_set_desc(dev, "EPSON RAM DRIVE");
- nrd_LED_off();
- } else
- device_set_desc(dev, "1M/640K FDD");
-#else
- device_set_desc(dev, "1M/640K FDD");
-#endif
- break;
- default:
- return (ENXIO);
- }
-#else
- switch (fd->type) {
- case FDT_12M:
- device_set_desc(dev, "1200-KB 5.25\" drive");
- break;
- case FDT_144M:
- device_set_desc(dev, "1440-KB 3.5\" drive");
- break;
- case FDT_288M:
- device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)");
- break;
- case FDT_360K:
- device_set_desc(dev, "360-KB 5.25\" drive");
- break;
- case FDT_720K:
- device_set_desc(dev, "720-KB 3.5\" drive");
- break;
- default:
- return (ENXIO);
- }
-#endif
- fd->track = FD_NO_TRACK;
- fd->fdc = fdc;
- fd->fdsu = fdsu;
- fd->options = 0;
-#ifdef PC98
- fd->pc98_trans = 0;
-#endif
- callout_handle_init(&fd->toffhandle);
- callout_handle_init(&fd->tohandle);
-
- /* initialize densities for subdevices */
-#ifdef PC98
- for (i = 0; i < NUMDENS; i++)
- memcpy(fd->fts + i, fd_searchlist_144m + i,
- sizeof(struct fd_type));
-#else
- for (i = 0; i < NUMDENS; i++)
- memcpy(fd->fts + i, fd_native_types + fd->type,
- sizeof(struct fd_type));
-#endif
- return (0);
-}
-
-static int
-fd_attach(device_t dev)
-{
- struct fd_data *fd;
-
- fd = device_get_softc(dev);
- fd->masterdev = make_dev(&fd_cdevsw, fd->fdu,
- UID_ROOT, GID_OPERATOR, 0640, "fd%d", fd->fdu);
- fd->masterdev->si_drv1 = fd;
- fd->device_stats = devstat_new_entry(device_get_name(dev),
- device_get_unit(dev), 0, DEVSTAT_NO_ORDERED_TAGS,
- DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER,
- DEVSTAT_PRIORITY_FD);
- return (0);
-}
-
-static int
-fd_detach(device_t dev)
-{
- struct fd_data *fd;
-
- fd = device_get_softc(dev);
- untimeout(fd_turnoff, fd, fd->toffhandle);
- devstat_remove_entry(fd->device_stats);
- destroy_dev(fd->masterdev);
-
- return (0);
-}
-
-static device_method_t fd_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, fd_probe),
- DEVMETHOD(device_attach, fd_attach),
- DEVMETHOD(device_detach, fd_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX */
- DEVMETHOD(device_resume, bus_generic_resume), /* XXX */
-
- { 0, 0 }
-};
-
-static driver_t fd_driver = {
- "fd",
- fd_methods,
- sizeof(struct fd_data)
-};
-
-DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, 0, 0);
-
-/*
- * More auxiliary functions.
- */
-/*
- * Motor control stuff.
- * Remember to not deselect the drive we're working on.
- */
-static void
-set_motor(struct fdc_data *fdc, int fdsu, int turnon)
-{
-#ifdef PC98
- bus_space_write_1(fdc->sc_fdsiot, fdc->sc_fdsioh, 0,
- (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
- DELAY(10);
- fdctl_wr(fdc, FDC_DMAE | FDC_MTON);
-#else
- int fdout;
-
- fdout = fdc->fdout;
- if (turnon) {
- fdout &= ~FDO_FDSEL;
- fdout |= (FDO_MOEN0 << fdsu) | FDO_FDMAEN | FDO_FRST | fdsu;
- } else
- fdout &= ~(FDO_MOEN0 << fdsu);
- fdc->fdout = fdout;
- fdout_wr(fdc, fdout);
- TRACE1("[0x%x->FDOUT]", fdout);
-#endif
-}
-
-static void
-fd_turnoff(void *xfd)
-{
- int s;
- fd_p fd = xfd;
-
- TRACE1("[fd%d: turnoff]", fd->fdu);
-
- s = splbio();
- /*
- * Don't turn off the motor yet if the drive is active.
- *
- * If we got here, this could only mean we missed an interrupt.
- * This can e. g. happen on the Y-E Date PCMCIA floppy controller
- * after a controller reset. Just schedule a pseudo-interrupt
- * so the state machine gets re-entered.
- */
- if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) {
- fdc_intr(fd->fdc);
- splx(s);
- return;
- }
-
- fd->flags &= ~FD_MOTOR;
- set_motor(fd->fdc, fd->fdsu, TURNOFF);
- splx(s);
-}
-
-static void
-fd_motor_on(void *xfd)
-{
- int s;
- fd_p fd = xfd;
-
- s = splbio();
- fd->flags &= ~FD_MOTOR_WAIT;
- if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT))
- {
- fdc_intr(fd->fdc);
- }
- splx(s);
-}
-
-static void
-fd_turnon(fd_p fd)
-{
- if(!(fd->flags & FD_MOTOR))
- {
- fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT);
- set_motor(fd->fdc, fd->fdsu, TURNON);
- timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */
- }
-}
-
-static void
-fdc_reset(fdc_p fdc)
-{
- /* Try a reset, keep motor on */
-#ifdef PC98
- set_density(fdc);
- if (pc98_machine_type & M_EPSON_PC98)
- fdctl_wr(fdc, FDC_RST | FDC_RDY | FDC_DD | FDC_MTON);
- else
- fdctl_wr(fdc, FDC_RST | FDC_RDY | FDC_DMAE | FDC_MTON);
- DELAY(200);
- fdctl_wr(fdc, FDC_DMAE | FDC_MTON);
- DELAY(10);
-#else
- fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
- TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
- DELAY(100);
- /* enable FDC, but defer interrupts a moment */
- fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
- TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN);
- DELAY(100);
- fdout_wr(fdc, fdc->fdout);
- TRACE1("[0x%x->FDOUT]", fdc->fdout);
-#endif
-
- /* XXX after a reset, silently believe the FDC will accept commands */
-#ifdef PC98
- (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
- NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
- 0);
-#else
- (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
- NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
- 0);
-#endif
- if (fdc->flags & FDC_HAS_FIFO)
- (void) enable_fifo(fdc);
-}
-
-/*
- * FDC IO functions, take care of the main status register, timeout
- * in case the desired status bits are never set.
- *
- * These PIO loops initially start out with short delays between
- * each iteration in the expectation that the required condition
- * is usually met quickly, so it can be handled immediately. After
- * about 1 ms, stepping is increased to achieve a better timing
- * accuracy in the calls to DELAY().
- */
-static int
-fd_in(struct fdc_data *fdc, int *ptr)
-{
- int i, j, step;
-
- for (j = 0, step = 1;
- (i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) != (NE7_DIO|NE7_RQM) &&
- j < FDSTS_TIMEOUT;
- j += step) {
- if (i == NE7_RQM)
- return (fdc_err(fdc, "ready for output in input\n"));
- if (j == 1000)
- step = 1000;
- DELAY(step);
- }
- if (j >= FDSTS_TIMEOUT)
- return (fdc_err(fdc, bootverbose? "input ready timeout\n": 0));
-#ifdef FDC_DEBUG
- i = fddata_rd(fdc);
- TRACE1("[FDDATA->0x%x]", (unsigned char)i);
- *ptr = i;
- return (0);
-#else /* !FDC_DEBUG */
- i = fddata_rd(fdc);
- if (ptr)
- *ptr = i;
- return (0);
-#endif /* FDC_DEBUG */
-}
-
-static int
-out_fdc(struct fdc_data *fdc, int x)
-{
- int i, j, step;
-
- for (j = 0, step = 1;
- (i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) != NE7_RQM &&
- j < FDSTS_TIMEOUT;
- j += step) {
- if (i == (NE7_DIO|NE7_RQM))
- return (fdc_err(fdc, "ready for input in output\n"));
- if (j == 1000)
- step = 1000;
- DELAY(step);
- }
- if (j >= FDSTS_TIMEOUT)
- return (fdc_err(fdc, bootverbose? "output ready timeout\n": 0));
-
- /* Send the command and return */
- fddata_wr(fdc, x);
- TRACE1("[0x%x->FDDATA]", x);
- return (0);
-}
-
-/*
- * Block device driver interface functions (interspersed with even more
- * auxiliary functions).
- */
-static int
-fdopen(struct cdev *dev, int flags, int mode, struct thread *td)
-{
- fd_p fd;
- fdc_p fdc;
-#ifdef PC98
- fdu_t fdu;
-#endif
- int rv, unitattn, dflags;
-
- fd = dev->si_drv1;
- if (fd == NULL)
- return (ENXIO);
- fdc = fd->fdc;
- if ((fdc == NULL) || (fd->type == FDT_NONE))
- return (ENXIO);
-#ifdef PC98
- fdu = fd->fdu;
-#endif
- dflags = device_get_flags(fd->dev);
- /*
- * This is a bit bogus. It's still possible that e. g. a
- * descriptor gets inherited to a child, but then it's at
- * least for the same subdevice. By checking FD_OPEN here, we
- * can ensure that a device isn't attempted to be opened with
- * different densities at the same time where the second open
- * could clobber the settings from the first one.
- */
- if (fd->flags & FD_OPEN)
- return (EBUSY);
-
-#ifdef PC98
- if (pc98_fd_check_ready(fdu) == -1)
- return(EIO);
-#endif
-
- if (flags & FNONBLOCK) {
- /*
- * Unfortunately, physio(9) discards its ioflag
- * argument, thus preventing us from seeing the
- * O_NONBLOCK bit. So we need to keep track
- * ourselves.
- */
- fd->flags |= FD_NONBLOCK;
- fd->ft = 0;
- } else {
- /*
- * Figure out a unit attention condition.
- *
- * If UA has been forced, proceed.
- *
- * If the drive has no changeline support,
- * or if the drive parameters have been lost
- * due to previous non-blocking access,
- * assume a forced UA condition.
- *
- * If motor is off, turn it on for a moment
- * and select our drive, in order to read the
- * UA hardware signal.
- *
- * If motor is on, and our drive is currently
- * selected, just read the hardware bit.
- *
- * If motor is on, but active for another
- * drive on that controller, we are lost. We
- * cannot risk to deselect the other drive, so
- * we just assume a forced UA condition to be
- * on the safe side.
- */
- unitattn = 0;
- if ((dflags & FD_NO_CHLINE) != 0 ||
- (fd->flags & FD_UA) != 0 ||
- fd->ft == 0) {
- unitattn = 1;
- fd->flags &= ~FD_UA;
-#ifndef PC98
- } else if (fdc->fdout & (FDO_MOEN0 | FDO_MOEN1 |
- FDO_MOEN2 | FDO_MOEN3)) {
- if ((fdc->fdout & FDO_FDSEL) == fd->fdsu)
- unitattn = fdin_rd(fdc) & FDI_DCHG;
- else
- unitattn = 1;
- } else {
- set_motor(fdc, fd->fdsu, TURNON);
- unitattn = fdin_rd(fdc) & FDI_DCHG;
- set_motor(fdc, fd->fdsu, TURNOFF);
-#endif /* PC98 */
- }
- if (unitattn && (rv = fdautoselect(dev)) != 0)
- return (rv);
- }
- fd->flags |= FD_OPEN;
-
- if ((fdc->flags & FDC_NODMA) == 0) {
- if (fdc->dmacnt++ == 0) {
- isa_dma_acquire(fdc->dmachan);
- isa_dmainit(fdc->dmachan, MAX_SEC_SIZE);
- }
- }
-
- /*
- * Clearing the DMA overrun counter at open time is a bit messy.
- * Since we're only managing one counter per controller, opening
- * the second drive could mess it up. Anyway, if the DMA overrun
- * condition is really persistent, it will eventually time out
- * still. OTOH, clearing it here will ensure we'll at least start
- * trying again after a previous (maybe even long ago) failure.
- * Also, this is merely a stop-gap measure only that should not
- * happen during normal operation, so we can tolerate it to be a
- * bit sloppy about this.
- */
- fdc->dma_overruns = 0;
-
- return 0;
-}
-
-static int
-fdclose(struct cdev *dev, int flags, int mode, struct thread *td)
-{
- struct fd_data *fd;
- fdc_p fdc;
-
- fd = dev->si_drv1;
- fdc = fd->fdc;
- fd->flags &= ~(FD_OPEN | FD_NONBLOCK);
- fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR);
-
- if ((fdc->flags & FDC_NODMA) == 0)
- if (--fdc->dmacnt == 0)
- isa_dma_release(fdc->dmachan);
-
- return (0);
-}
-
-static void
-fdstrategy(struct bio *bp)
-{
- long blknum, nblocks;
- int s;
- fdu_t fdu;
- fdc_p fdc;
- fd_p fd;
- size_t fdblk;
-
- fd = bp->bio_dev->si_drv1;
- fdu = fd->fdu;
- fdc = fd->fdc;
- bp->bio_resid = bp->bio_bcount;
- if (fd->type == FDT_NONE || fd->ft == 0) {
- if (fd->type != FDT_NONE && (fd->flags & FD_NONBLOCK))
- bp->bio_error = EAGAIN;
- else
- bp->bio_error = ENXIO;
- bp->bio_flags |= BIO_ERROR;
- goto bad;
- }
- fdblk = 128 << (fd->ft->secsize);
- if (bp->bio_cmd != FDBIO_FORMAT && bp->bio_cmd != FDBIO_RDSECTID) {
- if (fd->flags & FD_NONBLOCK) {
- bp->bio_error = EAGAIN;
- bp->bio_flags |= BIO_ERROR;
- goto bad;
- }
- if (bp->bio_offset < 0) {
- printf(
- "fd%d: fdstrat: bad request offset = %ju, bcount = %ld\n",
- fdu, (intmax_t)bp->bio_offset, bp->bio_bcount);
- bp->bio_error = EINVAL;
- bp->bio_flags |= BIO_ERROR;
- goto bad;
- }
- if ((bp->bio_bcount % fdblk) != 0) {
- bp->bio_error = EINVAL;
- bp->bio_flags |= BIO_ERROR;
- goto bad;
- }
- }
-
- /*
- * Set up block calculations.
- */
-#ifndef PC98
- if (bp->bio_offset >= ((off_t)128 << fd->ft->secsize) * fd->ft->size) {
- bp->bio_error = EINVAL;
- bp->bio_flags |= BIO_ERROR;
- goto bad;
- }
-#endif
- blknum = bp->bio_offset / fdblk;
- nblocks = fd->ft->size;
- if (blknum + bp->bio_bcount / fdblk > nblocks) {
- if (blknum >= nblocks) {
- if (bp->bio_cmd != BIO_READ) {
- bp->bio_error = ENOSPC;
- bp->bio_flags |= BIO_ERROR;
- }
- goto bad; /* not always bad, but EOF */
- }
- bp->bio_bcount = (nblocks - blknum) * fdblk;
- }
- bp->bio_pblkno = blknum;
- s = splbio();
- bioq_disksort(&fdc->head, bp);
- untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */
- devstat_start_transaction_bio(fd->device_stats, bp);
- device_busy(fd->dev);
- fdstart(fdc);
- splx(s);
- return;
-
-bad:
- biodone(bp);
-}
-
-/*
- * fdstart
- *
- * We have just queued something. If the controller is not busy
- * then simulate the case where it has just finished a command
- * So that it (the interrupt routine) looks on the queue for more
- * work to do and picks up what we just added.
- *
- * If the controller is already busy, we need do nothing, as it
- * will pick up our work when the present work completes.
- */
-static void
-fdstart(struct fdc_data *fdc)
-{
- int s;
-
- s = splbio();
- if(fdc->state == DEVIDLE)
- {
- fdc_intr(fdc);
- }
- splx(s);
-}
-
-static void
-fd_iotimeout(void *xfdc)
-{
- fdc_p fdc;
- int s;
-
- fdc = xfdc;
- TRACE1("fd%d[fd_iotimeout()]", fdc->fdu);
-
- /*
- * Due to IBM's brain-dead design, the FDC has a faked ready
- * signal, hardwired to ready == true. Thus, any command
- * issued if there's no diskette in the drive will _never_
- * complete, and must be aborted by resetting the FDC.
- * Many thanks, Big Blue!
- * The FDC must not be reset directly, since that would
- * interfere with the state machine. Instead, pretend that
- * the command completed but was invalid. The state machine
- * will reset the FDC and retry once.
- */
- s = splbio();
- fdc->status[0] = NE7_ST0_IC_IV;
- fdc->flags &= ~FDC_STAT_VALID;
- fdc->state = IOTIMEDOUT;
- fdc_intr(fdc);
- splx(s);
-}
-
-/* Just ensure it has the right spl. */
-static void
-fd_pseudointr(void *xfdc)
-{
- int s;
-
- s = splbio();
- fdc_intr(xfdc);
- splx(s);
-}
-
-/*
- * fdc_intr
- *
- * Keep calling the state machine until it returns a 0.
- * Always called at splbio.
- */
-static void
-fdc_intr(void *xfdc)
-{
- fdc_p fdc = xfdc;
- while(fdstate(fdc))
- ;
-}
-
-/*
- * Magic pseudo-DMA initialization for YE FDC. Sets count and
- * direction.
- */
-#define SET_BCDR(fdc,wr,cnt,port) \
- bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port, \
- ((cnt)-1) & 0xff); \
- bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port + 1, \
- ((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f)));
-
-/*
- * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy.
- */
-static int
-fdcpio(fdc_p fdc, long flags, caddr_t addr, u_int count)
-{
- u_char *cptr = (u_char *)addr;
-
- if (flags == BIO_READ) {
- if (fdc->state != PIOREAD) {
- fdc->state = PIOREAD;
- return(0);
- }
- SET_BCDR(fdc, 0, count, 0);
- bus_space_read_multi_1(fdc->portt, fdc->porth, fdc->port_off +
- FDC_YE_DATAPORT, cptr, count);
- } else {
- bus_space_write_multi_1(fdc->portt, fdc->porth, fdc->port_off +
- FDC_YE_DATAPORT, cptr, count);
- SET_BCDR(fdc, 0, count, 0);
- }
- return(1);
-}
-
-/*
- * Try figuring out the density of the media present in our device.
- */
-static int
-fdautoselect(struct cdev *dev)
-{
- fd_p fd;
- struct fd_type *fdtp;
- struct fdc_readid id;
- int i, n, oopts, rv;
-
- fd = dev->si_drv1;
-
- switch (fd->type) {
- default:
- return (ENXIO);
-
-#ifndef PC98
- case FDT_360K:
- case FDT_720K:
- /* no autoselection on those drives */
- fd->ft = fd_native_types + fd->type;
- return (0);
-#endif
-
- case FDT_12M:
- fdtp = fd_searchlist_12m;
- n = sizeof fd_searchlist_12m / sizeof(struct fd_type);
- break;
-
- case FDT_144M:
- fdtp = fd_searchlist_144m;
- n = sizeof fd_searchlist_144m / sizeof(struct fd_type);
- break;
-
-#ifndef PC98
- case FDT_288M:
- fdtp = fd_searchlist_288m;
- n = sizeof fd_searchlist_288m / sizeof(struct fd_type);
- break;
-#endif
- }
-
- /*
- * Try reading sector ID fields, first at cylinder 0, head 0,
- * then at cylinder 2, head N. We don't probe cylinder 1,
- * since for 5.25in DD media in a HD drive, there are no data
- * to read (2 step pulses per media cylinder required). For
- * two-sided media, the second probe always goes to head 1, so
- * we can tell them apart from single-sided media. As a
- * side-effect this means that single-sided media should be
- * mentioned in the search list after two-sided media of an
- * otherwise identical density. Media with a different number
- * of sectors per track but otherwise identical parameters
- * cannot be distinguished at all.
- *
- * If we successfully read an ID field on both cylinders where
- * the recorded values match our expectation, we are done.
- * Otherwise, we try the next density entry from the table.
- *
- * Stepping to cylinder 2 has the side-effect of clearing the
- * unit attention bit.
- */
- oopts = fd->options;
- fd->options |= FDOPT_NOERRLOG | FDOPT_NORETRY;
- for (i = 0; i < n; i++, fdtp++) {
- fd->ft = fdtp;
-
- id.cyl = id.head = 0;
- rv = fdmisccmd(dev, FDBIO_RDSECTID, &id);
- if (rv != 0)
- continue;
- if (id.cyl != 0 || id.head != 0 ||
- id.secshift != fdtp->secsize)
- continue;
- id.cyl = 2;
- id.head = fd->ft->heads - 1;
- rv = fdmisccmd(dev, FDBIO_RDSECTID, &id);
- if (id.cyl != 2 || id.head != fdtp->heads - 1 ||
- id.secshift != fdtp->secsize)
- continue;
- if (rv == 0)
- break;
- }
-
- fd->options = oopts;
- if (i == n) {
- if (bootverbose)
- device_printf(fd->dev, "autoselection failed\n");
- fd->ft = 0;
- return (EIO);
- } else {
- if (bootverbose)
- device_printf(fd->dev, "autoselected %d KB medium\n",
-#ifdef PC98
- (128 << (fd->ft->secsize)) *
- fd->ft->size / 1024);
-#else
- fd->ft->size / 2);
-#endif
- return (0);
- }
-}
-
-
-/*
- * The controller state machine.
- *
- * If it returns a non zero value, it should be called again immediately.
- */
-static int
-fdstate(fdc_p fdc)
-{
- struct fdc_readid *idp;
- int read, format, rdsectid, cylinder, head, i, sec = 0, sectrac;
- int st0, cyl, st3, idf, ne7cmd, mfm, steptrac;
- unsigned long blknum;
- fdu_t fdu = fdc->fdu;
- fd_p fd;
- register struct bio *bp;
- struct fd_formb *finfo = NULL;
- size_t fdblk;
-
- bp = fdc->bp;
- if (bp == NULL) {
- bp = bioq_takefirst(&fdc->head);
- if (bp != NULL)
- fdc->bp = bp;
- }
- if (bp == NULL) {
- /*
- * Nothing left for this controller to do,
- * force into the IDLE state.
- */
- fdc->state = DEVIDLE;
- if (fdc->fd) {
- device_printf(fdc->fdc_dev,
- "unexpected valid fd pointer\n");
- fdc->fd = (fd_p) 0;
- fdc->fdu = -1;
- }
- TRACE1("[fdc%d IDLE]", fdc->fdcu);
- return (0);
- }
- fd = bp->bio_dev->si_drv1;
- fdu = fd->fdu;
- fdblk = 128 << fd->ft->secsize;
- if (fdc->fd && (fd != fdc->fd))
- device_printf(fd->dev, "confused fd pointers\n");
- read = bp->bio_cmd == BIO_READ;
- mfm = (fd->ft->flags & FL_MFM)? NE7CMD_MFM: 0;
- steptrac = (fd->ft->flags & FL_2STEP)? 2: 1;
- if (read)
- idf = ISADMA_READ;
- else
- idf = ISADMA_WRITE;
- format = bp->bio_cmd == FDBIO_FORMAT;
- rdsectid = bp->bio_cmd == FDBIO_RDSECTID;
- if (format)
- finfo = (struct fd_formb *)bp->bio_data;
- TRACE1("fd%d", fdu);
- TRACE1("[%s]", fdstates[fdc->state]);
- TRACE1("(0x%x)", fd->flags);
- untimeout(fd_turnoff, fd, fd->toffhandle);
- fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);
- switch (fdc->state)
- {
- case DEVIDLE:
- case FINDWORK: /* we have found new work */
- fdc->retry = 0;
- fd->skip = 0;
- fdc->fd = fd;
- fdc->fdu = fdu;
-#ifdef PC98
- pc98_trans = fd->ft->trans;
- if (pc98_trans_prev != pc98_trans) {
- int i;
- set_density(fdc);
- for (i = 0; i < 10; i++) {
- outb(0x5f, 0);
- outb(0x5f, 0);
- }
- pc98_trans_prev = pc98_trans;
- }
- if (pc98_trans != fd->pc98_trans) {
- if (fd->type == FDT_144M) {
- bus_space_write_1(fdc->sc_fdemsiot,
- fdc->sc_fdemsioh,
- 0,
- (fdu << 5) | 0x10 |
- (pc98_trans >> 1));
- outb(0x5f, 0);
- outb(0x5f, 0);
- }
- fd->pc98_trans = pc98_trans;
- }
-#else
- fdc->fdctl_wr(fdc, fd->ft->trans);
-#endif
- TRACE1("[0x%x->FDCTL]", fd->ft->trans);
- /*
- * If the next drive has a motor startup pending, then
- * it will start up in its own good time.
- */
- if(fd->flags & FD_MOTOR_WAIT) {
- fdc->state = MOTORWAIT;
- return (0); /* will return later */
- }
- /*
- * Maybe if it's not starting, it SHOULD be starting.
- */
-#ifdef EPSON_NRDISK
- if (fdu != nrdu) {
- if (!(fd->flags & FD_MOTOR))
- {
- fdc->state = MOTORWAIT;
- fd_turnon(fdu);
- return(0);
- }
- else /* at least make sure we are selected */
- {
- set_motor(fdcu, fd->fdsu, TURNON);
- }
- }
-#else /* !EPSON_NRDISK */
- if (!(fd->flags & FD_MOTOR))
- {
- fdc->state = MOTORWAIT;
- fd_turnon(fd);
- return (0); /* will return later */
- }
- else /* at least make sure we are selected */
- {
- set_motor(fdc, fd->fdsu, TURNON);
- }
-#endif
- if (fdc->flags & FDC_NEEDS_RESET) {
- fdc->state = RESETCTLR;
- fdc->flags &= ~FDC_NEEDS_RESET;
- } else
- fdc->state = DOSEEK;
- return (1); /* will return immediately */
-
- case DOSEEK:
- blknum = bp->bio_pblkno + fd->skip / fdblk;
- cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
- if (cylinder == fd->track)
- {
- fdc->state = SEEKCOMPLETE;
- return (1); /* will return immediately */
- }
-#ifdef PC98
- pc98_fd_check_ready(fdu);
-#endif
- if (fd_cmd(fdc, 3, NE7CMD_SEEK,
- fd->fdsu, cylinder * steptrac, 0))
- {
- /*
- * Seek command not accepted, looks like
- * the FDC went off to the Saints...
- */
- fdc->retry = 6; /* try a reset */
- return(retrier(fdc));
- }
- fd->track = FD_NO_TRACK;
- fdc->state = SEEKWAIT;
- return(0); /* will return later */
-
- case SEEKWAIT:
- /* allow heads to settle */
- timeout(fd_pseudointr, fdc, hz / 16);
- fdc->state = SEEKCOMPLETE;
- return(0); /* will return later */
-
- case SEEKCOMPLETE : /* seek done, start DMA */
- blknum = bp->bio_pblkno + fd->skip / fdblk;
- cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
-
- /* Make sure seek really happened. */
- if(fd->track == FD_NO_TRACK) {
- int descyl = cylinder * steptrac;
- do {
- /*
- * This might be a "ready changed" interrupt,
- * which cannot really happen since the
- * RDY pin is hardwired to + 5 volts. This
- * generally indicates a "bouncing" intr
- * line, so do one of the following:
- *
- * When running on an enhanced FDC that is
- * known to not go stuck after responding
- * with INVALID, fetch all interrupt states
- * until seeing either an INVALID or a
- * real interrupt condition.
- *
- * When running on a dumb old NE765, give
- * up immediately. The controller will
- * provide up to four dummy RC interrupt
- * conditions right after reset (for the
- * corresponding four drives), so this is
- * our only chance to get notice that it
- * was not the FDC that caused the interrupt.
- */
- if (fd_sense_int(fdc, &st0, &cyl)
- == FD_NOT_VALID)
- return (0); /* will return later */
- if(fdc->fdct == FDC_NE765
- && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
- return (0); /* hope for a real intr */
- } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
-
- if (0 == descyl) {
- int failed = 0;
- /*
- * seek to cyl 0 requested; make sure we are
- * really there
- */
- if (fd_sense_drive_status(fdc, &st3))
- failed = 1;
-#ifdef EPSON_NRDISK
- if (fdu == nrdu) st3 = NE7_ST3_T0;
-#endif /* EPSON_NRDISK */
- if ((st3 & NE7_ST3_T0) == 0) {
- printf(
- "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n",
- fdu, st3, NE7_ST3BITS);
- failed = 1;
- }
-
- if (failed) {
- if(fdc->retry < 3)
- fdc->retry = 3;
- return (retrier(fdc));
- }
- }
-#ifdef EPSON_NRDISK
- if (fdu == nrdu) cyl = descyl;
-#endif
-
- if (cyl != descyl) {
- printf(
- "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
- fdu, descyl, cyl, st0);
- if (fdc->retry < 3)
- fdc->retry = 3;
- return (retrier(fdc));
- }
- }
-
- fd->track = cylinder;
- if (format)
- fd->skip = (char *)&(finfo->fd_formb_cylno(0))
- - (char *)finfo;
-#ifdef EPSON_NRDISK
- if (fdu != nrdu) {
-#endif /* EPSON_NRDISK */
- if (!rdsectid && !(fdc->flags & FDC_NODMA))
- isa_dmastart(idf, bp->bio_data+fd->skip,
- format ? bp->bio_bcount : fdblk, fdc->dmachan);
- blknum = bp->bio_pblkno + fd->skip / fdblk;
- sectrac = fd->ft->sectrac;
- sec = blknum % (sectrac * fd->ft->heads);
- head = sec / sectrac;
- sec = sec % sectrac + 1;
- if (head != 0 && fd->ft->offset_side2 != 0)
- sec += fd->ft->offset_side2;
- fd->hddrv = ((head&1)<<2)+fdu;
-
- if(format || !(read || rdsectid))
- {
- /* make sure the drive is writable */
- if(fd_sense_drive_status(fdc, &st3) != 0)
- {
- /* stuck controller? */
- if (!(fdc->flags & FDC_NODMA))
- isa_dmadone(idf,
- bp->bio_data + fd->skip,
- format ? bp->bio_bcount : fdblk,
- fdc->dmachan);
- fdc->retry = 6; /* reset the beast */
- return (retrier(fdc));
- }
- if(st3 & NE7_ST3_WP)
- {
- /*
- * XXX YES! this is ugly.
- * in order to force the current operation
- * to fail, we will have to fake an FDC
- * error - all error handling is done
- * by the retrier()
- */
- fdc->status[0] = NE7_ST0_IC_AT;
- fdc->status[1] = NE7_ST1_NW;
- fdc->status[2] = 0;
- fdc->status[3] = fd->track;
- fdc->status[4] = head;
- fdc->status[5] = sec;
- fdc->retry = 8; /* break out immediately */
- fdc->state = IOTIMEDOUT; /* not really... */
- return (1); /* will return immediately */
- }
- }
-
- if (format) {
- ne7cmd = NE7CMD_FORMAT | mfm;
- if (fdc->flags & FDC_NODMA) {
- /*
- * This seems to be necessary for
- * whatever obscure reason; if we omit
- * it, we end up filling the sector ID
- * fields of the newly formatted track
- * entirely with garbage, causing
- * `wrong cylinder' errors all over
- * the place when trying to read them
- * back.
- *
- * Umpf.
- */
- SET_BCDR(fdc, 1, bp->bio_bcount, 0);
-
- (void)fdcpio(fdc,bp->bio_cmd,
- bp->bio_data+fd->skip,
- bp->bio_bcount);
-
- }
- /* formatting */
- if(fd_cmd(fdc, 6, ne7cmd, head << 2 | fdu,
- finfo->fd_formb_secshift,
- finfo->fd_formb_nsecs,
- finfo->fd_formb_gaplen,
- finfo->fd_formb_fillbyte, 0)) {
- /* controller fell over */
- if (!(fdc->flags & FDC_NODMA))
- isa_dmadone(idf,
- bp->bio_data + fd->skip,
- format ? bp->bio_bcount : fdblk,
- fdc->dmachan);
- fdc->retry = 6;
- return (retrier(fdc));
- }
- } else if (rdsectid) {
- ne7cmd = NE7CMD_READID | mfm;
- if (fd_cmd(fdc, 2, ne7cmd, head << 2 | fdu, 0)) {
- /* controller jamming */
- fdc->retry = 6;
- return (retrier(fdc));
- }
- } else {
- /* read or write operation */
- ne7cmd = (read ? NE7CMD_READ | NE7CMD_SK : NE7CMD_WRITE) | mfm;
- if (fdc->flags & FDC_NODMA) {
- /*
- * This seems to be necessary even when
- * reading data.
- */
- SET_BCDR(fdc, 1, fdblk, 0);
-
- /*
- * Perform the write pseudo-DMA before
- * the WRITE command is sent.
- */
- if (!read)
- (void)fdcpio(fdc,bp->bio_cmd,
- bp->bio_data+fd->skip,
- fdblk);
- }
- if (fd_cmd(fdc, 9,
- ne7cmd,
- head << 2 | fdu, /* head & unit */
- fd->track, /* track */
- head,
- sec, /* sector + 1 */
- fd->ft->secsize, /* sector size */
- sectrac, /* sectors/track */
- fd->ft->gap, /* gap size */
- fd->ft->datalen, /* data length */
- 0)) {
- /* the beast is sleeping again */
- if (!(fdc->flags & FDC_NODMA))
- isa_dmadone(idf,
- bp->bio_data + fd->skip,
- format ? bp->bio_bcount : fdblk,
- fdc->dmachan);
- fdc->retry = 6;
- return (retrier(fdc));
- }
- }
- if (!rdsectid && (fdc->flags & FDC_NODMA))
- /*
- * If this is a read, then simply await interrupt
- * before performing PIO.
- */
- if (read && !fdcpio(fdc,bp->bio_cmd,
- bp->bio_data+fd->skip,fdblk)) {
- fd->tohandle = timeout(fd_iotimeout, fdc, hz);
- return(0); /* will return later */
- }
-
- /*
- * Write (or format) operation will fall through and
- * await completion interrupt.
- */
- fdc->state = IOCOMPLETE;
- fd->tohandle = timeout(fd_iotimeout, fdc, hz);
- return (0); /* will return later */
-#ifdef EPSON_NRDISK
- }
- else {
- nrdblkn = (nrd_t)((unsigned long)bp->b_blkno*DEV_BSIZE/fdblk
- + fd->skip/fdblk);
- nrd_LED_on();
- nrd_addrset(fdblk * nrdblkn);
- while (!nrd_check_ready()) DELAY(1);
- if (read) epson_insw(P_NRD_DATA,
- bp->bio_data + fd->skip,
- fdblk / sizeof(short));
- else epson_outsw(P_NRD_DATA,
- bp->bio_data + fd->skip,
- (format ? bp->bio_bcount : fdblk)
- / sizeof(short));
-
- blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/fdblk
- + fd->skip/fdblk;
- sectrac = fd->ft->sectrac;
- sec = blknum % (sectrac * fd->ft->heads);
- head = sec / sectrac;
- sec = sec % sectrac + 1;
- fd->hddrv = ((head&1)<<2)+fdu;
-
- if (nrdsec++ >= nrd_sec())
- nrdaddr = (nrd_t)(fd->track * 8 + head * 4);
- nrdsec = sec;
- fdc->state = IOCOMPLETE;
- }
-#endif
-
- case PIOREAD:
- /*
- * Actually perform the PIO read. The IOCOMPLETE case
- * removes the timeout for us.
- */
- (void)fdcpio(fdc,bp->bio_cmd,bp->bio_data+fd->skip,fdblk);
- fdc->state = IOCOMPLETE;
- /* FALLTHROUGH */
- case IOCOMPLETE: /* IO done, post-analyze */
-#ifdef EPSON_NRDISK
- if (fdu != nrdu)
- untimeout(fd_iotimeout, fdc, fd->tohandle);
-#else
- untimeout(fd_iotimeout, fdc, fd->tohandle);
-#endif
-
- if (fd_read_status(fdc)) {
- if (!rdsectid && !(fdc->flags & FDC_NODMA))
- isa_dmadone(idf, bp->bio_data + fd->skip,
- format ? bp->bio_bcount : fdblk,
- fdc->dmachan);
- if (fdc->retry < 6)
- fdc->retry = 6; /* force a reset */
- return (retrier(fdc));
- }
-
- fdc->state = IOTIMEDOUT;
-
- /* FALLTHROUGH */
- case IOTIMEDOUT:
-#ifdef EPSON_NRDISK
- if (fdu != nrdu) {
-#endif /* EPSON_NRDISK */
- if (!rdsectid && !(fdc->flags & FDC_NODMA))
- isa_dmadone(idf, bp->bio_data + fd->skip,
- format ? bp->bio_bcount : fdblk, fdc->dmachan);
-#ifdef EPSON_NRDISK
- }
- else nrd_LED_off();
-#endif /* EPSON_NRDISK */
- if (fdc->status[0] & NE7_ST0_IC) {
- if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
- && fdc->status[1] & NE7_ST1_OR) {
- /*
- * DMA overrun. Someone hogged the bus and
- * didn't release it in time for the next
- * FDC transfer.
- *
- * We normally restart this without bumping
- * the retry counter. However, in case
- * something is seriously messed up (like
- * broken hardware), we rather limit the
- * number of retries so the IO operation
- * doesn't block indefinately.
- */
- if (fdc->dma_overruns++ < FDC_DMAOV_MAX) {
- fdc->state = SEEKCOMPLETE;
- return (1);/* will return immediately */
- } /* else fall through */
- }
- if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV
- && fdc->retry < 6)
- fdc->retry = 6; /* force a reset */
- else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
- && fdc->status[2] & NE7_ST2_WC
- && fdc->retry < 3)
- fdc->retry = 3; /* force recalibrate */
- return (retrier(fdc));
- }
- /* All OK */
- if (rdsectid) {
- /* copy out ID field contents */
- idp = (struct fdc_readid *)bp->bio_data;
- idp->cyl = fdc->status[3];
- idp->head = fdc->status[4];
- idp->sec = fdc->status[5];
- idp->secshift = fdc->status[6];
- }
- /* Operation successful, retry DMA overruns again next time. */
- fdc->dma_overruns = 0;
- fd->skip += fdblk;
- if (!rdsectid && !format && fd->skip < bp->bio_bcount) {
- /* set up next transfer */
- fdc->state = DOSEEK;
- } else {
- /* ALL DONE */
- fd->skip = 0;
- bp->bio_resid = 0;
- fdc->bp = NULL;
- device_unbusy(fd->dev);
- biofinish(bp, fd->device_stats, 0);
- fdc->fd = (fd_p) 0;
- fdc->fdu = -1;
- fdc->state = FINDWORK;
- }
- return (1); /* will return immediately */
-
- case RESETCTLR:
- fdc_reset(fdc);
- fdc->retry++;
- fdc->state = RESETCOMPLETE;
- return (0); /* will return later */
-
- case RESETCOMPLETE:
- /*
- * Discard all the results from the reset so that they
- * can't cause an unexpected interrupt later.
- */
- for (i = 0; i < 4; i++)
- (void)fd_sense_int(fdc, &st0, &cyl);
- fdc->state = STARTRECAL;
- /* FALLTHROUGH */
- case STARTRECAL:
-#ifdef PC98
- pc98_fd_check_ready(fdu);
-#endif
- if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) {
- /* arrgl */
- fdc->retry = 6;
- return (retrier(fdc));
- }
- fdc->state = RECALWAIT;
- return (0); /* will return later */
-
- case RECALWAIT:
- /* allow heads to settle */
- timeout(fd_pseudointr, fdc, hz / 8);
- fdc->state = RECALCOMPLETE;
- return (0); /* will return later */
-
- case RECALCOMPLETE:
- do {
- /*
- * See SEEKCOMPLETE for a comment on this:
- */
- if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
- return (0); /* will return later */
- if(fdc->fdct == FDC_NE765
- && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
- return (0); /* hope for a real intr */
- } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
-#ifdef EPSON_NRDISK
- if (fdu == nrdu) {
- st0 = NE7_ST0_IC_NT;
- cyl = 0;
- }
-#endif
- if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0)
- {
- if(fdc->retry > 3)
- /*
- * A recalibrate from beyond cylinder 77
- * will "fail" due to the FDC limitations;
- * since people used to complain much about
- * the failure message, try not logging
- * this one if it seems to be the first
- * time in a line.
- */
- printf("fd%d: recal failed ST0 %b cyl %d\n",
- fdu, st0, NE7_ST0BITS, cyl);
- if(fdc->retry < 3) fdc->retry = 3;
- return (retrier(fdc));
- }
- fd->track = 0;
- /* Seek (probably) necessary */
- fdc->state = DOSEEK;
- return (1); /* will return immediately */
-
- case MOTORWAIT:
- if(fd->flags & FD_MOTOR_WAIT)
- {
- return (0); /* time's not up yet */
- }
- if (fdc->flags & FDC_NEEDS_RESET) {
- fdc->state = RESETCTLR;
- fdc->flags &= ~FDC_NEEDS_RESET;
- } else
- fdc->state = DOSEEK;
- return (1); /* will return immediately */
-
- default:
- device_printf(fdc->fdc_dev, "unexpected FD int->");
- if (fd_read_status(fdc) == 0)
- printf("FDC status :%x %x %x %x %x %x %x ",
- fdc->status[0],
- fdc->status[1],
- fdc->status[2],
- fdc->status[3],
- fdc->status[4],
- fdc->status[5],
- fdc->status[6] );
- else
- printf("No status available ");
- if (fd_sense_int(fdc, &st0, &cyl) != 0)
- {
- printf("[controller is dead now]\n");
- return (0); /* will return later */
- }
- printf("ST0 = %x, PCN = %x\n", st0, cyl);
- return (0); /* will return later */
- }
- /* noone should ever get here */
-}
-
-static int
-retrier(struct fdc_data *fdc)
-{
- struct bio *bp;
- struct fd_data *fd;
- int fdu;
-
- bp = fdc->bp;
-
- /* XXX shouldn't this be cached somewhere? */
- fd = bp->bio_dev->si_drv1;
- fdu = fd->fdu;
- if (fd->options & FDOPT_NORETRY)
- goto fail;
-
- switch (fdc->retry) {
- case 0: case 1: case 2:
- fdc->state = SEEKCOMPLETE;
- break;
- case 3: case 4: case 5:
- fdc->state = STARTRECAL;
- break;
- case 6:
- fdc->state = RESETCTLR;
- break;
- case 7:
- break;
- default:
- fail:
- if ((fd->options & FDOPT_NOERRLOG) == 0) {
- disk_err(bp, "hard error",
- fdc->fd->skip / DEV_BSIZE, 0);
- if (fdc->flags & FDC_STAT_VALID) {
- printf(
- " (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n",
- fdc->status[0], NE7_ST0BITS,
- fdc->status[1], NE7_ST1BITS,
- fdc->status[2], NE7_ST2BITS,
- fdc->status[3], fdc->status[4],
- fdc->status[5]);
- }
- else
- printf(" (No status)\n");
- }
- if ((fd->options & FDOPT_NOERROR) == 0) {
- bp->bio_flags |= BIO_ERROR;
- bp->bio_error = EIO;
- bp->bio_resid = bp->bio_bcount - fdc->fd->skip;
- } else
- bp->bio_resid = 0;
- fdc->bp = NULL;
- fdc->fd->skip = 0;
- device_unbusy(fd->dev);
- biofinish(bp, fdc->fd->device_stats, 0);
- fdc->state = FINDWORK;
- fdc->flags |= FDC_NEEDS_RESET;
- fdc->fd = (fd_p) 0;
- fdc->fdu = -1;
- return (1);
- }
- fdc->retry++;
- return (1);
-}
-
-static void
-fdbiodone(struct bio *bp)
-{
- wakeup(bp);
-}
-
-static int
-fdmisccmd(struct cdev *dev, u_int cmd, void *data)
-{
- fdu_t fdu;
- fd_p fd;
- struct bio *bp;
- struct fd_formb *finfo;
- struct fdc_readid *idfield;
- size_t fdblk;
- int error;
-
- fd = dev->si_drv1;
- fdu = fd->fdu;
- fdblk = 128 << fd->ft->secsize;
- finfo = (struct fd_formb *)data;
- idfield = (struct fdc_readid *)data;
-
- bp = malloc(sizeof(struct bio), M_TEMP, M_WAITOK | M_ZERO);
-
- /*
- * Set up a bio request for fdstrategy(). bio_offset is faked
- * so that fdstrategy() will seek to the the requested
- * cylinder, and use the desired head.
- */
- bp->bio_cmd = cmd;
- if (cmd == FDBIO_FORMAT) {
- bp->bio_offset =
- (finfo->cyl * (fd->ft->sectrac * fd->ft->heads) +
- finfo->head * fd->ft->sectrac) * fdblk;
- bp->bio_bcount = sizeof(struct fd_idfield_data) *
- finfo->fd_formb_nsecs;
- } else if (cmd == FDBIO_RDSECTID) {
- bp->bio_offset =
- (idfield->cyl * (fd->ft->sectrac * fd->ft->heads) +
- idfield->head * fd->ft->sectrac) * fdblk;
- bp->bio_bcount = sizeof(struct fdc_readid);
- } else
- panic("wrong cmd in fdmisccmd()");
- bp->bio_data = data;
- bp->bio_dev = dev;
- bp->bio_done = fdbiodone;
- bp->bio_flags = 0;
-
- /* Now run the command. */
- fdstrategy(bp);
- error = biowait(bp, "fdcmd");
-
- free(bp, M_TEMP);
- return (error);
-}
-
-static int
-fdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
-{
- fdu_t fdu;
- fd_p fd;
- struct fdc_status *fsp;
- struct fdc_readid *rid;
- int error;
-
- fd = dev->si_drv1;
- fdu = fd->fdu;
-
-#ifdef PC98
- pc98_fd_check_ready(fdu);
-#endif
-
- /*
- * First, handle everything that could be done with
- * FD_NONBLOCK still being set.
- */
- switch (cmd) {
-
- case DIOCGMEDIASIZE:
- if (fd->ft == 0)
- return ((fd->flags & FD_NONBLOCK) ? EAGAIN : ENXIO);
- *(off_t *)addr = (128 << (fd->ft->secsize)) * fd->ft->size;
- return (0);
-
- case DIOCGSECTORSIZE:
- if (fd->ft == 0)
- return ((fd->flags & FD_NONBLOCK) ? EAGAIN : ENXIO);
- *(u_int *)addr = 128 << (fd->ft->secsize);
- return (0);
-
- case FIONBIO:
- if (*(int *)addr != 0)
- fd->flags |= FD_NONBLOCK;
- else {
- if (fd->ft == 0) {
- /*
- * No drive type has been selected yet,
- * cannot turn FNONBLOCK off.
- */
- return (EINVAL);
- }
- fd->flags &= ~FD_NONBLOCK;
- }
- return (0);
-
- case FIOASYNC:
- /* keep the generic fcntl() code happy */
- return (0);
-
- case FD_GTYPE: /* get drive type */
- if (fd->ft == 0)
- /* no type known yet, return the native type */
- *(struct fd_type *)addr = fd_native_types[fd->type];
- else
- *(struct fd_type *)addr = *fd->ft;
- return (0);
-
- case FD_STYPE: /* set drive type */
- /*
- * Allow setting drive type temporarily iff
- * currently unset. Used for fdformat so any
- * user can set it, and then start formatting.
- */
- if (fd->ft)
- return (EINVAL); /* already set */
- fd->fts[0] = *(struct fd_type *)addr;
- fd->ft = &fd->fts[0];
- fd->flags |= FD_UA;
- return (0);
-
- case FD_GOPTS: /* get drive options */
- *(int *)addr = fd->options + FDOPT_AUTOSEL;
- return (0);
-
- case FD_SOPTS: /* set drive options */
- fd->options = *(int *)addr & ~FDOPT_AUTOSEL;
- return (0);
-
-#ifdef FDC_DEBUG
- case FD_DEBUG:
- if ((fd_debug != 0) != (*(int *)addr != 0)) {
- fd_debug = (*(int *)addr != 0);
- printf("fd%d: debugging turned %s\n",
- fd->fdu, fd_debug ? "on" : "off");
- }
- return (0);
-#endif
-
- case FD_CLRERR:
- if (suser(td) != 0)
- return (EPERM);
- fd->fdc->fdc_errs = 0;
- return (0);
-
- case FD_GSTAT:
- fsp = (struct fdc_status *)addr;
- if ((fd->fdc->flags & FDC_STAT_VALID) == 0)
- return (EINVAL);
- memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int));
- return (0);
-
- case FD_GDTYPE:
- *(enum fd_drivetype *)addr = fd->type;
- return (0);
- }
-
- /*
- * Now handle everything else. Make sure we have a valid
- * drive type.
- */
- if (fd->flags & FD_NONBLOCK)
- return (EAGAIN);
- if (fd->ft == 0)
- return (ENXIO);
- error = 0;
-
- switch (cmd) {
-
- case FD_FORM:
- if ((flag & FWRITE) == 0)
- return (EBADF); /* must be opened for writing */
- if (((struct fd_formb *)addr)->format_version !=
- FD_FORMAT_VERSION)
- return (EINVAL); /* wrong version of formatting prog */
- error = fdmisccmd(dev, FDBIO_FORMAT, addr);
- break;
-
- case FD_GTYPE: /* get drive type */
- *(struct fd_type *)addr = *fd->ft;
- break;
-
- case FD_STYPE: /* set drive type */
- /* this is considered harmful; only allow for superuser */
- if (suser(td) != 0)
- return (EPERM);
- *fd->ft = *(struct fd_type *)addr;
- break;
-
- case FD_GOPTS: /* get drive options */
- *(int *)addr = fd->options;
- break;
-
- case FD_SOPTS: /* set drive options */
- fd->options = *(int *)addr;
- break;
-
-#ifdef FDC_DEBUG
- case FD_DEBUG:
- if ((fd_debug != 0) != (*(int *)addr != 0)) {
- fd_debug = (*(int *)addr != 0);
- printf("fd%d: debugging turned %s\n",
- fd->fdu, fd_debug ? "on" : "off");
- }
- break;
-#endif
-
- case FD_CLRERR:
- if (suser(td) != 0)
- return (EPERM);
- fd->fdc->fdc_errs = 0;
- break;
-
- case FD_GSTAT:
- fsp = (struct fdc_status *)addr;
- if ((fd->fdc->flags & FDC_STAT_VALID) == 0)
- return (EINVAL);
- memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int));
- break;
-
- case FD_READID:
- rid = (struct fdc_readid *)addr;
- if (rid->cyl > MAX_CYLINDER || rid->head > MAX_HEAD)
- return (EINVAL);
- error = fdmisccmd(dev, FDBIO_RDSECTID, addr);
- break;
-
- default:
- error = ENOTTY;
- break;
- }
- return (error);
-}
diff --git a/sys/pc98/pc98/fdc_cbus.c b/sys/pc98/pc98/fdc_cbus.c
deleted file mode 100644
index 0980e00..0000000
--- a/sys/pc98/pc98/fdc_cbus.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*-
- * Copyright (c) 2004 Yoshihiro TAKAHASHI
- * 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,
- * without modification, immediately at the beginning of the file.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/bio.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/rman.h>
-#include <sys/systm.h>
-
-#include <machine/bus.h>
-
-#include <pc98/pc98/fdcvar.h>
-#include <pc98/pc98/fdreg.h>
-
-#include <isa/isavar.h>
-#include <pc98/pc98/pc98.h>
-
-static bus_addr_t fdc_iat[] = {0, 2, 4};
-
-static int
-fdc_cbus_alloc_resources(device_t dev, struct fdc_data *fdc)
-{
- int rid;
-
- fdc->fdc_dev = dev;
- fdc->rid_ioport = 0;
- fdc->rid_irq = 0;
- fdc->rid_drq = 0;
- fdc->res_irq = 0;
- fdc->res_drq = 0;
-
- fdc->res_ioport = isa_alloc_resourcev(dev, SYS_RES_IOPORT,
- &fdc->rid_ioport, fdc_iat,
- 3, RF_ACTIVE);
- if (fdc->res_ioport == 0) {
- device_printf(dev, "cannot reserve I/O port range\n");
- return ENXIO;
- }
- isa_load_resourcev(fdc->res_ioport, fdc_iat, 3);
- fdc->portt = rman_get_bustag(fdc->res_ioport);
- fdc->porth = rman_get_bushandle(fdc->res_ioport);
-
- rid = 3;
- bus_set_resource(dev, SYS_RES_IOPORT, rid, IO_FDPORT, 1);
- fdc->res_fdsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
- RF_ACTIVE);
- if (fdc->res_fdsio == 0)
- return ENXIO;
- fdc->sc_fdsiot = rman_get_bustag(fdc->res_fdsio);
- fdc->sc_fdsioh = rman_get_bushandle(fdc->res_fdsio);
-
- rid = 4;
- bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x4be, 1);
- fdc->res_fdemsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
- RF_ACTIVE);
- if (fdc->res_fdemsio == 0)
- return ENXIO;
- fdc->sc_fdemsiot = rman_get_bustag(fdc->res_fdemsio);
- fdc->sc_fdemsioh = rman_get_bushandle(fdc->res_fdemsio);
-
- fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
- RF_ACTIVE);
- if (fdc->res_irq == 0) {
- device_printf(dev, "cannot reserve interrupt line\n");
- return ENXIO;
- }
-
- if ((fdc->flags & FDC_NODMA) == 0) {
- fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
- &fdc->rid_drq, RF_ACTIVE);
- if (fdc->res_drq == 0) {
- device_printf(dev, "cannot reserve DMA request line\n");
- return ENXIO;
- }
- fdc->dmachan = rman_get_start(fdc->res_drq);
- }
-
- return 0;
-}
-
-static int
-fdc_cbus_probe(device_t dev)
-{
- int error;
- struct fdc_data *fdc;
-
- fdc = device_get_softc(dev);
-
- /* Check pnp ids */
- if (isa_get_vendorid(dev))
- return (ENXIO);
-
- /* Attempt to allocate our resources for the duration of the probe */
- error = fdc_cbus_alloc_resources(dev, fdc);
- if (!error)
- error = fdc_initial_reset(fdc);
-
- fdc_release_resources(fdc);
- return (error);
-}
-
-static int
-fdc_cbus_attach(device_t dev)
-{
- struct fdc_data *fdc;
- int error;
-
- fdc = device_get_softc(dev);
-
- if ((error = fdc_cbus_alloc_resources(dev, fdc)) != 0 ||
- (error = fdc_attach(dev)) != 0 ||
- (error = fdc_hints_probe(dev)) != 0) {
- fdc_release_resources(fdc);
- return (error);
- }
-
- return (0);
-}
-
-static device_method_t fdc_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, fdc_cbus_probe),
- DEVMETHOD(device_attach, fdc_cbus_attach),
- DEVMETHOD(device_detach, fdc_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, fdc_print_child),
- DEVMETHOD(bus_read_ivar, fdc_read_ivar),
- DEVMETHOD(bus_write_ivar, fdc_write_ivar),
- /* Our children never use any other bus interface methods. */
-
- { 0, 0 }
-};
-
-static driver_t fdc_driver = {
- "fdc",
- fdc_methods,
- sizeof(struct fdc_data)
-};
-
-DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0);
diff --git a/sys/pc98/pc98/fdcvar.h b/sys/pc98/pc98/fdcvar.h
deleted file mode 100644
index 4ae53d9..0000000
--- a/sys/pc98/pc98/fdcvar.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*-
- * Copyright (c) 2004 M. Warner Losh.
- * 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,
- * without modification, immediately at the beginning of the file.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-/* XXX should audit this file to see if additional copyrights needed */
-
-enum fdc_type
-{
- FDC_NE765, FDC_ENHANCED, FDC_UNKNOWN = -1
-};
-
-enum fdc_states {
- DEVIDLE,
- FINDWORK,
- DOSEEK,
- SEEKCOMPLETE ,
- IOCOMPLETE,
- RECALCOMPLETE,
- STARTRECAL,
- RESETCTLR,
- SEEKWAIT,
- RECALWAIT,
- MOTORWAIT,
- IOTIMEDOUT,
- RESETCOMPLETE,
- PIOREAD
-};
-
-#ifdef FDC_DEBUG
-static char const * const fdstates[] = {
- "DEVIDLE",
- "FINDWORK",
- "DOSEEK",
- "SEEKCOMPLETE",
- "IOCOMPLETE",
- "RECALCOMPLETE",
- "STARTRECAL",
- "RESETCTLR",
- "SEEKWAIT",
- "RECALWAIT",
- "MOTORWAIT",
- "IOTIMEDOUT",
- "RESETCOMPLETE",
- "PIOREAD"
-};
-#endif
-
-/*
- * Per controller structure (softc).
- */
-struct fdc_data
-{
- int fdcu; /* our unit number */
- int dmacnt;
- int dmachan;
- int flags;
-#define FDC_STAT_VALID 0x08
-#define FDC_HAS_FIFO 0x10
-#define FDC_NEEDS_RESET 0x20
-#define FDC_NODMA 0x40
-#define FDC_ISPNP 0x80
-#define FDC_ISPCMCIA 0x100
- struct fd_data *fd;
- int fdu; /* the active drive */
- enum fdc_states state;
- int retry;
-#ifndef PC98
- int fdout; /* mirror of the w/o digital output reg */
-#endif
- u_int status[7]; /* copy of the registers */
- enum fdc_type fdct; /* chip version of FDC */
- int fdc_errs; /* number of logged errors */
- int dma_overruns; /* number of DMA overruns */
- struct bio_queue_head head;
- struct bio *bp; /* active buffer */
-#ifdef PC98
- struct resource *res_ioport, *res_fdsio, *res_fdemsio;
- struct resource *res_irq, *res_drq;
- int rid_ioport, rid_irq, rid_drq;
-#else
- struct resource *res_ioport, *res_ctl, *res_irq, *res_drq;
- int rid_ioport, rid_ctl, rid_irq, rid_drq;
-#endif
- int port_off;
- bus_space_tag_t portt;
- bus_space_handle_t porth;
-#ifdef PC98
- bus_space_tag_t sc_fdsiot;
- bus_space_handle_t sc_fdsioh;
- bus_space_tag_t sc_fdemsiot;
- bus_space_handle_t sc_fdemsioh;
-#else
- bus_space_tag_t ctlt;
- bus_space_handle_t ctlh;
-#endif
- void *fdc_intr;
- struct device *fdc_dev;
-#ifndef PC98
- void (*fdctl_wr)(struct fdc_data *fdc, u_int8_t v);
-#endif
-};
-
-typedef int fdu_t;
-typedef int fdcu_t;
-typedef int fdsu_t;
-typedef struct fd_data *fd_p;
-typedef struct fdc_data *fdc_p;
-typedef enum fdc_type fdc_t;
-
-/* error returns for fd_cmd() */
-#define FD_FAILED -1
-#define FD_NOT_VALID -2
-#define FDC_ERRMAX 100 /* do not log more */
-
-extern devclass_t fdc_devclass;
-
-enum fdc_device_ivars {
- FDC_IVAR_FDUNIT,
- FDC_IVAR_FDTYPE,
-};
-
-__BUS_ACCESSOR(fdc, fdunit, FDC, FDUNIT, int);
-__BUS_ACCESSOR(fdc, fdtype, FDC, FDTYPE, int);
-
-int fdc_alloc_resources(struct fdc_data *);
-#ifndef PC98
-void fdout_wr(fdc_p, u_int8_t);
-#endif
-int fd_cmd(struct fdc_data *, int, ...);
-void fdc_release_resources(struct fdc_data *);
-int fdc_attach(device_t);
-int fdc_hints_probe(device_t);
-int fdc_detach(device_t dev);
-device_t fdc_add_child(device_t, const char *, int);
-int fdc_initial_reset(struct fdc_data *);
-int fdc_print_child(device_t, device_t);
-int fdc_read_ivar(device_t, device_t, int, uintptr_t *);
-int fdc_write_ivar(device_t, device_t, int, uintptr_t);
-#ifndef PC98
-int fdc_isa_alloc_resources(device_t, struct fdc_data *);
-#endif
diff --git a/sys/pc98/pc98/fdreg.h b/sys/pc98/pc98/fdreg.h
deleted file mode 100644
index 6d8e7e1..0000000
--- a/sys/pc98/pc98/fdreg.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that 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.
- * 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: @(#)fdreg.h 7.1 (Berkeley) 5/9/91
- * $FreeBSD$
- */
-
-/*
- * AT floppy controller registers and bitfields
- */
-
-/* uses NEC765 controller */
-#include <dev/ic/nec765.h>
-
-#ifdef PC98
-/* registers */
-#define FDSTS 0 /* NEC 765 Main Status Register (R) */
-#define FDDATA 1 /* NEC 765 Data Register (R/W) */
-#define FDCTL 2 /* FD Control Register */
-#define FDC_RST 0x80 /* FDC RESET */
-#define FDC_RDY 0x40 /* force READY */
-#define FDC_DD 0x20 /* FDD Mode Exchange 0:1M 1:640K */
-#define FDC_DMAE 0x10 /* enable floppy DMA */
-#define FDC_MTON 0x08 /* MOTOR ON (when EMTON=1)*/
-#define FDC_TMSK 0x04 /* TIMER MASK */
-#define FDC_TTRG 0x01 /* TIMER TRIGER */
-
-#define FDP_EMTON 0x04 /* enable MTON */
-#define FDP_FDDEXC 0x02 /* FDD Mode Exchange 1:1M 0:640K */
-#define FDP_PORTEXC 0x01 /* PORT Exchane 1:1M 0:640K */
-
-#else
-/* registers */
-#define FDOUT 2 /* Digital Output Register (W) */
-#define FDO_FDSEL 0x03 /* floppy device select */
-#define FDO_FRST 0x04 /* floppy controller reset */
-#define FDO_FDMAEN 0x08 /* enable floppy DMA and Interrupt */
-#define FDO_MOEN0 0x10 /* motor enable drive 0 */
-#define FDO_MOEN1 0x20 /* motor enable drive 1 */
-#define FDO_MOEN2 0x40 /* motor enable drive 2 */
-#define FDO_MOEN3 0x80 /* motor enable drive 3 */
-
-#define FDSTS 4 /* NEC 765 Main Status Register (R) */
-#define FDDATA 5 /* NEC 765 Data Register (R/W) */
-#define FDCTL 7 /* Control Register (W) */
-#endif /* PC98 */
-
-/*
- * The definitions for FDC_500KBPS etc. have been moved out to <sys/fdcio.h>
- * since they need to be visible in userland. They cover the lower two bits
- * of FDCTL when used for output.
- */
-/*
- * this is the secret PIO data port (offset from base)
- */
-#define FDC_YE_DATAPORT 6
-
-#ifndef PC98
-#define FDIN 7 /* Digital Input Register (R) */
-#define FDI_DCHG 0x80 /* diskette has been changed */
- /* requires drive and motor being selected */
- /* is cleared by any step pulse to drive */
-#endif
diff --git a/sys/pc98/pc98/isa_dma.c b/sys/pc98/pc98/isa_dma.c
deleted file mode 100644
index 5bf2c88..0000000
--- a/sys/pc98/pc98/isa_dma.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 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: @(#)isa.c 7.2 (Berkeley) 5/13/91
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * code to manage AT bus
- *
- * 92/08/18 Frank P. MacLachlan (fpm@crash.cts.com):
- * Fixed uninitialized variable problem and added code to deal
- * with DMA page boundaries in isa_dmarangecheck(). Fixed word
- * mode DMA count compution and reorganized DMA setup code in
- * isa_dmastart()
- */
-
-#include "opt_pc98.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/lock.h>
-#include <sys/proc.h>
-#include <sys/mutex.h>
-#include <sys/module.h>
-#include <machine/md_var.h>
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-#include <pc98/pc98/pc98.h>
-#include <dev/ic/i8237.h>
-#include <isa/isavar.h>
-
-/*
-** Register definitions for DMA controller 1 (channels 0..3):
-*/
-#define DMA1_CHN(c) (IO_DMA + (4*(c))) /* addr reg for channel c */
-#define DMA1_STATUS (IO_DMA + 0x10) /* status register */
-#define DMA1_SMSK (IO_DMA + 0x14) /* single mask register */
-#define DMA1_MODE (IO_DMA + 0x16) /* mode register */
-#define DMA1_FFC (IO_DMA + 0x18) /* clear first/last FF */
-
-static int isa_dmarangecheck(caddr_t va, u_int length, int chan);
-
-static caddr_t dma_bouncebuf[4];
-static u_int dma_bouncebufsize[4];
-static u_int8_t dma_bounced = 0;
-static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */
-static u_int8_t dma_inuse = 0; /* User for acquire/release */
-static u_int8_t dma_auto_mode = 0;
-
-#define VALID_DMA_MASK (3)
-
-/* high byte of address is stored in this port for i-th dma channel */
-static int dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };
-
-/*
- * Setup a DMA channel's bounce buffer.
- */
-int
-isa_dma_init(int chan, u_int bouncebufsize, int flag)
-{
- void *buf;
-
-#ifdef DIAGNOSTIC
- if (chan & ~VALID_DMA_MASK)
- panic("isa_dma_init: channel out of range");
- if (dma_bouncebuf[chan] != NULL)
- panic("isa_dma_init: impossible request");
-#endif
-
- dma_bouncebufsize[chan] = bouncebufsize;
-
- /* Try malloc() first. It works better if it works. */
- buf = malloc(bouncebufsize, M_DEVBUF, flag);
- if (buf != NULL) {
- if (isa_dmarangecheck(buf, bouncebufsize, chan) == 0) {
- dma_bouncebuf[chan] = buf;
- return (0);
- }
- free(buf, M_DEVBUF);
- }
- buf = contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful,
- 1ul, chan & 4 ? 0x20000ul : 0x10000ul);
- if (buf == NULL)
- return (ENOMEM);
- dma_bouncebuf[chan] = buf;
- return (0);
-}
-
-/*
- * Register a DMA channel's usage. Usually called from a device driver
- * in open() or during its initialization.
- */
-int
-isa_dma_acquire(chan)
- int chan;
-{
-#ifdef DIAGNOSTIC
- if (chan & ~VALID_DMA_MASK)
- panic("isa_dma_acquire: channel out of range");
-#endif
-
- if (dma_inuse & (1 << chan)) {
- printf("isa_dma_acquire: channel %d already in use\n", chan);
- return (EBUSY);
- }
- dma_inuse |= (1 << chan);
- dma_auto_mode &= ~(1 << chan);
-
- return (0);
-}
-
-/*
- * Unregister a DMA channel's usage. Usually called from a device driver
- * during close() or during its shutdown.
- */
-void
-isa_dma_release(chan)
- int chan;
-{
-#ifdef DIAGNOSTIC
- if (chan & ~VALID_DMA_MASK)
- panic("isa_dma_release: channel out of range");
-
- if ((dma_inuse & (1 << chan)) == 0)
- printf("isa_dma_release: channel %d not in use\n", chan);
-#endif
-
- if (dma_busy & (1 << chan)) {
- dma_busy &= ~(1 << chan);
- /*
- * XXX We should also do "dma_bounced &= (1 << chan);"
- * because we are acting on behalf of isa_dmadone() which
- * was not called to end the last DMA operation. This does
- * not matter now, but it may in the future.
- */
- }
-
- dma_inuse &= ~(1 << chan);
- dma_auto_mode &= ~(1 << chan);
-}
-
-/*
- * isa_dmastart(): program 8237 DMA controller channel, avoid page alignment
- * problems by using a bounce buffer.
- */
-void
-isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
-{
- vm_paddr_t phys;
- int waport;
- caddr_t newaddr;
-
- GIANT_REQUIRED;
-
-#ifdef DIAGNOSTIC
- if (chan & ~VALID_DMA_MASK)
- panic("isa_dmastart: channel out of range");
-
- if ((chan < 4 && nbytes > (1<<16))
- || (chan >= 4 && (nbytes > (1<<17) || (u_int)addr & 1)))
- panic("isa_dmastart: impossible request");
-
- if ((dma_inuse & (1 << chan)) == 0)
- printf("isa_dmastart: channel %d not acquired\n", chan);
-#endif
-
-#if 0
- /*
- * XXX This should be checked, but drivers like ad1848 only call
- * isa_dmastart() once because they use Auto DMA mode. If we
- * leave this in, drivers that do this will print this continuously.
- */
- if (dma_busy & (1 << chan))
- printf("isa_dmastart: channel %d busy\n", chan);
-#endif
-
- dma_busy |= (1 << chan);
-
- if (isa_dmarangecheck(addr, nbytes, chan)) {
- if (dma_bouncebuf[chan] == NULL
- || dma_bouncebufsize[chan] < nbytes)
- panic("isa_dmastart: bad bounce buffer");
- dma_bounced |= (1 << chan);
- newaddr = dma_bouncebuf[chan];
-
- /* copy bounce buffer on write */
- if (!(flags & ISADMA_READ))
- bcopy(addr, newaddr, nbytes);
- addr = newaddr;
- }
-
- /* translate to physical */
- phys = pmap_extract(kernel_pmap, (vm_offset_t)addr);
-
- if (flags & ISADMA_RAW) {
- dma_auto_mode |= (1 << chan);
- } else {
- dma_auto_mode &= ~(1 << chan);
- }
-
- if (need_pre_dma_flush)
- wbinvd(); /* wbinvd (WB cache flush) */
-
- /* set dma channel mode, and reset address ff */
-
- /* If ISADMA_RAW flag is set, then use autoinitialise mode */
- if (flags & ISADMA_RAW) {
- if (flags & ISADMA_READ)
- outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_WRITE|chan);
- else
- outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_READ|chan);
- } else {
- if (flags & ISADMA_READ)
- outb(DMA1_MODE, DMA37MD_SINGLE|DMA37MD_WRITE|chan);
- else
- outb(DMA1_MODE, DMA37MD_SINGLE|DMA37MD_READ|chan);
- }
- outb(DMA1_FFC, 0);
-
- /* send start address */
- waport = DMA1_CHN(chan);
- outb(waport, phys);
- outb(waport, phys>>8);
- outb(dmapageport[chan], phys>>16);
-
- /* send count */
- outb(waport + 2, --nbytes);
- outb(waport + 2, nbytes>>8);
-
- /* unmask channel */
- outb(DMA1_SMSK, chan);
-}
-
-void
-isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
-{
-
- if (flags & ISADMA_READ) {
- /* cache flush only after reading 92/12/9 by A.Kojima */
- if (need_post_dma_flush)
- invd();
- }
-
-#ifdef DIAGNOSTIC
- if (chan & ~VALID_DMA_MASK)
- panic("isa_dmadone: channel out of range");
-
- if ((dma_inuse & (1 << chan)) == 0)
- printf("isa_dmadone: channel %d not acquired\n", chan);
-#endif
-
- if (((dma_busy & (1 << chan)) == 0) &&
- (dma_auto_mode & (1 << chan)) == 0 )
- printf("isa_dmadone: channel %d not busy\n", chan);
-
- if ((dma_auto_mode & (1 << chan)) == 0)
- outb(DMA1_SMSK, (chan & 3) | 4);
-
- if (dma_bounced & (1 << chan)) {
- /* copy bounce buffer on read */
- if (flags & ISADMA_READ)
- bcopy(dma_bouncebuf[chan], addr, nbytes);
-
- dma_bounced &= ~(1 << chan);
- }
- dma_busy &= ~(1 << chan);
-}
-
-/*
- * Check for problems with the address range of a DMA transfer
- * (non-contiguous physical pages, outside of bus address space,
- * crossing DMA page boundaries).
- * Return true if special handling needed.
- */
-
-static int
-isa_dmarangecheck(caddr_t va, u_int length, int chan)
-{
- vm_paddr_t phys, priorpage = 0;
- vm_offset_t endva;
- u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1);
-
- GIANT_REQUIRED;
-
- endva = (vm_offset_t)round_page((vm_offset_t)va + length);
- for (; va < (caddr_t) endva ; va += PAGE_SIZE) {
- phys = trunc_page(pmap_extract(kernel_pmap, (vm_offset_t)va));
-#ifdef EPSON_BOUNCEDMA
-#define ISARAM_END 0xf00000
-#else
-#define ISARAM_END RAM_END
-#endif
- if (phys == 0)
- panic("isa_dmacheck: no physical page present");
- if (phys >= ISARAM_END)
- return (1);
- if (priorpage) {
- if (priorpage + PAGE_SIZE != phys)
- return (1);
- /* check if crossing a DMA page boundary */
- if (((u_int)priorpage ^ (u_int)phys) & dma_pgmsk)
- return (1);
- }
- priorpage = phys;
- }
- return (0);
-}
-
-/*
- * Query the progress of a transfer on a DMA channel.
- *
- * To avoid having to interrupt a transfer in progress, we sample
- * each of the high and low databytes twice, and apply the following
- * logic to determine the correct count.
- *
- * Reads are performed with interrupts disabled, thus it is to be
- * expected that the time between reads is very small. At most
- * one rollover in the low count byte can be expected within the
- * four reads that are performed.
- *
- * There are three gaps in which a rollover can occur :
- *
- * - read low1
- * gap1
- * - read high1
- * gap2
- * - read low2
- * gap3
- * - read high2
- *
- * If a rollover occurs in gap1 or gap2, the low2 value will be
- * greater than the low1 value. In this case, low2 and high2 are a
- * corresponding pair.
- *
- * In any other case, low1 and high1 can be considered to be correct.
- *
- * The function returns the number of bytes remaining in the transfer,
- * or -1 if the channel requested is not active.
- *
- */
-int
-isa_dmastatus(int chan)
-{
- u_long cnt = 0;
- int ffport, waport;
- u_long low1, high1, low2, high2;
-
- /* channel active? */
- if ((dma_inuse & (1 << chan)) == 0) {
- printf("isa_dmastatus: channel %d not active\n", chan);
- return(-1);
- }
- /* channel busy? */
-
- if (((dma_busy & (1 << chan)) == 0) &&
- (dma_auto_mode & (1 << chan)) == 0 ) {
- printf("chan %d not busy\n", chan);
- return -2 ;
- }
- ffport = DMA1_FFC;
- waport = DMA1_CHN(chan) + 2;
-
- disable_intr(); /* no interrupts Mr Jones! */
- outb(ffport, 0); /* clear register LSB flipflop */
- low1 = inb(waport);
- high1 = inb(waport);
- outb(ffport, 0); /* clear again */
- low2 = inb(waport);
- high2 = inb(waport);
- enable_intr(); /* enable interrupts again */
-
- /*
- * Now decide if a wrap has tried to skew our results.
- * Note that after TC, the count will read 0xffff, while we want
- * to return zero, so we add and then mask to compensate.
- */
- if (low1 >= low2) {
- cnt = (low1 + (high1 << 8) + 1) & 0xffff;
- } else {
- cnt = (low2 + (high2 << 8) + 1) & 0xffff;
- }
-
- if (chan >= 4) /* high channels move words */
- cnt *= 2;
- return(cnt);
-}
-
-/*
- * Reached terminal count yet ?
- */
-int
-isa_dmatc(int chan)
-{
-
- return(inb(DMA1_STATUS) & (1 << chan));
-}
-
-/*
- * Stop a DMA transfer currently in progress.
- */
-int
-isa_dmastop(int chan)
-{
- if ((dma_inuse & (1 << chan)) == 0)
- printf("isa_dmastop: channel %d not acquired\n", chan);
-
- if (((dma_busy & (1 << chan)) == 0) &&
- ((dma_auto_mode & (1 << chan)) == 0)) {
- printf("chan %d not busy\n", chan);
- return -2 ;
- }
-
- if ((chan & 4) == 0)
- outb(DMA1_SMSK, (chan & 3) | 4 /* disable mask */);
-
- return(isa_dmastatus(chan));
-}
-
-/*
- * Attach to the ISA PnP descriptor for the AT DMA controller
- */
-static struct isa_pnp_id atdma_ids[] = {
- { 0x0002d041 /* PNP0200 */, "AT DMA controller" },
- { 0 }
-};
-
-static int
-atdma_probe(device_t dev)
-{
- int result;
-
- if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, atdma_ids)) <= 0)
- device_quiet(dev);
- return(result);
-}
-
-static int
-atdma_attach(device_t dev)
-{
- return(0);
-}
-
-static device_method_t atdma_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, atdma_probe),
- DEVMETHOD(device_attach, atdma_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- { 0, 0 }
-};
-
-static driver_t atdma_driver = {
- "atdma",
- atdma_methods,
- 1, /* no softc */
-};
-
-static devclass_t atdma_devclass;
-
-DRIVER_MODULE(atdma, isa, atdma_driver, atdma_devclass, 0, 0);
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index ab6c5c9..e7ff04e 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -103,7 +103,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <pc98/pc98/pc98_machdep.h>
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#include <net/netisr.h>
diff --git a/sys/pc98/pc98/nmi.c b/sys/pc98/pc98/nmi.c
deleted file mode 100644
index 431dd06..0000000
--- a/sys/pc98/pc98/nmi.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 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: @(#)isa.c 7.2 (Berkeley) 5/13/91
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <sys/syslog.h>
-#include <sys/systm.h>
-
-#include <machine/md_var.h>
-
-#include <pc98/pc98/epsonio.h>
-#include <pc98/pc98/pc98_machdep.h>
-
-#define NMI_PARITY 0x04
-#define NMI_EPARITY 0x02
-
-/*
- * Handle a NMI, possibly a machine check.
- * return true to panic system, false to ignore.
- */
-int
-isa_nmi(int cd)
-{
- int retval = 0;
- int port = inb(0x33);
-
- log(LOG_CRIT, "NMI PC98 port = %x\n", port);
- if (epson_machine_id == 0x20)
- epson_outb(0xc16, epson_inb(0xc16) | 0x1);
- if (port & NMI_PARITY) {
- log(LOG_CRIT, "BASE RAM parity error, likely hardware failure.");
- retval = 1;
- } else if (port & NMI_EPARITY) {
- log(LOG_CRIT, "EXTENDED RAM parity error, likely hardware failure.");
- retval = 1;
- } else {
- log(LOG_CRIT, "\nNMI Resume ??\n");
- }
-
- return(retval);
-}
diff --git a/sys/pc98/pc98/olpt.c b/sys/pc98/pc98/olpt.c
deleted file mode 100644
index 494eb04..0000000
--- a/sys/pc98/pc98/olpt.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*-
- * Copyright (c) 1990 William F. Jolitz, TeleMuse
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This software is a component of "386BSD" developed by
- * William F. Jolitz, TeleMuse.
- * 4. Neither the name of the developer nor the name "386BSD"
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ
- * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS
- * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT.
- * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT
- * NOT MAKE USE OF THIS WORK.
- *
- * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED
- * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN
- * REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES
- * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING
- * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND
- * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE
- * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS
- * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: unknown origin, 386BSD 0.1
- * $FreeBSD$
- */
-
-/*
- * Device Driver for AT parallel printer port
- * Written by William Jolitz 12/18/90
- */
-
-/*
- * Parallel port TCP/IP interfaces added. I looked at the driver from
- * MACH but this is a complete rewrite, and btw. incompatible, and it
- * should perform better too. I have never run the MACH driver though.
- *
- * This driver sends two bytes (0x08, 0x00) in front of each packet,
- * to allow us to distinguish another format later.
- *
- * Now added a Linux/Crynwr compatibility mode which is enabled using
- * IF_LINK0 - Tim Wilkinson.
- *
- * TODO:
- * Make HDLC/PPP mode, use IF_LLC1 to enable.
- *
- * Connect the two computers using a Laplink parallel cable to use this
- * feature:
- *
- * +----------------------------------------+
- * |A-name A-End B-End Descr. Port/Bit |
- * +----------------------------------------+
- * |DATA0 2 15 Data 0/0x01 |
- * |-ERROR 15 2 1/0x08 |
- * +----------------------------------------+
- * |DATA1 3 13 Data 0/0x02 |
- * |+SLCT 13 3 1/0x10 |
- * +----------------------------------------+
- * |DATA2 4 12 Data 0/0x04 |
- * |+PE 12 4 1/0x20 |
- * +----------------------------------------+
- * |DATA3 5 10 Strobe 0/0x08 |
- * |-ACK 10 5 1/0x40 |
- * +----------------------------------------+
- * |DATA4 6 11 Data 0/0x10 |
- * |BUSY 11 6 1/~0x80 |
- * +----------------------------------------+
- * |GND 18-25 18-25 GND - |
- * +----------------------------------------+
- *
- * Expect transfer-rates up to 75 kbyte/sec.
- *
- * If GCC could correctly grok
- * register int port asm("edx")
- * the code would be cleaner
- *
- * Poul-Henning Kamp <phk@freebsd.org>
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/uio.h>
-#include <sys/syslog.h>
-#include <sys/malloc.h>
-
-#include <machine/clock.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <isa/isavar.h>
-
-#include <i386/isa/lptreg.h>
-#include <dev/ppbus/lptio.h>
-
-#define LPINITRDY 4 /* wait up to 4 seconds for a ready */
-#define LPTOUTINITIAL 10 /* initial timeout to wait for ready 1/10 s */
-#define LPTOUTMAX 1 /* maximal timeout 1 s */
-#define LPPRI (PZERO+8)
-#define BUFSIZE 1024
-
-#ifndef DEBUG
-#define lprintf(args)
-#else
-#define lprintf(args) do { \
- if (lptflag) \
- printf args; \
- } while (0)
-static int volatile lptflag = 1;
-#endif
-
-#define LPTUNIT(s) ((s)&0x03)
-#define LPTFLAGS(s) ((s)&0xfc)
-
-struct lpt_softc {
- struct resource *res_port;
- struct resource *res_irq;
- void *sc_ih;
-
- int sc_port;
- short sc_state;
- /* default case: negative prime, negative ack, handshake strobe,
- prime once */
- u_char sc_control;
- char sc_flags;
-#define LP_POS_INIT 0x04 /* if we are a postive init signal */
-#define LP_POS_ACK 0x08 /* if we are a positive going ack */
-#define LP_NO_PRIME 0x10 /* don't prime the printer at all */
-#define LP_PRIMEOPEN 0x20 /* prime on every open */
-#define LP_AUTOLF 0x40 /* tell printer to do an automatic lf */
-#define LP_BYPASS 0x80 /* bypass printer ready checks */
- void *sc_inbuf;
- short sc_xfercnt ;
- char sc_primed;
- char *sc_cp ;
- u_char sc_irq ; /* IRQ status of port */
-#define LP_HAS_IRQ 0x01 /* we have an irq available */
-#define LP_USE_IRQ 0x02 /* we are using our irq */
-#define LP_ENABLE_IRQ 0x04 /* enable IRQ on open */
- u_char sc_backoff ; /* time to call lptout() again */
-};
-
-/* bits for state */
-#define OPEN (1<<0) /* device is open */
-#define ASLP (1<<1) /* awaiting draining of printer */
-#define ERROR (1<<2) /* error was received from printer */
-#define OBUSY (1<<3) /* printer is busy doing output */
-#define LPTOUT (1<<4) /* timeout while not selected */
-#define TOUT (1<<5) /* timeout while not selected */
-#define INIT (1<<6) /* waiting to initialize for open */
-#define INTERRUPTED (1<<7) /* write call was interrupted */
-
-
-/* status masks to interrogate printer status */
-#define RDY_MASK (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR) /* ready ? */
-#define LP_READY (LPS_SEL|LPS_NBSY|LPS_NERR)
-
-/* Printer Ready condition - from lpa.c */
-/* Only used in polling code */
-#define NOT_READY(x) ((inb(x) & LPS_NBSY) != LPS_NBSY)
-
-#define MAX_SLEEP (hz*5) /* Timeout while waiting for device ready */
-#define MAX_SPIN 20 /* Max delay for device ready in usecs */
-
-static timeout_t lptout;
-static int lpt_probe(device_t);
-static int lpt_attach(device_t);
-static void lpt_intr(void *);
-
-static devclass_t olpt_devclass;
-
-static device_method_t olpt_methods[] = {
- DEVMETHOD(device_probe, lpt_probe),
- DEVMETHOD(device_attach, lpt_attach),
- { 0, 0 }
-};
-
-static driver_t olpt_driver = {
- "olpt",
- olpt_methods,
- sizeof (struct lpt_softc),
-};
-
-DRIVER_MODULE(olpt, isa, olpt_driver, olpt_devclass, 0, 0);
-
-static d_open_t lptopen;
-static d_close_t lptclose;
-static d_write_t lptwrite;
-static d_ioctl_t lptioctl;
-
-static struct cdevsw lpt_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = lptopen,
- .d_close = lptclose,
- .d_write = lptwrite,
- .d_ioctl = lptioctl,
- .d_name = "lpt",
-};
-
-static bus_addr_t lpt_iat[] = {0, 2, 4, 6};
-
-/*
- * New lpt port probe Geoff Rehmet - Rhodes University - 14/2/94
- * Based partially on Rod Grimes' printer probe
- *
- * Logic:
- * 1) If no port address was given, use the bios detected ports
- * and autodetect what ports the printers are on.
- * 2) Otherwise, probe the data port at the address given,
- * using the method in Rod Grimes' port probe.
- * (Much code ripped off directly from Rod's probe.)
- *
- * Comments from Rod's probe:
- * Logic:
- * 1) You should be able to write to and read back the same value
- * to the data port. Do an alternating zeros, alternating ones,
- * walking zero, and walking one test to check for stuck bits.
- *
- * 2) You should be able to write to and read back the same value
- * to the control port lower 5 bits, the upper 3 bits are reserved
- * per the IBM PC technical reference manauls and different boards
- * do different things with them. Do an alternating zeros, alternating
- * ones, walking zero, and walking one test to check for stuck bits.
- *
- * Some printers drag the strobe line down when the are powered off
- * so this bit has been masked out of the control port test.
- *
- * XXX Some printers may not like a fast pulse on init or strobe, I
- * don't know at this point, if that becomes a problem these bits
- * should be turned off in the mask byte for the control port test.
- *
- * We are finally left with a mask of 0x14, due to some printers
- * being adamant about holding other bits high ........
- *
- * Before probing the control port, we write a 0 to the data port -
- * If not, some printers chuck out garbage when the strobe line
- * gets toggled.
- *
- * 3) Set the data and control ports to a value of 0
- *
- * This probe routine has been tested on Epson Lx-800, HP LJ3P,
- * Epson FX-1170 and C.Itoh 8510RM
- * printers.
- * Quick exit on fail added.
- */
-
-int
-lpt_probe(device_t dev)
-{
-#define PC98_OLD_LPT 0x40
-#define PC98_IEEE_1284_FUNCTION 0x149
- int rid;
- struct resource *res;
-
- /* Check isapnp ids */
- if (isa_get_vendorid(dev))
- return ENXIO;
-
- rid = 0;
- res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, lpt_iat, 4,
- RF_ACTIVE);
- if (res == NULL)
- return ENXIO;
- isa_load_resourcev(res, lpt_iat, 4);
-
- if (isa_get_port(dev) == PC98_OLD_LPT) {
- unsigned int pc98_ieee_mode, tmp;
-
- tmp = inb(PC98_IEEE_1284_FUNCTION);
- pc98_ieee_mode = tmp;
- if ((tmp & 0x10) == 0x10) {
- outb(PC98_IEEE_1284_FUNCTION, tmp & ~0x10);
- tmp = inb(PC98_IEEE_1284_FUNCTION);
- if ((tmp & 0x10) != 0x10) {
- outb(PC98_IEEE_1284_FUNCTION, pc98_ieee_mode);
- bus_release_resource(dev, SYS_RES_IOPORT, rid,
- res);
- return ENXIO;
- }
- }
- }
-
- bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
- return 0;
-}
-
-/* XXX Todo - try and detect if interrupt is working */
-int
-lpt_attach(device_t dev)
-{
- int rid, unit;
- struct lpt_softc *sc;
-
- unit = device_get_unit(dev);
- sc = device_get_softc(dev);
-
- rid = 0;
- sc->res_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
- lpt_iat, 4, RF_ACTIVE);
- if (sc->res_port == NULL)
- return ENXIO;
- isa_load_resourcev(sc->res_port, lpt_iat, 4);
-
- sc->sc_port = rman_get_start(sc->res_port);
- sc->sc_primed = 0; /* not primed yet */
-
- outb(sc->sc_port+lpt_pstb_ctrl, LPC_DIS_PSTB); /* PSTB disable */
- outb(sc->sc_port+lpt_control, LPC_MODE8255); /* 8255 mode set */
- outb(sc->sc_port+lpt_control, LPC_NIRQ8); /* IRQ8 inactive */
- outb(sc->sc_port+lpt_control, LPC_NPSTB); /* PSTB inactive */
- outb(sc->sc_port+lpt_pstb_ctrl, LPC_EN_PSTB); /* PSTB enable */
-
- sc->sc_irq = 0;
- if (isa_get_irq(dev) != -1) {
- rid = 0;
- sc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE);
- if (sc->res_irq == NULL) {
- bus_release_resource(dev, SYS_RES_IOPORT, 0,
- sc->res_port);
- return ENXIO;
- }
- if (bus_setup_intr(dev, sc->res_irq, INTR_TYPE_TTY, lpt_intr,
- sc, &sc->sc_ih)) {
- bus_release_resource(dev, SYS_RES_IOPORT, 0,
- sc->res_port);
- bus_release_resource(dev, SYS_RES_IRQ, 0,
- sc->res_irq);
- return ENXIO;
- }
- sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
- device_printf(dev, "Interrupt-driven port");
- }
-
- /* XXX what to do about the flags in the minor number? */
- make_dev(&lpt_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, "lpt%d", unit);
- make_dev(&lpt_cdevsw, unit | LP_BYPASS,
- UID_ROOT, GID_WHEEL, 0600, "lpctl%d", unit);
-
- return 0;
-}
-
-/*
- * lptopen -- reset the printer, then wait until it's selected and not busy.
- * If LP_BYPASS flag is selected, then we do not try to select the
- * printer -- this is just used for passing ioctls.
- */
-
-static int
-lptopen (struct cdev *dev, int flags, int fmt, struct thread *td)
-{
- struct lpt_softc *sc;
- int s;
- int port;
-
- sc = devclass_get_softc(olpt_devclass, LPTUNIT(minor(dev)));
- if (sc->sc_port == 0)
- return (ENXIO);
-
- if (sc->sc_state) {
- lprintf(("lp: still open %x\n", sc->sc_state));
- return(EBUSY);
- } else
- sc->sc_state |= INIT;
-
- sc->sc_flags = LPTFLAGS(minor(dev));
-
- /* Check for open with BYPASS flag set. */
- if (sc->sc_flags & LP_BYPASS) {
- sc->sc_state = OPEN;
- return(0);
- }
-
- s = spltty();
- lprintf(("lp flags 0x%x\n", sc->sc_flags));
- port = sc->sc_port;
-
- /* set IRQ status according to ENABLE_IRQ flag */
- if (sc->sc_irq & LP_ENABLE_IRQ)
- sc->sc_irq |= LP_USE_IRQ;
- else
- sc->sc_irq &= ~LP_USE_IRQ;
-
- /* init printer */
- sc->sc_state = OPEN;
- sc->sc_inbuf = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
- sc->sc_xfercnt = 0;
- splx(s);
-
- /* only use timeout if using interrupt */
- lprintf(("irq %x\n", sc->sc_irq));
- if (sc->sc_irq & LP_USE_IRQ) {
- sc->sc_state |= TOUT;
- timeout (lptout, (caddr_t)sc,
- (sc->sc_backoff = hz/LPTOUTINITIAL));
- }
-
- lprintf(("opened.\n"));
- return(0);
-}
-
-static void
-lptout (void *arg)
-{
- struct lpt_softc *sc = arg;
- int pl;
-
- lprintf(("T %x ", inb(sc->sc_port+lpt_status)));
- if (sc->sc_state & OPEN) {
- sc->sc_backoff++;
- if (sc->sc_backoff > hz/LPTOUTMAX)
- sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX;
- timeout (lptout, (caddr_t)sc, sc->sc_backoff);
- } else
- sc->sc_state &= ~TOUT;
-
- if (sc->sc_state & ERROR)
- sc->sc_state &= ~ERROR;
-
- /*
- * Avoid possible hangs do to missed interrupts
- */
- if (sc->sc_xfercnt) {
- pl = spltty();
- lpt_intr(sc);
- splx(pl);
- } else {
- sc->sc_state &= ~OBUSY;
- wakeup(sc);
- }
-}
-
-/*
- * lptclose -- close the device, free the local line buffer.
- *
- * Check for interrupted write call added.
- */
-
-static int
-lptclose(struct cdev *dev, int flags, int fmt, struct thread *td)
-{
- struct lpt_softc *sc;
-
- sc = devclass_get_softc(olpt_devclass, LPTUNIT(minor(dev)));
- if(sc->sc_flags & LP_BYPASS)
- goto end_close;
-
- sc->sc_state &= ~OPEN;
- free(sc->sc_inbuf, M_DEVBUF);
-
-end_close:
- sc->sc_state = 0;
- sc->sc_xfercnt = 0;
- lprintf(("closed.\n"));
- return(0);
-}
-
-/*
- * pushbytes()
- * Workhorse for actually spinning and writing bytes to printer
- * Derived from lpa.c
- * Originally by ?
- *
- * This code is only used when we are polling the port
- */
-static int
-pushbytes(struct lpt_softc * sc)
-{
- int spin, err, tic;
- char ch;
- int port = sc->sc_port;
-
- lprintf(("p"));
- /* loop for every character .. */
- while (sc->sc_xfercnt > 0) {
- /* printer data */
- ch = *(sc->sc_cp);
- sc->sc_cp++;
- sc->sc_xfercnt--;
-
- /*
- * Wait for printer ready.
- * Loop 20 usecs testing BUSY bit, then sleep
- * for exponentially increasing timeout. (vak)
- */
- for (spin=0; NOT_READY(port+lpt_status) && spin<MAX_SPIN; ++spin)
- DELAY(1); /* XXX delay is NOT this accurate! */
- if (spin >= MAX_SPIN) {
- tic = 0;
- while (NOT_READY(port+lpt_status)) {
- /*
- * Now sleep, every cycle a
- * little longer ..
- */
- tic = tic + tic + 1;
- /*
- * But no more than 10 seconds. (vak)
- */
- if (tic > MAX_SLEEP)
- tic = MAX_SLEEP;
- err = tsleep(sc, LPPRI,
- "lptpoll", tic);
- if (err != EWOULDBLOCK) {
- return (err);
- }
- }
- }
-
- /* output data */
- outb(port+lpt_data, ch);
- DELAY(1);
- outb(port+lpt_control, LPC_PSTB);
- DELAY(1);
- outb(port+lpt_control, LPC_NPSTB);
- }
- return(0);
-}
-
-/*
- * lptwrite --copy a line from user space to a local buffer, then call
- * putc to get the chars moved to the output queue.
- *
- * Flagging of interrupted write added.
- */
-
-static int
-lptwrite(struct cdev *dev, struct uio * uio, int ioflag)
-{
- register unsigned n;
- int pl, err;
- struct lpt_softc *sc;
-
- sc = devclass_get_softc(olpt_devclass, LPTUNIT(minor(dev)));
- if(sc->sc_flags & LP_BYPASS) {
- /* we can't do writes in bypass mode */
- return(EPERM);
- }
-
- sc->sc_state &= ~INTERRUPTED;
- while ((n = min(BUFSIZE, uio->uio_resid)) != 0) {
- sc->sc_cp = sc->sc_inbuf;
- uiomove(sc->sc_cp, n, uio);
- sc->sc_xfercnt = n ;
- while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) {
- lprintf(("i"));
- /* if the printer is ready for a char, */
- /* give it one */
- if ((sc->sc_state & OBUSY) == 0){
- lprintf(("\nC %d. ", sc->sc_xfercnt));
- pl = spltty();
- lpt_intr(sc);
- (void) splx(pl);
- }
- lprintf(("W "));
- if (sc->sc_state & OBUSY)
- if ((err = tsleep (sc,
- LPPRI|PCATCH, "lpwrite", 0))) {
- sc->sc_state |= INTERRUPTED;
- return(err);
- }
- }
- /* check to see if we must do a polled write */
- if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) {
- lprintf(("p"));
- if((err = pushbytes(sc)))
- return(err);
- }
- }
- return(0);
-}
-
-/*
- * lptintr -- handle printer interrupts which occur when the printer is
- * ready to accept another char.
- *
- * do checking for interrupted write call.
- */
-
-static void
-lpt_intr(void *arg)
-{
-}
-
-static int
-lptioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td)
-{
- int error = 0;
- struct lpt_softc *sc;
- u_int unit = LPTUNIT(minor(dev));
- u_char old_sc_irq; /* old printer IRQ status */
-
- sc = devclass_get_softc(olpt_devclass, unit);
-
- switch (cmd) {
- case LPT_IRQ :
- if(sc->sc_irq & LP_HAS_IRQ) {
- /*
- * NOTE:
- * If the IRQ status is changed,
- * this will only be visible on the
- * next open.
- *
- * If interrupt status changes,
- * this gets syslog'd.
- */
- old_sc_irq = sc->sc_irq;
- if(*(int*)data == 0)
- sc->sc_irq &= (~LP_ENABLE_IRQ);
- else
- sc->sc_irq |= LP_ENABLE_IRQ;
- if (old_sc_irq != sc->sc_irq )
- log(LOG_NOTICE, "lpt%c switched to %s mode\n",
- (char)unit+'0',
- (sc->sc_irq & LP_ENABLE_IRQ)?
- "interrupt-driven":"polled");
- } else /* polled port */
- error = EOPNOTSUPP;
- break;
- default:
- error = ENODEV;
- }
-
- return(error);
-}
diff --git a/sys/pc98/pc98/pc98.h b/sys/pc98/pc98/pc98.h
deleted file mode 100644
index 627c0e9..0000000
--- a/sys/pc98/pc98/pc98.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 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: @(#)isa.h 5.7 (Berkeley) 5/9/91
- * $FreeBSD$
- */
-
-#ifndef _PC98_PC98_PC98_H_
-#define _PC98_PC98_PC98_H_
-
-/* BEWARE: Included in both assembler and C code */
-
-/*
- * PC98 Bus conventions
- * modified for PC9801 by A.Kojima F.Ukai M.Ishii
- * Kyoto University Microcomputer Club (KMC)
- */
-
-/*
- * Input / Output Port Assignments
- */
-#ifndef IO_ISABEGIN
-#define IO_ISABEGIN 0x000 /* 0x000 - Beginning of I/O Registers */
-
-/* PC98 IO address ... very dirty (^_^; */
-
-#define IO_ICU1 0x000 /* 8259A Interrupt Controller #1 */
-#define IO_DMA 0x001 /* 8237A DMA Controller */
-#define IO_ICU2 0x008 /* 8259A Interrupt Controller #2 */
-#define IO_RTC 0x020 /* 4990A RTC */
-#define IO_SYSPORT 0x031 /* 8255A System Port */
-#define IO_PPI 0x035 /* Programmable Peripheral Interface */
-#define IO_KBD 0x041 /* 8251A Keyboard */
-#define IO_TIMER1 0x071 /* 8253C Timer */
-#define IO_COM2 0x0B1 /* 8251A RS232C serial I/O (ext) */
-#define IO_COM3 0x0B9 /* 8251A RS232C serial I/O (ext) */
-#define IO_FDPORT 0x0BE /* FD I/F port (1M<->640K,EMTON) */
-#define IO_NPX 0x0F8 /* Numeric Coprocessor */
-#define IO_WD1_EPSON 0x80 /* 386note Hard disk controller */
-#define IO_ISAEND 0xFFFF /* - 0x3FF End of I/O Registers */
-#endif /* !IO_ISABEGIN */
-
-/*
- * Input / Output Port Sizes - these are from several sources, and tend
- * to be the larger of what was found, ie COM ports can be 4, but some
- * boards do not fully decode the address, thus 8 ports are used.
- */
-#ifndef IO_ISASIZES
-#define IO_ISASIZES
-
-#define IO_KBDSIZE 16 /* 8042 Keyboard controllers */
-#define IO_LPTSIZE 8 /* LPT controllers, some use only 4 */
-#define IO_LPTSIZE_EXTENDED 8 /* "Extended" LPT controllers */
-#define IO_LPTSIZE_NORMAL 4 /* "Normal" LPT controllers */
-#define IO_NPXSIZE 8 /* 80387/80487 NPX registers */
-
-#endif /* !IO_ISASIZES */
-
-/*
- * Input / Output Memory Physical Addresses
- */
-#ifndef IOM_BEGIN
-#define IOM_BEGIN 0x0A0000 /* Start of I/O Memory "hole" */
-#define IOM_END 0x100000 /* End of I/O Memory "hole" */
-#define IOM_SIZE (IOM_END - IOM_BEGIN)
-#endif /* !IOM_BEGIN */
-
-/*
- * RAM Physical Address Space (ignoring the above mentioned "hole")
- */
-#ifndef RAM_BEGIN
-#define RAM_BEGIN 0x0000000 /* Start of RAM Memory */
-#ifdef EPSON_BOUNCEDMA
-#define RAM_END 0x0f00000 /* End of EPSON GR?? RAM Memory */
-#else
-#define RAM_END 0x1000000 /* End of RAM Memory */
-#endif
-#define RAM_SIZE (RAM_END - RAM_BEGIN)
-#endif /* !RAM_BEGIN */
-
-/*
- * IRQs
- */
-#define IRQ_NPX 8
-
-/*
- * Npx MD defines
- */
-/* full reset of npx: not needed on pc98 */
-#define npx_full_reset()
-
-#define M_NEC_PC98 0x0001
-#define M_EPSON_PC98 0x0002
-#define M_NOT_H98 0x0010
-#define M_H98 0x0020
-#define M_NOTE 0x0040
-#define M_NORMAL 0x1000
-#define M_8M 0x8000
-
-#endif /* !_PC98_PC98_PC98_H_ */
diff --git a/sys/pc98/pc98/pc98_machdep.c b/sys/pc98/pc98/pc98_machdep.c
index fbb348e..c82647f 100644
--- a/sys/pc98/pc98/pc98_machdep.c
+++ b/sys/pc98/pc98/pc98_machdep.c
@@ -39,7 +39,7 @@
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#ifdef EPSON_MEMWIN
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#endif
#include <pc98/pc98/pc98_machdep.h>
diff --git a/sys/pc98/pc98/pc98gdc.c b/sys/pc98/pc98/pc98gdc.c
deleted file mode 100644
index 9df28d5..0000000
--- a/sys/pc98/pc98/pc98gdc.c
+++ /dev/null
@@ -1,1500 +0,0 @@
-/*-
- * Copyright (c) 1999 FreeBSD(98) port team.
- * 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.
- *
- * $FreeBSD$
- */
-
-#include "opt_gdc.h"
-#include "opt_fb.h"
-#include "opt_syscons.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/bus.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <machine/resource.h>
-
-#include <sys/fbio.h>
-#include <sys/fcntl.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_param.h>
-
-#include <machine/md_var.h>
-#include <machine/pc/bios.h>
-
-#include <dev/fb/fbreg.h>
-
-#ifdef LINE30
-#include <pc98/pc98/pc98.h>
-#endif
-#include <pc98/pc98/pc98_machdep.h>
-#include <isa/isavar.h>
-
-#define TEXT_GDC 0x60
-#define GRAPHIC_GDC 0xa0
-#define ROW 25
-#define COL 80
-
-#define DRIVER_NAME "gdc"
-
-/* cdev driver declaration */
-
-#define GDC_UNIT(dev) minor(dev)
-#define GDC_MKMINOR(unit) (unit)
-
-typedef struct gdc_softc {
- video_adapter_t *adp;
- struct resource *res_tgdc, *res_ggdc;
- struct resource *res_egc, *res_pegc, *res_grcg, *res_kcg;
- struct resource *res_tmem, *res_gmem1, *res_gmem2;
-#ifdef FB_INSTALL_CDEV
- genfb_softc_t gensc;
-#endif
-} gdc_softc_t;
-
-#define GDC_SOFTC(unit) \
- ((gdc_softc_t *)devclass_get_softc(gdc_devclass, unit))
-
-static bus_addr_t gdc_iat[] = {0, 2, 4, 6, 8, 10, 12, 14};
-
-static devclass_t gdc_devclass;
-
-static int gdc_probe_unit(int unit, gdc_softc_t *sc, int flags);
-static int gdc_attach_unit(int unit, gdc_softc_t *sc, int flags);
-static int gdc_alloc_resource(device_t dev);
-static int gdc_release_resource(device_t dev);
-
-#if FB_INSTALL_CDEV
-
-static d_open_t gdcopen;
-static d_close_t gdcclose;
-static d_read_t gdcread;
-static d_write_t gdcwrite;
-static d_ioctl_t gdcioctl;
-static d_mmap_t gdcmmap;
-
-static struct cdevsw gdc_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = gdcopen,
- .d_close = gdcclose,
- .d_read = gdcread,
- .d_write = gdcwrite,
- .d_ioctl = gdcioctl,
- .d_mmap = gdcmmap,
- .d_name = DRIVER_NAME,
-};
-
-#endif /* FB_INSTALL_CDEV */
-
-static void
-gdc_identify(driver_t *driver, device_t parent)
-{
- BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, DRIVER_NAME, 0);
-}
-
-static int
-gdcprobe(device_t dev)
-{
- int error;
-
- /* Check isapnp ids */
- if (isa_get_vendorid(dev))
- return (ENXIO);
-
- device_set_desc(dev, "Generic GDC");
-
- error = gdc_alloc_resource(dev);
- if (error)
- return (error);
-
- error = gdc_probe_unit(device_get_unit(dev),
- device_get_softc(dev),
- device_get_flags(dev));
-
- gdc_release_resource(dev);
-
- return (error);
-}
-
-static int
-gdc_attach(device_t dev)
-{
- gdc_softc_t *sc;
- int error;
-
- error = gdc_alloc_resource(dev);
- if (error)
- return (error);
-
- sc = device_get_softc(dev);
- error = gdc_attach_unit(device_get_unit(dev),
- sc,
- device_get_flags(dev));
- if (error) {
- gdc_release_resource(dev);
- return error;
- }
-
-#ifdef FB_INSTALL_CDEV
- /* attach a virtual frame buffer device */
- error = fb_attach(GDC_MKMINOR(device_get_unit(dev)),
- sc->adp, &gdc_cdevsw);
- if (error) {
- gdc_release_resource(dev);
- return error;
- }
-#endif /* FB_INSTALL_CDEV */
-
- if (bootverbose)
- (*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose);
-
- return 0;
-}
-
-static int
-gdc_probe_unit(int unit, gdc_softc_t *sc, int flags)
-{
- video_switch_t *sw;
-
- sw = vid_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
- return (*sw->probe)(unit, &sc->adp, NULL, flags);
-}
-
-static int
-gdc_attach_unit(int unit, gdc_softc_t *sc, int flags)
-{
- video_switch_t *sw;
-
- sw = vid_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
- return (*sw->init)(unit, sc->adp, flags);
-}
-
-
-static int
-gdc_alloc_resource(device_t dev)
-{
- int rid;
- gdc_softc_t *sc;
-
- sc = device_get_softc(dev);
-
- /* TEXT GDC */
- rid = 0;
- bus_set_resource(dev, SYS_RES_IOPORT, rid, TEXT_GDC, 1);
- sc->res_tgdc = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
- gdc_iat, 8, RF_ACTIVE);
- if (sc->res_tgdc == NULL) {
- gdc_release_resource(dev);
- return (ENXIO);
- }
- isa_load_resourcev(sc->res_tgdc, gdc_iat, 8);
-
- /* GRAPHIC GDC */
- rid = 8;
- bus_set_resource(dev, SYS_RES_IOPORT, rid, GRAPHIC_GDC, 1);
- sc->res_ggdc = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
- gdc_iat, 8, RF_ACTIVE);
- if (sc->res_ggdc == NULL) {
- gdc_release_resource(dev);
- return (ENXIO);
- }
- isa_load_resourcev(sc->res_ggdc, gdc_iat, 8);
-
- /* EGC */
- rid = 16;
- bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x4a0, 1);
- sc->res_egc = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
- gdc_iat, 8, RF_ACTIVE);
- if (sc->res_egc == NULL) {
- gdc_release_resource(dev);
- return (ENXIO);
- }
- isa_load_resourcev(sc->res_egc, gdc_iat, 8);
-
- /* PEGC */
- rid = 24;
- bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x9a0, 1);
- sc->res_pegc = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
- gdc_iat, 8, RF_ACTIVE);
- if (sc->res_pegc == NULL) {
- gdc_release_resource(dev);
- return (ENXIO);
- }
- isa_load_resourcev(sc->res_pegc, gdc_iat, 8);
-
- /* CRTC/GRCG */
- rid = 32;
- bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x70, 1);
- sc->res_grcg = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
- gdc_iat, 8, RF_ACTIVE);
- if (sc->res_grcg == NULL) {
- gdc_release_resource(dev);
- return (ENXIO);
- }
- isa_load_resourcev(sc->res_grcg, gdc_iat, 8);
-
- /* KCG */
- rid = 40;
- bus_set_resource(dev, SYS_RES_IOPORT, rid, 0xa1, 1);
- sc->res_kcg = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
- gdc_iat, 8, RF_ACTIVE);
- if (sc->res_kcg == NULL) {
- gdc_release_resource(dev);
- return (ENXIO);
- }
- isa_load_resourcev(sc->res_kcg, gdc_iat, 8);
-
-
- /* TEXT Memory */
- rid = 0;
- sc->res_tmem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
- 0xa0000, 0xa4fff, 0x5000, RF_ACTIVE);
- if (sc->res_tmem == NULL) {
- gdc_release_resource(dev);
- return (ENXIO);
- }
-
- /* GRAPHIC Memory */
- rid = 1;
- sc->res_gmem1 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
- 0xa8000, 0xbffff, 0x18000,
- RF_ACTIVE);
- if (sc->res_gmem1 == NULL) {
- gdc_release_resource(dev);
- return (ENXIO);
- }
- rid = 2;
- sc->res_gmem2 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
- 0xe0000, 0xe7fff, 0x8000,
- RF_ACTIVE);
- if (sc->res_gmem2 == NULL) {
- gdc_release_resource(dev);
- return (ENXIO);
- }
-
- return (0);
-}
-
-static int
-gdc_release_resource(device_t dev)
-{
- gdc_softc_t *sc;
-
- sc = device_get_softc(dev);
-
- if (sc->res_tgdc)
- bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->res_tgdc);
- if (sc->res_ggdc)
- bus_release_resource(dev, SYS_RES_IOPORT, 8, sc->res_ggdc);
- if (sc->res_egc)
- bus_release_resource(dev, SYS_RES_IOPORT, 16, sc->res_egc);
- if (sc->res_pegc)
- bus_release_resource(dev, SYS_RES_IOPORT, 24, sc->res_pegc);
- if (sc->res_grcg)
- bus_release_resource(dev, SYS_RES_IOPORT, 32, sc->res_grcg);
- if (sc->res_kcg)
- bus_release_resource(dev, SYS_RES_IOPORT, 40, sc->res_kcg);
-
- if (sc->res_tmem)
- bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res_tmem);
- if (sc->res_gmem1)
- bus_release_resource(dev, SYS_RES_MEMORY, 1, sc->res_gmem1);
- if (sc->res_gmem2)
- bus_release_resource(dev, SYS_RES_MEMORY, 2, sc->res_gmem2);
-
- return (0);
-}
-
-/* cdev driver functions */
-
-#ifdef FB_INSTALL_CDEV
-
-static int
-gdcopen(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- gdc_softc_t *sc;
-
- sc = GDC_SOFTC(GDC_UNIT(dev));
- if (sc == NULL)
- return ENXIO;
- if (mode & (O_CREAT | O_APPEND | O_TRUNC))
- return ENODEV;
-
- return genfbopen(&sc->gensc, sc->adp, flag, mode, td);
-}
-
-static int
-gdcclose(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- gdc_softc_t *sc;
-
- sc = GDC_SOFTC(GDC_UNIT(dev));
- return genfbclose(&sc->gensc, sc->adp, flag, mode, td);
-}
-
-static int
-gdcread(struct cdev *dev, struct uio *uio, int flag)
-{
- gdc_softc_t *sc;
-
- sc = GDC_SOFTC(GDC_UNIT(dev));
- return genfbread(&sc->gensc, sc->adp, uio, flag);
-}
-
-static int
-gdcwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- gdc_softc_t *sc;
-
- sc = GDC_SOFTC(GDC_UNIT(dev));
- return genfbread(&sc->gensc, sc->adp, uio, flag);
-}
-
-static int
-gdcioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
-{
- gdc_softc_t *sc;
-
- sc = GDC_SOFTC(GDC_UNIT(dev));
- return genfbioctl(&sc->gensc, sc->adp, cmd, arg, flag, td);
-}
-
-static int
-gdcmmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int prot)
-{
- gdc_softc_t *sc;
-
- sc = GDC_SOFTC(GDC_UNIT(dev));
- return genfbmmap(&sc->gensc, sc->adp, offset, paddr, prot);
-}
-
-#endif /* FB_INSTALL_CDEV */
-
-static device_method_t gdc_methods[] = {
- DEVMETHOD(device_identify, gdc_identify),
- DEVMETHOD(device_probe, gdcprobe),
- DEVMETHOD(device_attach, gdc_attach),
- { 0, 0 }
-};
-
-static driver_t gdcdriver = {
- DRIVER_NAME,
- gdc_methods,
- sizeof(gdc_softc_t),
-};
-
-DRIVER_MODULE(gdc, isa, gdcdriver, gdc_devclass, 0, 0);
-
-/* LOW-LEVEL */
-
-
-#include <pc98/pc98/30line.h>
-
-#define TEXT_BUF_BASE 0x000a0000
-#define TEXT_BUF_SIZE 0x00008000
-#define GRAPHICS_BUF_BASE 0x000a8000
-#define GRAPHICS_BUF_SIZE 0x00040000
-#define VIDEO_BUF_BASE 0x000a0000
-#define VIDEO_BUF_SIZE 0x00048000
-
-#define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED)
-#define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED)
-#define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED)
-
-/*
- * NOTE: `va_window' should have a virtual address, but is initialized
- * with a physical address in the following table, they will be
- * converted at run-time.
- */
-static video_adapter_t adapter_init_value[] = {
- { 0,
- KD_PC98, "gdc", /* va_type, va_name */
- 0, 0, /* va_unit, va_minor */
- V_ADP_COLOR | V_ADP_MODECHANGE | V_ADP_BORDER,
- TEXT_GDC, 16, TEXT_GDC, /* va_io*, XXX */
- VIDEO_BUF_BASE, VIDEO_BUF_SIZE, /* va_mem* */
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, /* va_window* */
- 0, 0, /* va_buffer, va_buffer_size */
- 0, M_PC98_80x25, 0, /* va_*mode* */
- },
-};
-
-static video_adapter_t biosadapter[1];
-
-/* video driver declarations */
-static int gdc_configure(int flags);
-static int gdc_err(video_adapter_t *adp, ...);
-static vi_probe_t gdc_probe;
-static vi_init_t gdc_init;
-static vi_get_info_t gdc_get_info;
-static vi_query_mode_t gdc_query_mode;
-static vi_set_mode_t gdc_set_mode;
-static vi_set_border_t gdc_set_border;
-static vi_save_state_t gdc_save_state;
-static vi_load_state_t gdc_load_state;
-static vi_read_hw_cursor_t gdc_read_hw_cursor;
-static vi_set_hw_cursor_t gdc_set_hw_cursor;
-static vi_set_hw_cursor_shape_t gdc_set_hw_cursor_shape;
-static vi_blank_display_t gdc_blank_display;
-static vi_mmap_t gdc_mmap_buf;
-static vi_ioctl_t gdc_dev_ioctl;
-static vi_clear_t gdc_clear;
-static vi_fill_rect_t gdc_fill_rect;
-static vi_bitblt_t gdc_bitblt;
-static vi_diag_t gdc_diag;
-static vi_save_palette_t gdc_save_palette;
-static vi_load_palette_t gdc_load_palette;
-static vi_set_win_org_t gdc_set_origin;
-
-static video_switch_t gdcvidsw = {
- gdc_probe,
- gdc_init,
- gdc_get_info,
- gdc_query_mode,
- gdc_set_mode,
- (vi_save_font_t *)gdc_err,
- (vi_load_font_t *)gdc_err,
- (vi_show_font_t *)gdc_err,
- gdc_save_palette,
- gdc_load_palette,
- gdc_set_border,
- gdc_save_state,
- gdc_load_state,
- gdc_set_origin,
- gdc_read_hw_cursor,
- gdc_set_hw_cursor,
- gdc_set_hw_cursor_shape,
- gdc_blank_display,
- gdc_mmap_buf,
- gdc_dev_ioctl,
- gdc_clear,
- gdc_fill_rect,
- gdc_bitblt,
- (int (*)(void))gdc_err,
- (int (*)(void))gdc_err,
- gdc_diag,
-};
-
-VIDEO_DRIVER(gdc, gdcvidsw, gdc_configure);
-
-/* GDC BIOS standard video modes */
-#define EOT (-1)
-#define NA (-2)
-
-static video_info_t bios_vmode[] = {
- { M_PC98_80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
-#ifdef LINE30
- { M_PC98_80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
-#endif
-#ifndef GDC_NOGRAPHICS
- { M_PC98_EGC640x400, V_INFO_COLOR | V_INFO_GRAPHICS,
- 640, 400, 8, 16, 4, 4,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0,
- V_INFO_MM_PLANAR },
- { M_PC98_PEGC640x400, V_INFO_COLOR | V_INFO_GRAPHICS | V_INFO_VESA,
- 640, 400, 8, 16, 8, 1,
- GRAPHICS_BUF_BASE, 0x00008000, 0x00008000, 0, 0,
- V_INFO_MM_PACKED, 1 },
-#ifdef LINE30
- { M_PC98_PEGC640x480, V_INFO_COLOR | V_INFO_GRAPHICS | V_INFO_VESA,
- 640, 480, 8, 16, 8, 1,
- GRAPHICS_BUF_BASE, 0x00008000, 0x00008000, 0, 0,
- V_INFO_MM_PACKED, 1 },
-#endif
-#endif
- { EOT },
-};
-
-static int gdc_init_done = FALSE;
-
-/* local functions */
-static int map_gen_mode_num(int type, int color, int mode);
-static int probe_adapters(void);
-
-#define prologue(adp, flag, err) \
- if (!gdc_init_done || !((adp)->va_flags & (flag))) \
- return (err)
-
-/* a backdoor for the console driver */
-static int
-gdc_configure(int flags)
-{
- probe_adapters();
- biosadapter[0].va_flags |= V_ADP_INITIALIZED;
- if (!config_done(&biosadapter[0])) {
- if (vid_register(&biosadapter[0]) < 0)
- return 1;
- biosadapter[0].va_flags |= V_ADP_REGISTERED;
- }
-
- return 1;
-}
-
-/* local subroutines */
-
-/* map a generic video mode to a known mode number */
-static int
-map_gen_mode_num(int type, int color, int mode)
-{
- static struct {
- int from;
- int to;
- } mode_map[] = {
- { M_TEXT_80x25, M_PC98_80x25, },
-#ifdef LINE30
- { M_TEXT_80x30, M_PC98_80x30, },
-#endif
- };
- int i;
-
- for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
- if (mode_map[i].from == mode)
- return mode_map[i].to;
- }
- return mode;
-}
-
-static int
-verify_adapter(video_adapter_t *adp)
-{
-#ifndef GDC_NOGRAPHICS
- int i;
-
- if (PC98_SYSTEM_PARAMETER(0x45c) & 0x40) { /* PEGC exists */
- adp->va_flags |= V_ADP_VESA; /* XXX */
- } else {
- for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
- if (bios_vmode[i].vi_flags & V_INFO_VESA)
- bios_vmode[i].vi_mode = NA;
- }
- }
-#endif
- return 0;
-}
-
-/* probe video adapters and return the number of detected adapters */
-static int
-probe_adapters(void)
-{
- video_info_t info;
-
- /* do this test only once */
- if (gdc_init_done)
- return 1;
- gdc_init_done = TRUE;
-
- biosadapter[0] = adapter_init_value[0];
- biosadapter[0].va_flags |= V_ADP_PROBED;
- biosadapter[0].va_mode =
- biosadapter[0].va_initial_mode = biosadapter[0].va_initial_bios_mode;
-
- if ((PC98_SYSTEM_PARAMETER(0x597) & 0x80) ||
- (PC98_SYSTEM_PARAMETER(0x458) & 0x80)) {
- gdc_FH = (inb(0x9a8) & 1) ? _31KHZ : _24KHZ;
- } else {
- gdc_FH = _24KHZ;
- }
-
- gdc_get_info(&biosadapter[0], biosadapter[0].va_initial_mode, &info);
- initialize_gdc(T25_G400, info.vi_flags & V_INFO_GRAPHICS);
-
- biosadapter[0].va_window = BIOS_PADDRTOVADDR(info.vi_window);
- biosadapter[0].va_window_size = info.vi_window_size;
- biosadapter[0].va_window_gran = info.vi_window_gran;
- biosadapter[0].va_buffer = 0;
- biosadapter[0].va_buffer_size = 0;
- if (info.vi_flags & V_INFO_GRAPHICS) {
- switch (info.vi_depth/info.vi_planes) {
- case 1:
- biosadapter[0].va_line_width = info.vi_width/8;
- break;
- case 2:
- biosadapter[0].va_line_width = info.vi_width/4;
- break;
- case 4:
- biosadapter[0].va_line_width = info.vi_width/2;
- break;
- case 8:
- default: /* shouldn't happen */
- biosadapter[0].va_line_width = info.vi_width;
- break;
- }
- } else {
- biosadapter[0].va_line_width = info.vi_width;
- }
- bcopy(&info, &biosadapter[0].va_info, sizeof(info));
-
- verify_adapter(&biosadapter[0]);
-
- return 1;
-}
-
-static void master_gdc_cmd(unsigned int cmd)
-{
- while ( (inb(TEXT_GDC) & 2) != 0);
- outb(TEXT_GDC+2, cmd);
-}
-
-static void master_gdc_prm(unsigned int pmtr)
-{
- while ( (inb(TEXT_GDC) & 2) != 0);
- outb(TEXT_GDC, pmtr);
-}
-
-static void master_gdc_word_prm(unsigned int wpmtr)
-{
- master_gdc_prm(wpmtr & 0x00ff);
- master_gdc_prm((wpmtr >> 8) & 0x00ff);
-}
-
-#ifdef LINE30
-static void master_gdc_fifo_empty(void)
-{
- while ( (inb(TEXT_GDC) & 4) == 0);
-}
-#endif
-
-static void master_gdc_wait_vsync(void)
-{
- while ( (inb(TEXT_GDC) & 0x20) != 0);
- while ( (inb(TEXT_GDC) & 0x20) == 0);
-}
-
-static void gdc_cmd(unsigned int cmd)
-{
- while ( (inb(GRAPHIC_GDC) & 2) != 0);
- outb( GRAPHIC_GDC+2, cmd);
-}
-
-#ifdef LINE30
-static void gdc_prm(unsigned int pmtr)
-{
- while ( (inb(GRAPHIC_GDC) & 2) != 0);
- outb( GRAPHIC_GDC, pmtr);
-}
-
-static void gdc_word_prm(unsigned int wpmtr)
-{
- gdc_prm(wpmtr & 0x00ff);
- gdc_prm((wpmtr >> 8) & 0x00ff);
-}
-
-static void gdc_fifo_empty(void)
-{
- while ( (inb(GRAPHIC_GDC) & 0x04) == 0);
-}
-#endif
-
-static void gdc_wait_vsync(void)
-{
- while ( (inb(GRAPHIC_GDC) & 0x20) != 0);
- while ( (inb(GRAPHIC_GDC) & 0x20) == 0);
-}
-
-#ifdef LINE30
-static int check_gdc_clock(void)
-{
- if ((inb(IO_SYSPORT) & 0x80) == 0){
- return _5MHZ;
- } else {
- return _2_5MHZ;
- }
-}
-#endif
-
-static void initialize_gdc(unsigned int mode, int isGraph)
-{
-#ifdef LINE30
- /* start 30line initialize */
- int m_mode, s_mode, gdc_clock, hsync_clock;
-
- gdc_clock = check_gdc_clock();
- m_mode = (mode == T25_G400) ? _25L : _30L;
- s_mode = 2*mode+gdc_clock;
- gdc_INFO = m_mode;
-
- master_gdc_wait_vsync();
-
- if ((PC98_SYSTEM_PARAMETER(0x597) & 0x80) ||
- (PC98_SYSTEM_PARAMETER(0x458) & 0x80)) {
- if (PC98_SYSTEM_PARAMETER(0x481) & 0x08) {
- hsync_clock = (m_mode == _25L) ? gdc_FH : _31KHZ;
- outb(0x9a8, (hsync_clock == _31KHZ) ? 1 : 0);
- } else {
- hsync_clock = gdc_FH;
- }
- } else {
- hsync_clock = _24KHZ;
- }
-
- if ((gdc_clock == _2_5MHZ) &&
- (slave_param[hsync_clock][s_mode][GDC_LF] > 400)) {
- outb(0x6a, 0x83);
- outb(0x6a, 0x85);
- gdc_clock = _5MHZ;
- s_mode = 2*mode+gdc_clock;
- }
-
- master_gdc_cmd(_GDC_RESET);
- master_gdc_cmd(_GDC_MASTER);
- gdc_cmd(_GDC_RESET);
- gdc_cmd(_GDC_SLAVE);
-
- /* GDC Master */
- master_gdc_cmd(_GDC_SYNC);
- master_gdc_prm(0x00); /* flush less */ /* text & graph */
- master_gdc_prm(master_param[hsync_clock][m_mode][GDC_CR]);
- master_gdc_word_prm(((master_param[hsync_clock][m_mode][GDC_HFP] << 10)
- + (master_param[hsync_clock][m_mode][GDC_VS] << 5)
- + master_param[hsync_clock][m_mode][GDC_HS]));
- master_gdc_prm(master_param[hsync_clock][m_mode][GDC_HBP]);
- master_gdc_prm(master_param[hsync_clock][m_mode][GDC_VFP]);
- master_gdc_word_prm(((master_param[hsync_clock][m_mode][GDC_VBP] << 10)
- + (master_param[hsync_clock][m_mode][GDC_LF])));
- master_gdc_fifo_empty();
- master_gdc_cmd(_GDC_PITCH);
- master_gdc_prm(MasterPCH);
- master_gdc_fifo_empty();
-
- /* GDC slave */
- gdc_cmd(_GDC_SYNC);
- gdc_prm(0x06);
- gdc_prm(slave_param[hsync_clock][s_mode][GDC_CR]);
- gdc_word_prm((slave_param[hsync_clock][s_mode][GDC_HFP] << 10)
- + (slave_param[hsync_clock][s_mode][GDC_VS] << 5)
- + (slave_param[hsync_clock][s_mode][GDC_HS]));
- gdc_prm(slave_param[hsync_clock][s_mode][GDC_HBP]);
- gdc_prm(slave_param[hsync_clock][s_mode][GDC_VFP]);
- gdc_word_prm((slave_param[hsync_clock][s_mode][GDC_VBP] << 10)
- + (slave_param[hsync_clock][s_mode][GDC_LF]));
- gdc_fifo_empty();
- gdc_cmd(_GDC_PITCH);
- gdc_prm(SlavePCH[gdc_clock]);
- gdc_fifo_empty();
-
- /* set Master GDC scroll param */
- master_gdc_wait_vsync();
- master_gdc_wait_vsync();
- master_gdc_wait_vsync();
- master_gdc_cmd(_GDC_SCROLL);
- master_gdc_word_prm(0);
- master_gdc_word_prm((master_param[hsync_clock][m_mode][GDC_LF] << 4)
- | 0x0000);
- master_gdc_fifo_empty();
-
- /* set Slave GDC scroll param */
- gdc_wait_vsync();
- gdc_cmd(_GDC_SCROLL);
- gdc_word_prm(0);
- if (gdc_clock == _5MHZ) {
- gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
- } else {
- gdc_word_prm(SlaveScrlLF[mode] << 4);
- }
- gdc_fifo_empty();
-
- gdc_word_prm(0);
- if (gdc_clock == _5MHZ) {
- gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
- } else {
- gdc_word_prm(SlaveScrlLF[mode] << 4);
- }
- gdc_fifo_empty();
-
- /* sync start */
- gdc_cmd(isGraph ? _GDC_START : _GDC_STOP);
-
- gdc_wait_vsync();
- gdc_wait_vsync();
- gdc_wait_vsync();
-
- master_gdc_cmd(isGraph ? _GDC_STOP : _GDC_START);
-#else
- master_gdc_wait_vsync();
- master_gdc_cmd(isGraph ? _GDC_STOP : _GDC_START); /* text */
- gdc_wait_vsync();
- gdc_cmd(isGraph ? _GDC_START : _GDC_STOP); /* graphics */
-#endif
-}
-
-#ifndef GDC_NOGRAPHICS
-static u_char b_palette[] = {
- /* R G B */
- 0x00, 0x00, 0x00, /* 0 */
- 0x00, 0x00, 0x7f, /* 1 */
- 0x7f, 0x00, 0x00, /* 2 */
- 0x7f, 0x00, 0x7f, /* 3 */
- 0x00, 0x7f, 0x00, /* 4 */
- 0x00, 0x7f, 0x7f, /* 5 */
- 0x7f, 0x7f, 0x00, /* 6 */
- 0x7f, 0x7f, 0x7f, /* 7 */
- 0x40, 0x40, 0x40, /* 8 */
- 0x00, 0x00, 0xff, /* 9 */
- 0xff, 0x00, 0x00, /* 10 */
- 0xff, 0x00, 0xff, /* 11 */
- 0x00, 0xff, 0x00, /* 12 */
- 0x00, 0xff, 0xff, /* 13 */
- 0xff, 0xff, 0x00, /* 14 */
- 0xff, 0xff, 0xff, /* 15 */
-};
-#endif
-
-static int
-gdc_load_palette(video_adapter_t *adp, u_char *palette)
-{
-#ifndef GDC_NOGRAPHICS
- int i;
-
- if (adp->va_info.vi_flags & V_INFO_VESA) {
- gdc_wait_vsync();
- for (i = 0; i < 256; ++i) {
- outb(0xa8, i);
- outb(0xac, *palette++); /* R */
- outb(0xaa, *palette++); /* G */
- outb(0xae, *palette++); /* B */
- }
- } else {
- /*
- * XXX - Even though PC-98 text color is independent of palette,
- * we should set palette in text mode.
- * Because the background color of text mode is palette 0's one.
- */
- outb(0x6a, 1); /* 16 colors mode */
- bcopy(palette, b_palette, sizeof(b_palette));
-
- gdc_wait_vsync();
- for (i = 0; i < 16; ++i) {
- outb(0xa8, i);
- outb(0xac, *palette++ >> 4); /* R */
- outb(0xaa, *palette++ >> 4); /* G */
- outb(0xae, *palette++ >> 4); /* B */
- }
- }
-#endif
- return 0;
-}
-
-static int
-gdc_save_palette(video_adapter_t *adp, u_char *palette)
-{
-#ifndef GDC_NOGRAPHICS
- int i;
-
- if (adp->va_info.vi_flags & V_INFO_VESA) {
- for (i = 0; i < 256; ++i) {
- outb(0xa8, i);
- *palette++ = inb(0xac); /* R */
- *palette++ = inb(0xaa); /* G */
- *palette++ = inb(0xae); /* B */
- }
- } else {
- bcopy(b_palette, palette, sizeof(b_palette));
- }
-#endif
- return 0;
-}
-
-static int
-gdc_set_origin(video_adapter_t *adp, off_t offset)
-{
-#ifndef GDC_NOGRAPHICS
- if (adp->va_info.vi_flags & V_INFO_VESA) {
- writew(BIOS_PADDRTOVADDR(0x000e0004), offset >> 15);
- }
-#endif
- return 0;
-}
-
-/* entry points */
-
-static int
-gdc_err(video_adapter_t *adp, ...)
-{
- return ENODEV;
-}
-
-static int
-gdc_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
-{
- probe_adapters();
- if (unit >= 1)
- return ENXIO;
-
- *adpp = &biosadapter[unit];
-
- return 0;
-}
-
-static int
-gdc_init(int unit, video_adapter_t *adp, int flags)
-{
- if ((unit >= 1) || (adp == NULL) || !probe_done(adp))
- return ENXIO;
-
- if (!init_done(adp)) {
- /* nothing to do really... */
- adp->va_flags |= V_ADP_INITIALIZED;
- }
-
- if (!config_done(adp)) {
- if (vid_register(adp) < 0)
- return ENXIO;
- adp->va_flags |= V_ADP_REGISTERED;
- }
-
- return 0;
-}
-
-/*
- * get_info():
- * Return the video_info structure of the requested video mode.
- */
-static int
-gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
-{
- int i;
-
- if (!gdc_init_done)
- return ENXIO;
-
- mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode);
- for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
- if (bios_vmode[i].vi_mode == NA)
- continue;
- if (mode == bios_vmode[i].vi_mode) {
- *info = bios_vmode[i];
- info->vi_buffer_size = info->vi_window_size*info->vi_planes;
- return 0;
- }
- }
- return EINVAL;
-}
-
-/*
- * query_mode():
- * Find a video mode matching the requested parameters.
- * Fields filled with 0 are considered "don't care" fields and
- * match any modes.
- */
-static int
-gdc_query_mode(video_adapter_t *adp, video_info_t *info)
-{
- int i;
-
- if (!gdc_init_done)
- return ENXIO;
-
- for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
- if (bios_vmode[i].vi_mode == NA)
- continue;
-
- if ((info->vi_width != 0)
- && (info->vi_width != bios_vmode[i].vi_width))
- continue;
- if ((info->vi_height != 0)
- && (info->vi_height != bios_vmode[i].vi_height))
- continue;
- if ((info->vi_cwidth != 0)
- && (info->vi_cwidth != bios_vmode[i].vi_cwidth))
- continue;
- if ((info->vi_cheight != 0)
- && (info->vi_cheight != bios_vmode[i].vi_cheight))
- continue;
- if ((info->vi_depth != 0)
- && (info->vi_depth != bios_vmode[i].vi_depth))
- continue;
- if ((info->vi_planes != 0)
- && (info->vi_planes != bios_vmode[i].vi_planes))
- continue;
- /* XXX: should check pixel format, memory model */
- if ((info->vi_flags != 0)
- && (info->vi_flags != bios_vmode[i].vi_flags))
- continue;
-
- /* verify if this mode is supported on this adapter */
- if (gdc_get_info(adp, bios_vmode[i].vi_mode, info))
- continue;
- return 0;
- }
- return ENODEV;
-}
-
-/*
- * set_mode():
- * Change the video mode.
- */
-static int
-gdc_set_mode(video_adapter_t *adp, int mode)
-{
- video_info_t info;
-
- prologue(adp, V_ADP_MODECHANGE, ENODEV);
-
- mode = map_gen_mode_num(adp->va_type,
- adp->va_flags & V_ADP_COLOR, mode);
- if (gdc_get_info(adp, mode, &info))
- return EINVAL;
-
- switch (info.vi_mode) {
-#ifndef GDC_NOGRAPHICS
- case M_PC98_PEGC640x480: /* PEGC 640x480 */
- initialize_gdc(T30_G480, info.vi_flags & V_INFO_GRAPHICS);
- break;
- case M_PC98_PEGC640x400: /* PEGC 640x400 */
- case M_PC98_EGC640x400: /* EGC GRAPHICS */
-#endif
- case M_PC98_80x25: /* VGA TEXT */
- initialize_gdc(T25_G400, info.vi_flags & V_INFO_GRAPHICS);
- break;
- case M_PC98_80x30: /* VGA TEXT */
- initialize_gdc(T30_G400, info.vi_flags & V_INFO_GRAPHICS);
- break;
- default:
- break;
- }
-
-#ifndef GDC_NOGRAPHICS
- if (info.vi_flags & V_INFO_VESA) {
- outb(0x6a, 0x07); /* enable mode F/F change */
- outb(0x6a, 0x21); /* enhanced graphics */
- if (info.vi_height > 400)
- outb(0x6a, 0x69); /* 800 lines */
- writeb(BIOS_PADDRTOVADDR(0x000e0100), 0); /* packed pixel */
- } else {
- if (adp->va_flags & V_ADP_VESA) {
- outb(0x6a, 0x07); /* enable mode F/F change */
- outb(0x6a, 0x20); /* normal graphics */
- outb(0x6a, 0x68); /* 400 lines */
- }
- outb(0x6a, 1); /* 16 colors */
- }
-#endif
-
- adp->va_mode = mode;
- adp->va_flags &= ~V_ADP_COLOR;
- adp->va_flags |=
- (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
-#if 0
- adp->va_crtc_addr =
- (adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC;
-#endif
- adp->va_window = BIOS_PADDRTOVADDR(info.vi_window);
- adp->va_window_size = info.vi_window_size;
- adp->va_window_gran = info.vi_window_gran;
- if (info.vi_buffer_size == 0) {
- adp->va_buffer = 0;
- adp->va_buffer_size = 0;
- } else {
- adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer);
- adp->va_buffer_size = info.vi_buffer_size;
- }
- if (info.vi_flags & V_INFO_GRAPHICS) {
- switch (info.vi_depth/info.vi_planes) {
- case 1:
- adp->va_line_width = info.vi_width/8;
- break;
- case 2:
- adp->va_line_width = info.vi_width/4;
- break;
- case 4:
- adp->va_line_width = info.vi_width/2;
- break;
- case 8:
- default: /* shouldn't happen */
- adp->va_line_width = info.vi_width;
- break;
- }
- } else {
- adp->va_line_width = info.vi_width;
- }
- bcopy(&info, &adp->va_info, sizeof(info));
-
- /* move hardware cursor out of the way */
- (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
-
- return 0;
-}
-
-/*
- * set_border():
- * Change the border color.
- */
-static int
-gdc_set_border(video_adapter_t *adp, int color)
-{
- outb(0x6c, color << 4);
- return 0;
-}
-
-/*
- * save_state():
- * Read video card register values.
- */
-static int
-gdc_save_state(video_adapter_t *adp, void *p, size_t size)
-{
- return ENODEV;
-}
-
-/*
- * load_state():
- * Set video card registers at once.
- */
-static int
-gdc_load_state(video_adapter_t *adp, void *p)
-{
- return ENODEV;
-}
-
-/*
- * read_hw_cursor():
- * Read the position of the hardware text cursor.
- */
-static int
-gdc_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
-{
- u_int16_t off;
- int s;
-
- if (!gdc_init_done)
- return ENXIO;
-
- if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return ENODEV;
-
- s = spltty();
- master_gdc_cmd(0xe0); /* _GDC_CSRR */
- while((inb(TEXT_GDC + 0) & 0x1) == 0) {} /* GDC wait */
- off = inb(TEXT_GDC + 2); /* EADl */
- off |= (inb(TEXT_GDC + 2) << 8); /* EADh */
- inb(TEXT_GDC + 2); /* dummy */
- inb(TEXT_GDC + 2); /* dummy */
- inb(TEXT_GDC + 2); /* dummy */
- splx(s);
-
- if (off >= ROW*COL)
- off = 0;
- *row = off / adp->va_info.vi_width;
- *col = off % adp->va_info.vi_width;
-
- return 0;
-}
-
-/*
- * set_hw_cursor():
- * Move the hardware text cursor. If col and row are both -1,
- * the cursor won't be shown.
- */
-static int
-gdc_set_hw_cursor(video_adapter_t *adp, int col, int row)
-{
- u_int16_t off;
- int s;
-
- if (!gdc_init_done)
- return ENXIO;
-
- if ((col == -1) && (row == -1)) {
- off = -1;
- } else {
- if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return ENODEV;
- off = row*adp->va_info.vi_width + col;
- }
-
- s = spltty();
- master_gdc_cmd(0x49); /* _GDC_CSRW */
- master_gdc_word_prm(off);
- splx(s);
-
- return 0;
-}
-
-/*
- * set_hw_cursor_shape():
- * Change the shape of the hardware text cursor. If the height is zero
- * or negative, the cursor won't be shown.
- */
-static int
-gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
- int celsize, int blink)
-{
- int start;
- int end;
- int s;
-
- if (!gdc_init_done)
- return ENXIO;
-
- start = celsize - (base + height);
- end = celsize - base - 1;
-
-#if 0
- /*
- * muPD7220 GDC has anomaly that if end == celsize - 1 then start
- * must be 0, otherwise the cursor won't be correctly shown
- * in the first row in the screen. We shall set end to celsize - 2;
- * if end == celsize -1 && start > 0. XXX
- */
- if ((end == celsize - 1) && (start > 0) && (start < end))
- --end;
-#endif
-
- s = spltty();
- master_gdc_cmd(0x4b); /* _GDC_CSRFORM */
- master_gdc_prm(((height > 0) ? 0x80 : 0) /* cursor on/off */
- | ((celsize - 1) & 0x1f)); /* cel size */
- master_gdc_word_prm(((end & 0x1f) << 11) /* end line */
- | (12 << 6) /* blink rate */
- | (blink ? 0 : 0x20) /* blink on/off */
- | (start & 0x1f)); /* start line */
- splx(s);
-
- return 0;
-}
-
-/*
- * blank_display()
- * Put the display in power save/power off mode.
- */
-static int
-gdc_blank_display(video_adapter_t *adp, int mode)
-{
- int s;
- static int standby = 0;
-
- if (!gdc_init_done)
- return ENXIO;
-
- s = splhigh();
- switch (mode) {
- case V_DISPLAY_SUSPEND:
- case V_DISPLAY_STAND_BY:
- outb(0x09a2, 0x80 | 0x40); /* V/H-SYNC mask */
- if (inb(0x09a2) == (0x80 | 0x40))
- standby = 1;
- /* FALLTHROUGH */
-
- case V_DISPLAY_BLANK:
- if (epson_machine_id == 0x20) {
- outb(0x43f, 0x42);
- outb(0xc17, inb(0xc17) & ~0x08); /* turn off side light */
- outb(0xc16, inb(0xc16) & ~0x02); /* turn off back light */
- outb(0x43f, 0x40);
- } else {
- while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */
- ;
- outb(TEXT_GDC + 8, 0x0e); /* DISP off */
- }
- break;
-
- case V_DISPLAY_ON:
- if (epson_machine_id == 0x20) {
- outb(0x43f, 0x42);
- outb(0xc17, inb(0xc17) | 0x08);
- outb(0xc16, inb(0xc16) | 0x02);
- outb(0x43f, 0x40);
- } else {
- while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */
- ;
- outb(TEXT_GDC + 8, 0x0f); /* DISP on */
- }
- if (standby) {
- outb(0x09a2, 0x00); /* V/H-SYNC unmask */
- standby = 0;
- }
- break;
- }
- splx(s);
- return 0;
-}
-
-/*
- * mmap():
- * Mmap frame buffer.
- */
-static int
-gdc_mmap_buf(video_adapter_t *adp, vm_offset_t offset, vm_offset_t *paddr,
- int prot)
-{
- /* FIXME: is this correct? XXX */
- if (offset > VIDEO_BUF_SIZE - PAGE_SIZE)
- return -1;
- *paddr = adp->va_info.vi_window + offset;
- return 0;
-}
-
-#ifndef GDC_NOGRAPHICS
-static void
-planar_fill(video_adapter_t *adp, int val)
-{
-
- outb(0x7c, 0x80); /* GRCG on & TDW mode */
- outb(0x7e, 0); /* tile B */
- outb(0x7e, 0); /* tile R */
- outb(0x7e, 0); /* tile G */
- outb(0x7e, 0); /* tile I */
-
- fillw_io(0, adp->va_window, 0x8000 / 2); /* XXX */
-
- outb(0x7c, 0); /* GRCG off */
-}
-
-static void
-packed_fill(video_adapter_t *adp, int val)
-{
- int length;
- int at; /* position in the frame buffer */
- int l;
-
- at = 0;
- length = adp->va_line_width*adp->va_info.vi_height;
- while (length > 0) {
- l = imin(length, adp->va_window_size);
- (*vidsw[adp->va_index]->set_win_org)(adp, at);
- bzero_io(adp->va_window, l);
- length -= l;
- at += l;
- }
-}
-
-static int
-gdc_clear(video_adapter_t *adp)
-{
-
- switch (adp->va_info.vi_mem_model) {
- case V_INFO_MM_TEXT:
- /* do nothing? XXX */
- break;
- case V_INFO_MM_PLANAR:
- planar_fill(adp, 0);
- break;
- case V_INFO_MM_PACKED:
- packed_fill(adp, 0);
- break;
- }
-
- return 0;
-}
-#else /* GDC_NOGRAPHICS */
-static int
-gdc_clear(video_adapter_t *adp)
-{
-
- return 0;
-}
-#endif /* GDC_NOGRAPHICS */
-
-static int
-gdc_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
-{
- return ENODEV;
-}
-
-static int
-gdc_bitblt(video_adapter_t *adp,...)
-{
- /* FIXME */
- return ENODEV;
-}
-
-static int
-gdc_dev_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
-{
- switch (cmd) {
- case FBIO_GETWINORG: /* get frame buffer window origin */
- *(u_int *)arg = 0;
- return 0;
-
- case FBIO_SETWINORG: /* set frame buffer window origin */
- case FBIO_SETDISPSTART: /* set display start address */
- case FBIO_SETLINEWIDTH: /* set scan line length in pixel */
- case FBIO_GETPALETTE: /* get color palette */
- case FBIO_SETPALETTE: /* set color palette */
- case FBIOGETCMAP: /* get color palette */
- case FBIOPUTCMAP: /* set color palette */
- return ENODEV;
-
- case FBIOGTYPE: /* get frame buffer type info. */
- ((struct fbtype *)arg)->fb_type = fb_type(adp->va_type);
- ((struct fbtype *)arg)->fb_height = adp->va_info.vi_height;
- ((struct fbtype *)arg)->fb_width = adp->va_info.vi_width;
- ((struct fbtype *)arg)->fb_depth = adp->va_info.vi_depth;
- if ((adp->va_info.vi_depth <= 1) || (adp->va_info.vi_depth > 8))
- ((struct fbtype *)arg)->fb_cmsize = 0;
- else
- ((struct fbtype *)arg)->fb_cmsize = 1 << adp->va_info.vi_depth;
- ((struct fbtype *)arg)->fb_size = adp->va_buffer_size;
- return 0;
-
- default:
- return fb_commonioctl(adp, cmd, arg);
- }
-}
-
-/*
- * diag():
- * Print some information about the video adapter and video modes,
- * with requested level of details.
- */
-static int
-gdc_diag(video_adapter_t *adp, int level)
-{
-#if FB_DEBUG > 1
- int i;
-#endif
-
- if (!gdc_init_done)
- return ENXIO;
-
- fb_dump_adp_info(DRIVER_NAME, adp, level);
-
-#if FB_DEBUG > 1
- for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
- if (bios_vmode[i].vi_mode == NA)
- continue;
- if (get_mode_param(bios_vmode[i].vi_mode) == NULL)
- continue;
- fb_dump_mode_info(DRIVER_NAME, adp, &bios_vmode[i], level);
- }
-#endif
-
- return 0;
-}
diff --git a/sys/pc98/pc98/pc98kbd.c b/sys/pc98/pc98/pc98kbd.c
deleted file mode 100644
index f33b8c2..0000000
--- a/sys/pc98/pc98/pc98kbd.c
+++ /dev/null
@@ -1,964 +0,0 @@
-/*-
- * Copyright (c) 1999 FreeBSD(98) port team.
- * 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.
- *
- * $FreeBSD$
- */
-
-#include "opt_kbd.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <sys/kbio.h>
-
-#include <machine/resource.h>
-
-#include <dev/kbd/kbdreg.h>
-
-#include <pc98/pc98/pc98.h>
-
-#include <isa/isavar.h>
-
-#define DRIVER_NAME "pckbd"
-
-/* device configuration flags */
-#define KB_CONF_FAIL_IF_NO_KBD (1 << 0) /* don't install if no kbd is found */
-
-static devclass_t pckbd_devclass;
-
-static int pckbdprobe(device_t dev);
-static int pckbdattach(device_t dev);
-static int pckbdresume(device_t dev);
-static void pckbd_isa_intr(void *arg);
-
-static device_method_t pckbd_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, pckbdprobe),
- DEVMETHOD(device_attach, pckbdattach),
- DEVMETHOD(device_resume, pckbdresume),
- { 0, 0 }
-};
-
-static driver_t pckbd_driver = {
- DRIVER_NAME,
- pckbd_methods,
- 1,
-};
-
-DRIVER_MODULE(pckbd, isa, pckbd_driver, pckbd_devclass, 0, 0);
-
-static bus_addr_t pckbd_iat[] = {0, 2};
-
-static int pckbd_probe_unit(int unit, int port, int irq,
- int flags);
-static int pckbd_attach_unit(int unit, keyboard_t **kbd,
- int port, int irq, int flags);
-static timeout_t pckbd_timeout;
-
-
-static int
-pckbdprobe(device_t dev)
-{
- struct resource *res;
- int error, rid;
-
- /* Check isapnp ids */
- if (isa_get_vendorid(dev))
- return (ENXIO);
-
- device_set_desc(dev, "PC-98 Keyboard");
-
- rid = 0;
- res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, pckbd_iat, 2,
- RF_ACTIVE);
- if (res == NULL)
- return ENXIO;
- isa_load_resourcev(res, pckbd_iat, 2);
-
- error = pckbd_probe_unit(device_get_unit(dev),
- isa_get_port(dev),
- (1 << isa_get_irq(dev)),
- device_get_flags(dev));
-
- bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
-
- return (error);
-}
-
-static int
-pckbdattach(device_t dev)
-{
- keyboard_t *kbd;
- void *ih;
- struct resource *res;
- int error, rid;
-
- rid = 0;
- res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, pckbd_iat, 2,
- RF_ACTIVE);
- if (res == NULL)
- return ENXIO;
- isa_load_resourcev(res, pckbd_iat, 2);
-
- error = pckbd_attach_unit(device_get_unit(dev), &kbd,
- isa_get_port(dev),
- (1 << isa_get_irq(dev)),
- device_get_flags(dev));
-
- rid = 0;
- res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
- if (res == NULL)
- return ENXIO;
- BUS_SETUP_INTR(device_get_parent(dev), dev, res, INTR_TYPE_TTY,
- pckbd_isa_intr, kbd, &ih);
-
- return 0;
-}
-
-static int
-pckbdresume(device_t dev)
-{
- keyboard_t *kbd;
-
- kbd = kbd_get_keyboard(kbd_find_keyboard(DRIVER_NAME,
- device_get_unit(dev)));
- if (kbd)
- (*kbdsw[kbd->kb_index]->clear_state)(kbd);
-
- return (0);
-}
-
-static void
-pckbd_isa_intr(void *arg)
-{
- keyboard_t *kbd = arg;
-
- (*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
-}
-
-static int
-pckbd_probe_unit(int unit, int port, int irq, int flags)
-{
- keyboard_switch_t *sw;
- int args[2];
- int error;
-
- sw = kbd_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
-
- args[0] = port;
- args[1] = irq;
- error = (*sw->probe)(unit, args, flags);
- if (error)
- return error;
- return 0;
-}
-
-static int
-pckbd_attach_unit(int unit, keyboard_t **kbd, int port, int irq, int flags)
-{
- keyboard_switch_t *sw;
- int args[2];
- int error;
-
- sw = kbd_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
-
- /* reset, initialize and enable the device */
- args[0] = port;
- args[1] = irq;
- *kbd = NULL;
- error = (*sw->probe)(unit, args, flags);
- if (error)
- return error;
- error = (*sw->init)(unit, kbd, args, flags);
- if (error)
- return error;
- (*sw->enable)(*kbd);
-
-#ifdef KBD_INSTALL_CDEV
- /* attach a virtual keyboard cdev */
- error = kbd_attach(*kbd);
- if (error)
- return error;
-#endif /* KBD_INSTALL_CDEV */
-
- /*
- * This is a kludge to compensate for lost keyboard interrupts.
- * A similar code used to be in syscons. See below. XXX
- */
- pckbd_timeout(*kbd);
-
- if (bootverbose)
- (*sw->diag)(*kbd, bootverbose);
-
- return 0;
-}
-
-static void
-pckbd_timeout(void *arg)
-{
- keyboard_t *kbd;
- int s;
-
- /* The following comments are extracted from syscons.c (1.287) */
- /*
- * With release 2.1 of the Xaccel server, the keyboard is left
- * hanging pretty often. Apparently an interrupt from the
- * keyboard is lost, and I don't know why (yet).
- * This ugly hack calls scintr if input is ready for the keyboard
- * and conveniently hides the problem. XXX
- */
- /*
- * Try removing anything stuck in the keyboard controller; whether
- * it's a keyboard scan code or mouse data. `scintr()' doesn't
- * read the mouse data directly, but `kbdio' routines will, as a
- * side effect.
- */
- s = spltty();
- kbd = (keyboard_t *)arg;
- if ((*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) {
- /*
- * We have seen the lock flag is not set. Let's reset
- * the flag early, otherwise the LED update routine fails
- * which may want the lock during the interrupt routine.
- */
- (*kbdsw[kbd->kb_index]->lock)(kbd, FALSE);
- if ((*kbdsw[kbd->kb_index]->check_char)(kbd))
- (*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
- }
- splx(s);
- timeout(pckbd_timeout, arg, hz/10);
-}
-
-/* LOW-LEVEL */
-
-#include <sys/limits.h>
-
-#define PC98KBD_DEFAULT 0
-
-typedef caddr_t KBDC;
-
-typedef struct pckbd_state {
- KBDC kbdc; /* keyboard controller */
- int ks_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
- int ks_flags; /* flags */
-#define COMPOSE (1 << 0)
- int ks_state; /* shift/lock key state */
- int ks_accents; /* accent key index (> 0) */
- u_int ks_composed_char; /* composed char code (> 0) */
-} pckbd_state_t;
-
-/* keyboard driver declaration */
-static int pckbd_configure(int flags);
-static kbd_probe_t pckbd_probe;
-static kbd_init_t pckbd_init;
-static kbd_term_t pckbd_term;
-static kbd_intr_t pckbd_intr;
-static kbd_test_if_t pckbd_test_if;
-static kbd_enable_t pckbd_enable;
-static kbd_disable_t pckbd_disable;
-static kbd_read_t pckbd_read;
-static kbd_check_t pckbd_check;
-static kbd_read_char_t pckbd_read_char;
-static kbd_check_char_t pckbd_check_char;
-static kbd_ioctl_t pckbd_ioctl;
-static kbd_lock_t pckbd_lock;
-static kbd_clear_state_t pckbd_clear_state;
-static kbd_get_state_t pckbd_get_state;
-static kbd_set_state_t pckbd_set_state;
-static kbd_poll_mode_t pckbd_poll;
-
-keyboard_switch_t pckbdsw = {
- pckbd_probe,
- pckbd_init,
- pckbd_term,
- pckbd_intr,
- pckbd_test_if,
- pckbd_enable,
- pckbd_disable,
- pckbd_read,
- pckbd_check,
- pckbd_read_char,
- pckbd_check_char,
- pckbd_ioctl,
- pckbd_lock,
- pckbd_clear_state,
- pckbd_get_state,
- pckbd_set_state,
- genkbd_get_fkeystr,
- pckbd_poll,
- genkbd_diag,
-};
-
-KEYBOARD_DRIVER(pckbd, pckbdsw, pckbd_configure);
-
-struct kbdc_softc {
- int port; /* base port address */
- int lock; /* FIXME: XXX not quite a semaphore... */
-};
-
-/* local functions */
-static int probe_keyboard(KBDC kbdc, int flags);
-static int init_keyboard(KBDC kbdc, int *type, int flags);
-static KBDC kbdc_open(int port);
-static int kbdc_lock(KBDC kbdc, int lock);
-static int kbdc_data_ready(KBDC kbdc);
-static int read_kbd_data(KBDC kbdc);
-static int read_kbd_data_no_wait(KBDC kbdc);
-static int wait_for_kbd_data(struct kbdc_softc *kbdc);
-
-/* local variables */
-
-/* the initial key map, accent map and fkey strings */
-#include <dev/kbd/kbdtables.h>
-
-/* structures for the default keyboard */
-static keyboard_t default_kbd;
-static pckbd_state_t default_kbd_state;
-static keymap_t default_keymap;
-static accentmap_t default_accentmap;
-static fkeytab_t default_fkeytab[NUM_FKEYS];
-
-/*
- * The back door to the keyboard driver!
- * This function is called by the console driver, via the kbdio module,
- * to tickle keyboard drivers when the low-level console is being initialized.
- * Almost nothing in the kernel has been initialied yet. Try to probe
- * keyboards if possible.
- * NOTE: because of the way the low-level conole is initialized, this routine
- * may be called more than once!!
- */
-static int
-pckbd_configure(int flags)
-{
- keyboard_t *kbd;
- int arg[2];
- int i;
-
- /* XXX: a kludge to obtain the device configuration flags */
- if (resource_int_value(DRIVER_NAME, 0, "flags", &i) == 0) {
- flags |= i;
- /* if the driver is disabled, unregister the keyboard if any */
- if (resource_disabled(DRIVER_NAME, 0)) {
- i = kbd_find_keyboard(DRIVER_NAME, PC98KBD_DEFAULT);
- if (i >= 0) {
- kbd = kbd_get_keyboard(i);
- kbd_unregister(kbd);
- kbd->kb_flags &= ~KB_REGISTERED;
- return 0;
- }
- }
- }
-
- /* probe the default keyboard */
- arg[0] = -1;
- arg[1] = -1;
- kbd = NULL;
- if (pckbd_probe(PC98KBD_DEFAULT, arg, flags))
- return 0;
- if (pckbd_init(PC98KBD_DEFAULT, &kbd, arg, flags))
- return 0;
-
- /* return the number of found keyboards */
- return 1;
-}
-
-/* low-level functions */
-
-/* detect a keyboard */
-static int
-pckbd_probe(int unit, void *arg, int flags)
-{
- KBDC kbdc;
- int *data = (int *)arg;
-
- if (unit != PC98KBD_DEFAULT)
- return ENXIO;
- if (KBD_IS_PROBED(&default_kbd))
- return 0;
-
- kbdc = kbdc_open(data[0]);
- if (kbdc == NULL)
- return ENXIO;
- if (probe_keyboard(kbdc, flags)) {
- if (flags & KB_CONF_FAIL_IF_NO_KBD)
- return ENXIO;
- }
- return 0;
-}
-
-/* reset and initialize the device */
-static int
-pckbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
-{
- keyboard_t *kbd;
- pckbd_state_t *state;
- keymap_t *keymap;
- accentmap_t *accmap;
- fkeytab_t *fkeymap;
- int fkeymap_size;
- int *data = (int *)arg;
-
- if (unit != PC98KBD_DEFAULT) /* shouldn't happen */
- return ENXIO;
-
- *kbdp = kbd = &default_kbd;
- state = &default_kbd_state;
- if (!KBD_IS_PROBED(kbd)) {
- keymap = &default_keymap;
- accmap = &default_accentmap;
- fkeymap = default_fkeytab;
- fkeymap_size =
- sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
-
- state->kbdc = kbdc_open(data[0]);
- if (state->kbdc == NULL)
- return ENXIO;
- kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags,
- data[0], IO_KBDSIZE);
- bcopy(&key_map, keymap, sizeof(key_map));
- bcopy(&accent_map, accmap, sizeof(accent_map));
- bcopy(fkey_tab, fkeymap,
- imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
- kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
- kbd->kb_data = (void *)state;
-
- if (probe_keyboard(state->kbdc, flags)) {/* shouldn't happen */
- if (flags & KB_CONF_FAIL_IF_NO_KBD)
- return ENXIO;
- } else {
- KBD_FOUND_DEVICE(kbd);
- }
- pckbd_clear_state(kbd);
- state->ks_mode = K_XLATE;
- KBD_PROBE_DONE(kbd);
- }
- if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
- if (KBD_HAS_DEVICE(kbd)
- && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
- && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
- return ENXIO;
- pckbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
- KBD_INIT_DONE(kbd);
- }
- if (!KBD_IS_CONFIGURED(kbd)) {
- if (kbd_register(kbd) < 0)
- return ENXIO;
- KBD_CONFIG_DONE(kbd);
- }
-
- return 0;
-}
-
-/* finish using this keyboard */
-static int
-pckbd_term(keyboard_t *kbd)
-{
- kbd_unregister(kbd);
- return 0;
-}
-
-/* keyboard interrupt routine */
-static int
-pckbd_intr(keyboard_t *kbd, void *arg)
-{
- int c;
-
- if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
- /* let the callback function to process the input */
- (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
- kbd->kb_callback.kc_arg);
- } else {
- /* read and discard the input; no one is waiting for input */
- do {
- c = pckbd_read_char(kbd, FALSE);
- } while (c != NOKEY);
- }
- return 0;
-}
-
-/* test the interface to the device */
-static int
-pckbd_test_if(keyboard_t *kbd)
-{
- return 0;
-}
-
-/*
- * Enable the access to the device; until this function is called,
- * the client cannot read from the keyboard.
- */
-static int
-pckbd_enable(keyboard_t *kbd)
-{
- int s;
-
- s = spltty();
- KBD_ACTIVATE(kbd);
- splx(s);
- return 0;
-}
-
-/* disallow the access to the device */
-static int
-pckbd_disable(keyboard_t *kbd)
-{
- int s;
-
- s = spltty();
- KBD_DEACTIVATE(kbd);
- splx(s);
- return 0;
-}
-
-/* read one byte from the keyboard if it's allowed */
-static int
-pckbd_read(keyboard_t *kbd, int wait)
-{
- int c;
-
- if (wait)
- c = read_kbd_data(((pckbd_state_t *)kbd->kb_data)->kbdc);
- else
- c = read_kbd_data_no_wait(((pckbd_state_t *)kbd->kb_data)->kbdc);
- if (c != -1)
- ++kbd->kb_count;
- return (KBD_IS_ACTIVE(kbd) ? c : -1);
-}
-
-/* check if data is waiting */
-static int
-pckbd_check(keyboard_t *kbd)
-{
- if (!KBD_IS_ACTIVE(kbd))
- return FALSE;
- return kbdc_data_ready(((pckbd_state_t *)kbd->kb_data)->kbdc);
-}
-
-/* read char from the keyboard */
-static u_int
-pckbd_read_char(keyboard_t *kbd, int wait)
-{
- pckbd_state_t *state;
- u_int action;
- int scancode;
- int keycode;
-
- state = (pckbd_state_t *)kbd->kb_data;
-next_code:
- /* do we have a composed char to return? */
- if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
- action = state->ks_composed_char;
- state->ks_composed_char = 0;
- if (action > UCHAR_MAX)
- return ERRKEY;
- return action;
- }
-
- /* see if there is something in the keyboard port */
- if (wait) {
- do {
- scancode = read_kbd_data(state->kbdc);
- } while (scancode == -1);
- } else {
- scancode = read_kbd_data_no_wait(state->kbdc);
- if (scancode == -1)
- return NOKEY;
- }
- ++kbd->kb_count;
-
-#if 0
- printf("pckbd_read_char(): scancode:0x%x\n", scancode);
-#endif
-
- /* return the byte as is for the K_RAW mode */
- if (state->ks_mode == K_RAW)
- return scancode;
-
- /* translate the scan code into a keycode */
- keycode = scancode & 0x7F;
- switch(scancode) {
- case 0xF3: /* GRPH (compose key) released */
- if (state->ks_flags & COMPOSE) {
- state->ks_flags &= ~COMPOSE;
- if (state->ks_composed_char > UCHAR_MAX)
- state->ks_composed_char = 0;
- }
- break;
- case 0x73: /* GRPH (compose key) pressed */
- if (!(state->ks_flags & COMPOSE)) {
- state->ks_flags |= COMPOSE;
- state->ks_composed_char = 0;
- }
- break;
- }
-
- /* return the key code in the K_CODE mode */
- if (state->ks_mode == K_CODE)
- return (keycode | (scancode & 0x80));
-
- /* compose a character code */
- if (state->ks_flags & COMPOSE) {
- switch (scancode) {
- /* key pressed, process it */
- case 0x42: case 0x43: case 0x44: /* keypad 7,8,9 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += scancode - 0x3B;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x46: case 0x47: case 0x48: /* keypad 4,5,6 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += scancode - 0x42;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x4A: case 0x4B: case 0x4C: /* keypad 1,2,3 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += scancode - 0x49;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x4E: /* keypad 0 */
- state->ks_composed_char *= 10;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
-
- /* key released, no interest here */
- case 0xC2: case 0xC3: case 0xC4: /* keypad 7,8,9 */
- case 0xC6: case 0xC7: case 0xC8: /* keypad 4,5,6 */
- case 0xCA: case 0xCB: case 0xCC: /* keypad 1,2,3 */
- case 0xCE: /* keypad 0 */
- goto next_code;
-
- case 0x73: /* GRPH key */
- break;
-
- default:
- if (state->ks_composed_char > 0) {
- state->ks_flags &= ~COMPOSE;
- state->ks_composed_char = 0;
- return ERRKEY;
- }
- break;
- }
- }
-
- /* keycode to key action */
- action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
- &state->ks_state, &state->ks_accents);
- if (action == NOKEY)
- goto next_code;
- else
- return action;
-}
-
-/* check if char is waiting */
-static int
-pckbd_check_char(keyboard_t *kbd)
-{
- pckbd_state_t *state;
-
- if (!KBD_IS_ACTIVE(kbd))
- return FALSE;
- state = (pckbd_state_t *)kbd->kb_data;
- if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
- return TRUE;
- return kbdc_data_ready(state->kbdc);
-}
-
-/* some useful control functions */
-static int
-pckbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
-{
- pckbd_state_t *state = kbd->kb_data;
- int s;
- int i;
-
- s = spltty();
- switch (cmd) {
-
- case KDGKBMODE: /* get keyboard mode */
- *(int *)arg = state->ks_mode;
- break;
- case KDSKBMODE: /* set keyboard mode */
- switch (*(int *)arg) {
- case K_XLATE:
- if (state->ks_mode != K_XLATE) {
- /* make lock key state and LED state match */
- state->ks_state &= ~LOCK_MASK;
- state->ks_state |= KBD_LED_VAL(kbd);
- }
- /* FALLTHROUGH */
- case K_RAW:
- case K_CODE:
- if (state->ks_mode != *(int *)arg) {
- pckbd_clear_state(kbd);
- state->ks_mode = *(int *)arg;
- }
- break;
- default:
- splx(s);
- return EINVAL;
- }
- break;
-
- case KDGETLED: /* get keyboard LED */
- *(int *)arg = KBD_LED_VAL(kbd);
- break;
- case KDSETLED: /* set keyboard LED */
- /* NOTE: lock key state in ks_state won't be changed */
- if (*(int *)arg & ~LOCK_MASK) {
- splx(s);
- return EINVAL;
- }
- i = *(int *)arg;
- /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
- if (kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
- if (i & ALKED)
- i |= CLKED;
- else
- i &= ~CLKED;
- }
- KBD_LED_VAL(kbd) = *(int *)arg;
- break;
-
- case KDGKBSTATE: /* get lock key state */
- *(int *)arg = state->ks_state & LOCK_MASK;
- break;
- case KDSKBSTATE: /* set lock key state */
- if (*(int *)arg & ~LOCK_MASK) {
- splx(s);
- return EINVAL;
- }
- state->ks_state &= ~LOCK_MASK;
- state->ks_state |= *(int *)arg;
- splx(s);
- /* set LEDs and quit */
- return pckbd_ioctl(kbd, KDSETLED, arg);
-
- case KDSETRAD: /* set keyboard repeat rate (old interface)*/
- break;
- case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
- break;
-
- case PIO_KEYMAP: /* set keyboard translation table */
- case PIO_KEYMAPENT: /* set keyboard translation table entry */
- case PIO_DEADKEYMAP: /* set accent key translation table */
- state->ks_accents = 0;
- /* FALLTHROUGH */
- default:
- splx(s);
- return genkbd_commonioctl(kbd, cmd, arg);
- }
-
- splx(s);
- return 0;
-}
-
-/* lock the access to the keyboard */
-static int
-pckbd_lock(keyboard_t *kbd, int lock)
-{
- return kbdc_lock(((pckbd_state_t *)kbd->kb_data)->kbdc, lock);
-}
-
-/* clear the internal state of the keyboard */
-static void
-pckbd_clear_state(keyboard_t *kbd)
-{
- pckbd_state_t *state;
-
- state = (pckbd_state_t *)kbd->kb_data;
- state->ks_flags = 0;
- state->ks_state &= LOCK_MASK; /* preserve locking key state */
- state->ks_accents = 0;
- state->ks_composed_char = 0;
-}
-
-/* save the internal state */
-static int
-pckbd_get_state(keyboard_t *kbd, void *buf, size_t len)
-{
- if (len == 0)
- return sizeof(pckbd_state_t);
- if (len < sizeof(pckbd_state_t))
- return -1;
- bcopy(kbd->kb_data, buf, sizeof(pckbd_state_t));
- return 0;
-}
-
-/* set the internal state */
-static int
-pckbd_set_state(keyboard_t *kbd, void *buf, size_t len)
-{
- if (len < sizeof(pckbd_state_t))
- return ENOMEM;
- if (((pckbd_state_t *)kbd->kb_data)->kbdc
- != ((pckbd_state_t *)buf)->kbdc)
- return ENOMEM;
- bcopy(buf, kbd->kb_data, sizeof(pckbd_state_t));
- return 0;
-}
-
-/* set polling mode */
-static int
-pckbd_poll(keyboard_t *kbd, int on)
-{
- return 0;
-}
-
-/* local functions */
-
-static int
-probe_keyboard(KBDC kbdc, int flags)
-{
- return 0;
-}
-
-static int
-init_keyboard(KBDC kbdc, int *type, int flags)
-{
- *type = KB_OTHER;
- return 0;
-}
-
-/* keyboard I/O routines */
-
-/* retry count */
-#ifndef KBD_MAXRETRY
-#define KBD_MAXRETRY 3
-#endif
-
-/* timing parameters */
-#ifndef KBD_RESETDELAY
-#define KBD_RESETDELAY 200 /* wait 200msec after kbd/mouse reset */
-#endif
-#ifndef KBD_MAXWAIT
-#define KBD_MAXWAIT 5 /* wait 5 times at most after reset */
-#endif
-
-/* I/O recovery time */
-#define KBDC_DELAYTIME 37
-#define KBDD_DELAYTIME 37
-
-/* I/O ports */
-#define KBD_STATUS_PORT 2 /* status port, read */
-#define KBD_DATA_PORT 0 /* data port, read */
-
-/* status bits (KBD_STATUS_PORT) */
-#define KBDS_BUFFER_FULL 0x0002
-
-/* macros */
-
-#define kbdcp(p) ((struct kbdc_softc *)(p))
-
-/* local variables */
-
-static struct kbdc_softc kbdc_softc[1] = { { 0 }, };
-
-/* associate a port number with a KBDC */
-
-static KBDC
-kbdc_open(int port)
-{
- if (port <= 0)
- port = IO_KBD;
-
- /* PC-98 has only one keyboard I/F */
- kbdc_softc[0].port = port;
- kbdc_softc[0].lock = FALSE;
- return (KBDC)&kbdc_softc[0];
-}
-
-/* set/reset polling lock */
-static int
-kbdc_lock(KBDC p, int lock)
-{
- int prevlock;
-
- prevlock = kbdcp(p)->lock;
- kbdcp(p)->lock = lock;
-
- return (prevlock != lock);
-}
-
-/* check if any data is waiting to be processed */
-static int
-kbdc_data_ready(KBDC p)
-{
- return (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL);
-}
-
-/* wait for data from the keyboard */
-static int
-wait_for_kbd_data(struct kbdc_softc *kbdc)
-{
- /* CPU will stay inside the loop for 200msec at most */
- int retry = 10000;
- int port = kbdc->port;
-
- while (!(inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)) {
- DELAY(KBDD_DELAYTIME);
- DELAY(KBDC_DELAYTIME);
- if (--retry < 0)
- return 0;
- }
- DELAY(KBDD_DELAYTIME);
- return 1;
-}
-
-/* read one byte from the keyboard */
-static int
-read_kbd_data(KBDC p)
-{
- if (!wait_for_kbd_data(kbdcp(p)))
- return -1; /* timeout */
- DELAY(KBDC_DELAYTIME);
- return inb(kbdcp(p)->port + KBD_DATA_PORT);
-}
-
-/* read one byte from the keyboard, but return immediately if
- * no data is waiting
- */
-static int
-read_kbd_data_no_wait(KBDC p)
-{
- if (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL) {
- DELAY(KBDD_DELAYTIME);
- return inb(kbdcp(p)->port + KBD_DATA_PORT);
- }
- return -1; /* no data */
-}
diff --git a/sys/pc98/pc98/pmc.c b/sys/pc98/pc98/pmc.c
deleted file mode 100644
index 13eade0..0000000
--- a/sys/pc98/pc98/pmc.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*-
- * PMC (Power Management Controller of NEC PC-98Note) Driver
- *
- * Copyright (c) 2001 Chiharu Shibata.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/eventhandler.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/types.h>
-#include <sys/conf.h>
-#include <sys/reboot.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <isa/isavar.h>
-
-struct pmc_isa_softc {
- struct resource *port_res;
- eventhandler_tag evt;
- int flags;
-};
-
-static int pmc_isa_alloc_resources(device_t);
-static void pmc_isa_release_resources(device_t);
-static int pmc_isa_probe(device_t);
-static int pmc_isa_attach(device_t);
-static int pmc_isa_detach(device_t);
-
-#define PMC_ISA_PORT 0x8f0
-#define PMC_ISA_PORTSIZE 4
-
-#define sc_inw(sc, port) \
- bus_space_read_2(rman_get_bustag((sc)->port_res), \
- rman_get_bushandle((sc)->port_res), (port))
-
-#define sc_outw(sc, port, value) \
- bus_space_write_2(rman_get_bustag((sc)->port_res), \
- rman_get_bushandle((sc)->port_res), (port), (value))
-
-static void
-pmc_poweroff(void *arg, int howto)
-{
- struct pmc_isa_softc *sc = (struct pmc_isa_softc *)arg;
-
- if (!sc->flags) {
- outb(0x5e8e, inb(0x5e8e) & ~0x11); /* FDD LED off */
- }
-
- if (!(howto & RB_POWEROFF)) {
- return;
- }
-
- sc_outw(sc, 0, 0x0044);
- sc_outw(sc, 2, 1 << 10);
-#if 1
- /* for 9801NS/T */
- sc_outw(sc, 0, 0xf00a);
- sc_outw(sc, 2, 1 << 9);
-#endif
-}
-
-static int
-pmc_isa_alloc_resources(device_t dev)
-{
- struct pmc_isa_softc *sc = device_get_softc(dev);
- int rid;
-
- bzero(sc, sizeof(*sc));
-
- rid = 0;
- sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
- 0ul, ~0ul, PMC_ISA_PORTSIZE,
- RF_ACTIVE);
- if (sc->port_res == NULL) {
- return (ENOMEM);
- }
-
- return 0;
-}
-
-static void
-pmc_isa_release_resources(device_t dev)
-{
- struct pmc_isa_softc *sc = device_get_softc(dev);
-
- if (sc->port_res != NULL) {
- bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port_res);
- }
- sc->port_res = NULL;
-}
-
-static int
-pmc_isa_probe(device_t dev)
-{
- struct pmc_isa_softc *sc = device_get_softc(dev);
- u_int port;
- u_int16_t save, tmp;
-
-#if 0
- if (isa_get_vendorid(dev)) {
- return ENXIO;
- }
- if (device_get_unit(dev) > 0) {
- printf("pmc: Only one PMC driver supported.\n");
- return ENXIO;
- }
-#endif
- port = isa_get_port(dev);
- if (port == -1) {
- port = PMC_ISA_PORT;
- }
- if (bootverbose) {
- device_printf(dev, "port = 0x%x\n", port);
- }
-
- if (bus_set_resource(dev, SYS_RES_IOPORT, 0, port, PMC_ISA_PORTSIZE)) {
- if (bootverbose) {
- device_printf(dev, "bus_set_resource failed\n");
- }
- return ENXIO;
- }
- if (pmc_isa_alloc_resources(dev)) {
- if (bootverbose) {
- device_printf(dev, "pmc_isa_alloc_resources failed\n");
- }
- return ENXIO;
- }
-
- /* Check the existence of PMC */
- sc_outw(sc, 0, 0x0052);
- save = sc_inw(sc, 2);
- tmp = save & ~0x3f;
- sc_outw(sc, 2, tmp);
- if (sc_inw(sc, 2) != tmp) {
- if (bootverbose) {
- device_printf(dev, "failed to clear index(0x0052)\n");
- }
-
- pmc_isa_release_resources(dev);
- return ENXIO;
- }
-
- tmp |= 0x3e;
- sc_outw(sc, 2, tmp);
- if (sc_inw(sc, 2) != tmp) {
- if (bootverbose) {
- device_printf(dev, "failed to set index(0x0052)\n");
- }
-
- pmc_isa_release_resources(dev);
- return ENXIO;
- }
- sc_outw(sc, 2, save);
-
- pmc_isa_release_resources(dev);
-
- device_set_desc(dev, "Power Management Controller");
- return 0;
-}
-
-static int
-pmc_isa_attach(device_t dev)
-{
- struct pmc_isa_softc *sc = device_get_softc(dev);
- int error;
-
- error = pmc_isa_alloc_resources(dev);
- if (error) {
- device_printf(dev, "resource allocation failed\n");
- return error;
- }
-
- /* Power the system off using PMC */
- sc->evt = EVENTHANDLER_REGISTER(shutdown_final, pmc_poweroff, sc,
- SHUTDOWN_PRI_LAST);
- sc->flags = device_get_flags(dev);
- return 0;
-}
-
-static int
-pmc_isa_detach(device_t dev)
-{
- struct pmc_isa_softc *sc = device_get_softc(dev);
-
- if (bootverbose) {
- device_printf(dev, "pmc_isa_detach called\n");
- }
-
- if (sc->evt != NULL) {
- EVENTHANDLER_DEREGISTER(shutdown_final, sc->evt);
- }
- sc->evt = NULL;
-
- pmc_isa_release_resources(dev);
- return 0;
-}
-
-static device_method_t pmc_isa_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, pmc_isa_probe),
- DEVMETHOD(device_attach, pmc_isa_attach),
- DEVMETHOD(device_detach, pmc_isa_detach),
- {0, 0}
-};
-
-static driver_t pmc_isa_driver = {
- "pmc",
- pmc_isa_methods, sizeof(struct pmc_isa_softc),
-};
-
-devclass_t pmc_devclass;
-
-DRIVER_MODULE(pmc, isa, pmc_isa_driver, pmc_devclass, 0, 0);
diff --git a/sys/pc98/pc98/ppc.c b/sys/pc98/pc98/ppc.c
deleted file mode 100644
index 67adef3..0000000
--- a/sys/pc98/pc98/ppc.c
+++ /dev/null
@@ -1,2212 +0,0 @@
-/*-
- * Copyright (c) 2001 Alcove - Nicolas Souchu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- *
- */
-
-#include "opt_ppc.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <machine/vmparam.h>
-#include <sys/rman.h>
-
-#ifdef PC98
-#include <pc98/pc98/pc98.h>
-#else
-#include <isa/isareg.h>
-#endif
-#include <isa/isavar.h>
-
-#include <dev/ppbus/ppbconf.h>
-#include <dev/ppbus/ppb_msq.h>
-
-#include <dev/ppc/ppcvar.h>
-#ifdef PC98
-#include <pc98/pc98/ppcreg.h>
-#else
-#include <dev/ppc/ppcreg.h>
-#endif
-
-#include "ppbus_if.h"
-
-static int ppc_cbus_probe(device_t dev);
-
-static void ppcintr(void *arg);
-
-#define LOG_PPC(function, ppc, string) \
- if (bootverbose) printf("%s: %s\n", function, string)
-
-
-#define DEVTOSOFTC(dev) ((struct ppc_data *)device_get_softc(dev))
-
-devclass_t ppc_devclass;
-
-static device_method_t ppc_methods[] = {
- /* device interface */
- DEVMETHOD(device_probe, ppc_cbus_probe),
- DEVMETHOD(device_attach, ppc_attach),
-
- /* bus interface */
- DEVMETHOD(bus_read_ivar, ppc_read_ivar),
- DEVMETHOD(bus_setup_intr, ppc_setup_intr),
- DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
-
- /* ppbus interface */
- DEVMETHOD(ppbus_io, ppc_io),
- DEVMETHOD(ppbus_exec_microseq, ppc_exec_microseq),
- DEVMETHOD(ppbus_reset_epp, ppc_reset_epp),
- DEVMETHOD(ppbus_setmode, ppc_setmode),
- DEVMETHOD(ppbus_ecp_sync, ppc_ecp_sync),
- DEVMETHOD(ppbus_read, ppc_read),
- DEVMETHOD(ppbus_write, ppc_write),
-
- { 0, 0 }
- };
-
-static driver_t ppc_driver = {
- "ppc",
- ppc_methods,
- sizeof(struct ppc_data),
-};
-
-static char *ppc_models[] = {
- "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306",
- "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334",
- "SMC FDC37C935", "PC87303", 0
-};
-
-/* list of available modes */
-static char *ppc_avms[] = {
- "COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only",
- "EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only",
- "ECP/NIBBLE", "ECP/PS2", "ECP/PS2/NIBBLE", "ECP/EPP",
- "ECP/EPP/NIBBLE", "ECP/EPP/PS2", "ECP/EPP/PS2/NIBBLE", 0
-};
-
-/* list of current executing modes
- * Note that few modes do not actually exist.
- */
-static char *ppc_modes[] = {
- "COMPATIBLE", "NIBBLE", "PS/2", "PS/2", "EPP",
- "EPP", "EPP", "EPP", "ECP",
- "ECP", "ECP+PS2", "ECP+PS2", "ECP+EPP",
- "ECP+EPP", "ECP+EPP", "ECP+EPP", 0
-};
-
-static char *ppc_epp_protocol[] = { " (EPP 1.9)", " (EPP 1.7)", 0 };
-
-#ifdef __i386__
-/*
- * BIOS printer list - used by BIOS probe.
- */
-#define BIOS_PPC_PORTS 0x408
-#define BIOS_PORTS (short *)(KERNBASE+BIOS_PPC_PORTS)
-#define BIOS_MAX_PPC 4
-#endif
-
-/*
- * ppc_ecp_sync() XXX
- */
-void
-ppc_ecp_sync(device_t dev) {
-
- int i, r;
- struct ppc_data *ppc = DEVTOSOFTC(dev);
-
- if (!(ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_dtm & PPB_ECP))
- return;
-
- r = r_ecr(ppc);
- if ((r & 0xe0) != PPC_ECR_EPP)
- return;
-
- for (i = 0; i < 100; i++) {
- r = r_ecr(ppc);
- if (r & 0x1)
- return;
- DELAY(100);
- }
-
- printf("ppc%d: ECP sync failed as data still " \
- "present in FIFO.\n", ppc->ppc_unit);
-
- return;
-}
-
-/*
- * ppc_detect_fifo()
- *
- * Detect parallel port FIFO
- */
-static int
-ppc_detect_fifo(struct ppc_data *ppc)
-{
- char ecr_sav;
- char ctr_sav, ctr, cc;
- short i;
-
- /* save registers */
- ecr_sav = r_ecr(ppc);
- ctr_sav = r_ctr(ppc);
-
- /* enter ECP configuration mode, no interrupt, no DMA */
- w_ecr(ppc, 0xf4);
-
- /* read PWord size - transfers in FIFO mode must be PWord aligned */
- ppc->ppc_pword = (r_cnfgA(ppc) & PPC_PWORD_MASK);
-
- /* XXX 16 and 32 bits implementations not supported */
- if (ppc->ppc_pword != PPC_PWORD_8) {
- LOG_PPC(__func__, ppc, "PWord not supported");
- goto error;
- }
-
- w_ecr(ppc, 0x34); /* byte mode, no interrupt, no DMA */
- ctr = r_ctr(ppc);
- w_ctr(ppc, ctr | PCD); /* set direction to 1 */
-
- /* enter ECP test mode, no interrupt, no DMA */
- w_ecr(ppc, 0xd4);
-
- /* flush the FIFO */
- for (i=0; i<1024; i++) {
- if (r_ecr(ppc) & PPC_FIFO_EMPTY)
- break;
- cc = r_fifo(ppc);
- }
-
- if (i >= 1024) {
- LOG_PPC(__func__, ppc, "can't flush FIFO");
- goto error;
- }
-
- /* enable interrupts, no DMA */
- w_ecr(ppc, 0xd0);
-
- /* determine readIntrThreshold
- * fill the FIFO until serviceIntr is set
- */
- for (i=0; i<1024; i++) {
- w_fifo(ppc, (char)i);
- if (!ppc->ppc_rthr && (r_ecr(ppc) & PPC_SERVICE_INTR)) {
- /* readThreshold reached */
- ppc->ppc_rthr = i+1;
- }
- if (r_ecr(ppc) & PPC_FIFO_FULL) {
- ppc->ppc_fifo = i+1;
- break;
- }
- }
-
- if (i >= 1024) {
- LOG_PPC(__func__, ppc, "can't fill FIFO");
- goto error;
- }
-
- w_ecr(ppc, 0xd4); /* test mode, no interrupt, no DMA */
- w_ctr(ppc, ctr & ~PCD); /* set direction to 0 */
- w_ecr(ppc, 0xd0); /* enable interrupts */
-
- /* determine writeIntrThreshold
- * empty the FIFO until serviceIntr is set
- */
- for (i=ppc->ppc_fifo; i>0; i--) {
- if (r_fifo(ppc) != (char)(ppc->ppc_fifo-i)) {
- LOG_PPC(__func__, ppc, "invalid data in FIFO");
- goto error;
- }
- if (r_ecr(ppc) & PPC_SERVICE_INTR) {
- /* writeIntrThreshold reached */
- ppc->ppc_wthr = ppc->ppc_fifo - i+1;
- }
- /* if FIFO empty before the last byte, error */
- if (i>1 && (r_ecr(ppc) & PPC_FIFO_EMPTY)) {
- LOG_PPC(__func__, ppc, "data lost in FIFO");
- goto error;
- }
- }
-
- /* FIFO must be empty after the last byte */
- if (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
- LOG_PPC(__func__, ppc, "can't empty the FIFO");
- goto error;
- }
-
- w_ctr(ppc, ctr_sav);
- w_ecr(ppc, ecr_sav);
-
- return (0);
-
-error:
- w_ctr(ppc, ctr_sav);
- w_ecr(ppc, ecr_sav);
-
- return (EINVAL);
-}
-
-static int
-ppc_detect_port(struct ppc_data *ppc)
-{
-
- w_ctr(ppc, 0x0c); /* To avoid missing PS2 ports */
- w_dtr(ppc, 0xaa);
- if (r_dtr(ppc) != 0xaa)
- return (0);
-
- return (1);
-}
-
-/*
- * EPP timeout, according to the PC87332 manual
- * Semantics of clearing EPP timeout bit.
- * PC87332 - reading SPP_STR does it...
- * SMC - write 1 to EPP timeout bit XXX
- * Others - (?) write 0 to EPP timeout bit
- */
-static void
-ppc_reset_epp_timeout(struct ppc_data *ppc)
-{
- register char r;
-
- r = r_str(ppc);
- w_str(ppc, r | 0x1);
- w_str(ppc, r & 0xfe);
-
- return;
-}
-
-static int
-ppc_check_epp_timeout(struct ppc_data *ppc)
-{
- ppc_reset_epp_timeout(ppc);
-
- return (!(r_str(ppc) & TIMEOUT));
-}
-
-/*
- * Configure current operating mode
- */
-static int
-ppc_generic_setmode(struct ppc_data *ppc, int mode)
-{
- u_char ecr = 0;
-
- /* check if mode is available */
- if (mode && !(ppc->ppc_avm & mode))
- return (EINVAL);
-
- /* if ECP mode, configure ecr register */
- if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) {
- /* return to byte mode (keeping direction bit),
- * no interrupt, no DMA to be able to change to
- * ECP
- */
- w_ecr(ppc, PPC_ECR_RESET);
- ecr = PPC_DISABLE_INTR;
-
- if (mode & PPB_EPP)
- return (EINVAL);
- else if (mode & PPB_ECP)
- /* select ECP mode */
- ecr |= PPC_ECR_ECP;
- else if (mode & PPB_PS2)
- /* select PS2 mode with ECP */
- ecr |= PPC_ECR_PS2;
- else
- /* select COMPATIBLE/NIBBLE mode */
- ecr |= PPC_ECR_STD;
-
- w_ecr(ppc, ecr);
- }
-
- ppc->ppc_mode = mode;
-
- return (0);
-}
-
-/*
- * The ppc driver is free to choose options like FIFO or DMA
- * if ECP mode is available.
- *
- * The 'RAW' option allows the upper drivers to force the ppc mode
- * even with FIFO, DMA available.
- */
-static int
-ppc_smclike_setmode(struct ppc_data *ppc, int mode)
-{
- u_char ecr = 0;
-
- /* check if mode is available */
- if (mode && !(ppc->ppc_avm & mode))
- return (EINVAL);
-
- /* if ECP mode, configure ecr register */
- if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) {
- /* return to byte mode (keeping direction bit),
- * no interrupt, no DMA to be able to change to
- * ECP or EPP mode
- */
- w_ecr(ppc, PPC_ECR_RESET);
- ecr = PPC_DISABLE_INTR;
-
- if (mode & PPB_EPP)
- /* select EPP mode */
- ecr |= PPC_ECR_EPP;
- else if (mode & PPB_ECP)
- /* select ECP mode */
- ecr |= PPC_ECR_ECP;
- else if (mode & PPB_PS2)
- /* select PS2 mode with ECP */
- ecr |= PPC_ECR_PS2;
- else
- /* select COMPATIBLE/NIBBLE mode */
- ecr |= PPC_ECR_STD;
-
- w_ecr(ppc, ecr);
- }
-
- ppc->ppc_mode = mode;
-
- return (0);
-}
-
-#ifdef PPC_PROBE_CHIPSET
-/*
- * ppc_pc873xx_detect
- *
- * Probe for a Natsemi PC873xx-family part.
- *
- * References in this function are to the National Semiconductor
- * PC87332 datasheet TL/C/11930, May 1995 revision.
- */
-static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};
-static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0};
-static int pc873xx_irqtab[] = {5, 7, 5, 0};
-
-static int pc873xx_regstab[] = {
- PC873_FER, PC873_FAR, PC873_PTR,
- PC873_FCR, PC873_PCR, PC873_PMC,
- PC873_TUP, PC873_SID, PC873_PNP0,
- PC873_PNP1, PC873_LPTBA, -1
-};
-
-static char *pc873xx_rnametab[] = {
- "FER", "FAR", "PTR", "FCR", "PCR",
- "PMC", "TUP", "SID", "PNP0", "PNP1",
- "LPTBA", NULL
-};
-
-static int
-ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode) /* XXX mode never forced */
-{
- static int index = 0;
- int idport, irq;
- int ptr, pcr, val, i;
-
- while ((idport = pc873xx_basetab[index++])) {
-
- /* XXX should check first to see if this location is already claimed */
-
- /*
- * Pull the 873xx through the power-on ID cycle (2.2,1.).
- * We can't use this to locate the chip as it may already have
- * been used by the BIOS.
- */
- (void)inb(idport); (void)inb(idport);
- (void)inb(idport); (void)inb(idport);
-
- /*
- * Read the SID byte. Possible values are :
- *
- * 01010xxx PC87334
- * 0001xxxx PC87332
- * 01110xxx PC87306
- * 00110xxx PC87303
- */
- outb(idport, PC873_SID);
- val = inb(idport + 1);
- if ((val & 0xf0) == 0x10) {
- ppc->ppc_model = NS_PC87332;
- } else if ((val & 0xf8) == 0x70) {
- ppc->ppc_model = NS_PC87306;
- } else if ((val & 0xf8) == 0x50) {
- ppc->ppc_model = NS_PC87334;
- } else if ((val & 0xf8) == 0x40) { /* Should be 0x30 by the
- documentation, but probing
- yielded 0x40... */
- ppc->ppc_model = NS_PC87303;
- } else {
- if (bootverbose && (val != 0xff))
- printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val);
- continue ; /* not recognised */
- }
-
- /* print registers */
- if (bootverbose) {
- printf("PC873xx");
- for (i=0; pc873xx_regstab[i] != -1; i++) {
- outb(idport, pc873xx_regstab[i]);
- printf(" %s=0x%x", pc873xx_rnametab[i],
- inb(idport + 1) & 0xff);
- }
- printf("\n");
- }
-
- /*
- * We think we have one. Is it enabled and where we want it to be?
- */
- outb(idport, PC873_FER);
- val = inb(idport + 1);
- if (!(val & PC873_PPENABLE)) {
- if (bootverbose)
- printf("PC873xx parallel port disabled\n");
- continue;
- }
- outb(idport, PC873_FAR);
- val = inb(idport + 1);
- /* XXX we should create a driver instance for every port found */
- if (pc873xx_porttab[val & 0x3] != ppc->ppc_base) {
-
- /* First try to change the port address to that requested... */
-
- switch(ppc->ppc_base) {
- case 0x378:
- val &= 0xfc;
- break;
-
- case 0x3bc:
- val &= 0xfd;
- break;
-
- case 0x278:
- val &= 0xfe;
- break;
-
- default:
- val &= 0xfd;
- break;
- }
-
- outb(idport, PC873_FAR);
- outb(idport + 1, val);
- outb(idport + 1, val);
-
- /* Check for success by reading back the value we supposedly
- wrote and comparing...*/
-
- outb(idport, PC873_FAR);
- val = inb(idport + 1) & 0x3;
-
- /* If we fail, report the failure... */
-
- if (pc873xx_porttab[val] != ppc->ppc_base) {
- if (bootverbose)
- printf("PC873xx at 0x%x not for driver at port 0x%x\n",
- pc873xx_porttab[val], ppc->ppc_base);
- }
- continue;
- }
-
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
-
- /* get irq settings */
- if (ppc->ppc_base == 0x378)
- irq = (ptr & PC873_LPTBIRQ7) ? 7 : 5;
- else
- irq = pc873xx_irqtab[val];
-
- if (bootverbose)
- printf("PC873xx irq %d at 0x%x\n", irq, ppc->ppc_base);
-
- /*
- * Check if irq settings are correct
- */
- if (irq != ppc->ppc_irq) {
- /*
- * If the chipset is not locked and base address is 0x378,
- * we have another chance
- */
- if (ppc->ppc_base == 0x378 && !(ptr & PC873_CFGLOCK)) {
- if (ppc->ppc_irq == 7) {
- outb(idport + 1, (ptr | PC873_LPTBIRQ7));
- outb(idport + 1, (ptr | PC873_LPTBIRQ7));
- } else {
- outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
- outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
- }
- if (bootverbose)
- printf("PC873xx irq set to %d\n", ppc->ppc_irq);
- } else {
- if (bootverbose)
- printf("PC873xx sorry, can't change irq setting\n");
- }
- } else {
- if (bootverbose)
- printf("PC873xx irq settings are correct\n");
- }
-
- outb(idport, PC873_PCR);
- pcr = inb(idport + 1);
-
- if ((ptr & PC873_CFGLOCK) || !chipset_mode) {
- if (bootverbose)
- printf("PC873xx %s", (ptr & PC873_CFGLOCK)?"locked":"unlocked");
-
- ppc->ppc_avm |= PPB_NIBBLE;
- if (bootverbose)
- printf(", NIBBLE");
-
- if (pcr & PC873_EPPEN) {
- ppc->ppc_avm |= PPB_EPP;
-
- if (bootverbose)
- printf(", EPP");
-
- if (pcr & PC873_EPP19)
- ppc->ppc_epp = EPP_1_9;
- else
- ppc->ppc_epp = EPP_1_7;
-
- if ((ppc->ppc_model == NS_PC87332) && bootverbose) {
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
- if (ptr & PC873_EPPRDIR)
- printf(", Regular mode");
- else
- printf(", Automatic mode");
- }
- } else if (pcr & PC873_ECPEN) {
- ppc->ppc_avm |= PPB_ECP;
- if (bootverbose)
- printf(", ECP");
-
- if (pcr & PC873_ECPCLK) { /* XXX */
- ppc->ppc_avm |= PPB_PS2;
- if (bootverbose)
- printf(", PS/2");
- }
- } else {
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
- if (ptr & PC873_EXTENDED) {
- ppc->ppc_avm |= PPB_SPP;
- if (bootverbose)
- printf(", SPP");
- }
- }
- } else {
- if (bootverbose)
- printf("PC873xx unlocked");
-
- if (chipset_mode & PPB_ECP) {
- if ((chipset_mode & PPB_EPP) && bootverbose)
- printf(", ECP+EPP not supported");
-
- pcr &= ~PC873_EPPEN;
- pcr |= (PC873_ECPEN | PC873_ECPCLK); /* XXX */
- outb(idport + 1, pcr);
- outb(idport + 1, pcr);
-
- if (bootverbose)
- printf(", ECP");
-
- } else if (chipset_mode & PPB_EPP) {
- pcr &= ~(PC873_ECPEN | PC873_ECPCLK);
- pcr |= (PC873_EPPEN | PC873_EPP19);
- outb(idport + 1, pcr);
- outb(idport + 1, pcr);
-
- ppc->ppc_epp = EPP_1_9; /* XXX */
-
- if (bootverbose)
- printf(", EPP1.9");
-
- /* enable automatic direction turnover */
- if (ppc->ppc_model == NS_PC87332) {
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
- ptr &= ~PC873_EPPRDIR;
- outb(idport + 1, ptr);
- outb(idport + 1, ptr);
-
- if (bootverbose)
- printf(", Automatic mode");
- }
- } else {
- pcr &= ~(PC873_ECPEN | PC873_ECPCLK | PC873_EPPEN);
- outb(idport + 1, pcr);
- outb(idport + 1, pcr);
-
- /* configure extended bit in PTR */
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
-
- if (chipset_mode & PPB_PS2) {
- ptr |= PC873_EXTENDED;
-
- if (bootverbose)
- printf(", PS/2");
-
- } else {
- /* default to NIBBLE mode */
- ptr &= ~PC873_EXTENDED;
-
- if (bootverbose)
- printf(", NIBBLE");
- }
- outb(idport + 1, ptr);
- outb(idport + 1, ptr);
- }
-
- ppc->ppc_avm = chipset_mode;
- }
-
- if (bootverbose)
- printf("\n");
-
- ppc->ppc_type = PPC_TYPE_GENERIC;
- ppc_generic_setmode(ppc, chipset_mode);
-
- return(chipset_mode);
- }
- return(-1);
-}
-
-/*
- * ppc_smc37c66xgt_detect
- *
- * SMC FDC37C66xGT configuration.
- */
-static int
-ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode)
-{
- int s, i;
- u_char r;
- int type = -1;
- int csr = SMC66x_CSR; /* initial value is 0x3F0 */
-
- int port_address[] = { -1 /* disabled */ , 0x3bc, 0x378, 0x278 };
-
-
-#define cio csr+1 /* config IO port is either 0x3F1 or 0x371 */
-
- /*
- * Detection: enter configuration mode and read CRD register.
- */
-
- s = splhigh();
- outb(csr, SMC665_iCODE);
- outb(csr, SMC665_iCODE);
- splx(s);
-
- outb(csr, 0xd);
- if (inb(cio) == 0x65) {
- type = SMC_37C665GT;
- goto config;
- }
-
- for (i = 0; i < 2; i++) {
- s = splhigh();
- outb(csr, SMC666_iCODE);
- outb(csr, SMC666_iCODE);
- splx(s);
-
- outb(csr, 0xd);
- if (inb(cio) == 0x66) {
- type = SMC_37C666GT;
- break;
- }
-
- /* Another chance, CSR may be hard-configured to be at 0x370 */
- csr = SMC666_CSR;
- }
-
-config:
- /*
- * If chipset not found, do not continue.
- */
- if (type == -1)
- return (-1);
-
- /* select CR1 */
- outb(csr, 0x1);
-
- /* read the port's address: bits 0 and 1 of CR1 */
- r = inb(cio) & SMC_CR1_ADDR;
- if (port_address[(int)r] != ppc->ppc_base)
- return (-1);
-
- ppc->ppc_model = type;
-
- /*
- * CR1 and CR4 registers bits 3 and 0/1 for mode configuration
- * If SPP mode is detected, try to set ECP+EPP mode
- */
-
- if (bootverbose) {
- outb(csr, 0x1);
- printf("ppc%d: SMC registers CR1=0x%x", ppc->ppc_unit,
- inb(cio) & 0xff);
-
- outb(csr, 0x4);
- printf(" CR4=0x%x", inb(cio) & 0xff);
- }
-
- /* select CR1 */
- outb(csr, 0x1);
-
- if (!chipset_mode) {
- /* autodetect mode */
-
- /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
- if (type == SMC_37C666GT) {
- ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
- if (bootverbose)
- printf(" configuration hardwired, supposing " \
- "ECP+EPP SPP");
-
- } else
- if ((inb(cio) & SMC_CR1_MODE) == 0) {
- /* already in extended parallel port mode, read CR4 */
- outb(csr, 0x4);
- r = (inb(cio) & SMC_CR4_EMODE);
-
- switch (r) {
- case SMC_SPP:
- ppc->ppc_avm |= PPB_SPP;
- if (bootverbose)
- printf(" SPP");
- break;
-
- case SMC_EPPSPP:
- ppc->ppc_avm |= PPB_EPP | PPB_SPP;
- if (bootverbose)
- printf(" EPP SPP");
- break;
-
- case SMC_ECP:
- ppc->ppc_avm |= PPB_ECP | PPB_SPP;
- if (bootverbose)
- printf(" ECP SPP");
- break;
-
- case SMC_ECPEPP:
- ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
- if (bootverbose)
- printf(" ECP+EPP SPP");
- break;
- }
- } else {
- /* not an extended port mode */
- ppc->ppc_avm |= PPB_SPP;
- if (bootverbose)
- printf(" SPP");
- }
-
- } else {
- /* mode forced */
- ppc->ppc_avm = chipset_mode;
-
- /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
- if (type == SMC_37C666GT)
- goto end_detect;
-
- r = inb(cio);
- if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) {
- /* do not use ECP when the mode is not forced to */
- outb(cio, r | SMC_CR1_MODE);
- if (bootverbose)
- printf(" SPP");
- } else {
- /* an extended mode is selected */
- outb(cio, r & ~SMC_CR1_MODE);
-
- /* read CR4 register and reset mode field */
- outb(csr, 0x4);
- r = inb(cio) & ~SMC_CR4_EMODE;
-
- if (chipset_mode & PPB_ECP) {
- if (chipset_mode & PPB_EPP) {
- outb(cio, r | SMC_ECPEPP);
- if (bootverbose)
- printf(" ECP+EPP");
- } else {
- outb(cio, r | SMC_ECP);
- if (bootverbose)
- printf(" ECP");
- }
- } else {
- /* PPB_EPP is set */
- outb(cio, r | SMC_EPPSPP);
- if (bootverbose)
- printf(" EPP SPP");
- }
- }
- ppc->ppc_avm = chipset_mode;
- }
-
- /* set FIFO threshold to 16 */
- if (ppc->ppc_avm & PPB_ECP) {
- /* select CRA */
- outb(csr, 0xa);
- outb(cio, 16);
- }
-
-end_detect:
-
- if (bootverbose)
- printf ("\n");
-
- if (ppc->ppc_avm & PPB_EPP) {
- /* select CR4 */
- outb(csr, 0x4);
- r = inb(cio);
-
- /*
- * Set the EPP protocol...
- * Low=EPP 1.9 (1284 standard) and High=EPP 1.7
- */
- if (ppc->ppc_epp == EPP_1_9)
- outb(cio, (r & ~SMC_CR4_EPPTYPE));
- else
- outb(cio, (r | SMC_CR4_EPPTYPE));
- }
-
- /* end config mode */
- outb(csr, 0xaa);
-
- ppc->ppc_type = PPC_TYPE_SMCLIKE;
- ppc_smclike_setmode(ppc, chipset_mode);
-
- return (chipset_mode);
-}
-
-/*
- * SMC FDC37C935 configuration
- * Found on many Alpha machines
- */
-static int
-ppc_smc37c935_detect(struct ppc_data *ppc, int chipset_mode)
-{
- int s;
- int type = -1;
-
- s = splhigh();
- outb(SMC935_CFG, 0x55); /* enter config mode */
- outb(SMC935_CFG, 0x55);
- splx(s);
-
- outb(SMC935_IND, SMC935_ID); /* check device id */
- if (inb(SMC935_DAT) == 0x2)
- type = SMC_37C935;
-
- if (type == -1) {
- outb(SMC935_CFG, 0xaa); /* exit config mode */
- return (-1);
- }
-
- ppc->ppc_model = type;
-
- outb(SMC935_IND, SMC935_LOGDEV); /* select parallel port, */
- outb(SMC935_DAT, 3); /* which is logical device 3 */
-
- /* set io port base */
- outb(SMC935_IND, SMC935_PORTHI);
- outb(SMC935_DAT, (u_char)((ppc->ppc_base & 0xff00) >> 8));
- outb(SMC935_IND, SMC935_PORTLO);
- outb(SMC935_DAT, (u_char)(ppc->ppc_base & 0xff));
-
- if (!chipset_mode)
- ppc->ppc_avm = PPB_COMPATIBLE; /* default mode */
- else {
- ppc->ppc_avm = chipset_mode;
- outb(SMC935_IND, SMC935_PPMODE);
- outb(SMC935_DAT, SMC935_CENT); /* start in compatible mode */
-
- /* SPP + EPP or just plain SPP */
- if (chipset_mode & (PPB_SPP)) {
- if (chipset_mode & PPB_EPP) {
- if (ppc->ppc_epp == EPP_1_9) {
- outb(SMC935_IND, SMC935_PPMODE);
- outb(SMC935_DAT, SMC935_EPP19SPP);
- }
- if (ppc->ppc_epp == EPP_1_7) {
- outb(SMC935_IND, SMC935_PPMODE);
- outb(SMC935_DAT, SMC935_EPP17SPP);
- }
- } else {
- outb(SMC935_IND, SMC935_PPMODE);
- outb(SMC935_DAT, SMC935_SPP);
- }
- }
-
- /* ECP + EPP or just plain ECP */
- if (chipset_mode & PPB_ECP) {
- if (chipset_mode & PPB_EPP) {
- if (ppc->ppc_epp == EPP_1_9) {
- outb(SMC935_IND, SMC935_PPMODE);
- outb(SMC935_DAT, SMC935_ECPEPP19);
- }
- if (ppc->ppc_epp == EPP_1_7) {
- outb(SMC935_IND, SMC935_PPMODE);
- outb(SMC935_DAT, SMC935_ECPEPP17);
- }
- } else {
- outb(SMC935_IND, SMC935_PPMODE);
- outb(SMC935_DAT, SMC935_ECP);
- }
- }
- }
-
- outb(SMC935_CFG, 0xaa); /* exit config mode */
-
- ppc->ppc_type = PPC_TYPE_SMCLIKE;
- ppc_smclike_setmode(ppc, chipset_mode);
-
- return (chipset_mode);
-}
-
-/*
- * Winbond W83877F stuff
- *
- * EFER: extended function enable register
- * EFIR: extended function index register
- * EFDR: extended function data register
- */
-#define efir ((efer == 0x250) ? 0x251 : 0x3f0)
-#define efdr ((efer == 0x250) ? 0x252 : 0x3f1)
-
-static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 };
-static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 };
-static int w83877f_keyiter[] = { 1, 2, 2, 1 };
-static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 };
-
-static int
-ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode)
-{
- int i, j, efer;
- unsigned char r, hefere, hefras;
-
- for (i = 0; i < 4; i ++) {
- /* first try to enable configuration registers */
- efer = w83877f_efers[i];
-
- /* write the key to the EFER */
- for (j = 0; j < w83877f_keyiter[i]; j ++)
- outb (efer, w83877f_keys[i]);
-
- /* then check HEFERE and HEFRAS bits */
- outb (efir, 0x0c);
- hefere = inb(efdr) & WINB_HEFERE;
-
- outb (efir, 0x16);
- hefras = inb(efdr) & WINB_HEFRAS;
-
- /*
- * HEFRAS HEFERE
- * 0 1 write 89h to 250h (power-on default)
- * 1 0 write 86h twice to 3f0h
- * 1 1 write 87h twice to 3f0h
- * 0 0 write 88h to 250h
- */
- if ((hefere | hefras) == w83877f_hefs[i])
- goto found;
- }
-
- return (-1); /* failed */
-
-found:
- /* check base port address - read from CR23 */
- outb(efir, 0x23);
- if (ppc->ppc_base != inb(efdr) * 4) /* 4 bytes boundaries */
- return (-1);
-
- /* read CHIP ID from CR9/bits0-3 */
- outb(efir, 0x9);
-
- switch (inb(efdr) & WINB_CHIPID) {
- case WINB_W83877F_ID:
- ppc->ppc_model = WINB_W83877F;
- break;
-
- case WINB_W83877AF_ID:
- ppc->ppc_model = WINB_W83877AF;
- break;
-
- default:
- ppc->ppc_model = WINB_UNKNOWN;
- }
-
- if (bootverbose) {
- /* dump of registers */
- printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]);
- for (i = 0; i <= 0xd; i ++) {
- outb(efir, i);
- printf("0x%x ", inb(efdr));
- }
- for (i = 0x10; i <= 0x17; i ++) {
- outb(efir, i);
- printf("0x%x ", inb(efdr));
- }
- outb(efir, 0x1e);
- printf("0x%x ", inb(efdr));
- for (i = 0x20; i <= 0x29; i ++) {
- outb(efir, i);
- printf("0x%x ", inb(efdr));
- }
- printf("\n");
- printf("ppc%d:", ppc->ppc_unit);
- }
-
- ppc->ppc_type = PPC_TYPE_GENERIC;
-
- if (!chipset_mode) {
- /* autodetect mode */
-
- /* select CR0 */
- outb(efir, 0x0);
- r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1);
-
- /* select CR9 */
- outb(efir, 0x9);
- r |= (inb(efdr) & WINB_PRTMODS2);
-
- switch (r) {
- case WINB_W83757:
- if (bootverbose)
- printf("ppc%d: W83757 compatible mode\n",
- ppc->ppc_unit);
- return (-1); /* generic or SMC-like */
-
- case WINB_EXTFDC:
- case WINB_EXTADP:
- case WINB_EXT2FDD:
- case WINB_JOYSTICK:
- if (bootverbose)
- printf(" not in parallel port mode\n");
- return (-1);
-
- case (WINB_PARALLEL | WINB_EPP_SPP):
- ppc->ppc_avm |= PPB_EPP | PPB_SPP;
- if (bootverbose)
- printf(" EPP SPP");
- break;
-
- case (WINB_PARALLEL | WINB_ECP):
- ppc->ppc_avm |= PPB_ECP | PPB_SPP;
- if (bootverbose)
- printf(" ECP SPP");
- break;
-
- case (WINB_PARALLEL | WINB_ECP_EPP):
- ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
- ppc->ppc_type = PPC_TYPE_SMCLIKE;
-
- if (bootverbose)
- printf(" ECP+EPP SPP");
- break;
- default:
- printf("%s: unknown case (0x%x)!\n", __func__, r);
- }
-
- } else {
- /* mode forced */
-
- /* select CR9 and set PRTMODS2 bit */
- outb(efir, 0x9);
- outb(efdr, inb(efdr) & ~WINB_PRTMODS2);
-
- /* select CR0 and reset PRTMODSx bits */
- outb(efir, 0x0);
- outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1));
-
- if (chipset_mode & PPB_ECP) {
- if (chipset_mode & PPB_EPP) {
- outb(efdr, inb(efdr) | WINB_ECP_EPP);
- if (bootverbose)
- printf(" ECP+EPP");
-
- ppc->ppc_type = PPC_TYPE_SMCLIKE;
-
- } else {
- outb(efdr, inb(efdr) | WINB_ECP);
- if (bootverbose)
- printf(" ECP");
- }
- } else {
- /* select EPP_SPP otherwise */
- outb(efdr, inb(efdr) | WINB_EPP_SPP);
- if (bootverbose)
- printf(" EPP SPP");
- }
- ppc->ppc_avm = chipset_mode;
- }
-
- if (bootverbose)
- printf("\n");
-
- /* exit configuration mode */
- outb(efer, 0xaa);
-
- switch (ppc->ppc_type) {
- case PPC_TYPE_SMCLIKE:
- ppc_smclike_setmode(ppc, chipset_mode);
- break;
- default:
- ppc_generic_setmode(ppc, chipset_mode);
- break;
- }
-
- return (chipset_mode);
-}
-#endif
-
-/*
- * ppc_generic_detect
- */
-static int
-ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
-{
- /* default to generic */
- ppc->ppc_type = PPC_TYPE_GENERIC;
-
- if (bootverbose)
- printf("ppc%d:", ppc->ppc_unit);
-
- /* first, check for ECP */
- w_ecr(ppc, PPC_ECR_PS2);
- if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) {
- ppc->ppc_dtm |= PPB_ECP | PPB_SPP;
- if (bootverbose)
- printf(" ECP SPP");
-
- /* search for SMC style ECP+EPP mode */
- w_ecr(ppc, PPC_ECR_EPP);
- }
-
- /* try to reset EPP timeout bit */
- if (ppc_check_epp_timeout(ppc)) {
- ppc->ppc_dtm |= PPB_EPP;
-
- if (ppc->ppc_dtm & PPB_ECP) {
- /* SMC like chipset found */
- ppc->ppc_model = SMC_LIKE;
- ppc->ppc_type = PPC_TYPE_SMCLIKE;
-
- if (bootverbose)
- printf(" ECP+EPP");
- } else {
- if (bootverbose)
- printf(" EPP");
- }
- } else {
- /* restore to standard mode */
- w_ecr(ppc, PPC_ECR_STD);
- }
-
- /* XXX try to detect NIBBLE and PS2 modes */
- ppc->ppc_dtm |= PPB_NIBBLE;
-
- if (bootverbose)
- printf(" SPP");
-
- if (chipset_mode)
- ppc->ppc_avm = chipset_mode;
- else
- ppc->ppc_avm = ppc->ppc_dtm;
-
- if (bootverbose)
- printf("\n");
-
- switch (ppc->ppc_type) {
- case PPC_TYPE_SMCLIKE:
- ppc_smclike_setmode(ppc, chipset_mode);
- break;
- default:
- ppc_generic_setmode(ppc, chipset_mode);
- break;
- }
-
- return (chipset_mode);
-}
-
-/*
- * ppc_detect()
- *
- * mode is the mode suggested at boot
- */
-static int
-ppc_detect(struct ppc_data *ppc, int chipset_mode) {
-
-#ifdef PPC_PROBE_CHIPSET
- int i, mode;
-
- /* list of supported chipsets */
- int (*chipset_detect[])(struct ppc_data *, int) = {
- ppc_pc873xx_detect,
- ppc_smc37c66xgt_detect,
- ppc_w83877f_detect,
- ppc_smc37c935_detect,
- ppc_generic_detect,
- NULL
- };
-#endif
-
- /* if can't find the port and mode not forced return error */
- if (!ppc_detect_port(ppc) && chipset_mode == 0)
- return (EIO); /* failed, port not present */
-
- /* assume centronics compatible mode is supported */
- ppc->ppc_avm = PPB_COMPATIBLE;
-
-#ifdef PPC_PROBE_CHIPSET
- /* we have to differenciate available chipset modes,
- * chipset running modes and IEEE-1284 operating modes
- *
- * after detection, the port must support running in compatible mode
- */
- if (ppc->ppc_flags & 0x40) {
- if (bootverbose)
- printf("ppc: chipset forced to generic\n");
-#endif
-
- ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode);
-
-#ifdef PPC_PROBE_CHIPSET
- } else {
- for (i=0; chipset_detect[i] != NULL; i++) {
- if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
- ppc->ppc_mode = mode;
- break;
- }
- }
- }
-#endif
-
- /* configure/detect ECP FIFO */
- if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80))
- ppc_detect_fifo(ppc);
-
- return (0);
-}
-
-/*
- * ppc_exec_microseq()
- *
- * Execute a microsequence.
- * Microsequence mechanism is supposed to handle fast I/O operations.
- */
-int
-ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
-{
- struct ppc_data *ppc = DEVTOSOFTC(dev);
- struct ppb_microseq *mi;
- char cc, *p;
- int i, iter, len;
- int error;
-
- register int reg;
- register char mask;
- register int accum = 0;
- register char *ptr = 0;
-
- struct ppb_microseq *stack = 0;
-
-/* microsequence registers are equivalent to PC-like port registers */
-
-#define r_reg(register,ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, register))
-#define w_reg(register, ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, register, byte))
-
-#define INCR_PC (mi ++) /* increment program counter */
-
- mi = *p_msq;
- for (;;) {
- switch (mi->opcode) {
- case MS_OP_RSET:
- cc = r_reg(mi->arg[0].i, ppc);
- cc &= (char)mi->arg[2].i; /* clear mask */
- cc |= (char)mi->arg[1].i; /* assert mask */
- w_reg(mi->arg[0].i, ppc, cc);
- INCR_PC;
- break;
-
- case MS_OP_RASSERT_P:
- reg = mi->arg[1].i;
- ptr = ppc->ppc_ptr;
-
- if ((len = mi->arg[0].i) == MS_ACCUM) {
- accum = ppc->ppc_accum;
- for (; accum; accum--)
- w_reg(reg, ppc, *ptr++);
- ppc->ppc_accum = accum;
- } else
- for (i=0; i<len; i++)
- w_reg(reg, ppc, *ptr++);
- ppc->ppc_ptr = ptr;
-
- INCR_PC;
- break;
-
- case MS_OP_RFETCH_P:
- reg = mi->arg[1].i;
- mask = (char)mi->arg[2].i;
- ptr = ppc->ppc_ptr;
-
- if ((len = mi->arg[0].i) == MS_ACCUM) {
- accum = ppc->ppc_accum;
- for (; accum; accum--)
- *ptr++ = r_reg(reg, ppc) & mask;
- ppc->ppc_accum = accum;
- } else
- for (i=0; i<len; i++)
- *ptr++ = r_reg(reg, ppc) & mask;
- ppc->ppc_ptr = ptr;
-
- INCR_PC;
- break;
-
- case MS_OP_RFETCH:
- *((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) &
- (char)mi->arg[1].i;
- INCR_PC;
- break;
-
- case MS_OP_RASSERT:
- case MS_OP_DELAY:
-
- /* let's suppose the next instr. is the same */
- prefetch:
- for (;mi->opcode == MS_OP_RASSERT; INCR_PC)
- w_reg(mi->arg[0].i, ppc, (char)mi->arg[1].i);
-
- if (mi->opcode == MS_OP_DELAY) {
- DELAY(mi->arg[0].i);
- INCR_PC;
- goto prefetch;
- }
- break;
-
- case MS_OP_ADELAY:
- if (mi->arg[0].i)
- tsleep(NULL, PPBPRI, "ppbdelay",
- mi->arg[0].i * (hz/1000));
- INCR_PC;
- break;
-
- case MS_OP_TRIG:
- reg = mi->arg[0].i;
- iter = mi->arg[1].i;
- p = (char *)mi->arg[2].p;
-
- /* XXX delay limited to 255 us */
- for (i=0; i<iter; i++) {
- w_reg(reg, ppc, *p++);
- DELAY((unsigned char)*p++);
- }
- INCR_PC;
- break;
-
- case MS_OP_SET:
- ppc->ppc_accum = mi->arg[0].i;
- INCR_PC;
- break;
-
- case MS_OP_DBRA:
- if (--ppc->ppc_accum > 0)
- mi += mi->arg[0].i;
- INCR_PC;
- break;
-
- case MS_OP_BRSET:
- cc = r_str(ppc);
- if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i)
- mi += mi->arg[1].i;
- INCR_PC;
- break;
-
- case MS_OP_BRCLEAR:
- cc = r_str(ppc);
- if ((cc & (char)mi->arg[0].i) == 0)
- mi += mi->arg[1].i;
- INCR_PC;
- break;
-
- case MS_OP_BRSTAT:
- cc = r_str(ppc);
- if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
- (char)mi->arg[0].i)
- mi += mi->arg[2].i;
- INCR_PC;
- break;
-
- case MS_OP_C_CALL:
- /*
- * If the C call returns !0 then end the microseq.
- * The current state of ptr is passed to the C function
- */
- if ((error = mi->arg[0].f(mi->arg[1].p, ppc->ppc_ptr)))
- return (error);
-
- INCR_PC;
- break;
-
- case MS_OP_PTR:
- ppc->ppc_ptr = (char *)mi->arg[0].p;
- INCR_PC;
- break;
-
- case MS_OP_CALL:
- if (stack)
- panic("%s: too much calls", __func__);
-
- if (mi->arg[0].p) {
- /* store the state of the actual
- * microsequence
- */
- stack = mi;
-
- /* jump to the new microsequence */
- mi = (struct ppb_microseq *)mi->arg[0].p;
- } else
- INCR_PC;
-
- break;
-
- case MS_OP_SUBRET:
- /* retrieve microseq and pc state before the call */
- mi = stack;
-
- /* reset the stack */
- stack = 0;
-
- /* XXX return code */
-
- INCR_PC;
- break;
-
- case MS_OP_PUT:
- case MS_OP_GET:
- case MS_OP_RET:
- /* can't return to ppb level during the execution
- * of a submicrosequence */
- if (stack)
- panic("%s: can't return to ppb level",
- __func__);
-
- /* update pc for ppb level of execution */
- *p_msq = mi;
-
- /* return to ppb level of execution */
- return (0);
-
- default:
- panic("%s: unknown microsequence opcode 0x%x",
- __func__, mi->opcode);
- }
- }
-
- /* unreached */
-}
-
-static void
-ppcintr(void *arg)
-{
- device_t dev = (device_t)arg;
- struct ppc_data *ppc = (struct ppc_data *)device_get_softc(dev);
- u_char ctr, ecr, str;
-
- str = r_str(ppc);
- ctr = r_ctr(ppc);
- ecr = r_ecr(ppc);
-
-#if PPC_DEBUG > 1
- printf("![%x/%x/%x]", ctr, ecr, str);
-#endif
-
- /* don't use ecp mode with IRQENABLE set */
- if (ctr & IRQENABLE) {
- return;
- }
-
- /* interrupts are generated by nFault signal
- * only in ECP mode */
- if ((str & nFAULT) && (ppc->ppc_mode & PPB_ECP)) {
- /* check if ppc driver has programmed the
- * nFault interrupt */
- if (ppc->ppc_irqstat & PPC_IRQ_nFAULT) {
-
- w_ecr(ppc, ecr | PPC_nFAULT_INTR);
- ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
- } else {
- /* shall be handled by underlying layers XXX */
- return;
- }
- }
-
- if (ppc->ppc_irqstat & PPC_IRQ_DMA) {
- /* disable interrupts (should be done by hardware though) */
- w_ecr(ppc, ecr | PPC_SERVICE_INTR);
- ppc->ppc_irqstat &= ~PPC_IRQ_DMA;
- ecr = r_ecr(ppc);
-
- /* check if DMA completed */
- if ((ppc->ppc_avm & PPB_ECP) && (ecr & PPC_ENABLE_DMA)) {
-#ifdef PPC_DEBUG
- printf("a");
-#endif
- /* stop DMA */
- w_ecr(ppc, ecr & ~PPC_ENABLE_DMA);
- ecr = r_ecr(ppc);
-
- if (ppc->ppc_dmastat == PPC_DMA_STARTED) {
-#ifdef PPC_DEBUG
- printf("d");
-#endif
- isa_dmadone(
- ppc->ppc_dmaflags,
- ppc->ppc_dmaddr,
- ppc->ppc_dmacnt,
- ppc->ppc_dmachan);
-
- ppc->ppc_dmastat = PPC_DMA_COMPLETE;
-
- /* wakeup the waiting process */
- wakeup(ppc);
- }
- }
- } else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) {
-
- /* classic interrupt I/O */
- ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
- }
-
- return;
-}
-
-int
-ppc_read(device_t dev, char *buf, int len, int mode)
-{
- return (EINVAL);
-}
-
-/*
- * Call this function if you want to send data in any advanced mode
- * of your parallel port: FIFO, DMA
- *
- * If what you want is not possible (no ECP, no DMA...),
- * EINVAL is returned
- */
-int
-ppc_write(device_t dev, char *buf, int len, int how)
-{
- struct ppc_data *ppc = DEVTOSOFTC(dev);
- char ecr, ecr_sav, ctr, ctr_sav;
- int s, error = 0;
- int spin;
-
-#ifdef PPC_DEBUG
- printf("w");
-#endif
-
- ecr_sav = r_ecr(ppc);
- ctr_sav = r_ctr(ppc);
-
- /*
- * Send buffer with DMA, FIFO and interrupts
- */
- if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_registered)) {
-
- if (ppc->ppc_dmachan > 0) {
-
- /* byte mode, no intr, no DMA, dir=0, flush fifo
- */
- ecr = PPC_ECR_STD | PPC_DISABLE_INTR;
- w_ecr(ppc, ecr);
-
- /* disable nAck interrupts */
- ctr = r_ctr(ppc);
- ctr &= ~IRQENABLE;
- w_ctr(ppc, ctr);
-
- ppc->ppc_dmaflags = 0;
- ppc->ppc_dmaddr = (caddr_t)buf;
- ppc->ppc_dmacnt = (u_int)len;
-
- switch (ppc->ppc_mode) {
- case PPB_COMPATIBLE:
- /* compatible mode with FIFO, no intr, DMA, dir=0 */
- ecr = PPC_ECR_FIFO | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
- break;
- case PPB_ECP:
- ecr = PPC_ECR_ECP | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
- break;
- default:
- error = EINVAL;
- goto error;
- }
-
- w_ecr(ppc, ecr);
- ecr = r_ecr(ppc);
-
- /* enter splhigh() not to be preempted
- * by the dma interrupt, we may miss
- * the wakeup otherwise
- */
- s = splhigh();
-
- ppc->ppc_dmastat = PPC_DMA_INIT;
-
- /* enable interrupts */
- ecr &= ~PPC_SERVICE_INTR;
- ppc->ppc_irqstat = PPC_IRQ_DMA;
- w_ecr(ppc, ecr);
-
- isa_dmastart(
- ppc->ppc_dmaflags,
- ppc->ppc_dmaddr,
- ppc->ppc_dmacnt,
- ppc->ppc_dmachan);
-#ifdef PPC_DEBUG
- printf("s%d", ppc->ppc_dmacnt);
-#endif
- ppc->ppc_dmastat = PPC_DMA_STARTED;
-
- /* Wait for the DMA completed interrupt. We hope we won't
- * miss it, otherwise a signal will be necessary to unlock the
- * process.
- */
- do {
- /* release CPU */
- error = tsleep(ppc,
- PPBPRI | PCATCH, "ppcdma", 0);
-
- } while (error == EWOULDBLOCK);
-
- splx(s);
-
- if (error) {
-#ifdef PPC_DEBUG
- printf("i");
-#endif
- /* stop DMA */
- isa_dmadone(
- ppc->ppc_dmaflags, ppc->ppc_dmaddr,
- ppc->ppc_dmacnt, ppc->ppc_dmachan);
-
- /* no dma, no interrupt, flush the fifo */
- w_ecr(ppc, PPC_ECR_RESET);
-
- ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
- goto error;
- }
-
- /* wait for an empty fifo */
- while (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
-
- for (spin=100; spin; spin--)
- if (r_ecr(ppc) & PPC_FIFO_EMPTY)
- goto fifo_empty;
-#ifdef PPC_DEBUG
- printf("Z");
-#endif
- error = tsleep(ppc, PPBPRI | PCATCH, "ppcfifo", hz/100);
- if (error != EWOULDBLOCK) {
-#ifdef PPC_DEBUG
- printf("I");
-#endif
- /* no dma, no interrupt, flush the fifo */
- w_ecr(ppc, PPC_ECR_RESET);
-
- ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
- error = EINTR;
- goto error;
- }
- }
-
-fifo_empty:
- /* no dma, no interrupt, flush the fifo */
- w_ecr(ppc, PPC_ECR_RESET);
-
- } else
- error = EINVAL; /* XXX we should FIFO and
- * interrupts */
- } else
- error = EINVAL;
-
-error:
-
- /* PDRQ must be kept unasserted until nPDACK is
- * deasserted for a minimum of 350ns (SMC datasheet)
- *
- * Consequence may be a FIFO that never empty
- */
- DELAY(1);
-
- w_ecr(ppc, ecr_sav);
- w_ctr(ppc, ctr_sav);
-
- return (error);
-}
-
-void
-ppc_reset_epp(device_t dev)
-{
- struct ppc_data *ppc = DEVTOSOFTC(dev);
-
- ppc_reset_epp_timeout(ppc);
-
- return;
-}
-
-int
-ppc_setmode(device_t dev, int mode)
-{
- struct ppc_data *ppc = DEVTOSOFTC(dev);
-
- switch (ppc->ppc_type) {
- case PPC_TYPE_SMCLIKE:
- return (ppc_smclike_setmode(ppc, mode));
- break;
-
- case PPC_TYPE_GENERIC:
- default:
- return (ppc_generic_setmode(ppc, mode));
- break;
- }
-
- /* not reached */
- return (ENXIO);
-}
-
-static struct isa_pnp_id lpc_ids[] = {
- { 0x0004d041, "Standard parallel printer port" }, /* PNP0400 */
- { 0x0104d041, "ECP parallel printer port" }, /* PNP0401 */
- { 0 }
-};
-
-static int
-ppc_cbus_probe(device_t dev)
-{
- device_t parent;
- int error;
-
- parent = device_get_parent(dev);
-
- error = ISA_PNP_PROBE(parent, dev, lpc_ids);
- if (error == ENXIO)
- return (ENXIO);
- else if (error != 0) /* XXX shall be set after detection */
- device_set_desc(dev, "Parallel port");
-
- return(ppc_probe(dev));
-}
-
-int
-ppc_probe(device_t dev)
-{
-#ifdef __i386__
- static short next_bios_ppc = 0;
-#endif
- struct ppc_data *ppc;
- int error;
- u_long port;
-#ifdef PC98
-#define PC98_IEEE_1284_DISABLE 0x100
-#define PC98_IEEE_1284_PORT 0x140
-
- unsigned int pc98_ieee_mode = 0x00;
- unsigned int tmp;
-#endif
-
- /*
- * Allocate the ppc_data structure.
- */
- ppc = DEVTOSOFTC(dev);
- bzero(ppc, sizeof(struct ppc_data));
-
- ppc->rid_irq = ppc->rid_drq = ppc->rid_ioport = 0;
- ppc->res_irq = ppc->res_drq = ppc->res_ioport = 0;
-
- /* retrieve ISA parameters */
- error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &port, NULL);
-
-#ifdef __i386__
- /*
- * If port not specified, use bios list.
- */
- if (error) {
-#ifndef PC98
- if((next_bios_ppc < BIOS_MAX_PPC) &&
- (*(BIOS_PORTS+next_bios_ppc) != 0) ) {
- port = *(BIOS_PORTS+next_bios_ppc++);
- if (bootverbose)
- device_printf(dev, "parallel port found at 0x%x\n",
- (int) port);
- } else {
- device_printf(dev, "parallel port not found.\n");
- return ENXIO;
- }
-#else
- if (next_bios_ppc == 0) {
- /* Use default IEEE-1284 port of NEC PC-98x1 */
- port = PC98_IEEE_1284_PORT;
- next_bios_ppc += 1;
- if (bootverbose)
- device_printf(dev,
- "parallel port found at 0x%x\n",
- (int) port);
- }
-#endif
- bus_set_resource(dev, SYS_RES_IOPORT, 0, port,
- IO_LPTSIZE_EXTENDED);
- }
-#endif
-#ifdef __alpha__
- /*
- * There isn't a bios list on alpha. Put it in the usual place.
- */
- if (error) {
- bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3bc,
- IO_LPTSIZE_NORMAL);
- }
-#endif
-
- /* IO port is mandatory */
-
- /* Try "extended" IO port range...*/
- ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &ppc->rid_ioport, 0, ~0,
- IO_LPTSIZE_EXTENDED, RF_ACTIVE);
-
- if (ppc->res_ioport != 0) {
- if (bootverbose)
- device_printf(dev, "using extended I/O port range\n");
- } else {
- /* Failed? If so, then try the "normal" IO port range... */
- ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &ppc->rid_ioport, 0, ~0,
- IO_LPTSIZE_NORMAL,
- RF_ACTIVE);
- if (ppc->res_ioport != 0) {
- if (bootverbose)
- device_printf(dev, "using normal I/O port range\n");
- } else {
- device_printf(dev, "cannot reserve I/O port range\n");
- goto error;
- }
- }
-
- ppc->ppc_base = rman_get_start(ppc->res_ioport);
-
- ppc->bsh = rman_get_bushandle(ppc->res_ioport);
- ppc->bst = rman_get_bustag(ppc->res_ioport);
-
- ppc->ppc_flags = device_get_flags(dev);
-
- if (!(ppc->ppc_flags & 0x20)) {
- ppc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
- &ppc->rid_irq,
- RF_SHAREABLE);
- ppc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
- &ppc->rid_drq,
- RF_ACTIVE);
- }
-
- if (ppc->res_irq)
- ppc->ppc_irq = rman_get_start(ppc->res_irq);
- if (ppc->res_drq)
- ppc->ppc_dmachan = rman_get_start(ppc->res_drq);
-
- ppc->ppc_unit = device_get_unit(dev);
- ppc->ppc_model = GENERIC;
-
- ppc->ppc_mode = PPB_COMPATIBLE;
- ppc->ppc_epp = (ppc->ppc_flags & 0x10) >> 4;
-
- ppc->ppc_type = PPC_TYPE_GENERIC;
-
-#ifdef PC98
- /*
- * IEEE STD 1284 Function Check and Enable
- * for default IEEE-1284 port of NEC PC-98x1
- */
- if ((ppc->ppc_base == PC98_IEEE_1284_PORT) &&
- !(ppc->ppc_flags & PC98_IEEE_1284_DISABLE)) {
- tmp = inb(ppc->ppc_base + PPC_1284_ENABLE);
- pc98_ieee_mode = tmp;
- if ((tmp & 0x10) == 0x10) {
- outb(ppc->ppc_base + PPC_1284_ENABLE, tmp & ~0x10);
- tmp = inb(ppc->ppc_base + PPC_1284_ENABLE);
- if ((tmp & 0x10) == 0x10)
- goto error;
- } else {
- outb(ppc->ppc_base + PPC_1284_ENABLE, tmp | 0x10);
- tmp = inb(ppc->ppc_base + PPC_1284_ENABLE);
- if ((tmp & 0x10) != 0x10)
- goto error;
- }
- outb(ppc->ppc_base + PPC_1284_ENABLE, pc98_ieee_mode | 0x10);
- }
-#endif
-
- /*
- * Try to detect the chipset and its mode.
- */
- if (ppc_detect(ppc, ppc->ppc_flags & 0xf))
- goto error;
-
- return (0);
-
-error:
-#ifdef PC98
- if ((ppc->ppc_base == PC98_IEEE_1284_PORT) &&
- !(ppc->ppc_flags & PC98_IEEE_1284_DISABLE)) {
- outb(ppc->ppc_base + PPC_1284_ENABLE, pc98_ieee_mode);
- }
-#endif
- if (ppc->res_irq != 0) {
- bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq,
- ppc->res_irq);
- }
- if (ppc->res_ioport != 0) {
- bus_deactivate_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
- ppc->res_ioport);
- bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
- ppc->res_ioport);
- }
- if (ppc->res_drq != 0) {
- bus_deactivate_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
- ppc->res_drq);
- bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
- ppc->res_drq);
- }
- return (ENXIO);
-}
-
-int
-ppc_attach(device_t dev)
-{
- struct ppc_data *ppc = DEVTOSOFTC(dev);
-
- device_t ppbus;
- device_t parent = device_get_parent(dev);
-
- device_printf(dev, "%s chipset (%s) in %s mode%s\n",
- ppc_models[ppc->ppc_model], ppc_avms[ppc->ppc_avm],
- ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
- ppc_epp_protocol[ppc->ppc_epp] : "");
-
- if (ppc->ppc_fifo)
- device_printf(dev, "FIFO with %d/%d/%d bytes threshold\n",
- ppc->ppc_fifo, ppc->ppc_wthr, ppc->ppc_rthr);
-
- if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_dmachan > 0)) {
- /* acquire the DMA channel forever */ /* XXX */
- isa_dma_acquire(ppc->ppc_dmachan);
- isa_dmainit(ppc->ppc_dmachan, 1024); /* nlpt.BUFSIZE */
- }
-
- /* add ppbus as a child of this isa to parallel bridge */
- ppbus = device_add_child(dev, "ppbus", -1);
-
- /*
- * Probe the ppbus and attach devices found.
- */
- device_probe_and_attach(ppbus);
-
- /* register the ppc interrupt handler as default */
- if (ppc->res_irq) {
- /* default to the tty mask for registration */ /* XXX */
- if (BUS_SETUP_INTR(parent, dev, ppc->res_irq, INTR_TYPE_TTY,
- ppcintr, dev, &ppc->intr_cookie) == 0) {
-
- /* remember the ppcintr is registered */
- ppc->ppc_registered = 1;
- }
- }
-
- return (0);
-}
-
-u_char
-ppc_io(device_t ppcdev, int iop, u_char *addr, int cnt, u_char byte)
-{
- struct ppc_data *ppc = DEVTOSOFTC(ppcdev);
- switch (iop) {
- case PPB_OUTSB_EPP:
- bus_space_write_multi_1(ppc->bst, ppc->bsh, PPC_EPP_DATA, addr, cnt);
- break;
- case PPB_OUTSW_EPP:
- bus_space_write_multi_2(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
- break;
- case PPB_OUTSL_EPP:
- bus_space_write_multi_4(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
- break;
- case PPB_INSB_EPP:
- bus_space_read_multi_1(ppc->bst, ppc->bsh, PPC_EPP_DATA, addr, cnt);
- break;
- case PPB_INSW_EPP:
- bus_space_read_multi_2(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
- break;
- case PPB_INSL_EPP:
- bus_space_read_multi_4(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
- break;
- case PPB_RDTR:
- return (r_dtr(ppc));
- case PPB_RSTR:
- return (r_str(ppc));
- case PPB_RCTR:
- return (r_ctr(ppc));
- case PPB_REPP_A:
- return (r_epp_A(ppc));
- case PPB_REPP_D:
- return (r_epp_D(ppc));
- case PPB_RECR:
- return (r_ecr(ppc));
- case PPB_RFIFO:
- return (r_fifo(ppc));
- case PPB_WDTR:
- w_dtr(ppc, byte);
- break;
- case PPB_WSTR:
- w_str(ppc, byte);
- break;
- case PPB_WCTR:
- w_ctr(ppc, byte);
- break;
- case PPB_WEPP_A:
- w_epp_A(ppc, byte);
- break;
- case PPB_WEPP_D:
- w_epp_D(ppc, byte);
- break;
- case PPB_WECR:
- w_ecr(ppc, byte);
- break;
- case PPB_WFIFO:
- w_fifo(ppc, byte);
- break;
- default:
- panic("%s: unknown I/O operation", __func__);
- break;
- }
-
- return (0); /* not significative */
-}
-
-int
-ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
-{
- struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus);
-
- switch (index) {
- case PPC_IVAR_EPP_PROTO:
- *val = (u_long)ppc->ppc_epp;
- break;
- case PPC_IVAR_IRQ:
- *val = (u_long)ppc->ppc_irq;
- break;
- default:
- return (ENOENT);
- }
-
- return (0);
-}
-
-/*
- * Resource is useless here since ppbus devices' interrupt handlers are
- * multiplexed to the same resource initially allocated by ppc
- */
-int
-ppc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
- void (*ihand)(void *), void *arg, void **cookiep)
-{
- int error;
- struct ppc_data *ppc = DEVTOSOFTC(bus);
-
- if (ppc->ppc_registered) {
- /* XXX refuse registration if DMA is in progress */
-
- /* first, unregister the default interrupt handler */
- if ((error = BUS_TEARDOWN_INTR(device_get_parent(bus),
- bus, ppc->res_irq, ppc->intr_cookie)))
- return (error);
-
-/* bus_deactivate_resource(bus, SYS_RES_IRQ, ppc->rid_irq, */
-/* ppc->res_irq); */
-
- /* DMA/FIFO operation won't be possible anymore */
- ppc->ppc_registered = 0;
- }
-
- /* pass registration to the upper layer, ignore the incoming resource */
- return (BUS_SETUP_INTR(device_get_parent(bus), child,
- r, flags, ihand, arg, cookiep));
-}
-
-/*
- * When no underlying device has a registered interrupt, register the ppc
- * layer one
- */
-int
-ppc_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih)
-{
- int error;
- struct ppc_data *ppc = DEVTOSOFTC(bus);
- device_t parent = device_get_parent(bus);
-
- /* pass unregistration to the upper layer */
- if ((error = BUS_TEARDOWN_INTR(parent, child, r, ih)))
- return (error);
-
- /* default to the tty mask for registration */ /* XXX */
- if (ppc->ppc_irq &&
- !(error = BUS_SETUP_INTR(parent, bus, ppc->res_irq,
- INTR_TYPE_TTY, ppcintr, bus, &ppc->intr_cookie))) {
-
- /* remember the ppcintr is registered */
- ppc->ppc_registered = 1;
- }
-
- return (error);
-}
-
-DRIVER_MODULE(ppc, isa, ppc_driver, ppc_devclass, 0, 0);
-#ifndef PC98
-DRIVER_MODULE(ppc, acpi, ppc_driver, ppc_devclass, 0, 0);
-#endif
diff --git a/sys/pc98/pc98/ppcreg.h b/sys/pc98/pc98/ppcreg.h
deleted file mode 100644
index 2aa5ce4..0000000
--- a/sys/pc98/pc98/ppcreg.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/*-
- * Copyright (c) 2001 Alcove - Nicolas Souchu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- *
- */
-#ifndef __PPCREG_H
-#define __PPCREG_H
-
-/*
- * Parallel Port Chipset type.
- */
-#define SMC_LIKE 0
-#define SMC_37C665GT 1
-#define SMC_37C666GT 2
-#define NS_PC87332 3
-#define NS_PC87306 4
-#define INTEL_820191AA 5 /* XXX not implemented */
-#define GENERIC 6
-#define WINB_W83877F 7
-#define WINB_W83877AF 8
-#define WINB_UNKNOWN 9
-#define NS_PC87334 10
-#define SMC_37C935 11
-#define NS_PC87303 12
-
-/*
- * Parallel Port Chipset Type. SMC versus GENERIC (others)
- */
-#define PPC_TYPE_SMCLIKE 0
-#define PPC_TYPE_GENERIC 1
-
-/*
- * Generic structure to hold parallel port chipset info.
- */
-struct ppc_data {
-
- int ppc_unit;
- int ppc_model; /* chipset model if detected */
- int ppc_type; /* generic or smclike chipset type */
-
- int ppc_mode; /* chipset current mode */
- int ppc_avm; /* chipset available modes */
- int ppc_dtm; /* chipset detected modes */
-
-#define PPC_IRQ_NONE 0x0
-#define PPC_IRQ_nACK 0x1
-#define PPC_IRQ_DMA 0x2
-#define PPC_IRQ_FIFO 0x4
-#define PPC_IRQ_nFAULT 0x8
- int ppc_irqstat; /* remind irq settings */
-
-#define PPC_DMA_INIT 0x01
-#define PPC_DMA_STARTED 0x02
-#define PPC_DMA_COMPLETE 0x03
-#define PPC_DMA_INTERRUPTED 0x04
-#define PPC_DMA_ERROR 0x05
- int ppc_dmastat; /* dma state */
- int ppc_dmachan; /* dma channel */
- int ppc_dmaflags; /* dma transfer flags */
- caddr_t ppc_dmaddr; /* buffer address */
- u_int ppc_dmacnt; /* count of bytes sent with dma */
-
-#define PPC_PWORD_MASK 0x30
-#define PPC_PWORD_16 0x00
-#define PPC_PWORD_8 0x10
-#define PPC_PWORD_32 0x20
- char ppc_pword; /* PWord size */
- short ppc_fifo; /* FIFO threshold */
-
- short ppc_wthr; /* writeIntrThresold */
- short ppc_rthr; /* readIntrThresold */
-
- char *ppc_ptr; /* microseq current pointer */
- int ppc_accum; /* microseq accumulator */
- int ppc_base; /* parallel port base address */
- int ppc_epp; /* EPP mode (1.7 or 1.9) */
- int ppc_irq;
-
- unsigned char ppc_flags;
-
- device_t ppbus; /* parallel port chipset corresponding ppbus */
-
- int rid_irq, rid_drq, rid_ioport;
- struct resource *res_irq, *res_drq, *res_ioport;
-
- bus_space_handle_t bsh;
- bus_space_tag_t bst;
-
- void *intr_cookie;
-
- int ppc_registered; /* 1 if ppcintr() is the registered interrupt */
-};
-
-/*
- * Parallel Port Chipset registers.
- */
-#define PPC_SPP_DTR 0 /* SPP data register */
-#define PPC_ECP_A_FIFO 0 /* ECP Address fifo register */
-#define PPC_SPP_STR 1 /* SPP status register */
-#define PPC_SPP_CTR 2 /* SPP control register */
-#define PPC_EPP_ADDR 3 /* EPP address register (8 bit) */
-#define PPC_EPP_DATA 4 /* EPP data register (8, 16 or 32 bit) */
-#ifdef PC98
-#define PPC_1284_ENABLE 0x09 /* IEEE STD 1284 Enable register */
-#define PPC_ECP_D_FIFO 0x0c /* ECP Data fifo register */
-#define PPC_ECP_CNFGA 0x0c /* Configuration register A */
-#define PPC_ECP_CNFGB 0x0d /* Configuration register B */
-#define PPC_ECP_ECR 0x0e /* ECP extended control register */
-#else
-#define PPC_ECP_D_FIFO 0x400 /* ECP Data fifo register */
-#define PPC_ECP_CNFGA 0x400 /* Configuration register A */
-#define PPC_ECP_CNFGB 0x401 /* Configuration register B */
-#define PPC_ECP_ECR 0x402 /* ECP extended control register */
-#endif
-
-#define PPC_FIFO_EMPTY 0x1 /* ecr register - bit 0 */
-#define PPC_FIFO_FULL 0x2 /* ecr register - bit 1 */
-#define PPC_SERVICE_INTR 0x4 /* ecr register - bit 2 */
-#define PPC_ENABLE_DMA 0x8 /* ecr register - bit 3 */
-#define PPC_nFAULT_INTR 0x10 /* ecr register - bit 4 */
-#define PPC_ECR_STD 0x0
-#define PPC_ECR_PS2 0x20
-#define PPC_ECR_FIFO 0x40
-#define PPC_ECR_ECP 0x60
-#define PPC_ECR_EPP 0x80
-
-#define PPC_DISABLE_INTR (PPC_SERVICE_INTR | PPC_nFAULT_INTR)
-#define PPC_ECR_RESET (PPC_ECR_PS2 | PPC_DISABLE_INTR)
-
-#define r_dtr(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_SPP_DTR))
-#define r_str(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_SPP_STR))
-#define r_ctr(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_SPP_CTR))
-
-#define r_epp_A(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_EPP_ADDR))
-#define r_epp_D(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_EPP_DATA))
-#define r_cnfgA(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_ECP_CNFGA))
-#define r_cnfgB(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_ECP_CNFGB))
-#define r_ecr(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_ECP_ECR))
-#define r_fifo(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_ECP_D_FIFO))
-
-#define w_dtr(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_SPP_DTR, byte))
-#define w_str(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_SPP_STR, byte))
-#define w_ctr(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_SPP_CTR, byte))
-
-#define w_epp_A(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_EPP_ADDR, byte))
-#define w_epp_D(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_EPP_DATA, byte))
-#define w_ecr(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_ECP_ECR, byte))
-#define w_fifo(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_ECP_D_FIFO, byte))
-
-/*
- * Register defines for the PC873xx parts
- */
-
-#define PC873_FER 0x00
-#define PC873_PPENABLE (1<<0)
-#define PC873_FAR 0x01
-#define PC873_PTR 0x02
-#define PC873_CFGLOCK (1<<6)
-#define PC873_EPPRDIR (1<<7)
-#define PC873_EXTENDED (1<<7)
-#define PC873_LPTBIRQ7 (1<<3)
-#define PC873_FCR 0x03
-#define PC873_ZWS (1<<5)
-#define PC873_ZWSPWDN (1<<6)
-#define PC873_PCR 0x04
-#define PC873_EPPEN (1<<0)
-#define PC873_EPP19 (1<<1)
-#define PC873_ECPEN (1<<2)
-#define PC873_ECPCLK (1<<3)
-#define PC873_PMC 0x06
-#define PC873_TUP 0x07
-#define PC873_SID 0x08
-#define PC873_PNP0 0x1b
-#define PC873_PNP1 0x1c
-#define PC873_LPTBA 0x19
-
-/*
- * Register defines for the SMC FDC37C66xGT parts
- */
-
-/* Init codes */
-#define SMC665_iCODE 0x55
-#define SMC666_iCODE 0x44
-
-/* Base configuration ports */
-#define SMC66x_CSR 0x3F0
-#define SMC666_CSR 0x370 /* hard-configured value for 666 */
-
-/* Bits */
-#define SMC_CR1_ADDR 0x3 /* bit 0 and 1 */
-#define SMC_CR1_MODE (1<<3) /* bit 3 */
-#define SMC_CR4_EMODE 0x3 /* bits 0 and 1 */
-#define SMC_CR4_EPPTYPE (1<<6) /* bit 6 */
-
-/* Extended modes */
-#define SMC_SPP 0x0 /* SPP */
-#define SMC_EPPSPP 0x1 /* EPP and SPP */
-#define SMC_ECP 0x2 /* ECP */
-#define SMC_ECPEPP 0x3 /* ECP and EPP */
-
-/*
- * Register defines for the SMC FDC37C935 parts
- */
-
-/* Configuration ports */
-#define SMC935_CFG 0x370
-#define SMC935_IND 0x370
-#define SMC935_DAT 0x371
-
-/* Registers */
-#define SMC935_LOGDEV 0x7
-#define SMC935_ID 0x20
-#define SMC935_PORTHI 0x60
-#define SMC935_PORTLO 0x61
-#define SMC935_PPMODE 0xf0
-
-/* Parallel port modes */
-#define SMC935_SPP 0x38 + 0
-#define SMC935_EPP19SPP 0x38 + 1
-#define SMC935_ECP 0x38 + 2
-#define SMC935_ECPEPP19 0x38 + 3
-#define SMC935_CENT 0x38 + 4
-#define SMC935_EPP17SPP 0x38 + 5
-#define SMC935_UNUSED 0x38 + 6
-#define SMC935_ECPEPP17 0x38 + 7
-
-/*
- * Register defines for the Winbond W83877F parts
- */
-
-#define WINB_W83877F_ID 0xa
-#define WINB_W83877AF_ID 0xb
-
-/* Configuration bits */
-#define WINB_HEFERE (1<<5) /* CROC bit 5 */
-#define WINB_HEFRAS (1<<0) /* CR16 bit 0 */
-
-#define WINB_PNPCVS (1<<2) /* CR16 bit 2 */
-#define WINB_CHIPID 0xf /* CR9 bits 0-3 */
-
-#define WINB_PRTMODS0 (1<<2) /* CR0 bit 2 */
-#define WINB_PRTMODS1 (1<<3) /* CR0 bit 3 */
-#define WINB_PRTMODS2 (1<<7) /* CR9 bit 7 */
-
-/* W83877F modes: CR9/bit7 | CR0/bit3 | CR0/bit2 */
-#define WINB_W83757 0x0
-#define WINB_EXTFDC 0x4
-#define WINB_EXTADP 0x8
-#define WINB_EXT2FDD 0xc
-#define WINB_JOYSTICK 0x80
-
-#define WINB_PARALLEL 0x80
-#define WINB_EPP_SPP 0x4
-#define WINB_ECP 0x8
-#define WINB_ECP_EPP 0xc
-
-#endif
diff --git a/sys/pc98/pc98/sc_machdep.h b/sys/pc98/pc98/sc_machdep.h
deleted file mode 100644
index ea7b3ba..0000000
--- a/sys/pc98/pc98/sc_machdep.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1999 FreeBSD(98) Porting Team.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _PC98_PC98_SC_MACHDEP_H_
-#define _PC98_PC98_SC_MACHDEP_H_
-
-#undef SC_DFLT_FONT
-#undef SC_MOUSE_CHAR
-#undef SC_PIXEL_MODE
-#undef SC_NO_FONT_LOADING
-#define SC_NO_FONT_LOADING 1
-#undef SC_NO_PALETTE_LOADING
-#define SC_NO_PALETTE_LOADING 1
-
-#ifndef SC_KERNEL_CONS_ATTR
-#define SC_KERNEL_CONS_ATTR (FG_LIGHTGREY | BG_BLACK)
-#endif
-
-#define KANJI 1
-
-#define BELL_DURATION 5
-#define BELL_PITCH_8M 1339
-#define BELL_PITCH_5M 1678
-
-#define UJIS 0
-#define SJIS 1
-
-#define PRINTABLE(c) ((c) > 0x1b || ((c) > 0x0f && (c) < 0x1b) \
- || (c) < 0x07)
-
-#endif /* !_PC98_PC98_SC_MACHDEP_H_ */
diff --git a/sys/pc98/pc98/scgdcrndr.c b/sys/pc98/pc98/scgdcrndr.c
deleted file mode 100644
index abebc75..0000000
--- a/sys/pc98/pc98/scgdcrndr.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*-
- * Copyright (c) 1999 FreeBSD(98) Porting Team.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
- *
- * $FreeBSD$
- */
-
-#include "opt_syscons.h"
-#include "opt_gdc.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/fbio.h>
-#include <sys/consio.h>
-
-#include <dev/fb/fbreg.h>
-#include <dev/syscons/syscons.h>
-
-#ifndef SC_RENDER_DEBUG
-#define SC_RENDER_DEBUG 0
-#endif
-
-static vr_clear_t gdc_txtclear;
-static vr_draw_border_t gdc_txtborder;
-static vr_draw_t gdc_txtdraw;
-static vr_set_cursor_t gdc_txtcursor_shape;
-static vr_draw_cursor_t gdc_txtcursor;
-#ifndef SC_NO_CUTPASTE
-static vr_draw_mouse_t gdc_txtmouse;
-#else
-#define gdc_txtmouse (vr_draw_mouse_t *)gdc_nop
-#endif
-
-#ifndef SC_NO_MODE_CHANGE
-static vr_draw_border_t gdc_grborder;
-#endif
-
-static void gdc_nop(scr_stat *scp, ...);
-
-static sc_rndr_sw_t txtrndrsw = {
- gdc_txtclear,
- gdc_txtborder,
- gdc_txtdraw,
- gdc_txtcursor_shape,
- gdc_txtcursor,
- (vr_blink_cursor_t *)gdc_nop,
- (vr_set_mouse_t *)gdc_nop,
- gdc_txtmouse,
-};
-RENDERER(gdc, 0, txtrndrsw, gdc_set);
-
-#ifndef SC_NO_MODE_CHANGE
-static sc_rndr_sw_t grrndrsw = {
- (vr_clear_t *)gdc_nop,
- gdc_grborder,
- (vr_draw_t *)gdc_nop,
- (vr_set_cursor_t *)gdc_nop,
- (vr_draw_cursor_t *)gdc_nop,
- (vr_blink_cursor_t *)gdc_nop,
- (vr_set_mouse_t *)gdc_nop,
- (vr_draw_mouse_t *)gdc_nop,
-};
-RENDERER(gdc, GRAPHICS_MODE, grrndrsw, gdc_set);
-#endif /* SC_NO_MODE_CHANGE */
-
-RENDERER_MODULE(gdc, gdc_set);
-
-static void
-gdc_nop(scr_stat *scp, ...)
-{
-}
-
-/* text mode renderer */
-
-static void
-gdc_txtclear(scr_stat *scp, int c, int attr)
-{
- sc_vtb_clear(&scp->scr, c, attr);
-}
-
-static void
-gdc_txtborder(scr_stat *scp, int color)
-{
- (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
-}
-
-static void
-gdc_txtdraw(scr_stat *scp, int from, int count, int flip)
-{
- vm_offset_t p;
- int c;
- int a;
-
- if (from + count > scp->xsize*scp->ysize)
- count = scp->xsize*scp->ysize - from;
-
- if (flip) {
- for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) {
- c = sc_vtb_getc(&scp->vtb, from);
- a = sc_vtb_geta(&scp->vtb, from);
-#if 0
- a ^= 0x0800;
-#else
- a = (a & 0x8800) | ((a & 0x7000) >> 4)
- | ((a & 0x0700) << 4);
-#endif
- p = sc_vtb_putchar(&scp->scr, p, c, a);
- }
- } else {
- sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
- }
-}
-
-static void
-gdc_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
-{
- if (base < 0 || base >= scp->font_size)
- return;
- /* the caller may set height <= 0 in order to disable the cursor */
- (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
- base, height,
- scp->font_size, blink);
-}
-
-static void
-gdc_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
-{
- if (on) {
- scp->status |= VR_CURSOR_ON;
- (*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
- at%scp->xsize, at/scp->xsize);
- } else {
- if (scp->status & VR_CURSOR_ON)
- (*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
- -1, -1);
- scp->status &= ~VR_CURSOR_ON;
- }
-}
-
-#ifndef SC_NO_CUTPASTE
-
-static void
-draw_txtmouse(scr_stat *scp, int x, int y)
-{
- int at;
- int a;
-
- at = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
- a = sc_vtb_geta(&scp->vtb, at);
-#if 0
- a ^= 0x0800;
-#else
- a = (a & 0x8800) | ((a & 0x7000) >> 4)
- | ((a & 0x0700) << 4);
-#endif
- sc_vtb_putc(&scp->scr, at, sc_vtb_getc(&scp->scr, at), a);
-}
-
-static void
-remove_txtmouse(scr_stat *scp, int x, int y)
-{
-}
-
-static void
-gdc_txtmouse(scr_stat *scp, int x, int y, int on)
-{
- if (on)
- draw_txtmouse(scp, x, y);
- else
- remove_txtmouse(scp, x, y);
-}
-
-#endif /* SC_NO_CUTPASTE */
-
-#ifndef SC_NO_MODE_CHANGE
-
-/* graphics mode renderer */
-
-static void
-gdc_grborder(scr_stat *scp, int color)
-{
- (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
-}
-
-#endif /* SC_NO_MODE_CHANGE */
diff --git a/sys/pc98/pc98/scterm-sck.c b/sys/pc98/pc98/scterm-sck.c
deleted file mode 100644
index 7029c07..0000000
--- a/sys/pc98/pc98/scterm-sck.c
+++ /dev/null
@@ -1,1216 +0,0 @@
-/*-
- * Copyright (c) 1999 FreeBSD(98) Porting Team.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
- *
- * $FreeBSD$
- */
-
-#include "opt_syscons.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/consio.h>
-
-#include <machine/pc/display.h>
-
-#include <dev/syscons/syscons.h>
-#include <dev/syscons/sctermvar.h>
-
-#ifndef SC_DUMB_TERMINAL
-
-#define MAX_ESC_PAR 5
-
-#ifdef KANJI
-#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee))
-#define IS_KTYPE_KANA(A) ((A) & 0x11)
-#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0)
-#endif /* KANJI */
-
-/* attribute flags */
-typedef struct {
- u_short fg; /* foreground color */
- u_short bg; /* background color */
-} color_t;
-
-typedef struct {
- int flags;
-#define SCTERM_BUSY (1 << 0)
- int esc;
- int num_param;
- int last_param;
- int param[MAX_ESC_PAR];
- int saved_xpos;
- int saved_ypos;
-
-#ifdef KANJI
- u_char kanji_1st_char;
- u_char kanji_type;
-#define KTYPE_ASCII 0 /* ASCII */
-#define KTYPE_KANA 1 /* HANKAKU */
-#define KTYPE_JKANA 0x10 /* JIS HANKAKU */
-#define KTYPE_7JIS 0x20 /* JIS */
-#define KTYPE_SJIS 2 /* Shift JIS */
-#define KTYPE_UJIS 4 /* UJIS */
-#define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */
-#define KTYPE_SUJIS 6 /* SHift JIS or UJIS */
-#define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */
-#define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */
-#endif /* KANJI */
-
- int attr_mask; /* current logical attr mask */
-#define NORMAL_ATTR 0x00
-#define BLINK_ATTR 0x01
-#define BOLD_ATTR 0x02
-#define UNDERLINE_ATTR 0x04
-#define REVERSE_ATTR 0x08
-#define FG_CHANGED 0x10
-#define BG_CHANGED 0x20
- int cur_attr; /* current hardware attr word */
- color_t cur_color; /* current hardware color */
- color_t std_color; /* normal hardware color */
- color_t rev_color; /* reverse hardware color */
- color_t dflt_std_color; /* default normal color */
- color_t dflt_rev_color; /* default reverse color */
-} term_stat;
-
-static sc_term_init_t scterm_init;
-static sc_term_term_t scterm_term;
-static sc_term_puts_t scterm_puts;
-static sc_term_ioctl_t scterm_ioctl;
-static sc_term_reset_t scterm_reset;
-static sc_term_default_attr_t scterm_default_attr;
-static sc_term_clear_t scterm_clear;
-static sc_term_notify_t scterm_notify;
-static sc_term_input_t scterm_input;
-
-static sc_term_sw_t sc_term_sc = {
- { NULL, NULL },
- "sck", /* emulator name */
- "syscons kanji terminal", /* description */
- "*", /* matching renderer, any :-) */
- sizeof(term_stat), /* softc size */
- 0,
- scterm_init,
- scterm_term,
- scterm_puts,
- scterm_ioctl,
- scterm_reset,
- scterm_default_attr,
- scterm_clear,
- scterm_notify,
- scterm_input,
-};
-
-SCTERM_MODULE(sc, sc_term_sc);
-
-static term_stat reserved_term_stat;
-static int default_kanji = UJIS;
-static void scterm_scan_esc(scr_stat *scp, term_stat *tcp,
- u_char c);
-static int mask2attr(term_stat *tcp);
-
-#ifdef KANJI
-__inline static u_char
-iskanji1(u_char mode, u_char c)
-{
- if (c > 0x80) {
- if ((c >= 0xa1) && (c <= 0xdf)) {
- if (default_kanji == UJIS) {
- /* UJIS */
- return KTYPE_UJIS;
- }
- if (default_kanji == SJIS) {
- /* SJIS HANKAKU */
- return KTYPE_KANA;
- }
- }
-
- if (c <= 0x9f) {
- if (c == 0x8e) {
- /* SJIS or UJIS HANKAKU */
- return KTYPE_SUKANA;
- }
-
- /* SJIS */
- default_kanji = SJIS;
- return KTYPE_SJIS;
- }
-
- if ((c >= 0xe0) && (c <= 0xef)) {
- /* SJIS or UJIS */
- return KTYPE_SUJIS;
- }
-
- if ((c >= 0xf0) && (c <= 0xfe)) {
- /* UJIS */
- default_kanji = UJIS;
- return KTYPE_UJIS;
- }
- } else {
- if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) {
- /* JIS */
- default_kanji = UJIS;
- return KTYPE_7JIS;
- }
-
- if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) {
- /* JIS HANKAKU */
- default_kanji = UJIS;
- return KTYPE_JKANA;
- }
- }
-
- return KTYPE_ASCII;
-}
-
-__inline static u_char
-iskanji2(u_char mode, u_char c)
-{
- switch (mode) {
- case KTYPE_7JIS:
- if ((c >= 0x21) && (c <= 0x7e)) {
- /* JIS */
- return KTYPE_7JIS;
- }
- break;
- case KTYPE_SJIS:
- if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) {
- /* SJIS */
- return KTYPE_SJIS;
- }
- break;
- case KTYPE_UJIS:
- if ((c >= 0xa1) && (c <= 0xfe)) {
- /* UJIS */
- return KTYPE_UJIS;
- }
- break;
- case KTYPE_SUKANA:
- if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) {
- /* UJIS HANKAKU */
- return KTYPE_KANA;
- }
- if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) {
- /* SJIS */
- default_kanji = SJIS;
- return KTYPE_SJIS;
- }
- break;
- case KTYPE_SUJIS:
- if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) {
- /* SJIS */
- default_kanji = SJIS;
- return KTYPE_SJIS;
- }
- if ((c == 0xfd) || (c == 0xfe)) {
- /* UJIS */
- default_kanji = UJIS;
- return KTYPE_UJIS;
- }
- if ((c >= 0xa1) && (c <= 0xfc)) {
- if (default_kanji == SJIS)
- return KTYPE_SJIS;
- if (default_kanji == UJIS)
- return KTYPE_UJIS;
- }
- break;
- }
-
- return KTYPE_ASCII;
-}
-
-/*
- * JIS X0208-83 keisen conversion table
- */
-static u_short keiConv[32] = {
- 0x240c, 0x260c, 0x300c, 0x340c, 0x3c0c, 0x380c, 0x400c, 0x500c,
- 0x480c, 0x580c, 0x600c, 0x250c, 0x270c, 0x330c, 0x370c, 0x3f0c,
- 0x3b0c, 0x470c, 0x570c, 0x4f0c, 0x5f0c, 0x6f0c, 0x440c, 0x530c,
- 0x4c0c, 0x5b0c, 0x630c, 0x410c, 0x540c, 0x490c, 0x5c0c, 0x660c
-};
-
-static u_short
-kanji_convert(u_char mode, u_char h, u_char l)
-{
- u_short tmp, high, low, c;
-
- high = (u_short) h;
- low = (u_short) l;
-
- switch (mode) {
- case KTYPE_SJIS: /* SHIFT JIS */
- if (low >= 0xe0) {
- low -= 0x40;
- }
- low = (low - 0x81) * 2 + 0x21;
- if (high > 0x7f) {
- high--;
- }
- if (high > 0x9d) {
- low++;
- high -= 0x9e - 0x21;
- } else {
- high -= 0x40 - 0x21;
- }
- high &= 0x7F;
- low &= 0x7F;
- tmp = ((high << 8) | low) - 0x20;
- break;
- case KTYPE_7JIS: /* JIS */
- case KTYPE_UJIS: /* UJIS */
- high &= 0x7F;
- low &= 0x7F;
- tmp = ((high << 8) | low) - 0x20;
- break;
- default:
- tmp = 0;
- break;
- }
-
- /* keisen */
- c = ((tmp & 0xff) << 8) | (tmp >> 8);
- /* 0x2821 .. 0x2840 */
- if (0x0821 <= c && c <= 0x0840)
- tmp = keiConv[c - 0x0821];
-
- return (tmp);
-}
-#endif /* KANJI */
-
-static int
-scterm_init(scr_stat *scp, void **softc, int code)
-{
- term_stat *tcp;
-
- if (*softc == NULL) {
- if (reserved_term_stat.flags & SCTERM_BUSY)
- return EINVAL;
- *softc = &reserved_term_stat;
- }
- tcp = *softc;
-
- switch (code) {
- case SC_TE_COLD_INIT:
- bzero(tcp, sizeof(*tcp));
- tcp->flags = SCTERM_BUSY;
- tcp->esc = 0;
- tcp->saved_xpos = -1;
- tcp->saved_ypos = -1;
-#ifdef KANJI
- tcp->kanji_1st_char = 0;
- tcp->kanji_type = KTYPE_ASCII;
-#endif
- tcp->attr_mask = NORMAL_ATTR;
- /* XXX */
- tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f;
- tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f;
- tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f;
- tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f;
- tcp->std_color = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
- ++sc_term_sc.te_refcount;
- break;
-
- case SC_TE_WARM_INIT:
- tcp->esc = 0;
- tcp->saved_xpos = -1;
- tcp->saved_ypos = -1;
-#if 0
- tcp->std_color = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
-#endif
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
- break;
- }
-
- return 0;
-}
-
-static int
-scterm_term(scr_stat *scp, void **softc)
-{
- if (*softc == &reserved_term_stat) {
- *softc = NULL;
- bzero(&reserved_term_stat, sizeof(reserved_term_stat));
- }
- --sc_term_sc.te_refcount;
- return 0;
-}
-
-static void
-scterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c)
-{
- static u_char ansi_col[16] = {
- FG_BLACK, FG_RED, FG_GREEN, FG_BROWN,
- FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY,
- FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW,
- FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE
- };
- static int cattrs[] = {
- 0, /* block */
- CONS_BLINK_CURSOR, /* blinking block */
- CONS_CHAR_CURSOR, /* underline */
- CONS_CHAR_CURSOR | CONS_BLINK_CURSOR, /* blinking underline */
- CONS_RESET_CURSOR, /* reset to default */
- CONS_HIDDEN_CURSOR, /* hide cursor */
- };
- static int tcattrs[] = {
- CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, /* normal */
- CONS_HIDDEN_CURSOR | CONS_LOCAL_CURSOR, /* invisible */
- CONS_BLINK_CURSOR | CONS_LOCAL_CURSOR, /* very visible */
- };
- sc_softc_t *sc;
- int v0, v1, v2;
- int i, n;
-
- i = n = 0;
- sc = scp->sc;
- if (tcp->esc == 1) { /* seen ESC */
-#ifdef KANJI
- switch (tcp->kanji_type) {
- case KTYPE_KANIN: /* Kanji Invoke sequence */
- switch (c) {
- case 'B':
- case '@':
- tcp->kanji_type = KTYPE_7JIS;
- tcp->esc = 0;
- tcp->kanji_1st_char = 0;
- return;
- default:
- tcp->kanji_type = KTYPE_ASCII;
- tcp->esc = 0;
- break;
- }
- break;
- case KTYPE_ASCIN: /* Ascii Invoke sequence */
- switch (c) {
- case 'J':
- case 'B':
- case 'H':
- tcp->kanji_type = KTYPE_ASCII;
- tcp->esc = 0;
- tcp->kanji_1st_char = 0;
- return;
- case 'I':
- tcp->kanji_type = KTYPE_JKANA;
- tcp->esc = 0;
- tcp->kanji_1st_char = 0;
- return;
- default:
- tcp->kanji_type = KTYPE_ASCII;
- tcp->esc = 0;
- break;
- }
- break;
- default:
- break;
- }
-#endif
- switch (c) {
-
- case '7': /* Save cursor position */
- tcp->saved_xpos = scp->xpos;
- tcp->saved_ypos = scp->ypos;
- break;
-
- case '8': /* Restore saved cursor position */
- if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
- sc_move_cursor(scp, tcp->saved_xpos,
- tcp->saved_ypos);
- break;
-
- case '[': /* Start ESC [ sequence */
- tcp->esc = 2;
- tcp->last_param = -1;
- for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
- tcp->param[i] = 1;
- tcp->num_param = 0;
- return;
-
-#ifdef KANJI
- case '$': /* Kanji Invoke sequence */
- tcp->kanji_type = KTYPE_KANIN;
- return;
-#endif
-
- case 'M': /* Move cursor up 1 line, scroll if at top */
- sc_term_up_scroll(scp, 1, sc->scr_map[0x20],
- tcp->cur_attr, 0, 0);
- break;
-#if notyet
- case 'Q':
- tcp->esc = 4;
- return;
-#endif
- case 'c': /* reset */
- tcp->attr_mask = NORMAL_ATTR;
- tcp->cur_color = tcp->std_color
- = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
- tcp->cur_attr = mask2attr(tcp);
- sc_change_cursor_shape(scp,
- CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, -1, -1);
- sc_clear_screen(scp);
- break;
-
- case '(': /* iso-2022: designate 94 character set to G0 */
-#ifdef KANJI
- tcp->kanji_type = KTYPE_ASCIN;
-#else
- tcp->esc = 5;
-#endif
- return;
- }
- } else if (tcp->esc == 2) { /* seen ESC [ */
- if (c >= '0' && c <= '9') {
- if (tcp->num_param < MAX_ESC_PAR) {
- if (tcp->last_param != tcp->num_param) {
- tcp->last_param = tcp->num_param;
- tcp->param[tcp->num_param] = 0;
- } else {
- tcp->param[tcp->num_param] *= 10;
- }
- tcp->param[tcp->num_param] += c - '0';
- return;
- }
- }
- tcp->num_param = tcp->last_param + 1;
- switch (c) {
-
- case ';':
- if (tcp->num_param < MAX_ESC_PAR)
- return;
- break;
-
- case '=':
- tcp->esc = 3;
- tcp->last_param = -1;
- for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
- tcp->param[i] = 1;
- tcp->num_param = 0;
- return;
-
- case 'A': /* up n rows */
- sc_term_up(scp, tcp->param[0], 0);
- break;
-
- case 'B': /* down n rows */
- sc_term_down(scp, tcp->param[0], 0);
- break;
-
- case 'C': /* right n columns */
- sc_term_right(scp, tcp->param[0]);
- break;
-
- case 'D': /* left n columns */
- sc_term_left(scp, tcp->param[0]);
- break;
-
- case 'E': /* cursor to start of line n lines down */
- n = tcp->param[0];
- if (n < 1)
- n = 1;
- sc_move_cursor(scp, 0, scp->ypos + n);
- break;
-
- case 'F': /* cursor to start of line n lines up */
- n = tcp->param[0];
- if (n < 1)
- n = 1;
- sc_move_cursor(scp, 0, scp->ypos - n);
- break;
-
- case 'f': /* Cursor move */
- case 'H':
- if (tcp->num_param == 0)
- sc_move_cursor(scp, 0, 0);
- else if (tcp->num_param == 2)
- sc_move_cursor(scp, tcp->param[1] - 1,
- tcp->param[0] - 1);
- break;
-
- case 'J': /* Clear all or part of display */
- if (tcp->num_param == 0)
- n = 0;
- else
- n = tcp->param[0];
- sc_term_clr_eos(scp, n, sc->scr_map[0x20],
- tcp->cur_attr);
- break;
-
- case 'K': /* Clear all or part of line */
- if (tcp->num_param == 0)
- n = 0;
- else
- n = tcp->param[0];
- sc_term_clr_eol(scp, n, sc->scr_map[0x20],
- tcp->cur_attr);
- break;
-
- case 'L': /* Insert n lines */
- sc_term_ins_line(scp, scp->ypos, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr, 0);
- break;
-
- case 'M': /* Delete n lines */
- sc_term_del_line(scp, scp->ypos, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr, 0);
- break;
-
- case 'P': /* Delete n chars */
- sc_term_del_char(scp, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr);
- break;
-
- case '@': /* Insert n chars */
- sc_term_ins_char(scp, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr);
- break;
-
- case 'S': /* scroll up n lines */
- sc_term_del_line(scp, 0, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr, 0);
- break;
-
- case 'T': /* scroll down n lines */
- sc_term_ins_line(scp, 0, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr, 0);
- break;
-
- case 'X': /* erase n characters in line */
- n = tcp->param[0];
- if (n < 1)
- n = 1;
- if (n > scp->xsize - scp->xpos)
- n = scp->xsize - scp->xpos;
- sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
- sc->scr_map[0x20], tcp->cur_attr);
- mark_for_update(scp, scp->cursor_pos);
- mark_for_update(scp, scp->cursor_pos + n - 1);
- break;
-
- case 'Z': /* move n tabs backwards */
- sc_term_backtab(scp, tcp->param[0]);
- break;
-
- case '`': /* move cursor to column n */
- sc_term_col(scp, tcp->param[0]);
- break;
-
- case 'a': /* move cursor n columns to the right */
- sc_term_right(scp, tcp->param[0]);
- break;
-
- case 'd': /* move cursor to row n */
- sc_term_row(scp, tcp->param[0]);
- break;
-
- case 'e': /* move cursor n rows down */
- sc_term_down(scp, tcp->param[0], 0);
- break;
-
- case 'm': /* change attribute */
- if (tcp->num_param == 0) {
- tcp->attr_mask = NORMAL_ATTR;
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
- break;
- }
- for (i = 0; i < tcp->num_param; i++) {
- switch (n = tcp->param[i]) {
- case 0: /* back to normal */
- tcp->attr_mask = NORMAL_ATTR;
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 1: /* bold */
- tcp->attr_mask |= BOLD_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 4: /* underline */
- tcp->attr_mask |= UNDERLINE_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 5: /* blink */
- tcp->attr_mask |= BLINK_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 7: /* reverse */
- tcp->attr_mask |= REVERSE_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 22: /* remove bold (or dim) */
- tcp->attr_mask &= ~BOLD_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 24: /* remove underline */
- tcp->attr_mask &= ~UNDERLINE_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 25: /* remove blink */
- tcp->attr_mask &= ~BLINK_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 27: /* remove reverse */
- tcp->attr_mask &= ~REVERSE_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 30: case 31: /* set ansi fg color */
- case 32: case 33: case 34:
- case 35: case 36: case 37:
- tcp->attr_mask |= FG_CHANGED;
- tcp->cur_color.fg = ansi_col[n - 30];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 39: /* restore fg color back to normal */
- tcp->attr_mask &= ~(FG_CHANGED|BOLD_ATTR);
- tcp->cur_color.fg = tcp->std_color.fg;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 40: case 41: /* set ansi bg color */
- case 42: case 43: case 44:
- case 45: case 46: case 47:
- tcp->attr_mask |= BG_CHANGED;
- tcp->cur_color.bg = ansi_col[n - 40];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 49: /* restore bg color back to normal */
- tcp->attr_mask &= ~BG_CHANGED;
- tcp->cur_color.bg = tcp->std_color.bg;
- tcp->cur_attr = mask2attr(tcp);
- break;
- }
- }
- break;
-
- case 's': /* Save cursor position */
- tcp->saved_xpos = scp->xpos;
- tcp->saved_ypos = scp->ypos;
- break;
-
- case 'u': /* Restore saved cursor position */
- if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
- sc_move_cursor(scp, tcp->saved_xpos,
- tcp->saved_ypos);
- break;
-
- case 'x':
- if (tcp->num_param == 0)
- n = 0;
- else
- n = tcp->param[0];
- switch (n) {
- case 0: /* reset colors and attributes back to normal */
- tcp->attr_mask = NORMAL_ATTR;
- tcp->cur_color = tcp->std_color
- = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 1: /* set ansi background */
- tcp->attr_mask &= ~BG_CHANGED;
- tcp->cur_color.bg = tcp->std_color.bg
- = ansi_col[tcp->param[1] & 0x0f];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 2: /* set ansi foreground */
- tcp->attr_mask &= ~FG_CHANGED;
- tcp->cur_color.fg = tcp->std_color.fg
- = ansi_col[tcp->param[1] & 0x0f];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 3: /* set adapter attribute directly */
- tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED);
- tcp->cur_color.fg = tcp->std_color.fg
- = tcp->param[1] & 0x0f;
- tcp->cur_color.bg = tcp->std_color.bg
- = (tcp->param[1] >> 4) & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 5: /* set ansi reverse background */
- tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 6: /* set ansi reverse foreground */
- tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 7: /* set adapter reverse attribute directly */
- tcp->rev_color.fg = tcp->param[1] & 0x0f;
- tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- break;
- }
- break;
-
- case 'z': /* switch to (virtual) console n */
- if (tcp->num_param == 1)
- sc_switch_scr(sc, tcp->param[0]);
- break;
- }
- } else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */
- if (c >= '0' && c <= '9') {
- if (tcp->num_param < MAX_ESC_PAR) {
- if (tcp->last_param != tcp->num_param) {
- tcp->last_param = tcp->num_param;
- tcp->param[tcp->num_param] = 0;
- } else {
- tcp->param[tcp->num_param] *= 10;
- }
- tcp->param[tcp->num_param] += c - '0';
- return;
- }
- }
- tcp->num_param = tcp->last_param + 1;
- switch (c) {
-
- case ';':
- if (tcp->num_param < MAX_ESC_PAR)
- return;
- break;
-
- case 'A': /* set display border color */
- if (tcp->num_param == 1) {
- scp->border=tcp->param[0] & 0xff;
- if (scp == sc->cur_scp)
- sc_set_border(scp, scp->border);
- }
- break;
-
- case 'B': /* set bell pitch and duration */
- if (tcp->num_param == 2) {
- scp->bell_pitch = tcp->param[0];
- scp->bell_duration =
- (tcp->param[1] * hz + 99) / 100;
- }
- break;
-
- case 'C': /* set global/parmanent cursor type & shape */
- i = spltty();
- n = tcp->num_param;
- v0 = tcp->param[0];
- v1 = tcp->param[1];
- v2 = tcp->param[2];
- switch (n) {
- case 1: /* flags only */
- if (v0 < sizeof(cattrs)/sizeof(cattrs[0]))
- v0 = cattrs[v0];
- else /* backward compatibility */
- v0 = cattrs[v0 & 0x3];
- sc_change_cursor_shape(scp, v0, -1, -1);
- break;
- case 2:
- v2 = 0;
- v0 &= 0x1f; /* backward compatibility */
- v1 &= 0x1f;
- /* FALL THROUGH */
- case 3: /* base and height */
- if (v2 == 0) /* count from top */
- sc_change_cursor_shape(scp, -1,
- scp->font_size - v1 - 1,
- v1 - v0 + 1);
- else if (v2 == 1) /* count from bottom */
- sc_change_cursor_shape(scp, -1,
- v0, v1 - v0 + 1);
- break;
- }
- splx(i);
- break;
-
- case 'F': /* set adapter foreground */
- if (tcp->num_param == 1) {
- tcp->attr_mask &= ~FG_CHANGED;
- tcp->cur_color.fg = tcp->std_color.fg
- = tcp->param[0] & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- }
- break;
-
- case 'G': /* set adapter background */
- if (tcp->num_param == 1) {
- tcp->attr_mask &= ~BG_CHANGED;
- tcp->cur_color.bg = tcp->std_color.bg
- = tcp->param[0] & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- }
- break;
-
- case 'H': /* set adapter reverse foreground */
- if (tcp->num_param == 1) {
- tcp->rev_color.fg = tcp->param[0] & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- }
- break;
-
- case 'I': /* set adapter reverse background */
- if (tcp->num_param == 1) {
- tcp->rev_color.bg = tcp->param[0] & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- }
- break;
-
- case 'S': /* set local/temporary cursor type & shape */
- i = spltty();
- n = tcp->num_param;
- v0 = tcp->param[0];
- switch (n) {
- case 0:
- v0 = 0;
- /* FALL THROUGH */
- case 1:
- if (v0 < sizeof(tcattrs)/sizeof(tcattrs[0]))
- sc_change_cursor_shape(scp,
- tcattrs[v0], -1, -1);
- break;
- }
- splx(i);
- break;
- }
-#if notyet
- } else if (tcp->esc == 4) { /* seen ESC Q */
- /* to be filled */
-#endif
- } else if (tcp->esc == 5) { /* seen ESC ( */
- switch (c) {
- case 'B': /* iso-2022: desginate ASCII into G0 */
- break;
- /* other items to be filled */
- default:
- break;
- }
- }
- tcp->esc = 0;
-}
-
-static void
-scterm_puts(scr_stat *scp, u_char *buf, int len)
-{
- term_stat *tcp;
- u_char *ptr;
-#ifdef KANJI
- u_short kanji_code;
-#endif
-
- tcp = scp->ts;
- ptr = buf;
-outloop:
- scp->sc->write_in_progress++;
-
- if (tcp->esc) {
- scterm_scan_esc(scp, tcp, *ptr++);
- len--;
- } else if (PRINTABLE(*ptr)) { /* Print only printables */
- vm_offset_t p;
- u_char *map;
- int attr;
- int i;
- int cnt;
-#ifdef KANJI
- u_char c;
-#endif
-
- p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos);
- map = scp->sc->scr_map;
- attr = tcp->cur_attr;
-
-#ifdef KANJI
- c = *ptr;
- if (tcp->kanji_1st_char == 0) {
- tcp->kanji_type = iskanji1(tcp->kanji_type, c);
- if (!IS_KTYPE_ASCII_or_HANKAKU(tcp->kanji_type)) {
- /* not Ascii & not HANKAKU */
- tcp->kanji_1st_char = c;
- goto kanji_end;
- } else if (tcp->kanji_type == KTYPE_ASCII) {
- cnt = imin(len, scp->xsize - scp->xpos);
- i = cnt;
- do {
- p = sc_vtb_putchar(&scp->vtb, p, map[c], attr);
- c = *++ptr;
- --i;
- } while (i > 0 && PRINTABLE(c) &&
- iskanji1(tcp->kanji_type, c) == KTYPE_ASCII);
-
- len -= cnt - i;
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos += cnt - i;
- mark_for_update(scp, scp->cursor_pos - 1);
- scp->xpos += cnt - i;
- KTYPE_MASK_CTRL(tcp->kanji_type);
- goto ascii_end;
- }
- } else {
- if ((tcp->kanji_type =
- iskanji2(tcp->kanji_type, c)) & 0xee) {
- /* print kanji on TEXT VRAM */
- kanji_code = kanji_convert(tcp->kanji_type, c,
- tcp->kanji_1st_char);
- mark_for_update(scp, scp->cursor_pos);
- for (i = 0; i < 2; i++) {
- /* *cursor_pos = (kanji_code | (i*0x80)); */
- p = sc_vtb_putchar(&scp->vtb, p,
- kanji_code | ((i == 0) ? 0x00 : 0x80), attr);
- ++scp->cursor_pos;
- if (++scp->xpos >= scp->xsize) {
- scp->xpos = 0;
- scp->ypos++;
- }
- }
- mark_for_update(scp, scp->cursor_pos - 1);
- KTYPE_MASK_CTRL(tcp->kanji_type);
- tcp->kanji_1st_char = 0;
- goto kanji_end;
- } else {
- tcp->kanji_1st_char = 0;
- }
- }
- if (IS_KTYPE_KANA(tcp->kanji_type))
- c |= 0x80;
- KTYPE_MASK_CTRL(tcp->kanji_type);
- sc_vtb_putchar(&scp->vtb, p, map[c], attr);
- mark_for_update(scp, scp->cursor_pos);
- mark_for_update(scp, scp->cursor_pos);
- ++scp->cursor_pos;
- ++scp->xpos;
-kanji_end:
- ++ptr;
- --len;
-ascii_end:
-#else /* !KANJI */
- cnt = imin(len, scp->xsize - scp->xpos);
- i = cnt;
- do {
- /*
- * gcc-2.6.3 generates poor (un)sign extension code.
- * Casting the pointers in the following to volatile should
- * have no effect, but in fact speeds up this inner loop
- * from 26 to 18 cycles (+ cache misses) on i486's.
- */
-#define UCVP(ucp) ((u_char volatile *)(ucp))
- p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)],
- attr);
- ++ptr;
- --i;
- } while (i > 0 && PRINTABLE(*ptr));
-
- len -= cnt - i;
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos += cnt - i;
- mark_for_update(scp, scp->cursor_pos - 1);
- scp->xpos += cnt - i;
-#endif /* !KANJI */
-
- if (scp->xpos >= scp->xsize) {
- scp->xpos = 0;
- scp->ypos++;
- }
- } else {
- switch (*ptr) {
- case 0x07:
- sc_bell(scp, scp->bell_pitch, scp->bell_duration);
- break;
-
- case 0x08: /* non-destructive backspace */
- if (scp->cursor_pos > 0) {
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos--;
- mark_for_update(scp, scp->cursor_pos);
- if (scp->xpos > 0)
- scp->xpos--;
- else {
- scp->xpos += scp->xsize - 1;
- scp->ypos--;
- }
- }
- break;
-
- case 0x09: /* non-destructive tab */
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos += (8 - scp->xpos % 8u);
- scp->xpos += (8 - scp->xpos % 8u);
- if (scp->xpos >= scp->xsize) {
- scp->xpos = 0;
- scp->ypos++;
- scp->cursor_pos = scp->xsize * scp->ypos;
- }
- mark_for_update(scp, scp->cursor_pos);
- break;
-
- case 0x0a: /* newline, same pos */
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos += scp->xsize;
- mark_for_update(scp, scp->cursor_pos);
- scp->ypos++;
- break;
-
- case 0x0c: /* form feed, clears screen */
- sc_clear_screen(scp);
- break;
-
- case 0x0d: /* return, return to pos 0 */
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos -= scp->xpos;
- mark_for_update(scp, scp->cursor_pos);
- scp->xpos = 0;
- break;
-
- case 0x0e: /* ^N */
- tcp->kanji_type = KTYPE_JKANA;
- tcp->esc = 0;
- tcp->kanji_1st_char = 0;
- break;
-
- case 0x0f: /* ^O */
- tcp->kanji_type = KTYPE_ASCII;
- tcp->esc = 0;
- tcp->kanji_1st_char = 0;
- break;
-
- case 0x1b: /* start escape sequence */
- tcp->esc = 1;
- tcp->num_param = 0;
- break;
- }
- ptr++;
- len--;
- }
-
- sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr);
-
- scp->sc->write_in_progress--;
- if (len)
- goto outloop;
-}
-
-static int
-scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
- int flag, struct thread *td)
-{
- term_stat *tcp = scp->ts;
- vid_info_t *vi;
-
- switch (cmd) {
- case GIO_ATTR: /* get current attributes */
- /* FIXME: */
- *(int*)data = (tcp->cur_attr >> 8) & 0xff;
- return 0;
- case CONS_GETINFO: /* get current (virtual) console info */
- vi = (vid_info_t *)data;
- if (vi->size != sizeof(struct vid_info))
- return EINVAL;
- vi->mv_norm.fore = tcp->std_color.fg;
- vi->mv_norm.back = tcp->std_color.bg;
- vi->mv_rev.fore = tcp->rev_color.fg;
- vi->mv_rev.back = tcp->rev_color.bg;
- /*
- * The other fields are filled by the upper routine. XXX
- */
- return ENOIOCTL;
- }
- return ENOIOCTL;
-}
-
-static int
-scterm_reset(scr_stat *scp, int code)
-{
- /* FIXME */
- return 0;
-}
-
-static void
-scterm_default_attr(scr_stat *scp, int color, int rev_color)
-{
- term_stat *tcp = scp->ts;
-
- tcp->dflt_std_color.fg = color & 0x0f;
- tcp->dflt_std_color.bg = (color >> 4) & 0x0f;
- tcp->dflt_rev_color.fg = rev_color & 0x0f;
- tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f;
- tcp->std_color = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
-}
-
-static void
-scterm_clear(scr_stat *scp)
-{
- term_stat *tcp = scp->ts;
-
- sc_move_cursor(scp, 0, 0);
- sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr);
- mark_all(scp);
-}
-
-static void
-scterm_notify(scr_stat *scp, int event)
-{
- switch (event) {
- case SC_TE_NOTIFY_VTSWITCH_IN:
- break;
- case SC_TE_NOTIFY_VTSWITCH_OUT:
- break;
- }
-}
-
-static int
-scterm_input(scr_stat *scp, int c, struct tty *tp)
-{
- return FALSE;
-}
-
-/*
- * Calculate hardware attributes word using logical attributes mask and
- * hardware colors
- */
-
-/* FIXME */
-static int
-mask2attr(term_stat *tcp)
-{
- int attr, mask = tcp->attr_mask;
-
- if (mask & REVERSE_ATTR) {
- attr = ((mask & FG_CHANGED) ?
- tcp->cur_color.bg : tcp->rev_color.fg) |
- (((mask & BG_CHANGED) ?
- tcp->cur_color.fg : tcp->rev_color.bg) << 4);
- } else
- attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4);
-
- /* XXX: underline mapping for Hercules adapter can be better */
- if (mask & (BOLD_ATTR | UNDERLINE_ATTR))
- attr ^= 0x08;
- if (mask & BLINK_ATTR)
- attr ^= 0x80;
-
- return (attr << 8);
-}
-
-#endif /* SC_DUMB_TERMINAL */
diff --git a/sys/pc98/pc98/scvtbpc98.c b/sys/pc98/pc98/scvtbpc98.c
deleted file mode 100644
index 2d0ea3f..0000000
--- a/sys/pc98/pc98/scvtbpc98.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*-
- * Copyright (c) 1999 FreeBSD(98) Porting Team.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
- *
- * $FreeBSD$
- */
-
-#include "opt_syscons.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/consio.h>
-#include <sys/fbio.h>
-
-#include <machine/md_var.h>
-
-#include <dev/fb/fbreg.h>
-#include <dev/syscons/syscons.h>
-
-#define ATTR_OFFSET_FB 0x2000
-#define attr_offset(vtb) ((vtb)->vtb_size*sizeof(u_int16_t))
-
-#define vtb_pointer(vtb, at) \
- ((vtb)->vtb_buffer + sizeof(u_int16_t)*(at))
-
-#define vtb_wrap(vtb, at, offset) \
- (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
-
-static u_int8_t ibmpc_to_pc98[256] = {
- 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
- 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
- 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
- 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
- 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
- 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
-
- 0x03, 0x23, 0x83, 0xa3, 0x43, 0x63, 0xc3, 0xe3,
- 0x0b, 0x2b, 0x8b, 0xab, 0x4b, 0x6b, 0xcb, 0xeb,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
- 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
- 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
- 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
-};
-#define at2pc98(attr) ((attr) | ibmpc_to_pc98[(unsigned)(attr) >> 8])
-
-void
-sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
-{
- vtb->vtb_flags = 0;
- vtb->vtb_type = type;
- vtb->vtb_cols = cols;
- vtb->vtb_rows = rows;
- vtb->vtb_size = cols*rows;
- vtb->vtb_buffer = 0;
- vtb->vtb_tail = 0;
-
- switch (type) {
- case VTB_MEMORY:
- case VTB_RINGBUFFER:
- if ((buf == NULL) && (cols*rows != 0)) {
- vtb->vtb_buffer =
- (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
- M_DEVBUF,
- ((wait) ? M_WAITOK : M_NOWAIT) | M_ZERO);
- if (vtb->vtb_buffer != 0) {
- vtb->vtb_flags |= VTB_ALLOCED;
- }
- } else {
- vtb->vtb_buffer = (vm_offset_t)buf;
- }
- vtb->vtb_flags |= VTB_VALID;
- break;
- case VTB_FRAMEBUFFER:
- vtb->vtb_buffer = (vm_offset_t)buf;
- vtb->vtb_flags |= VTB_VALID;
- break;
- default:
- break;
- }
-}
-
-void
-sc_vtb_destroy(sc_vtb_t *vtb)
-{
- vm_offset_t p;
-
- vtb->vtb_cols = 0;
- vtb->vtb_rows = 0;
- vtb->vtb_size = 0;
- vtb->vtb_tail = 0;
-
- p = vtb->vtb_buffer;
- vtb->vtb_buffer = 0;
- switch (vtb->vtb_type) {
- case VTB_MEMORY:
- case VTB_RINGBUFFER:
- if ((vtb->vtb_flags & VTB_ALLOCED) && (p != 0))
- free((void *)p, M_DEVBUF);
- break;
- default:
- break;
- }
- vtb->vtb_flags = 0;
- vtb->vtb_type = VTB_INVALID;
-}
-
-size_t
-sc_vtb_size(int cols, int rows)
-{
- return (size_t)(cols*rows*sizeof(u_int16_t)*2);
-}
-
-int
-sc_vtb_getc(sc_vtb_t *vtb, int at)
-{
- vm_offset_t p = vtb_pointer(vtb, at);
-
- if (vtb->vtb_type == VTB_FRAMEBUFFER)
- return (readw(p) & 0x00ff);
- else
- return (*(u_int16_t *)p & 0x00ff);
-}
-
-int
-sc_vtb_geta(sc_vtb_t *vtb, int at)
-{
- vm_offset_t p = vtb_pointer(vtb, at);
-
- if (vtb->vtb_type == VTB_FRAMEBUFFER)
- return (readw(p + ATTR_OFFSET_FB) & 0xff00);
- else
- return (*(u_int16_t *)(p + attr_offset(vtb)) & 0xff00);
-}
-
-__inline static void
-vtb_putc(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
-{
- if (vtb->vtb_type == VTB_FRAMEBUFFER) {
- writew(p, c);
- writew(p + ATTR_OFFSET_FB, at2pc98(a));
- } else {
- *(u_int16_t *)p = c;
- *(u_int16_t *)(p + attr_offset(vtb)) = at2pc98(a);
- }
-}
-
-void
-sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
-{
- vtb_putc(vtb, vtb_pointer(vtb, at), c, a);
-}
-
-vm_offset_t
-sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
-{
- vtb_putc(vtb, p, c, a);
- return (p + sizeof(u_int16_t));
-}
-
-vm_offset_t
-sc_vtb_pointer(sc_vtb_t *vtb, int at)
-{
- return (vtb_pointer(vtb, at));
-}
-
-int
-sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
-{
- return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
-}
-
-void
-sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
-{
- vm_offset_t p = vtb_pointer(vtb, 0);
-
- if (vtb->vtb_type == VTB_FRAMEBUFFER) {
- fillw_io(c, p, vtb->vtb_size);
- fillw_io(at2pc98(attr), p + ATTR_OFFSET_FB, vtb->vtb_size);
- } else {
- fillw(c, (void *)p, vtb->vtb_size);
- fillw(at2pc98(attr), (void *)(p + attr_offset(vtb)),
- vtb->vtb_size);
- }
-}
-
-void
-sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
-{
- vm_offset_t p1, p2;
-
- p1 = vtb_pointer(vtb1, from);
- p2 = vtb_pointer(vtb2, to);
- if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
- bcopy_toio(p1, p2, count*sizeof(u_int16_t));
- bcopy_toio(p1 + attr_offset(vtb1),
- p2 + ATTR_OFFSET_FB,
- count*sizeof(u_int16_t));
- } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
- bcopy_fromio(p1, p2, count*sizeof(u_int16_t));
- bcopy_fromio(p1 + ATTR_OFFSET_FB,
- p2 + attr_offset(vtb2),
- count*sizeof(u_int16_t));
- } else {
- bcopy((void *)p1, (void *)p2, count*sizeof(u_int16_t));
- bcopy((void *)(p1 + attr_offset(vtb1)),
- (void *)(p2 + attr_offset(vtb2)),
- count*sizeof(u_int16_t));
- }
-}
-
-void
-sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
-{
- int len;
- vm_offset_t p1, p2;
-
- if (vtb2->vtb_type != VTB_RINGBUFFER)
- return;
-
- while (count > 0) {
- p1 = vtb_pointer(vtb1, from);
- p2 = vtb_pointer(vtb2, vtb2->vtb_tail);
- len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
- if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
- bcopy_fromio(p1, p2, len*sizeof(u_int16_t));
- bcopy_fromio(p1 + ATTR_OFFSET_FB,
- p2 + attr_offset(vtb2),
- len*sizeof(u_int16_t));
- } else {
- bcopy((void *)p1, (void *)p2, len*sizeof(u_int16_t));
- bcopy((void *)(p1 + attr_offset(vtb1)),
- (void *)(p2 + attr_offset(vtb2)),
- len*sizeof(u_int16_t));
- }
- from += len;
- count -= len;
- vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
- }
-}
-
-void
-sc_vtb_seek(sc_vtb_t *vtb, int pos)
-{
- vtb->vtb_tail = pos%vtb->vtb_size;
-}
-
-void
-sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
-{
- vm_offset_t p;
-
- if (at + count > vtb->vtb_size)
- count = vtb->vtb_size - at;
- p = vtb_pointer(vtb, at);
- if (vtb->vtb_type == VTB_FRAMEBUFFER) {
- fillw_io(c, p, count);
- fillw_io(at2pc98(attr), p + ATTR_OFFSET_FB, count);
- } else {
- fillw(c, (void *)p, count);
- fillw(at2pc98(attr), (void *)(p + attr_offset(vtb)), count);
- }
-}
-
-void
-sc_vtb_move(sc_vtb_t *vtb, int from, int to, int count)
-{
- vm_offset_t p1, p2;
-
- if (from + count > vtb->vtb_size)
- count = vtb->vtb_size - from;
- if (to + count > vtb->vtb_size)
- count = vtb->vtb_size - to;
- if (count <= 0)
- return;
-
- p1 = vtb_pointer(vtb, from);
- p2 = vtb_pointer(vtb, to);
- if (vtb->vtb_type == VTB_FRAMEBUFFER) {
- bcopy_io(p1, p2, count*sizeof(u_int16_t));
- bcopy_io(p1 + ATTR_OFFSET_FB,
- p2 + ATTR_OFFSET_FB, count*sizeof(u_int16_t));
- } else {
- bcopy((void *)p1, (void *)p2, count*sizeof(u_int16_t));
- bcopy((void *)(p1 + attr_offset(vtb)),
- (void *)(p2 + attr_offset(vtb)), count*sizeof(u_int16_t));
- }
-}
-
-void
-sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
-{
- int len;
- vm_offset_t p1, p2;
-
- if (at + count > vtb->vtb_size)
- count = vtb->vtb_size - at;
- len = vtb->vtb_size - at - count;
- if (len > 0) {
- p1 = vtb_pointer(vtb, at + count);
- p2 = vtb_pointer(vtb, at);
- if (vtb->vtb_type == VTB_FRAMEBUFFER) {
- bcopy_io(p1, p2, len*sizeof(u_int16_t));
- bcopy_io(p1 + ATTR_OFFSET_FB,
- p2 + ATTR_OFFSET_FB,
- len*sizeof(u_int16_t));
- } else {
- bcopy((void *)p1, (void *)p2, len*sizeof(u_int16_t));
- bcopy((void *)(p1 + attr_offset(vtb)),
- (void *)(p2 + attr_offset(vtb)),
- len*sizeof(u_int16_t));
- }
- }
- p1 = vtb_pointer(vtb, at + len);
- if (vtb->vtb_type == VTB_FRAMEBUFFER) {
- fillw_io(c, p1, vtb->vtb_size - at - len);
- fillw_io(at2pc98(attr), p1 + ATTR_OFFSET_FB,
- vtb->vtb_size - at - len);
- } else {
- fillw(c, (void *)p1, vtb->vtb_size - at - len);
- fillw(at2pc98(attr), (void *)(p1 + attr_offset(vtb)),
- vtb->vtb_size - at - len);
- }
-}
-
-void
-sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
-{
- vm_offset_t p1, p2;
-
- p1 = vtb_pointer(vtb, at);
- if (at + count > vtb->vtb_size) {
- count = vtb->vtb_size - at;
- } else {
- p2 = vtb_pointer(vtb, at + count);
- if (vtb->vtb_type == VTB_FRAMEBUFFER) {
- bcopy_io(p1, p2,
- (vtb->vtb_size - at - count)*sizeof(u_int16_t));
- bcopy_io(p1 + ATTR_OFFSET_FB,
- p2 + ATTR_OFFSET_FB,
- (vtb->vtb_size - at - count)*sizeof(u_int16_t));
- } else {
- bcopy((void *)p1, (void *)p2,
- (vtb->vtb_size - at - count)*sizeof(u_int16_t));
- bcopy((void *)(p1 + attr_offset(vtb)),
- (void *)(p2 + attr_offset(vtb)),
- (vtb->vtb_size - at - count)*sizeof(u_int16_t));
- }
- }
- if (vtb->vtb_type == VTB_FRAMEBUFFER) {
- fillw_io(c, p1, count);
- fillw_io(at2pc98(attr), p1 + ATTR_OFFSET_FB, count);
- } else {
- fillw(c, (void *)p1, count);
- fillw(at2pc98(attr), (void *)(p1 + attr_offset(vtb)), count);
- }
-}
diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c
deleted file mode 100644
index 297f61d..0000000
--- a/sys/pc98/pc98/sio.c
+++ /dev/null
@@ -1,4413 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that 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.
- * 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.
- *
- * $FreeBSD$
- * from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * from: i386/isa sio.c,v 1.234
- */
-
-#include "opt_comconsole.h"
-#include "opt_compat.h"
-#include "opt_gdb.h"
-#include "opt_kdb.h"
-#include "opt_sio.h"
-
-/*
- * Serial driver, based on 386BSD-0.1 com driver.
- * Mostly rewritten to use pseudo-DMA.
- * Works for National Semiconductor NS8250-NS16550AF UARTs.
- * COM driver, based on HP dca driver.
- *
- * Changes for PC-Card integration:
- * - Added PC-Card driver table and handlers
- */
-/*===============================================================
- * 386BSD(98),FreeBSD-1.1x(98) com driver.
- * -----
- * modified for PC9801 by M.Ishii
- * Kyoto University Microcomputer Club (KMC)
- * Chou "TEFUTEFU" Hirotomi
- * Kyoto Univ. the faculty of medicine
- *===============================================================
- * FreeBSD-2.0.1(98) sio driver.
- * -----
- * modified for pc98 Internal i8251 and MICRO CORE MC16550II
- * T.Koike(hfc01340@niftyserve.or.jp)
- * implement kernel device configuration
- * aizu@orient.center.nitech.ac.jp
- *
- * Notes.
- * -----
- * PC98 localization based on 386BSD(98) com driver. Using its PC98 local
- * functions.
- * This driver is under debugging,has bugs.
- */
-/*
- * modified for AIWA B98-01
- * by T.Hatanou <hatanou@yasuda.comm.waseda.ac.jp> last update: 15 Sep.1995
- */
-/*
- * Modified by Y.Takahashi of Kogakuin University.
- */
-/*
- * modified for 8251(FIFO) by Seigo TANIMURA <tanimura@FreeBSD.org>
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/interrupt.h>
-#include <sys/kdb.h>
-#include <sys/kernel.h>
-#include <sys/limits.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/reboot.h>
-#include <sys/serial.h>
-#include <sys/sysctl.h>
-#include <sys/syslog.h>
-#include <sys/tty.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <sys/timepps.h>
-#include <sys/uio.h>
-#include <sys/cons.h>
-
-#include <isa/isavar.h>
-
-#include <machine/resource.h>
-
-#include <dev/sio/sioreg.h>
-#include <dev/sio/siovar.h>
-
-#ifdef PC98
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/pc98_machdep.h>
-#endif
-
-#ifdef COM_ESP
-#include <dev/ic/esp.h>
-#endif
-#include <dev/ic/ns16550.h>
-#ifdef PC98
-#include <dev/ic/i8251.h>
-#include <dev/ic/rsa.h>
-#endif
-
-#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
-
-/*
- * Meaning of flags:
- *
- * 0x00000001 shared IRQs
- * 0x00000002 disable FIFO
- * 0x00000008 recover sooner from lost output interrupts
- * 0x00000010 device is potential system console
- * 0x00000020 device is forced to become system console
- * 0x00000040 device is reserved for low-level IO
- * 0x00000080 use this port for remote kernel debugging
- * 0x0000??00 minor number of master port
- * 0x00010000 PPS timestamping on CTS instead of DCD
- * 0x00080000 IIR_TXRDY bug
- * 0x00400000 If no comconsole found then mark as a comconsole
- * 0x1?000000 interface type
- */
-
-#ifdef COM_MULTIPORT
-/* checks in flags for multiport and which is multiport "master chip"
- * for a given card
- */
-#define COM_ISMULTIPORT(flags) ((flags) & 0x01)
-#define COM_MPMASTER(flags) (((flags) >> 8) & 0x0ff)
-#ifndef PC98
-#define COM_NOTAST4(flags) ((flags) & 0x04)
-#endif
-#else
-#define COM_ISMULTIPORT(flags) (0)
-#endif /* COM_MULTIPORT */
-
-#define COM_C_IIR_TXRDYBUG 0x80000
-#define COM_CONSOLE(flags) ((flags) & 0x10)
-#define COM_DEBUGGER(flags) ((flags) & 0x80)
-#ifndef PC98
-#define COM_FIFOSIZE(flags) (((flags) & 0xff000000) >> 24)
-#endif
-#define COM_FORCECONSOLE(flags) ((flags) & 0x20)
-#define COM_IIR_TXRDYBUG(flags) ((flags) & COM_C_IIR_TXRDYBUG)
-#define COM_LLCONSOLE(flags) ((flags) & 0x40)
-#define COM_LOSESOUTINTS(flags) ((flags) & 0x08)
-#define COM_NOFIFO(flags) ((flags) & 0x02)
-#ifndef PC98
-#define COM_NOSCR(flags) ((flags) & 0x100000)
-#endif
-#define COM_PPSCTS(flags) ((flags) & 0x10000)
-#ifndef PC98
-#define COM_ST16650A(flags) ((flags) & 0x20000)
-#define COM_TI16754(flags) ((flags) & 0x200000)
-#endif
-
-#define sio_getreg(com, off) \
- (bus_space_read_1((com)->bst, (com)->bsh, (off)))
-#define sio_setreg(com, off, value) \
- (bus_space_write_1((com)->bst, (com)->bsh, (off), (value)))
-
-/*
- * com state bits.
- * (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher
- * than the other bits so that they can be tested as a group without masking
- * off the low bits.
- *
- * The following com and tty flags correspond closely:
- * CS_BUSY = TS_BUSY (maintained by comstart(), siopoll() and
- * comstop())
- * CS_TTGO = ~TS_TTSTOP (maintained by comparam() and comstart())
- * CS_CTS_OFLOW = CCTS_OFLOW (maintained by comparam())
- * CS_RTS_IFLOW = CRTS_IFLOW (maintained by comparam())
- * TS_FLUSH is not used.
- * XXX I think TIOCSETA doesn't clear TS_TTSTOP when it clears IXON.
- * XXX CS_*FLOW should be CF_*FLOW in com->flags (control flags not state).
- */
-#define CS_BUSY 0x80 /* output in progress */
-#define CS_TTGO 0x40 /* output not stopped by XOFF */
-#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
-#define CS_CHECKMSR 1 /* check of MSR scheduled */
-#define CS_CTS_OFLOW 2 /* use CTS output flow control */
-#define CS_ODONE 4 /* output completed */
-#define CS_RTS_IFLOW 8 /* use RTS input flow control */
-#define CSE_BUSYCHECK 1 /* siobusycheck() scheduled */
-
-static char const * const error_desc[] = {
-#define CE_OVERRUN 0
- "silo overflow",
-#define CE_INTERRUPT_BUF_OVERFLOW 1
- "interrupt-level buffer overflow",
-#define CE_TTY_BUF_OVERFLOW 2
- "tty-level buffer overflow",
-};
-
-#define CE_NTYPES 3
-#define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum])
-
-/* types. XXX - should be elsewhere */
-typedef u_int Port_t; /* hardware port */
-typedef u_char bool_t; /* boolean */
-
-/* queue of linear buffers */
-struct lbq {
- u_char *l_head; /* next char to process */
- u_char *l_tail; /* one past the last char to process */
- struct lbq *l_next; /* next in queue */
- bool_t l_queued; /* nonzero if queued */
-};
-
-/* com device structure */
-struct com_s {
- u_char state; /* miscellaneous flag bits */
- u_char cfcr_image; /* copy of value written to CFCR */
-#ifdef COM_ESP
- bool_t esp; /* is this unit a hayes esp board? */
-#endif
- u_char extra_state; /* more flag bits, separate for order trick */
- u_char fifo_image; /* copy of value written to FIFO */
- bool_t hasfifo; /* nonzero for 16550 UARTs */
- bool_t loses_outints; /* nonzero if device loses output interrupts */
- u_char mcr_image; /* copy of value written to MCR */
-#ifdef COM_MULTIPORT
- bool_t multiport; /* is this unit part of a multiport device? */
-#endif /* COM_MULTIPORT */
- bool_t no_irq; /* nonzero if irq is not attached */
- bool_t gone; /* hardware disappeared */
- bool_t poll; /* nonzero if polling is required */
- bool_t poll_output; /* nonzero if polling for output is required */
- bool_t st16650a; /* nonzero if Startech 16650A compatible */
- int unit; /* unit number */
- u_int flags; /* copy of device flags */
- u_int tx_fifo_size;
-
- /*
- * The high level of the driver never reads status registers directly
- * because there would be too many side effects to handle conveniently.
- * Instead, it reads copies of the registers stored here by the
- * interrupt handler.
- */
- u_char last_modem_status; /* last MSR read by intr handler */
- u_char prev_modem_status; /* last MSR handled by high level */
-
- u_char *ibuf; /* start of input buffer */
- u_char *ibufend; /* end of input buffer */
- u_char *ibufold; /* old input buffer, to be freed */
- u_char *ihighwater; /* threshold in input buffer */
- u_char *iptr; /* next free spot in input buffer */
- int ibufsize; /* size of ibuf (not include error bytes) */
- int ierroff; /* offset of error bytes in ibuf */
-
- struct lbq obufq; /* head of queue of output buffers */
- struct lbq obufs[2]; /* output buffers */
-
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
-
-#ifdef PC98
- Port_t cmd_port;
- Port_t sts_port;
- Port_t in_modem_port;
- Port_t intr_ctrl_port;
- Port_t rsabase; /* Iobase address of an I/O-DATA RSA board. */
- int intr_enable;
- int pc98_prev_modem_status;
- int pc98_modem_delta;
- int modem_car_chg_timer;
- int pc98_prev_siocmd;
- int pc98_prev_siomod;
- int modem_checking;
- int pc98_if_type;
-
- bool_t pc98_8251fifo;
- bool_t pc98_8251fifo_enable;
-#endif /* PC98 */
- Port_t data_port; /* i/o ports */
-#ifdef COM_ESP
- Port_t esp_port;
-#endif
- Port_t int_ctl_port;
- Port_t int_id_port;
- Port_t modem_ctl_port;
- Port_t line_status_port;
- Port_t modem_status_port;
-
- struct tty *tp; /* cross reference */
-
- struct pps_state pps;
- int pps_bit;
-#ifdef ALT_BREAK_TO_DEBUGGER
- int alt_brk_state;
-#endif
-
- u_long bytes_in; /* statistics */
- u_long bytes_out;
- u_int delta_error_counts[CE_NTYPES];
- u_long error_counts[CE_NTYPES];
-
- u_long rclk;
-
- struct resource *irqres;
- struct resource *ioportres;
- int ioportrid;
- void *cookie;
-
- /*
- * Data area for output buffers. Someday we should build the output
- * buffer queue without copying data.
- */
-#ifdef PC98
- int obufsize;
- u_char *obuf1;
- u_char *obuf2;
-#else
- u_char obuf1[256];
- u_char obuf2[256];
-#endif
-};
-
-#ifdef COM_ESP
-static int espattach(struct com_s *com, Port_t esp_port);
-#endif
-
-static void combreak(struct tty *tp, int sig);
-static timeout_t siobusycheck;
-static u_int siodivisor(u_long rclk, speed_t speed);
-static void comclose(struct tty *tp);
-static int comopen(struct tty *tp, struct cdev *dev);
-static void sioinput(struct com_s *com);
-static void siointr1(struct com_s *com);
-static void siointr(void *arg);
-static int commodem(struct tty *tp, int sigon, int sigoff);
-static int comparam(struct tty *tp, struct termios *t);
-static void siopoll(void *);
-static void siosettimeout(void);
-static int siosetwater(struct com_s *com, speed_t speed);
-static void comstart(struct tty *tp);
-static void comstop(struct tty *tp, int rw);
-static timeout_t comwakeup;
-
-char sio_driver_name[] = "sio";
-static struct mtx sio_lock;
-static int sio_inited;
-
-/* table and macro for fast conversion from a unit number to its com struct */
-devclass_t sio_devclass;
-#define com_addr(unit) ((struct com_s *) \
- devclass_get_softc(sio_devclass, unit)) /* XXX */
-
-int comconsole = -1;
-static volatile speed_t comdefaultrate = CONSPEED;
-static u_long comdefaultrclk = DEFAULT_RCLK;
-SYSCTL_ULONG(_machdep, OID_AUTO, conrclk, CTLFLAG_RW, &comdefaultrclk, 0, "");
-static speed_t gdbdefaultrate = GDBSPEED;
-SYSCTL_UINT(_machdep, OID_AUTO, gdbspeed, CTLFLAG_RW,
- &gdbdefaultrate, GDBSPEED, "");
-static u_int com_events; /* input chars + weighted output completions */
-static Port_t siocniobase;
-static int siocnunit = -1;
-static void *sio_slow_ih;
-static void *sio_fast_ih;
-static int sio_timeout;
-static int sio_timeouts_until_log;
-static struct callout_handle sio_timeout_handle
- = CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle);
-static int sio_numunits;
-
-#ifdef PC98
-struct siodev {
- short if_type;
- short irq;
- Port_t cmd, sts, ctrl, mod;
-};
-static int sysclock;
-
-#define COM_INT_DISABLE {int previpri; previpri=spltty();
-#define COM_INT_ENABLE splx(previpri);}
-#define IEN_TxFLAG IEN_Tx
-
-#define COM_CARRIER_DETECT_EMULATE 0
-#define PC98_CHECK_MODEM_INTERVAL (hz/10)
-#define DCD_OFF_TOLERANCE 2
-#define DCD_ON_RECOGNITION 2
-#define IS_8251(if_type) (!(if_type & 0x10))
-#define COM1_EXT_CLOCK 0x40000
-
-static void commint(struct cdev *dev);
-static void com_tiocm_bis(struct com_s *com, int msr);
-static void com_tiocm_bic(struct com_s *com, int msr);
-static int com_tiocm_get(struct com_s *com);
-static int com_tiocm_get_delta(struct com_s *com);
-static void pc98_msrint_start(struct cdev *dev);
-static void com_cflag_and_speed_set(struct com_s *com, int cflag, int speed);
-static int pc98_ttspeedtab(struct com_s *com, int speed, u_int *divisor);
-static int pc98_get_modem_status(struct com_s *com);
-static timeout_t pc98_check_msr;
-static void pc98_set_baud_rate(struct com_s *com, u_int count);
-static void pc98_i8251_reset(struct com_s *com, int mode, int command);
-static void pc98_disable_i8251_interrupt(struct com_s *com, int mod);
-static void pc98_enable_i8251_interrupt(struct com_s *com, int mod);
-static int pc98_check_i8251_interrupt(struct com_s *com);
-static int pc98_i8251_get_cmd(struct com_s *com);
-static int pc98_i8251_get_mod(struct com_s *com);
-static void pc98_i8251_set_cmd(struct com_s *com, int x);
-static void pc98_i8251_or_cmd(struct com_s *com, int x);
-static void pc98_i8251_clear_cmd(struct com_s *com, int x);
-static void pc98_i8251_clear_or_cmd(struct com_s *com, int clr, int x);
-static int pc98_check_if_type(device_t dev, struct siodev *iod);
-static int pc98_check_8251vfast(void);
-static int pc98_check_8251fifo(void);
-static void pc98_check_sysclock(void);
-static void pc98_set_ioport(struct com_s *com);
-
-#define com_int_Tx_disable(com) \
- pc98_disable_i8251_interrupt(com,IEN_Tx|IEN_TxEMP)
-#define com_int_Tx_enable(com) \
- pc98_enable_i8251_interrupt(com,IEN_TxFLAG)
-#define com_int_Rx_disable(com) \
- pc98_disable_i8251_interrupt(com,IEN_Rx)
-#define com_int_Rx_enable(com) \
- pc98_enable_i8251_interrupt(com,IEN_Rx)
-#define com_int_TxRx_disable(com) \
- pc98_disable_i8251_interrupt(com,IEN_Tx|IEN_TxEMP|IEN_Rx)
-#define com_int_TxRx_enable(com) \
- pc98_enable_i8251_interrupt(com,IEN_TxFLAG|IEN_Rx)
-#define com_send_break_on(com) \
- (IS_8251((com)->pc98_if_type) ? \
- pc98_i8251_or_cmd((com), CMD8251_SBRK) : \
- sio_setreg((com), com_cfcr, (com)->cfcr_image |= CFCR_SBREAK))
-#define com_send_break_off(com) \
- (IS_8251((com)->pc98_if_type) ? \
- pc98_i8251_clear_cmd((com), CMD8251_SBRK) : \
- sio_setreg((com), com_cfcr, (com)->cfcr_image &= ~CFCR_SBREAK))
-
-static struct speedtab pc98speedtab[] = { /* internal RS232C interface */
- { 0, 0, },
- { 50, 50, },
- { 75, 75, },
- { 150, 150, },
- { 200, 200, },
- { 300, 300, },
- { 600, 600, },
- { 1200, 1200, },
- { 2400, 2400, },
- { 4800, 4800, },
- { 9600, 9600, },
- { 19200, 19200, },
- { 38400, 38400, },
- { 51200, 51200, },
- { 76800, 76800, },
- { 20800, 20800, },
- { 31200, 31200, },
- { 41600, 41600, },
- { 62400, 62400, },
- { -1, -1 }
-};
-static struct speedtab pc98fast_speedtab[] = {
- { 9600, 0x80 | (DEFAULT_RCLK / (16 * (9600))), },
- { 19200, 0x80 | (DEFAULT_RCLK / (16 * (19200))), },
- { 38400, 0x80 | (DEFAULT_RCLK / (16 * (38400))), },
- { 57600, 0x80 | (DEFAULT_RCLK / (16 * (57600))), },
- { 115200, 0x80 | (DEFAULT_RCLK / (16 * (115200))), },
- { -1, -1 }
-};
-static struct speedtab comspeedtab_pio9032b[] = {
- { 300, 6, },
- { 600, 5, },
- { 1200, 4, },
- { 2400, 3, },
- { 4800, 2, },
- { 9600, 1, },
- { 19200, 0, },
- { 38400, 7, },
- { -1, -1 }
-};
-static struct speedtab comspeedtab_b98_01[] = {
- { 75, 11, },
- { 150, 10, },
- { 300, 9, },
- { 600, 8, },
- { 1200, 7, },
- { 2400, 6, },
- { 4800, 5, },
- { 9600, 4, },
- { 19200, 3, },
- { 38400, 2, },
- { 76800, 1, },
- { 153600, 0, },
- { -1, -1 }
-};
-static struct speedtab comspeedtab_ind[] = {
- { 300, 1536, },
- { 600, 768, },
- { 1200, 384, },
- { 2400, 192, },
- { 4800, 96, },
- { 9600, 48, },
- { 19200, 24, },
- { 38400, 12, },
- { 57600, 8, },
- { 115200, 4, },
- { 153600, 3, },
- { 230400, 2, },
- { 460800, 1, },
- { -1, -1 }
-};
-
-struct {
- char *name;
- short port_table[7];
- short irr_mask;
- struct speedtab *speedtab;
- short check_irq;
-} if_8251_type[] = {
- /* COM_IF_INTERNAL */
- { " (internal)", {0x30, 0x32, 0x32, 0x33, 0x35, -1, -1},
- -1, pc98speedtab, 1 },
- /* COM_IF_PC9861K_1 */
- { " (PC9861K)", {0xb1, 0xb3, 0xb3, 0xb0, 0xb0, -1, -1},
- 3, NULL, 1 },
- /* COM_IF_PC9861K_2 */
- { " (PC9861K)", {0xb9, 0xbb, 0xbb, 0xb2, 0xb2, -1, -1},
- 3, NULL, 1 },
- /* COM_IF_IND_SS_1 */
- { " (IND-SS)", {0xb1, 0xb3, 0xb3, 0xb0, 0xb0, 0xb3, -1},
- 3, comspeedtab_ind, 1 },
- /* COM_IF_IND_SS_2 */
- { " (IND-SS)", {0xb9, 0xbb, 0xbb, 0xb2, 0xb2, 0xbb, -1},
- 3, comspeedtab_ind, 1 },
- /* COM_IF_PIO9032B_1 */
- { " (PIO9032B)", {0xb1, 0xb3, 0xb3, 0xb0, 0xb0, 0xb8, -1},
- 7, comspeedtab_pio9032b, 1 },
- /* COM_IF_PIO9032B_2 */
- { " (PIO9032B)", {0xb9, 0xbb, 0xbb, 0xb2, 0xb2, 0xba, -1},
- 7, comspeedtab_pio9032b, 1 },
- /* COM_IF_B98_01_1 */
- { " (B98-01)", {0xb1, 0xb3, 0xb3, 0xb0, 0xb0, 0xd1, 0xd3},
- 7, comspeedtab_b98_01, 0 },
- /* COM_IF_B98_01_2 */
- { " (B98-01)", {0xb9, 0xbb, 0xbb, 0xb2, 0xb2, 0xd5, 0xd7},
- 7, comspeedtab_b98_01, 0 },
-};
-#define PC98SIO_data_port(type) (if_8251_type[type].port_table[0])
-#define PC98SIO_cmd_port(type) (if_8251_type[type].port_table[1])
-#define PC98SIO_sts_port(type) (if_8251_type[type].port_table[2])
-#define PC98SIO_in_modem_port(type) (if_8251_type[type].port_table[3])
-#define PC98SIO_intr_ctrl_port(type) (if_8251_type[type].port_table[4])
-#define PC98SIO_baud_rate_port(type) (if_8251_type[type].port_table[5])
-#define PC98SIO_func_port(type) (if_8251_type[type].port_table[6])
-
-#define I8251F_data 0x130
-#define I8251F_lsr 0x132
-#define I8251F_msr 0x134
-#define I8251F_iir 0x136
-#define I8251F_fcr 0x138
-#define I8251F_div 0x13a
-
-
-static bus_addr_t port_table_0[] =
- {0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007};
-static bus_addr_t port_table_1[] =
- {0x000, 0x002, 0x004, 0x006, 0x008, 0x00a, 0x00c, 0x00e};
-static bus_addr_t port_table_8[] =
- {0x000, 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700};
-static bus_addr_t port_table_rsa[] = {
- 0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
- 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007
-};
-
-struct {
- char *name;
- short irr_read;
- short irr_write;
- bus_addr_t *iat;
- bus_size_t iatsz;
- u_long rclk;
-} if_16550a_type[] = {
- /* COM_IF_RSA98 */
- {" (RSA-98)", -1, -1, port_table_0, IO_COMSIZE, DEFAULT_RCLK},
- /* COM_IF_NS16550 */
- {"", -1, -1, port_table_0, IO_COMSIZE, DEFAULT_RCLK},
- /* COM_IF_SECOND_CCU */
- {"", -1, -1, port_table_0, IO_COMSIZE, DEFAULT_RCLK},
- /* COM_IF_MC16550II */
- {" (MC16550II)", -1, 0x1000, port_table_8, IO_COMSIZE,
- DEFAULT_RCLK * 4},
- /* COM_IF_MCRS98 */
- {" (MC-RS98)", -1, 0x1000, port_table_8, IO_COMSIZE, DEFAULT_RCLK * 4},
- /* COM_IF_RSB3000 */
- {" (RSB-3000)", 0xbf, -1, port_table_1, IO_COMSIZE, DEFAULT_RCLK * 10},
- /* COM_IF_RSB384 */
- {" (RSB-384)", 0xbf, -1, port_table_1, IO_COMSIZE, DEFAULT_RCLK * 10},
- /* COM_IF_MODEM_CARD */
- {"", -1, -1, port_table_0, IO_COMSIZE, DEFAULT_RCLK},
- /* COM_IF_RSA98III */
- {" (RSA-98III)", -1, -1, port_table_rsa, 16, DEFAULT_RCLK * 8},
- /* COM_IF_ESP98 */
- {" (ESP98)", -1, -1, port_table_1, IO_COMSIZE, DEFAULT_RCLK * 4},
-};
-#endif /* PC98 */
-
-#ifdef GDB
-static Port_t siogdbiobase = 0;
-#endif
-
-#ifdef COM_ESP
-#ifdef PC98
-
-/* XXX configure this properly. */
-/* XXX quite broken for new-bus. */
-static Port_t likely_com_ports[] = { 0, 0xb0, 0xb1, 0 };
-static Port_t likely_esp_ports[] = { 0xc0d0, 0 };
-
-#define ESP98_CMD1 (ESP_CMD1 * 0x100)
-#define ESP98_CMD2 (ESP_CMD2 * 0x100)
-#define ESP98_STATUS1 (ESP_STATUS1 * 0x100)
-#define ESP98_STATUS2 (ESP_STATUS2 * 0x100)
-
-#else /* PC98 */
-
-/* XXX configure this properly. */
-static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
-static Port_t likely_esp_ports[] = { 0x140, 0x180, 0x280, 0 };
-
-#endif /* PC98 */
-#endif
-
-/*
- * handle sysctl read/write requests for console speed
- *
- * In addition to setting comdefaultrate for I/O through /dev/console,
- * also set the initial and lock values for the /dev/ttyXX device
- * if there is one associated with the console. Finally, if the /dev/tty
- * device has already been open, change the speed on the open running port
- * itself.
- */
-
-static int
-sysctl_machdep_comdefaultrate(SYSCTL_HANDLER_ARGS)
-{
- int error, s;
- speed_t newspeed;
- struct com_s *com;
- struct tty *tp;
-
- newspeed = comdefaultrate;
-
- error = sysctl_handle_opaque(oidp, &newspeed, sizeof newspeed, req);
- if (error || !req->newptr)
- return (error);
-
- comdefaultrate = newspeed;
-
- if (comconsole < 0) /* serial console not selected? */
- return (0);
-
- com = com_addr(comconsole);
- if (com == NULL)
- return (ENXIO);
-
- tp = com->tp;
- if (tp == NULL)
- return (ENXIO);
-
- /*
- * set the initial and lock rates for /dev/ttydXX and /dev/cuaXX
- * (note, the lock rates really are boolean -- if non-zero, disallow
- * speed changes)
- */
- tp->t_init_in.c_ispeed = tp->t_init_in.c_ospeed =
- tp->t_lock_in.c_ispeed = tp->t_lock_in.c_ospeed =
- tp->t_init_out.c_ispeed = tp->t_init_out.c_ospeed =
- tp->t_lock_out.c_ispeed = tp->t_lock_out.c_ospeed = comdefaultrate;
-
- if (tp->t_state & TS_ISOPEN) {
- tp->t_termios.c_ispeed =
- tp->t_termios.c_ospeed = comdefaultrate;
- s = spltty();
- error = comparam(tp, &tp->t_termios);
- splx(s);
- }
- return error;
-}
-
-SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW,
- 0, 0, sysctl_machdep_comdefaultrate, "I", "");
-
-/*
- * Unload the driver and clear the table.
- * XXX this is mostly wrong.
- * XXX TODO:
- * This is usually called when the card is ejected, but
- * can be caused by a kldunload of a controller driver.
- * The idea is to reset the driver's view of the device
- * and ensure that any driver entry points such as
- * read and write do not hang.
- */
-int
-siodetach(device_t dev)
-{
- struct com_s *com;
-
- com = (struct com_s *) device_get_softc(dev);
- if (com == NULL) {
- device_printf(dev, "NULL com in siounload\n");
- return (0);
- }
- com->gone = TRUE;
- if (com->tp)
- ttyfree(com->tp);
- if (com->irqres) {
- bus_teardown_intr(dev, com->irqres, com->cookie);
- bus_release_resource(dev, SYS_RES_IRQ, 0, com->irqres);
- }
- if (com->ioportres)
- bus_release_resource(dev, SYS_RES_IOPORT, com->ioportrid,
- com->ioportres);
- if (com->ibuf != NULL)
- free(com->ibuf, M_DEVBUF);
-#ifdef PC98
- if (com->obuf1 != NULL)
- free(com->obuf1, M_DEVBUF);
-#endif
-
- device_set_softc(dev, NULL);
- free(com, M_DEVBUF);
- return (0);
-}
-
-int
-sioprobe(dev, xrid, rclk, noprobe)
- device_t dev;
- int xrid;
- u_long rclk;
- int noprobe;
-{
-#if 0
- static bool_t already_init;
- device_t xdev;
-#endif
- struct com_s *com;
- u_int divisor;
- bool_t failures[10];
- int fn;
- device_t idev;
- Port_t iobase;
- intrmask_t irqmap[4];
- intrmask_t irqs;
- u_char mcr_image;
- int result;
- u_long xirq;
- u_int flags = device_get_flags(dev);
- int rid;
- struct resource *port;
-#ifdef PC98
- int tmp;
- struct siodev iod;
-#endif
-
-#ifdef PC98
- iod.if_type = GET_IFTYPE(flags);
- if ((iod.if_type < 0 || iod.if_type > COM_IF_END1) &&
- (iod.if_type < 0x10 || iod.if_type > COM_IF_END2))
- return ENXIO;
-#endif
-
- rid = xrid;
-#ifdef PC98
- if (IS_8251(iod.if_type)) {
- port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
- RF_ACTIVE);
- } else if (iod.if_type == COM_IF_MODEM_CARD ||
- iod.if_type == COM_IF_RSA98III ||
- isa_get_vendorid(dev)) {
- port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
- if_16550a_type[iod.if_type & 0x0f].iatsz, RF_ACTIVE);
- } else {
- port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
- if_16550a_type[iod.if_type & 0x0f].iat,
- if_16550a_type[iod.if_type & 0x0f].iatsz, RF_ACTIVE);
- }
-#else
- port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
- 0, ~0, IO_COMSIZE, RF_ACTIVE);
-#endif
- if (!port)
- return (ENXIO);
-#ifdef PC98
- if (!IS_8251(iod.if_type)) {
- if (isa_load_resourcev(port,
- if_16550a_type[iod.if_type & 0x0f].iat,
- if_16550a_type[iod.if_type & 0x0f].iatsz) != 0) {
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- return ENXIO;
- }
- }
-#endif
-
- com = malloc(sizeof(*com), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (com == NULL) {
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- return (ENOMEM);
- }
- device_set_softc(dev, com);
- com->bst = rman_get_bustag(port);
- com->bsh = rman_get_bushandle(port);
-#ifdef PC98
- if (!IS_8251(iod.if_type) && rclk == 0)
- rclk = if_16550a_type[iod.if_type & 0x0f].rclk;
-#else
- if (rclk == 0)
- rclk = DEFAULT_RCLK;
-#endif
- com->rclk = rclk;
-
- while (sio_inited != 2)
- if (atomic_cmpset_int(&sio_inited, 0, 1)) {
- mtx_init(&sio_lock, sio_driver_name, NULL,
- (comconsole != -1) ?
- MTX_SPIN | MTX_QUIET : MTX_SPIN);
- atomic_store_rel_int(&sio_inited, 2);
- }
-
-#if 0
- /*
- * XXX this is broken - when we are first called, there are no
- * previously configured IO ports. We could hard code
- * 0x3f8, 0x2f8, 0x3e8, 0x2e8 etc but that's probably worse.
- * This code has been doing nothing since the conversion since
- * "count" is zero the first time around.
- */
- if (!already_init) {
- /*
- * Turn off MCR_IENABLE for all likely serial ports. An unused
- * port with its MCR_IENABLE gate open will inhibit interrupts
- * from any used port that shares the interrupt vector.
- * XXX the gate enable is elsewhere for some multiports.
- */
- device_t *devs;
- int count, i, xioport;
-#ifdef PC98
- int xiftype;
-#endif
-
- devclass_get_devices(sio_devclass, &devs, &count);
-#ifdef PC98
- for (i = 0; i < count; i++) {
- xdev = devs[i];
- xioport = bus_get_resource_start(xdev, SYS_RES_IOPORT, 0);
- xiftype = GET_IFTYPE(device_get_flags(xdev));
- if (device_is_enabled(xdev) && xioport > 0) {
- if (IS_8251(xiftype))
- outb((xioport & 0xff00) | PC98SIO_cmd_port(xiftype & 0x0f), 0xf2);
- else
- outb(xioport + if_16550a_type[xiftype & 0x0f].iat[com_mcr], 0);
- }
- }
-#else
- for (i = 0; i < count; i++) {
- xdev = devs[i];
- if (device_is_enabled(xdev) &&
- bus_get_resource(xdev, SYS_RES_IOPORT, 0, &xioport,
- NULL) == 0)
- outb(xioport + com_mcr, 0);
- }
-#endif
- free(devs, M_TEMP);
- already_init = TRUE;
- }
-#endif
-
- if (COM_LLCONSOLE(flags)) {
- printf("sio%d: reserved for low-level i/o\n",
- device_get_unit(dev));
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- device_set_softc(dev, NULL);
- free(com, M_DEVBUF);
- return (ENXIO);
- }
-
-#ifdef PC98
- DELAY(10);
-
- /*
- * If the port is i8251 UART (internal, B98_01)
- */
- if (pc98_check_if_type(dev, &iod) == -1) {
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- device_set_softc(dev, NULL);
- free(com, M_DEVBUF);
- return (ENXIO);
- }
- if (iod.irq > 0)
- bus_set_resource(dev, SYS_RES_IRQ, 0, iod.irq, 1);
- if (IS_8251(iod.if_type)) {
- outb(iod.cmd, 0);
- DELAY(10);
- outb(iod.cmd, 0);
- DELAY(10);
- outb(iod.cmd, 0);
- DELAY(10);
- outb(iod.cmd, CMD8251_RESET);
- DELAY(1000); /* for a while...*/
- outb(iod.cmd, 0xf2); /* MODE (dummy) */
- DELAY(10);
- outb(iod.cmd, 0x01); /* CMD (dummy) */
- DELAY(1000); /* for a while...*/
- if (( inb(iod.sts) & STS8251_TxEMP ) == 0 ) {
- result = (ENXIO);
- }
- if (if_8251_type[iod.if_type & 0x0f].check_irq) {
- COM_INT_DISABLE
- tmp = ( inb( iod.ctrl ) & ~(IEN_Rx|IEN_TxEMP|IEN_Tx));
- outb( iod.ctrl, tmp|IEN_TxEMP );
- DELAY(10);
- result = isa_irq_pending() ? 0 : ENXIO;
- outb( iod.ctrl, tmp );
- COM_INT_ENABLE
- } else {
- /*
- * B98_01 doesn't activate TxEMP interrupt line
- * when being reset, so we can't check irq pending.
- */
- result = 0;
- }
- if (epson_machine_id==0x20) { /* XXX */
- result = 0;
- }
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- if (result) {
- device_set_softc(dev, NULL);
- free(com, M_DEVBUF);
- }
- return result;
- }
-#endif /* PC98 */
- /*
- * If the device is on a multiport card and has an AST/4
- * compatible interrupt control register, initialize this
- * register and prepare to leave MCR_IENABLE clear in the mcr.
- * Otherwise, prepare to set MCR_IENABLE in the mcr.
- * Point idev to the device struct giving the correct id_irq.
- * This is the struct for the master device if there is one.
- */
- idev = dev;
- mcr_image = MCR_IENABLE;
-#ifdef COM_MULTIPORT
- if (COM_ISMULTIPORT(flags)) {
-#ifndef PC98
- Port_t xiobase;
- u_long io;
-#endif
-
- idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags));
- if (idev == NULL) {
- printf("sio%d: master device %d not configured\n",
- device_get_unit(dev), COM_MPMASTER(flags));
- idev = dev;
- }
-#ifndef PC98
- if (!COM_NOTAST4(flags)) {
- if (bus_get_resource(idev, SYS_RES_IOPORT, 0, &io,
- NULL) == 0) {
- xiobase = io;
- if (bus_get_resource(idev, SYS_RES_IRQ, 0,
- NULL, NULL) == 0)
- outb(xiobase + com_scr, 0x80);
- else
- outb(xiobase + com_scr, 0);
- }
- mcr_image = 0;
- }
-#endif
- }
-#endif /* COM_MULTIPORT */
- if (bus_get_resource(idev, SYS_RES_IRQ, 0, NULL, NULL) != 0)
- mcr_image = 0;
-
- bzero(failures, sizeof failures);
- iobase = rman_get_start(port);
-
-#ifdef PC98
- if (iod.if_type == COM_IF_RSA98III) {
- mcr_image = 0;
-
- outb(iobase + rsa_msr, 0x04);
- outb(iobase + rsa_frr, 0x00);
- if ((inb(iobase + rsa_srr) & 0x36) != 0x36) {
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- device_set_softc(dev, NULL);
- free(com, M_DEVBUF);
- return (ENXIO);
- }
- outb(iobase + rsa_ier, 0x00);
- outb(iobase + rsa_frr, 0x00);
- outb(iobase + rsa_tivsr, 0x00);
- outb(iobase + rsa_tcr, 0x00);
- }
-
- tmp = if_16550a_type[iod.if_type & 0x0f].irr_write;
- if (tmp != -1) {
- /* MC16550II */
- int irqout;
- switch (isa_get_irq(idev)) {
- case 3: irqout = 4; break;
- case 5: irqout = 5; break;
- case 6: irqout = 6; break;
- case 12: irqout = 7; break;
- default:
- printf("sio%d: irq configuration error\n",
- device_get_unit(dev));
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- device_set_softc(dev, NULL);
- free(com, M_DEVBUF);
- return (ENXIO);
- }
- outb((iobase & 0x00ff) | tmp, irqout);
- }
-#endif
-
- /*
- * We don't want to get actual interrupts, just masked ones.
- * Interrupts from this line should already be masked in the ICU,
- * but mask them in the processor as well in case there are some
- * (misconfigured) shared interrupts.
- */
- mtx_lock_spin(&sio_lock);
-/* EXTRA DELAY? */
-
- /*
- * Initialize the speed and the word size and wait long enough to
- * drain the maximum of 16 bytes of junk in device output queues.
- * The speed is undefined after a master reset and must be set
- * before relying on anything related to output. There may be
- * junk after a (very fast) soft reboot and (apparently) after
- * master reset.
- * XXX what about the UART bug avoided by waiting in comparam()?
- * We don't want to to wait long enough to drain at 2 bps.
- */
- if (iobase == siocniobase)
- DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
- else {
- sio_setreg(com, com_cfcr, CFCR_DLAB | CFCR_8BITS);
- divisor = siodivisor(rclk, SIO_TEST_SPEED);
- sio_setreg(com, com_dlbl, divisor & 0xff);
- sio_setreg(com, com_dlbh, divisor >> 8);
- sio_setreg(com, com_cfcr, CFCR_8BITS);
- DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
- }
-
- /*
- * Enable the interrupt gate and disable device interupts. This
- * should leave the device driving the interrupt line low and
- * guarantee an edge trigger if an interrupt can be generated.
- */
-/* EXTRA DELAY? */
- sio_setreg(com, com_mcr, mcr_image);
- sio_setreg(com, com_ier, 0);
- DELAY(1000); /* XXX */
- irqmap[0] = isa_irq_pending();
-
- /*
- * Attempt to set loopback mode so that we can send a null byte
- * without annoying any external device.
- */
-/* EXTRA DELAY? */
- sio_setreg(com, com_mcr, mcr_image | MCR_LOOPBACK);
-
- /*
- * Attempt to generate an output interrupt. On 8250's, setting
- * IER_ETXRDY generates an interrupt independent of the current
- * setting and independent of whether the THR is empty. On 16450's,
- * setting IER_ETXRDY generates an interrupt independent of the
- * current setting. On 16550A's, setting IER_ETXRDY only
- * generates an interrupt when IER_ETXRDY is not already set.
- */
- sio_setreg(com, com_ier, IER_ETXRDY);
-#ifdef PC98
- if (iod.if_type == COM_IF_RSA98III)
- outb(iobase + rsa_ier, 0x04);
-#endif
-
- /*
- * On some 16x50 incompatibles, setting IER_ETXRDY doesn't generate
- * an interrupt. They'd better generate one for actually doing
- * output. Loopback may be broken on the same incompatibles but
- * it's unlikely to do more than allow the null byte out.
- */
- sio_setreg(com, com_data, 0);
- if (iobase == siocniobase)
- DELAY((1 + 2) * 1000000 / (comdefaultrate / 10));
- else
- DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10));
-
- /*
- * Turn off loopback mode so that the interrupt gate works again
- * (MCR_IENABLE was hidden). This should leave the device driving
- * an interrupt line high. It doesn't matter if the interrupt
- * line oscillates while we are not looking at it, since interrupts
- * are disabled.
- */
-/* EXTRA DELAY? */
- sio_setreg(com, com_mcr, mcr_image);
-
- /*
- * It seems my Xircom CBEM56G Cardbus modem wants to be reset
- * to 8 bits *again*, or else probe test 0 will fail.
- * gwk@sgi.com, 4/19/2001
- */
- sio_setreg(com, com_cfcr, CFCR_8BITS);
-
- /*
- * Some PCMCIA cards (Palido 321s, DC-1S, ...) have the "TXRDY bug",
- * so we probe for a buggy IIR_TXRDY implementation even in the
- * noprobe case. We don't probe for it in the !noprobe case because
- * noprobe is always set for PCMCIA cards and the problem is not
- * known to affect any other cards.
- */
- if (noprobe) {
- /* Read IIR a few times. */
- for (fn = 0; fn < 2; fn ++) {
- DELAY(10000);
- failures[6] = sio_getreg(com, com_iir);
- }
-
- /* IIR_TXRDY should be clear. Is it? */
- result = 0;
- if (failures[6] & IIR_TXRDY) {
- /*
- * No. We seem to have the bug. Does our fix for
- * it work?
- */
- sio_setreg(com, com_ier, 0);
- if (sio_getreg(com, com_iir) & IIR_NOPEND) {
- /* Yes. We discovered the TXRDY bug! */
- SET_FLAG(dev, COM_C_IIR_TXRDYBUG);
- } else {
- /* No. Just fail. XXX */
- result = ENXIO;
- sio_setreg(com, com_mcr, 0);
- }
- } else {
- /* Yes. No bug. */
- CLR_FLAG(dev, COM_C_IIR_TXRDYBUG);
- }
- sio_setreg(com, com_ier, 0);
- sio_setreg(com, com_cfcr, CFCR_8BITS);
- mtx_unlock_spin(&sio_lock);
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- if (iobase == siocniobase)
- result = 0;
- if (result != 0) {
- device_set_softc(dev, NULL);
- free(com, M_DEVBUF);
- }
- return (result);
- }
-
- /*
- * Check that
- * o the CFCR, IER and MCR in UART hold the values written to them
- * (the values happen to be all distinct - this is good for
- * avoiding false positive tests from bus echoes).
- * o an output interrupt is generated and its vector is correct.
- * o the interrupt goes away when the IIR in the UART is read.
- */
-/* EXTRA DELAY? */
- failures[0] = sio_getreg(com, com_cfcr) - CFCR_8BITS;
- failures[1] = sio_getreg(com, com_ier) - IER_ETXRDY;
- failures[2] = sio_getreg(com, com_mcr) - mcr_image;
- DELAY(10000); /* Some internal modems need this time */
- irqmap[1] = isa_irq_pending();
- failures[4] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_TXRDY;
-#ifdef PC98
- if (iod.if_type == COM_IF_RSA98III)
- inb(iobase + rsa_srr);
-#endif
- DELAY(1000); /* XXX */
- irqmap[2] = isa_irq_pending();
- failures[6] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND;
-#ifdef PC98
- if (iod.if_type == COM_IF_RSA98III)
- inb(iobase + rsa_srr);
-#endif
-
- /*
- * Turn off all device interrupts and check that they go off properly.
- * Leave MCR_IENABLE alone. For ports without a master port, it gates
- * the OUT2 output of the UART to
- * the ICU input. Closing the gate would give a floating ICU input
- * (unless there is another device driving it) and spurious interrupts.
- * (On the system that this was first tested on, the input floats high
- * and gives a (masked) interrupt as soon as the gate is closed.)
- */
- sio_setreg(com, com_ier, 0);
- sio_setreg(com, com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */
- failures[7] = sio_getreg(com, com_ier);
-#ifdef PC98
- if (iod.if_type == COM_IF_RSA98III)
- outb(iobase + rsa_ier, 0x00);
-#endif
- DELAY(1000); /* XXX */
- irqmap[3] = isa_irq_pending();
- failures[9] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND;
-#ifdef PC98
- if (iod.if_type == COM_IF_RSA98III) {
- inb(iobase + rsa_srr);
- outb(iobase + rsa_frr, 0x00);
- }
-#endif
-
- mtx_unlock_spin(&sio_lock);
-
- irqs = irqmap[1] & ~irqmap[0];
- if (bus_get_resource(idev, SYS_RES_IRQ, 0, &xirq, NULL) == 0 &&
- ((1 << xirq) & irqs) == 0) {
- printf(
- "sio%d: configured irq %ld not in bitmap of probed irqs %#x\n",
- device_get_unit(dev), xirq, irqs);
- printf(
- "sio%d: port may not be enabled\n",
- device_get_unit(dev));
- }
- if (bootverbose)
- printf("sio%d: irq maps: %#x %#x %#x %#x\n",
- device_get_unit(dev),
- irqmap[0], irqmap[1], irqmap[2], irqmap[3]);
-
- result = 0;
- for (fn = 0; fn < sizeof failures; ++fn)
- if (failures[fn]) {
- sio_setreg(com, com_mcr, 0);
- result = ENXIO;
- if (bootverbose) {
- printf("sio%d: probe failed test(s):",
- device_get_unit(dev));
- for (fn = 0; fn < sizeof failures; ++fn)
- if (failures[fn])
- printf(" %d", fn);
- printf("\n");
- }
- break;
- }
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- if (iobase == siocniobase)
- result = 0;
- if (result != 0) {
- device_set_softc(dev, NULL);
- free(com, M_DEVBUF);
- }
- return (result);
-}
-
-#ifdef COM_ESP
-static int
-espattach(com, esp_port)
- struct com_s *com;
- Port_t esp_port;
-{
- u_char dips;
- u_char val;
-
- /*
- * Check the ESP-specific I/O port to see if we're an ESP
- * card. If not, return failure immediately.
- */
- if ((inb(esp_port) & 0xf3) == 0) {
- printf(" port 0x%x is not an ESP board?\n", esp_port);
- return (0);
- }
-
- /*
- * We've got something that claims to be a Hayes ESP card.
- * Let's hope so.
- */
-
- /* Get the dip-switch configuration */
-#ifdef PC98
- outb(esp_port + ESP98_CMD1, ESP_GETDIPS);
- dips = inb(esp_port + ESP98_STATUS1);
-#else
- outb(esp_port + ESP_CMD1, ESP_GETDIPS);
- dips = inb(esp_port + ESP_STATUS1);
-#endif
-
- /*
- * Bits 0,1 of dips say which COM port we are.
- */
-#ifdef PC98
- if ((rman_get_start(com->ioportres) & 0xff) ==
- likely_com_ports[dips & 0x03])
-#else
- if (rman_get_start(com->ioportres) == likely_com_ports[dips & 0x03])
-#endif
- printf(" : ESP");
- else {
- printf(" esp_port has com %d\n", dips & 0x03);
- return (0);
- }
-
- /*
- * Check for ESP version 2.0 or later: bits 4,5,6 = 010.
- */
-#ifdef PC98
- outb(esp_port + ESP98_CMD1, ESP_GETTEST);
- val = inb(esp_port + ESP98_STATUS1); /* clear reg 1 */
- val = inb(esp_port + ESP98_STATUS2);
-#else
- outb(esp_port + ESP_CMD1, ESP_GETTEST);
- val = inb(esp_port + ESP_STATUS1); /* clear reg 1 */
- val = inb(esp_port + ESP_STATUS2);
-#endif
- if ((val & 0x70) < 0x20) {
- printf("-old (%o)", val & 0x70);
- return (0);
- }
-
- /*
- * Check for ability to emulate 16550: bit 7 == 1
- */
- if ((dips & 0x80) == 0) {
- printf(" slave");
- return (0);
- }
-
- /*
- * Okay, we seem to be a Hayes ESP card. Whee.
- */
- com->esp = TRUE;
- com->esp_port = esp_port;
- return (1);
-}
-#endif /* COM_ESP */
-
-int
-sioattach(dev, xrid, rclk)
- device_t dev;
- int xrid;
- u_long rclk;
-{
- struct com_s *com;
-#ifdef COM_ESP
- Port_t *espp;
-#endif
- Port_t iobase;
- int unit;
- u_int flags;
- int rid;
- struct resource *port;
- int ret;
- int error;
- struct tty *tp;
-#ifdef PC98
- u_char *obuf;
- u_long obufsize;
- int if_type = GET_IFTYPE(device_get_flags(dev));
-#endif
-
- rid = xrid;
-#ifdef PC98
- if (IS_8251(if_type)) {
- port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
- RF_ACTIVE);
- } else if (if_type == COM_IF_MODEM_CARD ||
- if_type == COM_IF_RSA98III ||
- isa_get_vendorid(dev)) {
- port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
- if_16550a_type[if_type & 0x0f].iatsz, RF_ACTIVE);
- } else {
- port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
- if_16550a_type[if_type & 0x0f].iat,
- if_16550a_type[if_type & 0x0f].iatsz, RF_ACTIVE);
- }
-#else
- port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
- 0, ~0, IO_COMSIZE, RF_ACTIVE);
-#endif
- if (!port)
- return (ENXIO);
-#ifdef PC98
- if (!IS_8251(if_type)) {
- if (isa_load_resourcev(port,
- if_16550a_type[if_type & 0x0f].iat,
- if_16550a_type[if_type & 0x0f].iatsz) != 0) {
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- return ENXIO;
- }
- }
-#endif
-
- iobase = rman_get_start(port);
- unit = device_get_unit(dev);
- com = device_get_softc(dev);
- flags = device_get_flags(dev);
-
- if (unit >= sio_numunits)
- sio_numunits = unit + 1;
-
-#ifdef PC98
- obufsize = 256;
- if (if_type == COM_IF_RSA98III)
- obufsize = 2048;
- if ((obuf = malloc(obufsize * 2, M_DEVBUF, M_NOWAIT)) == NULL) {
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- return ENXIO;
- }
- bzero(obuf, obufsize * 2);
-#endif
-
- /*
- * sioprobe() has initialized the device registers as follows:
- * o cfcr = CFCR_8BITS.
- * It is most important that CFCR_DLAB is off, so that the
- * data port is not hidden when we enable interrupts.
- * o ier = 0.
- * Interrupts are only enabled when the line is open.
- * o mcr = MCR_IENABLE, or 0 if the port has AST/4 compatible
- * interrupt control register or the config specifies no irq.
- * Keeping MCR_DTR and MCR_RTS off might stop the external
- * device from sending before we are ready.
- */
- bzero(com, sizeof *com);
- com->unit = unit;
- com->ioportres = port;
- com->ioportrid = rid;
- com->bst = rman_get_bustag(port);
- com->bsh = rman_get_bushandle(port);
- com->cfcr_image = CFCR_8BITS;
- com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
- com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0;
- com->tx_fifo_size = 1;
-#ifdef PC98
- com->obufsize = obufsize;
- com->obuf1 = obuf;
- com->obuf2 = obuf + obufsize;
-#endif
- com->obufs[0].l_head = com->obuf1;
- com->obufs[1].l_head = com->obuf2;
-
-#ifdef PC98
- com->pc98_if_type = if_type;
-
- if (IS_8251(if_type)) {
- pc98_set_ioport(com);
-
- if (if_type == COM_IF_INTERNAL && pc98_check_8251fifo()) {
- com->pc98_8251fifo = 1;
- com->pc98_8251fifo_enable = 0;
- }
- } else {
- bus_addr_t *iat = if_16550a_type[if_type & 0x0f].iat;
-
- com->data_port = iobase + iat[com_data];
- com->int_ctl_port = iobase + iat[com_ier];
- com->int_id_port = iobase + iat[com_iir];
- com->modem_ctl_port = iobase + iat[com_mcr];
- com->mcr_image = inb(com->modem_ctl_port);
- com->line_status_port = iobase + iat[com_lsr];
- com->modem_status_port = iobase + iat[com_msr];
- }
-#else /* not PC98 */
- com->data_port = iobase + com_data;
- com->int_ctl_port = iobase + com_ier;
- com->int_id_port = iobase + com_iir;
- com->modem_ctl_port = iobase + com_mcr;
- com->mcr_image = inb(com->modem_ctl_port);
- com->line_status_port = iobase + com_lsr;
- com->modem_status_port = iobase + com_msr;
-#endif
-
- tp = com->tp = ttyalloc();
- tp->t_oproc = comstart;
- tp->t_param = comparam;
- tp->t_stop = comstop;
- tp->t_modem = commodem;
- tp->t_break = combreak;
- tp->t_close = comclose;
- tp->t_open = comopen;
- tp->t_sc = com;
-
-#ifdef PC98
- if (!IS_8251(if_type) && rclk == 0)
- rclk = if_16550a_type[if_type & 0x0f].rclk;
-#else
- if (rclk == 0)
- rclk = DEFAULT_RCLK;
-#endif
- com->rclk = rclk;
-
- if (unit == comconsole)
- ttyconsolemode(tp, comdefaultrate);
- error = siosetwater(com, tp->t_init_in.c_ispeed);
- mtx_unlock_spin(&sio_lock);
- if (error) {
- /*
- * Leave i/o resources allocated if this is a `cn'-level
- * console, so that other devices can't snarf them.
- */
- if (iobase != siocniobase)
- bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- return (ENOMEM);
- }
-
- /* attempt to determine UART type */
- printf("sio%d: type", unit);
-
-#ifndef PC98
- if (!COM_ISMULTIPORT(flags) &&
- !COM_IIR_TXRDYBUG(flags) && !COM_NOSCR(flags)) {
- u_char scr;
- u_char scr1;
- u_char scr2;
-
- scr = sio_getreg(com, com_scr);
- sio_setreg(com, com_scr, 0xa5);
- scr1 = sio_getreg(com, com_scr);
- sio_setreg(com, com_scr, 0x5a);
- scr2 = sio_getreg(com, com_scr);
- sio_setreg(com, com_scr, scr);
- if (scr1 != 0xa5 || scr2 != 0x5a) {
- printf(" 8250 or not responding");
- goto determined_type;
- }
- }
-#endif /* !PC98 */
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- if (com->pc98_8251fifo && !COM_NOFIFO(flags))
- com->tx_fifo_size = 16;
- com_int_TxRx_disable( com );
- com_cflag_and_speed_set( com, tp->t_init_in.c_cflag, comdefaultrate );
- com_tiocm_bic( com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE );
- com_send_break_off( com );
-
- if (com->pc98_if_type == COM_IF_INTERNAL) {
- printf(" (internal%s%s)",
- com->pc98_8251fifo ? " fifo" : "",
- PC98SIO_baud_rate_port(com->pc98_if_type) != -1 ?
- " v-fast" : "");
- } else {
- printf(" 8251%s", if_8251_type[com->pc98_if_type & 0x0f].name);
- }
- } else {
-#endif /* PC98 */
- sio_setreg(com, com_fifo, FIFO_ENABLE | FIFO_RX_HIGH);
- DELAY(100);
- switch (inb(com->int_id_port) & IIR_FIFO_MASK) {
- case FIFO_RX_LOW:
- printf(" 16450");
- break;
- case FIFO_RX_MEDL:
- printf(" 16450?");
- break;
- case FIFO_RX_MEDH:
- printf(" 16550?");
- break;
- case FIFO_RX_HIGH:
- if (COM_NOFIFO(flags)) {
- printf(" 16550A fifo disabled");
- break;
- }
- com->hasfifo = TRUE;
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- com->tx_fifo_size = 2048;
- com->rsabase = iobase;
- outb(com->rsabase + rsa_ier, 0x00);
- outb(com->rsabase + rsa_frr, 0x00);
- }
-#else
- if (COM_ST16650A(flags)) {
- printf(" ST16650A");
- com->st16650a = TRUE;
- com->tx_fifo_size = 32;
- break;
- }
- if (COM_TI16754(flags)) {
- printf(" TI16754");
- com->tx_fifo_size = 64;
- break;
- }
-#endif
- printf(" 16550A");
-#ifdef COM_ESP
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_ESP98)
-#endif
- for (espp = likely_esp_ports; *espp != 0; espp++)
- if (espattach(com, *espp)) {
- com->tx_fifo_size = 1024;
- break;
- }
- if (com->esp)
- break;
-#endif
-#ifdef PC98
- com->tx_fifo_size = 16;
-#else
- com->tx_fifo_size = COM_FIFOSIZE(flags);
- if (com->tx_fifo_size == 0)
- com->tx_fifo_size = 16;
- else
- printf(" lookalike with %u bytes FIFO",
- com->tx_fifo_size);
-#endif
- break;
- }
-
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSB3000) {
- /* Set RSB-2000/3000 Extended Buffer mode. */
- u_char lcr;
- lcr = sio_getreg(com, com_cfcr);
- sio_setreg(com, com_cfcr, lcr | CFCR_DLAB);
- sio_setreg(com, com_emr, EMR_EXBUFF | EMR_EFMODE);
- sio_setreg(com, com_cfcr, lcr);
- }
-#endif
-
-#ifdef COM_ESP
- if (com->esp) {
- /*
- * Set 16550 compatibility mode.
- * We don't use the ESP_MODE_SCALE bit to increase the
- * fifo trigger levels because we can't handle large
- * bursts of input.
- * XXX flow control should be set in comparam(), not here.
- */
-#ifdef PC98
- outb(com->esp_port + ESP98_CMD1, ESP_SETMODE);
- outb(com->esp_port + ESP98_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO);
-#else
- outb(com->esp_port + ESP_CMD1, ESP_SETMODE);
- outb(com->esp_port + ESP_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO);
-#endif
-
- /* Set RTS/CTS flow control. */
-#ifdef PC98
- outb(com->esp_port + ESP98_CMD1, ESP_SETFLOWTYPE);
- outb(com->esp_port + ESP98_CMD2, ESP_FLOW_RTS);
- outb(com->esp_port + ESP98_CMD2, ESP_FLOW_CTS);
-#else
- outb(com->esp_port + ESP_CMD1, ESP_SETFLOWTYPE);
- outb(com->esp_port + ESP_CMD2, ESP_FLOW_RTS);
- outb(com->esp_port + ESP_CMD2, ESP_FLOW_CTS);
-#endif
-
- /* Set flow-control levels. */
-#ifdef PC98
- outb(com->esp_port + ESP98_CMD1, ESP_SETRXFLOW);
- outb(com->esp_port + ESP98_CMD2, HIBYTE(768));
- outb(com->esp_port + ESP98_CMD2, LOBYTE(768));
- outb(com->esp_port + ESP98_CMD2, HIBYTE(512));
- outb(com->esp_port + ESP98_CMD2, LOBYTE(512));
-#else
- outb(com->esp_port + ESP_CMD1, ESP_SETRXFLOW);
- outb(com->esp_port + ESP_CMD2, HIBYTE(768));
- outb(com->esp_port + ESP_CMD2, LOBYTE(768));
- outb(com->esp_port + ESP_CMD2, HIBYTE(512));
- outb(com->esp_port + ESP_CMD2, LOBYTE(512));
-#endif
-
-#ifdef PC98
- /* Set UART clock prescaler. */
- outb(com->esp_port + ESP98_CMD1, ESP_SETCLOCK);
- outb(com->esp_port + ESP98_CMD2, 2); /* 4 times */
-#endif
- }
-#endif /* COM_ESP */
- sio_setreg(com, com_fifo, 0);
-#ifdef PC98
- printf("%s", if_16550a_type[com->pc98_if_type & 0x0f].name);
-#else
-determined_type: ;
-#endif
-
-#ifdef COM_MULTIPORT
- if (COM_ISMULTIPORT(flags)) {
- device_t masterdev;
-
- com->multiport = TRUE;
- printf(" (multiport");
- if (unit == COM_MPMASTER(flags))
- printf(" master");
- printf(")");
- masterdev = devclass_get_device(sio_devclass,
- COM_MPMASTER(flags));
- com->no_irq = (masterdev == NULL || bus_get_resource(masterdev,
- SYS_RES_IRQ, 0, NULL, NULL) != 0);
- }
-#endif /* COM_MULTIPORT */
-#ifdef PC98
- }
-#endif
- if (unit == comconsole)
- printf(", console");
- if (COM_IIR_TXRDYBUG(flags))
- printf(" with a buggy IIR_TXRDY implementation");
- printf("\n");
-
- if (sio_fast_ih == NULL) {
- swi_add(&tty_ithd, "sio", siopoll, NULL, SWI_TTY, 0,
- &sio_fast_ih);
- swi_add(&clk_ithd, "sio", siopoll, NULL, SWI_CLOCK, 0,
- &sio_slow_ih);
- }
-
- com->flags = flags;
- com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
- tp->t_pps = &com->pps;
-
- if (COM_PPSCTS(flags))
- com->pps_bit = MSR_CTS;
- else
- com->pps_bit = MSR_DCD;
- pps_init(&com->pps);
-
- rid = 0;
- com->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
- if (com->irqres) {
- ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres,
- INTR_TYPE_TTY | INTR_FAST,
- siointr, com, &com->cookie);
- if (ret) {
- ret = BUS_SETUP_INTR(device_get_parent(dev), dev,
- com->irqres, INTR_TYPE_TTY,
- siointr, com, &com->cookie);
- if (ret == 0)
- device_printf(dev, "unable to activate interrupt in fast mode - using normal mode\n");
- }
- if (ret)
- device_printf(dev, "could not activate interrupt\n");
-#if defined(KDB) && (defined(BREAK_TO_DEBUGGER) || \
- defined(ALT_BREAK_TO_DEBUGGER))
- /*
- * Enable interrupts for early break-to-debugger support
- * on the console.
- */
- if (ret == 0 && unit == comconsole)
- outb(siocniobase + com_ier, IER_ERXRDY | IER_ERLS |
- IER_EMSC);
-#endif
- }
-
- /* We're ready, open the doors... */
- ttycreate(tp, NULL, unit, MINOR_CALLOUT, "d%r", unit);
-
- return (0);
-}
-
-static int
-comopen(struct tty *tp, struct cdev *dev)
-{
- struct com_s *com;
- int i;
-
- com = tp->t_sc;
- com->poll = com->no_irq;
- com->poll_output = com->loses_outints;
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- com_tiocm_bis(com, TIOCM_DTR|TIOCM_RTS);
- pc98_msrint_start(dev);
- if (com->pc98_8251fifo) {
- com->pc98_8251fifo_enable = 1;
- outb(I8251F_fcr, CTRL8251F_ENABLE |
- CTRL8251F_XMT_RST | CTRL8251F_RCV_RST);
- }
- }
-#endif
- if (com->hasfifo) {
- /*
- * (Re)enable and drain fifos.
- *
- * Certain SMC chips cause problems if the fifos
- * are enabled while input is ready. Turn off the
- * fifo if necessary to clear the input. We test
- * the input ready bit after enabling the fifos
- * since we've already enabled them in comparam()
- * and to handle races between enabling and fresh
- * input.
- */
- for (i = 0; i < 500; i++) {
- sio_setreg(com, com_fifo,
- FIFO_RCV_RST | FIFO_XMT_RST
- | com->fifo_image);
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III)
- outb(com->rsabase + rsa_frr , 0x00);
-#endif
- /*
- * XXX the delays are for superstitious
- * historical reasons. It must be less than
- * the character time at the maximum
- * supported speed (87 usec at 115200 bps
- * 8N1). Otherwise we might loop endlessly
- * if data is streaming in. We used to use
- * delays of 100. That usually worked
- * because DELAY(100) used to usually delay
- * for about 85 usec instead of 100.
- */
- DELAY(50);
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III ?
- !(inb(com->rsabase + rsa_srr) & 0x08) :
- !(inb(com->line_status_port) & LSR_RXRDY))
- break;
-#else
- if (!(inb(com->line_status_port) & LSR_RXRDY))
- break;
-#endif
- sio_setreg(com, com_fifo, 0);
- DELAY(50);
- (void) inb(com->data_port);
- }
- if (i == 500)
- return (EIO);
- }
-
- mtx_lock_spin(&sio_lock);
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- com_tiocm_bis(com, TIOCM_LE);
- com->pc98_prev_modem_status = pc98_get_modem_status(com);
- com_int_Rx_enable(com);
- } else {
-#endif
- (void) inb(com->line_status_port);
- (void) inb(com->data_port);
- com->prev_modem_status = com->last_modem_status
- = inb(com->modem_status_port);
- outb(com->int_ctl_port,
- IER_ERXRDY | IER_ERLS | IER_EMSC
- | (COM_IIR_TXRDYBUG(com->flags) ? 0 : IER_ETXRDY));
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- outb(com->rsabase + rsa_ier, 0x1d);
- outb(com->int_ctl_port, IER_ERLS | IER_EMSC);
- }
-#endif
-#ifdef PC98
- }
-#endif
- mtx_unlock_spin(&sio_lock);
- siosettimeout();
- /* XXX: should be generic ? */
-#ifdef PC98
- if ((IS_8251(com->pc98_if_type) &&
- (pc98_get_modem_status(com) & TIOCM_CAR)) ||
- (!IS_8251(com->pc98_if_type) &&
- (com->prev_modem_status & MSR_DCD)) ||
- ISCALLOUT(dev))
- ttyld_modem(tp, 1);
-#else
- if (com->prev_modem_status & MSR_DCD || ISCALLOUT(dev))
- ttyld_modem(tp, 1);
-#endif
- return (0);
-}
-
-static void
-comclose(tp)
- struct tty *tp;
-{
- int s;
- struct com_s *com;
-
- s = spltty();
- com = tp->t_sc;
- com->poll = FALSE;
- com->poll_output = FALSE;
-#ifdef PC98
- com_send_break_off(com);
-#else
- sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
-#endif
-
-#if defined(KDB) && (defined(BREAK_TO_DEBUGGER) || \
- defined(ALT_BREAK_TO_DEBUGGER))
- /*
- * Leave interrupts enabled and don't clear DTR if this is the
- * console. This allows us to detect break-to-debugger events
- * while the console device is closed.
- */
- if (com->unit != comconsole)
-#endif
- {
-#ifdef PC98
- int tmp;
- if (IS_8251(com->pc98_if_type))
- com_int_TxRx_disable(com);
- else
- sio_setreg(com, com_ier, 0);
- if (com->pc98_if_type == COM_IF_RSA98III)
- outb(com->rsabase + rsa_ier, 0x00);
- if (IS_8251(com->pc98_if_type))
- tmp = pc98_get_modem_status(com) & TIOCM_CAR;
- else
- tmp = com->prev_modem_status & MSR_DCD;
-#else
- sio_setreg(com, com_ier, 0);
-#endif
- if (tp->t_cflag & HUPCL
- /*
- * XXX we will miss any carrier drop between here and the
- * next open. Perhaps we should watch DCD even when the
- * port is closed; it is not sufficient to check it at
- * the next open because it might go up and down while
- * we're not watching.
- */
- || (!tp->t_actout
-#ifdef PC98
- && !(tmp)
-#else
- && !(com->prev_modem_status & MSR_DCD)
-#endif
- && !(tp->t_init_in.c_cflag & CLOCAL))
- || !(tp->t_state & TS_ISOPEN)) {
-#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- com_tiocm_bic(com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE);
- else
-#endif
- (void)commodem(tp, 0, SER_DTR);
- ttydtrwaitstart(tp);
- }
-#ifdef PC98
- else {
- if (IS_8251(com->pc98_if_type))
- com_tiocm_bic(com, TIOCM_LE);
- }
-#endif
- }
-#ifdef PC98
- if (com->pc98_8251fifo) {
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, CTRL8251F_XMT_RST | CTRL8251F_RCV_RST);
- com->pc98_8251fifo_enable = 0;
- }
-#endif
- if (com->hasfifo) {
- /*
- * Disable fifos so that they are off after controlled
- * reboots. Some BIOSes fail to detect 16550s when the
- * fifos are enabled.
- */
- sio_setreg(com, com_fifo, 0);
- }
- tp->t_actout = FALSE;
- wakeup(&tp->t_actout);
- wakeup(TSA_CARR_ON(tp)); /* restart any wopeners */
- siosettimeout();
- splx(s);
-}
-
-static void
-siobusycheck(chan)
- void *chan;
-{
- struct com_s *com;
- int s;
-
- com = (struct com_s *)chan;
-
- /*
- * Clear TS_BUSY if low-level output is complete.
- * spl locking is sufficient because siointr1() does not set CS_BUSY.
- * If siointr1() clears CS_BUSY after we look at it, then we'll get
- * called again. Reading the line status port outside of siointr1()
- * is safe because CS_BUSY is clear so there are no output interrupts
- * to lose.
- */
- s = spltty();
- if (com->state & CS_BUSY)
- com->extra_state &= ~CSE_BUSYCHECK; /* False alarm. */
-#ifdef PC98
- else if ((IS_8251(com->pc98_if_type) &&
- ((com->pc98_8251fifo_enable &&
- (inb(I8251F_lsr) & (STS8251F_TxRDY | STS8251F_TxEMP))
- == (STS8251F_TxRDY | STS8251F_TxEMP)) ||
- (!com->pc98_8251fifo_enable &&
- (inb(com->sts_port) & (STS8251_TxRDY | STS8251_TxEMP))
- == (STS8251_TxRDY | STS8251_TxEMP)))) ||
- ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
- == (LSR_TSRE | LSR_TXRDY))) {
-#else
- else if ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
- == (LSR_TSRE | LSR_TXRDY)) {
-#endif
- com->tp->t_state &= ~TS_BUSY;
- ttwwakeup(com->tp);
- com->extra_state &= ~CSE_BUSYCHECK;
- } else
- timeout(siobusycheck, com, hz / 100);
- splx(s);
-}
-
-static u_int
-siodivisor(rclk, speed)
- u_long rclk;
- speed_t speed;
-{
- long actual_speed;
- u_int divisor;
- int error;
-
- if (speed == 0)
- return (0);
-#if UINT_MAX > (ULONG_MAX - 1) / 8
- if (speed > (ULONG_MAX - 1) / 8)
- return (0);
-#endif
- divisor = (rclk / (8UL * speed) + 1) / 2;
- if (divisor == 0 || divisor >= 65536)
- return (0);
- actual_speed = rclk / (16UL * divisor);
-
- /* 10 times error in percent: */
- error = ((actual_speed - (long)speed) * 2000 / (long)speed + 1) / 2;
-
- /* 3.0% maximum error tolerance: */
- if (error < -30 || error > 30)
- return (0);
-
- return (divisor);
-}
-
-/*
- * Call this function with the sio_lock mutex held. It will return with the
- * lock still held.
- */
-static void
-sioinput(com)
- struct com_s *com;
-{
- u_char *buf;
- int incc;
- u_char line_status;
- int recv_data;
- struct tty *tp;
-
- buf = com->ibuf;
- tp = com->tp;
- if (!(tp->t_state & TS_ISOPEN) || !(tp->t_cflag & CREAD)) {
- com_events -= (com->iptr - com->ibuf);
- com->iptr = com->ibuf;
- return;
- }
- if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
- /*
- * Avoid the grotesquely inefficient lineswitch routine
- * (ttyinput) in "raw" mode. It usually takes about 450
- * instructions (that's without canonical processing or echo!).
- * slinput is reasonably fast (usually 40 instructions plus
- * call overhead).
- */
- do {
- /*
- * This may look odd, but it is using save-and-enable
- * semantics instead of the save-and-disable semantics
- * that are used everywhere else.
- */
- mtx_unlock_spin(&sio_lock);
- incc = com->iptr - buf;
- if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
- && (com->state & CS_RTS_IFLOW
- || tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK))
- ttyblock(tp);
- com->delta_error_counts[CE_TTY_BUF_OVERFLOW]
- += b_to_q((char *)buf, incc, &tp->t_rawq);
- buf += incc;
- tk_nin += incc;
- tk_rawcc += incc;
- tp->t_rawcc += incc;
- ttwakeup(tp);
- if (tp->t_state & TS_TTSTOP
- && (tp->t_iflag & IXANY
- || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
- tp->t_state &= ~TS_TTSTOP;
- tp->t_lflag &= ~FLUSHO;
- comstart(tp);
- }
- mtx_lock_spin(&sio_lock);
- } while (buf < com->iptr);
- } else {
- do {
- /*
- * This may look odd, but it is using save-and-enable
- * semantics instead of the save-and-disable semantics
- * that are used everywhere else.
- */
- mtx_unlock_spin(&sio_lock);
- line_status = buf[com->ierroff];
- recv_data = *buf++;
- if (line_status
- & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) {
- if (line_status & LSR_BI)
- recv_data |= TTY_BI;
- if (line_status & LSR_FE)
- recv_data |= TTY_FE;
- if (line_status & LSR_OE)
- recv_data |= TTY_OE;
- if (line_status & LSR_PE)
- recv_data |= TTY_PE;
- }
- ttyld_rint(tp, recv_data);
- mtx_lock_spin(&sio_lock);
- } while (buf < com->iptr);
- }
- com_events -= (com->iptr - com->ibuf);
- com->iptr = com->ibuf;
-
- /*
- * There is now room for another low-level buffer full of input,
- * so enable RTS if it is now disabled and there is room in the
- * high-level buffer.
- */
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- if ((com->state & CS_RTS_IFLOW) &&
- !(com_tiocm_get(com) & TIOCM_RTS) &&
- !(tp->t_state & TS_TBLOCK))
- com_tiocm_bis(com, TIOCM_RTS);
- } else {
- if ((com->state & CS_RTS_IFLOW) &&
- !(com->mcr_image & MCR_RTS) &&
- !(tp->t_state & TS_TBLOCK))
- outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
- }
-#else
- if ((com->state & CS_RTS_IFLOW) && !(com->mcr_image & MCR_RTS) &&
- !(tp->t_state & TS_TBLOCK))
- outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
-#endif
-}
-
-static void
-siointr(arg)
- void *arg;
-{
- struct com_s *com;
-#if defined(PC98) && defined(COM_MULTIPORT)
- u_char rsa_buf_status;
-#endif
-
-#ifndef COM_MULTIPORT
- com = (struct com_s *)arg;
-
- mtx_lock_spin(&sio_lock);
- siointr1(com);
- mtx_unlock_spin(&sio_lock);
-#else /* COM_MULTIPORT */
- bool_t possibly_more_intrs;
- int unit;
-
- /*
- * Loop until there is no activity on any port. This is necessary
- * to get an interrupt edge more than to avoid another interrupt.
- * If the IRQ signal is just an OR of the IRQ signals from several
- * devices, then the edge from one may be lost because another is
- * on.
- */
- mtx_lock_spin(&sio_lock);
- do {
- possibly_more_intrs = FALSE;
- for (unit = 0; unit < sio_numunits; ++unit) {
- com = com_addr(unit);
- /*
- * XXX COM_LOCK();
- * would it work here, or be counter-productive?
- */
-#ifdef PC98
- if (com != NULL
- && !com->gone
- && IS_8251(com->pc98_if_type)) {
- siointr1(com);
- } else if (com != NULL
- && !com->gone
- && com->pc98_if_type == COM_IF_RSA98III) {
- rsa_buf_status =
- inb(com->rsabase + rsa_srr) & 0xc9;
- if ((rsa_buf_status & 0xc8)
- || !(rsa_buf_status & 0x01)) {
- siointr1(com);
- if (rsa_buf_status !=
- (inb(com->rsabase + rsa_srr) & 0xc9))
- possibly_more_intrs = TRUE;
- }
- } else
-#endif
- if (com != NULL
- && !com->gone
- && (inb(com->int_id_port) & IIR_IMASK)
- != IIR_NOPEND) {
- siointr1(com);
- possibly_more_intrs = TRUE;
- }
- /* XXX COM_UNLOCK(); */
- }
- } while (possibly_more_intrs);
- mtx_unlock_spin(&sio_lock);
-#endif /* COM_MULTIPORT */
-}
-
-static struct timespec siots[8];
-static int siotso;
-static int volatile siotsunit = -1;
-
-static int
-sysctl_siots(SYSCTL_HANDLER_ARGS)
-{
- char buf[128];
- long long delta;
- size_t len;
- int error, i, tso;
-
- for (i = 1, tso = siotso; i < tso; i++) {
- delta = (long long)(siots[i].tv_sec - siots[i - 1].tv_sec) *
- 1000000000 +
- (siots[i].tv_nsec - siots[i - 1].tv_nsec);
- len = sprintf(buf, "%lld\n", delta);
- if (delta >= 110000)
- len += sprintf(buf + len - 1, ": *** %ld.%09ld\n",
- (long)siots[i].tv_sec, siots[i].tv_nsec) - 1;
- if (i == tso - 1)
- buf[len - 1] = '\0';
- error = SYSCTL_OUT(req, buf, len);
- if (error != 0)
- return (error);
- uio_yield();
- }
- return (0);
-}
-
-SYSCTL_PROC(_machdep, OID_AUTO, siots, CTLTYPE_STRING | CTLFLAG_RD,
- 0, 0, sysctl_siots, "A", "sio timestamps");
-
-static void
-siointr1(com)
- struct com_s *com;
-{
- u_char int_ctl;
- u_char int_ctl_new;
- u_char line_status;
- u_char modem_status;
- u_char *ioptr;
- u_char recv_data;
-
-#ifdef PC98
- u_char tmp = 0;
- u_char rsa_buf_status = 0;
- int rsa_tx_fifo_size = 0;
-#endif /* PC98 */
-
- if (COM_IIR_TXRDYBUG(com->flags)) {
- int_ctl = inb(com->int_ctl_port);
- int_ctl_new = int_ctl;
- } else {
- int_ctl = 0;
- int_ctl_new = 0;
- }
-
- while (!com->gone) {
-#ifdef PC98
-status_read:;
- if (IS_8251(com->pc98_if_type)) {
- if (com->pc98_8251fifo_enable)
- tmp = inb(I8251F_lsr);
- else
- tmp = inb(com->sts_port);
-more_intr:
- line_status = 0;
- if (com->pc98_8251fifo_enable) {
- if (tmp & STS8251F_TxRDY) line_status |= LSR_TXRDY;
- if (tmp & STS8251F_RxRDY) line_status |= LSR_RXRDY;
- if (tmp & STS8251F_TxEMP) line_status |= LSR_TSRE;
- if (tmp & STS8251F_PE) line_status |= LSR_PE;
- if (tmp & STS8251F_OE) line_status |= LSR_OE;
- if (tmp & STS8251F_BD_SD) line_status |= LSR_BI;
- } else {
- if (tmp & STS8251_TxRDY) line_status |= LSR_TXRDY;
- if (tmp & STS8251_RxRDY) line_status |= LSR_RXRDY;
- if (tmp & STS8251_TxEMP) line_status |= LSR_TSRE;
- if (tmp & STS8251_PE) line_status |= LSR_PE;
- if (tmp & STS8251_OE) line_status |= LSR_OE;
- if (tmp & STS8251_FE) line_status |= LSR_FE;
- if (tmp & STS8251_BD_SD) line_status |= LSR_BI;
- }
- } else {
-#endif /* PC98 */
- if (com->pps.ppsparam.mode & PPS_CAPTUREBOTH) {
- modem_status = inb(com->modem_status_port);
- if ((modem_status ^ com->last_modem_status) &
- com->pps_bit) {
- pps_capture(&com->pps);
- pps_event(&com->pps,
- (modem_status & com->pps_bit) ?
- PPS_CAPTUREASSERT : PPS_CAPTURECLEAR);
- }
- }
- line_status = inb(com->line_status_port);
-#ifdef PC98
- }
- if (com->pc98_if_type == COM_IF_RSA98III)
- rsa_buf_status = inb(com->rsabase + rsa_srr);
-#endif /* PC98 */
-
- /* input event? (check first to help avoid overruns) */
-#ifndef PC98
- while (line_status & LSR_RCV_MASK) {
-#else
- while ((line_status & LSR_RCV_MASK)
- || (com->pc98_if_type == COM_IF_RSA98III
- && (rsa_buf_status & 0x08))) {
-#endif /* PC98 */
- /* break/unnattached error bits or real input? */
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- if (com->pc98_8251fifo_enable) {
- recv_data = inb(I8251F_data);
- if (tmp & (STS8251F_PE | STS8251F_OE |
- STS8251F_BD_SD)) {
- pc98_i8251_or_cmd(com, CMD8251_ER);
- recv_data = 0;
- }
- } else {
- recv_data = inb(com->data_port);
- if (tmp & (STS8251_PE | STS8251_OE |
- STS8251_FE | STS8251_BD_SD)) {
- pc98_i8251_or_cmd(com, CMD8251_ER);
- recv_data = 0;
- }
- }
- } else if (com->pc98_if_type == COM_IF_RSA98III) {
- if (!(rsa_buf_status & 0x08))
- recv_data = 0;
- else
- recv_data = inb(com->data_port);
- } else
-#endif
- if (!(line_status & LSR_RXRDY))
- recv_data = 0;
- else
- recv_data = inb(com->data_port);
-#ifdef KDB
-#ifdef ALT_BREAK_TO_DEBUGGER
- if (com->unit == comconsole &&
- kdb_alt_break(recv_data, &com->alt_brk_state) != 0)
- kdb_enter("Break sequence on console");
-#endif /* ALT_BREAK_TO_DEBUGGER */
-#endif /* KDB */
- if (line_status & (LSR_BI | LSR_FE | LSR_PE)) {
- /*
- * Don't store BI if IGNBRK or FE/PE if IGNPAR.
- * Otherwise, push the work to a higher level
- * (to handle PARMRK) if we're bypassing.
- * Otherwise, convert BI/FE and PE+INPCK to 0.
- *
- * This makes bypassing work right in the
- * usual "raw" case (IGNBRK set, and IGNPAR
- * and INPCK clear).
- *
- * Note: BI together with FE/PE means just BI.
- */
- if (line_status & LSR_BI) {
-#if defined(KDB) && defined(BREAK_TO_DEBUGGER)
- if (com->unit == comconsole) {
- kdb_enter("Line break on console");
- goto cont;
- }
-#endif
- if (com->tp == NULL
- || com->tp->t_iflag & IGNBRK)
- goto cont;
- } else {
- if (com->tp == NULL
- || com->tp->t_iflag & IGNPAR)
- goto cont;
- }
- if (com->tp->t_state & TS_CAN_BYPASS_L_RINT
- && (line_status & (LSR_BI | LSR_FE)
- || com->tp->t_iflag & INPCK))
- recv_data = 0;
- }
- ++com->bytes_in;
- if (com->tp != NULL &&
- com->tp->t_hotchar != 0 && recv_data == com->tp->t_hotchar)
- swi_sched(sio_fast_ih, 0);
- ioptr = com->iptr;
- if (ioptr >= com->ibufend)
- CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
- else {
- if (com->tp != NULL && com->tp->t_do_timestamp)
- microtime(&com->tp->t_timestamp);
- ++com_events;
- swi_sched(sio_slow_ih, SWI_DELAY);
-#if 0 /* for testing input latency vs efficiency */
-if (com->iptr - com->ibuf == 8)
- swi_sched(sio_fast_ih, 0);
-#endif
- ioptr[0] = recv_data;
- ioptr[com->ierroff] = line_status;
- com->iptr = ++ioptr;
- if (ioptr == com->ihighwater
- && com->state & CS_RTS_IFLOW)
-#ifdef PC98
- IS_8251(com->pc98_if_type) ?
- com_tiocm_bic(com, TIOCM_RTS) :
-#endif
- outb(com->modem_ctl_port,
- com->mcr_image &= ~MCR_RTS);
- if (line_status & LSR_OE)
- CE_RECORD(com, CE_OVERRUN);
- }
-cont:
- if (line_status & LSR_TXRDY
- && com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY))
- goto txrdy;
-
- /*
- * "& 0x7F" is to avoid the gcc-1.40 generating a slow
- * jump from the top of the loop to here
- */
-#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- goto status_read;
- else
-#endif
- line_status = inb(com->line_status_port) & 0x7F;
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III)
- rsa_buf_status = inb(com->rsabase + rsa_srr);
-#endif /* PC98 */
- }
-
- /* modem status change? (always check before doing output) */
-#ifdef PC98
- if (!IS_8251(com->pc98_if_type)) {
-#endif
- modem_status = inb(com->modem_status_port);
- if (modem_status != com->last_modem_status) {
- /*
- * Schedule high level to handle DCD changes. Note
- * that we don't use the delta bits anywhere. Some
- * UARTs mess them up, and it's easy to remember the
- * previous bits and calculate the delta.
- */
- com->last_modem_status = modem_status;
- if (!(com->state & CS_CHECKMSR)) {
- com_events += LOTS_OF_EVENTS;
- com->state |= CS_CHECKMSR;
- swi_sched(sio_fast_ih, 0);
- }
-
- /* handle CTS change immediately for crisp flow ctl */
- if (com->state & CS_CTS_OFLOW) {
- if (modem_status & MSR_CTS)
- com->state |= CS_ODEVREADY;
- else
- com->state &= ~CS_ODEVREADY;
- }
- }
-#ifdef PC98
- }
-#endif
-
-txrdy:
- /* output queued and everything ready? */
-#ifndef PC98
- if (line_status & LSR_TXRDY
- && com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
-#else
- if (((com->pc98_if_type == COM_IF_RSA98III)
- ? (rsa_buf_status & 0x02)
- : (line_status & LSR_TXRDY))
- && com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
-#endif
-#ifdef PC98
- Port_t tmp_data_port;
-
- if (IS_8251(com->pc98_if_type) &&
- com->pc98_8251fifo_enable)
- tmp_data_port = I8251F_data;
- else
- tmp_data_port = com->data_port;
-#endif
-
- ioptr = com->obufq.l_head;
- if (com->tx_fifo_size > 1 && com->unit != siotsunit) {
- u_int ocount;
-
- ocount = com->obufq.l_tail - ioptr;
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- rsa_buf_status = inb(com->rsabase + rsa_srr);
- rsa_tx_fifo_size = 1024;
- if (!(rsa_buf_status & 0x01))
- rsa_tx_fifo_size = 2048;
- if (ocount > rsa_tx_fifo_size)
- ocount = rsa_tx_fifo_size;
- } else
-#endif
- if (ocount > com->tx_fifo_size)
- ocount = com->tx_fifo_size;
- com->bytes_out += ocount;
- do
-#ifdef PC98
- outb(tmp_data_port, *ioptr++);
-#else
- outb(com->data_port, *ioptr++);
-#endif
- while (--ocount != 0);
- } else {
-#ifdef PC98
- outb(tmp_data_port, *ioptr++);
-#else
- outb(com->data_port, *ioptr++);
-#endif
- ++com->bytes_out;
- if (com->unit == siotsunit
- && siotso < sizeof siots / sizeof siots[0])
- nanouptime(&siots[siotso++]);
- }
-#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- if (!(pc98_check_i8251_interrupt(com) & IEN_TxFLAG))
- com_int_Tx_enable(com);
-#endif
- com->obufq.l_head = ioptr;
- if (COM_IIR_TXRDYBUG(com->flags))
- int_ctl_new = int_ctl | IER_ETXRDY;
- if (ioptr >= com->obufq.l_tail) {
- struct lbq *qp;
-
- qp = com->obufq.l_next;
- qp->l_queued = FALSE;
- qp = qp->l_next;
- if (qp != NULL) {
- com->obufq.l_head = qp->l_head;
- com->obufq.l_tail = qp->l_tail;
- com->obufq.l_next = qp;
- } else {
- /* output just completed */
- if (COM_IIR_TXRDYBUG(com->flags))
- int_ctl_new = int_ctl
- & ~IER_ETXRDY;
- com->state &= ~CS_BUSY;
-#if defined(PC98)
- if (IS_8251(com->pc98_if_type) &&
- pc98_check_i8251_interrupt(com) & IEN_TxFLAG)
- com_int_Tx_disable(com);
-#endif
- }
- if (!(com->state & CS_ODONE)) {
- com_events += LOTS_OF_EVENTS;
- com->state |= CS_ODONE;
- /* handle at high level ASAP */
- swi_sched(sio_fast_ih, 0);
- }
- }
-#ifdef PC98
- if (COM_IIR_TXRDYBUG(com->flags)
- && int_ctl != int_ctl_new) {
- if (com->pc98_if_type == COM_IF_RSA98III) {
- int_ctl_new &= ~(IER_ETXRDY | IER_ERXRDY);
- outb(com->int_ctl_port, int_ctl_new);
- outb(com->rsabase + rsa_ier, 0x1d);
- } else
- outb(com->int_ctl_port, int_ctl_new);
- }
-#else
- if (COM_IIR_TXRDYBUG(com->flags)
- && int_ctl != int_ctl_new)
- outb(com->int_ctl_port, int_ctl_new);
-#endif
- }
-#ifdef PC98
- else if (line_status & LSR_TXRDY) {
- if (IS_8251(com->pc98_if_type))
- if (pc98_check_i8251_interrupt(com) & IEN_TxFLAG)
- com_int_Tx_disable(com);
- }
- if (IS_8251(com->pc98_if_type)) {
- if (com->pc98_8251fifo_enable) {
- if ((tmp = inb(I8251F_lsr)) & STS8251F_RxRDY)
- goto more_intr;
- } else {
- if ((tmp = inb(com->sts_port)) & STS8251_RxRDY)
- goto more_intr;
- }
- }
-#endif
-
- /* finished? */
-#ifndef COM_MULTIPORT
-#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- return;
-#endif
- if ((inb(com->int_id_port) & IIR_IMASK) == IIR_NOPEND)
-#endif /* COM_MULTIPORT */
- return;
- }
-}
-
-/* software interrupt handler for SWI_TTY */
-static void
-siopoll(void *dummy)
-{
- int unit;
-
- if (com_events == 0)
- return;
-repeat:
- for (unit = 0; unit < sio_numunits; ++unit) {
- struct com_s *com;
- int incc;
- struct tty *tp;
-
- com = com_addr(unit);
- if (com == NULL)
- continue;
- tp = com->tp;
- if (tp == NULL || com->gone) {
- /*
- * Discard any events related to never-opened or
- * going-away devices.
- */
- mtx_lock_spin(&sio_lock);
- incc = com->iptr - com->ibuf;
- com->iptr = com->ibuf;
- if (com->state & CS_CHECKMSR) {
- incc += LOTS_OF_EVENTS;
- com->state &= ~CS_CHECKMSR;
- }
- com_events -= incc;
- mtx_unlock_spin(&sio_lock);
- continue;
- }
- if (com->iptr != com->ibuf) {
- mtx_lock_spin(&sio_lock);
- sioinput(com);
- mtx_unlock_spin(&sio_lock);
- }
- if (com->state & CS_CHECKMSR) {
- u_char delta_modem_status;
-
-#ifdef PC98
- if (!IS_8251(com->pc98_if_type)) {
-#endif
- mtx_lock_spin(&sio_lock);
- delta_modem_status = com->last_modem_status
- ^ com->prev_modem_status;
- com->prev_modem_status = com->last_modem_status;
- com_events -= LOTS_OF_EVENTS;
- com->state &= ~CS_CHECKMSR;
- mtx_unlock_spin(&sio_lock);
- if (delta_modem_status & MSR_DCD)
- ttyld_modem(tp,
- com->prev_modem_status & MSR_DCD);
-#ifdef PC98
- }
-#endif
- }
- if (com->state & CS_ODONE) {
- mtx_lock_spin(&sio_lock);
- com_events -= LOTS_OF_EVENTS;
- com->state &= ~CS_ODONE;
- mtx_unlock_spin(&sio_lock);
- if (!(com->state & CS_BUSY)
- && !(com->extra_state & CSE_BUSYCHECK)) {
- timeout(siobusycheck, com, hz / 100);
- com->extra_state |= CSE_BUSYCHECK;
- }
- ttyld_start(tp);
- }
- if (com_events == 0)
- break;
- }
- if (com_events >= LOTS_OF_EVENTS)
- goto repeat;
-}
-
-static void
-combreak(tp, sig)
- struct tty *tp;
- int sig;
-{
- struct com_s *com;
-
- com = tp->t_sc;
-
-#ifdef PC98
- if (sig)
- com_send_break_on(com);
- else
- com_send_break_off(com);
-#else
- if (sig)
- sio_setreg(com, com_cfcr, com->cfcr_image |= CFCR_SBREAK);
- else
- sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
-#endif
-}
-
-static int
-comparam(tp, t)
- struct tty *tp;
- struct termios *t;
-{
- u_int cfcr;
- int cflag;
- struct com_s *com;
- u_int divisor;
- u_char dlbh;
- u_char dlbl;
- u_char efr_flowbits;
- int s;
-#ifdef PC98
- u_char param = 0;
-#endif
-
- com = tp->t_sc;
- if (com == NULL)
- return (ENODEV);
-
-#ifdef PC98
- cfcr = 0;
-
- if (IS_8251(com->pc98_if_type)) {
- if (pc98_ttspeedtab(com, t->c_ospeed, &divisor) != 0)
- return (EINVAL);
- } else {
-#endif
- /* check requested parameters */
- if (t->c_ispeed != (t->c_ospeed != 0 ? t->c_ospeed : tp->t_ospeed))
- return (EINVAL);
- divisor = siodivisor(com->rclk, t->c_ispeed);
- if (divisor == 0)
- return (EINVAL);
-#ifdef PC98
- }
-#endif
-
- /* parameters are OK, convert them to the com struct and the device */
- s = spltty();
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- if (t->c_ospeed == 0)
- com_tiocm_bic(com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE);
- else
- com_tiocm_bis(com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE);
- } else
-#endif
- if (t->c_ospeed == 0)
- (void)commodem(tp, 0, SER_DTR); /* hang up line */
- else
- (void)commodem(tp, SER_DTR, 0);
- cflag = t->c_cflag;
-#ifdef PC98
- if (!IS_8251(com->pc98_if_type)) {
-#endif
- switch (cflag & CSIZE) {
- case CS5:
- cfcr = CFCR_5BITS;
- break;
- case CS6:
- cfcr = CFCR_6BITS;
- break;
- case CS7:
- cfcr = CFCR_7BITS;
- break;
- default:
- cfcr = CFCR_8BITS;
- break;
- }
- if (cflag & PARENB) {
- cfcr |= CFCR_PENAB;
- if (!(cflag & PARODD))
- cfcr |= CFCR_PEVEN;
- }
- if (cflag & CSTOPB)
- cfcr |= CFCR_STOPB;
-
- if (com->hasfifo) {
- /*
- * Use a fifo trigger level low enough so that the input
- * latency from the fifo is less than about 16 msec and
- * the total latency is less than about 30 msec. These
- * latencies are reasonable for humans. Serial comms
- * protocols shouldn't expect anything better since modem
- * latencies are larger.
- *
- * The fifo trigger level cannot be set at RX_HIGH for high
- * speed connections without further work on reducing
- * interrupt disablement times in other parts of the system,
- * without producing silo overflow errors.
- */
- com->fifo_image = com->unit == siotsunit ? 0
- : t->c_ispeed <= 4800
- ? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_MEDH;
-#ifdef COM_ESP
- /*
- * The Hayes ESP card needs the fifo DMA mode bit set
- * in compatibility mode. If not, it will interrupt
- * for each character received.
- */
- if (com->esp)
- com->fifo_image |= FIFO_DMA_MODE;
-#endif
- sio_setreg(com, com_fifo, com->fifo_image);
- }
-#ifdef PC98
- }
-#endif
-
- /*
- * This returns with interrupts disabled so that we can complete
- * the speed change atomically. Keeping interrupts disabled is
- * especially important while com_data is hidden.
- */
- (void) siosetwater(com, t->c_ispeed);
-
-#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- com_cflag_and_speed_set(com, cflag, t->c_ospeed);
- else {
-#endif
- sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB);
- /*
- * Only set the divisor registers if they would change, since on
- * some 16550 incompatibles (UMC8669F), setting them while input
- * is arriving loses sync until data stops arriving.
- */
- dlbl = divisor & 0xFF;
- if (sio_getreg(com, com_dlbl) != dlbl)
- sio_setreg(com, com_dlbl, dlbl);
- dlbh = divisor >> 8;
- if (sio_getreg(com, com_dlbh) != dlbh)
- sio_setreg(com, com_dlbh, dlbh);
-#ifdef PC98
- }
-#endif
-
- efr_flowbits = 0;
-
- if (cflag & CRTS_IFLOW) {
- com->state |= CS_RTS_IFLOW;
- efr_flowbits |= EFR_AUTORTS;
- /*
- * If CS_RTS_IFLOW just changed from off to on, the change
- * needs to be propagated to MCR_RTS. This isn't urgent,
- * so do it later by calling comstart() instead of repeating
- * a lot of code from comstart() here.
- */
- } else if (com->state & CS_RTS_IFLOW) {
- com->state &= ~CS_RTS_IFLOW;
- /*
- * CS_RTS_IFLOW just changed from on to off. Force MCR_RTS
- * on here, since comstart() won't do it later.
- */
-#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- com_tiocm_bis(com, TIOCM_RTS);
- else
- outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
-#else
- outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
-#endif
- }
-
- /*
- * Set up state to handle output flow control.
- * XXX - worth handling MDMBUF (DCD) flow control at the lowest level?
- * Now has 10+ msec latency, while CTS flow has 50- usec latency.
- */
- com->state |= CS_ODEVREADY;
- com->state &= ~CS_CTS_OFLOW;
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- param = inb(com->rsabase + rsa_msr);
- outb(com->rsabase + rsa_msr, param & 0x14);
- }
-#endif
- if (cflag & CCTS_OFLOW) {
- com->state |= CS_CTS_OFLOW;
- efr_flowbits |= EFR_AUTOCTS;
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- if (!(pc98_get_modem_status(com) & TIOCM_CTS))
- com->state &= ~CS_ODEVREADY;
- } else if (com->pc98_if_type == COM_IF_RSA98III) {
- /* Set automatic flow control mode */
- outb(com->rsabase + rsa_msr, param | 0x08);
- } else
-#endif
- if (!(com->last_modem_status & MSR_CTS))
- com->state &= ~CS_ODEVREADY;
- }
-
-#ifdef PC98
- if (!IS_8251(com->pc98_if_type))
- sio_setreg(com, com_cfcr, com->cfcr_image = cfcr);
-#else
- if (com->st16650a) {
- sio_setreg(com, com_lcr, LCR_EFR_ENABLE);
- sio_setreg(com, com_efr,
- (sio_getreg(com, com_efr)
- & ~(EFR_AUTOCTS | EFR_AUTORTS)) | efr_flowbits);
- }
- sio_setreg(com, com_cfcr, com->cfcr_image = cfcr);
-#endif
-
- /* XXX shouldn't call functions while intrs are disabled. */
- ttyldoptim(tp);
-
- mtx_unlock_spin(&sio_lock);
- splx(s);
- comstart(tp);
- if (com->ibufold != NULL) {
- free(com->ibufold, M_DEVBUF);
- com->ibufold = NULL;
- }
- return (0);
-}
-
-/*
- * This function must be called with the sio_lock mutex released and will
- * return with it obtained.
- */
-static int
-siosetwater(com, speed)
- struct com_s *com;
- speed_t speed;
-{
- int cp4ticks;
- u_char *ibuf;
- int ibufsize;
- struct tty *tp;
-
- /*
- * Make the buffer size large enough to handle a softtty interrupt
- * latency of about 2 ticks without loss of throughput or data
- * (about 3 ticks if input flow control is not used or not honoured,
- * but a bit less for CS5-CS7 modes).
- */
- cp4ticks = speed / 10 / hz * 4;
- for (ibufsize = 128; ibufsize < cp4ticks;)
- ibufsize <<= 1;
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III)
- ibufsize = 2048;
-#endif
- if (ibufsize == com->ibufsize) {
- mtx_lock_spin(&sio_lock);
- return (0);
- }
-
- /*
- * Allocate input buffer. The extra factor of 2 in the size is
- * to allow for an error byte for each input byte.
- */
- ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
- if (ibuf == NULL) {
- mtx_lock_spin(&sio_lock);
- return (ENOMEM);
- }
-
- /* Initialize non-critical variables. */
- com->ibufold = com->ibuf;
- com->ibufsize = ibufsize;
- tp = com->tp;
- if (tp != NULL) {
- tp->t_ififosize = 2 * ibufsize;
- tp->t_ispeedwat = (speed_t)-1;
- tp->t_ospeedwat = (speed_t)-1;
- }
-
- /*
- * Read current input buffer, if any. Continue with interrupts
- * disabled.
- */
- mtx_lock_spin(&sio_lock);
- if (com->iptr != com->ibuf)
- sioinput(com);
-
- /*-
- * Initialize critical variables, including input buffer watermarks.
- * The external device is asked to stop sending when the buffer
- * exactly reaches high water, or when the high level requests it.
- * The high level is notified immediately (rather than at a later
- * clock tick) when this watermark is reached.
- * The buffer size is chosen so the watermark should almost never
- * be reached.
- * The low watermark is invisibly 0 since the buffer is always
- * emptied all at once.
- */
- com->iptr = com->ibuf = ibuf;
- com->ibufend = ibuf + ibufsize;
- com->ierroff = ibufsize;
- com->ihighwater = ibuf + 3 * ibufsize / 4;
- return (0);
-}
-
-static void
-comstart(tp)
- struct tty *tp;
-{
- struct com_s *com;
- int s;
-
- com = tp->t_sc;
- if (com == NULL)
- return;
- s = spltty();
- mtx_lock_spin(&sio_lock);
- if (tp->t_state & TS_TTSTOP)
- com->state &= ~CS_TTGO;
- else
- com->state |= CS_TTGO;
- if (tp->t_state & TS_TBLOCK) {
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- if ((com_tiocm_get(com) & TIOCM_RTS) &&
- (com->state & CS_RTS_IFLOW))
- com_tiocm_bic(com, TIOCM_RTS);
- } else {
- if ((com->mcr_image & MCR_RTS) &&
- (com->state & CS_RTS_IFLOW))
- outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
- }
-#else
- if (com->mcr_image & MCR_RTS && com->state & CS_RTS_IFLOW)
- outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
-#endif
- } else {
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- if (!(com_tiocm_get(com) & TIOCM_RTS) &&
- com->iptr < com->ihighwater &&
- com->state & CS_RTS_IFLOW)
- com_tiocm_bis(com, TIOCM_RTS);
- } else {
- if (!(com->mcr_image & MCR_RTS) &&
- com->iptr < com->ihighwater &&
- com->state & CS_RTS_IFLOW)
- outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
- }
-#else
- if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater
- && com->state & CS_RTS_IFLOW)
- outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
-#endif
- }
- mtx_unlock_spin(&sio_lock);
- if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
- ttwwakeup(tp);
- splx(s);
- return;
- }
- if (tp->t_outq.c_cc != 0) {
- struct lbq *qp;
- struct lbq *next;
-
- if (!com->obufs[0].l_queued) {
- com->obufs[0].l_tail
- = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1,
-#ifdef PC98
- com->obufsize);
-#else
- sizeof com->obuf1);
-#endif
- com->obufs[0].l_next = NULL;
- com->obufs[0].l_queued = TRUE;
- mtx_lock_spin(&sio_lock);
- if (com->state & CS_BUSY) {
- qp = com->obufq.l_next;
- while ((next = qp->l_next) != NULL)
- qp = next;
- qp->l_next = &com->obufs[0];
- } else {
- com->obufq.l_head = com->obufs[0].l_head;
- com->obufq.l_tail = com->obufs[0].l_tail;
- com->obufq.l_next = &com->obufs[0];
- com->state |= CS_BUSY;
- }
- mtx_unlock_spin(&sio_lock);
- }
- if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
- com->obufs[1].l_tail
- = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2,
-#ifdef PC98
- com->obufsize);
-#else
- sizeof com->obuf2);
-#endif
- com->obufs[1].l_next = NULL;
- com->obufs[1].l_queued = TRUE;
- mtx_lock_spin(&sio_lock);
- if (com->state & CS_BUSY) {
- qp = com->obufq.l_next;
- while ((next = qp->l_next) != NULL)
- qp = next;
- qp->l_next = &com->obufs[1];
- } else {
- com->obufq.l_head = com->obufs[1].l_head;
- com->obufq.l_tail = com->obufs[1].l_tail;
- com->obufq.l_next = &com->obufs[1];
- com->state |= CS_BUSY;
- }
- mtx_unlock_spin(&sio_lock);
- }
- tp->t_state |= TS_BUSY;
- }
- mtx_lock_spin(&sio_lock);
- if (com->state >= (CS_BUSY | CS_TTGO))
- siointr1(com); /* fake interrupt to start output */
- mtx_unlock_spin(&sio_lock);
- ttwwakeup(tp);
- splx(s);
-}
-
-static void
-comstop(tp, rw)
- struct tty *tp;
- int rw;
-{
- struct com_s *com;
-#ifdef PC98
- int rsa98_tmp = 0;
-#endif
-
- com = tp->t_sc;
- if (com == NULL || com->gone)
- return;
- mtx_lock_spin(&sio_lock);
- if (rw & FWRITE) {
-#ifdef PC98
- if (!IS_8251(com->pc98_if_type)) {
-#endif
- if (com->hasfifo)
-#ifdef COM_ESP
- /* XXX avoid h/w bug. */
- if (!com->esp)
-#endif
- sio_setreg(com, com_fifo,
- FIFO_XMT_RST | com->fifo_image);
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III)
- for (rsa98_tmp = 0; rsa98_tmp < 2048; rsa98_tmp++)
- sio_setreg(com, com_fifo,
- FIFO_XMT_RST | com->fifo_image);
- }
-#endif
- com->obufs[0].l_queued = FALSE;
- com->obufs[1].l_queued = FALSE;
- if (com->state & CS_ODONE)
- com_events -= LOTS_OF_EVENTS;
- com->state &= ~(CS_ODONE | CS_BUSY);
- com->tp->t_state &= ~TS_BUSY;
- }
- if (rw & FREAD) {
-#ifdef PC98
- if (!IS_8251(com->pc98_if_type)) {
- if (com->pc98_if_type == COM_IF_RSA98III)
- for (rsa98_tmp = 0; rsa98_tmp < 2048; rsa98_tmp++)
- sio_getreg(com, com_data);
-#endif
- if (com->hasfifo)
-#ifdef COM_ESP
- /* XXX avoid h/w bug. */
- if (!com->esp)
-#endif
- sio_setreg(com, com_fifo,
- FIFO_RCV_RST | com->fifo_image);
-#ifdef PC98
- }
-#endif
- com_events -= (com->iptr - com->ibuf);
- com->iptr = com->ibuf;
- }
- mtx_unlock_spin(&sio_lock);
- comstart(tp);
-}
-
-static int
-commodem(struct tty *tp, int sigon, int sigoff)
-{
- struct com_s *com;
- int bitand, bitor, msr;
-#ifdef PC98
- int clr, set;
-#endif
-
- com = tp->t_sc;
- if (com->gone)
- return(0);
- if (sigon != 0 || sigoff != 0) {
-#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- bitand = bitor = 0;
- clr = set = 0;
- if (sigoff & SER_DTR) {
- bitand |= TIOCM_DTR;
- clr |= CMD8251_DTR;
- }
- if (sigoff & SER_RTS) {
- bitand |= TIOCM_RTS;
- clr |= CMD8251_RxEN | CMD8251_RTS;
- }
- if (sigon & SER_DTR) {
- bitor |= TIOCM_DTR;
- set |= CMD8251_TxEN | CMD8251_RxEN |
- CMD8251_DTR;
- }
- if (sigon & SER_RTS) {
- bitor |= TIOCM_RTS;
- set |= CMD8251_TxEN | CMD8251_RxEN |
- CMD8251_RTS;
- }
- bitand = ~bitand;
- mtx_lock_spin(&sio_lock);
- com->pc98_prev_modem_status &= bitand;
- com->pc98_prev_modem_status |= bitor;
- pc98_i8251_clear_or_cmd(com, clr, set);
- mtx_unlock_spin(&sio_lock);
- return (0);
- } else {
-#endif
- bitand = bitor = 0;
- if (sigoff & SER_DTR)
- bitand |= MCR_DTR;
- if (sigoff & SER_RTS)
- bitand |= MCR_RTS;
- if (sigon & SER_DTR)
- bitor |= MCR_DTR;
- if (sigon & SER_RTS)
- bitor |= MCR_RTS;
- bitand = ~bitand;
- mtx_lock_spin(&sio_lock);
- com->mcr_image &= bitand;
- com->mcr_image |= bitor;
- outb(com->modem_ctl_port, com->mcr_image);
- mtx_unlock_spin(&sio_lock);
- return (0);
-#ifdef PC98
- }
-#endif
- } else {
-#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- return (com_tiocm_get(com));
- else {
-#endif
- bitor = 0;
- if (com->mcr_image & MCR_DTR)
- bitor |= SER_DTR;
- if (com->mcr_image & MCR_RTS)
- bitor |= SER_RTS;
- msr = com->prev_modem_status;
- if (msr & MSR_CTS)
- bitor |= SER_CTS;
- if (msr & MSR_DCD)
- bitor |= SER_DCD;
- if (msr & MSR_DSR)
- bitor |= SER_DSR;
- if (msr & MSR_DSR)
- bitor |= SER_DSR;
- if (msr & (MSR_RI | MSR_TERI))
- bitor |= SER_RI;
- return (bitor);
-#ifdef PC98
- }
-#endif
- }
-}
-
-static void
-siosettimeout()
-{
- struct com_s *com;
- bool_t someopen;
- int unit;
-
- /*
- * Set our timeout period to 1 second if no polled devices are open.
- * Otherwise set it to max(1/200, 1/hz).
- * Enable timeouts iff some device is open.
- */
- untimeout(comwakeup, (void *)NULL, sio_timeout_handle);
- sio_timeout = hz;
- someopen = FALSE;
- for (unit = 0; unit < sio_numunits; ++unit) {
- com = com_addr(unit);
- if (com != NULL && com->tp != NULL
- && com->tp->t_state & TS_ISOPEN && !com->gone) {
- someopen = TRUE;
- if (com->poll || com->poll_output) {
- sio_timeout = hz > 200 ? hz / 200 : 1;
- break;
- }
- }
- }
- if (someopen) {
- sio_timeouts_until_log = hz / sio_timeout;
- sio_timeout_handle = timeout(comwakeup, (void *)NULL,
- sio_timeout);
- } else {
- /* Flush error messages, if any. */
- sio_timeouts_until_log = 1;
- comwakeup((void *)NULL);
- untimeout(comwakeup, (void *)NULL, sio_timeout_handle);
- }
-}
-
-static void
-comwakeup(chan)
- void *chan;
-{
- struct com_s *com;
- int unit;
-
- sio_timeout_handle = timeout(comwakeup, (void *)NULL, sio_timeout);
-
- /*
- * Recover from lost output interrupts.
- * Poll any lines that don't use interrupts.
- */
- for (unit = 0; unit < sio_numunits; ++unit) {
- com = com_addr(unit);
- if (com != NULL && !com->gone
- && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
- mtx_lock_spin(&sio_lock);
- siointr1(com);
- mtx_unlock_spin(&sio_lock);
- }
- }
-
- /*
- * Check for and log errors, but not too often.
- */
- if (--sio_timeouts_until_log > 0)
- return;
- sio_timeouts_until_log = hz / sio_timeout;
- for (unit = 0; unit < sio_numunits; ++unit) {
- int errnum;
-
- com = com_addr(unit);
- if (com == NULL)
- continue;
- if (com->gone)
- continue;
- for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
- u_int delta;
- u_long total;
-
- mtx_lock_spin(&sio_lock);
- delta = com->delta_error_counts[errnum];
- com->delta_error_counts[errnum] = 0;
- mtx_unlock_spin(&sio_lock);
- if (delta == 0)
- continue;
- total = com->error_counts[errnum] += delta;
- log(LOG_ERR, "sio%d: %u more %s%s (total %lu)\n",
- unit, delta, error_desc[errnum],
- delta == 1 ? "" : "s", total);
- }
- }
-}
-
-#ifdef PC98
-/* commint is called when modem control line changes */
-static void
-commint(struct cdev *dev)
-{
- register struct tty *tp;
- int stat,delta;
- struct com_s *com;
-
- com = dev->si_drv1;
- tp = com->tp;
-
- stat = com_tiocm_get(com);
- delta = com_tiocm_get_delta(com);
-
- if (com->state & CS_CTS_OFLOW) {
- if (stat & TIOCM_CTS)
- com->state |= CS_ODEVREADY;
- else
- com->state &= ~CS_ODEVREADY;
- }
- if ((delta & TIOCM_CAR) && (ISCALLOUT(dev)) == 0) {
- if (stat & TIOCM_CAR )
- (void)ttyld_modem(tp, 1);
- else if (ttyld_modem(tp, 0) == 0) {
- /* negate DTR, RTS */
- com_tiocm_bic(com, (tp->t_cflag & HUPCL) ?
- TIOCM_DTR|TIOCM_RTS|TIOCM_LE : TIOCM_LE );
- /* disable IENABLE */
- com_int_TxRx_disable( com );
- }
- }
-}
-#endif
-
-/*
- * Following are all routines needed for SIO to act as console
- */
-struct siocnstate {
- u_char dlbl;
- u_char dlbh;
- u_char ier;
- u_char cfcr;
- u_char mcr;
-};
-
-/*
- * This is a function in order to not replicate "ttyd%d" more
- * places than absolutely necessary.
- */
-static void
-siocnset(struct consdev *cd, int unit)
-{
-
- cd->cn_unit = unit;
- sprintf(cd->cn_name, "ttyd%d", unit);
-}
-
-static speed_t siocngetspeed(Port_t, u_long rclk);
-static void siocnclose(struct siocnstate *sp, Port_t iobase);
-static void siocnopen(struct siocnstate *sp, Port_t iobase, int speed);
-static void siocntxwait(Port_t iobase);
-
-static cn_probe_t siocnprobe;
-static cn_init_t siocninit;
-static cn_term_t siocnterm;
-static cn_checkc_t siocncheckc;
-static cn_getc_t siocngetc;
-static cn_putc_t siocnputc;
-
-CONS_DRIVER(sio, siocnprobe, siocninit, siocnterm, siocngetc, siocncheckc,
- siocnputc, NULL);
-
-static void
-siocntxwait(iobase)
- Port_t iobase;
-{
- int timo;
-
- /*
- * Wait for any pending transmission to finish. Required to avoid
- * the UART lockup bug when the speed is changed, and for normal
- * transmits.
- */
- timo = 100000;
- while ((inb(iobase + com_lsr) & (LSR_TSRE | LSR_TXRDY))
- != (LSR_TSRE | LSR_TXRDY) && --timo != 0)
- ;
-}
-
-/*
- * Read the serial port specified and try to figure out what speed
- * it's currently running at. We're assuming the serial port has
- * been initialized and is basicly idle. This routine is only intended
- * to be run at system startup.
- *
- * If the value read from the serial port doesn't make sense, return 0.
- */
-
-static speed_t
-siocngetspeed(iobase, rclk)
- Port_t iobase;
- u_long rclk;
-{
- u_int divisor;
- u_char dlbh;
- u_char dlbl;
- u_char cfcr;
-
- cfcr = inb(iobase + com_cfcr);
- outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
-
- dlbl = inb(iobase + com_dlbl);
- dlbh = inb(iobase + com_dlbh);
-
- outb(iobase + com_cfcr, cfcr);
-
- divisor = dlbh << 8 | dlbl;
-
- /* XXX there should be more sanity checking. */
- if (divisor == 0)
- return (CONSPEED);
- return (rclk / (16UL * divisor));
-}
-
-static void
-siocnopen(sp, iobase, speed)
- struct siocnstate *sp;
- Port_t iobase;
- int speed;
-{
- u_int divisor;
- u_char dlbh;
- u_char dlbl;
-
- /*
- * Save all the device control registers except the fifo register
- * and set our default ones (cs8 -parenb speed=comdefaultrate).
- * We can't save the fifo register since it is read-only.
- */
- sp->ier = inb(iobase + com_ier);
- outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */
- siocntxwait(iobase);
- sp->cfcr = inb(iobase + com_cfcr);
- outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
- sp->dlbl = inb(iobase + com_dlbl);
- sp->dlbh = inb(iobase + com_dlbh);
- /*
- * Only set the divisor registers if they would change, since on
- * some 16550 incompatibles (Startech), setting them clears the
- * data input register. This also reduces the effects of the
- * UMC8669F bug.
- */
- divisor = siodivisor(comdefaultrclk, speed);
- dlbl = divisor & 0xFF;
- if (sp->dlbl != dlbl)
- outb(iobase + com_dlbl, dlbl);
- dlbh = divisor >> 8;
- if (sp->dlbh != dlbh)
- outb(iobase + com_dlbh, dlbh);
- outb(iobase + com_cfcr, CFCR_8BITS);
- sp->mcr = inb(iobase + com_mcr);
- /*
- * We don't want interrupts, but must be careful not to "disable"
- * them by clearing the MCR_IENABLE bit, since that might cause
- * an interrupt by floating the IRQ line.
- */
- outb(iobase + com_mcr, (sp->mcr & MCR_IENABLE) | MCR_DTR | MCR_RTS);
-}
-
-static void
-siocnclose(sp, iobase)
- struct siocnstate *sp;
- Port_t iobase;
-{
- /*
- * Restore the device control registers.
- */
- siocntxwait(iobase);
- outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
- if (sp->dlbl != inb(iobase + com_dlbl))
- outb(iobase + com_dlbl, sp->dlbl);
- if (sp->dlbh != inb(iobase + com_dlbh))
- outb(iobase + com_dlbh, sp->dlbh);
- outb(iobase + com_cfcr, sp->cfcr);
- /*
- * XXX damp oscillations of MCR_DTR and MCR_RTS by not restoring them.
- */
- outb(iobase + com_mcr, sp->mcr | MCR_DTR | MCR_RTS);
- outb(iobase + com_ier, sp->ier);
-}
-
-static void
-siocnprobe(cp)
- struct consdev *cp;
-{
- speed_t boot_speed;
- u_char cfcr;
- u_int divisor;
- int s, unit;
- struct siocnstate sp;
-
- /*
- * Find our first enabled console, if any. If it is a high-level
- * console device, then initialize it and return successfully.
- * If it is a low-level console device, then initialize it and
- * return unsuccessfully. It must be initialized in both cases
- * for early use by console drivers and debuggers. Initializing
- * the hardware is not necessary in all cases, since the i/o
- * routines initialize it on the fly, but it is necessary if
- * input might arrive while the hardware is switched back to an
- * uninitialized state. We can't handle multiple console devices
- * yet because our low-level routines don't take a device arg.
- * We trust the user to set the console flags properly so that we
- * don't need to probe.
- */
- cp->cn_pri = CN_DEAD;
-
- for (unit = 0; unit < 16; unit++) { /* XXX need to know how many */
- int flags;
-
- if (resource_disabled("sio", unit))
- continue;
- if (resource_int_value("sio", unit, "flags", &flags))
- continue;
- if (COM_CONSOLE(flags) || COM_DEBUGGER(flags)) {
- int port;
- Port_t iobase;
-
- if (resource_int_value("sio", unit, "port", &port))
- continue;
- iobase = port;
- s = spltty();
- if (boothowto & RB_SERIAL) {
- boot_speed =
- siocngetspeed(iobase, comdefaultrclk);
- if (boot_speed)
- comdefaultrate = boot_speed;
- }
-
- /*
- * Initialize the divisor latch. We can't rely on
- * siocnopen() to do this the first time, since it
- * avoids writing to the latch if the latch appears
- * to have the correct value. Also, if we didn't
- * just read the speed from the hardware, then we
- * need to set the speed in hardware so that
- * switching it later is null.
- */
- cfcr = inb(iobase + com_cfcr);
- outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
- divisor = siodivisor(comdefaultrclk, comdefaultrate);
- outb(iobase + com_dlbl, divisor & 0xff);
- outb(iobase + com_dlbh, divisor >> 8);
- outb(iobase + com_cfcr, cfcr);
-
- siocnopen(&sp, iobase, comdefaultrate);
-
- splx(s);
- if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) {
- siocnset(cp, unit);
- cp->cn_pri = COM_FORCECONSOLE(flags)
- || boothowto & RB_SERIAL
- ? CN_REMOTE : CN_NORMAL;
- siocniobase = iobase;
- siocnunit = unit;
- }
-#ifdef GDB
- if (COM_DEBUGGER(flags))
- siogdbiobase = iobase;
-#endif
- }
- }
-}
-
-static void
-siocninit(cp)
- struct consdev *cp;
-{
- comconsole = cp->cn_unit;
-}
-
-static void
-siocnterm(cp)
- struct consdev *cp;
-{
- comconsole = -1;
-}
-
-static int
-siocncheckc(struct consdev *cd)
-{
- int c;
- Port_t iobase;
- int s;
- struct siocnstate sp;
- speed_t speed;
-
- if (cd != NULL && cd->cn_unit == siocnunit) {
- iobase = siocniobase;
- speed = comdefaultrate;
- } else {
-#ifdef GDB
- iobase = siogdbiobase;
- speed = gdbdefaultrate;
-#else
- return (-1);
-#endif
- }
- s = spltty();
- siocnopen(&sp, iobase, speed);
- if (inb(iobase + com_lsr) & LSR_RXRDY)
- c = inb(iobase + com_data);
- else
- c = -1;
- siocnclose(&sp, iobase);
- splx(s);
- return (c);
-}
-
-static int
-siocngetc(struct consdev *cd)
-{
- int c;
- Port_t iobase;
- int s;
- struct siocnstate sp;
- speed_t speed;
-
- if (cd != NULL && cd->cn_unit == siocnunit) {
- iobase = siocniobase;
- speed = comdefaultrate;
- } else {
-#ifdef GDB
- iobase = siogdbiobase;
- speed = gdbdefaultrate;
-#else
- return (-1);
-#endif
- }
- s = spltty();
- siocnopen(&sp, iobase, speed);
- while (!(inb(iobase + com_lsr) & LSR_RXRDY))
- ;
- c = inb(iobase + com_data);
- siocnclose(&sp, iobase);
- splx(s);
- return (c);
-}
-
-static void
-siocnputc(struct consdev *cd, int c)
-{
- int need_unlock;
- int s;
- struct siocnstate sp;
- Port_t iobase;
- speed_t speed;
-
- if (cd != NULL && cd->cn_unit == siocnunit) {
- iobase = siocniobase;
- speed = comdefaultrate;
- } else {
-#ifdef GDB
- iobase = siogdbiobase;
- speed = gdbdefaultrate;
-#else
- return;
-#endif
- }
- s = spltty();
- need_unlock = 0;
- if (!kdb_active && sio_inited == 2 && !mtx_owned(&sio_lock)) {
- mtx_lock_spin(&sio_lock);
- need_unlock = 1;
- }
- siocnopen(&sp, iobase, speed);
- siocntxwait(iobase);
- outb(iobase + com_data, c);
- siocnclose(&sp, iobase);
- if (need_unlock)
- mtx_unlock_spin(&sio_lock);
- splx(s);
-}
-
-/*
- * Remote gdb(1) support.
- */
-
-#if defined(GDB)
-
-#include <gdb/gdb.h>
-
-static gdb_probe_f siogdbprobe;
-static gdb_init_f siogdbinit;
-static gdb_term_f siogdbterm;
-static gdb_getc_f siogdbgetc;
-static gdb_checkc_f siogdbcheckc;
-static gdb_putc_f siogdbputc;
-
-GDB_DBGPORT(sio, siogdbprobe, siogdbinit, siogdbterm, siogdbcheckc,
- siogdbgetc, siogdbputc);
-
-static int
-siogdbprobe(void)
-{
- return ((siogdbiobase != 0) ? 0 : -1);
-}
-
-static void
-siogdbinit(void)
-{
-}
-
-static void
-siogdbterm(void)
-{
-}
-
-static void
-siogdbputc(int c)
-{
- siocnputc(NULL, c);
-}
-
-static int
-siogdbcheckc(void)
-{
- return (siocncheckc(NULL));
-}
-
-static int
-siogdbgetc(void)
-{
- return (siocngetc(NULL));
-}
-
-#endif
-
-#ifdef PC98
-/*
- * pc98 local function
- */
-static void
-com_tiocm_bis(struct com_s *com, int msr)
-{
- int s;
- int tmp = 0;
-
- s=spltty();
- com->pc98_prev_modem_status |= ( msr & (TIOCM_LE|TIOCM_DTR|TIOCM_RTS) );
- tmp |= CMD8251_TxEN|CMD8251_RxEN;
- if ( msr & TIOCM_DTR ) tmp |= CMD8251_DTR;
- if ( msr & TIOCM_RTS ) tmp |= CMD8251_RTS;
-
- pc98_i8251_or_cmd( com, tmp );
- splx(s);
-}
-
-static void
-com_tiocm_bic(struct com_s *com, int msr)
-{
- int s;
- int tmp = msr;
-
- s=spltty();
- com->pc98_prev_modem_status &= ~( msr & (TIOCM_LE|TIOCM_DTR|TIOCM_RTS) );
- if ( msr & TIOCM_DTR ) tmp |= CMD8251_DTR;
- if ( msr & TIOCM_RTS ) tmp |= CMD8251_RTS;
-
- pc98_i8251_clear_cmd( com, tmp );
- splx(s);
-}
-
-static int
-com_tiocm_get(struct com_s *com)
-{
- return( com->pc98_prev_modem_status );
-}
-
-static int
-com_tiocm_get_delta(struct com_s *com)
-{
- int tmp;
-
- tmp = com->pc98_modem_delta;
- com->pc98_modem_delta = 0;
- return( tmp );
-}
-
-/* convert to TIOCM_?? ( ioctl.h ) */
-static int
-pc98_get_modem_status(struct com_s *com)
-{
- register int msr;
-
- msr = com->pc98_prev_modem_status
- & ~(TIOCM_CAR|TIOCM_RI|TIOCM_DSR|TIOCM_CTS);
- if (com->pc98_8251fifo_enable) {
- int stat2;
-
- stat2 = inb(I8251F_msr);
- if ( stat2 & CICSCDF_CD ) msr |= TIOCM_CAR;
- if ( stat2 & CICSCDF_CI ) msr |= TIOCM_RI;
- if ( stat2 & CICSCDF_DR ) msr |= TIOCM_DSR;
- if ( stat2 & CICSCDF_CS ) msr |= TIOCM_CTS;
-#if COM_CARRIER_DETECT_EMULATE
- if ( msr & (TIOCM_DSR|TIOCM_CTS) ) {
- msr |= TIOCM_CAR;
- }
-#endif
- } else {
- int stat, stat2;
-
- stat = inb(com->sts_port);
- stat2 = inb(com->in_modem_port);
- if ( !(stat2 & CICSCD_CD) ) msr |= TIOCM_CAR;
- if ( !(stat2 & CICSCD_CI) ) msr |= TIOCM_RI;
- if ( stat & STS8251_DSR ) msr |= TIOCM_DSR;
- if ( !(stat2 & CICSCD_CS) ) msr |= TIOCM_CTS;
-#if COM_CARRIER_DETECT_EMULATE
- if ( msr & (TIOCM_DSR|TIOCM_CTS) ) {
- msr |= TIOCM_CAR;
- }
-#endif
- }
- return(msr);
-}
-
-static void
-pc98_check_msr(void* chan)
-{
- int msr, delta;
- int s;
- register struct tty *tp;
- struct com_s *com;
- struct cdev *dev;
-
- dev=(struct cdev *)chan;
- com = dev->si_drv1;
- tp = dev->si_tty;
-
- s = spltty();
- msr = pc98_get_modem_status(com);
- /* make change flag */
- delta = msr ^ com->pc98_prev_modem_status;
- if ( delta & TIOCM_CAR ) {
- if ( com->modem_car_chg_timer ) {
- if ( -- com->modem_car_chg_timer )
- msr ^= TIOCM_CAR;
- } else {
- if ((com->modem_car_chg_timer = (msr & TIOCM_CAR) ?
- DCD_ON_RECOGNITION : DCD_OFF_TOLERANCE) != 0)
- msr ^= TIOCM_CAR;
- }
- } else
- com->modem_car_chg_timer = 0;
- delta = ( msr ^ com->pc98_prev_modem_status ) &
- (TIOCM_CAR|TIOCM_RI|TIOCM_DSR|TIOCM_CTS);
- com->pc98_prev_modem_status = msr;
- delta = ( com->pc98_modem_delta |= delta );
- splx(s);
- if ( com->modem_checking || (tp->t_state & (TS_ISOPEN)) ) {
- if ( delta ) {
- commint(dev);
- }
- timeout(pc98_check_msr, (caddr_t)dev,
- PC98_CHECK_MODEM_INTERVAL);
- } else {
- com->modem_checking = 0;
- }
-}
-
-static void
-pc98_msrint_start(struct cdev *dev)
-{
- struct com_s *com;
- int s = spltty();
-
- com = dev->si_drv1;
- /* modem control line check routine envoke interval is 1/10 sec */
- if ( com->modem_checking == 0 ) {
- com->pc98_prev_modem_status = pc98_get_modem_status(com);
- com->pc98_modem_delta = 0;
- timeout(pc98_check_msr, (caddr_t)dev,
- PC98_CHECK_MODEM_INTERVAL);
- com->modem_checking = 1;
- }
- splx(s);
-}
-
-static void
-pc98_disable_i8251_interrupt(struct com_s *com, int mod)
-{
- /* disable interrupt */
- register int tmp;
-
- mod |= ~(IEN_Tx|IEN_TxEMP|IEN_Rx);
- COM_INT_DISABLE
- tmp = inb( com->intr_ctrl_port ) & ~(IEN_Tx|IEN_TxEMP|IEN_Rx);
- outb( com->intr_ctrl_port, (com->intr_enable&=~mod) | tmp );
- COM_INT_ENABLE
-}
-
-static void
-pc98_enable_i8251_interrupt(struct com_s *com, int mod)
-{
- register int tmp;
-
- COM_INT_DISABLE
- tmp = inb( com->intr_ctrl_port ) & ~(IEN_Tx|IEN_TxEMP|IEN_Rx);
- outb( com->intr_ctrl_port, (com->intr_enable|=mod) | tmp );
- COM_INT_ENABLE
-}
-
-static int
-pc98_check_i8251_interrupt(struct com_s *com)
-{
- return ( com->intr_enable & 0x07 );
-}
-
-static void
-pc98_i8251_clear_cmd(struct com_s *com, int x)
-{
- int tmp;
-
- COM_INT_DISABLE
- tmp = com->pc98_prev_siocmd & ~(x);
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, 0);
- outb(com->cmd_port, tmp);
- com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH);
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, CTRL8251F_ENABLE);
- COM_INT_ENABLE
-}
-
-static void
-pc98_i8251_or_cmd(struct com_s *com, int x)
-{
- int tmp;
-
- COM_INT_DISABLE
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, 0);
- tmp = com->pc98_prev_siocmd | (x);
- outb(com->cmd_port, tmp);
- com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH);
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, CTRL8251F_ENABLE);
- COM_INT_ENABLE
-}
-
-static void
-pc98_i8251_set_cmd(struct com_s *com, int x)
-{
- int tmp;
-
- COM_INT_DISABLE
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, 0);
- tmp = (x);
- outb(com->cmd_port, tmp);
- com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH);
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, CTRL8251F_ENABLE);
- COM_INT_ENABLE
-}
-
-static void
-pc98_i8251_clear_or_cmd(struct com_s *com, int clr, int x)
-{
- int tmp;
- COM_INT_DISABLE
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, 0);
- tmp = com->pc98_prev_siocmd & ~(clr);
- tmp |= (x);
- outb(com->cmd_port, tmp);
- com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH);
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, CTRL8251F_ENABLE);
- COM_INT_ENABLE
-}
-
-static int
-pc98_i8251_get_cmd(struct com_s *com)
-{
- return com->pc98_prev_siocmd;
-}
-
-static int
-pc98_i8251_get_mod(struct com_s *com)
-{
- return com->pc98_prev_siomod;
-}
-
-static void
-pc98_i8251_reset(struct com_s *com, int mode, int command)
-{
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, 0);
- outb(com->cmd_port, 0); /* dummy */
- DELAY(2);
- outb(com->cmd_port, 0); /* dummy */
- DELAY(2);
- outb(com->cmd_port, 0); /* dummy */
- DELAY(2);
- outb(com->cmd_port, CMD8251_RESET); /* internal reset */
- DELAY(2);
- outb(com->cmd_port, mode ); /* mode register */
- com->pc98_prev_siomod = mode;
- DELAY(2);
- pc98_i8251_set_cmd( com, (command|CMD8251_ER) );
- DELAY(10);
- if (com->pc98_8251fifo_enable)
- outb(I8251F_fcr, CTRL8251F_ENABLE |
- CTRL8251F_XMT_RST | CTRL8251F_RCV_RST);
-}
-
-static void
-pc98_check_sysclock(void)
-{
- /* get system clock from port */
- if ( pc98_machine_type & M_8M ) {
- /* 8 MHz system & H98 */
- sysclock = 8;
- } else {
- /* 5 MHz system */
- sysclock = 5;
- }
-}
-
-static void
-com_cflag_and_speed_set( struct com_s *com, int cflag, int speed)
-{
- int cfcr=0;
- int previnterrupt;
- u_int count;
-
- if (pc98_ttspeedtab(com, speed, &count) != 0)
- return;
-
- previnterrupt = pc98_check_i8251_interrupt(com);
- pc98_disable_i8251_interrupt( com, IEN_Tx|IEN_TxEMP|IEN_Rx );
-
- switch ( cflag&CSIZE ) {
- case CS5:
- cfcr = MOD8251_5BITS; break;
- case CS6:
- cfcr = MOD8251_6BITS; break;
- case CS7:
- cfcr = MOD8251_7BITS; break;
- case CS8:
- cfcr = MOD8251_8BITS; break;
- }
- if ( cflag&PARENB ) {
- if ( cflag&PARODD )
- cfcr |= MOD8251_PODD;
- else
- cfcr |= MOD8251_PEVEN;
- } else
- cfcr |= MOD8251_PDISAB;
-
- if ( cflag&CSTOPB )
- cfcr |= MOD8251_STOP2;
- else
- cfcr |= MOD8251_STOP1;
-
- if ( count & 0x10000 )
- cfcr |= MOD8251_CLKX1;
- else
- cfcr |= MOD8251_CLKX16;
-
- if (epson_machine_id != 0x20) { /* XXX */
- int tmp;
- while (!((tmp = inb(com->sts_port)) & STS8251_TxEMP))
- ;
- }
- /* set baud rate from ospeed */
- pc98_set_baud_rate( com, count );
-
- if ( cfcr != pc98_i8251_get_mod(com) )
- pc98_i8251_reset(com, cfcr, pc98_i8251_get_cmd(com) );
-
- pc98_enable_i8251_interrupt( com, previnterrupt );
-}
-
-static int
-pc98_ttspeedtab(struct com_s *com, int speed, u_int *divisor)
-{
- int if_type, effect_sp, count = -1, mod;
-
- if_type = com->pc98_if_type & 0x0f;
-
- switch (com->pc98_if_type) {
- case COM_IF_INTERNAL:
- if (PC98SIO_baud_rate_port(if_type) != -1) {
- count = ttspeedtab(speed, if_8251_type[if_type].speedtab);
- if (count > 0) {
- count |= COM1_EXT_CLOCK;
- break;
- }
- }
-
- /* for *1CLK asynchronous! mode, TEFUTEFU */
- mod = (sysclock == 5) ? 2457600 : 1996800;
- effect_sp = ttspeedtab( speed, pc98speedtab );
- if ( effect_sp < 0 ) /* XXX */
- effect_sp = ttspeedtab( (speed - 1), pc98speedtab );
- if ( effect_sp <= 0 )
- return effect_sp;
- if ( effect_sp == speed )
- mod /= 16;
- if ( mod % effect_sp )
- return(-1);
- count = mod / effect_sp;
- if ( count > 65535 )
- return(-1);
- if ( effect_sp != speed )
- count |= 0x10000;
- break;
- case COM_IF_PC9861K_1:
- case COM_IF_PC9861K_2:
- count = 1;
- break;
- case COM_IF_IND_SS_1:
- case COM_IF_IND_SS_2:
- case COM_IF_PIO9032B_1:
- case COM_IF_PIO9032B_2:
- count = ttspeedtab( speed, if_8251_type[if_type].speedtab );
- break;
- case COM_IF_B98_01_1:
- case COM_IF_B98_01_2:
- count = ttspeedtab( speed, if_8251_type[if_type].speedtab );
-#ifdef B98_01_OLD
- if (count == 0 || count == 1) {
- count += 4;
- count |= 0x20000; /* x1 mode for 76800 and 153600 */
- }
-#endif
- break;
- }
-
- if (count < 0)
- return count;
-
- *divisor = (u_int) count;
- return 0;
-}
-
-static void
-pc98_set_baud_rate( struct com_s *com, u_int count )
-{
- int if_type, io, s;
-
- if_type = com->pc98_if_type & 0x0f;
- io = rman_get_start(com->ioportres) & 0xff00;
-
- switch (com->pc98_if_type) {
- case COM_IF_INTERNAL:
- if (PC98SIO_baud_rate_port(if_type) != -1) {
- if (count & COM1_EXT_CLOCK) {
- outb((Port_t)PC98SIO_baud_rate_port(if_type), count & 0xff);
- break;
- } else {
- outb((Port_t)PC98SIO_baud_rate_port(if_type), 0x09);
- }
- }
-
- if (count == 0)
- return;
-
- /* set i8253 */
- s = splclock();
- if (count != 3)
- outb( 0x77, 0xb6 );
- else
- outb( 0x77, 0xb4 );
- outb( 0x5f, 0);
- outb( 0x75, count & 0xff );
- outb( 0x5f, 0);
- outb( 0x75, (count >> 8) & 0xff );
- splx(s);
- break;
- case COM_IF_IND_SS_1:
- case COM_IF_IND_SS_2:
- outb(io | PC98SIO_intr_ctrl_port(if_type), 0);
- outb(io | PC98SIO_baud_rate_port(if_type), 0);
- outb(io | PC98SIO_baud_rate_port(if_type), 0xc0);
- outb(io | PC98SIO_baud_rate_port(if_type), (count >> 8) | 0x80);
- outb(io | PC98SIO_baud_rate_port(if_type), count & 0xff);
- break;
- case COM_IF_PIO9032B_1:
- case COM_IF_PIO9032B_2:
- outb(io | PC98SIO_baud_rate_port(if_type), count);
- break;
- case COM_IF_B98_01_1:
- case COM_IF_B98_01_2:
- outb(io | PC98SIO_baud_rate_port(if_type), count & 0x0f);
-#ifdef B98_01_OLD
- /*
- * Some old B98_01 board should be controlled
- * in different way, but this hasn't been tested yet.
- */
- outb(io | PC98SIO_func_port(if_type),
- (count & 0x20000) ? 0xf0 : 0xf2);
-#endif
- break;
- }
-}
-static int
-pc98_check_if_type(device_t dev, struct siodev *iod)
-{
- int irr, io, if_type, tmp;
- static short irq_tab[2][8] = {
- { 3, 5, 6, 9, 10, 12, 13, -1},
- { 3, 10, 12, 13, 5, 6, 9, -1}
- };
-
- if_type = iod->if_type & 0x0f;
- iod->irq = 0;
- io = isa_get_port(dev) & 0xff00;
-
- if (IS_8251(iod->if_type)) {
- if (PC98SIO_func_port(if_type) != -1) {
- outb(io | PC98SIO_func_port(if_type), 0xf2);
- tmp = ttspeedtab(9600, if_8251_type[if_type].speedtab);
- if (tmp != -1 && PC98SIO_baud_rate_port(if_type) != -1)
- outb(io | PC98SIO_baud_rate_port(if_type), tmp);
- }
-
- iod->cmd = io | PC98SIO_cmd_port(if_type);
- iod->sts = io | PC98SIO_sts_port(if_type);
- iod->mod = io | PC98SIO_in_modem_port(if_type);
- iod->ctrl = io | PC98SIO_intr_ctrl_port(if_type);
-
- if (iod->if_type == COM_IF_INTERNAL) {
- iod->irq = 4;
-
- if (pc98_check_8251vfast()) {
- PC98SIO_baud_rate_port(if_type) = I8251F_div;
- if_8251_type[if_type].speedtab = pc98fast_speedtab;
- }
- } else {
- tmp = inb( iod->mod ) & if_8251_type[if_type].irr_mask;
- if ((isa_get_port(dev) & 0xff) == IO_COM2)
- iod->irq = irq_tab[0][tmp];
- else
- iod->irq = irq_tab[1][tmp];
- }
- } else {
- irr = if_16550a_type[if_type].irr_read;
-#ifdef COM_MULTIPORT
- if (!COM_ISMULTIPORT(device_get_flags(dev)) ||
- device_get_unit(dev) == COM_MPMASTER(device_get_flags(dev)))
-#endif
- if (irr != -1) {
- tmp = inb(io | irr);
- if (isa_get_port(dev) & 0x01) /* XXX depend on RSB-384 */
- iod->irq = irq_tab[1][tmp >> 3];
- else
- iod->irq = irq_tab[0][tmp & 0x07];
- }
- }
- if ( iod->irq == -1 ) return -1;
-
- return 0;
-}
-static void
-pc98_set_ioport(struct com_s *com)
-{
- int if_type = com->pc98_if_type & 0x0f;
- Port_t io = rman_get_start(com->ioportres) & 0xff00;
-
- pc98_check_sysclock();
- com->data_port = io | PC98SIO_data_port(if_type);
- com->cmd_port = io | PC98SIO_cmd_port(if_type);
- com->sts_port = io | PC98SIO_sts_port(if_type);
- com->in_modem_port = io | PC98SIO_in_modem_port(if_type);
- com->intr_ctrl_port = io | PC98SIO_intr_ctrl_port(if_type);
-}
-static int
-pc98_check_8251vfast(void)
-{
- int i;
-
- outb(I8251F_div, 0x8c);
- DELAY(10);
- for (i = 0; i < 100; i++) {
- if ((inb(I8251F_div) & 0x80) != 0) {
- i = 0;
- break;
- }
- DELAY(1);
- }
- outb(I8251F_div, 0);
- DELAY(10);
- for (; i < 100; i++) {
- if ((inb(I8251F_div) & 0x80) == 0)
- return 1;
- DELAY(1);
- }
-
- return 0;
-}
-static int
-pc98_check_8251fifo(void)
-{
- u_char tmp1, tmp2;
-
- tmp1 = inb(I8251F_iir);
- DELAY(10);
- tmp2 = inb(I8251F_iir);
- if (((tmp1 ^ tmp2) & 0x40) != 0 && ((tmp1 | tmp2) & 0x20) == 0)
- return 1;
-
- return 0;
-}
-#endif /* PC98 defined */
diff --git a/sys/pc98/pc98/sio_cbus.c b/sys/pc98/pc98/sio_cbus.c
deleted file mode 100644
index a5c9946..0000000
--- a/sys/pc98/pc98/sio_cbus.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*-
- * Copyright (c) 2001 Yoshihiro TAKAHASHI. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/module.h>
-#include <sys/tty.h>
-#include <machine/bus.h>
-#include <sys/timepps.h>
-
-#include <dev/sio/siovar.h>
-
-#include <isa/isavar.h>
-
-static int sio_isa_attach(device_t dev);
-static int sio_isa_probe(device_t dev);
-
-static device_method_t sio_isa_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, sio_isa_probe),
- DEVMETHOD(device_attach, sio_isa_attach),
- DEVMETHOD(device_detach, siodetach),
-
- { 0, 0 }
-};
-
-static driver_t sio_isa_driver = {
- sio_driver_name,
- sio_isa_methods,
- 0,
-};
-
-static struct isa_pnp_id sio_ids[] = {
- {0x0100e4a5, "RSA-98III"},
- {0x4180a3b8, NULL}, /* NEC8041 - PC-9821CB-B04 */
- {0x0181a3b8, NULL}, /* NEC8101 - PC-9821CB2-B04 */
- {0x5181a3b8, NULL}, /* NEC8151 - Internal FAX/Modem for Cx3, Cb3 */
- {0x9181a3b8, NULL}, /* NEC8191 - NEC PC-9801-120 */
- {0xe181a3b8, NULL}, /* NEC81E1 - Internal FAX/Modem */
- {0x1182a3b8, NULL}, /* NEC8211 - PC-9801-123 */
- {0x3182a3b8, NULL}, /* NEC8231 - Internal FAX/Modem(Voice) */
- {0x4182a3b8, NULL}, /* NEC8241 - NEC PC-9821NR-B05 */
- {0x5182a3b8, NULL}, /* NEC8251 - Internel FAX/Modem */
- {0x7182a3b8, NULL}, /* NEC8271 - NEC PC-9801-125 */
- {0x11802fbf, NULL}, /* OYO8011 - Internal FAX/Modem for ValueStar(Ring) */
- {0}
-};
-
-static int
-sio_isa_probe(dev)
- device_t dev;
-{
- int logical_id;
-
- /* Check isapnp ids */
- if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO)
- return (ENXIO);
-
- logical_id = isa_get_logicalid(dev);
- switch (logical_id) {
- case 0x0100e4a5: /* RSA-98III */
- SET_FLAG(dev, SET_IFTYPE(COM_IF_RSA98III));
- break;
- case 0x4180a3b8: /* PC-9821CB-B04 */
- case 0x0181a3b8: /* PC-9821CB2-B04 */
- case 0x5181a3b8: /* for Cx3, Cb3 internal */
- case 0x9181a3b8: /* PC-9801-120 */
- case 0xe181a3b8: /* Internal FAX/Modem */
- case 0x1182a3b8: /* PC-9801-123 */
- case 0x3182a3b8: /* FAX/Voice/Modem internal */
- case 0x4182a3b8: /* PC-9821NR-B05 */
- case 0x5182a3b8: /* FAX/Modem internal */
- case 0x7182a3b8: /* PC-9801-125 */
- case 0x11802fbf: /* for ValueStar internal */
- SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550));
- break;
- }
-
- return (sioprobe(dev, 0, 0UL, 0));
-}
-
-static int
-sio_isa_attach(dev)
- device_t dev;
-{
- return (sioattach(dev, 0, 0UL));
-}
-
-DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0);
diff --git a/sys/pc98/pc98/syscons_pc98.c b/sys/pc98/pc98/syscons_pc98.c
deleted file mode 100644
index df8934e..0000000
--- a/sys/pc98/pc98/syscons_pc98.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*-
- * Copyright (c) 1999 FreeBSD(98) Porting Team.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
- *
- * $FreeBSD$
- */
-
-#include "opt_syscons.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/cons.h>
-#include <sys/consio.h>
-#include <sys/sysctl.h>
-
-#include <machine/clock.h>
-
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/pc98_machdep.h>
-
-#include <dev/syscons/syscons.h>
-
-#include <i386/isa/timerreg.h>
-
-#include <isa/isavar.h>
-
-static devclass_t sc_devclass;
-
-static sc_softc_t main_softc;
-#ifdef SC_NO_SUSPEND_VTYSWITCH
-static int sc_no_suspend_vtswitch = 1;
-#else
-static int sc_no_suspend_vtswitch = 0;
-#endif
-static int sc_cur_scr;
-
-TUNABLE_INT("hw.syscons.sc_no_suspend_vtswitch", (int *)&sc_no_suspend_vtswitch);
-SYSCTL_DECL(_hw_syscons);
-SYSCTL_INT(_hw_syscons, OID_AUTO, sc_no_suspend_vtswitch, CTLFLAG_RW,
- &sc_no_suspend_vtswitch, 0, "Disable VT switch before suspend.");
-
-static void
-scidentify (driver_t *driver, device_t parent)
-{
- BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "sc", 0);
-}
-
-static int
-scprobe(device_t dev)
-{
- /* No pnp support */
- if (isa_get_vendorid(dev))
- return (ENXIO);
-
- device_set_desc(dev, "System console");
- return sc_probe_unit(device_get_unit(dev), device_get_flags(dev));
-}
-
-static int
-scattach(device_t dev)
-{
- return sc_attach_unit(device_get_unit(dev), device_get_flags(dev));
-}
-
-static int
-scsuspend(device_t dev)
-{
- int retry = 10;
- static int dummy;
- sc_softc_t *sc;
-
- sc = &main_softc;
-
- if (sc->cur_scp == NULL)
- return (0);
-
- sc_cur_scr = sc->cur_scp->index;
-
- if (sc_no_suspend_vtswitch)
- return (0);
-
- do {
- sc_switch_scr(sc, 0);
- if (!sc->switch_in_progress) {
- break;
- }
- tsleep(&dummy, 0, "scsuspend", 100);
- } while (retry--);
-
- return (0);
-}
-
-static int
-scresume(device_t dev)
-{
- sc_softc_t *sc;
-
- if (sc_no_suspend_vtswitch)
- return (0);
-
- sc = &main_softc;
- sc_switch_scr(sc, sc_cur_scr);
-
- return (0);
-}
-
-int
-sc_max_unit(void)
-{
- return devclass_get_maxunit(sc_devclass);
-}
-
-sc_softc_t
-*sc_get_softc(int unit, int flags)
-{
- sc_softc_t *sc;
-
- if (unit < 0)
- return NULL;
- if (flags & SC_KERNEL_CONSOLE) {
- /* FIXME: clear if it is wired to another unit! */
- sc = &main_softc;
- } else {
- sc = (sc_softc_t *)device_get_softc(devclass_get_device(sc_devclass, unit));
- if (sc == NULL)
- return NULL;
- }
- sc->unit = unit;
- if (!(sc->flags & SC_INIT_DONE)) {
- sc->keyboard = -1;
- sc->adapter = -1;
- sc->mouse_char = SC_MOUSE_CHAR;
- }
- return sc;
-}
-
-sc_softc_t
-*sc_find_softc(struct video_adapter *adp, struct keyboard *kbd)
-{
- sc_softc_t *sc;
- int units;
- int i;
-
- sc = &main_softc;
- if (((adp == NULL) || (adp == sc->adp))
- && ((kbd == NULL) || (kbd == sc->kbd)))
- return sc;
- units = devclass_get_maxunit(sc_devclass);
- for (i = 0; i < units; ++i) {
- sc = (sc_softc_t *)device_get_softc(devclass_get_device(sc_devclass, i));
- if (sc == NULL)
- continue;
- if (((adp == NULL) || (adp == sc->adp))
- && ((kbd == NULL) || (kbd == sc->kbd)))
- return sc;
- }
- return NULL;
-}
-
-int
-sc_get_cons_priority(int *unit, int *flags)
-{
- const char *at;
- int u, f;
-
- *unit = -1;
- for (u = 0; u < 16; u++) {
- if (resource_disabled(SC_DRIVER_NAME, u))
- continue;
- if (resource_string_value(SC_DRIVER_NAME, u, "at", &at) != 0)
- continue;
- if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0)
- f = 0;
- if (f & SC_KERNEL_CONSOLE) {
- /* the user designates this unit to be the console */
- *unit = u;
- *flags = f;
- break;
- }
- if (*unit < 0) {
- /* ...otherwise remember the first found unit */
- *unit = u;
- *flags = f;
- }
- }
- if (*unit < 0)
- return CN_DEAD;
- return CN_INTERNAL;
-}
-
-void
-sc_get_bios_values(bios_values_t *values)
-{
- values->cursor_start = 15;
- values->cursor_end = 16;
- values->shift_state = 0;
- if (pc98_machine_type & M_8M)
- values->bell_pitch = BELL_PITCH_8M;
- else
- values->bell_pitch = BELL_PITCH_5M;
-}
-
-int
-sc_tone(int herz)
-{
- int pitch;
-
- if (herz) {
- /* enable counter 1 */
- outb(0x35, inb(0x35) & 0xf7);
- /* set command for counter 1, 2 byte write */
- if (acquire_timer1(TIMER_16BIT | TIMER_SQWAVE))
- return EBUSY;
- /* set pitch */
- pitch = timer_freq/herz;
- outb(TIMER_CNTR1, pitch);
- outb(TIMER_CNTR1, pitch >> 8);
- } else {
- /* disable counter 1 */
- outb(0x35, inb(0x35) | 0x08);
- release_timer1();
- }
- return 0;
-}
-
-static device_method_t sc_methods[] = {
- DEVMETHOD(device_identify, scidentify),
- DEVMETHOD(device_probe, scprobe),
- DEVMETHOD(device_attach, scattach),
- DEVMETHOD(device_suspend, scsuspend),
- DEVMETHOD(device_resume, scresume),
- { 0, 0 }
-};
-
-static driver_t sc_driver = {
- SC_DRIVER_NAME,
- sc_methods,
- sizeof(sc_softc_t),
-};
-
-DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
diff --git a/sys/pccard/pccard_nbk.c b/sys/pccard/pccard_nbk.c
index 3772ba8..bda9db1 100644
--- a/sys/pccard/pccard_nbk.c
+++ b/sys/pccard/pccard_nbk.c
@@ -64,7 +64,7 @@
/* XXX Shouldn't reach into the MD code here */
#ifdef PC98
-#include <pc98/pc98/pc98.h>
+#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
OpenPOWER on IntegriCloud