From 39edf1e85f8a4ee3a1df326cab14a54243b6173b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 23 Oct 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-10-23 --- alphapc/arch164.c | 2 ++ alphapc/clock.c | 13 +++++++ alphapc/dat.h | 18 ++++++++++ alphapc/devarch.c | 15 ++++++++ alphapc/ether2114x.c | 85 +++++++++++++++++++++++++++++++++----------- alphapc/fns.h | 6 ++++ alphapc/pci.c | 22 +++++++++++- alphapc/trap.c | 31 ++++++++++++++++ pc/devpccard.c | 2 ++ pc/ether2114x.c | 36 +++++++++++++++---- 10 files changed, 202 insertions(+), 28 deletions(-) diff --git a/alphapc/arch164.c b/alphapc/arch164.c index 88da71bb79db8cb948a224cf0a625b5ac25b3269..a0bc512508f29f0ba6795214fd05af0d1564f87a 100644 --- a/alphapc/arch164.c +++ b/alphapc/arch164.c @@ -346,6 +346,8 @@ PCArch arch164 = { pcicfg2117x, pcimem2117x, intrenable164, + nil, + nil, inb2117x, ins2117x, diff --git a/alphapc/clock.c b/alphapc/clock.c index edf573cac5fc5f560a2045fccf4c464082812ccf..346c703fd41cb00fd2f1938d3ba7b9179c588924 100644 --- a/alphapc/clock.c +++ b/alphapc/clock.c @@ -89,3 +89,16 @@ clock(Ureg *ureg) portclock(ureg); } + +ulong +TK2MS(ulong ticks) +{ + uvlong t, hz; + + t = ticks; + hz = HZ; + t *= 1000L; + t = t/hz; + ticks = t; + return ticks; +} diff --git a/alphapc/dat.h b/alphapc/dat.h index 1bd82cf49af67847b605d29a710fda28bcd53c7a..c192404c1b3db2f4498d58c58677a62c818bdc5b 100644 --- a/alphapc/dat.h +++ b/alphapc/dat.h @@ -189,6 +189,8 @@ struct PCArch void *(*pcicfg)(int, int); /* map and point to PCI cfg space */ void *(*pcimem)(int, int); /* map and point to PCI memory space */ int (*intrenable)(Vctl*); + int (*intrvecno)(int); + int (*intrdisable)(int); int (*_inb)(int); ushort (*_ins)(int); @@ -229,3 +231,19 @@ extern Mach mach0; extern register Mach *m; extern register Proc *up; + +/* + * hardware info about a device + */ +typedef struct { + ulong port; + int size; +} port_t; + +struct DevConf +{ + ulong interrupt; /* interrupt number */ + char *type; /* card type, malloced */ + int nports; /* Number of ports */ + port_t *ports; /* The ports themselves */ +}; diff --git a/alphapc/devarch.c b/alphapc/devarch.c index 384de1b42936d4a4181beba16a5e5e371f99b9e1..0653091e63faedbf03de70f8428ab28ee0e44bb6 100644 --- a/alphapc/devarch.c +++ b/alphapc/devarch.c @@ -51,6 +51,8 @@ static Dirtab archdir[] = { }; Lock archwlock; /* the lock is only for changing archdir */ int narchdir = Qbase; +int (*_pcmspecial)(char *, ISAConf *); +void (*_pcmspecialclose)(int); /* * Add a file to the #P listing. Once added, you can't delete it. @@ -479,3 +481,16 @@ archinit(void) addarchfile("cputype", 0444, cputyperead, nil); } + +int +pcmspecial(char *idstr, ISAConf *isa) +{ + return (_pcmspecial != nil)? _pcmspecial(idstr, isa): -1; +} + +void +pcmspecialclose(int a) +{ + if (_pcmspecialclose != nil) + _pcmspecialclose(a); +} diff --git a/alphapc/ether2114x.c b/alphapc/ether2114x.c index 614ecada1d828f8347739a11712fd1d2d30ffadd..2144eefa33f0b3832a9650615ce5965b886444c6 100644 --- a/alphapc/ether2114x.c +++ b/alphapc/ether2114x.c @@ -32,17 +32,14 @@ enum { enum { /* CRS0 - Bus Mode */ Swr = 0x00000001, /* Software Reset */ Bar = 0x00000002, /* Bus Arbitration */ - DslMASK = 0x0000007C, /* Descriptor Skip Length */ - DslSHIFT = 2, + Dsl = 0x0000007C, /* Descriptor Skip Length (field) */ Ble = 0x00000080, /* Big/Little Endian */ - PblMASK = 0x00003F00, /* Programmable Burst Length (field) */ - PblSHIFT = 8, + Pbl = 0x00003F00, /* Programmable Burst Length (field) */ Cal = 0x0000C000, /* Cache Alignment (field) */ Cal8 = 0x00004000, /* 8 longword boundary alignment */ Cal16 = 0x00008000, /* 16 longword boundary alignment */ Cal32 = 0x0000C000, /* 32 longword boundary alignment */ - TapMASK = 0x000E0000, /* Transmit Automatic Polling */ - TapSHIFT = 17, + Tap = 0x000E0000, /* Transmit Automatic Polling (field) */ Dbo = 0x00100000, /* Descriptor Byte Ordering Mode */ Rml = 0x00200000, /* Read Multiple */ }; @@ -201,7 +198,8 @@ typedef struct Ctlr { int active; int id; /* (pcidev->did<<16)|pcidev->vid */ - uchar srom[128]; + uchar* srom; + int sromsz; /* address size in bits */ uchar* sromea; /* MAC address */ uchar* leaf; int sct; /* selected connection type */ @@ -350,7 +348,7 @@ ifstat(Ether* ether, void* a, long n, ulong offset) n -= len; l = snprint(p, READSTR, "srom:"); - for(i = 0; i < sizeof(ctlr->srom); i++){ + for(i = 0; i < (1<sromsz); i++){ if(i && ((i & 0x0F) == 0)) l += snprint(p+l, READSTR-l, "\n "); l += snprint(p+l, READSTR-l, " %2.2uX", ctlr->srom[i]); @@ -577,11 +575,11 @@ ctlrinit(Ether* ether) * create and post a setup packet to initialise * the physical ethernet address. */ - ctlr->rdr = malloc(ctlr->nrdr*sizeof(Des)); + ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(Des), 8*sizeof(ulong), 0); for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){ des->bp = iallocb(Rbsz); if(des->bp == nil) - panic("can't allocate ethernet receive ring"); + panic("can't allocate ethernet receive ring\n"); des->status = Own; des->control = Rbsz; des->addr = PCIWADDR(des->bp->rp); @@ -614,7 +612,7 @@ ctlrinit(Ether* ether) } bp = iallocb(Eaddrlen*2*16); if(bp == nil) - panic("can't allocate ethernet setup buffer"); + panic("can't allocate ethernet setup buffer\n"); memset(bp->rp, 0xFF, sizeof(bi)); for(i = sizeof(bi); i < sizeof(bi)*16; i += sizeof(bi)) memmove(bp->rp+i, bi, sizeof(bi)); @@ -723,7 +721,7 @@ miiw(Ctlr* ctlr, int phyad, int regad, int data) static int sromr(Ctlr* ctlr, int r) { - int i, op, data; + int i, op, data, size; if(ctlr->id == Pnic){ i = 1000; @@ -733,6 +731,9 @@ sromr(Ctlr* ctlr, int r) data = csr32r(ctlr, 19); }while((data & 0x80000000) && --i); + if(ctlr->sromsz == 0) + ctlr->sromsz = 6; + return csr32r(ctlr, 9) & 0xFFFF; } @@ -741,6 +742,7 @@ sromr(Ctlr* ctlr, int r) * in the EEPROM is taken straight from Section * 7.4 of the 21140 Hardware Reference Manual. */ +reread: csr9w(ctlr, Rd|Ss); csr9w(ctlr, Rd|Ss|Scs); csr9w(ctlr, Rd|Ss|Sclk|Scs); @@ -754,11 +756,20 @@ sromr(Ctlr* ctlr, int r) csr9w(ctlr, data); } - for(i = 6-1; i >= 0; i--){ - data = Rd|Ss|(((r>>i) & 0x01)<<2)|Scs; + /* + * First time through must work out the EEPROM size. + */ + if((size = ctlr->sromsz) == 0) + size = 8; + + for(size = size-1; size >= 0; size--){ + data = Rd|Ss|(((r>>size) & 0x01)<<2)|Scs; csr9w(ctlr, data); csr9w(ctlr, data|Sclk); csr9w(ctlr, data); + microdelay(1); + if(!(csr32r(ctlr, 9) & Sdo)) + break; } data = 0; @@ -771,6 +782,11 @@ sromr(Ctlr* ctlr, int r) csr9w(ctlr, 0); + if(ctlr->sromsz == 0){ + ctlr->sromsz = 8-size; + goto reread; + } + return data & 0xFFFF; } @@ -783,7 +799,7 @@ softreset(Ctlr* ctlr) */ csr32w(ctlr, 0, Swr); microdelay(10); - csr32w(ctlr, 0, Rml|Cal16|(32<csr6 = (command & 0x71) << 18; + csr32w(ctlr, 6, ctlr->csr6); + return 0; +} + static int type0link(Ctlr* ctlr, uchar* block) { @@ -1002,8 +1038,7 @@ type0mode(Ctlr* ctlr, uchar* block, int wait) { int csr6, m, timeo; -// csr6 = Sc|Mbo|Hbd|Ca|Sb|TrMODE; - csr6 = Mbo|Hbd|Sb|TrMODE; + csr6 = Sc|Mbo|Hbd|Ca|Sb|TrMODE; debug("type0: medium 0x%uX, fd %d: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n", ctlr->medium, ctlr->fd, block[0], block[1], block[2], block[3]); switch(block[0]){ @@ -1078,6 +1113,10 @@ mediaxx(Ether* ether, int wait) if(typephymode(ctlr, block, wait)) return 0; break; + case 4: + if(typesymmode(ctlr, block, wait)) + return 0; + break; } } else{ @@ -1221,8 +1260,12 @@ srom(Ctlr* ctlr) * 'Digital Semiconductor 21X4 Serial ROM Format, Version 4.05, * 2-Mar-98'. Only the 2114[03] are handled, support for other * controllers can be added as needed. + * Do a dummy read first to get the size and allocate ctlr->srom. */ - for(i = 0; i < sizeof(ctlr->srom)/2; i++){ + sromr(ctlr, 0); + if(ctlr->srom == nil) + ctlr->srom = malloc((1<sromsz)*sizeof(ushort)); + for(i = 0; i < (1<sromsz); i++){ x = sromr(ctlr, i); ctlr->srom[2*i] = x; ctlr->srom[2*i+1] = x>>8; @@ -1415,9 +1458,9 @@ dec2114xpci(void) switch(ctlr->id){ default: -// break; -// -// case Pnic: /* PNIC */ + break; + + case Pnic: /* PNIC */ /* * Turn off the jabber timer. */ diff --git a/alphapc/fns.h b/alphapc/fns.h index 33b0e18e75b2ae836c861db6fee32d13f32fc8b7..3331eba14bf3ef0aea028a1da57355410f61c8f2 100644 --- a/alphapc/fns.h +++ b/alphapc/fns.h @@ -43,6 +43,7 @@ void icflush(void); void illegal0(void); void intr0(void); void intrenable(int, void (*)(Ureg*, void*), void*, int, char*); +void intrdisable(int, void (*)(Ureg *, void *), void*, int, char*); int ioalloc(int, int, int, char*); void iofree(int); void ioinit(void); @@ -72,11 +73,16 @@ int pcicfgr32(Pcidev*, int); void pcicfgw8(Pcidev*, int, int); void pcicfgw16(Pcidev*, int, int); void pcicfgw32(Pcidev*, int, int); +void pciclrbme(Pcidev*); void pcihinv(Pcidev*); Pcidev* pcimatch(Pcidev*, int, int); Pcidev* pcimatchtbdf(int); void pcireset(void); void pcisetbme(Pcidev*); +int pcmspecial(char*, ISAConf*); +int (*_pcmspecial)(char *, ISAConf *); +void pcmspecialclose(int); +void (*_pcmspecialclose)(int); void prflush(void); void printinit(void); #define procrestore(p) diff --git a/alphapc/pci.c b/alphapc/pci.c index 1a8dcdef928666a65a761a2faeda146873d25525..d474f6387d17ae368a24da99a4af724f94122f0f 100644 --- a/alphapc/pci.c +++ b/alphapc/pci.c @@ -16,6 +16,16 @@ enum { MaxUBN = 255, }; +enum +{ /* command register */ + IOen = (1<<0), + MEMen = (1<<1), + MASen = (1<<2), + MemWrInv = (1<<4), + PErrEn = (1<<6), + SErrEn = (1<<8), +}; + static Lock pcicfglock; static Lock pcicfginitlock; static int pcicfgmode = -1; @@ -388,6 +398,16 @@ pcisetbme(Pcidev* p) int pcr; pcr = pcicfgr16(p, PciPCR); - pcr |= 0x0004; + pcr |= MASen; + pcicfgw16(p, PciPCR, pcr); +} + +void +pciclrbme(Pcidev* p) +{ + int pcr; + + pcr = pcicfgr16(p, PciPCR); + pcr &= ~MASen; pcicfgw16(p, PciPCR, pcr); } diff --git a/alphapc/trap.c b/alphapc/trap.c index 6f52650258368d66066fc836c1dbb59644023e3b..5828f6c3464bedea20b02d4f722bb5b792400ec1 100644 --- a/alphapc/trap.c +++ b/alphapc/trap.c @@ -73,6 +73,37 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name) iunlock(&vctllock); } +void +intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name) +{ + Vctl **pv, *v; + int vno; + + /* + * For now, none of this will work with the APIC code, + * there is no mapping between irq and vector as the IRQ + * is pretty meaningless. + */ + if(arch->intrvecno == nil) + return; + vno = arch->intrvecno(irq); + ilock(&vctllock); + pv = &vctl[vno]; + while (*pv && + ((*pv)->irq != irq || (*pv)->tbdf != tbdf || (*pv)->f != f || (*pv)->a != a || + strcmp((*pv)->name, name))) + pv = &((*pv)->next); + assert(*pv); + + v = *pv; + *pv = (*pv)->next; /* Link out the entry */ + + if (vctl[vno] == nil && arch->intrdisable != nil) + arch->intrdisable(irq); + iunlock(&vctllock); + xfree(v); +} + int irqallocread(char *buf, long n, vlong offset) { diff --git a/pc/devpccard.c b/pc/devpccard.c index 78827aa899035ec5d9ed85cf5df99fc2127f129d..3f28c56963a1a8d523cfd60fc78287e2bd86f37e 100644 --- a/pc/devpccard.c +++ b/pc/devpccard.c @@ -13,6 +13,7 @@ enum { TI_vid = 0x104c, + TI_1250_did = 0xAC16, TI_1450_did = 0xAC1B, TI_1251A_did = 0xAC1D, @@ -38,6 +39,7 @@ typedef struct { static variant_t variant[] = { { Ricoh_vid, Ricoh_476_did, "Ricoh 476 PCI/Cardbus bridge", }, { Ricoh_vid, Ricoh_478_did, "Ricoh 478 PCI/Cardbus bridge", }, +{ TI_vid, TI_1250_did, "TI PCI-1250 Cardbus Controller", }, { TI_vid, TI_1450_did, "TI PCI-1450 Cardbus Controller", }, { TI_vid, TI_1251A_did, "TI PCI-1251A Cardbus Controller", }, { TI_vid, 0xAC51, "TI 0xAC51 Cardbus Controller", }, diff --git a/pc/ether2114x.c b/pc/ether2114x.c index b4a6b4dbbfd0c48db2797f78408f3d917681462a..2144eefa33f0b3832a9650615ce5965b886444c6 100644 --- a/pc/ether2114x.c +++ b/pc/ether2114x.c @@ -386,7 +386,7 @@ txstart(Ether* ether) ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic; des = &ctlr->tdr[ctlr->tdrh]; des->bp = bp; - des->addr = PADDR(bp->rp); + des->addr = PCIWADDR(bp->rp); des->control |= control; ctlr->ntq++; coherence(); @@ -471,7 +471,7 @@ interrupt(Ureg*, void* arg) des->bp->wp = des->bp->rp+len; etheriq(ether, des->bp, 1); des->bp = bp; - des->addr = PADDR(bp->rp); + des->addr = PCIWADDR(bp->rp); } des->control &= Er; @@ -575,24 +575,24 @@ ctlrinit(Ether* ether) * create and post a setup packet to initialise * the physical ethernet address. */ - ctlr->rdr = malloc(ctlr->nrdr*sizeof(Des)); + ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(Des), 8*sizeof(ulong), 0); for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){ des->bp = iallocb(Rbsz); if(des->bp == nil) panic("can't allocate ethernet receive ring\n"); des->status = Own; des->control = Rbsz; - des->addr = PADDR(des->bp->rp); + des->addr = PCIWADDR(des->bp->rp); } ctlr->rdr[ctlr->nrdr-1].control |= Er; ctlr->rdrx = 0; - csr32w(ctlr, 3, PADDR(ctlr->rdr)); + csr32w(ctlr, 3, PCIWADDR(ctlr->rdr)); ctlr->tdr = xspanalloc(ctlr->ntdr*sizeof(Des), 8*sizeof(ulong), 0); ctlr->tdr[ctlr->ntdr-1].control |= Er; ctlr->tdrh = 0; ctlr->tdri = 0; - csr32w(ctlr, 4, PADDR(ctlr->tdr)); + csr32w(ctlr, 4, PCIWADDR(ctlr->tdr)); /* * Clear any bits in the Status Register (CSR5) as @@ -998,6 +998,26 @@ typephymode(Ctlr* ctlr, uchar* block, int wait) return -1; } +static int +typesymmode(Ctlr *ctlr, uchar *block, int wait) +{ + uint gpmode, gpdata, command; + + USED(wait); + gpmode = block[3] | ((uint) block[4] << 8); + gpdata = block[5] | ((uint) block[6] << 8); + command = (block[7] | ((uint) block[8] << 8)) & 0x71; + if (command & 0x8000) { + print("ether2114x.c: FIXME: handle type 4 mode blocks where cmd.active_invalid != 0\n"); + return -1; + } + csr32w(ctlr, 15, gpmode); + csr32w(ctlr, 15, gpdata); + ctlr->csr6 = (command & 0x71) << 18; + csr32w(ctlr, 6, ctlr->csr6); + return 0; +} + static int type0link(Ctlr* ctlr, uchar* block) { @@ -1093,6 +1113,10 @@ mediaxx(Ether* ether, int wait) if(typephymode(ctlr, block, wait)) return 0; break; + case 4: + if(typesymmode(ctlr, block, wait)) + return 0; + break; } } else{