fixed ddb, improved fifo handling, new still-not-working dma support
authorderaadt <deraadt@openbsd.org>
Fri, 1 Dec 1995 18:13:15 +0000 (18:13 +0000)
committerderaadt <deraadt@openbsd.org>
Fri, 1 Dec 1995 18:13:15 +0000 (18:13 +0000)
from drahn@pacific.urbana.mcd.mot.com

sys/arch/mvme68k/dev/cl.c
sys/arch/mvme68k/dev/clreg.h

index f6f384f..12b1184 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: cl.c,v 1.4 1995/11/19 03:04:16 chuck Exp $ */
+/*     $Id: cl.c,v 1.5 1995/12/01 18:13:15 deraadt Exp $ */
 
 /*
  * Copyright (c) 1995 Dale Rahn. All rights reserved.
@@ -30,6 +30,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */  
 
+/* DMA mode still does not work!!! */
+
 #include <sys/param.h>
 #include <sys/callout.h>
 #include <sys/conf.h>
 #define CL_FIFO_CNT    0xc
 #define        CL_RX_TIMEOUT   0x10
 
-#define CL_DMAMODE     0x1
-#define CL_INTRMODE    0x0
+#define CL_RXDMAINT    0x82
+#define CL_TXDMAINT    0x42
+#define CL_TXMASK      0x47
+#define CL_RXMASK      0x87 
+#define CL_TXINTR      0x02
+#define CL_RXINTR      0x02
 
 struct cl_cons {
        u_char *cl_paddr;
-       volatile struct clreg *cl_vaddr;
+       struct clreg *cl_vaddr;
        volatile struct pcctworeg *pcctwoaddr;
        u_char  channel;
 } cl_cons;
@@ -86,8 +92,20 @@ struct cl_info {
        u_char  transmitting;
        u_long  txcnt;
        u_long  rxcnt;
+
+       void *rx[2];
+       void *rxp[2];
+       void *tx[2];
+       void *txp[2];
 };
 #define CLCD_PORTS_PER_CHIP 4
