From b5adc66fccb2b43bc2ff0721d95a851d883e5599 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 21 Sep 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-09-21 --- bitsy/mmu.c | 37 +++++++++++++++++++---- pc/devether.c | 15 ++++++---- pc/etherelnk3.c | 80 +++++++++++++++++++++++++++++++++++-------------- pc/etherif.h | 2 ++ 4 files changed, 101 insertions(+), 33 deletions(-) diff --git a/bitsy/mmu.c b/bitsy/mmu.c index c67f59d902fe25069a354307721e9e9031ede2d5..d9873c481e9c7df7466174a5e09ada716093e3a6 100644 --- a/bitsy/mmu.c +++ b/bitsy/mmu.c @@ -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; diff --git a/pc/devether.c b/pc/devether.c index f042e2b248a3dcb327f41aede1518d97e7cff53f..8edfaa3f2ebdddbbcab1af1aa28445aa617d7565 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -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); diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index 7557c8dff07b331340c135ada16e6b921e787b0e..e9bd2cc03d6f34fed75df3126d213aef8d87b68b 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -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 diff --git a/pc/etherif.h b/pc/etherif.h index 85b85925ecbb22f4d73f1b5ccdd67943be7180d9..33a5ad045f1779142b925decdd3535a093134002 100644 --- a/pc/etherif.h +++ b/pc/etherif.h @@ -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;