~kris/9p

9hist

b5adc66fccb2b43bc2ff0721d95a851d883e5599 — David du Colombier 26 years ago fa2de1d
Plan 9 from Bell Labs 2000-09-21
4 files changed, 101 insertions(+), 33 deletions(-)

M bitsy/mmu.c
M pc/devether.c
M pc/etherelnk3.c
M pc/etherif.h
M bitsy/mmu.c => bitsy/mmu.c +32 -5
@@ 91,13 91,20 @@ mmuinit(void)
}

/*
 *  map special use space
 *  map special space, assume that the space isn't already mapped
 */
ulong*
mapspecial(ulong physaddr, int len)
{
	ulong *t;
	ulong virtaddr, i;
	ulong virtaddr, i, base, end, off, entry, candidate;

	base = physaddr & ~(BY2PG-1);
	end = (physaddr+len-1) & ~(BY2PG-1);
	if(len > 128*1024)
		usemeg = 1;
	off = 0;
	candidate = 0;

	/* first see if we've mapped it somewhere, the first hole means we're done */
	for(virtaddr = REGZERO; virtaddr < REGTOP; virtaddr += OneMeg){


@@ 105,14 112,34 @@ mapspecial(ulong physaddr, int len)
			/* create a page table and break */
			t = xspanalloc(BY2PG, 1024, 0);
			memzero(t, BY2PG, 0);
			l1table[virtaddr>>20] = L1PageTable | L1Domain0 | (((ulong)t) & L1PTBaseMask);
			l1table[virtaddr>>20] = L1PageTable | L1Domain0 |
						(((ulong)t) & L1PTBaseMask);
			break;
		}
		t = (ulong*)(l1table[virtaddr>>20] & L1PTBaseMask);
		for(i = 0; i < OneMeg; i += BY2PG){
			if((t[(virtaddr+i)>>20] & L2TypeMask) != L2SmallPage)
			entry = t[(virtaddr+i)>>20];

			/* first hole means nothing left, add map */
			if((entry & L2TypeMask) != L2SmallPage)
				break;
			

			if(candidate == 0){
				/* look for start of range */
				if((entry & L2PageBaseMask) != base)
					continue;
				candidate = virtaddr+i;
			} else {
				/* look for contiunued range */
				if((entry & L2PageBaseMask) != base + off)
					candidate = 0;
					continue;
				}
			}

			/* if we're at the end of the range, area is already mapped */
			if((entry & L2PageBaseMask) == end)
				return candidate + (physaddr-base);
		}
		if(i < OneMeg){
			virtaddr += i;

M pc/devether.c => pc/devether.c +9 -6
@@ 258,9 258,9 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
		error(Ebadctl);
	}

	if(n > ETHERMAXTU)
	if(n > ether->maxmtu)
		error(Etoobig);
	if(n < ETHERMINTU)
	if(n < ether->minmtu)
		error(Etoosmall);

	bp = allocb(n);