+#define CL_BUFSIZE 256
+
+#ifndef DO_MALLOC
+/* four (4) buffers per port */
+char cl_dmabuf [CLCD_PORTS_PER_CHIP * CL_BUFSIZE * 4];
+#endif
+
 struct clsoftc {
        struct device   sc_dev;
        struct evcnt sc_txintrcnt;
@@ -96,7 +114,7 @@ struct clsoftc {
        time_t  sc_rotime;      /* time of last ring overrun */
        time_t  sc_fotime;      /* time of last fifo overrun */
        u_char *pbase;
-       volatile struct clreg *cl_reg;
+       struct clreg *cl_reg;
        struct cl_info          sc_cl[CLCD_PORTS_PER_CHIP];
        struct intrhand         sc_ih_e;
        struct intrhand         sc_ih_m;
@@ -133,7 +151,7 @@ struct {
 int clcnprobe __P((struct consdev *cp));
 int clcninit __P((struct consdev *cp));
 int clcngetc __P((dev_t dev));
-int clcnputc __P((dev_t dev, char c));
+int clcnputc __P((dev_t dev, u_char c));
 u_char cl_clkdiv __P((int speed));
 u_char cl_clknum __P((int speed));
 u_char cl_clkrxtimeout __P((int speed));
@@ -145,7 +163,7 @@ int clparam __P((struct tty *tp, struct termios *t));
 int cl_mintr __P((struct clsoftc *sc));
 int cl_txintr __P((struct clsoftc *sc));
 int cl_rxintr __P((struct clsoftc *sc));
-void cl_overflow __P((struct clsoftc *sc, int channel, long *ptime, char *msg));
+void cl_overflow __P((struct clsoftc *sc, int channel, long *ptime, u_char *msg));
 void cl_parity __P((struct clsoftc *sc, int channel));
 void cl_frame __P((struct clsoftc *sc, int channel));
 void cl_break __P(( struct clsoftc *sc, int channel));
@@ -163,7 +181,7 @@ int clioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p));
 int clstop  __P((struct tty *tp, int flag));
 
 static void cl_initchannel __P((struct clsoftc *sc, int channel));
-static void clputc __P((struct clsoftc *sc, int unit, char c));
+static void clputc __P((struct clsoftc *sc, int unit, u_char c));
 static u_char clgetc __P((struct clsoftc *sc, int *channel));
 static void cloutput __P( (struct tty *tp));
 
@@ -204,7 +222,7 @@ int clprobe(parent, self, aux)
         * should be previously configured, 
         * we can check the value before resetting the chip
         */
-       volatile struct clreg *cl_reg;
+       struct clreg *cl_reg;
        struct confargs *ca = aux;
        int ret;
        if (cputyp != CPU_167 && cputyp != CPU_166
@@ -253,7 +271,39 @@ clattach(parent, self, aux)
        sc->cl_reg->cl_tpilr = 0x02;
        sc->cl_reg->cl_mpilr = 0x01;
 
+#ifdef DO_MALLOC
+       sc->sc_cl[0].rx[0] = (void *)(dvma_malloc(16 * CL_BUFSIZE));
+#else
+       sc->sc_cl[0].rx[0] = (void *) (&cl_dmabuf);
+#endif
+       sc->sc_cl[0].rx[1] = (void *)(((int)sc->sc_cl[0].rx[0]) + CL_BUFSIZE);
+       sc->sc_cl[1].rx[0] = (void *)(((int)sc->sc_cl[0].rx[1]) + CL_BUFSIZE);
+       sc->sc_cl[1].rx[1] = (void *)(((int)sc->sc_cl[1].rx[0]) + CL_BUFSIZE);
+
+       sc->sc_cl[2].rx[0] = (void *)(((int)sc->sc_cl[1].rx[1]) + CL_BUFSIZE);
+       sc->sc_cl[2].rx[1] = (void *)(((int)sc->sc_cl[2].rx[0]) + CL_BUFSIZE);
+       sc->sc_cl[3].rx[0] = (void *)(((int)sc->sc_cl[2].rx[1]) + CL_BUFSIZE);
+       sc->sc_cl[3].rx[1] = (void *)(((int)sc->sc_cl[3].rx[0]) + CL_BUFSIZE);
+
+       sc->sc_cl[0].tx[0] = (void *)(((int)sc->sc_cl[3].rx[1]) + CL_BUFSIZE);
+       sc->sc_cl[0].tx[1] = (void *)(((int)sc->sc_cl[0].tx[0]) + CL_BUFSIZE);
+       sc->sc_cl[1].tx[0] = (void *)(((int)sc->sc_cl[0].tx[1]) + CL_BUFSIZE);
+       sc->sc_cl[1].tx[1] = (void *)(((int)sc->sc_cl[1].tx[0]) + CL_BUFSIZE);
+
+       sc->sc_cl[2].tx[0] = (void *)(((int)sc->sc_cl[1].tx[1]) + CL_BUFSIZE);
+       sc->sc_cl[2].tx[1] = (void *)(((int)sc->sc_cl[2].tx[0]) + CL_BUFSIZE);
+       sc->sc_cl[3].tx[0] = (void *)(((int)sc->sc_cl[2].tx[1]) + CL_BUFSIZE);
+       sc->sc_cl[3].tx[1] = (void *)(((int)sc->sc_cl[3].tx[0]) + CL_BUFSIZE);
        for (i = 0; i < CLCD_PORTS_PER_CHIP; i++) {
+               int j;
+               for (j = 0; j < 2 ; j++) {
+               sc->sc_cl[i].rxp[j] = (void *)kvtop(sc->sc_cl[i].rx[j]);
+printf("cl[%d].rxbuf[%d] %x p %x\n",
+       i, j, sc->sc_cl[i].rx[j], sc->sc_cl[i].rxp[j]);
+               sc->sc_cl[i].txp[j] = (void *)kvtop(sc->sc_cl[i].tx[j]);
+printf("cl[%d].txbuf[%d] %x p %x\n",
+       i, j, sc->sc_cl[i].tx[j], sc->sc_cl[i].txp[j]);
+               }
 #if 0
                sc->sc_cl[i].cl_rxmode =
                        !(!((flags >> (i * CL_FLAG_BIT_PCH)) & 0x01));
@@ -315,15 +365,14 @@ cl_initchannel(sc, channel)
        int channel;
 {
        int s;
-       volatile struct clreg *cl_reg = sc->cl_reg;
+       struct clreg *cl_reg = sc->cl_reg;
        /* set up option registers */
        sc->sc_cl[channel].tty = NULL;
        s = splhigh();
-       cl_reg->cl_car  = (char) channel;
+       cl_reg->cl_car  = (u_char) channel;
        /* async, do we want to try DMA at some point? */
        cl_reg->cl_livr = PCC2_VECBASE + 0xc;/* set vector base at 5C */
        cl_reg->cl_ier  = 0x88;  /* should change XXX */
-       cl_reg->cl_licr = 0x00;  /* will change if DMA support XXX */
        /* if the port is not the console */
        if (sc->sc_cl[channel].cl_consio != 1) {
                cl_reg->cl_cmr  = 0x02; 
@@ -351,6 +400,18 @@ cl_initchannel(sc, channel)
                cl_reg->cl_rtprl        = CL_RX_TIMEOUT;
                cl_reg->cl_rtprh        = 0x00;
        }
+       if (channel == 2) { /* test one channel now */
+               /* shift for tx DMA */
+               /* no shift for rx DMA */
+       /* async only */
+       /* rx only (tx commented out) */
+               cl_reg->cl_cmr  = /* CL_TXDMAINT | */ CL_RXDMAINT; 
+               cl_reg->cl_ier  = 0xa8; 
+               cl_reg->cl_licr = 0x00;
+       }
+       sc->cl_reg->cl_ccr = 0x20;
+       while (sc->cl_reg->cl_ccr != 0) {
+       }
 
        splx(s);
 }
@@ -513,6 +574,48 @@ int clopen (dev, flag, mode, p)
                }
 #endif
                tp->t_state |= TS_CARR_ON;
+#ifdef CL_DMA_WORKS
+               {
+                       u_char save = sc->cl_reg->cl_car;
+                       sc->cl_reg->cl_car = channel;
+                       sc->cl_reg->cl_arbadrl  =
+                               ((u_long)sc->sc_cl[channel].rxp[0]) & 0xffff;
+                       sc->cl_reg->cl_arbadru  =
+                               ((u_long)sc->sc_cl[channel].rxp[0]) >> 16;
+                       sc->cl_reg->cl_brbadrl  =
+                               ((u_long)sc->sc_cl[channel].rxp[1]) & 0xffff;
+                       sc->cl_reg->cl_brbadru  =
+                               ((u_long)sc->sc_cl[channel].rxp[1]) >> 16;
+                       sc->cl_reg->cl_atbadrl  =
+                               ((u_long)sc->sc_cl[channel].txp[0]) & 0xffff;
+                       sc->cl_reg->cl_atbadru  =
+                               ((u_long)sc->sc_cl[channel].txp[0]) >> 16;
+                       sc->cl_reg->cl_btbadrl  =
+                               ((u_long)sc->sc_cl[channel].txp[1]) & 0xffff;
+                       sc->cl_reg->cl_btbadru  =
+                               ((u_long)sc->sc_cl[channel].txp[1]) >> 16;
+                       sc->cl_reg->cl_arbcnt   = CL_BUFSIZE;
+                       sc->cl_reg->cl_brbcnt   = CL_BUFSIZE;
+                       sc->cl_reg->cl_arbsts   = 0x01;
+                       sc->cl_reg->cl_brbsts   = 0x01;
+if (channel == 2) { /* test one channel now */
+                       /* shift for tx DMA */
+                       /* no shift for rx DMA */
+#if 0
+                       /* tx only */
+                       sc->cl_reg->cl_licr     = (CL_DMAMODE << 4);
+                       sc->cl_reg->cl_cmr      = 0x42; 
+#endif
+               /* rx only */
+                       sc->cl_reg->cl_licr     = 0x00;
+                       sc->cl_reg->cl_cmr      = 0x82; 
+}
+                       sc->cl_reg->cl_ccr = 0x20;
+                       while (sc->cl_reg->cl_ccr != 0) {
+                       }
+                       sc->cl_reg->cl_car = save;
+               }
+#endif /* CL_DMA_WORKS */
        } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
                splx(s);
                return(EBUSY);
@@ -566,11 +669,11 @@ void cloutput(tp)
        struct tty *tp;
 {
        int cc, s, unit, cnt;
-       char *tptr;
+       u_char *tptr;
        int channel;
        struct clsoftc *sc;
        dev_t dev;
-       char cl_obuffer[CLCDBUF+1];
+       u_char cl_obuffer[CLCDBUF+1];
 
        dev = tp->t_dev;
        unit = CL_UNIT(dev);
@@ -807,7 +910,7 @@ struct consdev *cp;
        int size = (0x1ff + PGOFSET) & ~PGOFSET;
        int pcc2_size = (0x3C + PGOFSET) & ~PGOFSET;
 #endif
-       volatile struct clreg *cl_reg;
+       struct clreg *cl_reg;
        
        cl_cons.cl_paddr = (void *)0xfff45000;
 #ifdef MAP_DOES_WORK
@@ -854,7 +957,7 @@ int
 cl_instat(sc)
        struct clsoftc *sc;
 {
-       volatile struct clreg *cl_reg;
+       struct clreg *cl_reg;
        if ( NULL == sc) {
                cl_reg = cl_cons.cl_vaddr;
        } else {
@@ -868,7 +971,7 @@ clcngetc(dev)
 {
        u_char val, reoir, licr, isrl, data, status, fifo_cnt;
        int got_char = 0;
-       volatile struct clreg *cl_reg = cl_cons.cl_vaddr;
+       struct clreg *cl_reg = cl_cons.cl_vaddr;
        volatile struct pcctworeg *pcc2_base = cl_cons.pcctwoaddr;
        while (got_char == 0) {
                val = cl_reg->cl_rir;
@@ -915,7 +1018,7 @@ clcngetc(dev)
 int
 clcnputc(dev, c)
        dev_t dev;
-       char c;
+       u_char c;
 {
        /* is this the correct location for the cr -> cr/lf tranlation? */
        if (c == '\n')
@@ -939,12 +1042,12 @@ static void
 clputc(sc, unit, c)
        struct clsoftc *sc;
        int unit;
-       char c;
+       u_char c;
 {
        int s;
        u_char schar;
        u_char oldchannel;
-       volatile struct clreg *cl_reg;
+       struct clreg *cl_reg;
        if (0 == sc) {
                /* output on console */
                cl_reg = cl_cons.cl_vaddr;
@@ -1042,7 +1145,7 @@ clgetc(sc, channel)
        struct clsoftc *sc;
        int *channel;
 {
-       volatile struct clreg *cl_reg;
+       struct clreg *cl_reg;
        volatile struct pcctworeg *pcc2_base;
        u_char val, reoir, licr, isrl, fifo_cnt, data;
        if (0 == sc) {
@@ -1145,14 +1248,23 @@ clccparam(sc, par, channel)
        }
        sc->cl_reg->cl_cor3 = par->c_cflag & PARENB ? 4 : 2;
 
-       if (par->c_cflag & PARENB) {
-               if (par->c_cflag & PARODD) {
-                       sc->cl_reg->cl_cor1 = 0xE0 | clen ; /* odd */
+       {
+               u_char cor1;
+               if (par->c_cflag & PARENB) {
+                       if (par->c_cflag & PARODD) {
+                               cor1 = 0xE0 | clen ; /* odd */
+                       } else {
+                               cor1 = 0x40 | clen ; /* even */
+                       }
                } else {
-                       sc->cl_reg->cl_cor1 = 0x40 | clen ; /* even */
+                       cor1 = 0x10 | clen; /* ignore parity */
+               }
+               if (sc->cl_reg->cl_cor1 != cor1) { 
+                       sc->cl_reg->cl_cor1 = cor1;
+                       sc->cl_reg->cl_ccr = 0x20;
+                       while (sc->cl_reg->cl_ccr != 0) {
+                       }
                }
-       } else {
-               sc->cl_reg->cl_cor1 = 0x10 | clen; /* ignore parity */
        }
 
        if (sc->sc_cl[channel].cl_consio == 0
@@ -1162,6 +1274,8 @@ clccparam(sc, par, channel)
        } else {
                sc->cl_reg->cl_ccr = 0x0a;
        }
+       while (sc->cl_reg->cl_ccr != 0) {
+       }
        ints = 0;
 #define SCC_DSR 0x80
 #define SCC_DCD 0x40
@@ -1308,7 +1422,7 @@ cl_mintr(sc)
        struct tty *tp;
        if(((mir = sc->cl_reg->cl_mir) & 0x40) == 0x0) {
                /* only if intr is not shared? */
-               printf("cl_mintr extra intr\n");
+               log(LOG_WARNING, "cl_mintr extra intr\n");
                return 0;
        }
        sc->sc_mxintrcnt.ev_count++;
@@ -1318,26 +1432,26 @@ cl_mintr(sc)
        msvr = sc->cl_reg->cl_msvr_rts;
        if (misr & 0x01) {
                /* timers are not currently used?? */
-               printf ("cl_mintr: channel %x timer 1 unexpected\n",channel);
+               log(LOG_WARNING, "cl_mintr: channel %x timer 1 unexpected\n",channel);
        }
        if (misr & 0x02) {
                /* timers are not currently used?? */
-               printf ("cl_mintr: channel %x timer 2 unexpected\n",channel);
+               log(LOG_WARNING, "cl_mintr: channel %x timer 2 unexpected\n",channel);
        }
        if (misr & 0x20) {
-               printf ("cl_mintr: channel %x cts %x\n",channel, 
+               log(LOG_WARNING, "cl_mintr: channel %x cts %x\n",channel, 
                ((msvr & 0x20) != 0x0)
                );
        }
        if (misr & 0x40) {
                struct tty *tp = sc->sc_cl[channel].tty;
-               printf ("cl_mintr: channel %x cd %x\n",channel,
+               log(LOG_WARNING, "cl_mintr: channel %x cd %x\n",channel,
                ((msvr & 0x40) != 0x0)
                );
                ttymodem(tp, ((msvr & 0x40) != 0x0) );
        }
        if (misr & 0x80) {
-               printf ("cl_mintr: channel %x dsr %x\n",channel,
+               log(LOG_WARNING, "cl_mintr: channel %x dsr %x\n",channel,
                ((msvr & 0x80) != 0x0)
                );
        }
@@ -1350,7 +1464,7 @@ cl_txintr(sc)
        struct clsoftc *sc;
 {
        static empty = 0;
-       u_char tir, licr, teoir;
+       u_char tir, cmr, teoir;
        u_char max;
        int channel;
        struct tty *tp;
@@ -1359,13 +1473,13 @@ cl_txintr(sc)
        u_char *tptr;
        if(((tir = sc->cl_reg->cl_tir) & 0x40) == 0x0) {
                /* only if intr is not shared ??? */
-               printf ("cl_txintr extra intr\n");
+               log(LOG_WARNING, "cl_txintr extra intr\n");
                return 0;
        }
        sc->sc_txintrcnt.ev_count++;
 
        channel = tir & 0x03;
-       licr    = sc->cl_reg->cl_licr;
+       cmr     = sc->cl_reg->cl_cmr;
        
        sc->sc_cl[channel].txcnt ++;
 
@@ -1374,11 +1488,62 @@ cl_txintr(sc)
                sc->cl_reg->cl_teoir = 0x08;
                return 1;
        }
-       switch ((licr >> 4)& 0x3) {
-       case CL_DMAMODE:
-               teoir = 0x08;
+       switch (cmr & CL_TXMASK) {
+       case CL_TXDMAINT:
+               {
+                       u_char dmabsts;
+                       int nbuf, busy, resid;
+                       void *pbuffer;
+                       dmabsts = sc->cl_reg->cl_dmabsts;
+               log(LOG_WARNING, "cl_txintr: DMAMODE channel %x dmabsts %x\n",
+                       channel, dmabsts);
+                       nbuf = ((dmabsts & 0x8) >> 3) & 0x1;
+                       busy = ((dmabsts & 0x4) >> 2) & 0x1;
+
+                       do {
+                               pbuffer = sc->sc_cl[channel].tx[nbuf];
+                               resid = tp->t_outq.c_cc;
+                               cnt = min (CL_BUFSIZE,resid);
+               log(LOG_WARNING, "cl_txintr: resid %x cnt %x pbuf %x\n",
+                       resid, cnt, pbuffer);
+                               if (cnt != 0) {
+                                       cnt = q_to_b(&tp->t_outq, pbuffer, cnt);
+                                       resid -= cnt;
+                                       if (nbuf == 0) {
+                                               sc->cl_reg->cl_atbadru =
+                                                       ((u_long) sc->sc_cl[channel].txp[nbuf]) >> 16;
+                                               sc->cl_reg->cl_atbadrl =
+                                                       ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff;
+                                               sc->cl_reg->cl_atbcnt = cnt;
+                                               sc->cl_reg->cl_atbsts = 0x43;
+                                       } else {
+                                               sc->cl_reg->cl_btbadru =
+                                                       ((u_long) sc->sc_cl[channel].txp[nbuf]) >> 16;
+                                               sc->cl_reg->cl_btbadrl =
+                                                       ((u_long) sc->sc_cl[channel].txp[nbuf]) & 0xffff;
+                                               sc->cl_reg->cl_btbcnt = cnt;
+                                               sc->cl_reg->cl_btbsts = 0x43;
+                                       }
+                               teoir = 0x08;
+                               } else {
+                                       teoir = 0x08;
+                                       if (tp->t_state & TS_BUSY) {
+                                               tp->t_state &= ~(TS_BUSY | TS_FLUSH);
+                                               if (tp->t_state & TS_ASLEEP) {
+                                                       tp->t_state &= ~TS_ASLEEP;
+                                                       wakeup((caddr_t) &tp->t_outq);
+                                               }
+                                               selwakeup(&tp->t_wsel);
+                                       }
+                                       sc->cl_reg->cl_ier = sc->cl_reg->cl_ier & ~0x3;
+                               }
+                               nbuf = ~nbuf & 0x1;
+                               busy--;
+                       } while (resid != 0 && busy != -1);/* if not busy do other buffer */
+               log(LOG_WARNING, "cl_txintr: done\n");
+               }
                break;
-       case CL_INTRMODE:
+       case CL_TXINTR:
                max = sc->cl_reg->cl_tftc;
                cnt = min ((int)max,tp->t_outq.c_cc);
                if (cnt != 0) {
@@ -1390,7 +1555,7 @@ cl_txintr(sc)
                        teoir = 0x00;
                } else {
                        if (empty > 5 && ((empty % 20000 )== 0)) {
-                       printf("cl_txintr to many empty intr %d channel %d\n",
+                       log(LOG_WARNING, "cl_txintr to many empty intr %d channel %d\n",
                                empty, channel);
                        }
                        empty++;
@@ -1407,7 +1572,7 @@ cl_txintr(sc)
                }
                break;
        default:
-               printf("cl_txintr unknown mode %x\n", ((licr >> 4) & 0x3));
+               log(LOG_WARNING, "cl_txintr unknown mode %x\n", cmr);
                /* we probably will go to hell quickly now */
                teoir = 0x08;
        }
@@ -1419,75 +1584,160 @@ int
 cl_rxintr(sc)
        struct clsoftc *sc;
 {
-       u_char rir, channel, licr, risrl;
+       u_char rir, channel, cmr, risrl;
        u_char c;
        u_char fifocnt;
        struct tty *tp;
        int i;
        u_char reoir;
+       u_char buffer[CL_FIFO_MAX +1];
        
        rir = sc->cl_reg->cl_rir;
        if((rir & 0x40) == 0x0) {
                /* only if intr is not shared ??? */
-               printf ("cl_rxintr extra intr\n");
+               log(LOG_WARNING, "cl_rxintr extra intr\n");
                return 0;
        }
        sc->sc_rxintrcnt.ev_count++;
        channel = rir & 0x3;
-       licr = sc->cl_reg->cl_licr;
+       cmr = sc->cl_reg->cl_cmr;
        reoir = 0x08;
 
        sc->sc_cl[channel].rxcnt ++;
-
-       switch (licr & 0x03) {
-       case CL_DMAMODE:
+       risrl = sc->cl_reg->cl_risrl;
+       if (risrl & 0x80) {
+               /* timeout, no characters */
                reoir = 0x08;
+       } else
+       /* We don't need no sinkin special characters */
+       if (risrl & 0x08) {
+               cl_overflow (sc, channel, &sc->sc_fotime, "fifo");
+               reoir = 0x08;
+       } else
+       if (risrl & 0x04) {
+               cl_parity(sc, channel);
+               reoir = 0x08;
+       } else
+       if (risrl & 0x02) {
+               cl_frame(sc, channel);
+               reoir = 0x08;
+       } else
+       if (risrl & 0x01) {
+               cl_break(sc, channel);
+               reoir = 0x08;
+       }
+
+       switch (cmr & CL_RXMASK) {
+       case CL_RXDMAINT:
+               {
+                       int nbuf;
+                       u_short cnt;
+                       int bufcomplete;
+                       u_char status, dmabsts;
+                       u_char risrh = sc->cl_reg->cl_risrh;
+                       dmabsts = sc->cl_reg->cl_dmabsts;
+#ifdef DMA_DEBUG
+log(LOG_WARNING, "cl_txintr: DMAMODE channel %x dmabsts %x risrl %x risrh %x\n",
+       channel, dmabsts, risrl, risrh);
+#endif
+                       nbuf = (risrh & 0x08) ? 1 : 0;
+                       bufcomplete = (risrh & 0x20) ? 1 : 0;
+                       if (nbuf == 0) {
+                               cnt  = sc->cl_reg->cl_arbcnt;
+                               status =  sc->cl_reg->cl_arbsts;
+                       } else {
+                               cnt  = sc->cl_reg->cl_brbcnt;
+                               status =  sc->cl_reg->cl_brbsts;
+                       }
+#ifdef DMA_DEBUG
+log(LOG_WARNING, "cl_rxintr: 1channel %x buf %x cnt %x status %x\n",
+channel, nbuf, cnt, status);
+#endif
+#if USE_BUFFER
+                       cl_appendbufn(sc, channel, sc->rx[nbuf], cnt);
+#else 
+                       {
+                               int i;
+                               u_char *pbuf;
+                               tp = sc->sc_cl[channel].tty;
+                               pbuf = sc->sc_cl[channel].rx[nbuf];
+                       /* this should be done at off level */
+{
+       u_short rcbadru, rcbadrl;
+       u_char arbsts, brbsts;
+       u_char *pbufs, *pbufe;
+       rcbadru = sc->cl_reg->cl_rcbadru;
+       rcbadrl = sc->cl_reg->cl_rcbadrl;
+       arbsts =  sc->cl_reg->cl_arbsts;
+       brbsts =  sc->cl_reg->cl_brbsts;
+       pbufs = sc->sc_cl[channel].rxp[nbuf];
+       pbufe = (u_char *)(((u_long)rcbadru << 16) | (u_long)rcbadrl);
+       cnt = pbufe - pbufs;
+#ifdef DMA_DEBUG
+       log(LOG_WARNING, "cl_rxintr: rcbadru %x rcbadrl %x arbsts %x brbsts %x cnt %x\n",
+       rcbadru, rcbadrl, arbsts, brbsts, cnt);
+#endif
+#ifdef DMA_DEBUG1
+       log(LOG_WARNING, "cl_rxintr: buf %x cnt %x\n",
+       nbuf, cnt);
+#endif
+}
+                               reoir = 0x0 | (bufcomplete) ? 0 : 0xd0;
+                               sc->cl_reg->cl_reoir = reoir;
+#ifdef DMA_DEBUG
+log(LOG_WARNING, "cl_rxintr: reoir %x\n", reoir);
+#endif
+                               delay(10); /* give the chip a moment */
+#ifdef DMA_DEBUG
+log(LOG_WARNING, "cl_rxintr: 2channel %x buf %x cnt %x status %x\n",
+channel, nbuf, cnt, status);
+#endif
+                               for (i = 0; i < cnt; i++) {
+                                       u_char c;
+                                       c = pbuf[i];
+                                       (*linesw[tp->t_line].l_rint)(c,tp);
+                               }
+                       /* this should be done at off level */
+                               if (nbuf == 0) {
+                                       sc->cl_reg->cl_arbcnt = CL_BUFSIZE;
+                                       sc->cl_reg->cl_arbsts = 0x01;
+                               } else {
+                                       sc->cl_reg->cl_brbcnt = CL_BUFSIZE;
+                                       sc->cl_reg->cl_brbsts = 0x01;
+                               }
+                       }
+#endif
+               }
+               sc->cl_reg->cl_reoir = reoir;
                break;
-       case CL_INTRMODE:
-               risrl = sc->cl_reg->cl_risrl;
-               if (risrl & 0x80) {
-                       /* timeout, no characters */
-                       reoir = 0x08;
-               } else
-               /* We don't need no sinkin special characters */
-               if (risrl & 0x08) {
-                       cl_overflow (sc, channel, &sc->sc_fotime, "fifo");
-                       reoir = 0x08;
-               } else
-               if (risrl & 0x04) {
-                       cl_parity(sc, channel);
-                       reoir = 0x08;
-               } else
-               if (risrl & 0x02) {
-                       cl_frame(sc, channel);
-                       reoir = 0x08;
-               } else
-               if (risrl & 0x01) {
-                       cl_break(sc, channel);
-                       reoir = 0x08;
-               } else {
-                       fifocnt = sc->cl_reg->cl_rfoc;
-                       tp = sc->sc_cl[channel].tty;
-                       for (i = 0; i < fifocnt; i++) {
-                               c = sc->cl_reg->cl_rdr;
+       case CL_RXINTR:
+               fifocnt = sc->cl_reg->cl_rfoc;
+               tp = sc->sc_cl[channel].tty;
+               for (i = 0; i < fifocnt; i++) {
+                       buffer[i] = sc->cl_reg->cl_rdr;
+               }
+
+               sc->cl_reg->cl_reoir = reoir;
+               for (i = 0; i < fifocnt; i++) {
+                       u_char c;
+                       c = buffer[i];
 #if USE_BUFFER
-                               cl_appendbuf(sc, channel, c);
+               cl_appendbuf(sc, channel, c);
 #else
-                               /* does any restricitions exist on spl
-                                * for this call
-                                */
-                               (*linesw[tp->t_line].l_rint)(c,tp);
-                               reoir = 0x00;
+                       /* does any restricitions exist on spl
+                        * for this call
+                        */
+                       (*linesw[tp->t_line].l_rint)(c,tp);
+                       reoir = 0x00;
 #endif
-                       }
                }
                break;
        default:
-               printf("cl_rxintr unknown mode %x\n",licr & 0x03);
+               log(LOG_WARNING, "cl_rxintr unknown mode %x\n", cmr);
                /* we probably will go to hell quickly now */
                reoir = 0x08;
+               sc->cl_reg->cl_reoir = reoir;
        }
-       sc->cl_reg->cl_reoir = reoir;
        return 1;
 }
 
@@ -1496,7 +1746,7 @@ cl_overflow (sc, channel, ptime, msg)
 struct clsoftc *sc;
 int channel;
 long *ptime;
-char *msg;
+u_char *msg;
 {
 /*
        if (*ptime != time.tv_sec) {
@@ -1505,7 +1755,7 @@ char *msg;
 /*
                *ptime = time.tv_sec;
 */
-               log(LOG_WARNING, "%s%d[%d]: %s overrun", clcd.cd_name,
+               log(LOG_WARNING, "%s%d[%d]: %s overrun\n", clcd.cd_name,
                        0 /* fix */, channel, msg);
        }
        return;
@@ -1515,7 +1765,7 @@ cl_parity (sc, channel)
        struct clsoftc *sc;
        int channel;
 {
-       log(LOG_WARNING, "%s%d[%d]: parity error", clcd.cd_name, 0, channel);
+       log(LOG_WARNING, "%s%d[%d]: parity error\n", clcd.cd_name, 0, channel);
        return;
 }
 void
@@ -1523,7 +1773,7 @@ cl_frame (sc, channel)
        struct clsoftc *sc;
        int channel;
 {
-       log(LOG_WARNING, "%s%d[%d]: frame error", clcd.cd_name, 0, channel);
+       log(LOG_WARNING, "%s%d[%d]: frame error\n", clcd.cd_name, 0, channel);
        return;
 }
 void
@@ -1531,7 +1781,7 @@ cl_break (sc, channel)
        struct clsoftc *sc;
        int channel;
 {
-       log(LOG_WARNING, "%s%d[%d]: break detected", clcd.cd_name, 0, channel);
+       log(LOG_WARNING, "%s%d[%d]: break detected\n", clcd.cd_name, 0, channel);
        return;
 }
 
@@ -1567,10 +1817,16 @@ cl_dumpport(channel)
        u_char  livr, cmr, cor1, cor2, cor3, cor4, cor5, cor6, cor7,
                schr1, schr2, schr3, schr4, scrl, scrh, lnxt,
                rbpr, rcor, tbpr, tcor, rpilr, rir, tpr, ier, ccr,
+               dmabsts, arbsts, brbsts, atbsts, btbsts,
                csr, rts, dtr, rtprl, rtprh;
+       volatile void * parbadru, *parbadrl,  *parbsts, *parbcnt;
+       u_short rcbadru, rcbadrl, arbadru, arbadrl, arbcnt,
+               brbadru, brbadrl, brbcnt;
+       u_short tcbadru, tcbadrl, atbadru, atbadrl, atbcnt,
+               btbadru, btbadrl, btbcnt;
        struct clsoftc *sc;
 
-       volatile struct clreg *cl_reg;
+       struct clreg *cl_reg;
        int s;
 
        cl_reg = cl_cons.cl_vaddr;
@@ -1578,7 +1834,7 @@ cl_dumpport(channel)
        sc = (struct clsoftc *) clcd.cd_devs[0];
 
        s = splcl();
-       cl_reg->cl_car  = (char) channel;
+       cl_reg->cl_car  = (u_char) channel;
        livr = cl_reg->cl_livr;
        cmr = cl_reg->cl_cmr;
        cor1 = cl_reg->cl_cor1;
@@ -1608,6 +1864,37 @@ cl_dumpport(channel)
        dtr = cl_reg->cl_msvr_dtr;
        rtprl = cl_reg->cl_rtprl;
        rtprh = cl_reg->cl_rtprh;
+       dmabsts = cl_reg->cl_dmabsts;
+       tcbadru = cl_reg->cl_tcbadru;
+       tcbadrl = cl_reg->cl_tcbadrl;
+       rcbadru = cl_reg->cl_rcbadru;
+       rcbadrl = cl_reg->cl_rcbadrl;
+
+       parbadru = &(cl_reg->cl_arbadru);
+       parbadrl = &(cl_reg->cl_arbadrl);
+       parbcnt  = &(cl_reg->cl_arbcnt);
+       parbsts  = &(cl_reg->cl_arbsts);
+
+       arbadru = cl_reg->cl_arbadru;
+       arbadrl = cl_reg->cl_arbadrl;
+       arbcnt  = cl_reg->cl_arbcnt;
+       arbsts  = cl_reg->cl_arbsts;
+
+       brbadru = cl_reg->cl_brbadru;
+       brbadrl = cl_reg->cl_brbadrl;
+       brbcnt  = cl_reg->cl_brbcnt;
+       brbsts  = cl_reg->cl_brbsts;
+
+       atbadru = cl_reg->cl_atbadru;
+       atbadrl = cl_reg->cl_atbadrl;
+       atbcnt  = cl_reg->cl_atbcnt;
+       atbsts  = cl_reg->cl_atbsts;
+
+       btbadru = cl_reg->cl_btbadru;
+       btbadrl = cl_reg->cl_btbadrl;
+       btbcnt  = cl_reg->cl_btbcnt;
+       btbsts  = cl_reg->cl_btbsts;
+
        splx(s);
 
        printf("{ port %x livr %x cmr %x\n",
@@ -1628,6 +1915,18 @@ cl_dumpport(channel)
                rtprl,   rtprh);
        printf("rxcnt %x txcnt %x\n",
                sc->sc_cl[channel].rxcnt, sc->sc_cl[channel].txcnt);
+       printf("dmabsts %x, tcbadru %x, tcbadrl %x, rcbadru %x, rcbadrl %x,\n",
+               dmabsts,    tcbadru,    tcbadrl,    rcbadru,    rcbadrl );
+       printf("parbadru %x, parbadrl %x, parbcnt %x, parbsts %x\n",
+               parbadru,    parbadrl,    parbcnt,    parbsts);
+       printf("arbadru %x, arbadrl %x, arbcnt %x, arbsts %x\n",
+               arbadru,    arbadrl,    arbcnt,    arbsts);
+       printf("brbadru %x, brbadrl %x, brbcnt %x, brbsts %x\n",
+               brbadru,    brbadrl,    brbcnt,    brbsts);
+       printf("atbadru %x, atbadrl %x, atbcnt %x, atbsts %x\n",
+               atbadru,    atbadrl,    atbcnt,    atbsts);
+       printf("btbadru %x, btbadrl %x, btbcnt %x, btbsts %x\n",
+               btbadru,    btbadrl,    btbcnt,    btbsts);
        printf("}\n");
        return;
 }
index b54c83f..6d02a4d 100644 (file)
@@ -1,8 +1,8 @@
-/*     $Id: clreg.h,v 1.2 1995/11/07 08:48:54 deraadt Exp $ */
+/*     $Id: clreg.h,v 1.3 1995/12/01 18:13:16 deraadt Exp $ */
 
 /*
  * Copyright (c) 1995 Dale Rahn. All rights reserved.
- *   
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -13,7 +13,7 @@
  *    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 Dale Rahn.
+ *   This product includes software developed by Dale Rahn.
  * 4. The name of the author may not be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
  * 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.
- */  
+ */
 
 struct clreg {
-       u_char  anon1[0x7];
-       u_char  cl_cor7;                        /* 0x07 */
-       u_char  anon2[0x1];
-       u_char  cl_livr;                        /* 0x09 */
-       u_char  anon3[0x6];
-       u_char  cl_cor1;                        /* 0x10 */
-       u_char  cl_ier;                         /* 0x11 */
-       u_char  cl_stcr;                        /* 0x12 */
-       u_char  cl_ccr;                         /* 0x13 */
-       u_char  cl_cor5;                        /* 0x14 */
-       u_char  cl_cor4;                        /* 0x15 */
-       u_char  cl_cor3;                        /* 0x16 */
-       u_char  cl_cor2;                        /* 0x17 */
-       u_char  cl_cor6;                        /* 0x18 */
-       u_char  cl_dmabsts;                     /* 0x19 */
-       u_char  cl_csr;                         /* 0x1a */
-       u_char  cl_cmr;                         /* 0x1b */
-       u_char  cl_schr4;                       /* 0x1c */
-       u_char  cl_schr3;                       /* 0x1d */
-       u_char  cl_schr2;                       /* 0x1e */
-       u_char  cl_schr1;                       /* 0x1f */
-       u_char  anon5[0x2];
-       u_char  cl_scrh;                        /* 0x22 */
-       u_char  cl_scrl;                        /* 0x23 */
+       volatile u_char anon1[0x7];
+       volatile u_char cl_cor7;                        /* 0x07 */
+       volatile u_char anon2[0x1];
+       volatile u_char cl_livr;                        /* 0x09 */
+       volatile u_char anon3[0x6];
+       volatile u_char cl_cor1;                        /* 0x10 */
+       volatile u_char cl_ier;                         /* 0x11 */
+       volatile u_char cl_stcr;                        /* 0x12 */
+       volatile u_char cl_ccr;                         /* 0x13 */
+       volatile u_char cl_cor5;                        /* 0x14 */
+       volatile u_char cl_cor4;                        /* 0x15 */
+       volatile u_char cl_cor3;                        /* 0x16 */
+       volatile u_char cl_cor2;                        /* 0x17 */
+       volatile u_char cl_cor6;                        /* 0x18 */
+       volatile u_char cl_dmabsts;                     /* 0x19 */
+       volatile u_char cl_csr;                         /* 0x1a */
+       volatile u_char cl_cmr;                         /* 0x1b */
+       volatile u_char cl_schr4;                       /* 0x1c */
+       volatile u_char cl_schr3;                       /* 0x1d */
+       volatile u_char cl_schr2;                       /* 0x1e */
+       volatile u_char cl_schr1;                       /* 0x1f */
+       volatile u_char anon5[0x2];
+       volatile u_char cl_scrh;                        /* 0x22 */
+       volatile u_char cl_scrl;                        /* 0x23 */
 #define cl_rtpr rtpr.rtpr_rtpr
 #define cl_rtprh rtpr.hl.rtpr_rtprh
 #define cl_rtprl rtpr.hl.rtpr_rtprl
        union {
-               u_short rtpr_rtpr;              /* 0x24 */
+               volatile u_short rtpr_rtpr;             /* 0x24 */
                struct {
-                       u_char  rtpr_rtprh;     /* 0x24 */
-                       u_char  rtpr_rtprl;     /* 0x25 */
+                       volatile u_char rtpr_rtprh;     /* 0x24 */
+                       volatile u_char rtpr_rtprl;     /* 0x25 */
                } hl;
        } rtpr;
-       u_char  cl_licr;                        /* 0x26 */
-       u_char  anon6[0x7];
-       u_char  cl_lnxt;                        /* 0x2e */
-       u_char  anon7[0x1];
-       u_char  cl_rfoc;                        /* 0x30 */
-       u_char  anon8[0x7];
-       u_char  cl_rtbadru;                     /* 0x38 */
-       u_char  anon9[0x1];
-       u_char  cl_rtbadrl;                     /* 0x3a */
-       u_char  anona[0x1];
-       u_char  cl_rcbadru;                     /* 0x3c */
-       u_char  anonb[0x1];
-       u_char  cl_rcbadrl;                     /* 0x3e */
-       u_char  anonc[0x1];
-       u_char  cl_arbadru;                     /* 0x40 */
-       u_char  anond[0x1];
-       u_char  cl_arbadrl;                     /* 0x42 */
-       u_char  anone[0x1];
-       u_char  cl_brbadru;                     /* 0x44 */
-       u_char  anonf[0x1];
-       u_char  cl_brbadrl;                     /* 0x46 */
-       u_char  anong[0x1];
-       u_char  cl_brbcnt;                      /* 0x48 */
-       u_char  anonh[0x1];
-       u_char  cl_arbcnt;                      /* 0x4a */
-       u_char  anoni[0x3];
-       u_char  cl_brbsts;                      /* 0x4e */
-       u_char  cl_arbsts;                      /* 0x4f */
-       u_char  cl_atbadru;                     /* 0x50 */
-       u_char  anonj[0x1];
-       u_char  cl_atbadrl;                     /* 0x52 */
-       u_char  anonk[0x1];
-       u_char  cl_btbadru;                     /* 0x54 */
-       u_char  anonl[0x1];
-       u_char  cl_btbadrl;                     /* 0x56 */
-       u_char  anonm[0x1];
-       u_char  cl_btbcnt;                      /* 0x58 */
-       u_char  anonn[0x1];
-       u_char  cl_atbcnt;                      /* 0x5a */
-       u_char  anono[0x3];
-       u_char  cl_btbsts;                      /* 0x5e */
-       u_char  cl_atbsts;                      /* 0x5f */
-       u_char  anonp[0x20];
-       u_char  cl_tftc;                        /* 0x80 */
-       u_char  cl_gfrcr;                       /* 0x81 */
-       u_char  anonq[0x2];
-       u_char  cl_reoir;                       /* 0x84 */
-       u_char  cl_teoir;                       /* 0x85 */
-       u_char  cl_meoir;                       /* 0x86 */
-       u_char  anonr[0x1];
+       volatile u_char cl_licr;                        /* 0x26 */
+       volatile u_char anon6[0x7];
+       volatile u_char cl_lnxt;                        /* 0x2e */
+       volatile u_char anon7[0x1];
+       volatile u_char cl_rfoc;                        /* 0x30 */
+       volatile u_char anon8[0x7];
+       volatile u_short cl_tcbadru;                    /* 0x38 */
+       volatile u_short cl_tcbadrl;                    /* 0x3a */
+       volatile u_short cl_rcbadru;                    /* 0x3c */
+       volatile u_short cl_rcbadrl;                    /* 0x3e */
+       volatile u_short cl_arbadru;                    /* 0x40 */
+       volatile u_short cl_arbadrl;                    /* 0x42 */
+       volatile u_short cl_brbadru;                    /* 0x44 */
+       volatile u_short cl_brbadrl;                    /* 0x46 */
+       volatile u_short cl_brbcnt;                     /* 0x48 */
+       volatile u_short cl_arbcnt;                     /* 0x4a */
+       volatile u_char anoni[0x2];
+       volatile u_char cl_brbsts;                      /* 0x4e */
+       volatile u_char cl_arbsts;                      /* 0x4f */
+#define cl_atbadr  atbadr.atbadr
+#define cl_atbadru atbadr.hl.atbadru
+#define cl_atbadrl atbadr.hl.atbadrl
+       union {
+               struct {
+                       volatile u_short atbadru;       /* 0x50 */
+                       volatile u_short atbadrl;       /* 0x52 */
+               } hl;
+               volatile u_long atbadr;                 /* 0x50 */
+       } atbadr;
+#define cl_btbadr  btbadr.btbadr
+#define cl_btbadru btbadr.hl.btbadru
+#define cl_btbadrl btbadr.hl.btbadrl
+       union {
+               struct {
+                       volatile u_short btbadru;       /* 0x54 */
+                       volatile u_short btbadrl;       /* 0x56 */
+               } hl;
+               volatile u_long btbadr;                 /* 0x54 */
+       } btbadr;
+       volatile u_short cl_btbcnt;                     /* 0x58 */
+       volatile u_short cl_atbcnt;                     /* 0x5a */
+       volatile u_char anono[0x2];
+       volatile u_char cl_btbsts;                      /* 0x5e */
+       volatile u_char cl_atbsts;                      /* 0x5f */
+       volatile u_char anonp[0x20];
+       volatile u_char cl_tftc;                        /* 0x80 */
+       volatile u_char cl_gfrcr;                       /* 0x81 */
+       volatile u_char anonq[0x2];
+       volatile u_char cl_reoir;                       /* 0x84 */
+       volatile u_char cl_teoir;                       /* 0x85 */
+       volatile u_char cl_meoir;                       /* 0x86 */
+       volatile u_char anonr[0x1];
 #define cl_risr risr.risr_risr
 #define cl_risrl risr.hl.risr_risrl
 #define cl_risrh risr.hl.risr_risrh
        union {
-               u_short risr_risr;              /* 0x88 */
+               volatile u_short risr_risr;             /* 0x88 */
                struct {
-                       u_char  risr_risrh;     /* 0x88 */
-                       u_char  risr_risrl;     /* 0x89 */
+                       volatile u_char risr_risrh;     /* 0x88 */
+                       volatile u_char risr_risrl;     /* 0x89 */
                } hl;
        } risr;
-       u_char  cl_tisr;                        /* 0x8a */
-       u_char  cl_misr;                        /* 0x8b */
-       u_char  anons[0x2];
-       u_char  cl_bercnt;                      /* 0x8e */
-       u_char  anont[0x31];
-       u_char  cl_tcor;                        /* 0xc0 */
-       u_char  anonu[0x2];
-       u_char  cl_tbpr;                        /* 0xc3 */
-       u_char  anonv[0x4];
-       u_char  cl_rcor;                        /* 0xc8 */
-       u_char  anonw[0x2];
-       u_char  cl_rbpr;                        /* 0xcb */
-       u_char  anonx[0xa];
-       u_char  cl_cpsr;                        /* 0xd6 */
-       u_char  anony[0x3];
-       u_char  cl_tpr;                         /* 0xda */
-       u_char  anonz[0x3];
-       u_char  cl_msvr_rts;                    /* 0xde */
-       u_char  cl_msvr_dtr;                    /* 0xdf */
-       u_char  cl_tpilr;                       /* 0xe0 */
-       u_char  cl_rpilr;                       /* 0xe1 */
-       u_char  cl_stk;                         /* 0xe2 */
-       u_char  cl_mpilr;                       /* 0xe3 */
-       u_char  anonA[0x8];
-       u_char  cl_tir;                         /* 0xec */
-       u_char  cl_rir;                         /* 0xed */
-       u_char  cl_car;                         /* 0xee */
-       u_char  cl_mir;                         /* 0xef */
-       u_char  anonB[0x6];
-       u_char  cl_dmr;                         /* 0xf6 */
-       u_char  anonC[0x1];
+       volatile u_char cl_tisr;                        /* 0x8a */
+       volatile u_char cl_misr;                        /* 0x8b */
+       volatile u_char anons[0x2];
+       volatile u_char cl_bercnt;                      /* 0x8e */
+       volatile u_char anont[0x31];
+       volatile u_char cl_tcor;                        /* 0xc0 */
+       volatile u_char anonu[0x2];
+       volatile u_char cl_tbpr;                        /* 0xc3 */
+       volatile u_char anonv[0x4];
+       volatile u_char cl_rcor;                        /* 0xc8 */
+       volatile u_char anonw[0x2];
+       volatile u_char cl_rbpr;                        /* 0xcb */
+       volatile u_char anonx[0xa];
+       volatile u_char cl_cpsr;                        /* 0xd6 */
+       volatile u_char anony[0x3];
+       volatile u_char cl_tpr;                         /* 0xda */
+       volatile u_char anonz[0x3];
+       volatile u_char cl_msvr_rts;                    /* 0xde */
+       volatile u_char cl_msvr_dtr;                    /* 0xdf */
+       volatile u_char cl_tpilr;                       /* 0xe0 */
+       volatile u_char cl_rpilr;                       /* 0xe1 */
+       volatile u_char cl_stk;                         /* 0xe2 */
+       volatile u_char cl_mpilr;                       /* 0xe3 */
+       volatile u_char anonA[0x8];
+       volatile u_char cl_tir;                         /* 0xec */
+       volatile u_char cl_rir;                         /* 0xed */
+       volatile u_char cl_car;                         /* 0xee */
+       volatile u_char cl_mir;                         /* 0xef */
+       volatile u_char anonB[0x6];
+       volatile u_char cl_dmr;                         /* 0xf6 */
+       volatile u_char anonC[0x1];
 #define cl_rdr cl_tdr
-       u_char  cl_tdr;                         /* 0xf8 */
-       u_char  anonD[7];
-};                                             /* 0x200 total */
+       volatile u_char cl_tdr;                         /* 0xf8 */
+       volatile u_char anonD[7];
+};