summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-08-27 16:55:42 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-08-27 16:55:42 +0000
commit8e348635a9f1cf593f640d0a9b7be6dcdec07dc6 (patch)
treede6a6739ddb2ef0e2d5812fa94d9459058c140e8 /sys/arch
parent5078cd3731f61a8f4967ae7620d9b07f41045098 (diff)
Work-in-progress VXT2000 support (commented out in GENERIC so far). Glass
console works on color model, serial console works, ethernet attaches but does not work correctly yet.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/vax/conf/GENERIC11
-rw-r--r--sys/arch/vax/conf/RAMDISK11
-rw-r--r--sys/arch/vax/conf/files.vax21
-rw-r--r--sys/arch/vax/include/clock.h4
-rw-r--r--sys/arch/vax/include/nexus.h3
-rw-r--r--sys/arch/vax/vax/clock.c33
-rw-r--r--sys/arch/vax/vax/conf.c19
-rw-r--r--sys/arch/vax/vax/findcpu.c6
-rw-r--r--sys/arch/vax/vax/led.c16
-rw-r--r--sys/arch/vax/vax/locore.c9
-rw-r--r--sys/arch/vax/vax/vxt.c137
-rw-r--r--sys/arch/vax/vax/wscons_machdep.c18
-rw-r--r--sys/arch/vax/vsa/lcspx.c73
-rw-r--r--sys/arch/vax/vxt/if_ze_vxtbus.c95
-rw-r--r--sys/arch/vax/vxt/qsc.c1078
-rw-r--r--sys/arch/vax/vxt/qsckbd.c290
-rw-r--r--sys/arch/vax/vxt/qscms.c167
-rw-r--r--sys/arch/vax/vxt/qscreg.h173
-rw-r--r--sys/arch/vax/vxt/qscvar.h115
-rw-r--r--sys/arch/vax/vxt/vxtbus.c156
-rw-r--r--sys/arch/vax/vxt/vxtbusvar.h28
21 files changed, 2432 insertions, 31 deletions
diff --git a/sys/arch/vax/conf/GENERIC b/sys/arch/vax/conf/GENERIC
index 557a2f954e1..4adf6670987 100644
--- a/sys/arch/vax/conf/GENERIC
+++ b/sys/arch/vax/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.45 2006/07/30 12:39:34 miod Exp $
+# $OpenBSD: GENERIC,v 1.46 2006/08/27 16:55:38 miod Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -30,6 +30,7 @@ option VAX46 # VS 4000/60
option VAX48 # VS 4000 VLC
option VAX49 # VS 4000/90
option VAX53 # VAX 4000 10X, MicroVAX 3100m9X
+#option VXT # VXT2000 and VXT2000+
# Old compat stuff; needed to run 4.3BSD Reno programs.
# Note that if COMPAT_ULTRIX is set, you lose compatibility with
@@ -53,6 +54,7 @@ vsbus0 at mainbus0 # All VAXstations
ibus0 at mainbus0 # All Microvax
#nbi0 at mainbus0 # VAX 8800
#xmi0 at mainbus0 # VAX 6000
+#vxtbus0 at mainbus0 # VXT2000
# Vsbus, the virtual VAXstation bus, and possible devices.
le0 at vsbus0 csr 0x200e0000 # LANCE ethernet
@@ -78,6 +80,11 @@ ze0 at ibus0 # SGEC on-board ethernet
le0 at ibus0 # LANCE ethernet (MV3400)
#shac0 at ibus0 # DSSI controller
+# VXT2000 devices
+#ze0 at vxtbus0 # SGEC on-board ethernet
+#qsc0 at vxtbus0 # serial ports
+#lcspx0 at vxtbus0 # color frame buffer
+
# Devices connected at VAXBI
#cpu* at bi? node? # KA820/KA825 cpu
#mem* at bi? node? # Memory subsystems
@@ -149,8 +156,10 @@ wsdisplay* at smg?
#wsdisplay* at qv0
lkkbd0 at dz0 line 0
+#lkkbd0 at qsc0 line 2
wskbd* at lkkbd?
lkms0 at dz0 line 1
+#lkms0 at qsc0 line 3
wsmouse* at lkms?
# Machine leds
diff --git a/sys/arch/vax/conf/RAMDISK b/sys/arch/vax/conf/RAMDISK
index fab68b18a2a..d36b74a7f40 100644
--- a/sys/arch/vax/conf/RAMDISK
+++ b/sys/arch/vax/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.25 2006/07/30 12:40:07 miod Exp $
+# $OpenBSD: RAMDISK,v 1.26 2006/08/27 16:55:38 miod Exp $
machine vax # machine type
@@ -22,6 +22,7 @@ option VAX46 # VS 4000/60
option VAX48 # VS 4000 VLC
option VAX49 # VS 4000/90
option VAX53 # VAX 4000/10{0,5,6}
+#option VXT # VXT2000 and VXT2000+
maxusers 8 # estimated number of users
option TIMEZONE=0 # time zone to adjust RTC time by
@@ -61,6 +62,7 @@ vsbus0 at mainbus0 # All VAXstations
ibus0 at mainbus0 # All Microvax
#nbi0 at mainbus0 # VAX 8800
#xmi0 at mainbus0 # VAX 6000
+#vxtbus0 at mainbus0 # VXT2000
# Vsbus, the virtual VAXstation bus, and possible devices.
le0 at vsbus0 csr 0x200e0000 # LANCE ethernet
@@ -86,6 +88,11 @@ ze0 at ibus0 # SGEC on-board ethernet
le0 at ibus0 # LANCE ethernet
#shac0 at ibus0 # DSSI controller
+# VXT2000 devices
+#ze0 at vxtbus0 # SGEC on-board ethernet
+#qsc0 at vxtbus0 # serial ports
+#lcspx0 at vxtbus0 # color frame buffer
+
# Devices connected at VAXBI
#cpu* at bi? node? # KA820/KA825 cpu
#mem* at bi? node? # Memory subsystems
@@ -157,8 +164,10 @@ wsdisplay* at smg?
#wsdisplay* at qv0
lkkbd0 at dz0 line 0
+#lkkbd0 at qsc0 line 2
wskbd* at lkkbd?
#lkms0 at dz0 line 1
+#lkms0 at qsc0 line 3
#wsmouse* at lkms?
pseudo-device loop 1 # network loopback
diff --git a/sys/arch/vax/conf/files.vax b/sys/arch/vax/conf/files.vax
index ceca8eeea07..c8b54c074a0 100644
--- a/sys/arch/vax/conf/files.vax
+++ b/sys/arch/vax/conf/files.vax
@@ -1,4 +1,4 @@
-# $OpenBSD: files.vax,v 1.39 2006/07/29 14:18:55 miod Exp $
+# $OpenBSD: files.vax,v 1.40 2006/08/27 16:55:38 miod Exp $
# $NetBSD: files.vax,v 1.60 1999/08/27 20:04:32 ragge Exp $
#
# new style config file for vax architecture
@@ -55,11 +55,17 @@ device ibus {}
attach ibus at mainbus
file arch/vax/vax/ibus.c ibus
+device vxtbus {}
+attach vxtbus at mainbus
+file arch/vax/vxt/vxtbus.c vxtbus
+
device ze: sgec, ether, ifnet
attach ze at ibus with ze_ibus
file arch/vax/if/if_ze.c ze_ibus
attach ze at vsbus with ze_vsbus
file arch/vax/vsa/if_ze_vsbus.c ze_vsbus
+attach ze at vxtbus with ze_vxtbus
+file arch/vax/vxt/if_ze_vxtbus.c ze_vxtbus
attach le at ibus with le_ibus
file arch/vax/if/if_le.c le_ibus
@@ -113,6 +119,11 @@ file arch/vax/uba/ts.c ts needs-flag
attach dz at vsbus with dz_vsbus
file arch/vax/vsa/dz_ibus.c dz_vsbus
+# VXT serial
+device qsc {line = -1}: tty
+attach qsc at vxtbus
+file arch/vax/vxt/qsc.c qsc needs-flag
+
# RD-type disks at VS2000's onboard MFM-controller
device hdc {drive = -1}
attach hdc at vsbus
@@ -174,16 +185,21 @@ file arch/vax/vsa/lcg.c lcg needs-flag
# LCSPX framebuffer on KA49
device lcspx: wsemuldisplaydev, rasops8
-attach lcspx at vsbus
+attach lcspx at vsbus with lcspx_vsbus
+attach lcspx at vxtbus with lcspx_vxtbus
file arch/vax/vsa/lcspx.c lcspx needs-flag
device lkkbd: wskbddev
attach lkkbd at dz with dzkbd
+attach lkkbd at qsc with qsckbd
file arch/vax/dec/dzkbd.c dzkbd needs-flag
+file arch/vax/vxt/qsckbd.c qsckbd needs-flag
device lkms: wsmousedev
attach lkms at dz with dzms
+attach lkms at qsc with qscms
file arch/vax/dec/dzms.c dzms needs-flag
+file arch/vax/vxt/qscms.c qscms needs-flag
# These devices aren't tested (or even compiled!)
# They are just included here to make some files happy ;)
@@ -348,6 +364,7 @@ file arch/vax/vax/ka650.c vax650
file arch/vax/vax/ka660.c vax660
file arch/vax/vax/ka670.c vax670
file arch/vax/vax/ka680.c vax680
+file arch/vax/vax/vxt.c vxt
file arch/vax/vax/scb.c
file arch/vax/vax/conf.c
file arch/vax/vax/urem.s
diff --git a/sys/arch/vax/include/clock.h b/sys/arch/vax/include/clock.h
index a5a53365087..6070eec3227 100644
--- a/sys/arch/vax/include/clock.h
+++ b/sys/arch/vax/include/clock.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.h,v 1.5 2002/03/14 01:26:48 millert Exp $ */
+/* $OpenBSD: clock.h,v 1.6 2006/08/27 16:55:41 miod Exp $ */
/* $NetBSD: clock.h,v 1.4 1999/09/06 19:52:53 ragge Exp $ */
/*
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
@@ -74,3 +74,5 @@ int generic_clkread(time_t);
void generic_clkwrite(void);
int chip_clkread(time_t);
void chip_clkwrite(void);
+int missing_clkread(time_t);
+void missing_clkwrite(void);
diff --git a/sys/arch/vax/include/nexus.h b/sys/arch/vax/include/nexus.h
index 62fddaa2e72..69c7583dc41 100644
--- a/sys/arch/vax/include/nexus.h
+++ b/sys/arch/vax/include/nexus.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: nexus.h,v 1.12 2006/07/20 19:15:34 miod Exp $ */
+/* $OpenBSD: nexus.h,v 1.13 2006/08/27 16:55:41 miod Exp $ */
/* $NetBSD: nexus.h,v 1.17 2000/06/04 17:58:19 ragge Exp $ */
/*-
@@ -53,6 +53,7 @@ struct mainbus_attach_args {
#define VAX_VSBUS 7 /* Virtual vaxstation bus */
#define VAX_IBUS 8 /* Internal Microvax bus */
#define VAX_XMIBUS 9 /* XMI master bus (6000) */
+#define VAX_VXTBUS 10 /* Pseudo VXT2000 bus */
#define VAX_LEDS 0x42 /* pseudo value to attach led0 */
diff --git a/sys/arch/vax/vax/clock.c b/sys/arch/vax/vax/clock.c
index 6f1919d7a0c..47b5e0bc20a 100644
--- a/sys/arch/vax/vax/clock.c
+++ b/sys/arch/vax/vax/clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.c,v 1.18 2004/07/07 23:10:46 deraadt Exp $ */
+/* $OpenBSD: clock.c,v 1.19 2006/08/27 16:55:41 miod Exp $ */
/* $NetBSD: clock.c,v 1.35 2000/06/04 06:16:58 matt Exp $ */
/*
* Copyright (c) 1995 Ludd, University of Lule}, Sweden.
@@ -66,15 +66,17 @@ microtime(tvp)
switch (vax_boardtype) {
#ifdef VAX46
- case VAX_BTYP_46: {
+ case VAX_BTYP_46:
+ {
extern struct vs_cpu *ka46_cpu;
i = *(volatile int *)(&ka46_cpu->vc_diagtimu);
i = (i >> 16) * 1024 + (i & 0x3ff);
+ }
break;
- }
#endif
-#ifdef VAX48
- case VAX_BTYP_48: {
+#if defined(VAX48) || defined(VXT)
+ case VAX_BTYP_48:
+ case VAX_BTYP_VXT:
/*
* PR_ICR doesn't exist. We could use the vc_diagtimu
* counter, saving the value on the timer interrupt and
@@ -82,7 +84,6 @@ microtime(tvp)
*/
i = 0;
break;
- }
#endif
default:
i = mfpr(PR_ICR);
@@ -176,7 +177,8 @@ delay(i)
void
cpu_initclocks()
{
- mtpr(-10000, PR_NICR); /* Load in count register */
+ if (vax_boardtype != VAX_BTYP_VXT)
+ mtpr(-10000, PR_NICR); /* Load in count register */
mtpr(0x800000d1, PR_ICCS); /* Start clock and enable interrupt */
evcount_attach(&clock_intrcnt, "clock", NULL, &evcount_intr);
}
@@ -210,7 +212,7 @@ numtoyear(num)
int num;
{
int y = 70, j;
- while(num >= (j = SECPERYEAR(y))) {
+ while (num >= (j = SECPERYEAR(y))) {
y++;
num -= j;
}
@@ -328,3 +330,18 @@ chip_clkwrite()
REGPOKE(CSRB_OFF, CSRB_DM|CSRB_24);
};
#endif
+
+#if VXT
+int
+missing_clkread(base)
+ time_t base;
+{
+ printf("WARNING: no TOY clock");
+ return CLKREAD_BAD;
+}
+
+void
+missing_clkwrite()
+{
+}
+#endif
diff --git a/sys/arch/vax/vax/conf.c b/sys/arch/vax/vax/conf.c
index 080f87d20fa..dde59a7f14c 100644
--- a/sys/arch/vax/vax/conf.c
+++ b/sys/arch/vax/vax/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.48 2006/07/30 12:32:43 miod Exp $ */
+/* $OpenBSD: conf.c,v 1.49 2006/08/27 16:55:41 miod Exp $ */
/* $NetBSD: conf.c,v 1.44 1999/10/27 16:38:54 ragge Exp $ */
/*-
@@ -145,9 +145,12 @@ int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
cons_decl(dz);
cons_decl(gen);
cons_decl(qd);
+cons_decl(qsc);
cons_decl(ws);
+#include "dz.h"
#include "qd.h"
+#include "qsc.h"
#include "qv.h"
#include "wsdisplay.h"
#include "wskbd.h"
@@ -161,8 +164,15 @@ struct consdev constab[]={
#define NGEN 0
#endif
#if VAX410 || VAX43 || VAX46 || VAX48 || VAX49 || VAX53
+#if NDZ > 0
cons_init(dz), /* DZ11-like serial console on VAXstations */
#endif
+#endif
+#ifdef VXT
+#if NQSC > 0
+ cons_init(qsc), /* SC26C94 serial console on VXT2000 */
+#endif
+#endif
#if VAX650 || VAX630
#if NQV
cons_init(qv), /* QVSS/QDSS bit-mapped console driver */
@@ -172,7 +182,7 @@ struct consdev constab[]={
#endif
#endif
#if NWSDISPLAY > 0 || NWSKBD > 0
- cons_init(ws),
+ cons_init(ws), /* any other frame buffer console */
#endif
#ifdef notyet
@@ -277,7 +287,8 @@ cdev_decl(crx);
#define cflwrite cflrw
cdev_decl(cfl);
-#include "dz.h"
+cdev_decl(qsc);
+
cdev_decl(dz);
#include "vp.h"
@@ -393,7 +404,7 @@ struct cdevsw cdevsw[] =
cdev_notdef(), /* 45 was Datakit */
cdev_notdef(), /* 46 was Datakit */
cdev_notdef(), /* 47 */
- cdev_notdef(), /* 48 */
+ cdev_tty_init(NQSC,qsc), /* 48: SC26C94 on VXT2000 */
cdev_systrace_init(NSYSTRACE,systrace), /* 49: system call tracing */
cdev_ksyms_init(NKSYMS,ksyms), /* 50: Kernel symbols device */
cdev_cnstore_init(NCRX,crx), /* 51: Console RX50 at 8200 */
diff --git a/sys/arch/vax/vax/findcpu.c b/sys/arch/vax/vax/findcpu.c
index d388faae50a..bc6a4b65b34 100644
--- a/sys/arch/vax/vax/findcpu.c
+++ b/sys/arch/vax/vax/findcpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: findcpu.c,v 1.11 2006/07/20 19:07:14 miod Exp $ */
+/* $OpenBSD: findcpu.c,v 1.12 2006/08/27 16:55:41 miod Exp $ */
/* $NetBSD: findcpu.c,v 1.5 1999/08/23 19:10:43 ragge Exp $ */
/*
* Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden.
@@ -99,6 +99,10 @@ findcpu(void)
vax_confdata = *(int *)(0x25800000);
vax_bustype = VAX_VSBUS;
break;
+ case VAX_BTYP_VXT:
+ vax_confdata = *(int *)(0x200c0000);
+ vax_bustype = VAX_VXTBUS;
+ break;
case VAX_BTYP_9CC:
case VAX_BTYP_9RR:
diff --git a/sys/arch/vax/vax/led.c b/sys/arch/vax/vax/led.c
index d97db5d0558..e04f06e2d5c 100644
--- a/sys/arch/vax/vax/led.c
+++ b/sys/arch/vax/vax/led.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: led.c,v 1.3 2006/08/01 18:08:55 deraadt Exp $ */
+/* $OpenBSD: led.c,v 1.4 2006/08/27 16:55:41 miod Exp $ */
/* $NetBSD: leds.c,v 1.4 2005/12/11 12:19:37 christos Exp $ */
/*
@@ -116,7 +116,7 @@ ledmatch(struct device *parent, void *cf, void *aux)
return (0);
switch (vax_boardtype) {
-#if VAX46 || VAX48 || VAX49 || VAX53
+#if VAX46 || VAX48 || VAX49 || VAX53 || VXT
#if VAX46
case VAX_BTYP_46:
#endif
@@ -129,6 +129,9 @@ ledmatch(struct device *parent, void *cf, void *aux)
#if VAX53
case VAX_BTYP_1303:
#endif
+#if VXT
+ case VAX_BTYP_VXT:
+#endif
return (1);
#endif
default:
@@ -140,7 +143,7 @@ void
ledattach(struct device *parent, struct device *self, void *aux)
{
struct led_softc *sc = (void *)self;
-#if VAX49 || VAX53
+#if VAX49 || VAX53 || VXT
vaddr_t pgva;
#endif
@@ -179,6 +182,13 @@ ledattach(struct device *parent, struct device *self, void *aux)
sc->sc_pat = led_pattern4;
break;
#endif
+#if VXT
+ case VAX_BTYP_VXT:
+ pgva = vax_map_physmem(0x200c1000, 1);
+ sc->sc_reg = (volatile u_short *)pgva;
+ sc->sc_pat = led_pattern8;
+ break;
+#endif
}
sc->sc_patpos = sc->sc_pat;
diff --git a/sys/arch/vax/vax/locore.c b/sys/arch/vax/vax/locore.c
index 01cd4adf942..a5e38e0f895 100644
--- a/sys/arch/vax/vax/locore.c
+++ b/sys/arch/vax/vax/locore.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.c,v 1.31 2006/08/15 20:27:41 miod Exp $ */
+/* $OpenBSD: locore.c,v 1.32 2006/08/27 16:55:41 miod Exp $ */
/* $NetBSD: locore.c,v 1.43 2000/03/26 11:39:45 ragge Exp $ */
/*
* Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden.
@@ -78,6 +78,7 @@ extern struct cpu_dep ka650_calls;
extern struct cpu_dep ka660_calls;
extern struct cpu_dep ka670_calls;
extern struct cpu_dep ka680_calls;
+extern struct cpu_dep vxt_calls;
/*
* Start is called from boot; the first routine that is called
@@ -165,6 +166,12 @@ start(struct rpb *prpb)
}
break;
#endif
+#ifdef VXT
+ case VAX_BTYP_VXT:
+ dep_call = &vxt_calls;
+ strlcpy(cpu_model, "VXT2000", sizeof cpu_model);
+ break;
+#endif
#if VAX48
case VAX_BTYP_48:
dep_call = &ka48_calls;
diff --git a/sys/arch/vax/vax/vxt.c b/sys/arch/vax/vax/vxt.c
new file mode 100644
index 00000000000..fd18a73a06a
--- /dev/null
+++ b/sys/arch/vax/vax/vxt.c
@@ -0,0 +1,137 @@
+/* $OpenBSD: vxt.c,v 1.1 2006/08/27 16:55:41 miod Exp $ */
+/*
+ * Copyright (c) 1998 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Ludd by Bertram Barth.
+ *
+ * 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 at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*** needs to be completed MK-990306 ***/
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/cpu.h>
+#include <machine/mtpr.h>
+#include <machine/ka48.h>
+#include <machine/clock.h>
+
+static void vxt_conf(void);
+static void vxt_steal_pages(void);
+static void vxt_memerr(void);
+static int vxt_mchk(caddr_t);
+static void vxt_halt(void);
+static void vxt_reboot(int);
+static void vxt_cache_enable(void);
+
+struct vs_cpu *vxt_cpu;
+
+/*
+ * Declaration of vxt-specific calls.
+ */
+
+struct cpu_dep vxt_calls = {
+ vxt_steal_pages,
+ vxt_mchk,
+ vxt_memerr,
+ vxt_conf,
+ missing_clkread,
+ missing_clkwrite,
+ 6, /* ~VUPS */
+ 2, /* SCB pages */
+ vxt_halt,
+ vxt_reboot,
+};
+
+void
+vxt_conf()
+{
+ printf("cpu: KA48\n");
+}
+
+void
+vxt_cache_enable()
+{
+ int i, *tmp;
+ long *par_ctl = (long *)KA48_PARCTL;
+
+ /* Disable cache */
+ mtpr(0, PR_CADR); /* disable */
+ *par_ctl &= ~KA48_PARCTL_INVENA; /* clear ? invalid enable */
+ mtpr(2, PR_CADR); /* flush */
+
+ /* Clear caches */
+ tmp = (void *)KA48_INVFLT; /* inv filter */
+ for (i = 0; i < KA48_INVFLTSZ / sizeof(int); i++)
+ tmp[i] = 0;
+ *par_ctl |= KA48_PARCTL_INVENA; /* Enable ???? */
+ mtpr(4, PR_CADR); /* enable cache */
+ *par_ctl |= (KA48_PARCTL_AGS | /* AGS? */
+ KA48_PARCTL_NPEN | /* N? Parity Enable */
+ KA48_PARCTL_CPEN); /* Cpu parity enable */
+}
+
+void
+vxt_memerr()
+{
+ printf("Memory err!\n");
+}
+
+int
+vxt_mchk(addr)
+ caddr_t addr;
+{
+ panic("Machine check");
+ return 0;
+}
+
+void
+vxt_steal_pages()
+{
+ /* Turn on caches (to speed up execution a bit) */
+ vxt_cache_enable();
+}
+
+static void
+vxt_halt()
+{
+ asm("halt");
+}
+
+static void
+vxt_reboot(arg)
+ int arg;
+{
+ asm("halt");
+}
diff --git a/sys/arch/vax/vax/wscons_machdep.c b/sys/arch/vax/vax/wscons_machdep.c
index 80f84d8f235..bb47bbba895 100644
--- a/sys/arch/vax/vax/wscons_machdep.c
+++ b/sys/arch/vax/vax/wscons_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wscons_machdep.c,v 1.1 2006/07/29 14:18:57 miod Exp $ */
+/* $OpenBSD: wscons_machdep.c,v 1.2 2006/08/27 16:55:41 miod Exp $ */
/*
* Copyright (c) 2006 Miodrag Vallat.
*
@@ -23,6 +23,7 @@
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <machine/nexus.h>
#include <machine/vsbus.h>
#include <machine/scb.h>
#include <machine/sid.h>
@@ -41,6 +42,10 @@
#include <vax/qbus/dzvar.h>
#include <vax/dec/dzkbdvar.h>
+#include "qsckbd.h"
+
+#include <vax/vxt/qscvar.h>
+
#include "gpx.h"
#include "lcg.h"
#include "lcspx.h"
@@ -102,9 +107,18 @@ wscninit(struct consdev *cp)
{
(*wsfbcninit)();
+ switch (vax_bustype) {
+ case VAX_VSBUS:
#if NDZKBD > 0
- dzkbd_cnattach(0); /* Connect keyboard and screen together */
+ dzkbd_cnattach(0); /* Connect keyboard and screen together */
+#endif
+ break;
+ case VAX_VXTBUS:
+#if NQSCKBD > 0
+ qsckbd_cnattach(QSC_LINE_KEYBOARD);
#endif
+ break;
+ }
}
void
diff --git a/sys/arch/vax/vsa/lcspx.c b/sys/arch/vax/vsa/lcspx.c
index fd6b07ec1b1..bcf7c62dea2 100644
--- a/sys/arch/vax/vsa/lcspx.c
+++ b/sys/arch/vax/vsa/lcspx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lcspx.c,v 1.9 2006/08/26 17:39:53 miod Exp $ */
+/* $OpenBSD: lcspx.c,v 1.10 2006/08/27 16:55:41 miod Exp $ */
/*
* Copyright (c) 2006 Miodrag Vallat.
*
@@ -53,6 +53,7 @@
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <machine/nexus.h>
#include <machine/vsbus.h>
#include <machine/scb.h>
#include <machine/sid.h>
@@ -79,8 +80,9 @@
#define LCSPX_HEIGHT 1024
#define LCSPX_FBSIZE (LCSPX_WIDTH * LCSPX_HEIGHT)
-int lcspx_match(struct device *, void *, void *);
void lcspx_attach(struct device *, struct device *, void *);
+int lcspx_vsbus_match(struct device *, void *, void *);
+int lcspx_vxtbus_match(struct device *, void *, void *);
struct lcspx_screen {
struct rasops_info ss_ri;
@@ -104,8 +106,12 @@ struct lcspx_softc {
int sc_nscreens;
};
-struct cfattach lcspx_ca = {
- sizeof(struct lcspx_softc), lcspx_match, lcspx_attach,
+struct cfattach lcspx_vsbus_ca = {
+ sizeof(struct lcspx_softc), lcspx_vsbus_match, lcspx_attach,
+};
+
+struct cfattach lcspx_vxtbus_ca = {
+ sizeof(struct lcspx_softc), lcspx_vxtbus_match, lcspx_attach,
};
struct cfdriver lcspx_cd = {
@@ -154,7 +160,7 @@ void lcspx_resetcmap(struct lcspx_screen *);
int lcspx_setup_screen(struct lcspx_screen *);
int
-lcspx_match(struct device *parent, void *vcf, void *aux)
+lcspx_vsbus_match(struct device *parent, void *vcf, void *aux)
{
struct vsbus_softc *sc = (void *)parent;
struct vsbus_attach_args *va = aux;
@@ -178,6 +184,34 @@ lcspx_match(struct device *parent, void *vcf, void *aux)
return (20);
}
+int
+lcspx_vxtbus_match(struct device *parent, void *vcf, void *aux)
+{
+ struct bp_conf *bp = aux;
+ int missing;
+ volatile u_int8_t *ch;
+
+ if (strcmp(bp->type, lcspx_cd.cd_name) != 0)
+ return (0);
+
+ /*
+ * Check for video memory at SPX address.
+ */
+ missing = 0;
+ ch = (volatile u_int8_t *)vax_map_physmem(LCSPX_FB_ADDR, 1);
+ *ch = 0x01;
+ if ((*ch & 0x01) == 0)
+ missing = 1;
+ else {
+ *ch = 0x00;
+ if ((*ch & 0x01) != 0)
+ missing = 1;
+ }
+ vax_unmap_physmem((vaddr_t)ch, 1);
+
+ return (missing ? 0 : 1);
+}
+
void
lcspx_attach(struct device *parent, struct device *self, void *aux)
{
@@ -187,7 +221,13 @@ lcspx_attach(struct device *parent, struct device *self, void *aux)
int i, console;
extern struct consdev wsdisplay_cons;
- console = (vax_confdata & 8) == 0 && cn_tab == &wsdisplay_cons;
+ if (cn_tab == &wsdisplay_cons) {
+ if (vax_boardtype == VAX_BTYP_49)
+ console = (vax_confdata & 8) == 0;
+ else /* VXT2000 */
+ console = (vax_confdata & 2) != 0;
+ } else
+ console = 0;
if (console) {
ss = &lcspx_consscr;
sc->sc_nscreens = 1;
@@ -498,6 +538,9 @@ void lcspxcninit(void);
int
lcspxcnprobe()
{
+ extern vaddr_t virtual_avail;
+ volatile u_int8_t *ch;
+
switch (vax_boardtype) {
case VAX_BTYP_49:
if ((vax_confdata & 8) != 0)
@@ -508,6 +551,24 @@ lcspxcnprobe()
return (1);
+ case VAX_BTYP_VXT:
+ if ((vax_confdata & 2) == 0)
+ break; /* doesn't use graphics console */
+
+ /*
+ * Check for video memory at SPX address.
+ */
+ ioaccess(virtual_avail, LCSPX_FB_ADDR, 1);
+ ch = (volatile u_int8_t *)virtual_avail;
+ *ch = 0x01;
+ if ((*ch & 0x01) == 0)
+ break;
+ *ch = 0x00;
+ if ((*ch & 0x01) != 0)
+ break;
+
+ return (1);
+
default:
break;
}
diff --git a/sys/arch/vax/vxt/if_ze_vxtbus.c b/sys/arch/vax/vxt/if_ze_vxtbus.c
new file mode 100644
index 00000000000..ee4e4ed08e1
--- /dev/null
+++ b/sys/arch/vax/vxt/if_ze_vxtbus.c
@@ -0,0 +1,95 @@
+/* $OpenBSD: if_ze_vxtbus.c,v 1.1 2006/08/27 16:55:41 miod Exp $ */
+/*
+ * Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/nexus.h>
+
+#include <vax/if/sgecreg.h>
+#include <vax/if/sgecvar.h>
+
+#include <vax/vxt/vxtbusvar.h>
+
+int ze_vxt_match(struct device *, void *, void *);
+void ze_vxt_attach(struct device *, struct device *, void *);
+
+struct cfattach ze_vxtbus_ca = {
+ sizeof(struct ze_softc), ze_vxt_match, ze_vxt_attach
+};
+
+int
+ze_vxt_match(struct device *parent, void *vcf, void *aux)
+{
+ struct bp_conf *bp = aux;
+
+ if (strcmp(bp->type, "sgec") == 0)
+ return (1);
+ return (0);
+}
+
+void
+ze_vxt_attach(struct device *parent, struct device *self, void *aux)
+{
+ extern struct vax_bus_dma_tag vax_bus_dma_tag;
+ struct ze_softc *sc = (void *)self;
+ int *ea, i;
+
+ /*
+ * Map in SGEC registers.
+ */
+ sc->sc_ioh = vax_map_physmem(SGECADDR_VXT, 1);
+ sc->sc_iot = 0; /* :-) */
+ sc->sc_dmat = &vax_bus_dma_tag;
+
+ sc->sc_intvec = VXT_INTRVEC;
+ vxtbus_intr_establish(self->dv_xname, IPL_NET,
+ (int (*)(void *))sgec_intr, sc);
+
+ /*
+ * Map in, read and release ethernet rom address.
+ */
+ ea = (int *)vax_map_physmem(NISA_ROM_VXT, 1);
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ sc->sc_ac.ac_enaddr[i] = ea[i] & 0xff;
+ vax_unmap_physmem((vaddr_t)ea, 1);
+
+ sgec_attach(sc);
+}
diff --git a/sys/arch/vax/vxt/qsc.c b/sys/arch/vax/vxt/qsc.c
new file mode 100644
index 00000000000..ce8a1e65bfd
--- /dev/null
+++ b/sys/arch/vax/vxt/qsc.c
@@ -0,0 +1,1078 @@
+/* $OpenBSD: qsc.c,v 1.1 2006/08/27 16:55:41 miod Exp $ */
+/*
+ * Copyright (c) 2006 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice, this permission notice, and the disclaimer below
+ * appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/syslog.h>
+#include <sys/conf.h>
+
+#include <machine/bus.h>
+#include <machine/nexus.h>
+#include <machine/sid.h>
+
+#include <dev/cons.h>
+
+#include <vax/vxt/vxtbusvar.h>
+
+#include <vax/vxt/qscreg.h>
+#include <vax/vxt/qscvar.h>
+
+#ifdef DDB
+#include <machine/cpu.h>
+#include <ddb/db_var.h>
+#endif
+
+#include "qsckbd.h"
+#include "qscms.h"
+
+struct cfdriver qsc_cd = {
+ NULL, "qsc", DV_TTY
+};
+
+/* console storage */
+struct qsc_sv_reg qsccn_sv;
+
+/* prototypes */
+cdev_decl(qsc);
+cons_decl(qsc);
+int qscintr(void *);
+int qscparam(struct tty *, struct termios *);
+void qscrint(struct qscsoftc *, u_int);
+int qscspeed(int);
+void qscstart(struct tty *);
+struct tty *qsctty(dev_t);
+void qscxint(struct qscsoftc *, u_int);
+
+/*
+ * Registers are mapped as the least-significant byte of 32-bit
+ * addresses. The following macros hide this.
+ */
+
+#define qsc_readp(sc, reg) \
+ bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, 4 * (reg))
+#define qsc_read(sc, line, reg) \
+ bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, \
+ (sc)->sc_regaddr[line][reg])
+#define qsc_writep(sc, reg, val) \
+ bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, 4 * (reg), (val))
+#define qsc_write(sc, line, reg, val) \
+ bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, \
+ (sc)->sc_regaddr[line][reg], (val))
+
+#define SC_LINE(dev) (minor(dev))
+
+/*
+ * Attachment glue.
+ */
+
+int qsc_match(struct device *parent, void *self, void *aux);
+void qsc_attach(struct device *parent, struct device *self, void *aux);
+int qsc_print(void *, const char *);
+
+struct cfattach qsc_ca = {
+ sizeof(struct qscsoftc), qsc_match, qsc_attach
+};
+
+int
+qsc_match(struct device *parent, void *cf, void *aux)
+{
+ struct bp_conf *bp = aux;
+
+ if (strcmp(bp->type, qsc_cd.cd_name) == 0)
+ return (1);
+ return (0);
+}
+
+void
+qsc_attach(struct device *parent, struct device *self, void *aux)
+{
+ extern struct vax_bus_space vax_mem_bus_space;
+ struct qscsoftc *sc = (struct qscsoftc *)self;
+ bus_space_handle_t ioh;
+ u_int line, pair, reg;
+#if NQSCKBD > 0 || NQSCMS > 0
+ struct qsc_attach_args qa;
+#endif
+
+ sc->sc_iot = &vax_mem_bus_space;
+ if (bus_space_map(sc->sc_iot, QSCADDR, VAX_NBPG, 0, &ioh) != 0) {
+ printf(": can't map registers!\n");
+ return;
+ }
+ sc->sc_ioh = ioh;
+
+ if (cn_tab->cn_putc == qsccnputc) {
+ sc->sc_console = 1;
+ printf(": console");
+ }
+
+ /*
+ * Initialize line-specific data (register addresses)
+ */
+
+ for (line = 0; line < SC_NLINES; line++) {
+ sc->sc_regaddr[line][SC_MR] = line * 8 + SC_MRA;
+ sc->sc_regaddr[line][SC_CSR] = line * 8 + SC_CSRA;
+ sc->sc_regaddr[line][SC_CR] = line * 8 + SC_CRA;
+ sc->sc_regaddr[line][SC_TXFIFO] = line * 8 + SC_TXFIFOA;
+
+ sc->sc_regaddr[line][SC_IOPCR] = (line < 2 ? 0 : 0x10) +
+ (line & 1) + SC_IOPCRA;
+
+ sc->sc_regaddr[line][SC_ACR] = (line < 2 ? 0 : 0x10) + SC_ACRAB;
+ sc->sc_regaddr[line][SC_IMR] = (line < 2 ? 0 : 0x10) + SC_IMRAB;
+ sc->sc_regaddr[line][SC_OPR] = (line < 2 ? 0 : 0x10) + SC_OPRAB;
+ }
+ for (line = 0; line < SC_NLINES; line++)
+ for (reg = 0; reg < SC_LOGICAL; reg++)
+ sc->sc_regaddr[line][reg] =
+ 0 + 4 * sc->sc_regaddr[line][reg];
+
+ /*
+ * Initialize all lines.
+ */
+ sc->sc_sv_reg = sc->sc_console ? &qsccn_sv : &sc->sc_sv_reg_storage;
+ for (line = 0; line < SC_NLINES; line++) {
+ /* do not reinitialize the console line... */
+ if (sc->sc_console && line == QSC_LINE_SERIAL)
+ continue;
+
+ sc->sc_sv_reg->sv_mr1[line] =
+ (line == 3 ? ODDPAR | PAREN : PARDIS) | RXRTS | CL8;
+ sc->sc_sv_reg->sv_mr2[line] = /* TXCTS | */ SB1;
+ sc->sc_sv_reg->sv_csr[line] = line < 2 ? BD9600 : BD4800;
+ sc->sc_sv_reg->sv_cr[line] = TXEN | RXEN;
+
+ pair = line >> 1;
+
+ if (sc->sc_console && pair == (QSC_LINE_SERIAL >> 1))
+ continue;
+
+ /* Start out with Tx and RX interrupts disabled */
+ sc->sc_sv_reg->sv_imr[pair] = 0;
+ }
+
+ for (line = 0; line < SC_NLINES; line++) {
+ /* do not reset the console line... */
+ if (sc->sc_console && line == QSC_LINE_SERIAL)
+ continue;
+
+ qsc_write(sc, line, SC_CR, RXRESET | TXDIS | RXDIS);
+ DELAY(1);
+ qsc_write(sc, line, SC_CR, TXRESET | TXDIS | RXDIS);
+ DELAY(1);
+ qsc_write(sc, line, SC_CR, ERRRESET | TXDIS | RXDIS);
+ DELAY(1);
+ qsc_write(sc, line, SC_CR, BRKINTRESET | TXDIS | RXDIS);
+ DELAY(1);
+ qsc_write(sc, line, SC_CR, MRZERO | TXDIS | RXDIS);
+ DELAY(1);
+
+ qsc_write(sc, line, SC_MR, 0);
+ qsc_write(sc, line, SC_MR, sc->sc_sv_reg->sv_mr1[line]);
+ qsc_write(sc, line, SC_MR, sc->sc_sv_reg->sv_mr2[line]);
+ qsc_write(sc, line, SC_CSR, sc->sc_sv_reg->sv_csr[line]);
+ qsc_write(sc, line, SC_CR, sc->sc_sv_reg->sv_cr[line]);
+ DELAY(1);
+ }
+
+ for (pair = 0; pair < SC_NLINES / 2; pair++)
+ qsc_write(sc, pair << 1, SC_IMR,
+ sc->sc_sv_reg->sv_imr[pair]);
+
+ for (line = 0; line < SC_NLINES; line++) {
+ sc->sc_tty[line] = NULL;
+ sc->sc_swflags[line] = 0;
+ }
+ if (sc->sc_console)
+ sc->sc_swflags[QSC_LINE_SERIAL] |= TIOCFLAG_SOFTCAR;
+
+ printf("\n");
+
+ /*
+ * Configure interrupts. We are bidding in 2681 mode for now.
+ */
+
+ qsc_writep(sc, SC_ICR, 0x00);
+ for (line = SC_BIDCRA; line <= SC_BIDCRD; line++)
+ qsc_writep(sc, line, 0x00);
+ qsc_writep(sc, SC_IVR, VXT_INTRVEC >> 2);
+
+ vxtbus_intr_establish(self->dv_xname, IPL_TTY, qscintr, sc);
+
+ /*
+ * Attach subdevices, and enable RX and TX interrupts on their lines
+ * if successful.
+ */
+#if NQSCKBD > 0
+ /* keyboard */
+ qa.qa_line = QSC_LINE_KEYBOARD;
+ qa.qa_console = !sc->sc_console;
+ qa.qa_hook = &sc->sc_hook[QSC_LINE_KEYBOARD];
+ if (config_found(self, &qa, qsc_print) != NULL)
+ sc->sc_sv_reg->sv_imr[QSC_LINE_KEYBOARD >> 1] |= IRXRDYA;
+#endif
+#if NQSCMS > 0
+ /* mouse */
+ qa.qa_line = QSC_LINE_MOUSE;
+ qa.qa_console = 0;
+ qa.qa_hook = &sc->sc_hook[QSC_LINE_MOUSE];
+ if (config_found(self, &qa, qsc_print) != NULL)
+ sc->sc_sv_reg->sv_imr[QSC_LINE_MOUSE >> 1] |= IRXRDYB;
+#endif
+
+ for (pair = 0; pair < SC_NLINES / 2; pair++)
+ qsc_write(sc, pair << 1, SC_IMR,
+ sc->sc_sv_reg->sv_imr[pair]);
+
+ sc->sc_rdy = 1;
+}
+
+/* speed tables */
+const struct qsc_s {
+ int kspeed;
+ int dspeed;
+} qsc_speeds[] = {
+ { B0, 0 }, /* 0 baud, special HUP condition */
+ { B50, NOBAUD }, /* 50 baud, not implemented */
+ { B75, BD75 }, /* 75 baud */
+ { B110, BD110 }, /* 110 baud */
+ { B134, BD134 }, /* 134.5 baud */
+ { B150, BD150 }, /* 150 baud */
+ { B200, NOBAUD }, /* 200 baud, not implemented */
+ { B300, BD300 }, /* 300 baud */
+ { B600, BD600 }, /* 600 baud */
+ { B1200, BD1200 }, /* 1200 baud */
+ { B1800, BD1800 }, /* 1800 baud */
+ { B2400, BD2400 }, /* 2400 baud */
+ { B4800, BD4800 }, /* 4800 baud */
+ { B9600, BD9600 }, /* 9600 baud */
+ { B19200, BD19200 }, /* 19200 baud */
+ { -1, NOBAUD }, /* anything more is uncivilized */
+};
+
+int
+qscspeed(int speed)
+{
+ const struct qsc_s *ds;
+
+ for (ds = qsc_speeds; ds->kspeed != -1; ds++)
+ if (ds->kspeed == speed)
+ return ds->dspeed;
+
+ return NOBAUD;
+}
+
+struct tty *
+qsctty(dev_t dev)
+{
+ u_int line;
+ struct qscsoftc *sc;
+
+ line = SC_LINE(dev);
+ if (qsc_cd.cd_ndevs == 0 || line >= SC_NLINES)
+ return (NULL);
+
+ sc = (struct qscsoftc *)qsc_cd.cd_devs[0];
+ if (sc == NULL)
+ return (NULL);
+
+ return sc->sc_tty[line];
+}
+
+void
+qscstart(struct tty *tp)
+{
+ struct qscsoftc *sc;
+ dev_t dev;
+ int s;
+ u_int line;
+ int c, tries;
+
+ if ((tp->t_state & TS_ISOPEN) == 0)
+ return;
+
+ dev = tp->t_dev;
+ line = SC_LINE(dev);
+ sc = (struct qscsoftc *)qsc_cd.cd_devs[0];
+
+ s = spltty();
+
+ if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
+ goto bail;
+
+ if (tp->t_outq.c_cc <= tp->t_lowat) {
+ if (tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup((caddr_t)&tp->t_outq);
+ }
+ selwakeup(&tp->t_wsel);
+ if (tp->t_outq.c_cc == 0)
+ goto bail;
+ }
+
+ tp->t_state |= TS_BUSY;
+ while (tp->t_outq.c_cc != 0) {
+
+ /* load transmitter until it is full */
+ for (tries = 10000; tries != 0; tries --)
+ if (qsc_read(sc, line, SC_SR) & TXRDY)
+ break;
+
+ if (tries == 0) {
+ timeout_add(&tp->t_rstrt_to, 1);
+ tp->t_state |= TS_TIMEOUT;
+ break;
+ } else {
+ c = getc(&tp->t_outq);
+
+ qsc_write(sc, line, SC_TXFIFO, c & 0xff);
+
+ sc->sc_sv_reg->sv_imr[line >> 1] |=
+ line & 1 ? ITXRDYB : ITXRDYA;
+ qsc_write(sc, line, SC_IMR,
+ sc->sc_sv_reg->sv_imr[line >> 1]);
+ }
+ }
+ tp->t_state &= ~TS_BUSY;
+
+bail:
+ splx(s);
+}
+
+int
+qscstop(struct tty *tp, int flag)
+{
+ int s;
+
+ s = spltty();
+ if (tp->t_state & TS_BUSY) {
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+ }
+ splx(s);
+
+ return 0;
+}
+
+int
+qscioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ int error;
+ u_int line;
+ struct tty *tp;
+ struct qscsoftc *sc;
+
+ line = SC_LINE(dev);
+ sc = (struct qscsoftc *)qsc_cd.cd_devs[0];
+
+ tp = sc->sc_tty[line];
+ if (tp == NULL)
+ return (ENXIO);
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return(error);
+
+ error = ttioctl(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return(error);
+
+ switch (cmd) {
+ case TIOCGFLAGS:
+ *(int *)data = sc->sc_swflags[line];
+ break;
+ case TIOCSFLAGS:
+ error = suser(p, 0);
+ if (error != 0)
+ return (EPERM);
+
+ sc->sc_swflags[line] = *(int *)data &
+ /* only allow valid flags */
+ (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
+ break;
+ default:
+ return (ENOTTY);
+ }
+
+ return (0);
+}
+
+int
+qscparam(struct tty *tp, struct termios *t)
+{
+ int flags;
+ u_int line, pair;
+ int speeds;
+ u_int8_t mr1, mr2;
+ struct qscsoftc *sc;
+ dev_t dev;
+
+ dev = tp->t_dev;
+ line = SC_LINE(dev);
+ pair = line >> 1;
+ sc = (struct qscsoftc *)qsc_cd.cd_devs[0];
+
+ tp->t_ispeed = t->c_ispeed;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = t->c_cflag;
+
+ flags = tp->t_flags;
+
+ /* disable Tx and Rx */
+ if (sc->sc_console == 0 || line != QSC_LINE_SERIAL) {
+ if (line & 1)
+ sc->sc_sv_reg->sv_imr[pair] &= ~(ITXRDYB | IRXRDYB);
+ else
+ sc->sc_sv_reg->sv_imr[pair] &= ~(ITXRDYA | IRXRDYA);
+ qsc_write(sc, line, SC_IMR, sc->sc_sv_reg->sv_imr[pair]);
+
+ /* set baudrate */
+ speeds = qscspeed(tp->t_ispeed);
+ if (speeds == NOBAUD)
+ speeds = DEFBAUD;
+ qsc_write(sc, line, SC_CSR, speeds);
+ sc->sc_sv_reg->sv_csr[line] = speeds;
+
+ /* get saved mode registers and clear set up parameters */
+ mr1 = sc->sc_sv_reg->sv_mr1[line];
+ mr1 &= ~(CLMASK | PARTYPEMASK | PARMODEMASK);
+
+ mr2 = sc->sc_sv_reg->sv_mr2[line];
+ mr2 &= ~SBMASK;
+
+ /* set up character size */
+ switch (t->c_cflag & CSIZE) {
+ case CL8:
+ mr1 |= CL8;
+ break;
+ case CL7:
+ mr1 |= CL7;
+ break;
+ case CL6:
+ mr1 |= CL6;
+ break;
+ case CL5:
+ mr1 |= CL5;
+ break;
+ }
+
+ /* set up stop bits */
+ if (tp->t_ospeed == B110)
+ mr2 |= SB2;
+ else
+ mr2 |= SB1;
+
+ /* set up parity */
+ if (t->c_cflag & PARENB) {
+ mr1 |= PAREN;
+ if (t->c_cflag & PARODD)
+ mr1 |= ODDPAR;
+ else
+ mr1 |= EVENPAR;
+ } else
+ mr1 |= PARDIS;
+
+ if (sc->sc_sv_reg->sv_mr1[line] != mr1 ||
+ sc->sc_sv_reg->sv_mr2[line] != mr2) {
+ /* write mode registers to duart */
+ qsc_write(sc, line, SC_CR, MRONE);
+ DELAY(1);
+ qsc_write(sc, line, SC_MR, mr1);
+ qsc_write(sc, line, SC_MR, mr2);
+
+ /* save changed mode registers */
+ sc->sc_sv_reg->sv_mr1[line] = mr1;
+ sc->sc_sv_reg->sv_mr2[line] = mr2;
+ }
+ }
+
+ /* enable transmitter? */
+ if (tp->t_state & TS_BUSY) {
+ sc->sc_sv_reg->sv_imr[pair] |= line & 1 ? ITXRDYB : ITXRDYA;
+ }
+
+ /* re-enable the receiver */
+ sc->sc_sv_reg->sv_imr[pair] |= line & 1 ? IRXRDYB : IRXRDYA;
+ qsc_write(sc, line, SC_IMR, sc->sc_sv_reg->sv_imr[pair]);
+
+ return (0);
+}
+
+int
+qscopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ int s;
+ u_int line;
+ struct qscsoftc *sc;
+ struct tty *tp;
+
+ line = SC_LINE(dev);
+ if (qsc_cd.cd_ndevs == 0 || line >= SC_NLINES)
+ return (ENXIO);
+ /* Line B is not wired... */
+ if (line == QSC_LINE_DEAD)
+ return (ENXIO);
+ sc = (struct qscsoftc *)qsc_cd.cd_devs[0];
+ if (sc == NULL)
+ return (ENXIO);
+
+ /* if some other device is using the line, it's not available */
+ if (sc->sc_hook[line].fn != NULL)
+ return (ENXIO);
+
+ s = spltty();
+ if (sc->sc_tty[line] != NULL)
+ tp = sc->sc_tty[line];
+ else
+ tp = sc->sc_tty[line] = ttymalloc();
+
+ tp->t_oproc = qscstart;
+ tp->t_param = qscparam;
+ tp->t_dev = dev;
+
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ ttychars(tp);
+
+ if (tp->t_ispeed == 0) {
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = B9600;
+ if (sc->sc_console && line == QSC_LINE_SERIAL) {
+ /* console is 8N1 */
+ tp->t_cflag = (CREAD | CS8 | HUPCL);
+ } else {
+ tp->t_cflag = TTYDEF_CFLAG;
+ }
+ }
+
+ if (sc->sc_swflags[line] & TIOCFLAG_CLOCAL)
+ tp->t_cflag |= CLOCAL;
+ if (sc->sc_swflags[line] & TIOCFLAG_CRTSCTS)
+ tp->t_cflag |= CRTSCTS;
+ if (sc->sc_swflags[line] & TIOCFLAG_MDMBUF)
+ tp->t_cflag |= MDMBUF;
+
+ qscparam(tp, &tp->t_termios);
+ ttsetwater(tp);
+
+ tp->t_state |= TS_CARR_ON;
+ } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ splx(s);
+ return (EBUSY);
+ }
+
+ /*
+ * Reset the tty pointer, as there could have been a dialout
+ * use of the tty with a dialin open waiting.
+ */
+ tp->t_dev = dev;
+ splx(s);
+ return ((*linesw[tp->t_line].l_open)(dev, tp));
+}
+
+int
+qscclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct tty *tp;
+ struct qscsoftc *sc;
+ u_int line;
+
+ line = SC_LINE(dev);
+ sc = (struct qscsoftc *)qsc_cd.cd_devs[0];
+
+ tp = sc->sc_tty[line];
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+
+ return (0);
+}
+
+int
+qscread(dev_t dev, struct uio *uio, int flag)
+{
+ u_int line;
+ struct tty *tp;
+ struct qscsoftc *sc;
+
+ line = SC_LINE(dev);
+ sc = (struct qscsoftc *)qsc_cd.cd_devs[0];
+
+ tp = sc->sc_tty[line];
+ if (tp == NULL)
+ return (ENXIO);
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+int
+qscwrite(dev_t dev, struct uio *uio, int flag)
+{
+ u_int line;
+ struct tty *tp;
+ struct qscsoftc *sc;
+
+ line = SC_LINE(dev);
+ sc = (struct qscsoftc *)qsc_cd.cd_devs[0];
+
+ tp = sc->sc_tty[line];
+ if (tp == NULL)
+ return (ENXIO);
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+void
+qscrint(struct qscsoftc *sc, u_int line)
+{
+ struct tty *tp;
+ int data;
+ unsigned char sr;
+ int overrun = 0;
+
+ tp = sc->sc_tty[line];
+
+ /* read status reg */
+ while ((sr = qsc_read(sc, line, SC_SR)) & RXRDY) {
+ /* read data and reset receiver */
+ data = qsc_read(sc, line, SC_RXFIFO);
+
+ if (sr & RBRK) {
+ /* clear break state */
+ qsc_write(sc, line, SC_CR, BRKINTRESET);
+ DELAY(1);
+ qsc_write(sc, line, SC_CR, ERRRESET);
+ DELAY(1);
+ continue;
+ }
+
+ if ((sr & ROVRN) && cold == 0 && overrun == 0) {
+ log(LOG_WARNING, "%s line %d: receiver overrun\n",
+ sc->sc_dev.dv_xname, line);
+ overrun = 1;
+ }
+
+ if (sr & FRERR)
+ data |= TTY_FE;
+ if (sr & PERR)
+ data |= TTY_PE;
+
+ /* clear error state */
+ if (sr & (ROVRN | FRERR | PERR)) {
+ qsc_write(sc, line, SC_CR, ERRRESET);
+ DELAY(1);
+ }
+
+ if (sc->sc_hook[line].fn != NULL) {
+ if ((data & TTY_ERRORMASK) != 0 ||
+ (*sc->sc_hook[line].fn)(sc->sc_hook[line].arg, data))
+ continue;
+ }
+
+ if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)) == 0 &&
+ (sc->sc_console == 0 || line != QSC_LINE_SERIAL)) {
+ continue;
+ }
+
+ /* no errors */
+#if defined(DDB)
+ if (tp->t_dev == cn_tab->cn_dev) {
+ int j = kdbrint(data);
+
+ if (j == 1)
+ continue;
+
+ if (j == 2)
+ (*linesw[tp->t_line].l_rint)(27, tp);
+ }
+#endif
+ (*linesw[tp->t_line].l_rint)(data, tp);
+ }
+}
+
+void
+qscxint(struct qscsoftc *sc, u_int line)
+{
+ struct tty *tp;
+ u_int pair;
+
+ tp = sc->sc_tty[line];
+
+ if ((tp->t_state & (TS_ISOPEN|TS_WOPEN))==0)
+ goto out;
+
+ if (tp->t_state & TS_BUSY) {
+ tp->t_state &= ~(TS_BUSY | TS_FLUSH);
+ qscstart(tp);
+ if (tp->t_state & TS_BUSY) {
+ /* do not disable transmitter, yet */
+ return;
+ }
+ }
+out:
+
+ /* disable transmitter */
+ pair = line >> 1;
+ sc->sc_sv_reg->sv_imr[pair] &= line & 1 ? ~ITXRDYB : ~ITXRDYA;
+ qsc_write(sc, line, SC_IMR, sc->sc_sv_reg->sv_imr[pair]);
+}
+
+int
+qscintr(void *arg)
+{
+ struct qscsoftc *sc = arg;
+ u_int8_t isr[SC_NLINES >> 1], curisr;
+ u_int pair, line;
+ int rc = 0;
+
+ for (pair = 0; pair < SC_NLINES >> 1; pair++) {
+ line = pair << 1;
+
+ /* read interrupt status register and mask with imr */
+ isr[pair] = curisr = qsc_read(sc, line, SC_ISR);
+ curisr &= sc->sc_sv_reg->sv_imr[pair];
+ if (curisr == 0)
+ continue;
+
+ rc = 1;
+
+ if (curisr & IRXRDYA)
+ qscrint(sc, line);
+ if (curisr & ITXRDYA)
+ qscxint(sc, line);
+ if (curisr & IBRKA) {
+ qsc_write(sc, line, SC_CR, BRKINTRESET);
+ DELAY(1);
+ }
+
+ if (curisr & IRXRDYB)
+ qscrint(sc, line + 1);
+ if (curisr & ITXRDYB)
+ qscxint(sc, line + 1);
+ if (curisr & IBRKB) {
+ qsc_write(sc, line + 1, SC_CR, BRKINTRESET);
+ DELAY(1);
+ }
+ }
+
+ return (rc);
+}
+
+/*
+ * Console interface routines.
+ */
+
+vaddr_t qsc_cnregs;
+#define qsc_cnread(reg) \
+ *(volatile u_int8_t *)(qsc_cnregs + 4 * (reg))
+#define qsc_cnwrite(reg, val) \
+ *(volatile u_int8_t *)(qsc_cnregs + 4 * (reg)) = (val)
+
+void
+qsccnprobe(struct consdev *cp)
+{
+ int maj;
+ extern int getmajor(void *);
+ extern vaddr_t iospace;
+
+ if (vax_boardtype != VAX_BTYP_VXT)
+ return;
+
+ /* locate the major number */
+ if ((maj = getmajor(qscopen)) < 0)
+ return;
+
+ qsc_cnregs = iospace;
+ ioaccess(iospace, QSCADDR, 1);
+
+ cp->cn_dev = makedev(maj, QSC_LINE_SERIAL);
+ cp->cn_pri = vax_confdata & 2 ? CN_NORMAL : CN_REMOTE;
+}
+
+void
+qsccninit(cp)
+ struct consdev *cp;
+{
+ qsccn_sv.sv_mr1[QSC_LINE_SERIAL] = PARDIS | RXRTS | CL8;
+ qsccn_sv.sv_mr2[QSC_LINE_SERIAL] = /* TXCTS | */ SB1;
+ qsccn_sv.sv_csr[QSC_LINE_SERIAL] = BD9600;
+ qsccn_sv.sv_cr[QSC_LINE_SERIAL] = TXEN | RXEN;
+ qsccn_sv.sv_imr[QSC_LINE_SERIAL] = 0;
+
+ qsc_cnwrite(SC_CRA, RXRESET | TXDIS | RXDIS);
+ DELAY(1);
+ qsc_cnwrite(SC_CRA, TXRESET | TXDIS | RXDIS);
+ DELAY(1);
+ qsc_cnwrite(SC_CRA, ERRRESET | TXDIS | RXDIS);
+ DELAY(1);
+ qsc_cnwrite(SC_CRA, BRKINTRESET | TXDIS | RXDIS);
+ DELAY(1);
+ qsc_cnwrite(SC_CRA, MRZERO | TXDIS | RXDIS);
+ DELAY(1);
+
+ qsc_cnwrite(SC_MRA, 0);
+ qsc_cnwrite(SC_MRA, qsccn_sv.sv_mr1[QSC_LINE_SERIAL]);
+ qsc_cnwrite(SC_MRA, qsccn_sv.sv_mr2[QSC_LINE_SERIAL]);
+ qsc_cnwrite(SC_CSRA, qsccn_sv.sv_csr[QSC_LINE_SERIAL]);
+ qsc_cnwrite(SC_CRA, qsccn_sv.sv_cr[QSC_LINE_SERIAL]);
+ DELAY(1);
+
+ qsc_cnwrite(SC_IMRAB, qsccn_sv.sv_imr[QSC_LINE_SERIAL]);
+ qsc_cnwrite(SC_IMRCD, 0);
+}
+
+int
+qsccngetc(dev_t dev)
+{
+ unsigned char sr; /* status reg of line a/b */
+ u_char c; /* received character */
+ int s;
+
+ s = spltty();
+
+ /* disable interrupts for this line and enable receiver */
+ qsc_cnwrite(SC_IMRAB, qsccn_sv.sv_imr[QSC_LINE_SERIAL] & ~ITXRDYA);
+ qsc_cnwrite(SC_CRA, RXEN);
+ DELAY(1);
+
+ for (;;) {
+ /* read status reg */
+ sr = qsc_cnread(SC_SRA);
+
+ /* receiver interrupt handler*/
+ if (sr & RXRDY) {
+ /* read character from line */
+ c = qsc_cnread(SC_RXFIFOA);
+
+ /* check break condition */
+ if (sr & RBRK) {
+ /* clear break state */
+ qsc_cnwrite(SC_CRA, BRKINTRESET);
+ DELAY(1);
+ qsc_cnwrite(SC_CRA, ERRRESET);
+ DELAY(1);
+ break;
+ }
+
+ if (sr & (FRERR | PERR | ROVRN)) {
+ /* clear error state */
+ qsc_cnwrite(SC_CRA, ERRRESET);
+ DELAY(1);
+ } else {
+ break;
+ }
+ }
+ }
+
+ /* restore the previous state */
+ qsc_cnwrite(SC_IMRAB, qsccn_sv.sv_imr[QSC_LINE_SERIAL]);
+ qsc_cnwrite(SC_CRA, qsccn_sv.sv_cr[QSC_LINE_SERIAL]);
+
+ splx(s);
+
+ return ((int)c);
+}
+
+void
+qsccnputc(dev_t dev, int c)
+{
+ int s;
+
+ if (mfpr(PR_MAPEN) == 0)
+ return;
+
+ s = spltty();
+
+ /* disable interrupts for this line and enable transmitter */
+ qsc_cnwrite(SC_IMRAB, qsccn_sv.sv_imr[QSC_LINE_SERIAL] & ~ITXRDYA);
+ qsc_cnwrite(SC_CRA, TXEN);
+ DELAY(1);
+
+ while ((qsc_cnread(SC_SRA) & TXRDY) == 0)
+ ;
+ qsc_cnwrite(SC_TXFIFOA, c);
+
+ /* wait for transmitter to empty */
+ while ((qsc_cnread(SC_SRA) & TXEMT) == 0)
+ ;
+
+ /* restore the previous state */
+ qsc_cnwrite(SC_IMRAB, qsccn_sv.sv_imr[QSC_LINE_SERIAL]);
+ qsc_cnwrite(SC_CRA, qsccn_sv.sv_cr[QSC_LINE_SERIAL]);
+ DELAY(1);
+
+ splx(s);
+}
+
+void
+qsccnpollc(dev, pollflag)
+ dev_t dev;
+ int pollflag;
+{
+}
+
+/*
+ * Keyboard and mouse helper routines
+ */
+
+#if NQSCKBD > 0 || NQSCMS > 0
+int
+qsc_print(void *aux, const char *name)
+{
+ struct qsc_attach_args *qa = aux;
+
+ if (name != NULL)
+ printf(qa->qa_line == QSC_LINE_KEYBOARD ?
+ "lkkbd at %s" : "lkms at %s", name);
+ else
+ printf(" line %d", qa->qa_line);
+
+ return (UNCONF);
+}
+
+int
+qscgetc(u_int line)
+{
+ bus_addr_t craddr;
+ struct qscsoftc *sc = NULL;
+ int s;
+ u_int8_t sr, imr, imrmask, cr, c;
+
+ s = spltty();
+
+ craddr = line == QSC_LINE_KEYBOARD ? SC_CRC : SC_CRD;
+ imrmask = line & 1 ? ~IRXRDYB : ~IRXRDYA;
+ imr = sc != NULL ? sc->sc_sv_reg->sv_imr[line / 2] : 0;
+ cr = sc != NULL ? sc->sc_sv_reg->sv_cr[line] : 0;
+
+ /* disable interrupts for this line and enable receiver */
+ qsc_cnwrite(SC_IMRCD, imr & imrmask);
+ qsc_cnwrite(craddr, RXEN);
+ DELAY(1);
+
+ for (;;) {
+ /* read status reg */
+ sr = qsc_cnread(line == QSC_LINE_KEYBOARD ? SC_SRC : SC_SRD);
+
+ /* receiver interrupt handler*/
+ if (sr & RXRDY) {
+ /* read character from line */
+ c = qsc_cnread(line == QSC_LINE_KEYBOARD ?
+ SC_RXFIFOC : SC_RXFIFOD);
+
+ /* check break condition */
+ if (sr & RBRK) {
+ /* clear break state */
+ qsc_cnwrite(craddr, BRKINTRESET);
+ DELAY(1);
+ qsc_cnwrite(craddr, ERRRESET);
+ DELAY(1);
+ break;
+ }
+
+ if (sr & (FRERR | PERR | ROVRN)) {
+ /* clear error state */
+ qsc_cnwrite(craddr, ERRRESET);
+ DELAY(1);
+ } else {
+ break;
+ }
+ }
+ }
+
+ /* restore the previous state */
+ qsc_cnwrite(SC_IMRCD, imr);
+ qsc_cnwrite(craddr, cr);
+ DELAY(1);
+
+ splx(s);
+
+ return ((int)c);
+}
+
+void
+qscputc(u_int line, int c)
+{
+ bus_addr_t craddr;
+ struct qscsoftc *sc = NULL;
+ int s;
+ u_int8_t imr, imrmask, cr;
+
+ s = spltty();
+
+ if (qsc_cd.cd_ndevs != 0 &&
+ (sc = (struct qscsoftc *)qsc_cd.cd_devs[0]) != NULL)
+ if (sc->sc_rdy == 0)
+ sc = NULL;
+
+ craddr = line == QSC_LINE_KEYBOARD ? SC_CRC : SC_CRD;
+ imrmask = line & 1 ? ~ITXRDYB : ~ITXRDYA;
+ imr = sc != NULL ? sc->sc_sv_reg->sv_imr[line / 2] : 0;
+ cr = sc != NULL ? sc->sc_sv_reg->sv_cr[line] : 0;
+
+ /* disable interrupts for this line and enable transmitter */
+ qsc_cnwrite(SC_IMRCD, imr & imrmask);
+ qsc_cnwrite(craddr, TXEN);
+ DELAY(1);
+
+ while ((qsc_cnread(line == QSC_LINE_KEYBOARD ? SC_SRC : SC_SRD) &
+ TXRDY) == 0)
+ ;
+ qsc_cnwrite(line == QSC_LINE_KEYBOARD ? SC_TXFIFOC : SC_TXFIFOD, c);
+
+ /* wait for transmitter to empty */
+ while ((qsc_cnread(line == QSC_LINE_KEYBOARD ? SC_SRC : SC_SRD) &
+ TXEMT) == 0)
+ ;
+
+ /* restore the previous state */
+ qsc_cnwrite(SC_IMRCD, imr);
+ qsc_cnwrite(craddr, cr);
+ DELAY(1);
+
+ splx(s);
+}
+#endif
diff --git a/sys/arch/vax/vxt/qsckbd.c b/sys/arch/vax/vxt/qsckbd.c
new file mode 100644
index 00000000000..bf9f54ade79
--- /dev/null
+++ b/sys/arch/vax/vxt/qsckbd.c
@@ -0,0 +1,290 @@
+/* $OpenBSD: qsckbd.c,v 1.1 2006/08/27 16:55:41 miod Exp $ */
+/* from OpenBSD: dzkbd.c,v 1.11 2006/08/05 22:05:55 miod Exp */
+/*
+ * Copyright (c) 2006 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice, this permission notice, and the disclaimer below
+ * appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, Lawrence Berkeley Laboratory.
+ *
+ * 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. 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.
+ *
+ * @(#)kbd.c 8.2 (Berkeley) 10/30/93
+ */
+
+/*
+ * LK200/LK400 keyboard attached to line C of the SC26C94
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/syslog.h>
+#include <sys/malloc.h>
+#include <sys/timeout.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wskbdvar.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
+#include <vax/dec/wskbdmap_lk201.h>
+
+#include <machine/bus.h>
+
+#include <vax/dec/lk201reg.h>
+#include <vax/dec/lk201var.h>
+
+#include <vax/vxt/qscvar.h>
+
+struct qsckbd_internal {
+ u_int dzi_line;
+ struct lk201_state dzi_ks;
+};
+
+struct qsckbd_internal qsckbd_console_internal;
+
+struct qsckbd_softc {
+ struct device qsckbd_dev; /* required first: base device */
+
+ struct qsckbd_internal *sc_itl;
+ int sc_enabled;
+ struct device *sc_wskbddev;
+};
+
+int qsckbd_match(struct device *, void *, void *);
+void qsckbd_attach(struct device *, struct device *, void *);
+
+struct cfattach qsckbd_ca = {
+ sizeof(struct qsckbd_softc), qsckbd_match, qsckbd_attach,
+};
+
+int qsckbd_enable(void *, int);
+void qsckbd_set_leds(void *, int);
+int qsckbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
+
+const struct wskbd_accessops qsckbd_accessops = {
+ qsckbd_enable,
+ qsckbd_set_leds,
+ qsckbd_ioctl,
+};
+
+void qsckbd_cngetc(void *, u_int *, int *);
+void qsckbd_cnpollc(void *, int);
+
+const struct wskbd_consops qsckbd_consops = {
+ qsckbd_cngetc,
+ qsckbd_cnpollc,
+};
+
+const struct wskbd_mapdata qsckbd_keymapdata = {
+ lkkbd_keydesctab,
+#ifdef LKKBD_LAYOUT
+ LKKBD_LAYOUT,
+#else
+ KB_US,
+#endif
+};
+
+int qsckbd_input(void *, int);
+int qsckbd_sendchar(void *, int);
+
+int
+qsckbd_match(struct device *parent, void *vcf, void *aux)
+{
+ struct qsc_attach_args *qa = aux;
+ struct cfdata *cf = vcf;
+
+ if (cf->cf_loc[0] == qa->qa_line)
+ return 1;
+
+ return 0;
+}
+
+void
+qsckbd_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct qsckbd_softc *sc = (void *)self;
+ struct qsc_attach_args *qa = aux;
+ struct qsckbd_internal *dzi;
+ struct wskbddev_attach_args a;
+ int isconsole;
+
+ qa->qa_hook->fn = qsckbd_input;
+ qa->qa_hook->arg = self;
+
+ isconsole = qa->qa_console;
+
+ if (isconsole) {
+ dzi = &qsckbd_console_internal;
+ sc->sc_enabled = 1;
+ } else {
+ dzi = malloc(sizeof(struct qsckbd_internal), M_DEVBUF, M_NOWAIT);
+ if (dzi == NULL) {
+ printf(": out of memory\n");
+ return;
+ }
+ dzi->dzi_ks.attmt.sendchar = qsckbd_sendchar;
+ dzi->dzi_ks.attmt.cookie = (void *)qa->qa_line;
+ }
+ dzi->dzi_ks.device = self;
+ dzi->dzi_line = qa->qa_line;
+ sc->sc_itl = dzi;
+
+ printf("\n");
+
+ if (!isconsole)
+ lk201_init(&dzi->dzi_ks);
+
+ a.console = dzi == &qsckbd_console_internal;
+ a.keymap = &qsckbd_keymapdata;
+ a.accessops = &qsckbd_accessops;
+ a.accesscookie = sc;
+
+ sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
+}
+
+int
+qsckbd_cnattach(u_int line)
+{
+
+ qsckbd_console_internal.dzi_ks.attmt.sendchar = qsckbd_sendchar;
+ qsckbd_console_internal.dzi_ks.attmt.cookie = (void *)line;
+ lk201_init(&qsckbd_console_internal.dzi_ks);
+ qsckbd_console_internal.dzi_line = line;
+
+ wskbd_cnattach(&qsckbd_consops, &qsckbd_console_internal,
+ &qsckbd_keymapdata);
+
+ return 0;
+}
+
+int
+qsckbd_enable(void *v, int on)
+{
+ struct qsckbd_softc *sc = v;
+
+ sc->sc_enabled = on;
+ return 0;
+}
+
+void
+qsckbd_cngetc(void *v, u_int *type, int *data)
+{
+ struct qsckbd_internal *dzi = v;
+ int c;
+
+ do {
+ c = qscgetc(dzi->dzi_line);
+ } while (lk201_decode(&dzi->dzi_ks, 1, 0, c, type, data) == LKD_NODATA);
+}
+
+void
+qsckbd_cnpollc(void *v, int on)
+{
+}
+
+void
+qsckbd_set_leds(void *v, int leds)
+{
+ struct qsckbd_softc *sc = (struct qsckbd_softc *)v;
+
+ lk201_set_leds(&sc->sc_itl->dzi_ks, leds);
+}
+
+int
+qsckbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct qsckbd_softc *sc = (struct qsckbd_softc *)v;
+
+ switch (cmd) {
+ case WSKBDIO_GTYPE:
+ *(int *)data = lk201_get_type(&sc->sc_itl->dzi_ks);
+ return 0;
+ case WSKBDIO_SETLEDS:
+ lk201_set_leds(&sc->sc_itl->dzi_ks, *(int *)data);
+ return 0;
+ case WSKBDIO_GETLEDS:
+ *(int *)data = lk201_get_leds(&sc->sc_itl->dzi_ks);
+ return 0;
+ case WSKBDIO_COMPLEXBELL:
+ lk201_bell(&sc->sc_itl->dzi_ks,
+ (struct wskbd_bell_data *)data);
+ return 0;
+ }
+ return -1;
+}
+
+int
+qsckbd_input(void *v, int data)
+{
+ struct qsckbd_softc *sc = (struct qsckbd_softc *)v;
+ u_int type;
+ int val;
+ int decode;
+
+ /*
+ * We want to run through lk201_decode always, so that a late plugged
+ * keyboard will get configured correctly.
+ */
+ do {
+ decode = lk201_decode(&sc->sc_itl->dzi_ks, sc->sc_enabled, 1,
+ data, &type, &val);
+ if (decode != LKD_NODATA)
+ wskbd_input(sc->sc_wskbddev, type, val);
+ } while (decode == LKD_MORE);
+
+ return(1);
+}
+
+int
+qsckbd_sendchar(void *v, int c)
+{
+ qscputc((u_int)v, c);
+ return (0);
+}
diff --git a/sys/arch/vax/vxt/qscms.c b/sys/arch/vax/vxt/qscms.c
new file mode 100644
index 00000000000..6ec2bd21265
--- /dev/null
+++ b/sys/arch/vax/vxt/qscms.c
@@ -0,0 +1,167 @@
+/* $OpenBSD: qscms.c,v 1.1 2006/08/27 16:55:41 miod Exp $ */
+/* from OpenBSD: qscms.c,v 1.6 2006/07/31 18:50:13 miod Exp */
+/*
+ * Copyright (c) 2006 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice, this permission notice, and the disclaimer below
+ * appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, Lawrence Berkeley Laboratory.
+ *
+ * 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. 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.
+ *
+ * @(#)ms.c 8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * VSXXX mice attached to line D of the SC26C94
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/syslog.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+
+#include <machine/bus.h>
+
+#include <vax/qbus/dzreg.h>
+#include <vax/qbus/dzvar.h>
+
+#include <vax/vxt/qscvar.h>
+#include <vax/dec/vsmsvar.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+struct qscms_softc {
+ struct lkms_softc sc_base;
+ u_int sc_line;
+};
+
+int qscms_match(struct device *, void *, void *);
+void qscms_attach(struct device *, struct device *, void *);
+
+struct cfattach qscms_ca = {
+ sizeof(struct qscms_softc), qscms_match, qscms_attach,
+};
+
+int qscms_enable(void *);
+void qscms_disable(void *);
+
+const struct wsmouse_accessops qscms_accessops = {
+ qscms_enable,
+ lkms_ioctl,
+ qscms_disable,
+};
+
+int
+qscms_match(struct device *parent, void *vcf, void *aux)
+{
+ struct qsc_attach_args *qa = aux;
+ struct cfdata *cf = vcf;
+
+ if (cf->cf_loc[0] == qa->qa_line)
+ return 1;
+
+ return 0;
+}
+
+void
+qscms_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct qscms_softc *qscms = (void *)self;
+ struct lkms_softc *sc = (void *)self;
+ struct qsc_attach_args *qa = aux;
+ struct wsmousedev_attach_args a;
+
+ qa->qa_hook->fn = lkms_input;
+ qa->qa_hook->arg = self;
+ qscms->sc_line = qa->qa_line;
+
+ printf("\n");
+
+ a.accessops = &qscms_accessops;
+ a.accesscookie = qscms;
+
+ sc->sc_enabled = 0;
+ sc->sc_selftest = 0;
+ sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
+}
+
+int
+qscms_enable(void *v)
+{
+ struct qscms_softc *qscms = v;
+ struct lkms_softc *sc = v;
+
+ if (sc->sc_enabled)
+ return EBUSY;
+
+ sc->sc_selftest = 4; /* wait for 4 byte reply upto 1/2 sec */
+ qscputc(qscms->sc_line, MOUSE_SELF_TEST);
+ (void)tsleep(&sc->sc_enabled, TTIPRI, "qscmsopen", hz / 2);
+ if (sc->sc_selftest != 0) {
+ sc->sc_selftest = 0;
+ return ENXIO;
+ }
+ DELAY(150);
+ qscputc(qscms->sc_line, MOUSE_INCREMENTAL);
+ sc->sc_enabled = 1;
+ sc->inputstate = 0;
+ return 0;
+}
+
+void
+qscms_disable(void *v)
+{
+ struct lkms_softc *sc = v;
+
+ sc->sc_enabled = 0;
+}
diff --git a/sys/arch/vax/vxt/qscreg.h b/sys/arch/vax/vxt/qscreg.h
new file mode 100644
index 00000000000..bb15a4a84c1
--- /dev/null
+++ b/sys/arch/vax/vxt/qscreg.h
@@ -0,0 +1,173 @@
+/* $OpenBSD: qscreg.h,v 1.1 2006/08/27 16:55:41 miod Exp $ */
+/*
+ * Copyright (c) 2006 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice, this permission notice, and the disclaimer below
+ * appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * SC26C94 registers
+ */
+
+#define SC_MRA 0x00 /* R/W Mode Register A */
+#define SC_SRA 0x01 /* R Status Register A */
+#define SC_CSRA 0x01 /* W Clock Select Register A */
+#define SC_CRA 0x02 /* W Command Register A */
+#define SC_RXFIFOA 0x03 /* R Receive Holding Register A */
+#define SC_TXFIFOA 0x03 /* W Transmit Holding Register A */
+#define SC_IPCRAB 0x04 /* R Input Port Change Register AB */
+#define SC_ACRAB 0x04 /* W Auxiliary Control Register AB */
+#define SC_ISRAB 0x05 /* R Interrupt Status Register AB */
+#define SC_IMRAB 0x05 /* W Interrupt Mask Register AB */
+#define SC_CTURAB 0x06 /* R/W Counter/Timer Upper Register AB */
+#define SC_CTLRAB 0x07 /* R/W Counter/Timer Lower Register AB */
+#define SC_MRB 0x08 /* R/W Mode Register A */
+#define SC_SRB 0x09 /* R Status Register A */
+#define SC_CSRB 0x09 /* W Clock Select Register A */
+#define SC_CRB 0x0a /* W Command Register A */
+#define SC_RXFIFOB 0x0b /* R Receive Holding Register A */
+#define SC_TXFIFOB 0x0b /* W Transmit Holding Register A */
+#define SC_OPRAB 0x0c /* R/W Output Port Register AB */
+#define SC_IPRAB 0x0d /* R Input Port Register AB */
+#define SC_IOPCRA 0x0d /* W I/O Port Control Register A */
+#define SC_IOPCRB 0x0e /* W I/O Port Control Register A */
+#define SC_CTSTARTAB 0x0e /* R Start Counter AB */
+#define SC_CTSTOPAB 0x0f /* R Start Counter AB */
+
+#define SC_MRC 0x10 /* R/W Mode Register C */
+#define SC_SRC 0x11 /* R Status Register C */
+#define SC_CSRC 0x11 /* W Clock Select Register C */
+#define SC_CRC 0x12 /* W Command Register C */
+#define SC_RXFIFOC 0x13 /* R Receive Holding Register C */
+#define SC_TXFIFOC 0x13 /* W Transmit Holding Register C */
+#define SC_IPCRCD 0x14 /* R Input Port Change Register CD */
+#define SC_ACRCD 0x14 /* W Auxiliary Control Register CD */
+#define SC_ISRCD 0x15 /* R Interrupt Status Register CD */
+#define SC_IMRCD 0x15 /* W Interrupt Mask Register CD */
+#define SC_CTURCD 0x16 /* R/W Counter/Timer Upper Register CD */
+#define SC_CTLRCD 0x17 /* R/W Counter/Timer Lower Register CD */
+#define SC_MRD 0x18 /* R/W Mode Register C */
+#define SC_SRD 0x19 /* R Status Register C */
+#define SC_CSRD 0x19 /* W Clock Select Register C */
+#define SC_CRD 0x1a /* W Command Register C */
+#define SC_RXFIFOD 0x1b /* R Receive Holding Register C */
+#define SC_TXFIFOD 0x1b /* W Transmit Holding Register C */
+#define SC_OPRCD 0x1c /* R/W Output Port Register CD */
+#define SC_IPRCD 0x1d /* R Input Port Register CD */
+#define SC_IOPCRC 0x1d /* W I/O Port Control Register C */
+#define SC_IOPCRD 0x1e /* W I/O Port Control Register C */
+#define SC_CTSTARTCD 0x1e /* R Start Counter CD */
+#define SC_CTSTOPCD 0x1f /* R Start Counter CD */
+
+#define SC_BIDCRA 0x20 /* R/W Bidding Control Register A */
+#define SC_BIDCRB 0x21 /* R/W Bidding Control Register B */
+#define SC_BIDCRC 0x22 /* R/W Bidding Control Register C */
+#define SC_BIDCRD 0x23 /* R/W Bidding Control Register D */
+#define SC_POWERDOWN 0x24 /* W Power Down */
+#define SC_POWERUP 0x25 /* W Power Up */
+#define SC_DDACKN 0x26 /* W Disable DACKN */
+#define SC_EDACKN 0x27 /* W Enable DACKN */
+
+#define SC_CIR 0x28 /* R Current Interrupt Register */
+#define SC_GICR 0x29 /* R Global Interrupting Channel Register */
+#define SC_IVR 0x29 /* W Interrupt Vector Register */
+#define SC_GBICR 0x2a /* R Global Int Byte Count Register */
+#define SC_UCIR 0x2a /* W Update CIR */
+#define SC_GRXFIFO 0x2b /* R Global Receive Holding Register */
+#define SC_GTXFIFO 0x2b /* W Global Transmit Holding Register */
+#define SC_ICR 0x2c /* R/W Interrupt Control Register */
+#define SC_BRGRATE 0x2d /* W BRG Rate */
+#define SC_X1DIV2 0x2e /* W Set X1/CLK divide by two */
+#define SC_X1NORM 0x2f /* W Set X1/CLK normal */
+
+/* mode register 1: MR1x operations */
+#define RXRTS 0x80 /* enable receiver RTS */
+#define PAREN 0x00 /* with parity */
+#define PARDIS 0x10 /* no parity */
+#define EVENPAR 0x00 /* even parity */
+#define ODDPAR 0x04 /* odd parity */
+#define CL5 0x00 /* 5 bits per char */
+#define CL6 0x01 /* 6 bits per char */
+#define CL7 0x02 /* 7 bits per char */
+#define CL8 0x03 /* 8 bits per char */
+#define PARMODEMASK 0x18 /* parity mode mask */
+#define PARTYPEMASK 0x04 /* parity type mask */
+#define CLMASK 0x03 /* character length mask */
+
+/* mode register 2: MR2x operations */
+#define TXRTS 0x20 /* enable transmitter RTS */
+#define TXCTS 0x10 /* enable transmitter CTS */
+#define SB2 0x0f /* 2 stop bits */
+#define SB1 0x07 /* 1 stop bit */
+#define SB1L5 0x00 /* 1 stop bit at 5 bits per character */
+
+#define SBMASK 0x0f /* stop bit mask */
+
+/* clock-select register: CSRx operations */
+#define NOBAUD -1 /* 50 and 200 baud are not possible */
+/* they are not in Baud register set 2 */
+#define BD75 0x00 /* 75 baud */
+#define BD110 0x11 /* 110 baud */
+#define BD134 0x22 /* 134.5 baud */
+#define BD150 0x33 /* 150 baud */
+#define BD300 0x44 /* 300 baud */
+#define BD600 0x55 /* 600 baud */
+#define BD1200 0x66 /* 1200 baud */
+#define BD1800 0xaa /* 1800 baud */
+#define BD2400 0x88 /* 2400 baud */
+#define BD4800 0x99 /* 4800 baud */
+#define BD9600 0xbb /* 9600 baud */
+#define BD19200 0xcc /* 19200 baud */
+
+#define DEFBAUD BD9600 /* default value if baudrate is not possible */
+
+/* channel command register: CRx operations */
+#define MRONE 0x10 /* reset mr pointer to mr1 */
+#define RXRESET 0x20 /* reset receiver */
+#define TXRESET 0x30 /* reset transmitter */
+#define ERRRESET 0x40 /* reset error status */
+#define BRKINTRESET 0x50 /* reset channel's break interrupt */
+#define BRKSTART 0x60 /* start break */
+#define BRKSTOP 0x70 /* stop break */
+#define MRZERO 0xb0 /* reset mr pointer to mr0 */
+#define TXDIS 0x08 /* disable transmitter */
+#define TXEN 0x04 /* enable transmitter */
+#define RXDIS 0x02 /* disable receiver */
+#define RXEN 0x01 /* enable receiver */
+
+/* status register: SRx status */
+#define RBRK 0x80 /* received break */
+#define FRERR 0x40 /* frame error */
+#define PERR 0x20 /* parity error */
+#define ROVRN 0x10 /* receiver overrun error */
+#define TXEMT 0x08 /* transmitter empty */
+#define TXRDY 0x04 /* transmitter ready */
+#define FFULL 0x02 /* receiver FIFO full */
+#define RXRDY 0x01 /* receiver ready */
+
+/* auxiliary control register: ACR operations */
+#define BDSET1 0x00 /* baudrate generator set 1 */
+#define BDSET2 0x80 /* baudrate generator set 2 */
+#define CCLK1 0x60 /* timer clock: external rate. TA */
+#define CCLK16 0x30 /* counter clock: x1 clk divided by 16 */
+
+/* interrupt status and mask register: ISR status and IMR mask */
+#define IIPCHG 0x80 /* I/O Port Change */
+#define IBRKB 0x40 /* delta break b */
+#define IRXRDYB 0x20 /* receiver ready b */
+#define ITXRDYB 0x10 /* transmitter ready b */
+#define ITIMER 0x08 /* Counter Ready */
+#define IBRKA 0x04 /* delta break a */
+#define IRXRDYA 0x02 /* receiver ready a */
+#define ITXRDYA 0x01 /* transmitter ready a */
diff --git a/sys/arch/vax/vxt/qscvar.h b/sys/arch/vax/vxt/qscvar.h
new file mode 100644
index 00000000000..4b13fbcd1a0
--- /dev/null
+++ b/sys/arch/vax/vxt/qscvar.h
@@ -0,0 +1,115 @@
+/* $OpenBSD: qscvar.h,v 1.1 2006/08/27 16:55:41 miod Exp $ */
+/*
+ * Copyright (c) 2006 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice, this permission notice, and the disclaimer below
+ * appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Logical, per port, registers (serial functions only)
+ */
+
+#define SC_MR 0x00 /* R/W Mode Register */
+#define SC_SR 0x01 /* R Status Register */
+#define SC_CSR 0x01 /* W Clock Select Register */
+#define SC_CR 0x02 /* W Command Register */
+#define SC_RXFIFO 0x03 /* R Receive Holding Register */
+#define SC_TXFIFO 0x03 /* W Transmit Holding Register */
+#define SC_IPCR 0x04 /* R Input Port Change Register */
+#define SC_ACR 0x04 /* W Auxiliary Control Register */
+#define SC_ISR 0x05 /* R Interrupt Status Register */
+#define SC_IMR 0x05 /* W Interrupt Mask Register */
+#define SC_OPR 0x06 /* R/W Output Port Register */
+#define SC_IPR 0x07 /* R Input Port Register */
+#define SC_IOPCR 0x07 /* W I/O Port Control Register */
+#define SC_LOGICAL 0x08
+
+#define SC_NLINES 4
+
+/* saved registers */
+struct qsc_sv_reg {
+ u_int8_t sv_mr1[SC_NLINES];
+ u_int8_t sv_mr2[SC_NLINES];
+ u_int8_t sv_csr[SC_NLINES];
+ u_int8_t sv_cr[SC_NLINES];
+ u_int8_t sv_imr[SC_NLINES / 2];
+};
+
+struct qsc_input_hook {
+ int (*fn)(void *, int);
+ void *arg;
+};
+
+struct qscsoftc {
+ struct device sc_dev;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+ bus_addr_t sc_regaddr[SC_NLINES][SC_LOGICAL];
+
+ int sc_console;
+ int sc_rdy;
+
+ struct qsc_sv_reg *sc_sv_reg;
+ struct qsc_sv_reg sc_sv_reg_storage;
+
+ struct tty *sc_tty[SC_NLINES];
+ u_int sc_swflags[SC_NLINES];
+
+ struct qsc_input_hook sc_hook[SC_NLINES];
+};
+
+/*
+ * Line assignments on the VXT2000
+ */
+
+#define QSC_LINE_SERIAL 0
+#define QSC_LINE_DEAD 1
+#define QSC_LINE_KEYBOARD 2
+#define QSC_LINE_MOUSE 3
+
+struct qsc_attach_args {
+ u_int qa_line;
+ int qa_console; /* for keyboard attachment */
+ struct qsc_input_hook *qa_hook;
+};
+
+int qscgetc(u_int);
+void qscputc(u_int, int);
+
+int qsckbd_cnattach(u_int);
diff --git a/sys/arch/vax/vxt/vxtbus.c b/sys/arch/vax/vxt/vxtbus.c
new file mode 100644
index 00000000000..1749ca364f3
--- /dev/null
+++ b/sys/arch/vax/vxt/vxtbus.c
@@ -0,0 +1,156 @@
+/* $OpenBSD: vxtbus.c,v 1.1 2006/08/27 16:55:41 miod Exp $ */
+/*
+ * Copyright (c) 2006 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice, this permission notice, and the disclaimer below
+ * appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/evcount.h>
+#include <sys/queue.h>
+
+#include <machine/cpu.h>
+#include <machine/nexus.h>
+#include <machine/scb.h>
+
+#include <vax/vxt/vxtbusvar.h>
+
+struct vxtbus_softc {
+ struct device sc_dev;
+ LIST_HEAD(, vxtbus_ih) sc_intrlist;
+ struct evcount sc_intrcnt; /* unused */
+};
+
+void vxtbus_attach(struct device *, struct device *, void *);
+int vxtbus_match(struct device *, void*, void *);
+
+struct cfdriver vxtbus_cd = {
+ NULL, "vxtbus", DV_DULL
+};
+
+struct cfattach vxtbus_ca = {
+ sizeof(struct vxtbus_softc), vxtbus_match, vxtbus_attach
+};
+
+void vxtbus_intr(void *);
+int vxtbus_print(void *, const char *);
+
+int
+vxtbus_match(struct device *parent, void *vcf, void *aux)
+{
+ struct mainbus_attach_args *maa = aux;
+
+ return (maa->maa_bustype == VAX_VXTBUS ? 1 : 0);
+}
+
+void
+vxtbus_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct vxtbus_softc *sc = (void *)self;
+ struct bp_conf bp;
+
+ LIST_INIT(&sc->sc_intrlist);
+ scb_vecalloc(VXT_INTRVEC, vxtbus_intr, sc, SCB_ISTACK, &sc->sc_intrcnt);
+
+ printf("\n");
+
+ bp.type = "sgec";
+ config_found(self, &bp, vxtbus_print);
+
+ bp.type = "qsc";
+ config_found(self, &bp, vxtbus_print);
+
+ bp.type = "lcspx";
+ config_found(self, &bp, vxtbus_print);
+}
+
+int
+vxtbus_print(void *aux, const char *name)
+{
+ struct bp_conf *bp = aux;
+
+ if (name)
+ printf("%s at %s", bp->type, name);
+
+ return (UNCONF);
+}
+
+/*
+ * VXT2000 interrupt code.
+ *
+ * All device interrupts end up on the same vector, which is controllable
+ * by the SC26C94 chip.
+ *
+ * The following routines implement shared interrupts for vxtbus subdevices.
+ */
+
+struct vxtbus_ih {
+ LIST_ENTRY(vxtbus_ih) ih_link;
+ int (*ih_fn)(void *);
+ void * ih_arg;
+ int ih_vec;
+ struct evcount ih_cnt;
+};
+
+void
+vxtbus_intr_establish(const char *name, int ipl, int (*fn)(void *), void *arg)
+{
+ struct vxtbus_softc *sc = (void *)vxtbus_cd.cd_devs[0];
+ struct vxtbus_ih *ih;
+
+ ih = (struct vxtbus_ih *)malloc(sizeof(*ih), M_DEVBUF, M_WAITOK);
+
+ ih->ih_fn = fn;
+ ih->ih_arg = arg;
+ ih->ih_vec = VXT_INTRVEC;
+ evcount_attach(&ih->ih_cnt, name, (void *)&ih->ih_vec, &evcount_intr);
+
+ LIST_INSERT_HEAD(&sc->sc_intrlist, ih, ih_link);
+}
+
+void
+vxtbus_intr(void *arg)
+{
+ struct vxtbus_softc *sc = arg;
+ struct vxtbus_ih *ih;
+ int rc;
+#ifdef DIAGNOSTIC
+ int handled = 0;
+ static int strayintr = 0;
+#endif
+
+ LIST_FOREACH(ih, &sc->sc_intrlist, ih_link) {
+ rc = (*ih->ih_fn)(ih->ih_arg);
+ if (rc != 0) {
+#ifdef DIAGNOSTIC
+ handled = 1;
+#endif
+ ih->ih_cnt.ec_count++;
+ if (rc > 0)
+ break;
+ }
+ }
+
+#ifdef DIAGNOSTIC
+ if (handled == 0) {
+ if (++strayintr == 10)
+ panic("too many stray interrupts");
+ else
+ printf("stray interrupt");
+ }
+#endif
+}
diff --git a/sys/arch/vax/vxt/vxtbusvar.h b/sys/arch/vax/vxt/vxtbusvar.h
new file mode 100644
index 00000000000..64e5e9543fc
--- /dev/null
+++ b/sys/arch/vax/vxt/vxtbusvar.h
@@ -0,0 +1,28 @@
+/* $OpenBSD: vxtbusvar.h,v 1.1 2006/08/27 16:55:41 miod Exp $ */
+/*
+ * Copyright (c) 2006 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice, this permission notice, and the disclaimer below
+ * appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * VXT2000 Hardware addresses
+ */
+#define SGECADDR_VXT 0x20008000
+#define QSCADDR 0x200a0000
+#define NISA_ROM_VXT 0x200c4000
+
+#define VXT_INTRVEC 0x200
+
+void vxtbus_intr_establish(const char *, int, int (*)(void *), void *);