~kris/9p

9hist

c37268ee3be0685df1e704722dd947cdcc81332c — David du Colombier 35 years ago 9dddf4b
Plan 9 from Bell Labs 1990-12-28
4 files changed, 198 insertions(+), 72 deletions(-)

M port/devlance.c
M power/dat.h
M power/fns.h
M power/main.c
M port/devlance.c => port/devlance.c +47 -72
@@ 24,17 24,6 @@ enum {
#define NOW (MACHP(0)->ticks*MS2HZ)

/*
 *  Ethernet packet buffers.  These must also be in lance addressible RAM.
 */
typedef struct {
	uchar d[6];
	uchar s[6];
	uchar type[2];
	uchar data[1500];
	uchar crc[4];
} Pkt;

/*
 *  Communication with the lance is via a transmit and receive ring of
 *  message descriptors.  The Initblock contains pointers to and sizes of
 *  these rings.  The rings must be in RAM addressible by the lance


@@ 70,12 59,11 @@ typedef struct Lancemem
	Msg	tmr[Ntrb];		/* transmit message ring */

	/*
	 *  packet buffers (for IO2 version)
	 *  packet buffers (for SGI IO2 version only)
	 */
	Pkt	rp[Nrrb];
	Pkt	tp[Ntrb];
	Etherpkt	rp[Nrrb];
	Etherpkt	tp[Ntrb];
} Lancemem;
#define LANCEMEM ((Lancemem*)0)

/*
 *  Some macros for dealing with lance memory addresses.  The lance splits


@@ 83,6 71,16 @@ typedef struct Lancemem
 */
#define HADDR(a) ((((ulong)(a))>>16)&0xFF)
#define LADDR(a) (((ulong)a)&0xFFFF)

/*
 *  The following functions exist to sidestep a quirk in the SGI IO3 lance
 *  interface.  In all other processors, the lance's initialization block and
 *  descriptor rings look like normal memory.  In the SGI IO3, the CPU sees a
 *  6 byte pad twixt all lance memory shorts.  Therefore, we use the following
 *  macros to compute the address whenever accessing the lance memory to make
 *  the code portable.  Sic transit gloria.
 */
#define LANCEMEM ((Lancemem*)0)
#define MPs(a) (*(short *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0)))
#define MPus(a) (*(ushort *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0)))



