#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "../port/error.h" #include "../port/netif.h" enum { Nbuf= 2, /* double buffered */ Rbufsize= 512, Bufsize= (Rbufsize+CACHELINESZ-1)&~(CACHELINESZ-1), Nuart= 2+4, /* max in any 8xx architecture (2xSMC, 4xSCC) */ CTLS= 's'&037, CTLQ= 'q'&037,}; enum { /* status bits in SCC receive buffer descriptors */ RxBRK= 1<<7, /* break ended frame (async hdlc) */ RxDE= 1<<7, /* DPLL error (hdlc) */ RxBOF= 1<<6, /* BOF ended frame (async hdlc) */ RxLG= 1<<5, /* frame too large (hdlc) */ RxNO= 1<<4, /* bad bit alignment (hdlc) */ RxBR= 1<<5, /* break received during frame (uart) */ RxFR= 1<<4, /* framing error (uart) */ RxPR= 1<<3, /* parity error (uart) */ RxAB= 1<<3, /* frame aborted (hdlc, async hdlc) */ RxCR= 1<<2, /* bad CRC (hdlc, async hdlc) */ RxOV= 1<<1, /* receiver overrun (all) */ RxCD= 1<<0, /* CD lost (all) */ /* hdlc-specific Rx/Tx BDs */ TxTC= 1<<10,}; /* * SMC in UART mode */ typedef struct Uartsmc Uartsmc;struct Uartsmc { IOCparam; ushort maxidl; ushort idlc; ushort brkln; ushort brkec; ushort brkcr; ushort rmask;}; /* * SCC2 UART parameters */enum { /* special mode bits */ SccAHDLC = 1<<0, SccHDLC = 1<<1, SccIR = 1<<2, SccPPP = 1<<3,}; typedef struct Uartscc Uartscc;struct Uartscc { SCCparam; uchar rsvd[8]; ushort max_idl; ushort idlc; ushort brkcr; ushort parec; ushort frmec; ushort nosec; ushort brkec; ushort brkln; ushort uaddr1; ushort uaddr2; ushort rtemp; ushort toseq; ushort character[8]; ushort rccm; ushort rccrp; ushort rlbc;}; typedef struct UartAHDLC UartAHDLC;struct UartAHDLC { SCCparam; ulong rsvd1; ulong c_mask; ulong c_pres; ushort bof; ushort eof; ushort esc; ushort rsvd2[2]; ushort zero; ushort rsvd3; ushort rfthr; ushort resvd4[2]; ulong txctl_tbl; ulong rxctl_tbl; ushort nof; ushort rsvd5;}; typedef struct UartHDLC UartHDLC;struct UartHDLC { SCCparam; ulong rsvd1; ulong c_mask; ulong c_pres; ushort disfc; ushort crcec; ushort abtsc; ushort nmarc; ushort retrc; ushort mflr; ushort max_cnt; ushort rfthr; ushort rfcnt; ushort hmask; ushort haddr[4]; ushort tmp; ushort tmp_mb;}; enum { /* SCC events of possible interest here eventually */ AB= 1<<9, /* autobaud detected */ GRA= 1<<7, /* graceful stop completed */ CCR= 1<<3, /* control character detected */ /* SCC, SMC common interrupt events */ BSY= 1<<2, /* receive buffer was busy (overrun) */ TXB= 1<<1, /* block sent */ RXB= 1<<0, /* block received */ /* SCC events */ TXE = 1<<4, /* transmission error */ RXF = 1<<3, /* final block received */ /* gsmr_l */ ENR = 1<<5, /* enable receiver */ ENT = 1<<4, /* enable transmitter */ /* port A */ RXD1= SIBIT(15), TXD1= SIBIT(14), /* port B */ RTS1B= IBIT(19), /* port C */ RTS1C= SIBIT(15), CTS1= SIBIT(11), CD1= SIBIT(10),}; typedef struct Uart Uart;struct Uart{ QLock; Uart *elist; /* next enabled interface */ char name[KNAMELEN]; int x; /* index: x in SMCx or SCCx */ int cpmid; /* eg, SCC1ID, SMC1ID */ CPMdev* cpm; int opens; uchar bpc; /* bits/char */ uchar parity; uchar stopb; uchar setup; uchar enabled; int dev; ulong frame; /* framing errors */ ulong perror; ulong overrun; /* rcvr overruns */ ulong crcerr; ulong interrupts; int baud; /* baud rate */ /* flow control */ int xonoff; /* software flow control on */ int blocked; int modem; /* hardware flow control on */ int cts; /* ... cts state */ int rts; /* ... rts state */ Rendez r; /* buffers */ int (*putc)(Queue*, int); Queue *iq; Queue *oq; /* staging areas to avoid some of the per character costs */ /* TO DO: should probably use usual Ring */ Block* istage[Nbuf]; /* double buffered */ int rdrx; /* last buffer read */ Lock plock; /* for output variables */ Block* outb; /* currently transmitting Block */ BD* rxb; BD* txb; SMC* smc; SCC* scc; IOCparam* param; ushort* brkcr; /* brkcr location in appropriate block */ int brgc; int mode; Block* partial; int loopback;}; static Uart *uart[Nuart];static int nuart; struct Uartalloc { Lock; Uart *elist; /* list of enabled interfaces */} uartalloc; static void uartintr(Uart*, int);static void smcuintr(Ureg*, void*);static void sccuintr(Ureg*, void*); static voiduartsetbuf(Uart *up){ IOCparam *p; BD *bd; int i; Block *bp; p = up->param; p->rfcr = 0x18; p->tfcr = 0x18; p->mrblr = Rbufsize; if((bd = up->rxb) == nil){ bd = bdalloc(Nbuf); up->rxb = bd; } p->rbase = (ushort)bd; for(i=0; i<Nbuf; i++){ bd->status = BDEmpty|BDInt; bd->length = 0; if((bp = up->istage[i]) == nil) up->istage[i] = bp = allocb(Bufsize); bd->addr = PADDR(bp->wp); dcflush(bp->wp, Bufsize); bd++; } (bd-1)->status |= BDWrap; up->rdrx = 0; if((bd = up->txb) == nil){ bd = bdalloc(1); up->txb = bd; } p->tbase = (ushort)bd; bd->status = BDWrap|BDInt; bd->length = 0; bd->addr = 0;} static voidsmcsetup(Uart *up){ IMM *io; Uartsmc *p; SMC *smc; ulong txrx; archdisableuart(up->cpmid); up->brgc = brgalloc(); if(up->brgc < 0) error(Eio); m->iomem->brgc[up->brgc] = baudgen(up->baud, 16) | BaudEnable; smcnmsi(up->x, up->brgc); archenableuart(up->cpmid, 0); if(up->x == 1) txrx = IBIT(24)|IBIT(25); /* SMC1 RX/TX */ else txrx = IBIT(20)|IBIT(21); /* SMC2 */ io = ioplock(); io->pbpar |= txrx; io->pbdir &= ~txrx; iopunlock(); up->param = up->cpm->param; uartsetbuf(up); cpmop(up->cpm, InitRxTx, 0); /* SMC protocol parameters */ p = (Uartsmc*)up->param; up->brkcr = &p->brkcr; p->maxidl = 1; /* non-zero so buffer closes when idle before mrblr reached */ p->brkln = 0; p->brkec = 0; p->brkcr = 1; smc = up->cpm->regs; smc->smce = 0xff; /* clear events */ smc->smcm = BSY|RXB|TXB; /* enable all possible interrupts */ up->smc = smc; smc->smcmr = ((1+8+1-1)<<11)|(2<<4); /* 8-bit, 1 stop, no parity; UART mode */ intrenable(VectorCPIC+up->cpm->irq, smcuintr, up, BUSUNKNOWN, up->name); /* enable when device opened */} static voidsmcuintr(Ureg*, void *a){ Uart *up; int events; up = a; events = up->smc->smce; eieio(); up->smc->smce = events; uartintr(up, events&(BSY|RXB|TXB));} /* * set the IO ports to enable the control signals for SCCx */static voidsccuartpins(int x, int mode){ IMM *io; int i, w; x--; io = ioplock(); i = 2*x; w = (TXD1|RXD1)<<i; /* TXDn and RXDn in port A */ io->papar |= w; /* enable TXDn and RXDn pins */ io->padir &= ~w; if((mode & SccIR) == 0) io->paodr |= TXD1<<i; else io->paodr &= ~w; /* not open drain */ w = (CD1|CTS1)<<i; /* CDn and CTSn in port C */ io->pcpar &= ~w; io->pcdir &= ~w; if(conf.nocts2 || mode) io->pcso &= ~w; /* force CTS and CD on */ else io->pcso |= w; w = RTS1B<<x; io->pbpar &= ~w; io->pbdir &= ~w; w = RTS1C<<x; /* RTSn~ */ if((mode & SccIR) == 0) io->pcpar |= w; else io->pcpar &= ~w; /* don't use for IR */ iopunlock();} static voidsccsetup(Uart *up){ SCC *scc; int i; scc = up->cpm->regs; up->scc = scc; up->param = up->cpm->param; sccxstop(up->cpm); archdisableuart(up->cpmid); if(up->brgc < 0){ up->brgc = brgalloc(); if(up->brgc < 0) error(Eio); } m->iomem->brgc[up->brgc] = baudgen(up->baud, 16) | BaudEnable; sccnmsi(up->x, up->brgc, up->brgc); sccuartpins(up->x, up->mode); uartsetbuf(up); cpmop(up->cpm, InitRxTx, 0); /* SCC protocol parameters */ if((up->mode & (SccAHDLC|SccHDLC)) == 0){ Uartscc *sp; sp = (Uartscc*)up->param; sp->max_idl = 1; sp->brkcr = 1; sp->parec = 0; sp->frmec = 0; sp->nosec = 0; sp->brkec = 0; sp->brkln = 0; sp->brkec = 0; sp->uaddr1 = 0; sp->uaddr2 = 0; sp->toseq = 0; for(i=0; i<8; i++) sp->character[i] = 0x8000; sp->rccm = 0xC0FF; up->brkcr = &sp->brkcr; scc->irmode = 0; scc->dsr = ~0; scc->gsmrh = 1<<5; /* 8-bit oriented receive fifo */ scc->gsmrl = 0x28004; /* UART mode */ }else{ UartAHDLC *hp; hp = (UartAHDLC*)up->param; hp->c_mask = 0x0000F0B8; hp->c_pres = 0x0000FFFF; if(up->mode & SccIR){ hp->bof = 0xC0; hp->eof = 0xC1; //scc->dsr = 0xC0C0; scc->dsr = 0x7E7E; }else{ hp->bof = 0x7E; hp->eof = 0x7E; scc->dsr = 0x7E7E; } hp->esc = 0x7D; hp->zero = 0; if(up->mode & SccHDLC) hp->rfthr = 1; else hp->rfthr = 0; /* receive threshold of 1 doesn't work properly for Async HDLC */ hp->txctl_tbl = 0; hp->rxctl_tbl = 0; if(up->mode & SccIR){ /* low-speed infrared */ hp->nof = 12-1; /* 12 flags */ scc->irsip = 0; scc->irmode = (2<<8) | 1; archsetirxcvr(0); if(up->loopback) scc->irmode = (3<<4)|1; /* loopback */ }else{ scc->irmode = 0; hp->txctl_tbl = ~0; hp->rxctl_tbl = ~0; hp->nof = 1-1; /* one opening flag */ } up->brkcr = nil; scc->gsmrh = 1<<5; /* 8-bit oriented receive fifo */ if(up->mode & SccHDLC) scc->gsmrl = 0x28000; /* HDLC */ else scc->gsmrl = 0x28006; /* async HDLC/IrDA */ } archenableuart(up->cpmid, (up->mode&SccIR)!=0); scc->scce = ~0; /* clear events */ scc->sccm = TXE|BSY|RXF|TXB|RXB; /* enable all interesting interrupts */ intrenable(VectorCPIC+up->cpm->irq, sccuintr, up, BUSUNKNOWN, up->name); scc->psmr = 3<<12; /* 8-bit, 1 stop, no parity; UART mode */ if(up->loopback && (up->mode & SccIR) == 0) scc->gsmrl |= 1<<6; /* internal loop back */ scc->gsmrl |= ENT|ENR; /* enable rx/tx */ if(0){ print("gsmrl=%8.8lux gsmrh=%8.8lux dsr=%4.4ux irmode=%4.4ux\n", scc->gsmrl, scc->gsmrh, scc->dsr, scc->irmode); for(i=0; i<sizeof(Uartscc); i+=4) print("%2.2ux %8.8lux\n", i, *(ulong*)((uchar*)up->param+i)); }} static voidsccuintr(Ureg*, void *a){ Uart *up; int events; up = a; if(up->scc == nil) return; events = up->scc->scce; eieio(); up->scc->scce = events; if(up->enabled){ if(0) print("#%ux|", events); uartintr(up, events); }} static voiduartsetbaud(Uart *p, int rate){ if(rate <= 0 || p->brgc < 0)Lines 1–500 of 1450. Load more
#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "../port/error.h" #include "../port/netif.h" enum { Nbuf= 2, /* double buffered */ Rbufsize= 512, Bufsize= (Rbufsize+CACHELINESZ-1)&~(CACHELINESZ-1), Nuart= 2+4, /* max in any 8xx architecture (2xSMC, 4xSCC) */ CTLS= 's'&037, CTLQ= 'q'&037, }; enum { /* status bits in SCC receive buffer descriptors */ RxBRK= 1<<7, /* break ended frame (async hdlc) */ RxDE= 1<<7, /* DPLL error (hdlc) */ RxBOF= 1<<6, /* BOF ended frame (async hdlc) */ RxLG= 1<<5, /* frame too large (hdlc) */ RxNO= 1<<4, /* bad bit alignment (hdlc) */ RxBR= 1<<5, /* break received during frame (uart) */ RxFR= 1<<4, /* framing error (uart) */ RxPR= 1<<3, /* parity error (uart) */ RxAB= 1<<3, /* frame aborted (hdlc, async hdlc) */ RxCR= 1<<2, /* bad CRC (hdlc, async hdlc) */ RxOV= 1<<1, /* receiver overrun (all) */ RxCD= 1<<0, /* CD lost (all) */ /* hdlc-specific Rx/Tx BDs */ TxTC= 1<<10, }; /* * SMC in UART mode */ typedef struct Uartsmc Uartsmc; struct Uartsmc { IOCparam; ushort maxidl; ushort idlc; ushort brkln; ushort brkec; ushort brkcr; ushort rmask; }; /* * SCC2 UART parameters */ enum { /* special mode bits */ SccAHDLC = 1<<0, SccHDLC = 1<<1, SccIR = 1<<2, SccPPP = 1<<3, }; typedef struct Uartscc Uartscc; struct Uartscc { SCCparam; uchar rsvd[8]; ushort max_idl; ushort idlc; ushort brkcr; ushort parec; ushort frmec; ushort nosec; ushort brkec; ushort brkln; ushort uaddr1; ushort uaddr2; ushort rtemp; ushort toseq; ushort character[8]; ushort rccm; ushort rccrp; ushort rlbc; }; typedef struct UartAHDLC UartAHDLC; struct UartAHDLC { SCCparam; ulong rsvd1; ulong c_mask; ulong c_pres; ushort bof; ushort eof; ushort esc; ushort rsvd2[2]; ushort zero; ushort rsvd3; ushort rfthr; ushort resvd4[2]; ulong txctl_tbl; ulong rxctl_tbl; ushort nof; ushort rsvd5; }; typedef struct UartHDLC UartHDLC; struct UartHDLC { SCCparam; ulong rsvd1; ulong c_mask; ulong c_pres; ushort disfc; ushort crcec; ushort abtsc; ushort nmarc; ushort retrc; ushort mflr; ushort max_cnt; ushort rfthr; ushort rfcnt; ushort hmask; ushort haddr[4]; ushort tmp; ushort tmp_mb; }; enum { /* SCC events of possible interest here eventually */ AB= 1<<9, /* autobaud detected */ GRA= 1<<7, /* graceful stop completed */ CCR= 1<<3, /* control character detected */ /* SCC, SMC common interrupt events */ BSY= 1<<2, /* receive buffer was busy (overrun) */ TXB= 1<<1, /* block sent */ RXB= 1<<0, /* block received */ /* SCC events */ TXE = 1<<4, /* transmission error */ RXF = 1<<3, /* final block received */ /* gsmr_l */ ENR = 1<<5, /* enable receiver */ ENT = 1<<4, /* enable transmitter */ /* port A */ RXD1= SIBIT(15), TXD1= SIBIT(14), /* port B */ RTS1B= IBIT(19), /* port C */ RTS1C= SIBIT(15), CTS1= SIBIT(11), CD1= SIBIT(10), }; typedef struct Uart Uart; struct Uart { QLock; Uart *elist; /* next enabled interface */ char name[KNAMELEN]; int x; /* index: x in SMCx or SCCx */ int cpmid; /* eg, SCC1ID, SMC1ID */ CPMdev* cpm; int opens; uchar bpc; /* bits/char */ uchar parity; uchar stopb; uchar setup; uchar enabled; int dev; ulong frame; /* framing errors */ ulong perror; ulong overrun; /* rcvr overruns */ ulong crcerr; ulong interrupts; int baud; /* baud rate */ /* flow control */ int xonoff; /* software flow control on */ int blocked; int modem; /* hardware flow control on */ int cts; /* ... cts state */ int rts; /* ... rts state */ Rendez r; /* buffers */ int (*putc)(Queue*, int); Queue *iq; Queue *oq; /* staging areas to avoid some of the per character costs */ /* TO DO: should probably use usual Ring */ Block* istage[Nbuf]; /* double buffered */ int rdrx; /* last buffer read */ Lock plock; /* for output variables */ Block* outb; /* currently transmitting Block */ BD* rxb; BD* txb; SMC* smc; SCC* scc; IOCparam* param; ushort* brkcr; /* brkcr location in appropriate block */ int brgc; int mode; Block* partial; int loopback; }; static Uart *uart[Nuart]; static int nuart; struct Uartalloc { Lock; Uart *elist; /* list of enabled interfaces */ } uartalloc; static void uartintr(Uart*, int); static void smcuintr(Ureg*, void*); static void sccuintr(Ureg*, void*); static void uartsetbuf(Uart *up) { IOCparam *p; BD *bd; int i; Block *bp; p = up->param; p->rfcr = 0x18; p->tfcr = 0x18; p->mrblr = Rbufsize; if((bd = up->rxb) == nil){ bd = bdalloc(Nbuf); up->rxb = bd; } p->rbase = (ushort)bd; for(i=0; i<Nbuf; i++){ bd->status = BDEmpty|BDInt; bd->length = 0; if((bp = up->istage[i]) == nil) up->istage[i] = bp = allocb(Bufsize); bd->addr = PADDR(bp->wp); dcflush(bp->wp, Bufsize); bd++; } (bd-1)->status |= BDWrap; up->rdrx = 0; if((bd = up->txb) == nil){ bd = bdalloc(1); up->txb = bd; } p->tbase = (ushort)bd; bd->status = BDWrap|BDInt; bd->length = 0; bd->addr = 0; } static void smcsetup(Uart *up) { IMM *io; Uartsmc *p; SMC *smc; ulong txrx; archdisableuart(up->cpmid); up->brgc = brgalloc(); if(up->brgc < 0) error(Eio); m->iomem->brgc[up->brgc] = baudgen(up->baud, 16) | BaudEnable; smcnmsi(up->x, up->brgc); archenableuart(up->cpmid, 0); if(up->x == 1) txrx = IBIT(24)|IBIT(25); /* SMC1 RX/TX */ else txrx = IBIT(20)|IBIT(21); /* SMC2 */ io = ioplock(); io->pbpar |= txrx; io->pbdir &= ~txrx; iopunlock(); up->param = up->cpm->param; uartsetbuf(up); cpmop(up->cpm, InitRxTx, 0); /* SMC protocol parameters */ p = (Uartsmc*)up->param; up->brkcr = &p->brkcr; p->maxidl = 1; /* non-zero so buffer closes when idle before mrblr reached */ p->brkln = 0; p->brkec = 0; p->brkcr = 1; smc = up->cpm->regs; smc->smce = 0xff; /* clear events */ smc->smcm = BSY|RXB|TXB; /* enable all possible interrupts */ up->smc = smc; smc->smcmr = ((1+8+1-1)<<11)|(2<<4); /* 8-bit, 1 stop, no parity; UART mode */ intrenable(VectorCPIC+up->cpm->irq, smcuintr, up, BUSUNKNOWN, up->name); /* enable when device opened */ } static void smcuintr(Ureg*, void *a) { Uart *up; int events; up = a; events = up->smc->smce; eieio(); up->smc->smce = events; uartintr(up, events&(BSY|RXB|TXB)); } /* * set the IO ports to enable the control signals for SCCx */ static void sccuartpins(int x, int mode) { IMM *io; int i, w; x--; io = ioplock(); i = 2*x; w = (TXD1|RXD1)<<i; /* TXDn and RXDn in port A */ io->papar |= w; /* enable TXDn and RXDn pins */ io->padir &= ~w; if((mode & SccIR) == 0) io->paodr |= TXD1<<i; else io->paodr &= ~w; /* not open drain */ w = (CD1|CTS1)<<i; /* CDn and CTSn in port C */ io->pcpar &= ~w; io->pcdir &= ~w; if(conf.nocts2 || mode) io->pcso &= ~w; /* force CTS and CD on */ else io->pcso |= w; w = RTS1B<<x; io->pbpar &= ~w; io->pbdir &= ~w; w = RTS1C<<x; /* RTSn~ */ if((mode & SccIR) == 0) io->pcpar |= w; else io->pcpar &= ~w; /* don't use for IR */ iopunlock(); } static void sccsetup(Uart *up) { SCC *scc; int i; scc = up->cpm->regs; up->scc = scc; up->param = up->cpm->param; sccxstop(up->cpm); archdisableuart(up->cpmid); if(up->brgc < 0){ up->brgc = brgalloc(); if(up->brgc < 0) error(Eio); } m->iomem->brgc[up->brgc] = baudgen(up->baud, 16) | BaudEnable; sccnmsi(up->x, up->brgc, up->brgc); sccuartpins(up->x, up->mode); uartsetbuf(up); cpmop(up->cpm, InitRxTx, 0); /* SCC protocol parameters */ if((up->mode & (SccAHDLC|SccHDLC)) == 0){ Uartscc *sp; sp = (Uartscc*)up->param; sp->max_idl = 1; sp->brkcr = 1; sp->parec = 0; sp->frmec = 0; sp->nosec = 0; sp->brkec = 0; sp->brkln = 0; sp->brkec = 0; sp->uaddr1 = 0; sp->uaddr2 = 0; sp->toseq = 0; for(i=0; i<8; i++) sp->character[i] = 0x8000; sp->rccm = 0xC0FF; up->brkcr = &sp->brkcr; scc->irmode = 0; scc->dsr = ~0; scc->gsmrh = 1<<5; /* 8-bit oriented receive fifo */ scc->gsmrl = 0x28004; /* UART mode */ }else{ UartAHDLC *hp; hp = (UartAHDLC*)up->param; hp->c_mask = 0x0000F0B8; hp->c_pres = 0x0000FFFF; if(up->mode & SccIR){ hp->bof = 0xC0; hp->eof = 0xC1; //scc->dsr = 0xC0C0; scc->dsr = 0x7E7E; }else{ hp->bof = 0x7E; hp->eof = 0x7E; scc->dsr = 0x7E7E; } hp->esc = 0x7D; hp->zero = 0; if(up->mode & SccHDLC) hp->rfthr = 1; else hp->rfthr = 0; /* receive threshold of 1 doesn't work properly for Async HDLC */ hp->txctl_tbl = 0; hp->rxctl_tbl = 0; if(up->mode & SccIR){ /* low-speed infrared */ hp->nof = 12-1; /* 12 flags */ scc->irsip = 0; scc->irmode = (2<<8) | 1; archsetirxcvr(0); if(up->loopback) scc->irmode = (3<<4)|1; /* loopback */ }else{ scc->irmode = 0; hp->txctl_tbl = ~0; hp->rxctl_tbl = ~0; hp->nof = 1-1; /* one opening flag */ } up->brkcr = nil; scc->gsmrh = 1<<5; /* 8-bit oriented receive fifo */ if(up->mode & SccHDLC) scc->gsmrl = 0x28000; /* HDLC */ else scc->gsmrl = 0x28006; /* async HDLC/IrDA */ } archenableuart(up->cpmid, (up->mode&SccIR)!=0); scc->scce = ~0; /* clear events */ scc->sccm = TXE|BSY|RXF|TXB|RXB; /* enable all interesting interrupts */ intrenable(VectorCPIC+up->cpm->irq, sccuintr, up, BUSUNKNOWN, up->name); scc->psmr = 3<<12; /* 8-bit, 1 stop, no parity; UART mode */ if(up->loopback && (up->mode & SccIR) == 0) scc->gsmrl |= 1<<6; /* internal loop back */ scc->gsmrl |= ENT|ENR; /* enable rx/tx */ if(0){ print("gsmrl=%8.8lux gsmrh=%8.8lux dsr=%4.4ux irmode=%4.4ux\n", scc->gsmrl, scc->gsmrh, scc->dsr, scc->irmode); for(i=0; i<sizeof(Uartscc); i+=4) print("%2.2ux %8.8lux\n", i, *(ulong*)((uchar*)up->param+i)); } } static void sccuintr(Ureg*, void *a) { Uart *up; int events; up = a; if(up->scc == nil) return; events = up->scc->scce; eieio(); up->scc->scce = events; if(up->enabled){ if(0) print("#%ux|", events); uartintr(up, events); } } static void uartsetbaud(Uart *p, int rate) { if(rate <= 0 || p->brgc < 0)