xref: /openbsd/sys/arch/luna88k/stand/boot/sio.c (revision 8352e4cb)
1*8352e4cbSmiod /*	$OpenBSD: sio.c,v 1.4 2023/01/10 17:10:57 miod Exp $	*/
296f141a8Smiod /*	$NetBSD: sio.c,v 1.3 2013/01/21 11:58:12 tsutsui Exp $	*/
396f141a8Smiod 
496f141a8Smiod /*
596f141a8Smiod  * Copyright (c) 1992 OMRON Corporation.
696f141a8Smiod  *
796f141a8Smiod  * This code is derived from software contributed to Berkeley by
896f141a8Smiod  * OMRON Corporation.
996f141a8Smiod  *
1096f141a8Smiod  * Redistribution and use in source and binary forms, with or without
1196f141a8Smiod  * modification, are permitted provided that the following conditions
1296f141a8Smiod  * are met:
1396f141a8Smiod  * 1. Redistributions of source code must retain the above copyright
1496f141a8Smiod  *    notice, this list of conditions and the following disclaimer.
1596f141a8Smiod  * 2. Redistributions in binary form must reproduce the above copyright
1696f141a8Smiod  *    notice, this list of conditions and the following disclaimer in the
1796f141a8Smiod  *    documentation and/or other materials provided with the distribution.
1896f141a8Smiod  * 3. All advertising materials mentioning features or use of this software
1996f141a8Smiod  *    must display the following acknowledgement:
2096f141a8Smiod  *	This product includes software developed by the University of
2196f141a8Smiod  *	California, Berkeley and its contributors.
2296f141a8Smiod  * 4. Neither the name of the University nor the names of its contributors
2396f141a8Smiod  *    may be used to endorse or promote products derived from this software
2496f141a8Smiod  *    without specific prior written permission.
2596f141a8Smiod  *
2696f141a8Smiod  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2796f141a8Smiod  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2896f141a8Smiod  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2996f141a8Smiod  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3096f141a8Smiod  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3196f141a8Smiod  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3296f141a8Smiod  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3396f141a8Smiod  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3496f141a8Smiod  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3596f141a8Smiod  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3696f141a8Smiod  * SUCH DAMAGE.
3796f141a8Smiod  *
3896f141a8Smiod  *	@(#)sio.c	8.1 (Berkeley) 6/10/93
3996f141a8Smiod  */
4096f141a8Smiod /*
4196f141a8Smiod  * Copyright (c) 1992, 1993
4296f141a8Smiod  *	The Regents of the University of California.  All rights reserved.
4396f141a8Smiod  *
4496f141a8Smiod  * This code is derived from software contributed to Berkeley by
4596f141a8Smiod  * OMRON Corporation.
4696f141a8Smiod  *
4796f141a8Smiod  * Redistribution and use in source and binary forms, with or without
4896f141a8Smiod  * modification, are permitted provided that the following conditions
4996f141a8Smiod  * are met:
5096f141a8Smiod  * 1. Redistributions of source code must retain the above copyright
5196f141a8Smiod  *    notice, this list of conditions and the following disclaimer.
5296f141a8Smiod  * 2. Redistributions in binary form must reproduce the above copyright
5396f141a8Smiod  *    notice, this list of conditions and the following disclaimer in the
5496f141a8Smiod  *    documentation and/or other materials provided with the distribution.
5596f141a8Smiod  * 3. Neither the name of the University nor the names of its contributors
5696f141a8Smiod  *    may be used to endorse or promote products derived from this software
5796f141a8Smiod  *    without specific prior written permission.
5896f141a8Smiod  *
5996f141a8Smiod  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
6096f141a8Smiod  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6196f141a8Smiod  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6296f141a8Smiod  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
6396f141a8Smiod  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6496f141a8Smiod  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
6596f141a8Smiod  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6696f141a8Smiod  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
6796f141a8Smiod  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6896f141a8Smiod  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6996f141a8Smiod  * SUCH DAMAGE.
7096f141a8Smiod  *
7196f141a8Smiod  *	@(#)sio.c	8.1 (Berkeley) 6/10/93
7296f141a8Smiod  */
7396f141a8Smiod 
7496f141a8Smiod /* sio.c   NOV-25-1991 */
7596f141a8Smiod 
7696f141a8Smiod #define NSIO 2
7796f141a8Smiod 
7896f141a8Smiod #include <sys/param.h>
79d2f66e2eSmiod #include <machine/board.h>
8096f141a8Smiod #include <luna88k/stand/boot/samachdep.h>
8196f141a8Smiod #include <luna88k/stand/boot/sioreg.h>
8296f141a8Smiod #include <luna88k/stand/boot/rcvbuf.h>
8396f141a8Smiod #include <luna88k/stand/boot/kbdreg.h>
8496f141a8Smiod 
8596f141a8Smiod static int sioreg(int, int);
8696f141a8Smiod 
8796f141a8Smiod struct rcvbuf	rcvbuf[NSIO];
8896f141a8Smiod 
8996f141a8Smiod int	sioconsole = -1;
9096f141a8Smiod struct	siodevice *sio_addr[2];
9196f141a8Smiod 
9296f141a8Smiod int
siointr(int unit)9396f141a8Smiod siointr(int unit)
9496f141a8Smiod {
9596f141a8Smiod /*	struct siodevice *sio = sio_addr[unit]; */
9696f141a8Smiod 	int rr0 = sioreg(REG(unit, RR0), 0);
9796f141a8Smiod 	int rr1 = sioreg(REG(unit, RR1), 0);
9896f141a8Smiod 
9996f141a8Smiod 	if (rr0 & RR0_RXAVAIL) {
10096f141a8Smiod 		if (rr1 & RR1_FRAMING)
10196f141a8Smiod 			return 1;
10296f141a8Smiod 
10396f141a8Smiod 		if (rr1 & (RR1_PARITY | RR1_OVERRUN))
10496f141a8Smiod 		    sioreg(REG(unit, WR0), WR0_ERRRST); /* Channel-A Error Reset */
10596f141a8Smiod 
10696f141a8Smiod 		if (unit == 1) {
10796f141a8Smiod 			int c = kbd_decode(sio_addr[unit]->sio_data);
10896f141a8Smiod 
10996f141a8Smiod 			if ((c & KC_TYPE) == KC_CODE)
11096f141a8Smiod 				PUSH_RBUF(unit, c);
11196f141a8Smiod 		} else {
11296f141a8Smiod 			PUSH_RBUF(unit, sio_addr[unit]->sio_data);
11396f141a8Smiod 		}
11496f141a8Smiod 		return 1;
11596f141a8Smiod 	}
11696f141a8Smiod 
11796f141a8Smiod 	return 0;
11896f141a8Smiod }
11996f141a8Smiod 
12096f141a8Smiod /*
12196f141a8Smiod  * Following are all routines needed for SIO to act as console
12296f141a8Smiod  */
12396f141a8Smiod #include <dev/cons.h>
12496f141a8Smiod 
12596f141a8Smiod void
siocnprobe(struct consdev * cp)12696f141a8Smiod siocnprobe(struct consdev *cp)
12796f141a8Smiod {
128d2f66e2eSmiod 	sio_addr[0] = (struct siodevice *)OBIO_SIO;
129d2f66e2eSmiod 	sio_addr[1] = (struct siodevice *)OBIO_SIO + 1;
13096f141a8Smiod 
13196f141a8Smiod 	/* make sure hardware exists */
13296f141a8Smiod 	if (badaddr(sio_addr[0], 4) != 0) {
13396f141a8Smiod 		cp->cn_pri = CN_DEAD;
13496f141a8Smiod 		return;
13596f141a8Smiod 	}
13696f141a8Smiod 
13796f141a8Smiod 	/* locate the major number */
13896f141a8Smiod 
13996f141a8Smiod 	/* initialize required fields */
140a5011688Smiod 	cp->cn_dev = 0;
14196f141a8Smiod 	cp->cn_pri = CN_LOWPRI;
14296f141a8Smiod }
14396f141a8Smiod 
14496f141a8Smiod void
siocninit(struct consdev * cp)14596f141a8Smiod siocninit(struct consdev *cp)
14696f141a8Smiod {
147a5011688Smiod 	int unit = cp->cn_dev;
14896f141a8Smiod 
14996f141a8Smiod 	sioinit();
15096f141a8Smiod 	sioconsole = unit;
15196f141a8Smiod }
15296f141a8Smiod 
15396f141a8Smiod int
siocngetc(dev_t dev)15496f141a8Smiod siocngetc(dev_t dev)
15596f141a8Smiod {
156*8352e4cbSmiod 	int c, unit = dev & ~0x80, poll = (dev & 0x80) != 0;
15796f141a8Smiod 
158*8352e4cbSmiod 	siointr(unit);
159*8352e4cbSmiod 
160*8352e4cbSmiod 	if (poll) {
16196f141a8Smiod 		if (RBUF_EMPTY(unit))
16296f141a8Smiod 			return 0;
163*8352e4cbSmiod 		PEEK_RBUF(unit, c);
164*8352e4cbSmiod 		return c;
165*8352e4cbSmiod 
166*8352e4cbSmiod 	}
167*8352e4cbSmiod 
168*8352e4cbSmiod 	while (RBUF_EMPTY(unit)) {
169*8352e4cbSmiod 		DELAY(1);
170*8352e4cbSmiod 		siointr(unit);
171*8352e4cbSmiod 	}
17296f141a8Smiod 
17396f141a8Smiod 	POP_RBUF(unit, c);
174*8352e4cbSmiod 	return c;
17596f141a8Smiod }
17696f141a8Smiod 
17796f141a8Smiod void
siocnputc(dev_t dev,int c)17896f141a8Smiod siocnputc(dev_t dev, int c)
17996f141a8Smiod {
180a5011688Smiod 	int unit = dev;
18196f141a8Smiod 
18296f141a8Smiod 	if (sioconsole == -1) {
18396f141a8Smiod 		(void) sioinit();
18496f141a8Smiod 		sioconsole = unit;
18596f141a8Smiod 	}
18696f141a8Smiod 
18796f141a8Smiod 	/* wait for any pending transmission to finish */
18896f141a8Smiod 	while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0);
18996f141a8Smiod 
19096f141a8Smiod 	sio_addr[unit]->sio_data = (c & 0xFF);
19196f141a8Smiod 
19296f141a8Smiod 	/* wait for any pending transmission to finish */
19396f141a8Smiod 	while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0);
19496f141a8Smiod }
19596f141a8Smiod 
19696f141a8Smiod /* SIO misc routines */
19796f141a8Smiod 
19896f141a8Smiod void
sioinit(void)19996f141a8Smiod sioinit(void)
20096f141a8Smiod {
20196f141a8Smiod 	RBUF_INIT(0);
20296f141a8Smiod 	RBUF_INIT(1);
20396f141a8Smiod 
20496f141a8Smiod 	sioreg(REG(0, WR0), WR0_CHANRST);		/* Channel-A Reset */
20596f141a8Smiod 
20696f141a8Smiod 	sioreg(WR2A, WR2_VEC86  | WR2_INTR_1);		/* Set CPU BUS Interface Mode */
20796f141a8Smiod 	sioreg(WR2B, 0);				/* Set Interrupt Vector */
20896f141a8Smiod 
20996f141a8Smiod 	sioreg(REG(0, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
21096f141a8Smiod 	sioreg(REG(0, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY);	/* Tx/Rx */
21196f141a8Smiod 	sioreg(REG(0, WR3), WR3_RX8BIT | WR3_RXENBL);		/* Rx */
21296f141a8Smiod 	sioreg(REG(0, WR5), WR5_TX8BIT | WR5_TXENBL | WR5_DTR | WR5_RTS);		/* Tx */
21396f141a8Smiod 	sioreg(REG(0, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
21496f141a8Smiod 	sioreg(REG(0, WR1), WR1_RXALLS);		/* Interrupted All Char. */
21596f141a8Smiod 
21696f141a8Smiod 	sioreg(REG(1, WR0), WR0_CHANRST);		/* Channel-A Reset */
21796f141a8Smiod 
21896f141a8Smiod 	sioreg(REG(1, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
21996f141a8Smiod 	sioreg(REG(1, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY);	/* Tx/Rx */
22096f141a8Smiod 	sioreg(REG(1, WR3), WR3_RX8BIT | WR3_RXENBL);		/* Rx */
22196f141a8Smiod 	sioreg(REG(1, WR5), WR5_TX8BIT | WR5_TXENBL);		/* Tx */
22296f141a8Smiod 	sioreg(REG(1, WR0), WR0_RSTINT);		/* Reset E/S Interrupt */
22396f141a8Smiod 	sioreg(REG(1, WR1), WR1_RXALLS);		/* Interrupted All Char. */
22496f141a8Smiod }
22596f141a8Smiod 
22696f141a8Smiod int
sioreg(int reg,int val)22796f141a8Smiod sioreg(int reg, int val)
22896f141a8Smiod {
22996f141a8Smiod 	int chan;
23096f141a8Smiod 
23196f141a8Smiod 	chan = CHANNEL(reg);
23296f141a8Smiod 
23396f141a8Smiod 	if (isStatusReg(reg)) {
23496f141a8Smiod 		if (REGNO(reg) != 0)
23596f141a8Smiod 		    sio_addr[chan]->sio_cmd = REGNO(reg);
23696f141a8Smiod 		return(sio_addr[chan]->sio_stat);
23796f141a8Smiod 	} else {
23896f141a8Smiod 		if (REGNO(reg) != 0)
23996f141a8Smiod 		    sio_addr[chan]->sio_cmd = REGNO(reg);
24096f141a8Smiod 		sio_addr[chan]->sio_cmd = val;
24196f141a8Smiod 		return(val);
24296f141a8Smiod 	}
24396f141a8Smiod }
244