From 22fd6629344521b83f06a0bea8ea94d989667139 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 29 Dec 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-12-29 --- port/devlance.c | 129 ++++++++++++---------------- port/devnonet.c | 13 ++- port/stnoether.c | 6 ++ port/stream.c | 2 +- power/fns.h | 8 +- power/main.c | 215 ++++++++++++++++++++++------------------------- 6 files changed, 175 insertions(+), 198 deletions(-) diff --git a/port/devlance.c b/port/devlance.c index ad75e097c16c19679f32399498497f9b09954260..974064b612bc2d67373d16142b6a03f37dee9ffb 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -23,6 +23,8 @@ enum { #define NOW (MACHP(0)->ticks*MS2HZ) +int plance; + /* * Communication with the lance is via a transmit and receive ring of * message descriptors. The Initblock contains pointers to and sizes of @@ -57,12 +59,6 @@ typedef struct Lancemem */ Msg rmr[Nrrb]; /* recieve message ring */ Msg tmr[Ntrb]; /* transmit message ring */ - - /* - * packet buffers (for SGI IO2 version only) - */ - Etherpkt rp[Nrrb]; - Etherpkt tp[Ntrb]; } Lancemem; /* @@ -128,7 +124,6 @@ typedef struct { int sep; /* separaqtion between shorts in lance ram as seen by host */ ushort *lanceram; /* start of lance ram as seen by host */ - ushort *lanceend; /* end of lance ram as seen by host */ Lancemem *lm; /* start of lance memory as seen by lance */ Rendez rr; /* rendezvous for an input buffer */ @@ -145,10 +140,10 @@ typedef struct { int kstarted; Debqueue dq; - Etherpkt *rp; /* receive buffers */ - Etherpkt *tp; /* transmit buffers */ - uchar *rpa[Nrrb]; /* receive buffer address in lance space */ - uchar *tpa[Ntrb]; /* transmit buffer address in lance space */ + Etherpkt *rp; /* receive buffers (host address) */ + Etherpkt *tp; /* transmit buffers (host address) */ + Etherpkt *lrp; /* receive buffers (lance address) */ + Etherpkt *ltp; /* transmit buffers (lance address) */ /* sadistics */ @@ -266,7 +261,7 @@ lancedebq(char tag, Etherpkt *p, int len) memcpy(&(t->p), p, sizeof(Dpkt)); l.dq.next = (l.dq.next+1) % Ndpkt; unlock(&l.dq); -/* { + if(plance){ char buf[1024]; if(p->d[0] != 0xff){ sprintpacket(buf, t); @@ -405,10 +400,11 @@ lanceoput(Queue *q, Block *bp ) m = &(LANCEMEM->tmr[l.tc]); MPs(m->size) = -len; MPus(m->cntflags) = 0; - MPus(m->laddr) = LADDR(l.tpa[l.tc]); - MPus(m->flags) = OWN|STP|ENP|HADDR(l.tpa[l.tc]); + MPus(m->laddr) = LADDR(&l.ltp[l.tc]); + MPus(m->flags) = OWN|STP|ENP|HADDR(&l.ltp[l.tc]); l.tc = TSUCC(l.tc); *l.rdp = INEA|TDMD; /**/ + wbflush(); qunlock(&l.tlock); } @@ -423,23 +419,7 @@ enum { Dirtab lancedir[Ndir]; /* - * configure the lance - */ -void -lanceconfig(void *ramstart, void *ramend, void *rap, void *rdp, int sep, - void *lancemem, uchar* ea) -{ - l.lanceram = ramstart; - l.lanceend = ramend; - l.rap = rap; - l.rdp = rdp; - l.sep = sep; - l.lm = lancemem; /* where lance sees its memory start */ - memcpy(l.ea, ea, 6); -} - -/* - * stop the lance, disable all ring buffers, and free all staged rcv buffers + * stop the lance and allocate buffers */ void lancereset(void) @@ -448,6 +428,11 @@ lancereset(void) ulong x; int index; static int already; + ushort *lanceaddr; + ushort *hostaddr; + + l.rap = LANCERAP; + l.rdp = LANCERDP; /* * stop the lance @@ -457,38 +442,32 @@ lancereset(void) if(already == 0){ already = 1; - if(ioid < IO3R1){ - /* - * allocate packet buffers in lance memory - */ - for(i = 0; i < Nrrb; i++) - l.rpa[i] = (uchar *)&l.lm->rp[i]; - for(i = 0; i < Ntrb; i++) - l.tpa[i] = (uchar *)&l.lm->tp[i]; - - l.rp = ((Lancemem *)l.lanceram)->rp; - l.tp = ((Lancemem *)l.lanceram)->tp; - } else { - /* - * allocate packet buffers in MP bus memory - * and map it into lance space - */ - l.rp = (Etherpkt *)ialloc((Nrrb + Ntrb)*sizeof(Etherpkt), 1); - l.tp = l.rp + Nrrb; - index = 0x1E00; - for(i = 0; i < Nrrb; i++){ - x = (ulong)&l.rp[i]; - *WRITEMAP = (index<<16) | (x>>12)&0xFFFF; - l.rpa[i] = (uchar *)((i<<12) | (x & 0xFFF)); - index++; - } - for(i = 0; i < Ntrb; i++){ - x = (ulong)&l.tp[i]; - *WRITEMAP = (index<<16) | (x>>12)&0xFFFF; - l.tpa[i] = (uchar *)(((i+Nrrb)<<12) | (x & 0xFFF)); - index++; - } - } + + /* + * lance ethernet address + */ + lanceeaddr(l.ea); + + /* + * lance init block and descriptor rings + */ + lancectlmem(&hostaddr, &lanceaddr, &l.sep, sizeof(Lancemem)); + l.lanceram = hostaddr; + l.lm = (Lancemem*)lanceaddr; + + /* + * lance receive buffers + */ + lancepktmem(&hostaddr, &lanceaddr, Nrrb*sizeof(Etherpkt)); + l.rp = (Etherpkt*)hostaddr; + l.lrp = (Etherpkt*)lanceaddr; + + /* + * lance xmt buffers + */ + lancepktmem(&hostaddr, &lanceaddr, Ntrb*sizeof(Etherpkt)); + l.tp = (Etherpkt*)hostaddr; + l.ltp = (Etherpkt*)lanceaddr; } } @@ -536,8 +515,8 @@ lancestart(void) for(i = 0; i < Nrrb; i++, m++){ MPs(m->size) = -sizeof(Etherpkt); MPus(m->cntflags) = 0; - MPus(m->laddr) = LADDR(l.rpa[i]); - MPus(m->flags) = HADDR(l.rpa[i]); + MPus(m->laddr) = LADDR(&l.lrp[i]); + MPus(m->flags) = HADDR(&l.lrp[i]); } MPus(lm->rdralow) = LADDR(l.lm->rmr); MPus(lm->rdrahigh) = (LogNrrb<<13)|HADDR(l.lm->rmr); @@ -558,8 +537,8 @@ lancestart(void) for(i = 0; i < Ntrb; i++, m++){ MPs(m->size) = 0; MPus(m->cntflags) = 0; - MPus(m->laddr) = LADDR(l.tpa[i]); - MPus(m->flags) = HADDR(l.tpa[i]); + MPus(m->laddr) = LADDR(&l.ltp[i]); + MPus(m->flags) = HADDR(&l.ltp[i]); } MPus(lm->tdralow) = LADDR(l.lm->tmr); MPus(lm->tdrahigh) = (LogNtrb<<13)|HADDR(l.lm->tmr); @@ -583,6 +562,7 @@ lancestart(void) /* * initialize lance, turn on interrupts, turn on transmit and rcv. */ + wbflush(); *l.rap = 0; *l.rdp = INEA|INIT|STRT; /**/ } @@ -807,8 +787,9 @@ lanceintr(void) /* * look for rcv'd packets, just wakeup the input process */ - if(l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0) + if(l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0){ wakeup(&l.rr); + } /* * look for xmitt'd packets, wake any process waiting for a @@ -907,18 +888,16 @@ stage: m = &(lm->rmr[l.rc]); MPs(m->size) = -sizeof(Etherpkt); MPus(m->cntflags) = 0; - MPus(m->laddr) = LADDR(l.rpa[l.rc]); - MPus(m->flags) = OWN|HADDR(l.rpa[l.rc]); + MPus(m->laddr) = LADDR(&l.lrp[l.rc]); + MPus(m->flags) = OWN|HADDR(&l.lrp[l.rc]); l.rc = RSUCC(l.rc); + wbflush(); } sleep(&l.rr, isinput, 0); } } -void -lanceparity(void) +lancetoggle() { - print("lance DRAM parity error lmp=%ux\n", l.lmp); - MODEREG->promenet &= ~4; - MODEREG->promenet |= 4; + plance ^= 1; } diff --git a/port/devnonet.c b/port/devnonet.c index e32f462cc360c7d777d939d0d5cc0166667b8ce4..035a9360eb09d6522ab20e22471e2f8f07d74c03 100644 --- a/port/devnonet.c +++ b/port/devnonet.c @@ -6,16 +6,17 @@ #include "io.h" #include "errno.h" -#define DPRINT if(0) +#define DPRINT if(pnonet)print #define NOW (MACHP(0)->ticks*MS2HZ) static Noifc *noifc; +int pnonet; enum { /* * tuning parameters */ - MSrexmit = 500, /* retranmission interval in ms */ + MSrexmit = 500, /* retranmission interval in ms */ MSack = 50, /* ms to sit on an ack */ /* @@ -102,7 +103,7 @@ nonetreset(void) * allocate the interfaces */ noifc = (Noifc *)ialloc(sizeof(Noifc) * conf.nnoifc, 0); - for(i = 0; i < conf.nnoconv; i++) + for(i = 0; i < conf.nnoifc; i++) noifc[i].conv = (Noconv *)ialloc(sizeof(Noconv) * conf.nnoconv, 0); /* @@ -1040,6 +1041,7 @@ nonetrcvmsg(Noconv *cp, Block *bp) * if a new call request comes in on a connected channel, hang up the call */ if(h->mid==0 && (f & NO_NEWCALL) && cp->state==Cconnected){ + DPRINT("new call on connected channel\n"); freeb(bp); hangup(cp); return; @@ -1228,3 +1230,8 @@ nonetcksum(Block *bp, int offset) hp->sum[0] = s; return s & 0xffff; } + +nonettoggle() +{ + pnonet ^= 1; +} diff --git a/port/stnoether.c b/port/stnoether.c index 2fb8d85cb907e7b4d54a274de8c66f336d3ad338..0fc5612af63893c6fac6958ff794dd768d18756a 100644 --- a/port/stnoether.c +++ b/port/stnoether.c @@ -12,6 +12,9 @@ #include "io.h" #include "errno.h" +#define DPRINT if(pnonet)print +extern int pnonet; + static void etherparse(uchar*, char*); static void noetherclose(Queue*); static void noetheriput(Queue*, Block*); @@ -148,6 +151,7 @@ noetheriput(Queue *q, Block *bp) */ ep = &ifc->conv[conf.nnoconv]; for(cp = &ifc->conv[0]; cp < ep; cp++){ + DPRINT("checking %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n", cp->rcvcircuit, ph->d[0], ph->d[1], ph->d[2], ph->d[3], ph->d[4], ph->d[5]); if(circuit==cp->rcvcircuit && canqlock(cp)){ ph = (Etherhdr *)(cp->media->rptr); if(circuit == cp->rcvcircuit @@ -166,6 +170,7 @@ noetheriput(Queue *q, Block *bp) * if not a new call, then its misaddressed */ if((h->flag & NO_NEWCALL) == 0) { + DPRINT("misaddressed nonet packet %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n", circuit, h->s[0], h->s[1], h->s[2], h->s[3], h->s[4], h->s[5]); freeb(bp); return; } @@ -173,6 +178,7 @@ noetheriput(Queue *q, Block *bp) /* * Queue call in a circular queue and wakeup a listener. */ + DPRINT("call in\n"); lock(&ifc->lock); next = (ifc->wptr + 1) % Nnocalls; if(next == ifc->rptr){ diff --git a/port/stream.c b/port/stream.c index 4231a11c922a3a2c65db19d45f427b3ed8ac35bd..41946f5f0b68254de22c5236508cf49788027757 100644 --- a/port/stream.c +++ b/port/stream.c @@ -214,7 +214,6 @@ allocb(ulong size) tsleep(&bcp->r, isblock, (void *)bcp, 250); qunlock(bcp); poperror(); - splhi(); lock(bcp); } bp = bcp->first; @@ -242,6 +241,7 @@ freeb(Block *bp) { Bclass *bcp; int tries; + int x; if((bp->flags&S_CLASS) >= Nclass) panic("freeb class"); diff --git a/power/fns.h b/power/fns.h index 39076d4ca9c6f159873a4bc9cc20f5cfd8c443ed..fa787e6080364e17270333a6855421e6894b9947 100644 --- a/power/fns.h +++ b/power/fns.h @@ -91,12 +91,13 @@ void isdir(Chan*); void kbdchar(int); void kproc(char*, void(*)(void*), void*); void launchinit(void); -void lanceconfig(void*, void*, void*, void*, int, void*, uchar*); -void lancereset(void); +void lancectlmem(ushort**, ushort**, int*, int); +void lanceeaddr(uchar*); void lanceinit(void); void lanceintr(void); void lanceparity(void); -void lanceinit(void); +void lancepktmem(ushort**, ushort**, int); +void lancereset(void); void launch(int); void lights(int); void lock(Lock*); @@ -194,6 +195,7 @@ long syscall(Ureg*); void sysloginit(void); void syslog(char*, int); void tlbinit(void); +Block *tolance(Block*, int); void touser(void *); void tsleep(Rendez*, int (*)(void*), void*, int); void twakeme(Alarm*); diff --git a/power/main.c b/power/main.c index 21124944a1f0ccbd4d66132202ea34ed3cf28017..489f390a81d47941bc022e3a073dd269a916bb44 100644 --- a/power/main.c +++ b/power/main.c @@ -40,23 +40,16 @@ char sysname[64]; int ioid; /* - * lance memory mapping + * lance memory allocation */ -typedef struct Lancemap Lancemap; -struct Lancemap -{ - int rused; /* first used receive map */ - int rnext; /* next receive map to use */ - int rtot; - - int tused; /* first used transmit map */ - int tnext; /* next transmit map to use */ - int ttot; - Rendez tr; /* where to wait for a transmit map */ -}; -Lancemap lm; +ushort *lancelmem; /* next free lance mem as seen by lance */ +ushort *lancehmem; /* next free lance mem as seen by host */ +ushort *lancehend; -extern int ioid; +/* + * next free lance memory map + */ +int lancemap; char user[NAMELEN] = "bootes"; @@ -152,7 +145,6 @@ ioboardinit(void) long i; int maxlevel; ushort *sp; - uchar ea[6]; ioid = *IOID; if(ioid >= IO3R1) @@ -200,121 +192,27 @@ ioboardinit(void) */ *IO2SETMASK = 0xff; - /* - * get our ether addr out of the non-volatile ram - */ - ea[0] = LANCEID[20]>>8; - ea[1] = LANCEID[16]>>8; - ea[2] = LANCEID[12]>>8; - ea[3] = LANCEID[8]>>8; - ea[4] = LANCEID[4]>>8; - ea[5] = LANCEID[0]>>8; - /* * reset the lance. - * configure the lance software parameters. * run through all lance memory to set parity. */ if(ioid >= IO3R1){ MODEREG->promenet |= 1; MODEREG->promenet &= ~1; - lanceconfig(LANCE3RAM, LANCE3END, LANCERAP, LANCERDP, 4, - (void*)0x800000, ea); for(sp = LANCE3RAM; sp < LANCE3END; sp += 2) *sp = 0; + lancehmem = LANCE3RAM; + lancehend = LANCE3END; + lancelmem = (ushort*)0x800000; } else { MODEREG->promenet &= ~1; MODEREG->promenet |= 1; - lanceconfig(LANCERAM, LANCEEND, LANCERAP, LANCERDP, 1, - (void*)0x0, ea); for(sp = LANCERAM; sp < LANCEEND; sp += 1) *sp = 0; + lancehmem = LANCERAM; + lancehend = LANCEEND; + lancelmem = (ushort*)0; } - - /* - * initialize the map/buffer use - */ - lm.ttot = 128; - lm.rtot = 128; - lm.rnext = lm.rused = lm.tnext = lm.tused = 0; -} - -/* - * map/copy a list of blocks to somewhere the lance can access - * - * if bp==0, just create a block and map it in - */ -static int -isomap(void *x) -{ - int next; - - next = (int)x; - return x != lm.tused; -} -Block * -lancemap(Block *bp, int len) -{ - Block *nbp, *tbp; - int next; - ulong x; - - if(bp == 0){ - next = lm.rnext+1 % lm.rtot; - if(ioid >= IO3R1){ - bp = allocb(sizeof(Etherpkt)); - x = (ulong)(bp->wptr); - *WRITEMAP = (next<<16) | ((x>>12)&0xFFFF); - bp->va = (next<<12) | (x & 0xFFF)); - } else { - bp = allocb(0); - x = (ulong)(LANCEMEM+4*1024+next*sizeof(Etherpkt)); - bp->va = x; - bp->rptr = (uchar *)x; - bp->wptr = (uchar *)x; - } - lm.rnext = next; - return bp; - } - - if(ioid >= IO3R1){ - for(nbp = bp; nbp; nbp = nbp->next){ - next = lm.tnext+1 % lm.ttot; - if(next == lm.tused) - sleep(&lm.tr, isomap, (void *)next); - x = (ulong)(nbp->rptr); - *WRITEMAP = ((lm.rtot + next)<<16) | ((x>>12)&0xFFFF); - nbp->va = ((lm.rtot + next)<<12) | (x & 0xFFF)); - lm.tnext = next; - } - } else { - tbp = bp; - bp = allocb(0); - next = lm.tnext+1 % lm.ttot; - if(next == lm.tused) - sleep(&lm.tr, isomap, (void *)next); - x = (ulong)(LANCEMEM+4*1024+(next+lm.rtot)*sizeof(Etherpkt)); - bp->va = x; - bp->rptr = (uchar *)x; - bp->wptr = (uchar *)x; - for(nbp = tbp; nbp; nbp = nbp->next){ - n = BLEN(nbp); - if(BLEN(bp) + n < sizeof(Etherpkt)) - n = sizeof(Etherpkt) - BLEN(bp); - memcpy(bp->wptr, nbp->rptr, n); - bp->wptr += n; - } - freeb(tbp); - lm.tnext = next; - } -} - -/* - * get a block back from the lance - */ -Block * -lanceunmap(Block *bp) -{ } void @@ -834,3 +732,88 @@ arginit(void) _argv = argv; argsize = ssize; } + +/* + * get our ether addr out of the non-volatile ram + */ +void +lanceeaddr(uchar *ea) +{ + ea[0] = LANCEID[20]>>8; + ea[1] = LANCEID[16]>>8; + ea[2] = LANCEID[12]>>8; + ea[3] = LANCEID[8]>>8; + ea[4] = LANCEID[4]>>8; + ea[5] = LANCEID[0]>>8; +} + +/* + * allocate command memory for the initialization block + * and descriptor rings. + * + * pass back the host's address of the memory, the lance's address + * of the memory, and the span (in shorts) of each short as seen + * by the host. The latter is only for a peculiarity of the SGI IO3. + * It is normally 1. + */ +void +lancectlmem(ushort **hostaddr, ushort **lanceaddr, int *sep, int len) +{ + len = (len + sizeof(ushort) - 1)/sizeof(ushort); + if(ioid >= IO3R1) + *sep = 4; + else + *sep = 1; + if(len+lancehmem > lancehend) + panic("lancecmdmem"); + *lanceaddr = lancelmem; + *hostaddr = lancehmem; + lancelmem += len; + lancehmem += len; +} + +/* + * allocate packet buffer memory for the lance. + * + * pass back the host's address of the memory and the lance's address + * of the memory. + */ +void +lancepktmem(ushort **hostaddr, ushort **lanceaddr, int len) +{ + ulong x; + ulong y; + + if(ioid >= IO3R1){ + /* + * allocate some host mempry and map it into lance + * space + */ + *hostaddr = (ushort*)ialloc(len, 1); + x = (ulong)*hostaddr; + *lanceaddr = (ushort*)((lancemap<<12) | (x & 0xFFF)); + for(y = x; y < x+len; y += 0x1000){ + *WRITEMAP = ((0x1E00+lancemap)<<16) | (y>>12)&0xFFFF; + lancemap++; + } + } else { + /* + * allocate lance memory + */ + len = (len + sizeof(ushort) - 1)/sizeof(ushort); + if(len+lancehmem > lancehend) + panic("lancecmdmem"); + *lanceaddr = lancelmem; + *hostaddr = lancehmem; + lancelmem += len; + lancehmem += len; + } +} + +void +lanceparity(void) +{ + print("lance DRAM parity error\n"); + MODEREG->promenet &= ~4; + MODEREG->promenet |= 4; +}