~kris/9p

9hist

8aa2a47a237023d338999967195fa76b21cd395e — David du Colombier 32 years ago 22c3b72
Plan 9 from Bell Labs 1993-11-20
7 files changed, 111 insertions(+), 63 deletions(-)

M pc/devether.c
M pc/ether8003.c
M pc/ether8390.c
M port/devcons.c
M port/page.c
M port/portdat.h
M port/swap.c
M pc/devether.c => pc/devether.c +44 -0
@@ 94,6 94,46 @@ etherwstat(Chan *c, char *dp)
	netifwstat(ether[c->dev], c, dp);
}

void
etherrloop(Ether *ctlr, Etherpkt *pkt, long len)
{
	ushort type;
	Netfile *f, **fp, **ep;

	type = (pkt->type[0]<<8)|pkt->type[1];
	ep = &ctlr->f[Ntypes];
	for(fp = ctlr->f; fp < ep; fp++){
		f = *fp;
		if(f && (f->type == type || f->type < 0)){
			switch(qproduce(f->in, pkt->d, len)){

			case -1:
				print("etherrloop overflow\n");
				break;

			case -2:
				print("etherrloop memory\n");
				break;
			}
		}
	}
}

static int
etherwloop(Ether *ctlr, Etherpkt *pkt, long len)
{
	int s, different;

	different = memcmp(pkt->d, pkt->s, sizeof(pkt->s));
	if(different && memcmp(pkt->d, ctlr->bcast, sizeof(pkt->d)))
		return 0;

	s = splhi();
	etherrloop(ctlr, pkt, len);
	splx(s);
	return !different;
}

long
etherwrite(Chan *c, void *buf, long n, ulong offset)
{


@@ 107,6 147,9 @@ etherwrite(Chan *c, void *buf, long n, ulong offset)
	if(NETTYPE(c->qid.path) != Ndataqid)
		return netifwrite(ctlr, c, buf, n);

	if(etherwloop(ctlr, buf, n))
		return n;

	qlock(&ctlr->tlock);
	if(waserror()){
		qunlock(&ctlr->tlock);


@@ 204,6 247,7 @@ etherreset(void)

			ether[ctlrno] = ctlr;
			ctlr = 0;
			break;
		}
	}
	if(ctlr)

M pc/ether8003.c => pc/ether8003.c +0 -5
@@ 57,10 57,6 @@ static int intrmap[] = {
	9, 3, 5, 7, 10, 11, 15, 4,
};

static uchar debugea[6] = {
	0x00, 0x60, 0x8c, 0x00, 0x1a, 0x42,
};

/*
 * Get configuration parameters, enable memory.
 * There are opportunities here for buckets of code.


@@ 188,7 184,6 @@ reset(Ether *ether)
	 * ethernet address.
	 */
	dp8390reset(ether);
memmove(ether->ea, debugea, 6);
	dp8390setea(ether);

	return 0;

M pc/ether8390.c => pc/ether8390.c +28 -11
@@ 446,10 446,7 @@ receive(Ether *ether)
			for(fp = ether->f; fp < ep; fp++) {
				f = *fp;
				if(f && (f->type == type || f->type < 0))
{
print("Q%d|", len);
					qproduce(f->in, &ether->rpkt, len);
}
			}
		}



@@ 473,10 470,11 @@ istxavail(void *arg)
}

static long
write(Ether *ether, void *buf, long n)
write(Ether *ether, void *buf, long len)
{
	Dp8390 *dp8390;
	ulong port;
	Etherpkt *pkt;

	dp8390 = ether->private;
	port = dp8390->dp8390;


@@ 486,18 484,38 @@ write(Ether *ether, void *buf, long n)
		print("dp8390: transmitter jammed\n");
		return 0;
	}
	ether->tlen = n;
	ether->tlen = len;

	/*
	 * If it's a shared-memory interface, copy the packet
	 * directly to the shared-memory area. Otherwise, copy
	 * it to a staging buffer so the I/O-port write can be
	 * done in one.
	 */
	if(dp8390->ram)
		memmove((void*)(ether->mem+dp8390->tstart*Dp8390BufSz), buf, n);
		pkt = (Etherpkt*)(ether->mem+dp8390->tstart*Dp8390BufSz);
	else
		dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, buf, n);
		pkt = &ether->tpkt;
	memmove(pkt, buf, len);

	/*
	 * Give the packet a source address and make sure it
	 * is of minimum length.
	 */
	memmove(pkt->s, ether->ea, sizeof(ether->ea));
	if(len < ETHERMINTU){
		memset(pkt->d+len, 0, ETHERMINTU-len);
		len = ETHERMINTU;
	}

	if(dp8390->ram == 0)
		dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, pkt, len);

	dp8390outb(port+Tbcr0, n & 0xFF);
	dp8390outb(port+Tbcr1, (n>>8) & 0xFF);
	dp8390outb(port+Tbcr0, len & 0xFF);
	dp8390outb(port+Tbcr1, (len>>8) & 0xFF);
	dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta);

	return n;
	return len;
}

