~kris/9p

9hist

22fd6629344521b83f06a0bea8ea94d989667139 — David du Colombier 35 years ago c37268e
Plan 9 from Bell Labs 1990-12-29
6 files changed, 175 insertions(+), 198 deletions(-)

M port/devlance.c
M port/devnonet.c
M port/stnoether.c
M port/stream.c
M power/fns.h
M power/main.c
M port/devlance.c => port/devlance.c +54 -75
@@ 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;
}

M port/devnonet.c => port/devnonet.c +10 -3
@@ 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;
}

M port/stnoether.c => port/stnoether.c +6 -0
@@ 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){

M port/stream.c => port/stream.c +1 -1
@@ 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");

M power/fns.h => power/fns.h +5 -3
@@ 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*);

M power/main.c => power/main.c +99 -116
@@ 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)


@@ 201,120 193,26 @@ 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;
}