@@ 284,16 284,17 @@ etherbwrite(Chan* chan, Block* bp, ulong)
			nexterror();
		}
		n = etherwrite(chan, bp->rp, n, 0);
		poperror();
		freeb(bp);
		return n;
	}
	ether = etherxx[chan->dev];

	if(n > ETHERMAXTU){
	if(n > ether->maxmtu){
		freeb(bp);
		error(Ebadarg);
		error(Etoobig);
	}
	if(n < ETHERMINTU){
	if(n < ether->minmtu){
		freeb(bp);
		error(Etoosmall);
	}


@@ 355,6 356,8 @@ etherreset(void)
		ether->ctlrno = ctlrno;
		ether->tbdf = BUSUNKNOWN;
		ether->mbps = 10;
		ether->minmtu = ETHERMINTU;
		ether->maxmtu = ETHERMAXTU;
		if(isaconfig("ether", ctlrno, ether) == 0)
			continue;
		for(n = 0; cards[n].type; n++){


@@ 396,7 399,7 @@ etherreset(void)
			sprint(buf+i, "\n");
			print(buf);

			if(ether->mbps == 100){
			if(ether->mbps >= 100){
				netifinit(ether, name, Ntypes, 256*1024);
				if(ether->oq == 0)
					ether->oq = qopen(256*1024, 1, 0, 0);

M pc/etherelnk3.c => pc/etherelnk3.c +58 -22
@@ 344,6 344,8 @@ enum {						/* Window 7 - bus master operations */
};

enum {						/* 3C90x extended register set */
	Timer905		= 0x001A,	/* 8-bits */
	TxStatus905		= 0x001B,	/* 8-bits */
	PktStatus		= 0x0020,	/* 32-bits */
	DnListPtr		= 0x0024,	/* 32-bits, 8-byte aligned */
	FragAddr		= 0x0028,	/* 32-bits */


@@ 426,7 428,7 @@ typedef struct {
	int	dnq;

	long	interrupts;			/* statistics */
	long	timer;
	long	timer[2];
	long	stats[BytesRcvdOk+3];

	int	upqmax;


@@ 950,7 952,7 @@ static void
interrupt(Ureg*, void* arg)
{
	Ether *ether;
	int port, status, s, w, x;
	int port, status, s, txstatus, w, x;
	Ctlr *ctlr;

	ether = arg;


@@ 958,12 960,21 @@ interrupt(Ureg*, void* arg)
	ctlr = ether->ctlr;

	ilock(&ctlr->wlock);
	w = (STATUS(port)>>13) & 0x07;
	status = STATUS(port);
	if(!(status & (interruptMask|interruptLatch))){
		iunlock(&ctlr->wlock);
		return;
	}
	w = (status>>13) & 0x07;
	COMMAND(port, SelectRegisterWindow, Wop);

	ctlr->interrupts++;
	ctlr->timer += inb(port+Timer) & 0xFF;
	while((status = STATUS(port)) & (interruptMask|interruptLatch)){
	if(ctlr->busmaster == 2)
		ctlr->timer[0] += inb(port+Timer905) & 0xFF;
	else
		ctlr->timer[0] += inb(port+Timer) & 0xFF;

	do{
		if(status & hostError){
			/*
			 * Adapter failure, try to find out why, reset if


@@ 1026,10 1037,14 @@ interrupt(Ureg*, void* arg)
			 * as a busmaster receive may be in progress.
			 * For all conditions enable the transmitter.
			 */
			if(ctlr->busmaster == 2)
				txstatus = port+TxStatus905;
			else
				txstatus = port+TxStatus;
			s = 0;
			do{
				if(x = inb(port+TxStatus))
					outb(port+TxStatus, 0);
				if(x = inb(txstatus))
					outb(txstatus, 0);
				s |= x;
			}while(STATUS(port) & txComplete);



@@ 1111,7 1126,12 @@ interrupt(Ureg*, void* arg)
			panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status);

		COMMAND(port, AcknowledgeInterrupt, interruptLatch);
	}
	}while((status = STATUS(port)) & (interruptMask|interruptLatch));

	if(ctlr->busmaster == 2)
		ctlr->timer[1] += inb(port+Timer905) & 0xFF;
	else
		ctlr->timer[1] += inb(port+Timer) & 0xFF;

	COMMAND(port, SelectRegisterWindow, w);
	iunlock(&ctlr->wlock);


@@ 1135,18 1155,30 @@ ifstat(Ether* ether, void* a, long n, ulong offset)

	p = malloc(READSTR);
	len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts);
	len += snprint(p+len, READSTR-len, "timer: %lud\n", ctlr->timer);
	len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", ctlr->stats[CarrierLost]);
	len += snprint(p+len, READSTR-len, "sqeerrors: %lud\n", ctlr->stats[SqeErrors]);
	len += snprint(p+len, READSTR-len, "multiplecolls: %lud\n", ctlr->stats[MultipleColls]);
	len += snprint(p+len, READSTR-len, "singlecollframes: %lud\n", ctlr->stats[SingleCollFrames]);
	len += snprint(p+len, READSTR-len, "latecollisions: %lud\n", ctlr->stats[LateCollisions]);
	len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n", ctlr->stats[RxOverruns]);
	len += snprint(p+len, READSTR-len, "framesxmittedok: %lud\n", ctlr->stats[FramesXmittedOk]);
	len += snprint(p+len, READSTR-len, "framesrcvdok: %lud\n", ctlr->stats[FramesRcvdOk]);
	len += snprint(p+len, READSTR-len, "framesdeferred: %lud\n", ctlr->stats[FramesDeferred]);
	len += snprint(p+len, READSTR-len, "bytesrcvdok: %lud\n", ctlr->stats[BytesRcvdOk]);
	len += snprint(p+len, READSTR-len, "bytesxmittedok: %lud\n", ctlr->stats[BytesRcvdOk+1]);
	len += snprint(p+len, READSTR-len, "timer: %lud %lud\n",
		ctlr->timer[0], ctlr->timer[1]);
	len += snprint(p+len, READSTR-len, "carrierlost: %lud\n",
		ctlr->stats[CarrierLost]);
	len += snprint(p+len, READSTR-len, "sqeerrors: %lud\n",
		ctlr->stats[SqeErrors]);
	len += snprint(p+len, READSTR-len, "multiplecolls: %lud\n",
		ctlr->stats[MultipleColls]);
	len += snprint(p+len, READSTR-len, "singlecollframes: %lud\n",
		ctlr->stats[SingleCollFrames]);
	len += snprint(p+len, READSTR-len, "latecollisions: %lud\n",
		ctlr->stats[LateCollisions]);
	len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n",
		ctlr->stats[RxOverruns]);
	len += snprint(p+len, READSTR-len, "framesxmittedok: %lud\n",
		ctlr->stats[FramesXmittedOk]);
	len += snprint(p+len, READSTR-len, "framesrcvdok: %lud\n",
		ctlr->stats[FramesRcvdOk]);
	len += snprint(p+len, READSTR-len, "framesdeferred: %lud\n",
		ctlr->stats[FramesDeferred]);
	len += snprint(p+len, READSTR-len, "bytesrcvdok: %lud\n",
		ctlr->stats[BytesRcvdOk]);
	len += snprint(p+len, READSTR-len, "bytesxmittedok: %lud\n",
		ctlr->stats[BytesRcvdOk+1]);

	if(ctlr->upenabled){
		if(ctlr->upqmax > ctlr->upqmaxhw)


@@ 1925,8 1957,12 @@ XCVRDEBUG("\n");
	 * Clear out any lingering Tx status.
	 */
	COMMAND(port, SelectRegisterWindow, Wop);
	while(inb(port+TxStatus))
		outb(port+TxStatus, 0);
	if(busmaster == 2)
		x = port+TxStatus905;
	else
		x = port+TxStatus;
	while(inb(x))
		outb(x, 0);

	/*
	 * Allocate a controller structure, clear out the

M pc/etherif.h => pc/etherif.h +2 -0
@@ 10,6 10,8 @@ struct Ether {
	int	ctlrno;
	int	tbdf;			/* type+busno+devno+funcno */
	int	mbps;			/* Mbps */
	int	minmtu;
	int 	maxmtu;
	uchar	ea[Eaddrlen];
	int	encry;