diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/alpha/alpha/conf.c | 8 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/dec_3000_300.c | 48 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/dec_3000_500.c | 49 | ||||
-rw-r--r-- | sys/arch/alpha/conf/GENERIC | 6 | ||||
-rw-r--r-- | sys/arch/alpha/conf/RAMDISKBIG | 6 | ||||
-rw-r--r-- | sys/arch/alpha/conf/files.alpha | 19 | ||||
-rw-r--r-- | sys/arch/alpha/include/z8530var.h | 119 | ||||
-rw-r--r-- | sys/arch/alpha/tc/scc.c | 1230 | ||||
-rw-r--r-- | sys/arch/alpha/tc/sccreg.h | 173 | ||||
-rw-r--r-- | sys/arch/alpha/tc/sccvar.h | 118 | ||||
-rw-r--r-- | sys/arch/alpha/tc/tc_3000_300.c | 12 | ||||
-rw-r--r-- | sys/arch/alpha/tc/tc_3000_500.c | 12 | ||||
-rw-r--r-- | sys/dev/tc/files.tc | 20 | ||||
-rw-r--r-- | sys/dev/tc/zs_ioasic.c | 825 | ||||
-rw-r--r-- | sys/dev/tc/zs_ioasicvar.h | 44 |
15 files changed, 1050 insertions, 1639 deletions
diff --git a/sys/arch/alpha/alpha/conf.c b/sys/arch/alpha/alpha/conf.c index 97f567ca527..a08ba7a1490 100644 --- a/sys/arch/alpha/alpha/conf.c +++ b/sys/arch/alpha/alpha/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.83 2016/09/04 10:51:23 naddy Exp $ */ +/* $OpenBSD: conf.c,v 1.84 2017/11/02 14:04:24 mpi Exp $ */ /* $NetBSD: conf.c,v 1.16 1996/10/18 21:26:57 cgd Exp $ */ /*- @@ -82,8 +82,8 @@ cdev_decl(mm); #include "tun.h" #include "bpfilter.h" #include "ch.h" -#include "scc.h" -cdev_decl(scc); +#include "zs.h" +cdev_decl(zs); #include "audio.h" #include "video.h" #include "com.h" @@ -143,7 +143,7 @@ struct cdevsw cdevsw[] = cdev_tape_init(NST,st), /* 12: SCSI tape */ cdev_disk_init(NCD,cd), /* 13: SCSI CD-ROM */ cdev_ch_init(NCH,ch), /* 14: SCSI autochanger */ - cdev_tty_init(NSCC,scc), /* 15: scc 8530 serial interface */ + cdev_tty_init(NZS,zs), /* 15: Z8530 serial interface */ cdev_notdef(), /* 16 was lkm */ cdev_notdef(), /* 17 */ cdev_notdef(), /* 18 */ diff --git a/sys/arch/alpha/alpha/dec_3000_300.c b/sys/arch/alpha/alpha/dec_3000_300.c index f571f10535e..666f1a24d10 100644 --- a/sys/arch/alpha/alpha/dec_3000_300.c +++ b/sys/arch/alpha/alpha/dec_3000_300.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dec_3000_300.c,v 1.13 2014/05/08 20:46:49 miod Exp $ */ +/* $OpenBSD: dec_3000_300.c,v 1.14 2017/11/02 14:04:24 mpi Exp $ */ /* $NetBSD: dec_3000_300.c,v 1.30 2000/05/22 20:13:32 thorpej Exp $ */ /* @@ -46,12 +46,10 @@ #include <dev/tc/tcvar.h> #include <dev/tc/tcdsvar.h> #include <alpha/tc/tc_3000_300.h> -#ifndef NEW_SCC_DRIVER -#include <alpha/tc/sccvar.h> -#endif -#if 0 #include <machine/z8530var.h> +#include <dev/tc/zs_ioasicvar.h> +#if 0 #include <dev/dec/zskbdvar.h> #endif @@ -98,22 +96,10 @@ dec_3000_300_cons_init() ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off); -#ifndef NEW_SCC_DRIVER - switch (ctb->ctb_term_type) { - case CTB_GRAPHICS: -#if 0 - alpha_donot_kludge_scc = 1; -#endif - return; - case CTB_PRINTERPORT: - return; - default: - goto badconsole; - } -#else switch (ctb->ctb_term_type) { case CTB_GRAPHICS: #if NWSDISPLAY > 0 +#ifdef notyet /* display console ... */ if (zs_ioasic_lk201_cnattach(0x1a0000000, 0x00180000, 0) == 0 && tc_3000_300_fb_cnattach( @@ -121,8 +107,10 @@ dec_3000_300_cons_init() break; } #endif +#endif printf("consinit: Unable to init console on keyboard and "); - printf("TURBOchannel slot 0x%lx.\n", ctb->ctb_turboslot); + printf("TURBOchannel slot 0x%lx.\n", + (unsigned long)ctb->ctb_turboslot); printf("Using serial console.\n"); /* FALLTHROUGH */ @@ -144,25 +132,19 @@ dec_3000_300_cons_init() * XXX Should use ctb_line_off to get the * XXX line parameters. */ - if (zs_ioasic_cnattach(0x1a0000000, 0x00100000, 1, - 9600, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) - panic("can't init serial console"); + zs_ioasic_cnattach(0x1a0000000, 0x00100000, 1); break; } default: - goto badconsole; + printf("ctb->ctb_term_type = 0x%lx\n", + (unsigned long)ctb->ctb_term_type); + printf("ctb->ctb_turboslot = 0x%lx\n", + (unsigned long)ctb->ctb_turboslot); + panic("consinit: unknown console type %lu", + (unsigned long)ctb->ctb_term_type); + /* NOTREACHED */ } -#endif - return; -badconsole: - printf("ctb->ctb_term_type = 0x%lx\n", - (unsigned long)ctb->ctb_term_type); - printf("ctb->ctb_turboslot = 0x%lx\n", - (unsigned long)ctb->ctb_turboslot); - - panic("consinit: unknown console type %lu", - (unsigned long)ctb->ctb_term_type); } static void diff --git a/sys/arch/alpha/alpha/dec_3000_500.c b/sys/arch/alpha/alpha/dec_3000_500.c index bbf5f4d2a7f..c59b0e50b6a 100644 --- a/sys/arch/alpha/alpha/dec_3000_500.c +++ b/sys/arch/alpha/alpha/dec_3000_500.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dec_3000_500.c,v 1.13 2014/05/08 20:46:49 miod Exp $ */ +/* $OpenBSD: dec_3000_500.c,v 1.14 2017/11/02 14:04:24 mpi Exp $ */ /* $NetBSD: dec_3000_500.c,v 1.29 2000/05/22 20:13:32 thorpej Exp $ */ /* @@ -45,12 +45,10 @@ #include <dev/tc/tcvar.h> #include <dev/tc/tcdsvar.h> #include <alpha/tc/tc_3000_500.h> -#ifndef NEW_SCC_DRIVER -#include <alpha/tc/sccvar.h> -#endif -#if 0 #include <machine/z8530var.h> +#include <dev/tc/zs_ioasicvar.h> +#if 0 #include <dev/dec/zskbdvar.h> #endif @@ -117,23 +115,10 @@ dec_3000_500_cons_init() ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off); -#ifndef NEW_SCC_DRIVER - switch (ctb->ctb_term_type) { - case CTB_GRAPHICS: -#ifdef notyet - alpha_donot_kludge_scc = 1; -#endif - return; - case CTB_PRINTERPORT: - return; - default: - goto badconsole; - } -#else - switch (ctb->ctb_term_type) { case CTB_GRAPHICS: #if NWSDISPLAY > 0 +#ifdef notyet /* display console ... */ if (zs_ioasic_lk201_cnattach(0x1e0000000, 0x00180000, 0) == 0 && tc_3000_500_fb_cnattach( @@ -141,8 +126,10 @@ dec_3000_500_cons_init() break; } #endif +#endif printf("consinit: Unable to init console on keyboard and "); - printf("TURBOchannel slot 0x%lx.\n", ctb->ctb_turboslot); + printf("TURBOchannel slot 0x%lx.\n", + (unsigned long)ctb->ctb_turboslot); printf("Using serial console.\n"); /* FALLTHROUGH */ @@ -164,24 +151,18 @@ dec_3000_500_cons_init() * XXX Should use ctb_line_off to get the * XXX line parameters--these are the defaults. */ - if (zs_ioasic_cnattach(0x1e0000000, 0x00180000, 1, - 9600, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) - panic("can't init serial console"); + zs_ioasic_cnattach(0x1e0000000, 0x00180000, 1); break; } default: - goto badconsole; + printf("ctb->ctb_term_type = 0x%lx\n", + (unsigned long)ctb->ctb_term_type); + printf("ctb->ctb_turboslot = 0x%lx\n", + (unsigned long)ctb->ctb_turboslot); + panic("consinit: unknown console type %lu", + (unsigned long)ctb->ctb_term_type); + /* NOTREACHED */ } -#endif - return; -badconsole: - printf("ctb->ctb_term_type = 0x%lx\n", - (unsigned long)ctb->ctb_term_type); - printf("ctb->ctb_turboslot = 0x%lx\n", - (unsigned long)ctb->ctb_turboslot); - - panic("consinit: unknown console type %lu", - (unsigned long)ctb->ctb_term_type); } static void diff --git a/sys/arch/alpha/conf/GENERIC b/sys/arch/alpha/conf/GENERIC index a38f877079a..01b5e7beaaf 100644 --- a/sys/arch/alpha/conf/GENERIC +++ b/sys/arch/alpha/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.260 2017/08/28 19:32:53 jasper Exp $ +# $OpenBSD: GENERIC,v 1.261 2017/11/02 14:04:24 mpi Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -157,8 +157,8 @@ ioasic* at tc? mcclock* at ioasic? le* at ioasic? bba0 at ioasic? -scc0 at ioasic? -scc1 at ioasic? +zs* at ioasic? +zstty* at zs? channel 1 tcds* at tc? asc* at tcds? asc* at tc? diff --git a/sys/arch/alpha/conf/RAMDISKBIG b/sys/arch/alpha/conf/RAMDISKBIG index 5796dfea8c8..1c7cb8f09fe 100644 --- a/sys/arch/alpha/conf/RAMDISKBIG +++ b/sys/arch/alpha/conf/RAMDISKBIG @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISKBIG,v 1.100 2016/06/28 04:41:37 jmatthew Exp $ +# $OpenBSD: RAMDISKBIG,v 1.101 2017/11/02 14:04:24 mpi Exp $ machine alpha maxusers 4 @@ -78,8 +78,8 @@ tc* at tcasic? ioasic* at tc? mcclock* at ioasic? le* at ioasic? -scc0 at ioasic? -scc1 at ioasic? +zs* at ioasic? +zstty* at zs? channel 1 tcds* at tc? asc* at tcds? asc* at tc? diff --git a/sys/arch/alpha/conf/files.alpha b/sys/arch/alpha/conf/files.alpha index b4edb201c66..5a5d118c4b5 100644 --- a/sys/arch/alpha/conf/files.alpha +++ b/sys/arch/alpha/conf/files.alpha @@ -1,4 +1,4 @@ -# $OpenBSD: files.alpha,v 1.104 2017/06/05 17:49:06 deraadt Exp $ +# $OpenBSD: files.alpha,v 1.105 2017/11/02 14:04:24 mpi Exp $ # $NetBSD: files.alpha,v 1.32 1996/11/25 04:03:21 cgd Exp $ # # alpha-specific configuration info @@ -95,22 +95,7 @@ file arch/alpha/tc/tc_3000_300.c tcasic & dec_3000_300 # IOASIC device and attachment defined in sys/dev/tc/files.tc file arch/alpha/tc/ioasic.c ioasic needs-flag -# PMAG-B CX -device cfb: wsemuldisplaydev -attach cfb at tc -file arch/alpha/tc/cfb.c cfb needs-flag - -# PMAGB-B HX or CXT -device sfb: wsemuldisplaydev -attach sfb at tc -file arch/alpha/tc/sfb.c sfb needs-flag - -# 8530 UARTs -device scc -attach scc at ioasic -file arch/alpha/tc/scc.c scc needs-count - -# TC and baseboard ioasic Lance ethernet are in files.tc +# TC, baseboard ioasic Lance ethernet and baseboard 8530 serial are in files.tc # # ISA Bus support diff --git a/sys/arch/alpha/include/z8530var.h b/sys/arch/alpha/include/z8530var.h new file mode 100644 index 00000000000..e185de30715 --- /dev/null +++ b/sys/arch/alpha/include/z8530var.h @@ -0,0 +1,119 @@ +/* $OpenBSD: z8530var.h,v 1.1 2017/11/02 14:04:24 mpi Exp $ */ +/* $NetBSD: z8530var.h,v 1.9 2008/03/29 19:15:34 tsutsui Exp $ */ + +/* + * 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. + * + * @(#)zsvar.h 8.1 (Berkeley) 6/11/93 + */ + +/* + * Copyright (c) 1994 Gordon W. Ross + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)zsvar.h 8.1 (Berkeley) 6/11/93 + */ + +/* + * XXX XXX XXX THIS DOES NOT WORK WITH MULTIPLE ATTACHMENTS!!! XXX XXX XXX + */ + +#include <dev/ic/z8530sc.h> + +struct zsc_softc { + struct device zsc_dev; /* required: base device */ + struct zs_chanstate *zsc_cs[2]; /* channel soft state */ + /* Machine-dependent part follows... */ + int zsc_addroffset; /* used as "cookie" to identify scc */ + void *zsc_sih; /* softinterrupt handle */ +}; + +/* + * Functions to read and write individual registers in a channel. + * The ZS chip requires a 1.6 uSec. recovery time between accesses, + * and the Alpha TC hardware does NOT take care of this for you. + * The delay is now handled inside the chip access functions. + * These could be inlines, but with the delay, speed is moot. + */ + +uint8_t zs_read_reg(struct zs_chanstate *, uint8_t); +uint8_t zs_read_csr(struct zs_chanstate *); +uint8_t zs_read_data(struct zs_chanstate *); + +void zs_write_reg(struct zs_chanstate *, uint8_t, uint8_t); +void zs_write_csr(struct zs_chanstate *, uint8_t); +void zs_write_data(struct zs_chanstate *, uint8_t); + +/* Interrupt priority for the SCC chip */ +#define splzs() spltty() +#define IPL_ZS IPL_TTY diff --git a/sys/arch/alpha/tc/scc.c b/sys/arch/alpha/tc/scc.c deleted file mode 100644 index e790ecc0b26..00000000000 --- a/sys/arch/alpha/tc/scc.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* $OpenBSD: scc.c,v 1.30 2017/04/30 16:45:45 mpi Exp $ */ -/* $NetBSD: scc.c,v 1.58 2002/03/17 19:40:27 atatat Exp $ */ - -/* - * Copyright (c) 1991,1990,1989,1994,1995,1996 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 ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS 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. - */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Ralph Campbell and Rick Macklem. - * - * 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. - * - * @(#)scc.c 8.2 (Berkeley) 11/30/93 - */ - -/* - * Intel 82530 dual usart chip driver. Supports the serial port(s) on the - * Personal DECstation 5000/xx and DECstation 5000/1xx, plus the keyboard - * and mouse on the 5000/1xx. (Don't ask me where the A channel signals - * are on the 5000/xx.) - * - * See: Intel MicroCommunications Handbook, Section 2, pg. 155-173, 1992. - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/ioctl.h> -#include <sys/tty.h> -#include <sys/proc.h> -#include <sys/buf.h> -#include <sys/file.h> -#include <sys/uio.h> -#include <sys/kernel.h> -#include <sys/syslog.h> -#include <sys/device.h> - -#include <dev/cons.h> - -#include <dev/ic/z8530reg.h> -#include <alpha/tc/sccreg.h> -#include <alpha/tc/sccvar.h> - -#include <machine/rpb.h> -#include <machine/conf.h> - -#include <dev/tc/tcvar.h> -#include <dev/tc/ioasicreg.h> -#include <dev/tc/ioasicvar.h> - -#undef SCCDEV -#define SCCDEV 15 /* XXX */ - -#define raster_console() 1 /* Treat test for cn_screen as true */ -#define CONSOLE_ON_UNIT(unit) 0 /* No raster console on Alphas */ - -#define NSCCLINE (NSCC*2) -#define SCCUNIT(dev) (minor(dev) >> 1) -#define SCCLINE(dev) (minor(dev) & 0x1) - -#ifdef DEBUG -int debugChar; -#endif - -int alpha_donot_kludge_scc; - -struct scc_softc { - struct device sc_dv; - struct pdma scc_pdma[2]; - struct { - u_char wr1; - u_char wr3; - u_char wr4; - u_char wr5; - u_char wr14; - } scc_wreg[2]; - struct tty *scc_tty[2]; - int scc_softCAR; - - int scc_flags[2]; -#define SCC_CHAN_NEEDSDELAY 0x01 /* sw must delay 1.6us between output*/ -#define SCC_CHAN_NOMODEM 0x02 /* don't touch modem ctl lines (may - be left floating or x-wired */ -#define SCC_CHAN_MODEM_CROSSED 0x04 /* modem lines wired to other channel*/ -#define SCC_CHAN_KBDLINE 0x08 /* XXX special-case keyboard lines */ -}; - -/* - * BRG formula is: - * ClockFrequency - * BRGconstant = --------------------------- - 2 - * 2 * BaudRate * ClockDivider - * - * Speed selections with Pclk=7.3728MHz, clock x16 - */ -const struct speedtab sccspeedtab[] = { - { 0, 0, }, - { 50, 4606, }, - { 75, 3070, }, - { 110, 2093, }, - { 134.5, 1711, }, - { 150, 1534, }, - { 200, 1150, }, - { 300, 766, }, - { 600, 382, }, - { 1200, 190, }, - { 1800, 126, }, - { 2400, 94, }, - { 4800, 46, }, - { 7200, 30, }, /* non-POSIX */ - { 9600, 22, }, - { 14400, 14, }, /* non-POSIX */ - { 19200, 10, }, - { 28800, 6, }, /* non-POSIX */ - { 38400, 4, }, /* non-POSIX */ - { 57600, 2, }, /* non-POSIX */ - { -1, -1, }, -}; - -#ifndef PORTSELECTOR -#define ISPEED TTYDEF_SPEED -#define LFLAG TTYDEF_LFLAG -#else -#define ISPEED B4800 -#define LFLAG (TTYDEF_LFLAG & ~ECHO) -#endif - -/* Definition of the driver for autoconfig. */ -int sccmatch(struct device *, void *, void *); -void sccattach(struct device *, struct device *, void *); - -struct cfattach scc_ca = { - sizeof (struct scc_softc), sccmatch, sccattach, -}; - -struct cfdriver scc_cd = { - NULL, "scc", DV_TTY, -}; - -cdev_decl(scc); - -int sccGetc(dev_t); -void sccPutc(dev_t, int); -void sccPollc(dev_t, int); -int sccparam(struct tty *, struct termios *); -void sccstart(struct tty *); - -int sccmctl(struct scc_softc *, int, int, int); -int cold_sccparam(struct tty *, struct termios *, - struct scc_softc *sc, int line); - -#ifdef SCC_DEBUG -void rr(char *, scc_regmap_t *); -#endif -void scc_modem_intr(dev_t); -void sccreset(struct scc_softc *); - -int sccintr(void *); -void scc_alphaintr(int); - -/* - * console variables, for using serial console while still cold and - * autoconfig has not attached the scc device. - */ -scc_regmap_t *scc_cons_addr = 0; -struct consdev scccons = { - NULL, NULL, sccGetc, sccPutc, sccPollc, NULL, NODEV, 0 -}; - -/* - * Test to see if device is present. - * Return true if found. - */ -int -sccmatch(parent, vcf, aux) - struct device *parent; - void *vcf, *aux; -{ - extern struct cfdriver ioasic_cd; /* XXX */ - struct ioasicdev_attach_args *d = aux; - struct cfdata *cf = vcf; - void *sccaddr; - - if (parent->dv_cfdata->cf_driver != &ioasic_cd) { -#ifdef DIAGNOSTIC - printf("Cannot attach scc on %s\n", parent->dv_xname); -#endif - return (0); - } - - /* Make sure that we're looking for this type of device. */ - if ((strncmp(d->iada_modname, "z8530 ", TC_ROM_LLEN) != 0) && - (strncmp(d->iada_modname, "scc", TC_ROM_LLEN)!= 0)) - return (0); - - /* - * Check user-specified offset against the ioasic offset. - * Allow it to be wildcarded. - */ - if (cf->cf_loc[0] != -1 && - cf->cf_loc[0] != d->iada_offset) - return (0); - - /* Get the address, and check it for validity. */ - sccaddr = (void *)d->iada_addr; -#ifdef SPARSE - sccaddr = (void *)TC_DENSE_TO_SPARSE((tc_addr_t)sccaddr); -#endif - if (badaddr(sccaddr, 2)) - return (0); - - return (1); -} - -/* - * Enable ioasic SCC interrupts and scc DMA engine interrupts. - * XXX does not really belong here. - */ -void -scc_alphaintr(onoff) - int onoff; -{ - if (onoff) { - *(volatile u_int *)(ioasic_base + IOASIC_IMSK) |= - IOASIC_INTR_SCC_1 | IOASIC_INTR_SCC_0; -#if !defined(DEC_3000_300) && defined(SCC_DMA) - *(volatile u_int *)(ioasic_base + IOASIC_CSR) |= - IOASIC_CSR_DMAEN_T1 | IOASIC_CSR_DMAEN_R1 | - IOASIC_CSR_DMAEN_T2 | IOASIC_CSR_DMAEN_R2; -#endif - } else { - *(volatile u_int *)(ioasic_base + IOASIC_IMSK) &= - ~(IOASIC_INTR_SCC_1 | IOASIC_INTR_SCC_0); -#if !defined(DEC_3000_300) && defined(SCC_DMA) - *(volatile u_int *)(ioasic_base + IOASIC_CSR) &= - ~(IOASIC_CSR_DMAEN_T1 | IOASIC_CSR_DMAEN_R1 | - IOASIC_CSR_DMAEN_T2 | IOASIC_CSR_DMAEN_R2); -#endif - } - tc_mb(); -} - -void -sccattach(parent, self, aux) - struct device *parent; - struct device *self; - void *aux; -{ - struct scc_softc *sc = (struct scc_softc *)self; - struct ioasicdev_attach_args *d = aux; - struct pdma *pdp; - struct tty *tp; - void *sccaddr; - int cntr; - struct termios cterm; - struct tty ctty; - int s; - int unit; - - unit = sc->sc_dv.dv_unit; - - /* Get the address, and check it for validity. */ - sccaddr = (void *)d->iada_addr; -#ifdef SPARSE - sccaddr = (void *)TC_DENSE_TO_SPARSE((tc_addr_t)sccaddr); -#endif - - /* Register the interrupt handler. */ - ioasic_intr_establish(parent, d->iada_cookie, IPL_TTY, - sccintr, (void *)sc, self->dv_xname); - - /* - * For a remote console, wait a while for previous output to - * complete. - */ - if ((cputype == ST_DEC_3000_500 && sc->sc_dv.dv_unit == 1) || - (cputype == ST_DEC_3000_300 && sc->sc_dv.dv_unit == 0)) - DELAY(10000); - pdp = &sc->scc_pdma[0]; - - /* init pseudo DMA structures */ - for (cntr = 0; cntr < 2; cntr++) { - pdp->p_addr = (void *)sccaddr; - tp = sc->scc_tty[cntr] = ttymalloc(0); - pdp->p_arg = (long)tp; - pdp->p_fcn = (void (*)(struct tty*))0; - tp->t_dev = (dev_t)((sc->sc_dv.dv_unit << 1) | cntr); - pdp++; - } - /* What's the warning here? Defaulting to softCAR on line 2? */ - sc->scc_softCAR = sc->sc_dv.dv_cfdata->cf_flags | 0x2; /* XXX */ - - /* reset chip, initialize register-copies in softc */ - sccreset(sc); - - /* - * Special handling for consoles. - */ - if (1 /* SCCUNIT(cn_tab.cn_dev) == sc->sc_dv.dv_unit */) { - s = spltty(); - cterm.c_cflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8; - cterm.c_ospeed = cterm.c_ispeed = 9600; - (void) cold_sccparam(&ctty, &cterm, sc, - SCCLINE((sc->sc_dv.dv_unit == 0) ? - SCCCOMM2_PORT : SCCCOMM3_PORT)); - DELAY(1000); - splx(s); - } - - /* - * XXX - * Unit 1 is the remote console, wire it up now. - */ - if ((cputype == ST_DEC_3000_500 && sc->sc_dv.dv_unit == 1) || - (cputype == ST_DEC_3000_300 && sc->sc_dv.dv_unit == 0)) { - if (alpha_donot_kludge_scc) - printf("\nSWITCHING TO SERIAL CONSOLE!\n"); - cn_tab = &scccons; - cn_tab->cn_dev = makedev(SCCDEV, sc->sc_dv.dv_unit * 2); - - printf("%s console\n", alpha_donot_kludge_scc ? "\n***" : ":"); - - /* wire carrier for console. */ - sc->scc_softCAR |= SCCLINE(cn_tab->cn_dev); - } else - printf("\n"); -} - -/* - * Reset the chip. - */ -void -sccreset(sc) - register struct scc_softc *sc; -{ - register scc_regmap_t *regs; - register u_char val; - - regs = (scc_regmap_t *)sc->scc_pdma[0].p_addr; - /* - * Chip once-only initialization - * - * NOTE: The wiring we assume is the one on the 3min: - * - * out A-TxD --> TxD keybd or mouse - * in A-RxD --> RxD keybd or mouse - * out A-DTR~ --> DTR comm - * out A-RTS~ --> RTS comm - * in A-CTS~ --> SI comm - * in A-DCD~ --> RI comm - * in A-SYNCH~--> DSR comm - * out B-TxD --> TxD comm - * in B-RxD --> RxD comm - * in B-RxC --> TRxCB comm - * in B-TxC --> RTxCB comm - * out B-RTS~ --> SS comm - * in B-CTS~ --> CTS comm - * in B-DCD~ --> CD comm - */ - SCC_INIT_REG(regs, SCC_CHANNEL_A); - SCC_INIT_REG(regs, SCC_CHANNEL_B); - - SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_WR9, ZSWR9_HARD_RESET); - DELAY(50000); /*enough ? */ - SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_WR9, 0); - - /* program the interrupt vector */ - SCC_WRITE_REG(regs, SCC_CHANNEL_A, ZSWR_IVEC, 0xf0); - SCC_WRITE_REG(regs, SCC_CHANNEL_B, ZSWR_IVEC, 0xf0); - SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_WR9, ZSWR9_VECTOR_INCL_STAT); - - /* receive parameters and control */ - sc->scc_wreg[SCC_CHANNEL_A].wr3 = 0; - sc->scc_wreg[SCC_CHANNEL_B].wr3 = 0; - - /* timing base defaults */ - sc->scc_wreg[SCC_CHANNEL_A].wr4 = ZSWR4_CLK_X16; - sc->scc_wreg[SCC_CHANNEL_B].wr4 = ZSWR4_CLK_X16; - - /* enable DTR, RTS and SS */ - sc->scc_wreg[SCC_CHANNEL_B].wr5 = 0; - sc->scc_wreg[SCC_CHANNEL_A].wr5 = ZSWR5_RTS | ZSWR5_DTR; - - /* baud rates */ - val = ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK; - sc->scc_wreg[SCC_CHANNEL_B].wr14 = val; - sc->scc_wreg[SCC_CHANNEL_A].wr14 = val; - - /* interrupt conditions */ - val = ZSWR1_RIE | ZSWR1_PE_SC | ZSWR1_SIE | ZSWR1_TIE; - sc->scc_wreg[SCC_CHANNEL_A].wr1 = val; - sc->scc_wreg[SCC_CHANNEL_B].wr1 = val; -} - -int -sccopen(dev, flag, mode, p) - dev_t dev; - int flag, mode; - struct proc *p; -{ - register struct scc_softc *sc; - register struct tty *tp; - register int unit, line; - int s, error = 0; - int firstopen = 0; - - unit = SCCUNIT(dev); - if (unit >= scc_cd.cd_ndevs) - return (ENXIO); - sc = scc_cd.cd_devs[unit]; - if (!sc) - return (ENXIO); - - line = SCCLINE(dev); - if (sc->scc_pdma[line].p_addr == NULL) - return (ENXIO); - tp = sc->scc_tty[line]; - if (tp == NULL) { - tp = sc->scc_tty[line] = ttymalloc(0); - } - tp->t_oproc = sccstart; - tp->t_param = sccparam; - tp->t_dev = dev; - if ((tp->t_state & TS_ISOPEN) == 0) { - ttychars(tp); - firstopen = 1; -#ifndef PORTSELECTOR - if (tp->t_ispeed == 0) { -#endif - tp->t_iflag = TTYDEF_IFLAG; - tp->t_oflag = TTYDEF_OFLAG; - tp->t_cflag = TTYDEF_CFLAG; - tp->t_lflag = LFLAG; - tp->t_ispeed = tp->t_ospeed = ISPEED; -#ifdef PORTSELECTOR - tp->t_cflag |= HUPCL; -#else - } -#endif - (void) sccparam(tp, &tp->t_termios); - ttsetwater(tp); - } else if ((tp->t_state & TS_XCLUDE) && suser(curproc, 0) != 0) - return (EBUSY); - (void) sccmctl(sc, SCCLINE(dev), DML_DTR, DMSET); - s = spltty(); - while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) && - !(tp->t_state & TS_CARR_ON)) { - tp->t_state |= TS_WOPEN; - error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, - ttopen, 0); - tp->t_state &= ~TS_WOPEN; - if (error != 0) - break; - } - splx(s); - if (error) - return (error); - error = (*linesw[tp->t_line].l_open)(dev, tp, p); - - return (error); -} - -/*ARGSUSED*/ -int -sccclose(dev, flag, mode, p) - dev_t dev; - int flag, mode; - struct proc *p; -{ - register struct scc_softc *sc = scc_cd.cd_devs[SCCUNIT(dev)]; - register struct tty *tp; - register int line; - - line = SCCLINE(dev); - tp = sc->scc_tty[line]; - if (sc->scc_wreg[line].wr5 & ZSWR5_BREAK) { - sc->scc_wreg[line].wr5 &= ~ZSWR5_BREAK; - ttyoutput(0, tp); - } - (*linesw[tp->t_line].l_close)(tp, flag, p); - if ((tp->t_cflag & HUPCL) || (tp->t_state & TS_WOPEN) || - !(tp->t_state & TS_ISOPEN)) - (void) sccmctl(sc, line, 0, DMSET); - return (ttyclose(tp)); -} - -int -sccread(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - register struct scc_softc *sc; - register struct tty *tp; - - sc = scc_cd.cd_devs[SCCUNIT(dev)]; /* XXX*/ - tp = sc->scc_tty[SCCLINE(dev)]; - return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); -} - -int -sccwrite(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - register struct scc_softc *sc; - register struct tty *tp; - - sc = scc_cd.cd_devs[SCCUNIT(dev)]; /* XXX*/ - tp = sc->scc_tty[SCCLINE(dev)]; - return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); -} - -struct tty * -scctty(dev) - dev_t dev; -{ - register struct scc_softc *sc; - register struct tty *tp; - register int unit = SCCUNIT(dev); - - if ((unit >= scc_cd.cd_ndevs) || (sc = scc_cd.cd_devs[unit]) == 0) - return (0); - tp = sc->scc_tty[SCCLINE(dev)]; - return (tp); -} - -/*ARGSUSED*/ -int -sccioctl(dev, cmd, data, flag, p) - dev_t dev; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; -{ - register struct scc_softc *sc; - register struct tty *tp; - int error, line; - - line = SCCLINE(dev); - sc = scc_cd.cd_devs[SCCUNIT(dev)]; - tp = sc->scc_tty[line]; - 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 TIOCSBRK: - sc->scc_wreg[line].wr5 |= ZSWR5_BREAK; - ttyoutput(0, tp); - break; - - case TIOCCBRK: - sc->scc_wreg[line].wr5 &= ~ZSWR5_BREAK; - ttyoutput(0, tp); - break; - - case TIOCSDTR: - (void) sccmctl(sc, line, DML_DTR|DML_RTS, DMBIS); - break; - - case TIOCCDTR: - (void) sccmctl(sc, line, DML_DTR|DML_RTS, DMBIC); - break; - - case TIOCMSET: - (void) sccmctl(sc, line, *(int *)data, DMSET); - break; - - case TIOCMBIS: - (void) sccmctl(sc, line, *(int *)data, DMBIS); - break; - - case TIOCMBIC: - (void) sccmctl(sc, line, *(int *)data, DMBIC); - break; - - case TIOCMGET: - *(int *)data = sccmctl(sc, line, 0, DMGET); - break; - - default: - return (ENOTTY); - } - return (0); -} - - - -/* - * Set line parameters -- tty t_param entry point. - */ -int -sccparam(tp, t) - register struct tty *tp; - register struct termios *t; -{ - register struct scc_softc *sc; - - /* Extract the softc and call cold_sccparam to do all the work. */ - sc = scc_cd.cd_devs[SCCUNIT(tp->t_dev)]; - return cold_sccparam(tp, t, sc, SCCLINE(tp->t_dev)); -} - - -/* - * Do what sccparam() (t_param entry point) does, but callable when cold. - */ -int -cold_sccparam(tp, t, sc, line) - register struct tty *tp; - register struct termios *t; - register struct scc_softc *sc; - register int line; -{ - register scc_regmap_t *regs; - register u_char value, wvalue; - register int cflag = t->c_cflag; - int ospeed; - - /* Check arguments */ - if (t->c_ispeed && t->c_ispeed != t->c_ospeed) - return (EINVAL); - ospeed = ttspeedtab(t->c_ospeed, sccspeedtab); - if (ospeed < 0) - return (EINVAL); - /* and copy to tty */ - tp->t_ispeed = t->c_ispeed; - tp->t_ospeed = t->c_ospeed; - tp->t_cflag = cflag; - - /* - * Handle console specially. - */ - { - cflag = CS8; - ospeed = ttspeedtab(9600, sccspeedtab); - } - if (ospeed == 0) { - (void) sccmctl(sc, line, 0, DMSET); /* hang up line */ - return (0); - } - - regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr; - - /* - * pmax driver used to reset the SCC here. That reset causes the - * other channel on the SCC to drop outpur chars: at least that's - * what CGD reports for the Alpha. It's a bug. - */ -#if 0 - /* reset line */ - if (line == SCC_CHANNEL_A) - value = ZSWR9_A_RESET; - else - value = ZSWR9_B_RESET; - SCC_WRITE_REG(regs, line, SCC_WR9, value); - DELAY(25); -#endif - - /* stop bits, normally 1 */ - value = sc->scc_wreg[line].wr4 & 0xf0; - if (cflag & CSTOPB) - value |= ZSWR4_TWOSB; - else - value |= ZSWR4_ONESB; - if ((cflag & PARODD) == 0) - value |= ZSWR4_EVENP; - if (cflag & PARENB) - value |= ZSWR4_PARENB; - - /* set it now, remember it must be first after reset */ - sc->scc_wreg[line].wr4 = value; - SCC_WRITE_REG(regs, line, SCC_WR4, value); - - /* vector again */ - SCC_WRITE_REG(regs, line, ZSWR_IVEC, 0xf0); - - /* clear break, keep rts dtr */ - wvalue = sc->scc_wreg[line].wr5 & (ZSWR5_DTR|ZSWR5_RTS); - switch (cflag & CSIZE) { - case CS5: - value = ZSWR3_RX_5; - wvalue |= ZSWR5_TX_5; - break; - case CS6: - value = ZSWR3_RX_6; - wvalue |= ZSWR5_TX_6; - break; - case CS7: - value = ZSWR3_RX_7; - wvalue |= ZSWR5_TX_7; - break; - case CS8: - default: - value = ZSWR3_RX_8; - wvalue |= ZSWR5_TX_8; - }; - sc->scc_wreg[line].wr3 = value; - SCC_WRITE_REG(regs, line, SCC_WR3, value); - - sc->scc_wreg[line].wr5 = wvalue; - SCC_WRITE_REG(regs, line, SCC_WR5, wvalue); - - /* - * XXX Does the SCC chip require us to refresh the WR5 register - * for the other channel after writing the other, or not? - */ -#ifdef notdef - /* XXX */ - { - int otherline = (line + 1) & 1; - SCC_WRITE_REG(regs, otherline, SCC_WR5, sc->scc_wreg[otherline].wr5); - } -#endif - - SCC_WRITE_REG(regs, line, ZSWR_SYNCLO, 0); - SCC_WRITE_REG(regs, line, ZSWR_SYNCHI, 0); - SCC_WRITE_REG(regs, line, SCC_WR9, ZSWR9_VECTOR_INCL_STAT); - SCC_WRITE_REG(regs, line, SCC_WR10, 0); - value = ZSWR11_RXCLK_BAUD | ZSWR11_TXCLK_BAUD | - ZSWR11_TRXC_OUT_ENA | ZSWR11_TRXC_BAUD; - SCC_WRITE_REG(regs, line, SCC_WR11, value); - SCC_SET_TIMING_BASE(regs, line, ospeed); - value = sc->scc_wreg[line].wr14; - SCC_WRITE_REG(regs, line, SCC_WR14, value); - - if (sc->sc_dv.dv_unit == 1) { - /* On unit one, on the flamingo, modem control is floating! */ - value = ZSWR15_BREAK_IE; - } else - { - value = ZSWR15_BREAK_IE | ZSWR15_CTS_IE | ZSWR15_DCD_IE; - } - SCC_WRITE_REG(regs, line, SCC_WR15, value); - - /* and now the enables */ - value = sc->scc_wreg[line].wr3 | ZSWR3_RX_ENABLE; - SCC_WRITE_REG(regs, line, SCC_WR3, value); - value = sc->scc_wreg[line].wr5 | ZSWR5_TX_ENABLE; - sc->scc_wreg[line].wr5 = value; - SCC_WRITE_REG(regs, line, SCC_WR5, value); - - /* master inter enable */ - value = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT; - SCC_WRITE_REG(regs, line, SCC_WR9, value); - SCC_WRITE_REG(regs, line, SCC_WR1, sc->scc_wreg[line].wr1); - tc_mb(); - - scc_alphaintr(1); /* XXX XXX XXX */ - - return (0); -} - - -/* - * Check for interrupts from all devices. - */ -int -sccintr(xxxsc) - void *xxxsc; -{ - register struct scc_softc *sc = (struct scc_softc *)xxxsc; - register int unit = (long)sc->sc_dv.dv_unit; - register scc_regmap_t *regs; - register struct tty *tp; - register struct pdma *dp; - register int cc, chan, rr1, rr2, rr3; - int overrun = 0; - - rr1 = 0; /* shut up gcc -Wall */ - regs = (scc_regmap_t *)sc->scc_pdma[0].p_addr; - unit <<= 1; - for (;;) { - SCC_READ_REG(regs, SCC_CHANNEL_B, ZSRR_IVEC, rr2); - rr2 = SCC_RR2_STATUS(rr2); - /* are we done yet ? */ - if (rr2 == 6) { /* strange, distinguished value */ - SCC_READ_REG(regs, SCC_CHANNEL_A, ZSRR_IPEND, rr3); - if (rr3 == 0) - return 1; - } - - SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_RR0, ZSWR0_CLR_INTR); - if ((rr2 == SCC_RR2_A_XMIT_DONE) || (rr2 == SCC_RR2_B_XMIT_DONE)) { - chan = (rr2 == SCC_RR2_A_XMIT_DONE) ? - SCC_CHANNEL_A : SCC_CHANNEL_B; - tp = sc->scc_tty[chan]; - dp = &sc->scc_pdma[chan]; - if (dp->p_mem < dp->p_end) { - SCC_WRITE_DATA(regs, chan, *dp->p_mem++); - tc_mb(); - } else { - tp->t_state &= ~TS_BUSY; - if (tp->t_state & TS_FLUSH) - tp->t_state &= ~TS_FLUSH; - else { - ndflush(&tp->t_outq, dp->p_mem - - (caddr_t) tp->t_outq.c_cf); - dp->p_end = dp->p_mem = tp->t_outq.c_cf; - } - (*linesw[tp->t_line].l_start)(tp); - if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) { - SCC_READ_REG(regs, chan, SCC_RR15, cc); - cc &= ~ZSWR15_TXUEOM_IE; - SCC_WRITE_REG(regs, chan, SCC_WR15, cc); - cc = sc->scc_wreg[chan].wr1 & ~ZSWR1_TIE; - SCC_WRITE_REG(regs, chan, SCC_WR1, cc); - sc->scc_wreg[chan].wr1 = cc; - tc_mb(); - } - } - } else if (rr2 == SCC_RR2_A_RECV_DONE || - rr2 == SCC_RR2_B_RECV_DONE || rr2 == SCC_RR2_A_RECV_SPECIAL || - rr2 == SCC_RR2_B_RECV_SPECIAL) { - if (rr2 == SCC_RR2_A_RECV_DONE || rr2 == SCC_RR2_A_RECV_SPECIAL) - chan = SCC_CHANNEL_A; - else - chan = SCC_CHANNEL_B; - tp = sc->scc_tty[chan]; - SCC_READ_DATA(regs, chan, cc); - if (rr2 == SCC_RR2_A_RECV_SPECIAL || - rr2 == SCC_RR2_B_RECV_SPECIAL) { - SCC_READ_REG(regs, chan, SCC_RR1, rr1); - SCC_WRITE_REG(regs, chan, SCC_RR0, ZSWR0_RESET_ERRORS); - if ((rr1 & ZSRR1_DO) && overrun == 0) { - log(LOG_WARNING, "scc%d,%d: silo overflow\n", - unit >> 1, chan); - overrun = 1; - } - } - - if (!(tp->t_state & TS_ISOPEN)) { - wakeup((caddr_t)&tp->t_rawq); -#ifdef PORTSELECTOR - if (!(tp->t_state & TS_WOPEN)) -#endif - continue; - } - if (rr2 == SCC_RR2_A_RECV_SPECIAL || - rr2 == SCC_RR2_B_RECV_SPECIAL) { - if (rr1 & ZSRR1_PE) - cc |= TTY_PE; - if (rr1 & ZSRR1_FE) - cc |= TTY_FE; - } - (*linesw[tp->t_line].l_rint)(cc, tp); - } else if ((rr2 == SCC_RR2_A_EXT_STATUS) || (rr2 == SCC_RR2_B_EXT_STATUS)) { - chan = (rr2 == SCC_RR2_A_EXT_STATUS) ? - SCC_CHANNEL_A : SCC_CHANNEL_B; - SCC_WRITE_REG(regs, chan, SCC_RR0, ZSWR0_RESET_STATUS); - scc_modem_intr(unit | chan); - } - } - return 0; /* XXX */ -} - -void -sccstart(tp) - register struct tty *tp; -{ - register struct pdma *dp; - register scc_regmap_t *regs; - register struct scc_softc *sc; - register int cc, chan; - u_char temp; - int s, sendone; - - sc = scc_cd.cd_devs[SCCUNIT(tp->t_dev)]; - dp = &sc->scc_pdma[SCCLINE(tp->t_dev)]; - regs = (scc_regmap_t *)dp->p_addr; - s = spltty(); - if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) - goto out; - ttwakeupwr(tp); - if (tp->t_outq.c_cc == 0) - goto out; - /* handle console specially */ - if (tp == scctty(makedev(SCCDEV,SCCKBD_PORT)) && raster_console()) { - while (tp->t_outq.c_cc > 0) { - cc = getc(&tp->t_outq) & 0x7f; - cnputc(cc); - } - /* - * After we flush the output queue we may need to wake - * up the process that made the output. - */ - ttwakeupwr(tp); - goto out; - } - cc = ndqb(&tp->t_outq, 0); - - tp->t_state |= TS_BUSY; - dp->p_end = dp->p_mem = tp->t_outq.c_cf; - dp->p_end += cc; - - /* - * Enable transmission and send the first char, as required. - */ - chan = SCCLINE(tp->t_dev); - SCC_READ_REG(regs, chan, SCC_RR0, temp); - sendone = (temp & ZSRR0_TX_READY); - SCC_READ_REG(regs, chan, SCC_RR15, temp); - temp |= ZSWR15_TXUEOM_IE; - SCC_WRITE_REG(regs, chan, SCC_WR15, temp); - temp = sc->scc_wreg[chan].wr1 | ZSWR1_TIE; - SCC_WRITE_REG(regs, chan, SCC_WR1, temp); - sc->scc_wreg[chan].wr1 = temp; - if (sendone) { -#ifdef DIAGNOSTIC - if (cc == 0) - panic("sccstart: No chars"); -#endif - SCC_WRITE_DATA(regs, chan, *dp->p_mem++); - } - tc_mb(); -out: - splx(s); -} - -/* - * Stop output on a line. - */ -/*ARGSUSED*/ -int -sccstop(tp, flag) - register struct tty *tp; - int flag; -{ - register struct pdma *dp; - register struct scc_softc *sc; - register int s; - - sc = scc_cd.cd_devs[SCCUNIT(tp->t_dev)]; - dp = &sc->scc_pdma[SCCLINE(tp->t_dev)]; - s = spltty(); - if (tp->t_state & TS_BUSY) { - dp->p_end = dp->p_mem; - if (!(tp->t_state & TS_TTSTOP)) - tp->t_state |= TS_FLUSH; - } - splx(s); - return 0; -} - -int -sccmctl(sc, line, bits, how) - struct scc_softc *sc; - int line, bits, how; -{ - register scc_regmap_t *regs; - register int mbits; - register u_char value; - int s; - - regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr; - s = spltty(); - /* - * only channel B has modem control, however the DTR and RTS - * pins on the comm port are wired to the DTR and RTS A channel - * signals. - */ - mbits = DML_DTR | DML_DSR | DML_CAR; - if (line == SCC_CHANNEL_B) { - if (sc->scc_wreg[SCC_CHANNEL_A].wr5 & ZSWR5_DTR) - mbits = DML_DTR | DML_DSR; - else - mbits = 0; - SCC_READ_REG_ZERO(regs, SCC_CHANNEL_B, value); - if (value & ZSRR0_DCD) - mbits |= DML_CAR; - } - switch (how) { - case DMSET: - mbits = bits; - break; - - case DMBIS: - mbits |= bits; - break; - - case DMBIC: - mbits &= ~bits; - break; - - case DMGET: - (void) splx(s); - return (mbits); - } - if (line == SCC_CHANNEL_B) { - if (mbits & DML_DTR) - sc->scc_wreg[SCC_CHANNEL_A].wr5 |= ZSWR5_DTR; - else - sc->scc_wreg[SCC_CHANNEL_A].wr5 &= ~ZSWR5_DTR; - SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_WR5, - sc->scc_wreg[SCC_CHANNEL_A].wr5); - } - if ((mbits & DML_DTR) || (sc->scc_softCAR & (1 << line))) - sc->scc_tty[line]->t_state |= TS_CARR_ON; - (void) splx(s); - return (mbits); -} - -/* - * Check for carrier transition. - */ -void -scc_modem_intr(dev) - dev_t dev; -{ - register scc_regmap_t *regs; - register struct scc_softc *sc; - register struct tty *tp; - register int car, chan; - register u_char value; - int s; - - chan = SCCLINE(dev); - sc = scc_cd.cd_devs[SCCUNIT(dev)]; - tp = sc->scc_tty[chan]; - regs = (scc_regmap_t *)sc->scc_pdma[chan].p_addr; - if (chan == SCC_CHANNEL_A) - return; - s = spltty(); - if (sc->scc_softCAR & (1 << chan)) - car = 1; - else { - SCC_READ_REG_ZERO(regs, chan, value); - car = value & ZSRR0_DCD; - } - - /* Break on serial console drops into the debugger */ - if ((value & ZSRR0_BREAK) && CONSOLE_ON_UNIT(sc->sc_dv.dv_unit)) { -#ifdef DDB - splx(s); /* spl0()? */ - db_enter(); - return; -#else - /* XXX maybe fall back to PROM? */ -#endif - } - - splx(s); -} - -/* - * Get a char off the appropriate line via. a busy wait loop. - */ -int -sccGetc(dev) - dev_t dev; -{ - register scc_regmap_t *regs; - register int c, line; - register u_char value; - int s; - - line = SCCLINE(dev); - if (cold && scc_cons_addr) { - regs = scc_cons_addr; - } else { - register struct scc_softc *sc; - sc = scc_cd.cd_devs[SCCUNIT(dev)]; - regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr; - } - - if (!regs) - return (0); - s = splhigh(); - for (;;) { - SCC_READ_REG(regs, line, SCC_RR0, value); - if (value & ZSRR0_RX_READY) { - SCC_READ_REG(regs, line, SCC_RR1, value); - SCC_READ_DATA(regs, line, c); - if (value & (ZSRR1_PE | ZSRR1_DO | ZSRR1_FE)) { - SCC_WRITE_REG(regs, line, SCC_WR0, - ZSWR0_RESET_ERRORS); - SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_WR0, - ZSWR0_CLR_INTR); - } else { - SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_WR0, - ZSWR0_CLR_INTR); - splx(s); - return (c & 0xff); - } - } else - DELAY(10); - } -} - -/* - * Send a char on a port, via a busy wait loop. - */ -void -sccPutc(dev, c) - dev_t dev; - int c; -{ - register scc_regmap_t *regs; - register int line; - register u_char value; - int s; - - s = splhigh(); - line = SCCLINE(dev); - if (cold && scc_cons_addr) { - regs = scc_cons_addr; - } else { - register struct scc_softc *sc; - sc = scc_cd.cd_devs[SCCUNIT(dev)]; - regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr; - } - - /* - * Wait for transmitter to be not busy. - */ - do { - SCC_READ_REG(regs, line, SCC_RR0, value); - if (value & ZSRR0_TX_READY) - break; - DELAY(100); - } while (1); - - /* - * Send the char. - */ - SCC_WRITE_DATA(regs, line, c); - tc_mb(); - splx(s); - - return; -} - -/* - * Enable/disable polling mode - */ -void -sccPollc(dev, on) - dev_t dev; - int on; -{ -} - -#ifdef SCC_DEBUG -void -rr(msg, regs) - char *msg; - scc_regmap_t *regs; -{ - u_char value; - int r0, r1, r2, r3, r10, r15; - - printf("%s: register: %lx\n", msg, regs); -#define L(reg, r) { \ - SCC_READ_REG(regs, SCC_CHANNEL_A, reg, value); \ - r = value; \ -} - L(SCC_RR0, r0); - L(SCC_RR1, r1); - L(ZSRR_IVEC, r2); - L(ZSRR_IPEND, r3); - L(SCC_RR10, r10); - L(SCC_RR15, r15); - printf("A: 0: %x 1: %x 2(vec): %x 3: %x 10: %x 15: %x\n", - r0, r1, r2, r3, r10, r15); -#undef L -#define L(reg, r) { \ - SCC_READ_REG(regs, SCC_CHANNEL_B, reg, value); \ - r = value; \ -} - L(SCC_RR0, r0); - L(SCC_RR1, r1); - L(ZSRR_IVEC, r2); - L(SCC_RR10, r10); - L(SCC_RR15, r15); - printf("B: 0: %x 1: %x 2(state): %x 10: %x 15: %x\n", - r0, r1, r2, r10, r15); -} -#endif /* SCC_DEBUG */ diff --git a/sys/arch/alpha/tc/sccreg.h b/sys/arch/alpha/tc/sccreg.h deleted file mode 100644 index 5c3af0b818d..00000000000 --- a/sys/arch/alpha/tc/sccreg.h +++ /dev/null @@ -1,173 +0,0 @@ -/* $OpenBSD: sccreg.h,v 1.5 2003/06/02 23:27:44 millert Exp $ */ -/* $NetBSD: sccreg.h,v 1.3 1997/04/06 22:30:30 cgd Exp $ */ - -/* - * Copyright (c) 1991,1990,1989,1994,1995 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 ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS 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 Mellon - * the rights to redistribute these changes. - */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Ralph Campbell and Rick Macklem. - * - * 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. - * - * @(#)sccreg.h 8.1 (Berkeley) 6/10/93 - */ - -/* - * Definitions for Intel 82530 serial communications chip. Each chip is a - * dual uart with the A channels used for the keyboard and mouse with the B - * channel(s) for comm ports with modem control. Since some registers are - * used for the other channel, the following macros are used to access the - * register ports. - * - * Actual access to the registers is provided by sccvar.h, as it's - * machine-dependent. - */ - -/* Scc channel numbers; B channel comes first. */ -#define SCC_CHANNEL_B 0 -#define SCC_CHANNEL_A 1 - -#define SCC_INIT_REG(scc, chan) { \ - char tmp; \ - scc_get_datum((scc)->scc_channel[(chan)].scc_command, tmp); \ - scc_get_datum((scc)->scc_channel[(chan)].scc_command, tmp); \ -} - -#define SCC_READ_REG(scc, chan, reg, val) { \ - scc_set_datum((scc)->scc_channel[(chan)].scc_command, reg); \ - scc_get_datum((scc)->scc_channel[(chan)].scc_command, val); \ -} - -#define SCC_READ_REG_ZERO(scc, chan, val) { \ - scc_get_datum((scc)->scc_channel[(chan)].scc_command, val); \ -} - -#define SCC_WRITE_REG(scc, chan, reg, val) { \ - scc_set_datum((scc)->scc_channel[(chan)].scc_command, reg); \ - scc_set_datum((scc)->scc_channel[(chan)].scc_command, val); \ -} - -#define SCC_WRITE_REG_ZERO(scc, chan, val) { \ - scc_set_datum((scc)->scc_channel[(chan)].scc_command, val); \ -} - -#define SCC_READ_DATA(scc, chan, val) { \ - scc_get_datum((scc)->scc_channel[(chan)].scc_data, val); \ -} - -#define SCC_WRITE_DATA(scc, chan, val) { \ - scc_set_datum((scc)->scc_channel[(chan)].scc_data, val); \ -} - -/* Addressable registers. */ -#define SCC_RR0 0 /* status register */ -#define SCC_RR1 1 /* special receive conditions */ -#define SCC_RR8 8 /* recv buffer (alias for data) */ -#define SCC_RR10 10 /* sdlc status */ -#define SCC_RR15 15 /* interrupts currently enabled */ - -#define SCC_WR0 0 /* reg select, and commands */ -#define SCC_WR1 1 /* interrupt and DMA enables */ -#define SCC_WR3 3 /* receiver params and enables */ -#define SCC_WR4 4 /* clock/char/parity params */ -#define SCC_WR5 5 /* xmit params and enables */ -#define SCC_WR8 8 /* xmit buffer (alias for data) */ -#define SCC_WR9 9 /* vectoring and resets */ -#define SCC_WR10 10 /* synchr params */ -#define SCC_WR11 11 /* clocking definitions */ -#define SCC_WR14 14 /* BRG enables and commands */ -#define SCC_WR15 15 /* interrupt enables */ - -/* Read register's defines. */ - -/* - * RR2 contains the interrupt vector unmodified (channel A) or - * modified as follows (channel B, if vector-include-status). - */ -#define SCC_RR2_STATUS(val) ((val)&0xf) - -#define SCC_RR2_B_XMIT_DONE 0x0 -#define SCC_RR2_B_EXT_STATUS 0x2 -#define SCC_RR2_B_RECV_DONE 0x4 -#define SCC_RR2_B_RECV_SPECIAL 0x6 -#define SCC_RR2_A_XMIT_DONE 0x8 -#define SCC_RR2_A_EXT_STATUS 0xa -#define SCC_RR2_A_RECV_DONE 0xc -#define SCC_RR2_A_RECV_SPECIAL 0xe - -/* RR12/RR13 hold the timing base, upper byte in RR13. */ -#define SCC_GET_TIMING_BASE(scc, chan, val) { \ - register char tmp; \ - SCC_READ_REG(scc, chan, ZSRR_BAUDLO, val); \ - SCC_READ_REG(scc, chan, ZSRR_BAUDHI, tmp); \ - (val) = ((val) << 8) | (tmp & 0xff); \ - } - -/* - * Write register's defines. - */ - -/* WR12/WR13 are for timing base preset */ -#define SCC_SET_TIMING_BASE(scc, chan, val) { \ - SCC_WRITE_REG(scc, chan, ZSWR_BAUDLO, val); \ - SCC_WRITE_REG(scc, chan, ZSWR_BAUDHI, (val) >> 8); \ - } - -/* Bits in dm lsr, copied from dmreg.h. */ -#define DML_DSR 0000400 /* data set ready, not a real DM bit */ -#define DML_RNG 0000200 /* ring */ -#define DML_CAR 0000100 /* carrier detect */ -#define DML_CTS 0000040 /* clear to send */ -#define DML_SR 0000020 /* secondary receive */ -#define DML_ST 0000010 /* secondary transmit */ -#define DML_RTS 0000004 /* request to send */ -#define DML_DTR 0000002 /* data terminal ready */ -#define DML_LE 0000001 /* line enable */ diff --git a/sys/arch/alpha/tc/sccvar.h b/sys/arch/alpha/tc/sccvar.h deleted file mode 100644 index c4036e42e9e..00000000000 --- a/sys/arch/alpha/tc/sccvar.h +++ /dev/null @@ -1,118 +0,0 @@ -/* $OpenBSD: sccvar.h,v 1.7 2010/06/06 11:26:17 miod Exp $ */ -/* $NetBSD: sccvar.h,v 1.7 2001/08/26 16:39:56 simonb Exp $ */ - -/* - * Copyright (c) 1991,1990,1989,1994,1995 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 ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS 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 Mellon - * the rights to redistribute these changes. - */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Ralph Campbell and Rick Macklem. - * - * 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. - * - * from: @(#)sccreg.h 8.1 (Berkeley) 6/10/93 - */ - -/* - * Definitions for Intel 82530 serial communications chip. Each chip is a - * dual uart with the A channels used for the keyboard and mouse with the B - * channel(s) for comm ports with modem control. Since some registers are - * used for the other channel, the following macros are used to access the - * register ports. - */ - -#if 1 -#define alpha_sparse -#endif - -#define DENSE -#ifdef alpha_sparse -#undef DENSE -#define SPARSE -#endif - -typedef struct { - struct { - volatile u_int scc_command; /* Register select. */ -#ifdef SPARSE - u_int scc_pad0; -#endif - volatile u_int scc_data; /* Rx/Tx buffer */ -#ifdef SPARSE - u_int scc_pad1; -#endif - } scc_channel[2]; -} scc_regmap_t; - -#define scc_get_datum(d, v) \ - do { (v) = ((d) >> 8) & 0xff; alpha_mb(); DELAY(5); } while (0) -#define scc_set_datum(d, v) \ - do { (d) = (volatile unsigned int)(v) << 8; alpha_mb(); DELAY(5); } while (0) - -/* From <pmax/dev/pdma.h>. */ -struct pdma { - void *p_addr; - char *p_mem; - char *p_end; - int p_arg; - void (*p_fcn)(struct tty *tp); -}; - -/* - * Minor device numbers for scc. Weird because B channel comes first and - * the A channels are wired for keyboard/mouse and the B channels for the - * comm port(s). - */ -#define SCCCOMM2_PORT 0x0 -#define SCCMOUSE_PORT 0x1 -#define SCCCOMM3_PORT 0x2 -#define SCCKBD_PORT 0x3 - -extern int alpha_donot_kludge_scc; diff --git a/sys/arch/alpha/tc/tc_3000_300.c b/sys/arch/alpha/tc/tc_3000_300.c index 2104e880be6..1ce1daee16e 100644 --- a/sys/arch/alpha/tc/tc_3000_300.c +++ b/sys/arch/alpha/tc/tc_3000_300.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tc_3000_300.c,v 1.18 2015/05/19 20:28:14 miod Exp $ */ +/* $OpenBSD: tc_3000_300.c,v 1.19 2017/11/02 14:04:24 mpi Exp $ */ /* $NetBSD: tc_3000_300.c,v 1.26 2001/07/27 00:25:21 thorpej Exp $ */ /* @@ -42,11 +42,6 @@ #include <alpha/tc/tc_3000_300.h> #include "wsdisplay.h" -#include "sfb.h" - -#if NSFB > 0 -extern int sfb_cnattach(tc_addr_t); -#endif int tc_3000_300_intrnull(void *); @@ -297,12 +292,7 @@ tc_3000_300_fb_cnattach(turbo_slot) } if (output_slot == 0) { -#if NSFB > 0 - sfb_cnattach(KV(0x1c0000000) + 0x02000000); - return 0; -#else return ENXIO; -#endif } return tc_fb_cnattach(tc_3000_300_slots[output_slot-1].tcs_addr); diff --git a/sys/arch/alpha/tc/tc_3000_500.c b/sys/arch/alpha/tc/tc_3000_500.c index 171572a0f75..e7a52f0daa8 100644 --- a/sys/arch/alpha/tc/tc_3000_500.c +++ b/sys/arch/alpha/tc/tc_3000_500.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tc_3000_500.c,v 1.20 2017/10/29 08:50:43 mpi Exp $ */ +/* $OpenBSD: tc_3000_500.c,v 1.21 2017/11/02 14:04:24 mpi Exp $ */ /* $NetBSD: tc_3000_500.c,v 1.24 2001/07/27 00:25:21 thorpej Exp $ */ /* @@ -42,11 +42,6 @@ #include <alpha/tc/tc_3000_500.h> #include "wsdisplay.h" -#include "sfb.h" - -#if NSFB > 0 -extern int sfb_cnattach(tc_addr_t); -#endif int tc_3000_500_intrnull(void *); int tc_3000_500_fb_cnattach(u_int64_t); @@ -290,12 +285,7 @@ tc_3000_500_fb_cnattach(turbo_slot) if (hwrpb->rpb_variation & SV_GRAPHICS) { if (output_slot == 0) { -#if NSFB > 0 - sfb_cnattach(KV(0x1e0000000) + 0x02000000); - return 0; -#else return ENXIO; -#endif } } else { /* diff --git a/sys/dev/tc/files.tc b/sys/dev/tc/files.tc index b47daf622e4..aa4430d2263 100644 --- a/sys/dev/tc/files.tc +++ b/sys/dev/tc/files.tc @@ -1,4 +1,4 @@ -# $OpenBSD: files.tc,v 1.13 2015/05/11 06:46:22 ratchov Exp $ +# $OpenBSD: files.tc,v 1.14 2017/11/02 14:04:24 mpi Exp $ # $NetBSD: files.tc,v 1.26 2001/11/28 10:21:24 lukem Exp $ # # Config file and device description for machine-independent @@ -33,10 +33,26 @@ device tcds {[chip = -1]} attach tcds at tc file dev/tc/tcds.c tcds -# 53C[F]90 PMAZ single channel SCSI +# 53C[F]90 PMAZ single or dual channel SCSI device asc: ncr53c9x, scsi file dev/tc/asc.c asc attach asc at tc with asc_tc file dev/tc/asc_tc.c asc_tc attach asc at tcds with asc_tcds file dev/tc/asc_tcds.c asc_tcds + +# 8530 UARTs using the MI 8530 driver +device zs {[channel = -1]} +attach zs at ioasic with zs_ioasic +file dev/tc/zs_ioasic.c zs needs-flag +file dev/ic/z8530sc.c zs + +device zstty: tty +attach zstty at zs +file dev/ic/z8530tty.c zstty needs-flag + +#attach vsms at zs with zsms +#file dev/tc/zsms.c zsms + +#attach lkkbd at zs with zskbd +#file dev/tc/zskbd.c zskbd needs-flag diff --git a/sys/dev/tc/zs_ioasic.c b/sys/dev/tc/zs_ioasic.c new file mode 100644 index 00000000000..a0579934f9b --- /dev/null +++ b/sys/dev/tc/zs_ioasic.c @@ -0,0 +1,825 @@ +/* $OpenBSD: zs_ioasic.c,v 1.1 2017/11/02 14:04:24 mpi Exp $ */ +/* $NetBSD: zs_ioasic.c,v 1.40 2009/05/12 13:21:22 cegger Exp $ */ + +/*- + * Copyright (c) 1996, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Gordon W. Ross, Ken Hornstein, and by Jason R. Thorpe of the + * Numerical Aerospace Simulation Facility, NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Zilog Z8530 Dual UART driver (machine-dependent part). This driver + * handles Z8530 chips attached to the DECstation/Alpha IOASIC. Modified + * for NetBSD/alpha by Ken Hornstein and Jason R. Thorpe. NetBSD/pmax + * adaption by Mattias Drochner. Merge work by Tohru Nishimura. + * + * Runs two serial lines per chip using slave drivers. + * Plain tty/async lines use the zstty slave. + */ + +#if 0 +#include "zskbd.h" +#endif + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/device.h> +#include <sys/malloc.h> +#include <sys/file.h> +#include <sys/ioctl.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/tty.h> +#include <sys/time.h> +#include <sys/syslog.h> + +#include <machine/autoconf.h> +#include <machine/z8530var.h> + +#include <dev/cons.h> + +#include <dev/ic/z8530reg.h> + +#include <dev/tc/tcvar.h> +#include <dev/tc/ioasicreg.h> +#include <dev/tc/ioasicvar.h> + +#include <dev/tc/zs_ioasicvar.h> + +#if defined(__alpha__) +#include <machine/rpb.h> +#endif + +/* + * Helpers for console support. + */ +static void zs_ioasic_cninit(tc_addr_t, tc_offset_t, int); +static int zs_ioasic_cngetc(dev_t); +static void zs_ioasic_cnputc(dev_t, int); +static void zs_ioasic_cnpollc(dev_t, int); + +#if 0 +cons_decl(zs_ioasic_); +#endif +struct consdev zs_ioasic_cons = { + NULL, + NULL, + zs_ioasic_cngetc, + zs_ioasic_cnputc, + zs_ioasic_cnpollc, + NULL +}; + +static tc_offset_t zs_ioasic_console_offset; +static int zs_ioasic_console_channel; +static int zs_ioasic_console; +static struct zs_chanstate zs_ioasic_conschanstate_store; + +static int zs_ioasic_isconsole(tc_offset_t, int); +static void zs_putc(struct zs_chanstate *, int); + +/* + * Some warts needed by z8530tty.c + */ +int zs_def_cflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8; +#if defined(__alpha__) +int zs_major = 15; +#endif + +/* + * ZS chips are feeded a 7.372 MHz clock. + */ +#define PCLK (9600 * 768) /* PCLK pin input clock rate */ + +/* The layout of this is hardware-dependent (padding, order). */ +struct zshan { +#if defined(__alpha__) || defined(alpha) + volatile u_int zc_csr; /* ctrl,status, and indirect access */ + u_int zc_pad0; + volatile u_int zc_data; /* data */ + u_int sc_pad1; +#endif +}; + +struct zsdevice { + /* Yes, they are backwards. */ + struct zshan zs_chan_b; + struct zshan zs_chan_a; +}; + +static const uint8_t zs_ioasic_init_reg[16] = { + 0, /* 0: CMD (reset, etc.) */ + 0, /* 1: No interrupts yet. */ + 0xf0, /* 2: IVECT */ + ZSWR3_RX_8 | ZSWR3_RX_ENABLE, + ZSWR4_CLK_X16 | ZSWR4_ONESB, + ZSWR5_TX_8 | ZSWR5_TX_ENABLE, + 0, /* 6: TXSYNC/SYNCLO */ + 0, /* 7: RXSYNC/SYNCHI */ + 0, /* 8: alias for data port */ + ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT, + 0, /*10: Misc. TX/RX control bits */ + ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, + 22, /*12: BAUDLO (default=9600) */ + 0, /*13: BAUDHI (default=9600) */ + ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK, + ZSWR15_BREAK_IE +}; + +static struct zshan * +zs_ioasic_get_chan_addr(tc_addr_t zsaddr, int channel) +{ + struct zsdevice *addr; + struct zshan *zc; + +#if defined(__alpha__) + addr = (struct zsdevice *)TC_DENSE_TO_SPARSE(zsaddr); +#endif + + if (channel == 0) + zc = &addr->zs_chan_a; + else + zc = &addr->zs_chan_b; + + return (zc); +} + + +/**************************************************************** + * Autoconfig + ****************************************************************/ + +/* Definition of the driver for autoconfig. */ +static int zs_ioasic_match(struct device *, void *, void *); +static void zs_ioasic_attach(struct device *, struct device *, void *); +static int zs_ioasic_print(void *, const char *name); +static int zs_ioasic_submatch(struct device *, void *, void *); + +struct cfdriver zs_cd = { + NULL, "zs", DV_TTY +}; + +const struct cfattach zs_ioasic_ca = { + sizeof(struct zsc_softc), zs_ioasic_match, zs_ioasic_attach +}; + +/* Interrupt handlers. */ +static int zs_ioasic_hardintr(void *); +static void zs_ioasic_softintr(void *); + +/* + * Is the zs chip present? + */ +static int +zs_ioasic_match(struct device *parent, void *vcf, void *aux) +{ + struct ioasicdev_attach_args *d = aux; + tc_addr_t zs_addr; + + /* + * Make sure that we're looking for the right kind of device. + */ + if (strncmp(d->iada_modname, "z8530 ", TC_ROM_LLEN) != 0 && + strncmp(d->iada_modname, "scc", TC_ROM_LLEN) != 0) + return (0); + + /* + * Find out the device address, and check it for validity. + */ + zs_addr = TC_DENSE_TO_SPARSE((tc_addr_t)d->iada_addr); + if (tc_badaddr(zs_addr)) + return (0); + + return (1); +} + +/* + * Attach a found zs. + */ +static void +zs_ioasic_attach(struct device *parent, struct device *self, void *aux) +{ + struct zsc_softc *zs = (void *)self; + struct zsc_attach_args zs_args; + struct zs_chanstate *cs; + struct ioasicdev_attach_args *d = aux; + struct zshan *zc; + int s, channel; + u_long zflg; + + printf("\n"); + + /* + * Initialize software state for each channel. + */ + for (channel = 0; channel < 2; channel++) { + zs_args.channel = channel; + zs_args.hwflags = 0; + zs_args.type = NULL; + + if (zs_ioasic_isconsole(d->iada_offset, channel)) { + cs = &zs_ioasic_conschanstate_store; + zs_args.hwflags |= ZS_HWFLAG_CONSOLE; + } else { + cs = malloc(sizeof(struct zs_chanstate), + M_DEVBUF, M_NOWAIT | M_ZERO); + zc = zs_ioasic_get_chan_addr(d->iada_addr, channel); + cs->cs_reg_csr = (volatile void *)&zc->zc_csr; + + memcpy(cs->cs_creg, zs_ioasic_init_reg, 16); + memcpy(cs->cs_preg, zs_ioasic_init_reg, 16); + + cs->cs_defcflag = zs_def_cflag; + cs->cs_defspeed = 9600; /* XXX */ + (void)zs_set_modes(cs, cs->cs_defcflag); + } + + zs->zsc_cs[channel] = cs; + zs->zsc_addroffset = d->iada_offset; /* cookie only */ + cs->cs_channel = channel; + cs->cs_ops = &zsops_null; + cs->cs_brg_clk = PCLK / 16; + + /* + * DCD and CTS interrupts are only meaningful on + * SCC 0/B, and RTS and DTR only on B of SCC 0 & 1. + * + * XXX This is sorta gross. + */ + if (d->iada_offset == 0x00100000 && channel == 1) { + cs->cs_creg[15] |= ZSWR15_DCD_IE; + cs->cs_preg[15] |= ZSWR15_DCD_IE; + zflg = ZIP_FLAGS_DCDCTS; + } else + zflg = 0; + if (channel == 1) + zflg |= ZIP_FLAGS_DTRRTS; + cs->cs_private = (void *)zflg; + + /* + * Clear the master interrupt enable. + * The INTENA is common to both channels, + * so just do it on the A channel. + */ + if (channel == 0) { + zs_write_reg(cs, 9, 0); + } + + /* + * Set up the flow/modem control channel pointer to + * deal with the weird wiring on the TC Alpha and + * DECstation. + */ + if (channel == 1) + cs->cs_ctl_chan = zs->zsc_cs[0]; + else + cs->cs_ctl_chan = NULL; + + if (d->iada_offset == 0x00100000) { + if (channel == 0) + zs_args.type = "vsms"; + else + zs_args.type = "zstty"; + } else { + if (channel == 0) + zs_args.type = "lkkbd"; + else { +#if defined(__alpha__) + if (cputype != ST_DEC_3000_300) +#endif + zs_args.type = "zstty"; + } + } + + /* + * Look for a child driver for this channel. + * The child attach will setup the hardware. + */ + if (zs_args.type == NULL || + config_found_sm(self, (void *)&zs_args, zs_ioasic_print, + zs_ioasic_submatch) == + NULL) { + /* No sub-driver. Just reset it. */ + uint8_t reset = (channel == 0) ? + ZSWR9_A_RESET : ZSWR9_B_RESET; + s = splhigh(); + zs_write_reg(cs, 9, reset); + splx(s); + } + } + + /* + * Set up the ioasic interrupt handler. + */ + ioasic_intr_establish(parent, d->iada_cookie, IPL_TTY, + zs_ioasic_hardintr, zs, self->dv_xname); + zs->zsc_sih = softintr_establish(IPL_SOFTSERIAL, zs_ioasic_softintr, zs); + if (zs->zsc_sih == NULL) + panic("%s: unable to register softintr", __func__); + + /* + * Set the master interrupt enable and interrupt vector. The + * Sun does this only on one channel. The old Alpha SCC driver + * did it on both. We'll do it on both. + */ + s = splhigh(); + /* interrupt vector */ + zs_write_reg(zs->zsc_cs[0], 2, zs_ioasic_init_reg[2]); + zs_write_reg(zs->zsc_cs[1], 2, zs_ioasic_init_reg[2]); + + /* master interrupt control (enable) */ + zs_write_reg(zs->zsc_cs[0], 9, zs_ioasic_init_reg[9]); + zs_write_reg(zs->zsc_cs[1], 9, zs_ioasic_init_reg[9]); +#if defined(__alpha__) + /* ioasic interrupt enable */ + *(volatile u_int *)(ioasic_base + IOASIC_IMSK) |= + IOASIC_INTR_SCC_1 | IOASIC_INTR_SCC_0; + tc_mb(); +#endif + splx(s); +} + +static int +zs_ioasic_print(void *aux, const char *pnp) +{ + struct zsc_attach_args *args = aux; + + if (pnp != NULL) + printf("%s at %s", args->type, pnp); + + if (args->channel != -1) + printf(" channel %d", args->channel); + + return (UNCONF); +} + +static int +zs_ioasic_submatch(struct device *parent, void *vcf, void *aux) +{ + struct cfdata *cf = (struct cfdata *)vcf; + struct zsc_attach_args *za = (struct zsc_attach_args *)aux; + + if (strcmp(cf->cf_driver->cd_name, za->type) != 0) + return 0; + + return (*cf->cf_attach->ca_match)(parent, cf, aux); +} + +/* + * Hardware interrupt handler. + */ +static int +zs_ioasic_hardintr(void *arg) +{ + struct zsc_softc *zsc = arg; + int rval; + + /* + * Call the upper-level MI hardware interrupt handler. + */ + rval = zsc_intr_hard(zsc); + + /* + * Check to see if we need to schedule any software-level + * processing interrupts. + */ + if (rval != 0) { + if (zsc->zsc_cs[0]->cs_softreq | zsc->zsc_cs[1]->cs_softreq) + softintr_schedule(zsc->zsc_sih); + } + + return rval; +} + +/* + * Software-level interrupt (character processing, lower priority). + */ +static void +zs_ioasic_softintr(void *arg) +{ + struct zsc_softc *zsc = arg; + int s; + + s = spltty(); + (void)zsc_intr_soft(zsc); + splx(s); +} + +/* + * MD functions for setting the baud rate and control modes. + */ +int +zs_set_speed(struct zs_chanstate *cs, int bps) +{ + int tconst, real_bps; + + if (bps == 0) + return (0); + +#ifdef DIAGNOSTIC + if (cs->cs_brg_clk == 0) + panic("zs_set_speed"); +#endif + + tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps); + if (tconst < 0) + return (EINVAL); + + /* Convert back to make sure we can do it. */ + real_bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst); + +#if 0 + /* XXX - Allow some tolerance here? */ + if (real_bps != bps) + return (EINVAL); +#endif + + cs->cs_preg[12] = tconst; + cs->cs_preg[13] = tconst >> 8; + + /* Caller will stuff the pending registers. */ + return (0); +} + +int +zs_set_modes(struct zs_chanstate *cs, int cflag) +{ + u_long privflags = (u_long)cs->cs_private; + int s; + + /* + * Output hardware flow control on the chip is horrendous: + * if carrier detect drops, the receiver is disabled, and if + * CTS drops, the transmitter is stoped IN MID CHARACTER! + * Therefore, NEVER set the HFC bit, and instead use the + * status interrupt to detect CTS changes. + */ + s = splzs(); + cs->cs_rr0_pps = 0; + if ((cflag & (CLOCAL | MDMBUF)) != 0) { + cs->cs_rr0_dcd = 0; + if ((cflag & MDMBUF) == 0) + cs->cs_rr0_pps = ZSRR0_DCD; + } else + cs->cs_rr0_dcd = ZSRR0_DCD; + if ((cflag & CRTSCTS) != 0) { + cs->cs_wr5_dtr = ZSWR5_DTR; + cs->cs_wr5_rts = ZSWR5_RTS; + cs->cs_rr0_cts = ZSRR0_CTS; +#if defined(CDTRCTS) + } else if ((cflag & CDTRCTS) != 0) { + cs->cs_wr5_dtr = 0; + cs->cs_wr5_rts = ZSWR5_DTR; + cs->cs_rr0_cts = ZSRR0_CTS; +#endif + } else if ((cflag & MDMBUF) != 0) { + cs->cs_wr5_dtr = 0; + cs->cs_wr5_rts = ZSWR5_DTR; + cs->cs_rr0_cts = ZSRR0_DCD; + } else { + cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS; + cs->cs_wr5_rts = 0; + cs->cs_rr0_cts = 0; + } + + if ((privflags & ZIP_FLAGS_DCDCTS) == 0) { + cs->cs_rr0_dcd &= ~(ZSRR0_CTS|ZSRR0_DCD); + cs->cs_rr0_cts &= ~(ZSRR0_CTS|ZSRR0_DCD); + } + if ((privflags & ZIP_FLAGS_DTRRTS) == 0) { + cs->cs_wr5_dtr &= ~(ZSWR5_RTS|ZSWR5_DTR); + cs->cs_wr5_rts &= ~(ZSWR5_RTS|ZSWR5_DTR); + } + splx(s); + + /* Caller will stuff the pending registers. */ + return (0); +} + +/* + * Functions to read and write individual registers in a channel. + * The ZS chip requires a 1.6 uSec. recovery time between accesses, + * and the Alpha TC hardware does NOT take care of this for you. + * The delay is now handled inside the chip access functions. + * These could be inlines, but with the delay, speed is moot. + */ + +uint8_t +zs_read_reg(struct zs_chanstate *cs, uint8_t reg) +{ + volatile struct zshan *zc = (volatile void *)cs->cs_reg_csr; + unsigned val; + + zc->zc_csr = reg << 8; + tc_wmb(); + DELAY(5); + val = (zc->zc_csr >> 8) & 0xff; + /* tc_mb(); */ + DELAY(5); + return (val); +} + +void +zs_write_reg(struct zs_chanstate *cs, uint8_t reg, uint8_t val) +{ + volatile struct zshan *zc = (volatile void *)cs->cs_reg_csr; + + zc->zc_csr = reg << 8; + tc_wmb(); + DELAY(5); + zc->zc_csr = val << 8; + tc_wmb(); + DELAY(5); +} + +uint8_t +zs_read_csr(struct zs_chanstate *cs) +{ + volatile struct zshan *zc = (volatile void *)cs->cs_reg_csr; + unsigned val; + + val = (zc->zc_csr >> 8) & 0xff; + /* tc_mb(); */ + DELAY(5); + return (val); +} + +void +zs_write_csr(struct zs_chanstate *cs, uint8_t val) +{ + volatile struct zshan *zc = (volatile void *)cs->cs_reg_csr; + + zc->zc_csr = val << 8; + tc_wmb(); + DELAY(5); +} + +uint8_t +zs_read_data(struct zs_chanstate *cs) +{ + volatile struct zshan *zc = (volatile void *)cs->cs_reg_csr; + unsigned val; + + val = (zc->zc_data) >> 8 & 0xff; + /* tc_mb(); */ + DELAY(5); + return (val); +} + +void +zs_write_data(struct zs_chanstate *cs, uint8_t val) +{ + volatile struct zshan *zc = (volatile void *)cs->cs_reg_csr; + + zc->zc_data = val << 8; + tc_wmb(); + DELAY(5); +} + +/**************************************************************** + * Console support functions + ****************************************************************/ + +/* + * Handle user request to enter kernel debugger. + */ +void +zs_abort(struct zs_chanstate *cs) +{ + u_int rr0; + + /* Wait for end of break. */ + /* XXX - Limit the wait? */ + do { + rr0 = zs_read_csr(cs); + } while (rr0 & ZSRR0_BREAK); + +#if defined(DDB) + db_enter(); +#else + printf("zs_abort: ignoring break on console\n"); +#endif +} + +/* + * Polled input char. + */ +int +zs_getc(struct zs_chanstate *cs) +{ + int s, c; + u_int rr0; + + s = splhigh(); + /* Wait for a character to arrive. */ + do { + rr0 = zs_read_csr(cs); + } while ((rr0 & ZSRR0_RX_READY) == 0); + + c = zs_read_data(cs); + splx(s); + + /* + * This is used by the kd driver to read scan codes, + * so don't translate '\r' ==> '\n' here... + */ + return (c); +} + +/* + * Polled output char. + */ +static void +zs_putc(struct zs_chanstate *cs, int c) +{ + int s; + u_int rr0; + + s = splhigh(); + /* Wait for transmitter to become ready. */ + do { + rr0 = zs_read_csr(cs); + } while ((rr0 & ZSRR0_TX_READY) == 0); + + zs_write_data(cs, c); + + /* Wait for the character to be transmitted. */ + do { + rr0 = zs_read_csr(cs); + } while ((rr0 & ZSRR0_TX_READY) == 0); + splx(s); +} + +/*****************************************************************/ + +/* + * zs_ioasic_cninit -- + * Initialize the serial channel for either a keyboard or + * a serial console. + */ +static void +zs_ioasic_cninit(tc_addr_t ioasic_addr, tc_offset_t zs_offset, int channel) +{ + struct zs_chanstate *cs; + tc_addr_t zs_addr; + struct zshan *zc; + u_long zflg; + + /* + * Initialize the console finder helpers. + */ + zs_ioasic_console_offset = zs_offset; + zs_ioasic_console_channel = channel; + zs_ioasic_console = 1; + + /* + * Pointer to channel state. + */ + cs = &zs_ioasic_conschanstate_store; + + /* + * Compute the physical address of the chip, "map" it via + * K0SEG, and then get the address of the actual channel. + */ +#if defined(__alpha__) + zs_addr = ALPHA_PHYS_TO_K0SEG(ioasic_addr + zs_offset); +#endif + zc = zs_ioasic_get_chan_addr(zs_addr, channel); + + /* Setup temporary chanstate. */ + cs->cs_reg_csr = (volatile void *)&zc->zc_csr; + + cs->cs_channel = channel; + cs->cs_ops = &zsops_null; + cs->cs_brg_clk = PCLK / 16; + + /* Initialize the pending registers. */ + memcpy(cs->cs_preg, zs_ioasic_init_reg, 16); + /* cs->cs_preg[5] |= (ZSWR5_DTR | ZSWR5_RTS); */ + + /* + * DCD and CTS interrupts are only meaningful on + * SCC 0/B, and RTS and DTR only on B of SCC 0 & 1. + * + * XXX This is sorta gross. + */ + if (zs_offset == 0x00100000 && channel == 1) + zflg = ZIP_FLAGS_DCDCTS; + else + zflg = 0; + if (channel == 1) + zflg |= ZIP_FLAGS_DTRRTS; + cs->cs_private = (void *)zflg; + + /* Clear the master interrupt enable. */ + zs_write_reg(cs, 9, 0); + + /* Reset the whole SCC chip. */ + zs_write_reg(cs, 9, ZSWR9_HARD_RESET); + + /* Copy "pending" to "current" and H/W. */ + zs_loadchannelregs(cs); +} + +/* + * zs_ioasic_cnattach -- + * Initialize and attach a serial console. + */ +void +zs_ioasic_cnattach(tc_addr_t ioasic_addr, tc_offset_t zs_offset, int channel) +{ + struct zs_chanstate *cs = &zs_ioasic_conschanstate_store; + + zs_ioasic_cninit(ioasic_addr, zs_offset, channel); + cs->cs_defspeed = 9600; + cs->cs_defcflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8; + + /* Point the console at the SCC. */ + cn_tab = &zs_ioasic_cons; + cn_tab->cn_pri = CN_FORCED; + cn_tab->cn_dev = makedev(zs_major, (zs_offset == 0x100000) ? 0 : 1); +} + +#if 0 +/* + * zs_ioasic_lk201_cnattach -- + * Initialize and attach a keyboard. + */ +int +zs_ioasic_lk201_cnattach(tc_addr_t ioasic_addr, tc_offset_t zs_offset, + int channel) +{ +#if (NZSKBD > 0) + struct zs_chanstate *cs = &zs_ioasic_conschanstate_store; + + zs_ioasic_cninit(ioasic_addr, zs_offset, channel); + cs->cs_defspeed = 4800; + cs->cs_defcflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8; + return (zskbd_cnattach(cs)); +#else + return (ENXIO); +#endif +} +#endif + +static int +zs_ioasic_isconsole(tc_offset_t offset, int channel) +{ + if (zs_ioasic_console && + offset == zs_ioasic_console_offset && + channel == zs_ioasic_console_channel) + return (1); + + return (0); +} + +/* + * Polled console input putchar. + */ +static int +zs_ioasic_cngetc(dev_t dev) +{ + return (zs_getc(&zs_ioasic_conschanstate_store)); +} + +/* + * Polled console output putchar. + */ +static void +zs_ioasic_cnputc(dev_t dev, int c) +{ + zs_putc(&zs_ioasic_conschanstate_store, c); +} + +/* + * Set polling/no polling on console. + */ +static void +zs_ioasic_cnpollc(dev_t dev, int onoff) +{ +} diff --git a/sys/dev/tc/zs_ioasicvar.h b/sys/dev/tc/zs_ioasicvar.h new file mode 100644 index 00000000000..fbe7248b810 --- /dev/null +++ b/sys/dev/tc/zs_ioasicvar.h @@ -0,0 +1,44 @@ +/* $OpenBSD: zs_ioasicvar.h,v 1.1 2017/11/02 14:04:24 mpi Exp $ */ +/* $NetBSD: zs_ioasicvar.h,v 1.6 2008/04/28 20:23:58 martin Exp $ */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * We use the private data pointer as a (u_long) of flags. Here + * are the flags. + */ +#define ZIP_FLAGS_DCDCTS 0x01 /* channel has DCD and CTS signals */ +#define ZIP_FLAGS_DTRRTS 0x02 /* channel has DTR and RTS signals */ + +extern void zs_ioasic_cnattach(tc_addr_t, tc_offset_t, int); +extern int zs_ioasic_lk201_cnattach(tc_addr_t, tc_offset_t, int); +extern int zskbd_cnattach(struct zs_chanstate *); +extern int zs_getc(struct zs_chanstate *); |