~kris/9p

9hist

bfecc837910a5f86bd1336eeda521ca75ca4f2ef — David du Colombier 34 years ago 295722f
Plan 9 from Bell Labs 1992-05-01
4 files changed, 122 insertions(+), 111 deletions(-)

M pc/devether.c
M pc/vga.c
M port/portdat.h
M port/sysproc.c
M pc/devether.c => pc/devether.c +76 -65
@@ 14,8 14,11 @@ typedef struct Ctlr Ctlr;

struct Hw {
	int	addr;			/* interface address */
	void	*ram;			/* interface shared memory address */
	int	ramsz;			/* interface shared memory size */
	uchar	*ram;			/* interface shared memory address */
	int	size;
	uchar	tstart;
	uchar	pstart;
	uchar	pstop;
	void	(*reset)(Ctlr*);
	void	(*init)(Ctlr*);
	void	(*mode)(Ctlr*, int);


@@ 43,7 46,7 @@ struct Buffer {
	uchar	owner;
	uchar	busy;
	ushort	len;
	Etherpkt pkt;
	uchar	pkt[sizeof(Etherpkt)];
};

enum {


@@ 250,7 253,6 @@ etheroput(Queue *q, Block *bp)
	sleep(&cp->tr, isobuf, cp);

	tb = &cp->tb[cp->th];
	p = &tb->pkt;

	/*
	 * copy message into buffer


@@ 258,7 260,7 @@ etheroput(Queue *q, Block *bp)
	len = 0;
	for(nbp = bp; nbp; nbp = nbp->next){
		if(sizeof(Etherpkt) - len >= (n = BLEN(nbp))){
			memmove(((uchar *)p)+len, nbp->rptr, n);
			memmove(tb->pkt+len, nbp->rptr, n);
			len += n;
		} else
			print("no room damn it\n");


@@ 270,16 272,11 @@ etheroput(Queue *q, Block *bp)
	 * pad the packet (zero the pad)
	 */
	if(len < ETHERMINTU){
		memset(((char*)p)+len, 0, ETHERMINTU-len);
		memset(tb->pkt+len, 0, ETHERMINTU-len);
		len = ETHERMINTU;
	}

	/*
	 * give packet a local address
	 */
	memmove(p->s, cp->ea, sizeof(cp->ea));

