diff options
Diffstat (limited to 'sys/arch/vax')
-rw-r--r-- | sys/arch/vax/conf/GENERIC | 11 | ||||
-rw-r--r-- | sys/arch/vax/conf/RAMDISK | 11 | ||||
-rw-r--r-- | sys/arch/vax/conf/files.vax | 21 | ||||
-rw-r--r-- | sys/arch/vax/include/clock.h | 4 | ||||
-rw-r--r-- | sys/arch/vax/include/nexus.h | 3 | ||||
-rw-r--r-- | sys/arch/vax/vax/clock.c | 33 | ||||
-rw-r--r-- | sys/arch/vax/vax/conf.c | 19 | ||||
-rw-r--r-- | sys/arch/vax/vax/findcpu.c | 6 | ||||
-rw-r--r-- | sys/arch/vax/vax/led.c | 16 | ||||
-rw-r--r-- | sys/arch/vax/vax/locore.c | 9 | ||||
-rw-r--r-- | sys/arch/vax/vax/vxt.c | 137 | ||||
-rw-r--r-- | sys/arch/vax/vax/wscons_machdep.c | 18 | ||||
-rw-r--r-- | sys/arch/vax/vsa/lcspx.c | 73 | ||||
-rw-r--r-- | sys/arch/vax/vxt/if_ze_vxtbus.c | 95 | ||||
-rw-r--r-- | sys/arch/vax/vxt/qsc.c | 1078 | ||||
-rw-r--r-- | sys/arch/vax/vxt/qsckbd.c | 290 | ||||
-rw-r--r-- | sys/arch/vax/vxt/qscms.c | 167 | ||||
-rw-r--r-- | sys/arch/vax/vxt/qscreg.h | 173 | ||||
-rw-r--r-- | sys/arch/vax/vxt/qscvar.h | 115 | ||||
-rw-r--r-- | sys/arch/vax/vxt/vxtbus.c | 156 | ||||
-rw-r--r-- | sys/arch/vax/vxt/vxtbusvar.h | 28 |
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 *); |