@@ 147,8 145,8 @@ typedef struct {
	int	kstarted;
	Debqueue dq;

	Pkt	*rp;		/* receive buffers */
	Pkt	*tp;		/* transmit buffers */
	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 */



@@ 256,7 254,7 @@ sprintpacket(char *buf, Trace *t)
 *  save a message in a circular queue for later debugging
 */
void
lancedebq(char tag, Pkt *p, int len)
lancedebq(char tag, Etherpkt *p, int len)
{
	Trace *t;



@@ 338,7 336,7 @@ static void
lanceoput(Queue *q, Block *bp )
{
	int n, len;
	Pkt *p;
	Etherpkt *p;
	Msg *m;

	if(bp->type == M_CTL){


@@ 375,7 373,7 @@ lanceoput(Queue *q, Block *bp )
	 */
	len = 0;
	while(bp = getq(q)){
		if(sizeof(Pkt) - len >= (n = BLEN(bp))){
		if(sizeof(Etherpkt) - len >= (n = BLEN(bp))){
			memcpy(((uchar *)p)+len, bp->rptr, n);
			len += n;
		} else


@@ 425,42 423,42 @@ 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
 */
void
lancereset(void)
{
	int i;
	ushort *sp;
	ulong x;
	int index;
	static int already;

	/*
	 *  so that we don't have to indirect through constants
	 *  stop the lance
	 */
	l.rap = LANCERAP;
	l.rdp = LANCERDP;
	*l.rap = 0;
	*l.rdp = STOP;

	/*
	 *  allocate the send and receive buffers and map them into
	 *  the lance's address space.
	 */
	if(already == 0){
		already = 1;
		if(ioid < IO3R1){
			/*
			 *  toggle lance's reset line
			 */
			MODEREG->promenet &= ~1;
			MODEREG->promenet |= 1;

			l.lanceram = LANCERAM;
			l.lanceend = LANCEEND;
			l.lm = (Lancemem *)0;
			l.sep = 1;

			/*
			 *  allocate packet buffers in lance memory
			 */
			for(i = 0; i < Nrrb; i++)


@@ 468,25 466,14 @@ lancereset(void)
			for(i = 0; i < Ntrb; i++)
				l.tpa[i] = (uchar *)&l.lm->tp[i];

			l.rp = ((Lancemem *)LANCERAM)->rp;
			l.tp = ((Lancemem *)LANCERAM)->tp;
			l.rp = ((Lancemem *)l.lanceram)->rp;
			l.tp = ((Lancemem *)l.lanceram)->tp;
		} else {
			/*
			 *  toggle lance's reset line
			 */
			MODEREG->promenet |= 1;
			MODEREG->promenet &= ~1;

			l.lanceram = LANCE3RAM;
			l.lanceend = LANCE3END;
			l.lm = (Lancemem *)0x800000;
			l.sep = 4;

			/*
			 *  allocate packet buffers in MP bus memory
			 *  and map it into lance space
			 */
			l.rp = (Pkt *)ialloc((Nrrb + Ntrb)*sizeof(Pkt), 1);
			l.rp = (Etherpkt *)ialloc((Nrrb + Ntrb)*sizeof(Etherpkt), 1);
			l.tp = l.rp + Nrrb;
			index = 0x1E00;
			for(i = 0; i < Nrrb; i++){


@@ 504,12 491,6 @@ lancereset(void)
		}
	}

	/*
	 *  run through all lance memory to set parity
	 */
	for(sp = l.lanceram; sp < l.lanceend; sp += l.sep)
		*sp = 0;

}

/*


@@ 520,7 501,7 @@ static void
lancestart(void)
{
	int i;
	Pkt *p;
	Etherpkt *p;
	Lancemem *lm = LANCEMEM;
	Msg *m;



@@ 536,15 517,9 @@ lancestart(void)
	 *  the id prom has them in reverse order, the init
	 *  structure wants them in byte swapped order
	 */
	MPus(lm->etheraddr[0]) = (LANCEID[16]&0xff00)|((LANCEID[20]>>8)&0xff);
	MPus(lm->etheraddr[1]) = (LANCEID[8]&0xff00)|((LANCEID[12]>>8)&0xff);
	MPus(lm->etheraddr[2]) = (LANCEID[0]&0xff00)|((LANCEID[4]>>8)&0xff);
	l.ea[0] = LANCEID[20]>>8;
	l.ea[1] = LANCEID[16]>>8;
	l.ea[2] = LANCEID[12]>>8;
	l.ea[3] = LANCEID[8]>>8;
	l.ea[4] = LANCEID[4]>>8;
	l.ea[5] = LANCEID[0]>>8;
	MPus(lm->etheraddr[0]) = (l.ea[1]<<8) | l.ea[0];
	MPus(lm->etheraddr[1]) = (l.ea[3]<<8) | l.ea[2];
	MPus(lm->etheraddr[2]) = (l.ea[5]<<8) | l.ea[4];

	/*
	 *  ignore multicast addresses


@@ 559,7 534,7 @@ lancestart(void)
	 */
	m = lm->rmr;
	for(i = 0; i < Nrrb; i++, m++){
		MPs(m->size) = -sizeof(Pkt);
		MPs(m->size) = -sizeof(Etherpkt);
		MPus(m->cntflags) = 0;
		MPus(m->laddr) = LADDR(l.rpa[i]);
		MPus(m->flags) = HADDR(l.rpa[i]);


@@ 860,7 835,7 @@ void
lancekproc(void *arg)
{
	Block *bp;
	Pkt *p;
	Etherpkt *p;
	Ethertype *e;
	int t;
	int len;


@@ 930,7 905,7 @@ stage:
			 *  stage the next input buffer
			 */
			m = &(lm->rmr[l.rc]);
			MPs(m->size) = -sizeof(Pkt);
			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]);

M power/dat.h => power/dat.h +13 -0
@@ 9,6 9,7 @@ typedef struct Dirtab	Dirtab;
typedef struct Env	Env;
typedef struct Envp	Envp;
typedef struct Envval	Envval;
typedef struct Etherpkt	Etherpkt;
typedef struct FPsave	FPsave;
typedef struct Label	Label;
typedef struct List	List;


@@ 408,6 409,7 @@ struct Block
	uchar	*base;		/* start of the buffer */
	uchar	flags;
	uchar	type;
	ulong	va;		/* virtual address if mapped for a dev */
};

/* flag bits */


@@ 489,6 491,17 @@ enum {
};

/*
 *  Ethernet packet buffers.
 */
struct Etherpkt {
	uchar d[6];
	uchar s[6];
	uchar type[2];
	uchar data[1500];
	uchar crc[4];
};

/*
 *  nonet constants
 */
enum {

M power/fns.h => power/fns.h +1 -0
@@ 91,6 91,7 @@ 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	lanceinit(void);
void	lanceintr(void);

M power/main.c => power/main.c +137 -0
@@ 39,6 39,25 @@ char sysname[64];
 */
int ioid;

/*
 *  lance memory mapping
 */
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;

extern int	ioid;

char	user[NAMELEN] = "bootes";

void


@@ 132,6 151,8 @@ ioboardinit(void)
{
	long i;
	int maxlevel;
	ushort *sp;
	uchar ea[6];

	ioid = *IOID;
	if(ioid >= IO3R1)


@@ 178,6 199,122 @@ ioboardinit(void)
	 *  enable all interrupts on the IO2
	 */
	*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;
	} 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;
	}

	/*
	 *  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