From 1fb13e8ba2eea54e41f4301bd82f5f11950b1376 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 28 Mar 1997 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1997-03-28 --- pc/etherelnk3.c | 270 +++++++++++++++++++++++++++++++----------------- pc/main.c | 1 + pc/memory.c | 2 +- 3 files changed, 177 insertions(+), 96 deletions(-) diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index d91cf4b1330d6f117632da0c0fc2a146f091a25e..243a3ace0530dc0e29512be5f916c40f360c761f 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -6,7 +6,8 @@ * autoSelect; * PCI latency timer and master enable; * errata list; - * 3C90x. + * 3C90x full busmastering; + * rewrite all initialisation. * * Product ID: * 9150 ISA 3C509[B] @@ -27,6 +28,11 @@ * 5951 PCI 3C595-T4 Fast Etherlink Shared 10BASE-T/100BASE-T4 * 5952 PCI 3C595-MII Fast Etherlink 10BASE-T/MII * + * 9000 PCI 3C900-TPO Etherlink III XL PCI 10BASE-T + * 9001 PCI 3C900-COMBO Etherlink III XL PCI 10BASE-T/10BASE-2/AUI + * 9050 PCI 3C905-TX Fast Etherlink XL Shared 10BASE-T/100BASE-TX + * 9051 PCI 3C905-T4 Fast Etherlink Shared 10BASE-T/100BASE-T4 + * * 9058 PCMCIA 3C589[B]-[TP|COMBO] * * 627C MCA 3C529 @@ -54,12 +60,13 @@ enum { /* all windows */ enum { /* Commands */ GlobalReset = 0x0000, - SelectRegisterWindow = 0x0001, + SelectRegisterWindow = 0x0001, EnableDcConverter = 0x0002, RxDisable = 0x0003, RxEnable = 0x0004, RxReset = 0x0005, - TxDone = 0x0007, + Stall = 0x0006, /* 3C90x */ + TxDone = 0x0007, RxDiscard = 0x0008, TxEnable = 0x0009, TxDisable = 0x000A, @@ -91,8 +98,16 @@ enum { /* (Global|Rx|Tx)Reset command bits */ hostReset = 0x0020, /* bus interface logic */ dmaReset = 0x0040, /* bus master logic */ vcoReset = 0x0080, /* on-board 10Mbps VCO */ + updnReset = 0x0100, /* upload/download (Rx/TX) logic */ + + resetMask = 0x01FF, +}; - resetMask = 0x00FF, +enum { /* Stall command bits */ + UpStall = 0x0000, + UpUnStall = 0x0001, + DnStall = 0x0002, + DnUnStall = 0x0003, }; enum { /* SetRxFilter command bits */ @@ -117,10 +132,12 @@ enum { /* IntStatus bits */ intRequested = 0x0040, updateStats = 0x0080, transferInt = 0x0100, /* Bus Master Transfer Complete */ + dnComplete = 0x0200, + upComplete = 0x0400, busMasterInProgress = 0x0800, commandInProgress = 0x1000, - interruptMask = 0x01FE, + interruptMask = 0x07FE, }; #define COMMAND(port, cmd, a) outs((port)+CommandR, ((cmd)<<11)|(a)) @@ -201,9 +218,12 @@ enum { /* Window 3 - FIFO management */ ResetOptions = 0x0008, /* 3C59[0257] */ RxFree = 0x000A, /* InternalConfig bits */ + disableBadSsdDetect = 0x00000100, + ramLocation = 0x00000200, /* 0 external, 1 internal */ ramPartition5to3 = 0x00000000, ramPartition3to1 = 0x00010000, ramPartition1to1 = 0x00020000, + ramPartition3to5 = 0x00030000, ramPartitionMask = 0x00030000, xcvr10BaseT = 0x00000000, xcvrAui = 0x00100000, /* 10BASE5 */ @@ -225,7 +245,7 @@ enum { /* Window 3 - FIFO management */ base10TAvailable = 0x0008, coaxAvailable = 0x0010, auiAvailable = 0x0020, - miiAvailable = 0x0040, + miiConnector = 0x0040, }; enum { /* Window 4 - diagnostic */ @@ -237,6 +257,7 @@ enum { /* Window 4 - diagnostic */ PhysicalMgmt = 0x0008, MediaStatus = 0x000A, BadSSD = 0x000C, + UpperBytesOk = 0x000D, /* FifoDiagnostic bits */ txOverrun = 0x0400, rxUnderrun = 0x2000, @@ -254,7 +275,7 @@ enum { /* Window 4 - diagnostic */ linkBeatDetect = 0x0800, txInProg = 0x1000, dcConverterEnabled = 0x4000, - auiDisable = 0x8000, + auiDisable = 0x8000, /* 10BaseT transceiver selected */ }; enum { /* Window 5 - internal state */ @@ -301,7 +322,58 @@ enum { /* Window 7 - bus master operations */ masterInProgress = 0x8000, masterMask = 0xD00F, -}; +}; + +enum { /* 3C90x extended register set */ + PktStatus = 0x0020, /* 32-bits */ + DnListPtr = 0x0024, /* 32-bits, 8-byte aligned */ + FragAddr = 0x0028, /* 32-bits */ + FragLen = 0x002C, /* 16-bits */ + ListOffset = 0x002E, /* 8-bits */ + TxFreeThresh = 0x002F, /* 8-bits */ + UpPktStatus = 0x0030, /* 32-bits */ + FreeTimer = 0x0034, /* 16-bits */ + UpListPtr = 0x0038, /* 32-bits, 8-byte aligned */ + + /* PktStatus bits */ + fragLast = 0x00000001, + dnCmplReq = 0x00000002, + dnStalled = 0x00000004, + upCompleteX = 0x00000008, + dnCompleteX = 0x00000010, + upRxEarlyEnable = 0x00000020, + armCountdown = 0x00000040, + dnInProg = 0x00000080, + counterSpeed = 0x00000010, /* 0 3.2uS, 1 320nS */ + countdownMode = 0x00000020, + /* UpPktStatus bits */ + upPktLenMask = 0x00001FFF, + upStalled = 0x00002000, + upError = 0x00004000, + upPktComplete = 0x00008000, + upOverrrun = 0x00010000, /* RxError<<16 */ + upRuntFrame = 0x00020000, + upAlignmentError = 0x00040000, + upCRCError = 0x00080000, + upOversizedFrame = 0x00100000, + upDribbleBits = 0x00800000, + upOverflow = 0x01000000, +}; + +/* + * Up/Dn Packet Descriptor. + * The hardware info (np, control, addr, len) must be 8-byte aligned. + */ +typedef struct Pd Pd; +typedef struct Pd { + Pd* next; + Block* bp; + + ulong np; /* next pointer */ + ulong control; /* FSH or UpPktStatus */ + ulong addr; + ulong len; +}; typedef struct { Lock wlock; /* window access */ @@ -316,19 +388,7 @@ typedef struct { long interrupts; /* statistics */ long timer; - - long carrierlost; - long sqeerrors; - long multiplecolls; - long singlecollframes; - long latecollisions; - long rxoverruns; - long framesxmittedok; - long framesrcvdok; - long framesdeferred; - long bytesrcvdok; - long bytesxmittedok; - long badssd; + long stats[BytesRcvdOk+2]; int xcvr; /* transceiver type */ int rxstatus9; /* old-style RxStatus register */ @@ -385,7 +445,7 @@ promiscuous(void* arg, int on) int filter, port; port = ((Ether*)arg)->port; - + filter = receiveBroadcast|receiveIndividual; if(on) filter |= receiveAllFrames; @@ -437,7 +497,7 @@ attach(Ether* ether) static void statistics(Ether* ether) { - int port, u, w; + int port, i, u, w; Ctlr *ctlr; port = ether->port; @@ -451,25 +511,18 @@ statistics(Ether* ether) COMMAND(port, SelectRegisterWindow, Wstatistics); STATUS(port); - ctlr->carrierlost += inb(port+CarrierLost) & 0xFF; - ctlr->sqeerrors += inb(port+SqeErrors) & 0xFF; - ctlr->multiplecolls += inb(port+MultipleColls) & 0xFF; - ctlr->singlecollframes += inb(port+SingleCollFrames) & 0xFF; - ctlr->latecollisions += inb(port+LateCollisions) & 0xFF; - ctlr->rxoverruns += inb(port+RxOverruns) & 0xFF; - ctlr->framesxmittedok += inb(port+FramesXmittedOk) & 0xFF; - ctlr->framesrcvdok += inb(port+FramesRcvdOk) & 0xFF; + for(i = 0; i < UpperFramesOk; i++) + ctlr->stats[i] += inb(port+i) & 0xFF; u = inb(port+UpperFramesOk) & 0xFF; - ctlr->framesxmittedok += (u & 0x30)<<4; - ctlr->framesrcvdok += (u & 0x03)<<8; - ctlr->framesdeferred += inb(port+FramesDeferred) & 0xFF; - ctlr->bytesrcvdok += ins(port+BytesRcvdOk) & 0xFFFF; - ctlr->bytesxmittedok += ins(port+BytesXmittedOk) & 0xFFFF; + ctlr->stats[FramesXmittedOk] += (u & 0x30)<<4; + ctlr->stats[FramesRcvdOk] += (u & 0x03)<<8; + ctlr->stats[BytesRcvdOk] += ins(port+BytesRcvdOk) & 0xFFFF; + ctlr->stats[BytesRcvdOk+1] += ins(port+BytesXmittedOk) & 0xFFFF; if(ctlr->xcvr == xcvr100BaseTX || ctlr->xcvr == xcvr100BaseFX){ COMMAND(port, SelectRegisterWindow, Wdiagnostic); STATUS(port); - ctlr->badssd += inb(port+BadSSD); + ctlr->stats[BytesRcvdOk+2] += inb(port+BadSSD); } COMMAND(port, SelectRegisterWindow, w); @@ -656,7 +709,7 @@ interrupt(Ureg*, void* arg) ctlr->interrupts++; ctlr->timer += inb(port+Timer) & 0xFF; - for(status = STATUS(port); status & interruptMask; status = STATUS(port)){ + while((status = STATUS(port)) & (interruptMask|interruptLatch)){ if(status & hostError){ /* * Adapter failure, try to find out why, reset if @@ -732,7 +785,7 @@ interrupt(Ureg*, void* arg) if(ctlr->busmaster == 0) COMMAND(port, TxReset, 0); else - COMMAND(port, TxReset, dmaReset); + COMMAND(port, TxReset, (updnReset|dmaReset)); while(STATUS(port) & commandInProgress) ; COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts); @@ -768,8 +821,9 @@ interrupt(Ureg*, void* arg) */ if(status & interruptMask) panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status); + + COMMAND(port, AcknowledgeInterrupt, interruptLatch); } - COMMAND(port, AcknowledgeInterrupt, interruptLatch); COMMAND(port, SelectRegisterWindow, w); unlock(&ctlr->wlock); @@ -793,18 +847,18 @@ ifstat(Ether* ether, void* a, long n, ulong offset) len = sprint(buf, "interrupts: %ld\n", ctlr->interrupts); len += sprint(buf+len, "timer: %ld\n", ctlr->timer); - len += sprint(buf+len, "carrierlost: %ld\n", ctlr->carrierlost); - len += sprint(buf+len, "sqeerrors: %ld\n", ctlr->sqeerrors); - len += sprint(buf+len, "multiplecolls: %ld\n", ctlr->multiplecolls); - len += sprint(buf+len, "singlecollframes: %ld\n", ctlr->singlecollframes); - len += sprint(buf+len, "latecollisions: %ld\n", ctlr->latecollisions); - len += sprint(buf+len, "rxoverruns: %ld\n", ctlr->rxoverruns); - len += sprint(buf+len, "framesxmittedok: %ld\n", ctlr->framesxmittedok); - len += sprint(buf+len, "framesrcvdok: %ld\n", ctlr->framesrcvdok); - len += sprint(buf+len, "framesdeferred: %ld\n", ctlr->framesdeferred); - len += sprint(buf+len, "bytesrcvdok: %ld\n", ctlr->bytesrcvdok); - len += sprint(buf+len, "bytesxmittedok: %ld\n", ctlr->bytesxmittedok); - sprint(buf+len, "badssd: %ld\n", ctlr->badssd); + len += sprint(buf+len, "carrierlost: %ld\n", ctlr->stats[CarrierLost]); + len += sprint(buf+len, "sqeerrors: %ld\n", ctlr->stats[SqeErrors]); + len += sprint(buf+len, "multiplecolls: %ld\n", ctlr->stats[MultipleColls]); + len += sprint(buf+len, "singlecollframes: %ld\n", ctlr->stats[SingleCollFrames]); + len += sprint(buf+len, "latecollisions: %ld\n", ctlr->stats[LateCollisions]); + len += sprint(buf+len, "rxoverruns: %ld\n", ctlr->stats[RxOverruns]); + len += sprint(buf+len, "framesxmittedok: %ld\n", ctlr->stats[FramesXmittedOk]); + len += sprint(buf+len, "framesrcvdok: %ld\n", ctlr->stats[FramesRcvdOk]); + len += sprint(buf+len, "framesdeferred: %ld\n", ctlr->stats[FramesDeferred]); + len += sprint(buf+len, "bytesrcvdok: %ld\n", ctlr->stats[BytesRcvdOk]); + len += sprint(buf+len, "bytesxmittedok: %ld\n", ctlr->stats[BytesRcvdOk+1]); + sprint(buf+len, "badssd: %ld\n", ctlr->stats[BytesRcvdOk+2]); return readstr(offset, a, n, buf); } @@ -1037,6 +1091,9 @@ tcm59Xpci(Ether* ether) while(p = pcimatch(p, 0x10B7, 0)){ port = p->bar[0] & ~0x01; irq = p->intl; + COMMAND(port, GlobalReset, 0); + while(STATUS(port) & commandInProgress) + ; if(ether->port == 0 || ether->port == port){ ether->irq = irq; ether->tbdf = p->tbdf; @@ -1074,6 +1131,9 @@ autoselect(int port, int rxstatus9) media = ins(port+ResetOptions); } + if(media & miiConnector) + return xcvrMii; + COMMAND(port, SelectRegisterWindow, Wdiagnostic); x = ins(port+MediaStatus) & ~(dcConverterEnabled|linkBeatEnable|jabberGuardEnable); outs(port+MediaStatus, x); @@ -1139,10 +1199,22 @@ autoselect(int port, int rxstatus9) return autoSelect; } +static int +eepromdata(int port, int offset) +{ + COMMAND(port, SelectRegisterWindow, Wsetup); + while(EEPROMBUSY(port)) + ; + EEPROMCMD(port, EepromReadRegister, offset); + while(EEPROMBUSY(port)) + ; + return EEPROMDATA(port); +} + int etherelnk3reset(Ether* ether) { - int busmaster, i, port, rxearly, rxstatus9, x, xcvr; + int busmaster, did, i, port, rxearly, rxstatus9, x, xcvr; Block *bp, **bpp; Adapter *ap; uchar ea[Eaddrlen]; @@ -1157,9 +1229,6 @@ etherelnk3reset(Ether* ether) * If an adapter is found save the IRQ and transceiver type. */ port = 0; - rxearly = 2044; - rxstatus9 = 0; - xcvr = 0; bpp = &adapter; for(bp = *bpp; bp; bp = bp->next){ ap = (Adapter*)bp->rp; @@ -1173,44 +1242,60 @@ etherelnk3reset(Ether* ether) } bpp = &bp->next; } - if(port == 0 && (port = tcm5XXpcmcia(ether))){ - xcvr = ((ins(port+AddressConfig) & xcvrMask9)>>14)<<20; - rxstatus9 = 1; - } - else if(port == 0 && (port = tcm59Xpci(ether))){ - COMMAND(port, GlobalReset, 0); - while(STATUS(port) & commandInProgress) - ; + if(port == 0) + port = tcm5XXpcmcia(ether); + if(port == 0) + port = tcm59Xpci(ether); + if(port == 0) + port = tcm5XXeisa(ether); + if(port == 0) + port = tcm509isa(ether); + if(port == 0) + return -1; + /* + * Read the DeviceID from the EEPROM, it's at offset 0x03, + * and do something depending on capabilities. + */ + switch(did = eepromdata(port, 0x03)){ + + case 0x9000: + case 0x9001: + case 0x9050: + case 0x9051: + if(BUSTYPE(ether->tbdf) != BusPCI) + goto buggery; + busmaster = 2; + goto vortex; + + case 0x5900: + case 0x5920: + case 0x5950: + case 0x5951: + case 0x5952: + case 0x5970: + case 0x5971: + case 0x5972: + busmaster = 1; + vortex: COMMAND(port, SelectRegisterWindow, Wfifo); - rxearly = 8188; xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask); - } - else if(port == 0 && (port = tcm5XXeisa(ether))){ - x = ins(port+ProductID); - if((x & 0xFF00) == 0x5900){ - COMMAND(port, SelectRegisterWindow, Wfifo); - rxearly = 8188; - xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask); - } - else{ - x = ins(port+AddressConfig); - xcvr = ((x & xcvrMask9)>>14)<<20; - if(x & autoSelect9) - xcvr |= autoSelect; - rxstatus9 = 1; - } - } - else if(port == 0 && (port = tcm509isa(ether))){ + rxearly = 8188; + rxstatus9 = 0; + break; + + buggery: + default: + busmaster = 0; + COMMAND(port, SelectRegisterWindow, Wsetup); x = ins(port+AddressConfig); xcvr = ((x & xcvrMask9)>>14)<<20; if(x & autoSelect9) xcvr |= autoSelect; + rxearly = 2044; rxstatus9 = 1; + break; } - if(port == 0) - return -1; - /* * Check if the adapter's station address is to be overridden. * If not, read it from the EEPROM and set in ether->ea prior to loading the @@ -1218,14 +1303,8 @@ etherelnk3reset(Ether* ether) */ memset(ea, 0, Eaddrlen); if(memcmp(ea, ether->ea, Eaddrlen) == 0){ - COMMAND(port, SelectRegisterWindow, Wsetup); - while(EEPROMBUSY(port)) - ; for(i = 0; i < Eaddrlen/2; i++){ - EEPROMCMD(port, EepromReadRegister, i); - while(EEPROMBUSY(port)) - ; - x = EEPROMDATA(port); + x = eepromdata(port, i); ether->ea[2*i] = x>>8; ether->ea[2*i+1] = x; } @@ -1246,7 +1325,7 @@ etherelnk3reset(Ether* ether) x = ins(port+MediaStatus) & ~(linkBeatEnable|jabberGuardEnable); outs(port+MediaStatus, x); if(x & dataRate100){ - busmaster = 1; + ether->mbps = 100; x = inl(port+InternalConfig) & ~ramPartitionMask; outl(port+InternalConfig, x|ramPartition1to1); } @@ -1254,10 +1333,11 @@ etherelnk3reset(Ether* ether) busmaster = 0; switch(xcvr){ + case xcvrMii: + break; + case xcvr100BaseTX: case xcvr100BaseFX: - ether->mbps = 100; - /*FALLTHROUGH*/ case xcvr10BaseT: /* * Enable Link Beat and Jabber to start the diff --git a/pc/main.c b/pc/main.c index ed1514263d3211f6fe88eb82ae3c93e6a8e4eec5..587b530b4cc61e27328a65170acfec463ffeab97 100644 --- a/pc/main.c +++ b/pc/main.c @@ -81,6 +81,7 @@ main(void) archinit(); confinit(); xinit(); + dmainit(); trapinit(); screeninit(); printinit(); diff --git a/pc/memory.c b/pc/memory.c index 11e6cad017f3e0928b07aa91e5f74ccc92e99f31..23381a172d227c3ed1c0e9ee9eafef98507e788f 100644 --- a/pc/memory.c +++ b/pc/memory.c @@ -21,7 +21,7 @@ enum { KB = 1024, MemMinMB = 4, /* minimum physical memory (<=4MB) */ - MemMaxMB = 192, /* maximum physical memory to check */ + MemMaxMB = 512, /* maximum physical memory to check */ NMemBase = 10, };