	/*
	 * set up the transmit buffer and 
	 * start the transmission
	 */


@@ 392,12 389,14 @@ typefill(Chan *c, char *p, int n)
}

static void
etherup(Ctlr *cp, Etherpkt *p, int len)
etherup(Ctlr *cp, void *data, int len)
{
	Block *bp;
	Type *tp;
	Etherpkt *p;
	int t;
	Type *tp;
	Block *bp;

	p = data;
	t = (p->type[0]<<8)|p->type[1];
	for(tp = &cp->type[0]; tp < &cp->type[NType]; tp++){
		/*


@@ 464,7 463,7 @@ etherkproc(void *arg)
		 */
		while(bp = getq(&cp->lbq)){
			cp->inpackets++;
			etherup(cp, (Etherpkt*)bp->rptr, BLEN(bp));
			etherup(cp, bp->rptr, BLEN(bp));
			freeb(bp);
		}



@@ 474,7 473,7 @@ etherkproc(void *arg)
		while(cp->rb[cp->rh].owner == Host){
			cp->inpackets++;
			rb = &cp->rb[cp->rh];
			etherup(cp, &rb->pkt, rb->len);
			etherup(cp, rb->pkt, rb->len);
			rb->owner = Interface;
			cp->rh = NEXT(cp->rh, Nrb);
		}


@@ 528,8 527,7 @@ etherinit(void)
	/*
	 * put the receiver online
	 * and start the kproc
	 */
	
	 */	
	(*cp->hw->online)(cp, 1);
	if(cp->kproc == 0){
		sprint(cp->name, "ether%dkproc", ctlrno);


@@ 599,6 597,14 @@ typedef struct {
#define IN(hw, m)	inb((hw)->addr+OFFSETOF(Wd8013, m))
#define OUT(hw, m, x)	outb((hw)->addr+OFFSETOF(Wd8013, m), (x))

typedef struct {
	uchar	status;
	uchar	next;
	uchar	len0;
	uchar	len1;
	uchar	data[256-4];
} Ring;

/*
 */
static void


@@ 608,24 614,17 @@ wd8013reset(Ctlr *cp)
	int i;
	uchar msr;

	cp->rb = ialloc(sizeof(Buffer)*Nrb, 0);
	cp->nrb = Nrb;
	cp->tb = ialloc(sizeof(Buffer)*Ntb, 0);
	cp->tb = ialloc(sizeof(Buffer)*Ntb, 1);
	cp->ntb = Ntb;
	cp->rb = ialloc(sizeof(Buffer)*Nrb, 1);
	cp->nrb = Nrb;

	msr = IN(hw, msr);
	OUT(hw, msr, 0x40|msr);
{
int addr = hw->addr;

for(i = 0; i < 16; i++){
    print("#%2.2ux ", inb(addr));
    addr++;
}
print("\n");
}
	for(i = 0; i < sizeof(cp->ea); i++)
		cp->ea[i] = IN(hw, lan[i]);

	(*hw->init)(cp);
	setvec(Ethervec, hw->intr);
}


@@ 639,9 638,7 @@ wd8013init(Ctlr *cp)
{
	Hw *hw = cp->hw;
	int i;
	uchar bnry;

print("init %d %d\n", HOWMANY(sizeof(Etherpkt), 256), HOWMANY(hw->ramsz, 256));
	OUT(hw, w.cr, 0x21);			/* Page0|RD2|STP */
	OUT(hw, w.dcr, 0x48);			/* FT1|LS */
	OUT(hw, w.rbcr0, 0);


@@ 649,17 646,16 @@ print("init %d %d\n", HOWMANY(sizeof(Etherpkt), 256), HOWMANY(hw->ramsz, 256));
	OUT(hw, w.rcr, 0x04);			/* AB */
	OUT(hw, w.tcr, 0x20);			/* LB0 */

	bnry = HOWMANY(sizeof(Etherpkt), 256);
	OUT(hw, w.bnry, bnry);
	OUT(hw, w.pstart, bnry);
	OUT(hw, w.pstop, HOWMANY(hw->ramsz, 256));
	OUT(hw, w.bnry, hw->pstart);
	OUT(hw, w.pstart, hw->pstart);
	OUT(hw, w.pstop, hw->pstop);
	OUT(hw, w.isr, 0xFF);
	OUT(hw, w.imr, 0x1F);			/* OVWE|TXEE|RXEE|PTXE|PRXE */

	OUT(hw, w.cr, 0x61);			/* Page1|RD2|STP */
	for(i = 0; i < sizeof(cp->ea); i++)
		OUT(hw, par[i], cp->ea[i]);
	OUT(hw, curr, bnry+1);
	OUT(hw, curr, hw->pstart+1);

	OUT(hw, w.cr, 0x22);			/* Page0|RD2|STA */
	OUT(hw, w.tpsr, 0);


@@ 688,26 684,21 @@ wd8013online(Ctlr *cp, int on)
	OUT(cp->hw, w.tcr, 0);
}

static ulong wraps;

static void
wd8013receive(Ctlr *cp)
{
	Hw *hw = cp->hw;
	Buffer *rb;
	uchar bnry, curr, next;
	typedef struct Ring {
		uchar	status;
		uchar	next;
		uchar	len0;
		uchar	len1;
		uchar	data[256-4];
	} Ring;
	Ring *p;
	int len0, len1;
	int len;

	bnry = IN(hw, r.bnry);
	next = NEXT(bnry, HOWMANY(hw->ramsz, 256));
	if(next == 0)
		next = HOWMANY(sizeof(Etherpkt), 256);
	next = bnry+1;
	if(next >= hw->pstop)
		next = hw->pstart;
	for(;;){
		OUT(hw, w.cr, 0x62);		/* Page1|RD2|STA */
		curr = IN(hw, curr);


@@ 716,30 707,31 @@ wd8013receive(Ctlr *cp)
			break;
		cp->inpackets++;
		p = &((Ring*)hw->ram)[next];
		len0 = (p->len1<<8)|p->len0-4;
		len1 = 0;
		len = (p->len1<<8)|p->len0-4;
if(len > sizeof(Etherpkt))
    print("!");

		rb = &cp->rb[cp->ri];
		if(rb->owner == Interface){
			rb->len = len0;
			rb->len = len;
			/*copy in packet*/
			if(p->data+len0 >= (uchar*)hw->ram+hw->ramsz){
				len1 = p->data+len0 - (uchar*)hw->ram+hw->ramsz;
				len0 = (uchar*)hw->ram+hw->ramsz - p->data;
			if(p->data+len >= hw->ram+hw->size){
wraps++;
				len = hw->ram+hw->size - p->data;
				memmove(rb->pkt+len,
					&((Ring*)hw->ram)[hw->pstart],
					p->data+rb->len - hw->ram+hw->size);
			}
			memmove((uchar*)&rb->pkt, p->data, len0);
			if(len1)
				memmove((uchar*)&rb->pkt+len0,
					(uchar*)hw->ram+ROUNDUP(sizeof(Etherpkt), 256),
					len1);
			memmove(rb->pkt, p->data, len);
			rb->owner = Host;
			cp->ri = NEXT(cp->ri, Nrb);
		}

p->status = 0;
		next = p->next;
		bnry = next-1;
		if(bnry < HOWMANY(sizeof(Etherpkt), 256))
			bnry = HOWMANY(hw->ramsz, 256)-1;
		if(bnry < hw->pstart)
			bnry = hw->pstop-1;
		OUT(hw, w.bnry, bnry);
	}
}


@@ 751,20 743,18 @@ wd8013transmit(Ctlr *cp)
	Buffer *tb;
	int s;

print("transmit\n");
	s = splhi();
	tb = &cp->tb[cp->ti];
	if(tb->busy == 0 && tb->owner == Interface){
		hw = cp->hw;
print("transmit memove %lux %lux, %d\n", hw->ram, &tb->pkt, tb->len);
		memmove(hw->ram, &tb->pkt, tb->len);
tb->len = tb->len+1 & ~1;
		memmove(hw->ram, tb->pkt, tb->len);
		OUT(hw, w.tbcr0, tb->len & 0xFF);
		OUT(hw, w.tbcr1, (tb->len>>8) & 0xFF);
		OUT(hw, w.cr, 0x26);		/* Page0|RD2|TXP|STA */
		tb->busy = 1;
	}
	splx(s);
print("transmit done\n");
}

static void


@@ 814,7 804,10 @@ wd8013intr(Ureg *ur)
static Hw wd8013 = {
	0x360,					/* I/O base address */
	KZERO|0xC8000,				/* shared memory address */
	8*1024,					/* shared memory size */
	8*1024,
	0,
	HOWMANY(sizeof(Etherpkt), 256),
	HOWMANY(8*1024, 256),
	wd8013reset,
	wd8013init,
	wd8013mode,


@@ 827,4 820,22 @@ static Hw wd8013 = {
void
consdebug(void)
{
	Ctlr *cp = &ctlr[0];
	Hw *hw = cp->hw;
	Buffer *bp;
	uchar bnry, curr;

	print("th%d ti%d rh%d ri%d\n",
		cp->th, cp->ti, cp->rh, cp->ri);
	bp = &cp->tb[cp->ti];
	print("t: owner %d busy %d len %d\n",
		bp->owner, bp->busy, bp->len);
	bnry = IN(hw, r.bnry);
	OUT(hw, w.cr, 0x62);
	curr = IN(hw, curr);
	OUT(hw, w.cr, 0x22);
	print("bnry %d, curr %d\n", bnry, curr);
	print("in %d out %d crcs %d oerrs %d frames %d overflows %d buffs %d wraps %d\n",
		cp->inpackets, cp->outpackets, cp->crcs, cp->oerrs, cp->frames,
		cp->overflows, cp->buffs, wraps);
}

M pc/vga.c => pc/vga.c +8 -8
@@ 90,19 90,19 @@ VGAmode mode12 =
};

/*
 *  800x600 display, 16 bit color 
 *  VESA standard (?) 800x600 display, 16 bit color 
 */
VGAmode mode41 = 
VGAmode mode6a = 
{
	/* general */
	0xe7, 0x00,  /* 0x70, 0x04, these are read-only */
	0x2f, 0x00,  /* 0x70, 0x04, these are read-only */
	/* sequence */
	0x03, 0x01, 0x0f, 0x00, 0x06,
	/* crt */
	0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
	0x00, 0x40, 0x0d, 0x0e, 0x00, 0x00, 0x07, 0x80,
	0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
	0xff,
	0x7f, 0x63, 0x64, 0x9d, 0x67, 0x92, 0x77, 0xf0,
	0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x5d, 0x8f, 0x57, 0x32, 0x00, 0x5b, 0x74, 0xc3,
	0xff,  
	/* graphics */
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
	0xff,


@@ 248,7 248,7 @@ screeninit(void)
	int c;
	ulong *l;

	setmode(&mode41);
	setmode(&mode12);

	/*
	 *  swizzle the font longs.

M port/portdat.h => port/portdat.h +10 -10
@@ 449,16 449,16 @@ struct Waitq

enum
{
	FORKNSG		= (1<<0),
	FORKEVG		= (1<<1),
	FORKFDG		= (1<<2),
	FORKNTG		= (1<<3),
	FORKPCS		= (1<<4),
	FORKMEM		= (1<<5),
	FORKNOW		= (1<<6),
	FORKCNSG	= (1<<10),
	FORKCEVG	= (1<<11),
	FORKCFDG	= (1<<12)
	RFNAMEG		= (1<<0),
	RFENVG		= (1<<1),
	RFFDG		= (1<<2),
	RFNOTEG		= (1<<3),
	RFPROC		= (1<<4),
	RFMEM		= (1<<5),
	RFNOWAIT	= (1<<6),
	RFCNAMEG	= (1<<10),
	RFCENVG		= (1<<11),
	RFCFDG		= (1<<12)
};

/*

M port/sysproc.c => port/sysproc.c +28 -28
@@ 30,13 30,13 @@ long
sys__fork__(ulong *arg)
{
	USED(arg);
	return rfork(FORKFDG|FORKPCS);
	return rfork(RFFDG|RFPROC);
}

long
sys__rfork__(ulong *arg)
{
	return rfork(arg[0]|FORKPCS);
	return rfork(arg[0]|RFPROC);
}

/* This call will obsolete fork */


@@ 64,46 64,46 @@ rfork(ulong flag)
	int lastvar;	

	p = u->p;
	if((flag&FORKPCS) == 0) {
		if(flag & (FORKNSG|FORKCNSG)) {
			if((flag & (FORKNSG|FORKCNSG)) == (FORKNSG|FORKCNSG))
	if((flag&RFPROC) == 0) {
		if(flag & (RFNAMEG|RFCNAMEG)) {
			if((flag & (RFNAMEG|RFCNAMEG)) == (RFNAMEG|RFCNAMEG))
				error(Ebadarg);
			opg = p->pgrp;
			p->pgrp = newpgrp();
			if(flag & FORKNSG)
			if(flag & RFNAMEG)
				pgrpcpy(p->pgrp, opg);
			else
				*p->pgrp->crypt = *opg->crypt;
			closepgrp(opg);
		}
		if(flag & (FORKEVG|FORKCEVG)) {
			if((flag & (FORKEVG|FORKCEVG)) == (FORKEVG|FORKCEVG))
		if(flag & (RFENVG|RFCENVG)) {
			if((flag & (RFENVG|RFCENVG)) == (RFENVG|RFCENVG))
				error(Ebadarg);
			oeg = p->egrp;
			p->egrp = newegrp();
			if(flag & FORKEVG)
			if(flag & RFENVG)
				envcpy(p->egrp, oeg);
			closeegrp(oeg);
		}
		if(flag & FORKFDG)
		if(flag & RFFDG)
			error(Ebadarg);
		if(flag & FORKCFDG) {
		if(flag & RFCFDG) {
			ofg = p->fgrp;
			p->fgrp = newfgrp();
			closefgrp(ofg);
		}
		if(flag & FORKNTG)
		if(flag & RFNOTEG)
			p->noteid = incref(&noteidalloc);
		if(flag & (FORKMEM|FORKNOW))
		if(flag & (RFMEM|RFNOWAIT))
			error(Ebadarg);
		return 0;
	}
	/* Check flags before we commit */
	if((flag & (FORKFDG|FORKCFDG)) == (FORKFDG|FORKCFDG))
	if((flag & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
		error(Ebadarg);
	if((flag & (FORKNSG|FORKCNSG)) == (FORKNSG|FORKCNSG))
	if((flag & (RFNAMEG|RFCNAMEG)) == (RFNAMEG|RFCNAMEG))
		error(Ebadarg);
	if((flag & (FORKEVG|FORKCEVG)) == (FORKEVG|FORKCEVG))
	if((flag & (RFENVG|RFCENVG)) == (RFENVG|RFCENVG))
		error(Ebadarg);

	p = newproc();


@@ 123,7 123,7 @@ rfork(ulong flag)
	kunmap(k);

	/* Make a new set of memory segments */
	n = flag & FORKMEM;
	n = flag & RFMEM;
	for(i = 0; i < NSEG; i++)
		if(parent->seg[i])
			p->seg[i] = dupseg(parent->seg[i], n);


@@ 132,11 132,11 @@ rfork(ulong flag)
	incref(u->dot);	

	/* File descriptors */
	if(flag & (FORKFDG|FORKCFDG)) {
		if(flag & FORKFDG)
	if(flag & (RFFDG|RFCFDG)) {
		if(flag & RFFDG)
			p->fgrp = dupfgrp(parent->fgrp);
		else
		if(flag & FORKCFDG)
		if(flag & RFCFDG)
			p->fgrp = newfgrp();
	}
	else {


@@ 145,13 145,13 @@ rfork(ulong flag)
	}

	/* Process groups */
	if(flag & (FORKNSG|FORKCNSG)) {	
		if(flag & FORKNSG) {
	if(flag & (RFNAMEG|RFCNAMEG)) {	
		if(flag & RFNAMEG) {
			p->pgrp = newpgrp();
			pgrpcpy(p->pgrp, parent->pgrp);
		}
		else
		if(flag & FORKCNSG) {
		if(flag & RFCNAMEG) {
			p->pgrp = newpgrp();
			*p->pgrp->crypt = *parent->pgrp->crypt;
		}


@@ 162,13 162,13 @@ rfork(ulong flag)
	}

	/* Environment group */
	if(flag & (FORKEVG|FORKCEVG)) {
		if(flag & FORKEVG) {
	if(flag & (RFENVG|RFCENVG)) {
		if(flag & RFENVG) {
			p->egrp = newegrp();
			envcpy(p->egrp, parent->egrp);
		}
		else
		if(flag & FORKCEVG)
		if(flag & RFCENVG)
			p->egrp = newegrp();
	}
	else {


@@ 194,9 194,9 @@ rfork(ulong flag)

	p->parent = parent;
	p->parentpid = parent->pid;
	if(flag&FORKNOW)
	if(flag&RFNOWAIT)
		p->parentpid = 1;
	if((flag&FORKNTG) == 0)
	if((flag&RFNOTEG) == 0)
		p->noteid = parent->noteid;

	p->fpstate = parent->fpstate;