static void


@@ 551,7 569,6 @@ interrupt(Ether *ether)
	 */
	dp8390outb(port+Imr, 0x00);
	while(isr = dp8390inb(port+Isr)){
print("I%2.2ux|", isr);

		if(isr & Ovw){
			overflow(ether);

M port/devcons.c => port/devcons.c +2 -5
@@ 654,11 654,8 @@ consread(Chan *c, void *buf, long n, ulong offset)
		return n;

	case Qswap:
		k = 0;
		for(i = 0; i < NCOLOR; i++)
			k += palloc.freecol[i];

		sprint(tmp, "%d/%d memory %d/%d swap\n", palloc.user-k,
		sprint(tmp, "%d/%d memory %d/%d swap\n",
			palloc.user-palloc.freecount,
			palloc.user, conf.nswap-swapalloc.free, conf.nswap);

		return readstr(offset, buf, n, tmp);

M port/page.c => port/page.c +28 -28
@@ 29,7 29,7 @@ pageinit(void)
		p->next = p+1;
		p->pa = palloc.p0;
		p->color = color;
		palloc.freecol[color]++;
		palloc.freecount++;
		color = (color+1)%NCOLOR;
		palloc.p0 += BY2PG;
		palloc.np0--;


@@ 40,7 40,7 @@ pageinit(void)
		p->next = p+1;
		p->pa = palloc.p1;
		p->color = color;
		palloc.freecol[color]++;
		palloc.freecount++;
		color = (color+1)%NCOLOR;
		palloc.p1 += BY2PG;
		palloc.np1--;


@@ 70,18 70,17 @@ newpage(int clear, Segment **s, ulong va)
	KMap *k;
	int i, hw, dontalloc, color;

retry:
	lock(&palloc);

	lock(&palloc);
retry:
	color = getpgcolor(va);
	hw = swapalloc.highwater;
	for(;;) {
		if(palloc.freecol[color] > hw/NCOLOR)
		if(palloc.freecount > hw)
			break;
		if(up->kp && palloc.freecol[color] > 0)
		if(up->kp && palloc.freecount > 0)
			break;

		palloc.wanted++;
		unlock(&palloc);
		dontalloc = 0;
		if(s && *s) {


@@ 89,17 88,17 @@ retry:
			*s = 0;
			dontalloc = 1;
		}
		qlock(&palloc.pwait[color]); /* Hold memory requesters here */
		qlock(&palloc.pwait);	/* Hold memory requesters here */

		while(waserror())	/* Ignore interrupts */
			;

		kickpager();
		tsleep(&palloc.r[color], ispages, (void*)color, 1000);
		tsleep(&palloc.r, ispages, 0, 1000);

		poperror();

		qunlock(&palloc.pwait[color]);
		qunlock(&palloc.pwait);

		/*
		 * If called from fault and we lost the segment from


@@ 111,15 110,18 @@ retry:
			return 0;

		lock(&palloc);
		palloc.wanted--;
	}

	/* First try for out colour */
	for(p = palloc.head; p; p = p->next)
		if(p->color == color)
			break;

	if(p == 0)
		panic("newpage");
	if(p == 0) {
		p = palloc.head;
		memset(p->cachectl, PG_DATFLUSH, sizeof(p->cachectl));
		p->color = color;
	}

	if(p->prev) 
		p->prev->next = p->next;


@@ 132,12 134,15 @@ retry:
		palloc.tail = p->prev;


	palloc.freecol[color]--;
	palloc.freecount--;
	unlock(&palloc);

	lock(p);
	if(p->ref != 0) {	/* lookpage has priority on steal */
		unlock(p);
		print("stolen\n");
		lock(&palloc);
		palloc.freecount++;
		goto retry;
	}



@@ 161,17 166,13 @@ retry:
int
ispages(void *p)
{
	int color;

	color = (int)p;
	return palloc.freecol[color] >= swapalloc.highwater/NCOLOR;
	USED(p);
	return palloc.freecount >= swapalloc.highwater;
}

void
putpage(Page *p)
{
	Rendez *r;

	if(onswap(p)) {
		putswap(p);
		return;


@@ 209,10 210,9 @@ putpage(Page *p)
		p->prev = 0;
	}

	palloc.freecol[p->color]++;
	r = &palloc.r[p->color];
	if(r->p != 0)
		wakeup(r);
	palloc.freecount++;
	if(palloc.r.p != 0)
		wakeup(&palloc.r);

	unlock(&palloc);
	unlock(p);


@@ 225,13 225,13 @@ auxpage()

	lock(&palloc);
	p = palloc.head;
	if(palloc.freecol[p->color] < swapalloc.highwater/NCOLOR) {
	if(palloc.freecount < swapalloc.highwater) {
		unlock(&palloc);
		return 0;
	}
	p->next->prev = 0;
	palloc.head = p->next;
	palloc.freecol[p->color]--;
	palloc.freecount--;
	unlock(&palloc);

	lock(p);


@@ 259,7 259,7 @@ duppage(Page *p)				/* Always call with p locked */

	lock(&palloc);
	/* No freelist cache when memory is very low */
	if(palloc.freecol[p->color] < swapalloc.highwater/NCOLOR) {
	if(palloc.freecount < swapalloc.highwater) {
		unlock(&palloc);
		uncachepage(p);	
		return;


@@ 419,7 419,7 @@ lookpage(Image *i, ulong daddr)
				else
					palloc.tail = f->prev;

				palloc.freecol[f->color]--;
				palloc.freecount--;
			}
			unlock(&palloc);


M port/portdat.h => port/portdat.h +3 -4
@@ 455,13 455,12 @@ struct Palloc
	ulong	np0, np1;		/* number of pages in bank 0/1 */
	Page	*head;			/* most recently used */
	Page	*tail;			/* least recently used */
	ulong	freecol[NCOLOR];	/* how many pages on free list now */
	ulong	freecount;		/* how many pages on free list now */
	ulong	user;			/* how many user pages */
	Page	*hash[PGHSIZE];
	Lock	hashlock;
	Rendez	r[NCOLOR];		/* Sleep for free mem */
	QLock	pwait[NCOLOR];		/* Queue of procs waiting for memory */
	int	wanted;			/* Do the wakeup at free */
	Rendez	r;			/* Sleep for free mem */
	QLock	pwait;			/* Queue of procs waiting for memory */
	ulong	cmembase;		/* Key memory */
	ulong	cmemtop;
};

M port/swap.c => port/swap.c +6 -10
@@ 118,7 118,9 @@ loop:
		if(p->state == Dead || p->kp)
			continue;

		/* don't swap out programs from devroot.c */
		/* don't swap out programs from devroot.c - they
		 * supply important system services
		 */
		img = p->seg[SG_TEXT]->image;
		if(img && devchar[img->c->type] == '/')
			continue;


@@ 155,9 157,8 @@ loop:

			/* Emulate the old system if no swap channel */
			print("no physical memory\n");
			tsleep(&swapalloc.r, return0, 0, 1000);
			for(i = 0; i < NCOLOR; i++)
				wakeup(&palloc.r[i]);
			tsleep(&swapalloc.r, return0, 0, 5000);
			wakeup(&palloc.r);
		}
	}
	goto loop;


@@ 326,13 327,8 @@ executeio(void)
int
needpages(void *p)
{
	int i;

	USED(p);
	for(i = 0; i < NCOLOR; i++)
		if(palloc.freecol[i] < swapalloc.headroom/NCOLOR)
			return 1;
	return 0;
	return palloc.freecount < swapalloc.headroom;
}

void