From a6f1bb6e2ea229e3fa3289ad6ed94acf1ba6f4ad Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 6 Aug 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-08-06 --- port/devcons.c | 11 +- port/devlance.c | 843 ++++++++++++--------------------------------- port/portdat.h | 8 +- power/dat.h | 18 +- power/debugger.c | 249 -------------- power/devduart.c | 869 +++++++++++++++++++---------------------------- power/devhs.c | 595 -------------------------------- power/fns.h | 6 +- power/ipdat.h | 440 ------------------------ power/main.c | 23 +- power/mmu.c | 4 +- power/trap.c | 2 + 12 files changed, 624 insertions(+), 2444 deletions(-) delete mode 100644 power/debugger.c delete mode 100644 power/devhs.c delete mode 100644 power/ipdat.h diff --git a/port/devcons.c b/port/devcons.c index 9eadbb5652bba244195b85b07114aec08235e1b6..8cbf1cd68f43aadbde844ae7c5b6896511e6793b 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -47,9 +47,9 @@ printinit(void) void putstrn(char *str, int n) { - char buf[PRINTSIZE+2]; int m; char *t; + char buf[PRINTSIZE+2]; /* * if there's an attached bit mapped display, @@ -66,9 +66,10 @@ putstrn(char *str, int n) */ if(printq == 0) return; - while(n > 0){ + + while(n > 0) { t = memchr(str, '\n', n); - if(t){ + if(t) { m = t - str; memmove(buf, str, m); buf[m] = '\r'; @@ -76,7 +77,8 @@ putstrn(char *str, int n) qwrite(printq, buf, m+2, 1); str = t + 1; n -= m + 1; - } else { + } + else { qwrite(printq, str, n, 1); break; } @@ -97,6 +99,7 @@ print(char *fmt, ...) n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; putstrn(buf, n); + return n; } diff --git a/port/devlance.c b/port/devlance.c index 3fde7d086c49cc73a8c2c34d139a90a467f690b2..94350147f01ea31faa978d686fa1002d98cf738e 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -5,11 +5,11 @@ #include "fns.h" #include "io.h" #include "../port/error.h" -#include "devtab.h" +#include "../port/netif.h" enum { - Ntypes= 9, /* max number of ethernet packet types */ - Maxrb= 128, /* max buffers in a ring */ + Ntypes= 9, /* max number of ethernet packet types */ + Maxrb= 128, /* max buffers in a ring */ }; #define RSUCC(x) (((x)+1)%l.nrrb) #define TSUCC(x) (((x)+1)%l.ntrb) @@ -23,7 +23,7 @@ typedef struct { ushort laddr; /* low order piece of address */ ushort flags; /* flags and high order piece of address */ short size; /* size of buffer */ - ushort cntflags; /* (rcv)count of bytes in buffer; (xmt) more flags */ + ushort cntflags; /* (rcv)count of buffer; (xmt) more flags */ } Msg; /* @@ -69,386 +69,89 @@ struct Lancemem #define MPs(a) (*(short *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0))) #define MPus(a) (*(ushort *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0))) -/* - * one per ethernet packet type - */ -typedef struct Ethertype Ethertype; -struct Ethertype +enum { - QLock; - Netprot; /* stat info */ - int type; /* ethernet type */ - int prom; /* promiscuous mode */ - Queue *q; - int inuse; - Rendez rc; /* rendzvous for close */ - Ethertype *closeline; /* close list */ + PROM = 0x8000, + INTL = 0x40, + DRTY = 0x20, + COLL = 0x10, + DTCR = 0x8, + LOOP = 0x4, + DTX = 0x2, + DRX = 0x1, + ERR0 = 0x8000, + BABL = 0x4000, + CERR = 0x2000, + MISS = 0x1000, + MERR = 0x800, + RINT = 0x400, + TINT = 0x200, + IDON = 0x100, + INTR = 0x80, + INEA = 0x40, + RXON = 0x20, + TXON = 0x10, + TDMD = 0x8, + STOP = 0x4, + STRT = 0x2, + INIT = 0x1, + /* flag bits from a buffer descriptor in the rcv/xmt rings */ + LANCEOWNER= 0x8000, /* 1 means buffer can be used by the chip */ + ERR = 0x4000, /* error summary, the OR of all error bits */ + FRAM = 0x2000, /* CRC error */ + OFLO = 0x1000, /* (receive) lost some of the packet */ + MORE = 0x1000, /* (transmit) more than 1 retry to tx pkt */ + CRC = 0x800, /* (rcv) crc error reading packet */ + ONE = 0x800, /* (tx) one retry to transmit the packet */ + BUF = 0x400, /* (rcv) out of buffers */ + DEF = 0x400, /* (tx) deffered while transmitting packet */ + STP = 0x200, /* start of packet */ + ENP = 0x100, /* end of packet */ + /* cntflags bits from a buffer descriptor in the rcv/xmt rings */ + BUFF = 0x8000, /* buffer error (host screwed up?) */ + UFLO = 0x4000, /* underflow from memory */ + LCOL = 0x1000, /* late collision (ether too long?) */ + LCAR = 0x800, /* loss of carrier (ether broken?) */ + RTRY = 0x400, /* couldn't transmit (ether jammed?) */ + TTDR = 0x3FF, /* time domain reflectometer */ }; +struct Softlance +{ + Lance; /* host dependent lance params */ -/* - * lance state - */ -typedef struct { - QLock; + uchar ea[6]; + uchar bcast[6]; - Lance; /* host dependent lance params */ - int prom; /* number of promiscuous channels */ - int all; /* number of channels listening to all packets */ int wedged; /* the lance is wedged */ - Network net; - int inited; - uchar *lmp; /* location of parity test */ - - Rendez rr; /* rendezvous for an input buffer */ - QLock rlock; /* semaphore on tc */ ushort rl; /* first rcv Message belonging to Lance */ - - Rendez tr; /* rendezvous for an output buffer */ - QLock tlock; /* semaphore on tc */ ushort tc; /* next xmt Message CPU will try for */ - Ethertype *closeline; /* channels waiting to close */ - Lock closepin; /* lock for closeline */ - Ethertype e[Ntypes]; - int debug; - int kstarted; - uchar bcast[6]; - - Queue self; /* packets turned around at the interface */ - - /* sadistics */ - - int misses; - int inpackets; - int outpackets; - int crcs; /* input crc errors */ - int oerrs; /* output erros */ - int frames; /* framing errors */ - int overflows; /* packet overflows */ - int buffs; /* buffering errors */ -} SoftLance; -static SoftLance l; - -/* - * mode bits in the lance initialization block - */ -#define PROM 0x8000 -#define INTL 0x40 -#define DRTY 0x20 -#define COLL 0x10 -#define DTCR 0x8 -#define LOOP 0x4 -#define DTX 0x2 -#define DRX 0x1 - -/* - * LANCE CSR0, this is the register we play with most often. We leave - * this register pointed to by l.rap in normal operation. - */ -#define ERR0 0x8000 -#define BABL 0x4000 -#define CERR 0x2000 -#define MISS 0x1000 -#define MERR 0x800 -#define RINT 0x400 -#define TINT 0x200 -#define IDON 0x100 -#define INTR 0x80 -#define INEA 0x40 -#define RXON 0x20 -#define TXON 0x10 -#define TDMD 0x8 -#define STOP 0x4 -#define STRT 0x2 -#define INIT 0x1 - -/* - * flag bits from a buffer descriptor in the rcv/xmt rings - */ -#define LANCEOWNER 0x8000 /* 1 means that the buffer can be used by the chip */ -#define ERR 0x4000 /* error summary, the OR of all error bits */ -#define FRAM 0x2000 /* CRC error and incoming packet not a multiple of 8 bits */ -#define OFLO 0x1000 /* (receive) lost some of the packet */ -#define MORE 0x1000 /* (transmit) more than 1 retry to send the packet */ -#define CRC 0x800 /* (receive) crc error reading packet */ -#define ONE 0x800 /* (transmit) one retry to transmit the packet */ -#define BUF 0x400 /* (receive) out of buffers while reading a packet */ -#define DEF 0x400 /* (transmit) deffered while transmitting packet */ -#define STP 0x200 /* start of packet */ -#define ENP 0x100 /* end of packet */ - -/* - * cntflags bits from a buffer descriptor in the rcv/xmt rings - */ -#define BUFF 0x8000 /* buffer error (host screwed up?) */ -#define UFLO 0x4000 /* underflow from memory */ -#define LCOL 0x1000 /* late collision (ether too long?) */ -#define LCAR 0x800 /* loss of carrier (ether broken?) */ -#define RTRY 0x400 /* couldn't transmit (bad station on ether?) */ -#define TTDR 0x3FF /* time domain reflectometer */ - -/* - * predeclared - */ -static void lancekproc(void *); -static void lancestart(int); -static void lanceup(Etherpkt*, int); -static int lanceclonecon(Chan*); -static void lancestatsfill(Chan*, char*, int); -static void lancetypefill(Chan*, char*, int); - -/* - * lance stream module definition - */ -static void lanceoput(Queue*, Block*); -static void lancestopen(Queue*, Stream*); -static void lancestclose(Queue*); -static void stagerbuf(void); -Qinfo lanceinfo = { nullput, lanceoput, lancestopen, lancestclose, "lance" }; - -/* - * open a lance line discipline - */ -void -lancestopen(Queue *q, Stream *s) -{ - Ethertype *et; - - et = &l.e[s->id]; - RD(q)->ptr = WR(q)->ptr = et; - et->type = 0; - et->q = RD(q); - et->inuse = 1; -} - -/* - * close lance line discipline - * - * the lock is to synchronize changing the ethertype with - * sending packets up the stream on interrupts. - */ -static int -isclosed(void *x) -{ - return ((Ethertype *)x)->q == 0; -} - -static void -lancestclose(Queue *q) -{ - Ethertype *et; - - et = (Ethertype *)(q->ptr); - if(et->prom){ - qlock(&l); - l.prom--; - if(l.prom == 0) - lancestart(0); - qunlock(&l); - } - if(et->type == -1){ - qlock(&l); - l.all--; - qunlock(&l); - } - - /* - * mark as closing and wait for kproc to close us - */ - lock(&l.closepin); - et->closeline = l.closeline; - l.closeline = et; - unlock(&l.closepin); - wakeup(&l.rr); - sleep(&et->rc, isclosed, et); - - et->type = 0; - et->q = 0; - et->prom = 0; - et->inuse = 0; - netdisown(et); -} - -/* - * the ``connect'' control message specifyies the type - */ -Proc *lanceout; -static int -isobuf(void *x) -{ - Msg *m; - - m = x; - return l.wedged || (MPus(m->flags)&LANCEOWNER) == 0; -} - -static void -lanceoput(Queue *q, Block *bp) -{ - int n, len; - Etherpkt *p; - Ethertype *e; - Msg *m; - Block *nbp; - - if(bp->type == M_CTL){ - e = q->ptr; - qlock(&l); - if(streamparse("connect", bp)){ - if(e->type == -1) - l.all--; - e->type = strtol((char *)bp->rptr, 0, 0); - if(e->type == -1) - l.all++; - } else if(streamparse("promiscuous", bp)) { - e->prom = 1; - l.prom++; - if(l.prom == 1) - lancestart(PROM);/**/ - } - qunlock(&l); - freeb(bp); - return; - } - - /* - * give packet a local address, return upstream if destined for - * this machine. - */ - if(BLEN(bp) < ETHERHDRSIZE){ - bp = pullup(bp, ETHERHDRSIZE); - if(bp == 0) - return; - } - p = (Etherpkt *)bp->rptr; - memmove(p->s, l.ea, sizeof(l.ea)); - if(*p->d == 0xff || l.prom || l.all){ - len = blen(bp); - nbp = copyb(bp, len); - nbp = expandb(nbp, len >= ETHERMINTU ? len : ETHERMINTU); - if(nbp){ - nbp->wptr = nbp->rptr+len; - putq(&l.self, nbp); - wakeup(&l.rr); - } - } else if(*p->d == *l.ea && memcmp(l.ea, p->d, sizeof(l.ea)) == 0){ - len = blen(bp); - bp = expandb(bp, len >= ETHERMINTU ? len : ETHERMINTU); - if(bp){ - putq(&l.self, bp); - wakeup(&l.rr); - } - return; - } - - if(l.wedged) { - freeb(bp); - return; - } + QLock tlock; /* lock for grabbing transmitter queue */ + Rendez tr; /* wait here for free xmit buffer */ - /* - * only one transmitter at a time - */ - qlock(&l.tlock); - if(l.wedged) { - qunlock(&l.tlock); - freeb(bp); - return; - } + Netif; +} l; - if(waserror()){ - qunlock(&l.tlock); - freeb(bp); - nexterror(); - } +static void promiscuous(void*, int); - /* - * Wait till we get an output buffer, complain if input - * or output seems wedged. - */ - m = &(LANCEMEM->tmr[l.tc]); - p = &l.tp[l.tc]; - while((MPus(m->flags)&LANCEOWNER) != 0) { - tsleep(&l.tr, isobuf, m, 128); - if(l.wedged || isobuf(m) == 0){ - qunlock(&l.tlock); - freeb(bp); - poperror(); - print("lance wedged, dumping block & restarting\n"); - lancestart(0); - l.wedged = 0; - return; - } - } - - /* - * copy message into lance RAM - */ - len = 0; - for(nbp = bp; nbp; nbp = nbp->next){ - if(sizeof(Etherpkt) - len >= (n = BLEN(nbp))){ - memmove(((uchar *)p)+len, nbp->rptr, n); - len += n; - } else - print("no room damn it\n"); - if(bp->flags & S_DELIM) - break; - } - - /* - * pad the packet (zero the pad) - */ - if(len < ETHERMINTU){ - memset(((char*)p)+len, 0, ETHERMINTU-len); - len = ETHERMINTU; - } - - /* - * set up the ring descriptor and hand to lance - */ - l.outpackets++; - MPs(m->size) = -len; - MPus(m->cntflags) = 0; - MPus(m->laddr) = LADDR(&l.ltp[l.tc]); - MPus(m->flags) = LANCEOWNER|STP|ENP|HADDR(&l.ltp[l.tc]); - l.tc = TSUCC(l.tc); - *l.rdp = INEA|TDMD; /**/ - wbflush(); - qunlock(&l.tlock); - freeb(bp); - poperror(); -} - -/* - * stop the lance and allocate buffers - */ void lancereset(void) { static int already; - int i; if(already == 0){ already = 1; lancesetup(&l); - l.net.name = "ether"; - l.net.nconv = Ntypes; - l.net.devp = &lanceinfo; - l.net.protop = 0; - l.net.listen = 0; - l.net.clone = lanceclonecon; - l.net.ninfo = 2; - l.net.info[0].name = "stats"; - l.net.info[0].fill = lancestatsfill; - l.net.info[1].name = "type"; - l.net.info[1].fill = lancetypefill; - for(i = 0; i < Ntypes; i++) - netadd(&l.net, &l.e[i], i); - - memset(l.bcast, 0xff, sizeof l.bcast); + /* general network interface structure */ + netifinit(&l, "ether", Ntypes, 32*1024); + l.alen = 6; + memmove(l.addr, l.ea, 6); + memmove(l.bcast, etherbcast, 6); + l.promiscuous = promiscuous; + l.arg = &l; } /* @@ -459,8 +162,9 @@ lancereset(void) } /* - * Initialize and start the lance. This routine can be called only from a process. - * It may be used to restart a dead lance. + * Initialize and start the lance. + * This routine can be called only from a process. + * It may be used to restart a dead lance. */ static void lancestart(int mode) @@ -474,7 +178,6 @@ lancestart(int mode) * quiescent */ qlock(&l.tlock); - qlock(&l.rlock); lancereset(); l.rl = 0; @@ -507,7 +210,7 @@ lancestart(int mode) */ m = lm->rmr; for(i = 0; i < l.nrrb; i++, m++){ - MPs(m->size) = -sizeof(Etherpkt); + MPs(m->size) = -sizeof(Lancepkt); MPus(m->cntflags) = 0; MPus(m->laddr) = LADDR(&l.lrp[i]); MPus(m->flags) = HADDR(&l.lrp[i]); @@ -560,148 +263,14 @@ lancestart(int mode) *l.rdp = INEA|INIT|STRT; /**/ } -void -lanceinit(void) -{ -} - -Chan* -lanceattach(char *spec) -{ - if(l.kstarted == 0){ - kproc("lancekproc", lancekproc, 0); - l.kstarted = 1; - lancestart(0); - print("lance ether: %.2x%.2x%.2x%.2x%.2x%.2x\n", - l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]); - } - return devattach('l', spec); -} - -Chan* -lanceclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -lancewalk(Chan *c, char *name) -{ - return netwalk(c, name, &l.net); -} - -void -lancestat(Chan *c, char *dp) -{ - netstat(c, dp, &l.net); -} - -/* - * Pass open's of anything except the directory to streamopen - */ -Chan* -lanceopen(Chan *c, int omode) -{ - return netopen(c, omode, &l.net); -} - -void -lancecreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -lanceclose(Chan *c) -{ - if(c->stream) - streamclose(c); -} - -long -lanceread(Chan *c, void *a, long n, ulong offset) -{ - return netread(c, a, n, offset, &l.net); -} - -long -lancewrite(Chan *c, void *a, long n, ulong offset) -{ - USED(offset); - return streamwrite(c, a, n, 0); -} - -void -lanceremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -lancewstat(Chan *c, char *dp) -{ - netwstat(c, dp, &l.net); -} - -/* - * user level network interface routines - */ -static void -lancestatsfill(Chan *c, char* p, int n) -{ - char buf[512]; - - USED(c); - sprint(buf, "in: %d\nout: %d\ncrc errs %d\noverflows: %d\nframe errs %d\nbuff errs: %d\noerrs %d\naddr: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", - l.inpackets, l.outpackets, l.crcs, - l.overflows, l.frames, l.buffs, l.oerrs, - l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]); - strncpy(p, buf, n); -} - -static void -lancetypefill(Chan *c, char* p, int n) -{ - char buf[16]; - Ethertype *e; - - e = &l.e[STREAMID(c->qid.path)]; - sprint(buf, "%d", e->type); - strncpy(p, buf, n); -} - -static int -lanceclonecon(Chan *c) -{ - Ethertype *e; - - USED(c); - for(e = l.e; e < &l.e[Ntypes]; e++){ - qlock(e); - if(e->inuse || e->q){ - qunlock(e); - continue; - } - e->inuse = 1; - netown(e, up->user, 0); - qunlock(e); - return e - l.e; - } - error(Enodev); - return -1; /* never reached */ -} - -/* - * We will: - * (1) Clear interrupt cause in the lance - * (2) service all current events - */ void lanceintr(void) { - ushort csr; + Msg *m; + Lancepkt *p; + Netfile *f, **fp; + ushort csr, t, x; + Lancemem *lm = LANCEMEM; csr = *l.rdp; @@ -721,7 +290,6 @@ lanceintr(void) l.wedged = 1; l.misses = 0; lancereset(); - wakeup(&l.rr); wakeup(&l.tr); return; } @@ -729,7 +297,6 @@ lanceintr(void) if(csr & IDON){ l.wedged = 0; - qunlock(&l.rlock); qunlock(&l.tlock); } @@ -740,91 +307,9 @@ lanceintr(void) l.wedged = 1; /* - * wakeup the input process - */ - if(csr & RINT) - wakeup(&l.rr); - - /* - * wake any process waiting for a transmit buffer + * process incoming frames */ - if(csr & TINT) - wakeup(&l.tr); -} - -/* - * send a packet upstream - */ -static void -lanceup(Etherpkt *p, int len) -{ - int t; - Block *bp; - Ethertype *e; - - if(len <= 0) - return; - - t = (p->type[0]<<8) | p->type[1]; - for(e = &l.e[0]; e < &l.e[Ntypes]; e++){ - /* - * check for open, the right type, and flow control - */ - if(e->q==0 || (t!=e->type && e->type!=-1) || e->q->next->len>Streamhi) - continue; - - /* - * only a trace channel gets packets destined for other machines - */ - if(e->type!=-1 && p->d[0]!=0xff - && (*p->d != *l.ea || memcmp(p->d, l.ea, sizeof(p->d))!=0)) - continue; - - if(!waserror()){ - bp = allocb(len); - memmove(bp->rptr, (uchar *)p, len); - bp->wptr += len; - bp->flags |= S_DELIM; - PUTNEXT(e->q, bp); - poperror(); - } - } -} - -/* - * input process, awakened on each interrupt with rcv buffers filled - */ -static int -isinput(void *arg) -{ - Msg *m = arg; - - return ((MPus(m->flags) & LANCEOWNER)==0) || l.wedged || l.self.first - || l.closeline; -} - -static void -lancekproc(void *arg) -{ - Etherpkt *p; - Ethertype *e; - int len; - int t; - Lancemem *lm = LANCEMEM; - Msg *m; - Block *bp; - - USED(arg); - - while(waserror()) - print("lancekproc err %s\n", up->error); - - for(;;){ - qlock(&l.rlock); - while(bp = getq(&l.self)){ - lanceup((Etherpkt*)bp->rptr, BLEN(bp)); - freeb(bp); - } + if(csr & RINT) { m = &(lm->rmr[l.rl]); while((MPus(m->flags) & LANCEOWNER)==0){ l.inpackets++; @@ -839,18 +324,23 @@ lancekproc(void *arg) if(t & BUFF) l.buffs++; } else { - /* - * stuff packet up each queue that wants it - */ + /* stuff packet up each queue that wants it */ p = &l.rp[l.rl]; - len = MPus(m->cntflags) - 4; - lanceup(p, len); + x = MPus(m->cntflags) - 4; + t = (p->type[0]<<8) | p->type[1]; + for(fp = l.f; fp < &l.f[Ntypes]; fp++){ + f = *fp; + if(f == 0) + continue; + if(f->type == t || f->type < 0) + qproduce(f->in, p->d, x); + } } /* * stage the next input buffer */ - MPs(m->size) = -sizeof(Etherpkt); + MPs(m->size) = -sizeof(Lancepkt); MPus(m->cntflags) = 0; MPus(m->laddr) = LADDR(&l.lrp[l.rl]); MPus(m->flags) = LANCEOWNER|HADDR(&l.lrp[l.rl]); @@ -858,29 +348,144 @@ lancekproc(void *arg) l.rl = RSUCC(l.rl); m = &(lm->rmr[l.rl]); } - qunlock(&l.rlock); - sleep(&l.rr, isinput, m); - - /* - * if the lance is wedged, restart it - */ - if(l.wedged){ - print("lance wedged, restarting\n"); - lancestart(0); - l.wedged = 0; - } + } - /* - * close ethertypes requesting it - */ - if(l.closeline){ - lock(&l.closepin); - for(e = l.closeline; e; e = e->closeline){ - e->q = 0; - wakeup(&e->rc); - } - l.closeline = 0; - unlock(&l.closepin); + /* + * wake any process waiting for a transmit buffer + */ + if(csr & TINT) + wakeup(&l.tr); +} + +/* + * turn promiscuous mode on/off + */ +static void +promiscuous(void *arg, int on) +{ + USED(arg); + if(on) + lancestart(PROM); + else + lancestart(0);; +} + +void +lanceinit(void) +{ + lancestart(0); + print("lance ether: %.2x%.2x%.2x%.2x%.2x%.2x\n", + l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]); +} + +Chan* +lanceattach(char *spec) +{ + return devattach('l', spec); +} + +Chan* +lanceclone(Chan *c, Chan *nc) +{ + return devclone(c, nc); +} + +int +lancewalk(Chan *c, char *name) +{ + return netifwalk(&l, c, name); +} + +Chan* +lanceopen(Chan *c, int omode) +{ + return netifopen(&l, c, omode); +} + +void +lancecreate(Chan *c, char *name, int omode, ulong perm) +{ + USED(c, name, omode, perm); +} + +void +lanceclose(Chan *c) +{ + netifclose(&l, c); +} + +long +lanceread(Chan *c, void *buf, long n, ulong offset) +{ + return netifread(&l, c, buf, n, offset); +} + +static int +isoutbuf(void *x) +{ + Msg *m; + + m = x; + return l.wedged || (MPus(m->flags)&LANCEOWNER) == 0; +} + +long +lancewrite(Chan *c, void *buf, long n, ulong offset) +{ + Msg *m; + Lancepkt *p; + + USED(offset); + + if(n > ETHERMAXTU) + error(Ebadarg); + + /* etherif.c handles structure */ + if(NETTYPE(c->qid.path) != Ndataqid) + return netifwrite(&l, c, buf, n); + + /* we handle data */ + qlock(&l.tlock); + m = &(LANCEMEM->tmr[l.tc]); + tsleep(&l.tr, isoutbuf, m, 10000); + if(!isoutbuf(m) || l.wedged){ + print("lance transmitter jammed\n"); + } + else { + p = &l.tp[l.tc]; + memmove(p->d, buf, n); + if(n < 60) { + memset(p->d+n, 0, 60-n); + n = 60; } + memmove(p->s, l.ea, sizeof(l.ea)); + + l.outpackets++; + MPs(m->size) = -n; + MPus(m->cntflags) = 0; + MPus(m->laddr) = LADDR(&l.ltp[l.tc]); + MPus(m->flags) = LANCEOWNER|STP|ENP|HADDR(&l.ltp[l.tc]); + l.tc = TSUCC(l.tc); + *l.rdp = INEA|TDMD; /**/ } + qunlock(&l.tlock); + return n; +} + +void +lanceremove(Chan *c) +{ + USED(c); +} + +void +lancestat(Chan *c, char *dp) +{ + netifstat(&l, c, dp); +} + +void +lancewstat(Chan *c, char *dp) +{ + netifwstat(&l, c, dp); } diff --git a/port/portdat.h b/port/portdat.h index 9529d72a54b4a53b250a789a6be2ee98401ae8a6..297da6b28bf15ae4eb290bfd74a8a58454af0352 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -68,7 +68,7 @@ struct RWlock { Lock; /* Lock modify lock */ QLock x; /* Mutual exclusion lock */ - QLock k; /* Lock for waiting writers held for readers */ + QLock k; /* Lock for waiting writers */ int readers; /* Count of readers in lock */ }; @@ -84,7 +84,7 @@ struct Alarms Proc *head; }; -#define MAXSYSARG 5 /* for mount(fd, mpt, flag, arg, srv) */ +#define MAXSYSARG 5 /* for mount(fd, mpt, flag, arg, srv) */ struct Sargs { ulong args[MAXSYSARG]; @@ -458,7 +458,7 @@ struct Palloc Rendez r; /* Sleep for free mem */ QLock pwait; /* Queue of procs waiting for memory */ int wanted; /* Do the wakeup at free */ - ulong cmembase; /* Key memory protected from read by devproc */ + ulong cmembase; /* Key memory */ ulong cmemtop; }; @@ -565,7 +565,7 @@ struct Proc int kp; /* true if a kernel process */ Proc *palarm; /* Next alarm time */ ulong alarm; /* Time of call */ - int newtlb; /* Pager has changed my pte's so I must flush */ + int newtlb; /* Pager has changed my pte's, I must flush */ ulong rendtag; /* Tag for rendezvous */ ulong rendval; /* Value for rendezvous */ diff --git a/power/dat.h b/power/dat.h index 9158d571c141dbb53e7f1f33be6494e30e4c4a1b..e3d632ff81bca1c885e4b936c604cbeffedd8e7f 100644 --- a/power/dat.h +++ b/power/dat.h @@ -1,4 +1,5 @@ typedef struct Conf Conf; +typedef struct Lancepkt Lancepkt; typedef struct FPsave FPsave; typedef struct Cycmsg Cycmsg; typedef struct Lance Lance; @@ -148,6 +149,15 @@ typedef void KMap; #define ACON 0x2 #define BCON 0x1 +struct Lancepkt +{ + uchar d[6]; + uchar s[6]; + uchar type[2]; + uchar data[1500]; + uchar crc[4]; +}; + /* * system dependent lance stuff * filled by lancesetup() @@ -166,10 +176,10 @@ struct Lance as seen by host */ ushort *lanceram; /* start of lance ram as seen by host */ Lancemem *lm; /* start of lance ram as seen by lance */ - Etherpkt *rp; /* receive buffers (host address) */ - Etherpkt *tp; /* transmit buffers (host address) */ - Etherpkt *lrp; /* receive buffers (lance address) */ - Etherpkt *ltp; /* transmit buffers (lance address) */ + Lancepkt *rp; /* receive buffers (host address) */ + Lancepkt *tp; /* transmit buffers (host address) */ + Lancepkt *lrp; /* receive buffers (lance address) */ + Lancepkt *ltp; /* transmit buffers (lance address) */ }; struct diff --git a/power/debugger.c b/power/debugger.c deleted file mode 100644 index c22a0dc0ba448d2fde7cc1008fc60e72a8ef5b61..0000000000000000000000000000000000000000 --- a/power/debugger.c +++ /dev/null @@ -1,249 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" - -IOQ dkbdq; -IOQ dprintq; - -typedef struct Syslogbuf Syslogbuf; -struct Syslogbuf -{ - char *next; - char buf[4*1024]; -}; - -Syslogbuf syslogbuf[4]; - -static int -dprint(char *fmt, ...) -{ - char buf[PRINTSIZE]; - int n; - - n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; - dprintq.puts(&dprintq, buf, n); - return n; -} - -static int -dgetline(char *p, int n) -{ - int c; - char *end, *start; - char buf[1]; - - start = p; - end = p + n - 1; - for(;;){ - c = getc(&dkbdq); - if(c <= 0) - continue; - - /* echo */ - buf[0] = c; - if(c == '\r' || c == '\n') - dprintq.puts(&dprintq, "\r\n", 2); - else - dprintq.puts(&dprintq, buf, 1); - - if(c == '\b'){ - if(p != start) - p--; - continue; - } - if(c == '\r' || c == '\n') - break; - if(p >= end) - continue; - *p++ = c; - } - *p = 0; - return p - start; -} - -static void -printlog(char *cpu) -{ - int i, c; - char *p, *end; - Syslogbuf *s; - - if(cpu == 0) - i = 0; - else - i = atoi(cpu); - if(i < 0 || i > 3) - return; - s = &syslogbuf[i]; - - if(s->next < s->buf || s->next >= &s->buf[sizeof(s->buf)]) - s->next = s->buf; - end = s->next; - p = end + 1; - if(p >= &s->buf[sizeof(s->buf)] || p < s->buf) - p = s->buf; - while(p != end){ - c = *p & 0xff; - if(c == '\r' || c == '\n') - dprintq.puts(&dprintq, "\r\n", 2); - else if(c >= ' ' && c <= '~') - dprintq.puts(&dprintq, p, 1); - p++; - if(p >= &s->buf[sizeof(s->buf)]) - p = s->buf; - } -} - -static void -printhex(char *start, char *len) -{ - int i; - ulong n; - ulong *p; - - if(start == 0){ - dprint("! h - hex display\r\n"); - return; - } - n = strtoul(start, 0, 16); - if((n & KZERO) == 0) - return; - p = (ulong *)n; - - if(len) - n = strtoul(len, 0, 0); - else - n = 1; - - while(n > 0){ - dprint("%lux/", p); - for(i = 0; i < 8 && n > 0; i++, n--) - dprint(" %8.8lux", p[i]); - dprint("\r\n"); - p += 8; - } -} - -static void -printinfo(void) -{ - Mach *mp; - Proc *p; - Page *pg; - Ureg *ur; - ulong l; - int i; - - for(i = 0; i < 4; i++){ - if((active.machs&(1<proc); - dprint("mach[%d] proc/%lux\r\n", i, l); - dprint("mach[%d] splpc/%lux\r\n", i, mp->splpc); - - if(l & KZERO){ - p = (Proc*)l; - l = (ulong)(p->upage); - if(l & KZERO){ - pg = (Page*)l; - l = pg->pa; - dprint("mach[%d] proc->upage->pa/%lux\r\n", i, l); - } - } - l = (ulong)(mp->ur); - dprint("mach[%d] ur/%lux", i, l); - ur = (Ureg*)l; - dprint(" &status/%lux &cause/%lux &sp/%lux &pc/%lux", - &ur->status, &ur->cause, &ur->sp, &ur->pc); - dprint("\r\n"); - } -} - -void -debugger(void *arg) -{ - int n, level; - char buf[256]; - char *field[3]; - - USED(arg); - - /* - * sched() until we are on processor 1 - */ - for(;;){ - level = splhi(); - if(m->machno == 1) - break; - splx(level); - sched(); - } - - /* - * grab a port for a console - */ - initq(&dprintq); - initq(&dkbdq); - duartspecial(3, &dprintq, &dkbdq, 9600); - - /* - * take processor and process out of active groups - */ - active.machs &= ~(1<<1); - splx(level); - - for(;;){ - dprint("kdb> "); - dgetline(buf, sizeof(buf)); - memset(field, 0, sizeof(field)); - n = getfields(buf, field, 3, ' '); - if(n == 0) - continue; - switch(*field[0]){ - case 'l': - printlog(field[1]); - break; - case 'h': - printhex(field[1], field[2]); - break; - case 'i': - printinfo(); - break; - case 'q': - firmware(cpuserver ? PROM_AUTOBOOT : PROM_REINIT); - break; - default: - dprint("!commands are:\r\n"); - dprint("! l - print cpu log\r\n"); - dprint("! h - hex display\r\n"); - dprint("! i - display some addresses\r\n"); - dprint("! q - quit/rebooot\r\n"); - break; - } - } -} - -void -syslog(char *str, int n) -{ - Syslogbuf *s; - int level; - - level = splhi(); - s = &syslogbuf[m->machno]; - if(s->next < s->buf || s->next >= &s->buf[sizeof(s->buf)]) - s->next = s->buf; - while(n-- > 0){ - *s->next = *str++; - if(s->next >= &s->buf[sizeof(s->buf)-1]) - s->next = s->buf; - else - s->next++; - } - splx(level); -} diff --git a/power/devduart.c b/power/devduart.c index 9885085fac0b3b0d13aa3df2231f88684eb14140..1ed4c1183d228f55d4436f60fd716eca322fcda5 100644 --- a/power/devduart.c +++ b/power/devduart.c @@ -6,104 +6,103 @@ #include "io.h" #include "../port/error.h" -void duartputs(IOQ*, char*, int); -void iprint(char*, ...); - -#define PAD 15 /* registers are well-spaced */ +#include "devtab.h" +#include "../port/netif.h" /* - * Register set for half the duart. There are really two sets in adjacent - * memory locations. + * Register set for half the duart. + * There are really two sets in adjacent memory locations. */ struct Duartreg { - uchar mr1_2, /* Mode Register Channels 1 & 2 */ - pad0[PAD]; - uchar sr_csr, /* Status Register/Clock Select Register */ - pad1[PAD]; - uchar cmnd, /* Command Register */ - pad2[PAD]; - uchar data, /* RX Holding / TX Holding Register */ - pad3[PAD]; - uchar ipc_acr, /* Input Port Change/Aux. Control Register */ - pad4[PAD]; - uchar is_imr, /* Interrupt Status/Interrupt Mask Register */ - pad5[PAD]; - uchar ctur, /* Counter/Timer Upper Register */ - pad6[PAD]; - uchar ctlr, /* Counter/Timer Lower Register */ - pad7[PAD]; + uchar mr12; /* Mode Register Channels 1 & 2 */ + uchar pad0[15]; + uchar srcsr; /* Status Register/Clock Select Register */ + uchar pad1[15]; + uchar cmnd; /* Command Register */ + uchar pad2[15]; + uchar data; /* RX Holding / TX Holding Register */ + uchar pad3[15]; + uchar ipcacr; /* Input Uart Change/Aux. Control Register */ + uchar pad4[15]; + uchar isimr; /* Interrupt Status/Interrupt Mask Register */ + uchar pad5[15]; + uchar ctur; /* Counter/Timer Upper Register */ + uchar pad6[15]; + uchar ctlr; /* Counter/Timer Lower Register */ + uchar pad7[15]; }; -#define ppcr is_imr /* in the second register set */ - -#define DBD75 0 -#define DBD110 1 -#define DBD38400 2 -#define DBD150 3 -#define DBD300 4 -#define DBD600 5 -#define DBD1200 6 -#define DBD2000 7 -#define DBD2400 8 -#define DBD4800 9 -#define DBD1800 10 -#define DBD9600 11 -#define DBD19200 12 - -enum{ - CHAR_ERR =0x00, /* MR1x - Mode Register 1 */ - EVEN_PAR =0x00, - ODD_PAR =0x04, - NO_PAR =0x10, - CBITS8 =0x03, - CBITS7 =0x02, - CBITS6 =0x01, - CBITS5 =0x00, - NORM_OP =0x00, /* MR2x - Mode Register 2 */ - TWOSTOPB =0x0F, - ONESTOPB =0x07, - ENB_RX =0x01, /* CRx - Command Register */ - DIS_RX =0x02, - ENB_TX =0x04, - DIS_TX =0x08, - RESET_MR =0x10, - RESET_RCV =0x20, - RESET_TRANS =0x30, - RESET_ERR =0x40, - RESET_BCH =0x50, - STRT_BRK =0x60, - STOP_BRK =0x70, - RCV_RDY =0x01, /* SRx - Channel Status Register */ - FIFOFULL =0x02, - XMT_RDY =0x04, - XMT_EMT =0x08, - OVR_ERR =0x10, - PAR_ERR =0x20, - FRM_ERR =0x40, - RCVD_BRK =0x80, - IM_IPC =0x80, /* IMRx/ISRx - Interrupt Mask/Interrupt Status */ - IM_DBB =0x40, - IM_RRDYB =0x20, - IM_XRDYB =0x10, - IM_CRDY =0x08, - IM_DBA =0x04, - IM_RRDYA =0x02, - IM_XRDYA =0x01, - BD38400 =0xCC|0x0000, - BD19200 =0xCC|0x0100, - BD9600 =0xBB|0x0000, - BD4800 =0x99|0x0000, - BD2400 =0x88|0x0000, - BD1200 =0x66|0x0000, - BD300 =0x44|0x0000, - - Maxduart =8, +#define ppcr isimr /* in the second register set */ + +enum +{ + DBD75 = 0, + DBD110 = 1, + DBD38400 = 2, + DBD150 = 3, + DBD300 = 4, + DBD600 = 5, + DBD1200 = 6, + DBD2000 = 7, + DBD2400 = 8, + DBD4800 = 9, + DBD1800 = 10, + DBD9600 = 11, + DBD19200 = 12, + CHARERR = 0x00, /* MR1x - Mode Register 1 */ + EVENPAR = 0x00, + ODDPAR = 0x04, + NOPAR = 0x10, + CBITS8 = 0x03, + CBITS7 = 0x02, + CBITS6 = 0x01, + CBITS5 = 0x00, + NORMOP = 0x00, /* MR2x - Mode Register 2 */ + TWOSTOPB = 0x0F, + ONESTOPB = 0x07, + ENBRX = 0x01, /* CRx - Command Register */ + DISRX = 0x02, + ENBTX = 0x04, + DISTX = 0x08, + RESETMR = 0x10, + RESETRCV = 0x20, + RESETTRANS = 0x30, + RESETERR = 0x40, + RESETBCH = 0x50, + STRTBRK = 0x60, + STOPBRK = 0x70, + RCVRDY = 0x01, /* SRx - Channel Status Register */ + FIFOFULL = 0x02, + XMTRDY = 0x04, + XMTEMT = 0x08, + OVRERR = 0x10, + PARERR = 0x20, + FRMERR = 0x40, + RCVDBRK = 0x80, + IMIPC = 0x80, /* IMRx/ISRx - Int Mask/Interrupt Status */ + IMDBB = 0x40, + IMRRDYB = 0x20, + IMXRDYB = 0x10, + IMCRDY = 0x08, + IMDBA = 0x04, + IMRRDYA = 0x02, + IMXRDYA = 0x01, + BD38400 = 0xCC|0x0000, + BD19200 = 0xCC|0x0100, + BD9600 = 0xBB|0x0000, + BD4800 = 0x99|0x0000, + BD2400 = 0x88|0x0000, + BD1200 = 0x66|0x0000, + BD300 = 0x44|0x0000, + + Maxduart = 8, }; /* * requests to perform on a duart */ -enum { +enum +{ Dnone= 0, Dbaud, Dbreak, @@ -130,11 +129,10 @@ Duart duart[Maxduart]; /* * values specific to a single duart port */ -typedef struct Port Port; -struct Port +typedef struct Uart Uart; +struct Uart { QLock; - int printing; /* true if printing */ Duart *d; /* device */ Duartreg *reg; /* duart registers (for this port) */ int c; /* character to restart output */ @@ -142,24 +140,25 @@ struct Port int val; /* value of operation */ Rendez opr; /* waiot here for op to complete */ - /* console interface */ - int nostream; /* can't use the stream interface */ - IOQ *iq; /* input character queue */ - IOQ *oq; /* output character queue */ + int printing; /* need kick */ + int opens; + Rendez r; - /* stream interface */ - Queue *wq; /* write queue */ - Rendez r; /* kproc waiting for input */ - int kstarted; /* kproc started */ + /* buffers */ + int (*putc)(Queue*, int); + Queue *iq; + Queue *oq; }; -Port duartport[2*Maxduart]; +Uart uart[2*Maxduart]; + +void duartkick(Uart*); /* * configure a duart port, default is 9600 baud, 8 bits/char, 1 stop bit, * no parity */ void -duartsetup(Port *p, Duart *d, int devno) +duartsetup(Uart *p, Duart *d, int devno) { Duartreg *reg; @@ -167,16 +166,19 @@ duartsetup(Port *p, Duart *d, int devno) reg = &d->reg[devno]; p->reg = reg; - reg->cmnd = RESET_RCV|DIS_TX|DIS_RX; - reg->cmnd = RESET_TRANS; - reg->cmnd = RESET_ERR; - reg->cmnd = STOP_BRK; + reg->cmnd = RESETRCV|DISTX|DISRX; + reg->cmnd = RESETTRANS; + reg->cmnd = RESETERR; + reg->cmnd = STOPBRK; - reg->cmnd = RESET_MR; - reg->mr1_2 = NO_PAR|CBITS8; - reg->mr1_2 = ONESTOPB; - reg->sr_csr = (DBD9600<<4)|DBD9600; - reg->cmnd = ENB_TX|ENB_RX; + reg->cmnd = RESETMR; + reg->mr12 = NOPAR|CBITS8; + reg->mr12 = ONESTOPB; + reg->srcsr = (DBD9600<<4)|DBD9600; + reg->cmnd = ENBTX|ENBRX; + + p->iq = qopen(4*1024, 0, 0, 0); + p->oq = qopen(4*1024, 0, duartkick, p); } /* @@ -185,19 +187,21 @@ duartsetup(Port *p, Duart *d, int devno) void duartinit(void) { - Port *p; + Uart *p; Duart *d; d = &duart[m->machno]; if(d->inited) return; + d->reg = DUARTREG; - d->imr = IM_RRDYA|IM_XRDYA|IM_RRDYB|IM_XRDYB; - d->reg->is_imr = d->imr; + d->imr = IMRRDYA|IMXRDYA|IMRRDYB|IMXRDYB; + d->reg->isimr = d->imr; d->acr = 0x80; /* baud rate set 2 */ - d->reg->ipc_acr = d->acr; + d->reg->ipcacr = d->acr; + + p = &uart[2*m->machno]; - p = &duartport[2*m->machno]; duartsetup(p, d, 0); p++; duartsetup(p, d, 1); @@ -208,19 +212,19 @@ duartinit(void) * enable a duart port */ void -duartenable(Port *p) +duartenable(Uart *p) { - p->reg->cmnd = ENB_TX|ENB_RX; + p->reg->cmnd = ENBTX|ENBRX; } void duartenable0(void) { - DUARTREG->cmnd = ENB_TX|ENB_RX; + DUARTREG->cmnd = ENBTX|ENBRX; } void -duartbaud(Port *p, int b) +duartbaud(Uart *p, int b) { int x; @@ -253,12 +257,12 @@ duartbaud(Port *p, int b) p->d->acr |= 0x80; else p->d->acr &= ~0x80; - p->d->reg->ipc_acr = p->d->acr; - p->reg->sr_csr = x; + p->d->reg->ipcacr = p->d->acr; + p->reg->srcsr = x; } void -duartdtr(Port *p, int val) +duartdtr(Uart *p, int val) { if (val) p->reg->ctlr = 0x01; @@ -267,19 +271,19 @@ duartdtr(Port *p, int val) } void -duartbreak(Port *p, int val) +duartbreak(Uart *p, int val) { Duartreg *reg; reg = p->reg; if (val){ - p->d->imr &= ~IM_XRDYB; - p->d->reg->is_imr = p->d->imr; - reg->cmnd = STRT_BRK|ENB_TX; + p->d->imr &= ~IMXRDYB; + p->d->reg->isimr = p->d->imr; + reg->cmnd = STRTBRK|ENBTX; } else { - reg->cmnd = STOP_BRK|ENB_TX; - p->d->imr |= IM_XRDYB; - p->d->reg->is_imr = p->d->imr; + reg->cmnd = STOPBRK|ENBTX; + p->d->imr |= IMXRDYB; + p->d->reg->isimr = p->d->imr; } } @@ -287,7 +291,7 @@ duartbreak(Port *p, int val) * do anything requested for this CPU's duarts */ void -duartslave0(Port *p) +duartslave0(Uart *p) { switch(p->op){ case Ddtr: @@ -300,8 +304,9 @@ duartslave0(Port *p) duartbreak(p, p->val); break; case Dprint: - p->reg->cmnd = ENB_TX; + p->reg->cmnd = ENBTX; p->reg->data = p->val; +iprint("slave %c\n", p->val); break; case Dena: duartenable(p); @@ -316,62 +321,75 @@ duartslave0(Port *p) void duartslave(void) { - IOQ *cq; - Port *p; + Uart *p; - p = &duartport[2*m->machno]; - cq = p->iq; - if(p->wq && cangetc(cq)) - wakeup(&cq->r); + p = &uart[2*m->machno]; if(p->op != Dnone) duartslave0(p); p++; - cq = p->iq; - if(p->wq && cangetc(cq)) - wakeup(&cq->r); if(p->op != Dnone) duartslave0(p); } void -duartrintr(Port *p) +duartrintr(Uart *p) { - Duartreg *reg; - IOQ *cq; - int status; char ch; + int status; + Duartreg *reg; reg = p->reg; - status = reg->sr_csr; + status = reg->srcsr; ch = reg->data; - if(status & (FRM_ERR|OVR_ERR|PAR_ERR)) - reg->cmnd = RESET_ERR; + if(status & (FRMERR|OVRERR|PARERR)) + reg->cmnd = RESETERR; - cq = p->iq; - if(cq->putc) - (*cq->putc)(cq, ch); + if(p->putc) + (*p->putc)(p->iq, ch); else - putc(cq, ch); + qproduce(p->iq, &ch, 1); } +/* + * (re)start output + */ void -duartxintr(Port *p) +duartkick(Uart *p) +{ + char ch; + int n, x; + + x = splhi(); + if(p->printing) { + splx(x); + return; + } + + n = qconsume(p->oq, &ch, 1); + if(n <= 0){ + splx(x); + return; + } + + p->printing = 1; + p->val = ch; + p->op = Dprint; + splx(x); +} + +void +duartxintr(Uart *p) { - Duartreg *reg; - IOQ *cq; int ch; + Duartreg *reg; - cq = p->oq; - lock(cq); - ch = getc(cq); reg = p->reg; - if(ch < 0){ + if(qconsume(p->oq, &ch, 1) <= 0) { p->printing = 0; - wakeup(&cq->r); - reg->cmnd = DIS_TX; - } else + reg->cmnd = DISTX; + } + else reg->data = ch; - unlock(cq); } void @@ -379,34 +397,22 @@ duartintr(void) { int cause; Duartreg *reg; - Port *p; + Uart *p; - p = &duartport[2*m->machno]; + p = &uart[2*m->machno]; reg = p->reg; - cause = reg->is_imr; - - /* - * I can guess your interrupt. - */ - /* - * Is it 1? - */ - if(cause & IM_RRDYA) + cause = reg->isimr; + + if(cause & IMRRDYA) duartrintr(p); - /* - * Is it 2? - */ - if(cause & IM_XRDYA) + + if(cause & IMXRDYA) duartxintr(p); - /* - * Is it 3? - */ - if(cause & IM_RRDYB) + + if(cause & IMRRDYB) duartrintr(p+1); - /* - * Is it 4? - */ - if(cause & IM_XRDYB) + + if(cause & IMXRDYB) duartxintr(p+1); } @@ -416,310 +422,85 @@ duartintr(void) int duartrawputc(int c) { - Duartreg *reg; int i; + Duartreg *reg; reg = DUARTREG; - if(c == '\n') + if(c == '\n') { duartrawputc('\r'); - reg->cmnd = ENB_TX; + delay(100); + } + reg->cmnd = ENBTX; i = 0; - while((reg->sr_csr&XMT_RDY) == 0) - if(++i >= 1000000){ - duartsetup(&duartport[0], &duart[0], 0); - for(i=0; i<100000; i++) - ; - break; - } + while((reg->srcsr&XMTRDY) == 0 && i++ < 100000) + ; reg->data = c; - if(c == '\n') - for(i=0; i<100000; i++) - ; return c; } -void -duartrawputs(char *s) -{ - int i; - while(*s){ - duartrawputc(*s++); - } - for(i=0; i < 1000000; i++) - ; -} -void +int iprint(char *fmt, ...) { + int n, i; char buf[512]; - doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)); - duartrawputs(buf); + n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; + for(i = 0; i < n; i++) + duartrawputc(buf[i]); + return n; } -/* - * Queue n characters for output; if queue is full, we lose characters. - * Get the output going if it isn't already. - */ void -duartputs(IOQ *cq, char *s, int n) +duartspecial(int port, int s, Queue **in, Queue **out, int (*putc)(Queue*, int)) { - int ch, x; - Port *p; + Uart *p; - x = splhi(); - lock(cq); - puts(cq, s, n); - p = cq->ptr; - if(p->printing == 0){ - ch = getc(cq); - if(ch >= 0){ - p->printing = 1; - p->val = ch; - p->op = Dprint; - } - } - unlock(cq); - splx(x); -} - -/* - * set up an duart port as something other than a stream - */ -void -duartspecial(int port, IOQ *oq, IOQ *iq, int baud) -{ - Port *p = &duartport[port]; - IOQ *zq; + p = &uart[port]; - p->nostream = 1; - if(oq){ - p->oq = oq; - p->oq->puts = duartputs; - p->oq->ptr = p; - } - if(iq){ - p->iq = iq; - p->iq->ptr = p; - - /* - * Stupid HACK to undo a stupid hack - */ - zq = &kbdq; - if(iq == zq) - kbdq.putc = kbdcr2nl; - } duartenable(p); - duartbaud(p, baud); -} + if(s) + duartbaud(p, s); -static int duartputc(IOQ *, int); -static void duartstopen(Queue*, Stream*); -static void duartstclose(Queue*); -static void duartoput(Queue*, Block*); -static void duartkproc(void *); -Qinfo duartinfo = -{ - nullput, - duartoput, - duartstopen, - duartstclose, - "duart" -}; + p->putc = putc; + if(in) + *in = p->iq; + if(out) + *out = p->oq; + + p->opens++; +} static int opdone(void *x) { - Port *p = x; + Uart *p = x; return p->op == Dnone; } -static void -duartstopen(Queue *q, Stream *s) -{ - Port *p; - char name[NAMELEN]; - - p = &duartport[s->id]; - - qlock(p); - p->wq = WR(q); - WR(q)->ptr = p; - RD(q)->ptr = p; - qunlock(p); - - if(p->kstarted == 0){ - p->kstarted = 1; - sprint(name, "duart%d", s->id+1); - kproc(name, duartkproc, p); - } - - /* enable the port */ - qlock(p); - p->op = Dena; - sleep(&p->opr, opdone, p); - qunlock(p); -} - -static void -duartstclose(Queue *q) -{ - Port *p = q->ptr; - - qlock(p); - p->wq = 0; - p->iq->putc = 0; - WR(q)->ptr = 0; - RD(q)->ptr = 0; - qunlock(p); -} - -static void -duartoput(Queue *q, Block *bp) -{ - Port *p = q->ptr; - IOQ *cq; - int n, m; - - if(p == 0){ - freeb(bp); - return; - } - cq = p->oq; - if(waserror()){ - freeb(bp); - nexterror(); - } - if(bp->type == M_CTL){ - if(waserror()){ - qunlock(p); - qunlock(p->d); - nexterror(); - } - qlock(p); - qlock(p->d); - while (cangetc(cq)) /* let output drain */ - sleep(&cq->r, cangetc, cq); - n = strtoul((char *)(bp->rptr+1), 0, 0); - switch(*bp->rptr){ - case 'B': - case 'b': - p->val = n; - p->op = Dbaud; - sleep(&p->opr, opdone, p); - break; - case 'D': - case 'd': - p->val = n; - p->op = Ddtr; - sleep(&p->opr, opdone, p); - break; - case 'K': - case 'k': - p->val = 1; - p->op = Dbreak; - if(!waserror()){ - sleep(&p->opr, opdone, p); - tsleep(&p->opr, return0, 0, n); - poperror(); - } - p->val = 0; - p->op = Dbreak; - sleep(&p->opr, opdone, p); - break; - case 'R': - case 'r': - /* can't control? */ - break; - } - qunlock(p->d); - qunlock(p); - poperror(); - }else while((m = BLEN(bp)) > 0){ - while ((n = canputc(cq)) == 0){ - kprint(" duartoput: sleeping\n"); - sleep(&cq->r, canputc, cq); - } - if(n > m) - n = m; - (*cq->puts)(cq, bp->rptr, n); - bp->rptr += n; - } - freeb(bp); - poperror(); -} - -/* - * process to send bytes upstream for a port - */ -static void -duartkproc(void *a) -{ - Port *p = a; - IOQ *cq = p->iq; - Block *bp; - int n; - -loop: - while ((n = cangetc(cq)) == 0) - sleep(&cq->r, cangetc, cq); - qlock(p); - if(p->wq == 0){ - cq->out = cq->in; - }else{ - bp = allocb(n); - bp->flags |= S_DELIM; - bp->wptr += gets(cq, bp->wptr, n); - PUTNEXT(RD(p->wq), bp); - } - qunlock(p); - goto loop; -} - Dirtab *duartdir; -int nduartport; +int nuart; -/* - * allocate the queues if no one else has - */ void duartreset(void) { - Port *p; int i; - - /* - * allocate the directory and fill it in - */ - nduartport = 2*conf.nmach; - duartdir = xalloc(nduartport*2*sizeof(Dirtab)); - for(i = 0; i < nduartport; i++){ - sprint(duartdir[2*i].name, "eia%d", i+1); - sprint(duartdir[2*i+1].name, "eia%dctl", i+1); - duartdir[2*i].length = 0; - duartdir[2*i+1].length = 0; - duartdir[2*i].perm = 0666; - duartdir[2*i+1].perm = 0666; - duartdir[2*i].qid.path = STREAMQID(i, Sdataqid); - duartdir[2*i+1].qid.path = STREAMQID(i, Sctlqid); - } - - /* - * allocate queues for any stream interfaces - */ - for(p = duartport; p < &duartport[nduartport]; p++){ - if(p->nostream) - continue; - - p->iq = xalloc(sizeof(IOQ)); - initq(p->iq); - p->iq->ptr = p; - - p->oq = xalloc(sizeof(IOQ)); - initq(p->oq); - p->oq->ptr = p; - p->oq->puts = duartputs; + Dirtab *dp; + + nuart = 2*conf.nmach; + duartdir = xalloc(2 * nuart * sizeof(Dirtab)); + dp = duartdir; + for(i = 0; i < nuart; i++){ + /* 2 directory entries per port */ + print(dp->name, "eia%d", i); + dp->qid.path = NETQID(i, Ndataqid); + dp->perm = 0666; + dp++; + + print(dp->name, "eia%dctl", i); + dp->qid.path = NETQID(i, Nctlqid); + dp->perm = 0666; + dp++; } } @@ -738,19 +519,25 @@ duartclone(Chan *c, Chan *nc) int duartwalk(Chan *c, char *name) { - return devwalk(c, name, duartdir, 2*nduartport, devgen); + return devwalk(c, name, duartdir, 2*nuart, devgen); } void -duartstat(Chan *c, char *p) +duartstat(Chan *c, char *dp) { - switch(STREAMTYPE(c->qid.path)){ - case Sdataqid: - streamstat(c, p, duartdir[2*STREAMID(c->qid.path)].name, - duartdir[2*STREAMID(c->qid.path)].perm); + int i; + Uart *p; + Dir dir; + + i = NETID(c->qid.path); + switch(NETTYPE(c->qid.path)){ + case Ndataqid: + p = &uart[i]; + devdir(c, c->qid, duartdir[2*i].name, qlen(p->iq), eve, 0660, &dir); + convD2M(&dir, dp); break; default: - devstat(c, p, duartdir, 2*nduartport, devgen); + devstat(c, dp, duartdir, 2*nuart, devgen); break; } } @@ -758,75 +545,143 @@ duartstat(Chan *c, char *p) Chan* duartopen(Chan *c, int omode) { - Port *p; + Uart *p; - switch(STREAMTYPE(c->qid.path)){ - case Sdataqid: - case Sctlqid: - p = &duartport[STREAMID(c->qid.path)]; - break; - default: - p = 0; - break; + if(c->qid.path & CHDIR){ + if(omode != OREAD) + error(Ebadarg); + } + else { + p = &uart[NETID(c->qid.path)]; + qlock(p); + p->opens++; + if(p->opens == 1) { + /* enable the port */ + p->op = Dena; + sleep(&p->opr, opdone, p); + + qreopen(p->iq); + qreopen(p->oq); + } + qunlock(p); } - if(p && p->nostream) - error(Einuse); - - if((c->qid.path & CHDIR) == 0) - streamopen(c, &duartinfo); - return devopen(c, omode, duartdir, 2*nduartport, devgen); + c->mode = omode&~OTRUNC; + c->flag |= COPEN; + c->offset = 0; + return c; } void duartcreate(Chan *c, char *name, int omode, ulong perm) { - USED(c); - USED(name); - USED(omode); - USED(perm); + USED(c, name, omode, perm); error(Eperm); } void duartclose(Chan *c) { - if(c->stream) - streamclose(c); + Uart *p; + + if(c->qid.path & CHDIR) + return; + + p = &uart[NETID(c->qid.path)]; + qlock(p); + p->opens++; + if(p->opens == 0){ + qclose(p->iq); + qclose(p->oq); + } + qunlock(p); } long duartread(Chan *c, void *buf, long n, ulong offset) { - Port *p; + Uart *p; - if(c->qid.path&CHDIR) - return devdirread(c, buf, n, duartdir, 2*nduartport, devgen); + if(c->qid.path & CHDIR) + return devdirread(c, buf, n, duartdir, 2*nuart, devgen); - switch(STREAMTYPE(c->qid.path)){ - case Sdataqid: - return streamread(c, buf, n); - case Sctlqid: - if(offset) - return 0; - p = &duartport[STREAMID(c->qid.path)]; - qlock(p); - p->op = Dstate; - sleep(&p->opr, opdone, p); - *(uchar *)buf = p->val; - qunlock(p); - return 1; + p = &uart[NETID(c->qid.path)]; + switch(NETTYPE(c->qid.path)){ + case Ndataqid: + return qread(p->iq, buf, n); + case Nctlqid: + return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE); } - error(Egreg); - return 0; /* not reached */ + return 0; +} + +static void +duartctl(Uart *p, char *cmd) +{ + int n, i; + + /* let output drain for a while */ + for(i = 0; i < 16 && qlen(p->oq); i++) + tsleep(&p->r, qlen, p->oq, 125); + + n = atoi(cmd+1); + switch(cmd[0]){ + case 'B': + case 'b': + p->val = n; + p->op = Dbaud; + sleep(&p->opr, opdone, p); + break; + case 'D': + case 'd': + p->val = n; + p->op = Ddtr; + sleep(&p->opr, opdone, p); + break; + case 'K': + case 'k': + p->val = 1; + p->op = Dbreak; + if(!waserror()){ + sleep(&p->opr, opdone, p); + tsleep(&p->opr, return0, 0, n); + poperror(); + } + p->val = 0; + p->op = Dbreak; + sleep(&p->opr, opdone, p); + break; + case 'R': + case 'r': + /* can't control? */ + break; + } } long duartwrite(Chan *c, void *va, long n, ulong offset) { + Uart *p; + char cmd[32]; + USED(offset); - return streamwrite(c, va, n, 0); + + if(c->qid.path & CHDIR) + error(Eperm); + + p = &uart[NETID(c->qid.path)]; + switch(NETTYPE(c->qid.path)){ + case Ndataqid: + return qwrite(p->oq, va, n, 0); + case Nctlqid: + if(n >= sizeof(cmd)) + n = sizeof(cmd)-1; + memmove(cmd, va, n); + cmd[n] = 0; + duartctl(p, cmd); + return n; + } } void @@ -839,18 +694,6 @@ duartremove(Chan *c) void duartwstat(Chan *c, char *p) { - USED(c); - USED(p); + USED(c, p); error(Eperm); } - -int -duartactive(void) -{ - int i; - - for(i = 0; i < nduartport; i++) - if(duartport[i].printing) - return 1; - return 0; -} diff --git a/power/devhs.c b/power/devhs.c deleted file mode 100644 index 48354b91c362bede91390e15d08e0b96cc6936f0..0000000000000000000000000000000000000000 --- a/power/devhs.c +++ /dev/null @@ -1,595 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" - -#include "io.h" - -typedef struct Hs Hs; - -enum { - Maxburst= 1023, /* maximum transmit burst size */ - Intvec= 0xd0, /* vme vector for interrupts */ - Intlevel= 5, /* level to interrupt on */ - Nhs= 1, - - /* - * csr flags - */ - ALIVE = 0x0001, - IENABLE = 0x0004, - EXOFLOW = 0x0008, - IRQ = 0x0010, - EMUTE = 0x0020, - EPARITY = 0x0040, - EFRAME = 0x0080, - EROFLOW = 0x0100, - REF = 0x0800, - XFF = 0x4000, - XHF = 0x8000, - - /* - * csr reset flags - */ - FORCEW = 0x0008, - NORESET = 0xFF00, - RESET = 0x0000, - - /* - * data flags - */ - CTL = 0x0100, - CHNO = 0x0200, - TXEOD = 0x0400, - NND = 0x8000, -}; - -#define NOW (MACHP(0)->ticks*MS2HZ) -#define IPL(x) ((x)<<5) - -struct Hs { - QLock; - - QLock xmit; - HSdev *addr; - int vec; /* interupt vector */ - Rendez r; /* output process */ - Rendez kr; /* input kernel process */ - int chan; /* current input channel */ - Queue *rq; /* read queue */ - uchar buf[1024]; /* bytes being collected */ - uchar *wptr; /* pointer into buf */ - ulong time; /* time byte in buf[0] arrived */ - int kstarted; /* true if kernel process started */ - int started; - - /* statistics */ - - ulong parity; /* parity errors */ - ulong rintr; /* rcv interrupts */ - ulong tintr; /* transmit interrupts */ - ulong in; /* bytes in */ - ulong out; /* bytes out */ -}; - -Hs hs[Nhs]; - -static void hsintr(int); -static void hskproc(void*); - -/* - * hs stream module definition - */ -static void hsoput(Queue*, Block*); -static void hsstopen(Queue*, Stream*); -static void hsstclose(Queue*); -Qinfo hsinfo = -{ - nullput, - hsoput, - hsstopen, - hsstclose, - "hs" -}; - -void -hsrestart(Hs *hp) -{ - HSdev *addr; - - addr = hp->addr; - - addr->csr = RESET; - wbflush(); - delay(20); - - /* - * set interrupt vector - * turn on device - * set forcew to a known value - * interrupt on level `Intlevel' - */ - addr->vector = hp->vec; - addr->csr = NORESET|IPL(Intlevel)|IENABLE|ALIVE; - wbflush(); - delay(1); - addr->csr = NORESET|IPL(Intlevel)|FORCEW|IENABLE|ALIVE; - wbflush(); - delay(1); - hp->started = 1; -} - -/* - * reset all vme boards - */ -void -hsreset(void) -{ - int i; - Hs *hp; - - for(i=0; iaddr = HSDEV+i; - hp->vec = Intvec+i; - hp->addr->csr = RESET; - setvmevec(hp->vec, hsintr); - } - wbflush(); - delay(20); -} - -void -hsinit(void) -{ -} - -/* - * enable the device for interrupts, spec is the device number - */ -Chan* -hsattach(char *spec) -{ - Hs *hp; - int i; - Chan *c; - - i = strtoul(spec, 0, 0); - if(i >= Nhs) - error(Ebadarg); - hp = &hs[i]; - if(!hp->started) - hsrestart(hp); - - c = devattach('h', spec); - c->dev = i; - c->qid.path = CHDIR; - return c; -} - -Chan* -hsclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -hswalk(Chan *c, char *name) -{ - return devwalk(c, name, 0, 0, streamgen); -} - -void -hsstat(Chan *c, char *dp) -{ - devstat(c, dp, 0, 0, streamgen); -} - -Chan* -hsopen(Chan *c, int omode) -{ - if(c->qid.path == CHDIR){ - if(omode != OREAD) - error(Eperm); - }else - streamopen(c, &hsinfo); - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -void -hscreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c); - USED(name); - USED(omode); - USED(perm); - error(Eperm); -} - -void -hsclose(Chan *c) -{ - if(c->qid.path != CHDIR) - streamclose(c); -} - -long -hsread(Chan *c, void *buf, long n, ulong offset) -{ - USED(offset); - return streamread(c, buf, n); -} - -long -hswrite(Chan *c, void *buf, long n, ulong offset) -{ - USED(offset); - return streamwrite(c, buf, n, 0); -} - -void -hsremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -hswstat(Chan *c, char *dp) -{ - USED(c); - USED(dp); - error(Eperm); -} - -/* - * the stream routines - */ - -/* - * create the kernel process for input - */ -static void -hsstopen(Queue *q, Stream *s) -{ - Hs *hp; - char name[32]; - - hp = &hs[s->dev]; - sprint(name, "hs%d", s->dev); - q->ptr = q->other->ptr = hp; - hp->rq = q; - kproc(name, hskproc, hp); -} - -/* - * ask kproc to die and wait till it happens - */ -static int -kdead(void *arg) -{ - Hs *hp; - - hp = (Hs *)arg; - return hp->kstarted == 0; -} -static void -hsstclose(Queue * q) -{ - Hs *hp; - - hp = (Hs *)q->ptr; - qlock(hp); - hp->rq = 0; - qunlock(hp); - while(waserror()) - ; - while(hp->kstarted){ - wakeup(&hp->kr); - sleep(&hp->r, kdead, hp); - } - poperror(); -} - -/* - * free all blocks of a message in `q', `bp' is the first block - * of the message - */ -static void -freemsg(Queue *q, Block *bp) -{ - for(; bp; bp = getq(q)){ - if(bp->flags & S_DELIM){ - freeb(bp); - return; - } - freeb(bp); - } -} - -/* - * return true if the output fifo is at least half empty. - * the implication is that it can take at least another 1000 byte burst. - */ -static int -halfempty(void *arg) -{ - HSdev *addr; - - addr = (HSdev*)arg; - return addr->csr & XHF; -} - -/* - * output a block - * - * the first 2 bytes of every message are the channel number, - * low order byte first. the third is a possible trailing control - * character. - */ -void -hsoput(Queue *q, Block *bp) -{ - HSdev *addr; - Hs *hp; - int burst; - int chan; - int ctl; - int n; - - if(bp->type != M_DATA){ - freeb(bp); - return; - } - if(BLEN(bp) < 3){ - bp = pullup(bp, 3); - if(bp == 0){ - print("hsoput pullup failed\n"); - return; - } - } - - /* - * get a whole message before handing bytes to the device - */ - if(!putq(q, bp)) - return; - - /* - * one transmitter at a time - */ - hp = (Hs *)q->ptr; - qlock(&hp->xmit); - if(waserror()){ - qunlock(&hp->xmit); - nexterror(); - } - addr = hp->addr; - - /* - * parse message - */ - bp = getq(q); - chan = CHNO | bp->rptr[0] | (bp->rptr[1]<<8); - ctl = bp->rptr[2]; - bp->rptr += 3; - - /* - * send the 8 bit data, burst are up to Maxburst (9-bit) bytes long - */ - if(!(addr->csr & XHF)) - sleep(&hp->r, halfempty, addr); -/* print("->%.2uo\n", CHNO|chan);/**/ - addr->data = CHNO|chan; - burst = Maxburst; - while(bp){ - if(burst == 0){ - addr->data = TXEOD; -/* print("->%.2uo\n", TXEOD); /**/ - if(!(addr->csr & XHF)) - sleep(&hp->r, halfempty, addr); -/* print("->%.2uo\n", CHNO|chan); /**/ - addr->data = CHNO|chan; - burst = Maxburst; - } - n = bp->wptr - bp->rptr; - if(n > burst) - n = burst; - burst -= n; - while(n--){ -/* print("->%.2uo\n", *bp->rptr); /**/ - addr->data = *bp->rptr++; - } - if(bp->rptr >= bp->wptr){ - if(bp->flags & S_DELIM){ - freeb(bp); - break; - } - freeb(bp); - bp = getq(q); - } - } - - /* - * send the control byte if there is one - */ - if(ctl){ -/* print("->%.2uo\n", CTL|ctl); /**/ - addr->data = CTL|ctl; - } - - /* - * start the fifo emptying - */ -/* print("->%.2uo\n", TXEOD); /**/ - addr->data = TXEOD; - - qunlock(&hp->xmit); - poperror(); -} - -/* - * return true if the input fifo is non-empty - */ -static int -notempty(void *arg) -{ - HSdev *addr; - - addr = (HSdev *)arg; - return addr->csr & REF; -} - -/* - * fill a block with what is currently buffered and send it upstream - */ -static void -upstream(Hs *hp, unsigned int ctl) -{ - int n; - Block *bp; - - n = hp->wptr - hp->buf; - bp = allocb(3 + n); - bp->wptr[0] = hp->chan; - bp->wptr[1] = hp->chan>>8; - bp->wptr[2] = ctl; - if(n) - memmove(&bp->wptr[3], hp->buf, n); - bp->wptr += 3 + n; - bp->flags |= S_DELIM; - PUTNEXT(hp->rq, bp); - hp->wptr = hp->buf; - hp->time = 0; -} - -/* - * Read bytes from the input fifo. Since we take an interrupt every - * time the fifo goes non-empty, we need to waste time to let the - * fifo fill up. - */ -static void -hskproc(void *arg) -{ - Hs *hp; - HSdev *addr; - unsigned int c; - int locked; - - hp = (Hs *)arg; - addr = hp->addr; - hp->kstarted = 1; - hp->wptr = hp->buf; - - locked = 0; - if(waserror()){ - if(locked) - qunlock(hp); - hp->kstarted = 0; - wakeup(&hp->r); - return; - } - - for(;;){ - /* - * die if the device is closed - */ - USED(locked); /* so locked = 0 and locked = 1 stay */ - qlock(hp); - locked = 1; - if(hp->rq == 0){ - qunlock(hp); - hp->kstarted = 0; - wakeup(&hp->r); - poperror(); - return; - } - - /* - * 0xFFFF means an empty fifo - */ - while((c = addr->data) != 0xFFFF){ - hp->in++; - if(c & CHNO){ - c &= 0x1FF; - if(hp->chan == c) - continue; - /* - * new channel, put anything saved upstream - */ - if(hp->wptr - hp->buf != 0) - upstream(hp, 0); - hp->chan = c; - } else if(c & NND){ - /* - * ctl byte, this ends a message - */ - upstream(hp, c); - } else { - /* - * data byte, put in local buffer - */ - if(hp->time == 0) - hp->time = NOW + 100; - *hp->wptr++ = c; - if(hp->wptr == &hp->buf[sizeof hp->buf]) - upstream(hp, 0); - } - } - if(hp->time && NOW >= hp->time) - upstream(hp, 0); - USED(locked); - qunlock(hp); - locked = 0; - - /* - * Sleep if input fifo empty. Make sure we don't hold onto - * any byte for more than 1/10 second. - */ - if(!(addr->csr & REF)){ - if(hp->wptr == hp->buf) - tsleep(&hp->kr, notempty, addr, 2000); - else - tsleep(&hp->kr, notempty, addr, 100); - } - } -} - -/* - * only one flavor interrupt. we have to use the less than half full - * and not empty bits to figure out whom to wake. - */ -static void -hsintr(int vec) -{ - ushort csr; - Hs *hp; - - hp = &hs[vec - Intvec]; - if(hp < hs || hp > &hs[Nhs]){ - print("bad hs vec\n"); - return; - } - csr = hp->addr->csr; - - if(csr & REF){ - hp->rintr++; - wakeup(&hp->kr); - } - if(csr & XHF){ - hp->tintr++; - wakeup(&hp->r); - } - if((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)){ - hp->parity++; - hsrestart(hp); - print("hs %d: reset, csr = 0x%ux\n", - vec - Intvec, csr); - } -} diff --git a/power/fns.h b/power/fns.h index 56f9fd08f81c4da416b0c224f5224b920a507829..f88d1e445598c0e0ded0e4d476579deddcfa87d7 100644 --- a/power/fns.h +++ b/power/fns.h @@ -9,14 +9,13 @@ void confprint(void); void confset(char*); int conschar(void); void dcflush(void*, ulong); -void debugger(void*); int duartactive(void); void duartenable0(void); void duartinit(void); void duartintr(void); void duartreset(void); void duartslave(void); -void duartspecial(int, IOQ*, IOQ*, int); +void duartspecial(int, int, Queue**, Queue**, int (*)(Queue*, int)); void duartxmit(int); void evenaddr(ulong); void faultmips(Ureg*, int, int); @@ -32,6 +31,7 @@ ulong getcallerpc(void*); void icflush(void *, ulong); void ioboardinit(void); void intr(Ureg*); +int iprint(char*, ...); void kbdchar(int); void kproftimer(ulong); void lanceintr(void); @@ -58,7 +58,7 @@ void puttlb(ulong, ulong); void puttlbx(int, ulong, ulong); int readlog(ulong, char*, ulong); void restfpregs(FPsave*, ulong); -#define screenputs syslog +#define screenputs(a, b) void scsiintr(int); void setvmevec(int, void (*)(int)); void sinit(void); diff --git a/power/ipdat.h b/power/ipdat.h deleted file mode 100644 index 37ecd18825c57dd84a4f614cf8d5555749d0a027..0000000000000000000000000000000000000000 --- a/power/ipdat.h +++ /dev/null @@ -1,440 +0,0 @@ -typedef struct Ipconv Ipconv; -typedef struct Ipifc Ipifc; -typedef struct Fragq Fragq; -typedef struct Ipfrag Ipfrag; -typedef ulong Ipaddr; -typedef struct Arpcache Arpcache; -typedef ushort Port; -typedef struct Udphdr Udphdr; -typedef struct Etherhdr Etherhdr; -typedef struct Reseq Reseq; -typedef struct Tcp Tcp; -typedef struct Tcpctl Tcpctl; -typedef struct Tcphdr Tcphdr; -typedef struct Timer Timer; - -struct Etherhdr { -#define ETHER_HDR 14 - uchar d[6]; - uchar s[6]; - uchar type[2]; - - /* Now we have the ip fields */ -#define ETHER_IPHDR 20 - uchar vihl; /* Version and header length */ - uchar tos; /* Type of service */ - uchar length[2]; /* packet length */ - uchar id[2]; /* Identification */ - uchar frag[2]; /* Fragment information */ - uchar ttl; /* Time to live */ - uchar proto; /* Protocol */ - uchar cksum[2]; /* Header checksum */ - uchar src[4]; /* Ip source */ - uchar dst[4]; /* Ip destination */ -}; - -/* Ethernet packet types */ -#define ET_IP 0x0800 - -/* A userlevel data gram */ -struct Udphdr { -#define UDP_EHSIZE 22 - uchar d[6]; /* Ethernet destination */ - uchar s[6]; /* Ethernet source */ - uchar type[2]; /* Ethernet packet type */ - uchar vihl; /* Version and header length */ - uchar tos; /* Type of service */ - uchar length[2]; /* packet length */ - uchar id[2]; /* Identification */ - uchar frag[2]; /* Fragment information */ - - /* Udp pseudo ip really starts here */ -#define UDP_PHDRSIZE 12 -#define UDP_HDRSIZE 20 - uchar Unused; - uchar udpproto; /* Protocol */ - uchar udpplen[2]; /* Header plus data length */ - uchar udpsrc[4]; /* Ip source */ - uchar udpdst[4]; /* Ip destination */ - uchar udpsport[2]; /* Source port */ - uchar udpdport[2]; /* Destination port */ - uchar udplen[2]; /* data length */ - uchar udpcksum[2]; /* Checksum */ -}; - -#define TCP_PKT (TCP_EHSIZE+TCP_IPLEN+TCP_PHDRSIZE) - -struct Tcphdr { -#define TCP_EHSIZE 14 - uchar d[6]; /* Ethernet destination */ - uchar s[6]; /* Ethernet source */ - uchar type[2]; /* Ethernet packet type */ -#define TCP_IPLEN 8 - uchar vihl; /* Version and header length */ - uchar tos; /* Type of service */ - uchar length[2]; /* packet length */ - uchar id[2]; /* Identification */ - uchar frag[2]; /* Fragment information */ - -#define TCP_PHDRSIZE 12 - uchar Unused; - uchar proto; - uchar tcplen[2]; - uchar tcpsrc[4]; - uchar tcpdst[4]; - -#define TCP_HDRSIZE 20 - uchar tcpsport[2]; - uchar tcpdport[2]; - uchar tcpseq[4]; - uchar tcpack[4]; - uchar tcpflag[2]; - uchar tcpwin[2]; - uchar tcpcksum[2]; - uchar tcpurg[2]; - - /* Options segment */ - uchar tcpopt[2]; - uchar tcpmss[2]; - }; - - - -struct Timer { - Timer *next; - Timer *prev; - int state; - int start; - int count; - void (*func)(void*); - void *arg; - }; - -struct Tcpctl { - QLock; - uchar state; /* Connection state */ - uchar type; /* Listening or active connection */ - uchar code; /* Icmp code */ - struct { - int una; /* Unacked data pointer */ - int nxt; /* Next sequence expected */ - int ptr; /* Data pointer */ - ushort wnd; /* Tcp send window */ - int up; /* Urgent data pointer */ - int wl1; - int wl2; - } snd; - int iss; - ushort cwind; - ushort ssthresh; - int resent; - struct { - int nxt; - ushort wnd; - int up; - } rcv; - int irs; - ushort mss; - int rerecv; - ushort window; - int max_snd; - int last_ack; - char backoff; - char flags; - char tos; - - Block *rcvq; - ushort rcvcnt; - - Block *rcvoobq; - ushort rcvoobcnt; - - Block *sndq; /* List of data going out */ - ushort sndcnt; /* Amount of data in send queue */ - - Block *sndoobq; /* List of blocks going oob */ - ushort sndoobcnt; /* Size of out of band queue */ - ushort oobmark; /* Out of band sequence mark */ - char oobflags; /* Out of band data flags */ - - Reseq *reseq; /* Resequencing queue */ - Timer timer; - Timer acktimer; /* Acknoledge timer */ - Timer rtt_timer; /* Round trip timer */ - int rttseq; /* Round trip sequence */ - int srtt; /* Shortened round trip */ - int mdev; /* Mean deviation of round trip */ -}; - -struct Tcp { - Port source; - Port dest; - int seq; - int ack; - char flags; - ushort wnd; - ushort up; - ushort mss; - }; - -struct Reseq { - Reseq *next; - Tcp seg; - Block *bp; - ushort length; - char tos; - }; - -/* An ip interface used for UDP/TCP/ARP/ICMP */ -struct Ipconv { - QLock; /* Ref count lock */ - int ref; - Qinfo *stproto; /* Stream protocol for this device */ - Ipaddr dst; /* Destination from connect */ - - Port psrc; /* Source port */ - Port pdst; /* Destination port */ - - uchar ptype; /* Source port type */ - Ipifc *ipinterface; /* Ip protocol interface */ - Queue *readq; /* Pointer to upstream read q */ - - QLock listenq; /* List of people waiting incoming cons */ - Rendez listenr; /* Some where to sleep while waiting */ - Ipconv *listen; - - char err; /* Async protocol error */ - int backlog; /* Maximum number of waiting connections */ - int curlog; /* Number of waiting connections */ - int contype; - Tcpctl tcpctl; /* Tcp control block */ -}; - -#define MAX_TIME 100000000 /* Forever */ -#define TCP_ACK 200 /* Timed ack sequence every 200ms */ - -#define URG 0x20 -#define ACK 0x10 -#define PSH 0x08 -#define RST 0x04 -#define SYN 0x02 -#define FIN 0x01 - -#define EOL_KIND 0 -#define NOOP_KIND 1 -#define MSS_KIND 2 - -#define MSS_LENGTH 4 -#define MSL2 10 -#define MSPTICK 200 -#define DEF_MSS 1024 -#define DEF_RTT 1000 -#define TCPOOB_HADDATA 1 -#define TCPOOB_HAVEDATA 2 - -#define TCP_PASSIVE 0 -#define TCP_ACTIVE 1 - -#define MAXBACKOFF 5 -#define FORCE 1 -#define CLONE 2 -#define RETRAN 4 -#define ACTIVE 8 -#define SYNACK 16 -#define AGAIN 8 -#define DGAIN 4 - -#define TIMER_STOP 0 -#define TIMER_RUN 1 -#define TIMER_EXPIRE 2 - -#define set_timer(t,x) (((t)->start) = (x)/MSPTICK) -#define dur_timer(t) ((t)->start) -#define read_timer(t) ((t)->count) -#define run_timer(t) ((t)->state == TIMER_RUN) - -enum { - CLOSED = 0, - LISTEN, - SYN_SENT, - SYN_RECEIVED, - ESTABLISHED, - FINWAIT1, - FINWAIT2, - CLOSE_WAIT, - CLOSING, - LAST_ACK, - TIME_WAIT - }; - -/* - * Ip interface structure. We have one for each active protocol driver - */ -struct Ipifc { - QLock; - int ref; - uchar protocol; /* Ip header protocol number */ - char name[NAMELEN]; /* Protocol name */ - void (*iprcv) (Ipconv *, Block *); /* Receive demultiplexor */ - Ipconv *connections; /* Connection list */ - int maxmtu; /* Maximum transfer unit */ - int minmtu; /* Minumum tranfer unit */ - int hsize; /* Media header size */ - Lock; -}; - -struct Fragq { - QLock; - Block *blist; - Fragq *next; - Ipaddr src; - Ipaddr dst; - ushort id; - }; - -struct Ipfrag { - ushort foff; - ushort flen; - }; - -struct Arpcache { - uchar status; /* Entry status */ - uchar type; /* Entry type */ - Ipaddr ip; /* Host byte order */ - uchar eip[4]; /* Network byte order */ - uchar et[6]; /* Ethernet address for this ip */ - int age; /* Entry timeout */ - Arpcache *hash; - Arpcache **hashhd; - Arpcache *frwd; - Arpcache *prev; -}; -#define ARP_FREE 0 -#define ARP_OK 1 -#define ARP_ASKED 2 -#define ARP_TEMP 0 -#define ARP_PERM 1 -#define Arphashsize 32 -#define ARPHASH(p) arphash[((p[2]^p[3])%Arphashsize)] -#define ARP_WAITMS 2500 /* Wait for arp replys */ - -#define IP_VER 0x40 /* Using IP version 4 */ -#define IP_HLEN 0x05 /* Header length in characters */ -#define IP_DF 0x4000 /* Don't fragment */ -#define IP_MF 0x2000 /* More fragments */ - -#define ICMP_ECHOREPLY 0 /* Echo Reply */ -#define ICMP_UNREACH 3 /* Destination Unreachable */ -#define ICMP_SOURCEQUENCH 4 /* Source Quench */ -#define ICMP_REDIRECT 5 /* Redirect */ -#define ICMP_ECHO 8 /* Echo Request */ -#define ICMP_TIMXCEED 11 /* Time-to-live Exceeded */ -#define ICMP_PARAMPROB 12 /* Parameter Problem */ -#define ICMP_TSTAMP 13 /* Timestamp */ -#define ICMP_TSTAMPREPLY 14 /* Timestamp Reply */ -#define ICMP_IREQ 15 /* Information Request */ -#define ICMP_IREQREPLY 16 /* Information Reply */ - -/* Sizes */ -#define IP_MAX 8192 /* Maximum Internet packet size */ -#define UDP_MAX (IP_MAX-ETHER_IPHDR) /* Maximum UDP datagram size */ -#define UDP_DATMAX (UDP_MAX-UDP_HDRSIZE) /* Maximum amount of udp data */ - -/* Protocol numbers */ -#define IP_UDPPROTO 17 -#define IP_TCPPROTO 6 - -/* Protocol port numbers */ -#define PORTALLOC 5000 /* First automatic allocated port */ -#define PRIVPORTALLOC 600 /* First priveleged port allocated */ -#define PORTMAX 30000 /* Last port to allocte */ - -/* Stuff to go in funs.h someday */ -Ipifc *newipifc(uchar, void (*)(Ipconv *, Block*), Ipconv *, int, int, int, char*); -void closeipifc(Ipifc*); -ushort ip_csum(uchar*); -int arp_lookup(uchar*, uchar*); -Ipaddr ipparse(char*); -void hnputs(uchar*, ushort); -void hnputl(uchar*, ulong); -ulong nhgetl(uchar*); -ushort nhgets(uchar*); -ushort ptcl_csum(Block*bp, int, int); -void ppkt(Block*); -void udprcvmsg(Ipconv *, Block*); -Block *btrim(Block*, int, int); -Block *ip_reassemble(int, Block*, Etherhdr*); -Ipconv *portused(Ipconv *, Port); -Port nextport(Ipconv *, Port); -void arp_enter(Arpentry*, int); -void arp_flush(void); -int arp_delete(char*); -void arplinkhead(Arpcache*); -Fragq *ipfragallo(void); -void ipfragfree(Fragq*); -void iproute(uchar*, uchar*); -void initfrag(int); -Block *copyb(Block*, int); -int ntohtcp(Tcp*, Block**); -void reset(Ipaddr, Ipaddr, char, ushort, Tcp*); -void proc_syn(Ipconv*, char, Tcp*); -void send_syn(Tcpctl*); -void tcp_output(Ipconv*); -int seq_within(int, int, int); -void update(Ipconv *, Tcp *); -int trim(Tcpctl *, Tcp *, Block **, ushort *); -void add_reseq(Tcpctl *, char, Tcp *, Block *, ushort); -void close_self(Ipconv *, int); -int seq_gt(int, int); -void appendb(Block **, Block *); -Ipconv *ip_conn(Ipconv *, Port, Port, Ipaddr dest, char proto); -void ipmkdir(Qinfo *, Dirtab *, Ipconv *); -int inb_window(Tcpctl *, int); -Block *htontcp(Tcp *, Block *, Tcphdr *); -void start_timer(Timer *); -void stop_timer(Timer *); -int copyupb(Block **, uchar *, int); -void init_tcpctl(Ipconv *); -void close_self(Ipconv *, int); -int iss(void); -int seq_within(int, int, int); -int seq_lt(int, int); -int seq_le(int, int); -int seq_gt(int, int); -int seq_ge(int, int); -void setstate(Ipconv *, char); -void tcpackproc(void*); -Block *htontcp(Tcp *, Block *, Tcphdr *); -int ntohtcp(Tcp *, Block **); -void extract_oob(Block **, Block **, Tcp *); -void get_reseq(Tcpctl *, char *, Tcp *, Block **, ushort *); -void state_upcall(Ipconv*, char oldstate, char newstate); -int backoff(int); -int dupb(Block **, Block *, int, int); -void tcp_input(Ipconv *, Block *); -void tcprcvwin(Ipconv *); -void open_tcp(Ipconv *, int, ushort, char); -void tcpflow(void*); -void tcp_timeout(void *); -void tcp_acktimer(void *); -Ipconv *ipclonecon(Chan *); -void iplisten(Chan *, Ipconv *, Ipconv *); - -#define fmtaddr(xx) (xx>>24)&0xff,(xx>>16)&0xff,(xx>>8)&0xff,xx&0xff -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define BLKIP(xp) ((Etherhdr *)((xp)->rptr)) -#define BLKFRAG(xp) ((Ipfrag *)((xp)->rptr)) -#define PREC(x) ((x)>>5 & 7) - -#define WORKBUF 64 - -extern Ipaddr Myip; -extern Ipaddr Mymask; -extern Ipaddr classmask[4]; -extern Ipconv *ipconv[]; -extern char *tcpstate[]; -extern Rendez tcpflowr; -extern Qinfo tcpinfo; -extern Qinfo ipinfo; -extern Qinfo udpinfo; diff --git a/power/main.c b/power/main.c index 9e6c6550bf92c965ce47b63756fd730c0c84e875..b6489d97067d8c7686dd56a4bf5b96960f964cd5 100644 --- a/power/main.c +++ b/power/main.c @@ -23,22 +23,24 @@ main(void) machinit(); active.exiting = 0; active.machs = 1; +iprint("Boot baby\n"); arginit(); confinit(); lockinit(); xinit(); + duartinit(); printinit(); - duartspecial(0, &printq, &kbdq, 9600); - print("\n\nBRAZIL\n"); + duartspecial(0, 9600, &kbdq, &printq, kbdcr2nl); +iprint("F:\n", printq); + print("\n\nBrazil\n"); pageinit(); tlbinit(); - vecinit(); procinit0(); + vecinit(); initseg(); clockinit(); ioboardinit(); chandevreset(); - streaminit(); swapinit(); userinit(); launchinit(); @@ -55,7 +57,6 @@ machinit(void) memset(m, 0, sizeof(Mach)); m->machno = n; m->stb = &stlb[n][0]; - duartinit(); m->ledval = 0xff; } @@ -307,12 +308,12 @@ launch(int n) void online(void) { - machinit(); lock(&active); active.machs |= 1<machno; unlock(&active); tlbinit(); + duartinit(); clockinit(); schedinit(); } @@ -636,9 +637,9 @@ lanceIO2setup(Lance *lp) * Start at 4k to avoid the initialization block and * descriptor rings. */ - lp->lrp = (Etherpkt*)(4*1024); + lp->lrp = (Lancepkt*)(4*1024); lp->ltp = lp->lrp + lp->nrrb; - lp->rp = (Etherpkt*)(((ulong)LANCERAM) + (ulong)lp->lrp); + lp->rp = (Lancepkt*)(((ulong)LANCERAM) + (ulong)lp->lrp); lp->tp = lp->rp + lp->nrrb; } @@ -670,11 +671,11 @@ lanceIO3setup(Lance *lp) * allocate some host memory for buffers and map it into lance * space */ - len = (lp->nrrb + lp->ntrb)*sizeof(Etherpkt); - lp->rp = (Etherpkt*)xspanalloc(len , BY2PG, 0); + len = (lp->nrrb + lp->ntrb)*sizeof(Lancepkt); + lp->rp = (Lancepkt*)xspanalloc(len , BY2PG, 0); lp->tp = lp->rp + lp->nrrb; x = (ulong)lp->rp; - lp->lrp = (Etherpkt*)(x & 0xFFF); + lp->lrp = (Lancepkt*)(x & 0xFFF); lp->ltp = lp->lrp + lp->nrrb; index = LANCEINDEX; for(y = x+len; x < y; x += 0x1000){ diff --git a/power/mmu.c b/power/mmu.c index 64eb500b3b910a4d8d79ccbcd6ed1ddda676eced..3212315a65a49bd476a08f74a6147d9e40692f1d 100644 --- a/power/mmu.c +++ b/power/mmu.c @@ -70,10 +70,10 @@ putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) splhi(); ctl = &pg->cachectl[m->machno]; - if(*ctl == PG_TXTFLUSH) { + if(*ctl & PG_TXTFLUSH) { dcflush((void*)pg->pa, BY2PG); icflush((void*)pg->pa, BY2PG); - *ctl = PG_NOFLUSH; + *ctl &= ~PG_TXTFLUSH; } tp = up->pidonmach[m->machno]; diff --git a/power/trap.c b/power/trap.c index 670636e7b5ea5fa5c6f08da6860a8f7658610b40..230844dfcc89ddfbabf210caf415b611d4eee7e4 100644 --- a/power/trap.c +++ b/power/trap.c @@ -245,10 +245,12 @@ intr(Ureg *ur) any = 1; if(v & (1<<2)) lanceintr(); +/* if(v & (1<<1)) scsiintr(1); if(v & (1<<0)) scsiintr(0); +*/ } } /*