157100Sakito /* 257100Sakito * Copyright (c) 1992 OMRON Corporation. 357100Sakito * Copyright (c) 1992 The Regents of the University of California. 457100Sakito * All rights reserved. 557100Sakito * 657100Sakito * This code is derived from software contributed to Berkeley by 757100Sakito * OMRON Corporation. 857100Sakito * 957100Sakito * %sccs.include.redist.c% 1057100Sakito * 11*57620Sakito * @(#)sio.c 7.2 (Berkeley) 01/20/93 1257100Sakito */ 1357100Sakito 1457100Sakito /* sio.c NOV-25-1991 */ 1557100Sakito 1657100Sakito #define NSIO 2 1757100Sakito 1857100Sakito #include <sys/param.h> 1957100Sakito #include <luna68k/stand/sioreg.h> 2057100Sakito #include <luna68k/stand/rcvbuf.h> 2157100Sakito #include <luna68k/stand/kbdreg.h> 2257100Sakito 2357100Sakito struct rcvbuf rcvbuf[NSIO]; 2457100Sakito 2557100Sakito int sioconsole = -1; 2657100Sakito struct siodevice *sio_addr[2]; 2757100Sakito int cur_unit; 2857100Sakito 2957100Sakito 3057100Sakito #define siounit(x) ( x & 0xffff ) 3157100Sakito #define isprint(c) ((c >= 0x20) && (c < 0x7F) ? 1 : 0) 3257100Sakito 3357100Sakito 3457100Sakito void 3557100Sakito _siointr() 3657100Sakito { 3757100Sakito register int unit; 3857100Sakito 3957100Sakito for (unit = 0; unit < NSIO; unit++) 4057100Sakito siointr(unit); 4157100Sakito } 4257100Sakito 4357100Sakito siointr(unit) 4457100Sakito register int unit; 4557100Sakito { 4657100Sakito register struct siodevice *sio = sio_addr[unit]; 4757100Sakito register int rr0 = sioreg(REG(unit, RR0), 0); 4857100Sakito register int rr1 = sioreg(REG(unit, RR1), 0); 4957100Sakito 5057100Sakito if (rr0 & RR0_RXAVAIL) { 5157100Sakito if (rr1 & RR1_FRAMING) 5257100Sakito return; 5357100Sakito 5457100Sakito if (rr1 & (RR1_PARITY | RR1_OVERRUN)) 5557100Sakito sioreg(REG(unit, WR0), WR0_ERRRST); /* Channel-A Error Reset */ 5657100Sakito 5757100Sakito if (unit == 1) { 5857100Sakito register int c = kbd_decode(sio_addr[unit]->sio_data); 5957100Sakito 60*57620Sakito if ((c & KC_TYPE) == KC_CODE) 61*57620Sakito PUSH_RBUF(unit, c); 6257100Sakito } else { 6357100Sakito PUSH_RBUF(unit, sio_addr[unit]->sio_data); 6457100Sakito } 6557100Sakito } 6657100Sakito } 6757100Sakito 6857100Sakito /* 6957100Sakito * Following are all routines needed for SIO to act as console 7057100Sakito */ 7157100Sakito #include <luna68k/luna68k/cons.h> 7257100Sakito #include "romvec.h" 7357100Sakito 7457100Sakito siocnprobe(cp) 7557100Sakito struct consdev *cp; 7657100Sakito { 7757100Sakito sio_addr[0] = (struct siodevice *) 0x51000000; 7857100Sakito sio_addr[1] = (struct siodevice *) 0x51000004; 7957100Sakito 8057100Sakito /* make sure hardware exists */ 8157100Sakito if (badaddr((short *)sio_addr[0])) { 8257100Sakito cp->cn_pri = CN_DEAD; 8357100Sakito return; 8457100Sakito } 8557100Sakito 8657100Sakito /* locate the major number */ 8757100Sakito 8857100Sakito /* initialize required fields */ 8957100Sakito cp->cn_dev = cur_unit = 0; 9057100Sakito cp->cn_tp = 0; 9157100Sakito cp->cn_pri = CN_NORMAL; 9257100Sakito } 9357100Sakito 9457100Sakito siocninit(cp) 9557100Sakito struct consdev *cp; 9657100Sakito { 9757100Sakito int unit = siounit(cp->cn_dev); 9857100Sakito 9957100Sakito sioinit(); 10057100Sakito sioconsole = unit; 10157100Sakito } 10257100Sakito 10357100Sakito siocngetc(dev) 10457100Sakito dev_t dev; 10557100Sakito { 10657100Sakito register int c, unit = siounit(dev); 10757100Sakito 10857100Sakito while (RBUF_EMPTY(unit)) { 10957100Sakito DELAY(10); 11057100Sakito } 11157100Sakito 11257100Sakito POP_RBUF(unit, c); 11357100Sakito 11457100Sakito return(c); 11557100Sakito } 11657100Sakito 11757100Sakito siocnputc(dev, c) 11857100Sakito dev_t dev; 11957100Sakito int c; 12057100Sakito { 12157100Sakito int unit = siounit(dev); 12257100Sakito int s; 12357100Sakito 12457100Sakito if (sioconsole == -1) { 12557100Sakito (void) sioinit(); 12657100Sakito sioconsole = unit; 12757100Sakito } 12857100Sakito 12957100Sakito s = splsio(); 13057100Sakito 13157100Sakito /* wait for any pending transmission to finish */ 13257100Sakito while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0); 13357100Sakito 13457100Sakito sio_addr[unit]->sio_data = (c & 0xFF); 13557100Sakito 13657100Sakito /* wait for any pending transmission to finish */ 13757100Sakito while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0); 13857100Sakito 13957100Sakito splx(s); 14057100Sakito } 14157100Sakito 14257100Sakito /* SIO misc routines */ 14357100Sakito 14457100Sakito sioinit() 14557100Sakito { 14657100Sakito int s; 14757100Sakito 14857100Sakito RBUF_INIT(0); 14957100Sakito RBUF_INIT(1); 15057100Sakito 15157100Sakito s = splsio(); 15257100Sakito 15357100Sakito sioreg(REG(0, WR0), WR0_CHANRST); /* Channel-A Reset */ 15457100Sakito 15557100Sakito sioreg(WR2A, WR2_VEC86 | WR2_INTR_1); /* Set CPU BUS Interface Mode */ 15657100Sakito sioreg(WR2B, 0); /* Set Interrupt Vector */ 15757100Sakito 15857100Sakito sioreg(REG(0, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 15957100Sakito sioreg(REG(0, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY); /* Tx/Rx */ 16057100Sakito sioreg(REG(0, WR3), WR3_RX8BIT | WR3_RXENBL); /* Rx */ 16157100Sakito sioreg(REG(0, WR5), WR5_TX8BIT | WR5_TXENBL); /* Tx */ 16257100Sakito sioreg(REG(0, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 16357100Sakito sioreg(REG(0, WR1), WR1_RXALLS); /* Interrupted All Char. */ 16457100Sakito 16557100Sakito sioreg(REG(1, WR0), WR0_CHANRST); /* Channel-A Reset */ 16657100Sakito 16757100Sakito sioreg(REG(1, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 16857100Sakito sioreg(REG(1, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY); /* Tx/Rx */ 16957100Sakito sioreg(REG(1, WR3), WR3_RX8BIT | WR3_RXENBL); /* Rx */ 17057100Sakito sioreg(REG(1, WR5), WR5_TX8BIT | WR5_TXENBL); /* Tx */ 17157100Sakito sioreg(REG(1, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 17257100Sakito sioreg(REG(1, WR1), WR1_RXALLS); /* Interrupted All Char. */ 17357100Sakito 17457100Sakito splx(s); 17557100Sakito } 17657100Sakito 17757100Sakito int 17857100Sakito sioreg(reg, val) 17957100Sakito register int reg, val; 18057100Sakito { 18157100Sakito register int chan; 18257100Sakito 18357100Sakito chan = CHANNEL(reg); 18457100Sakito 18557100Sakito if (isStatusReg(reg)) { 18657100Sakito if (REGNO(reg) != 0) 18757100Sakito sio_addr[chan]->sio_cmd = REGNO(reg); 18857100Sakito return(sio_addr[chan]->sio_stat); 18957100Sakito } else { 19057100Sakito if (REGNO(reg) != 0) 19157100Sakito sio_addr[chan]->sio_cmd = REGNO(reg); 19257100Sakito sio_addr[chan]->sio_cmd = val; 19357100Sakito return(val); 19457100Sakito } 19557100Sakito } 196