# HG changeset patch # User Erik Quanstrom # Date 1331073999 -3600 # Node ID 784debe5594b0183cfe66a377a64b7ef7c932d64 # Parent dd5286addc1a67c9f71ee3690d07d737e8ae6f75 pci.c: delete unneeded junk a lot of crufty business has accumulated in pci.c 1. remove the pci console 2. make the maximum bus, device, function constants. (we can do this because we can assume type 1 access.) 3. replace pcicfgrw^(32 16 8) with pcicfgrw 4. remove unused pci re-enumeration code. let bios handle this. 5. configure memory space for any device that isn't a bridge rather than enumerating the types of devices. 6. remove pciscan. unused. 7. remove ancient southbridges that don't appear in 64-bit machines 8. remove type 2 access. this was depricated before amd64 appeared. 9. remove configuration of maxbno. this is unnecessary today. a. remove pciipin; unused b. remove pci^(get set)^ioe; unused. c. enumerate rather than comment in pcipms. undone. should do? 1. remove support for cardbus bridges R=nixiedev, nemo CC=nix-dev http://codereview.appspot.com/5758051 Committer: Francisco J Ballesteros diff -r dd5286addc1a -r 784debe5594b sys/src/nix/386/pci.c --- a/sys/src/nix/386/pci.c Tue Mar 06 23:39:47 2012 +0100 +++ b/sys/src/nix/386/pci.c Tue Mar 06 23:46:39 2012 +0100 @@ -10,64 +10,33 @@ #include "io.h" -struct +enum { - char output[16384]; - int ptr; -}PCICONS; - -int -pcilog(char *fmt, ...) -{ - int n; - va_list arg; - char buf[PRINTSIZE]; - - va_start(arg, fmt); - n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; - va_end(arg); - - memmove(PCICONS.output+PCICONS.ptr, buf, n); - PCICONS.ptr += n; - return n; -} - -enum -{ /* configuration mechanism #1 */ PciADDR = 0xCF8, /* CONFIG_ADDRESS */ PciDATA = 0xCFC, /* CONFIG_DATA */ - /* configuration mechanism #2 */ - PciCSE = 0xCF8, /* configuration space enable */ - PciFORWARD = 0xCFA, /* which bus */ + Maxfn = 7, + Maxdev = 31, + Maxbus = 255, - MaxFNO = 7, - MaxUBN = 255, -}; - -enum -{ /* command register */ + /* command register */ IOen = (1<<0), MEMen = (1<<1), MASen = (1<<2), MemWrInv = (1<<4), PErrEn = (1<<6), SErrEn = (1<<8), + + Write, + Read, }; static Lock pcicfglock; static Lock pcicfginitlock; static int pcicfgmode = -1; -static int pcimaxbno = 255; -static int pcimaxdno; static Pcidev* pciroot; static Pcidev* pcilist; static Pcidev* pcitail; -static int nobios, nopcirouting; - -static int pcicfgrw32(int, int, int, int); -static int pcicfgrw16(int, int, int, int); -static int pcicfgrw8(int, int, int, int); static char* bustypes[] = { "CBUSI", @@ -90,7 +59,7 @@ "XPRESS", }; -#pragma varargck type "T" int +static int pcicfgrw(int, int, int, int, int); static int tbdffmt(Fmt* fmt) @@ -124,248 +93,31 @@ return r; } -ulong +static ulong pcibarsize(Pcidev *p, int rno) { ulong v, size; - v = pcicfgrw32(p->tbdf, rno, 0, 1); - pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0); - size = pcicfgrw32(p->tbdf, rno, 0, 1); + v = pcicfgr32(p, rno); + pcicfgw32(p, rno, 0xFFFFFFF0); + size = pcicfgr32(p, rno); if(v & 1) size |= 0xFFFF0000; - pcicfgrw32(p->tbdf, rno, v, 0); + pcicfgw32(p, rno, v); return -(size & ~0x0F); } static int -pcisizcmp(void *a, void *b) -{ - Pcisiz *aa, *bb; - - aa = a; - bb = b; - return aa->siz - bb->siz; -} - -static ulong -pcimask(ulong v) -{ - ulong m; - - m = BI2BY*sizeof(v); - for(m = 1<<(m-1); m != 0; m >>= 1) { - if(m & v) - break; - } - - m--; - if((v & m) == 0) - return v; - - v |= m; - return v+1; -} - -static void -pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg) -{ - Pcidev *p; - int ntb, i, size, rno, hole; - ulong v, mema, ioa, sioa, smema, base, limit; - Pcisiz *table, *tptr, *mtb, *itb; - extern void qsort(void*, long, long, int (*)(void*, void*)); - - if(!nobios) - return; - - ioa = *pioa; - mema = *pmema; - - DBG("pcibusmap wr=%d %T mem=%luX io=%luX\n", - wrreg, root->tbdf, mema, ioa); - - ntb = 0; - for(p = root; p != nil; p = p->link) - ntb++; - - ntb *= (PciCIS-PciBAR0)/4; - table = malloc(2*ntb*sizeof(Pcisiz)); - itb = table; - mtb = table+ntb; - - /* - * Build a table of sizes - */ - for(p = root; p != nil; p = p->link) { - if(p->ccrb == 0x06) { - if(p->ccru != 0x04 || p->bridge == nil) { -// DBG("pci: ignored bridge %T\n", p->tbdf); - continue; - } - - sioa = ioa; - smema = mema; - pcibusmap(p->bridge, &smema, &sioa, 0); - - hole = pcimask(smema-mema); - if(hole < (1<<20)) - hole = 1<<20; - p->mema.size = hole; - - hole = pcimask(sioa-ioa); - if(hole < (1<<12)) - hole = 1<<12; - - p->ioa.size = hole; - - itb->dev = p; - itb->bar = -1; - itb->siz = p->ioa.size; - itb++; - - mtb->dev = p; - mtb->bar = -1; - mtb->siz = p->mema.size; - mtb++; - continue; - } - - for(i = 0; i <= 5; i++) { - rno = PciBAR0 + i*4; - v = pcicfgrw32(p->tbdf, rno, 0, 1); - size = pcibarsize(p, rno); - if(size == 0) - continue; - - if(v & 1) { - itb->dev = p; - itb->bar = i; - itb->siz = size; - itb++; - } - else { - mtb->dev = p; - mtb->bar = i; - mtb->siz = size; - mtb++; - } - - p->mem[i].size = size; - } - } - - /* - * Sort both tables IO smallest first, Memory largest - */ - qsort(table, itb-table, sizeof(Pcisiz), pcisizcmp); - tptr = table+ntb; - qsort(tptr, mtb-tptr, sizeof(Pcisiz), pcisizcmp); - - /* - * Allocate IO address space on this bus - */ - for(tptr = table; tptr < itb; tptr++) { - hole = tptr->siz; - if(tptr->bar == -1) - hole = 1<<12; - ioa = (ioa+hole-1) & ~(hole-1); - - p = tptr->dev; - if(tptr->bar == -1) - p->ioa.bar = ioa; - else { - p->pcr |= IOen; - p->mem[tptr->bar].bar = ioa|1; - if(wrreg) - pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), ioa|1, 0); - } - - ioa += tptr->siz; - } - - /* - * Allocate Memory address space on this bus - */ - for(tptr = table+ntb; tptr < mtb; tptr++) { - hole = tptr->siz; - if(tptr->bar == -1) - hole = 1<<20; - mema = (mema+hole-1) & ~(hole-1); - - p = tptr->dev; - if(tptr->bar == -1) - p->mema.bar = mema; - else { - p->pcr |= MEMen; - p->mem[tptr->bar].bar = mema; - if(wrreg) - pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), mema, 0); - } - mema += tptr->siz; - } - - *pmema = mema; - *pioa = ioa; - free(table); - - if(wrreg == 0) - return; - - /* - * Finally set all the bridge addresses & registers - */ - for(p = root; p != nil; p = p->link) { - if(p->bridge == nil) { - pcicfgrw8(p->tbdf, PciLTR, 64, 0); - - p->pcr |= MASen; - pcicfgrw16(p->tbdf, PciPCR, p->pcr, 0); - continue; - } - - base = p->ioa.bar; - limit = base+p->ioa.size-1; - v = pcicfgrw32(p->tbdf, PciIBR, 0, 1); - v = (v&0xFFFF0000)|(limit & 0xF000)|((base & 0xF000)>>8); - pcicfgrw32(p->tbdf, PciIBR, v, 0); - v = (limit & 0xFFFF0000)|(base>>16); - pcicfgrw32(p->tbdf, PciIUBR, v, 0); - - base = p->mema.bar; - limit = base+p->mema.size-1; - v = (limit & 0xFFF00000)|((base & 0xFFF00000)>>16); - pcicfgrw32(p->tbdf, PciMBR, v, 0); - - /* - * Disable memory prefetch - */ - pcicfgrw32(p->tbdf, PciPMBR, 0x0000FFFF, 0); - pcicfgrw8(p->tbdf, PciLTR, 64, 0); - - /* - * Enable the bridge - */ - p->pcr |= IOen|MEMen|MASen; - pcicfgrw32(p->tbdf, PciPCR, 0xFFFF0000|p->pcr , 0); - - sioa = p->ioa.bar; - smema = p->mema.bar; - pcibusmap(p->bridge, &smema, &sioa, 1); - } -} - -static int pcilscan(int bno, Pcidev** list) { Pcidev *p, *head, *tail; - int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn; + int dno, fno, i, hdt, l, maxfno, maxubn, sbn, tbdf, ubn; maxubn = bno; head = nil; tail = nil; - for(dno = 0; dno <= pcimaxdno; dno++){ + for(dno = 0; dno <= Maxdev; dno++){ maxfno = 0; for(fno = 0; fno <= maxfno; fno++){ /* @@ -377,7 +129,7 @@ * from the device's configuration space. */ tbdf = MKBUS(BusPCI, bno, dno, fno); - l = pcicfgrw32(tbdf, PciVID, 0, 1); + l = pcicfgrw(tbdf, PciVID, 0, Read, 4); if(l == 0xFFFFFFFF || l == 0) continue; p = malloc(sizeof(*p)); @@ -407,37 +159,25 @@ */ hdt = pcicfgr8(p, PciHDT); if(hdt & 0x80) - maxfno = MaxFNO; + maxfno = Maxfn; /* * If appropriate, read the base address registers * and work out the sizes. */ switch(p->ccrb) { - case 0x01: /* mass storage controller */ - case 0x02: /* network controller */ - case 0x03: /* display controller */ - case 0x04: /* multimedia device */ - case 0x07: /* simple comm. controllers */ - case 0x08: /* base system peripherals */ - case 0x09: /* input devices */ - case 0x0A: /* docking stations */ - case 0x0B: /* processors */ - case 0x0C: /* serial bus controllers */ + default: if((hdt & 0x7F) != 0) break; - rno = PciBAR0 - 4; for(i = 0; i < nelem(p->mem); i++) { - rno += 4; - p->mem[i].bar = pcicfgr32(p, rno); - p->mem[i].size = pcibarsize(p, rno); + p->mem[i].bar = pcicfgr32(p, PciBAR0+4*i); + p->mem[i].size = pcibarsize(p, PciBAR0+4*i); } break; case 0x00: case 0x05: /* memory controller */ case 0x06: /* bridge device */ - default: break; } @@ -468,7 +208,9 @@ sbn = pcicfgr8(p, PciSBN); ubn = pcicfgr8(p, PciUBN); - if(sbn == 0 || ubn == 0 || nobios) { + if(sbn == 0 || ubn == 0) { + print("%T: unconfigured bridge\n", p->tbdf); + sbn = maxubn+1; /* * Make sure memory, I/O and master enables are @@ -479,13 +221,10 @@ * Initialisation of the bridge should be done here. */ pcicfgw32(p, PciPCR, 0xFFFF0000); - l = (MaxUBN<<16)|(sbn<<8)|bno; - pcicfgw32(p, PciPBN, l); + pcicfgw32(p, PciPBN, Maxbus<<16 | sbn<<8 | bno); pcicfgw16(p, PciSPSR, 0xFFFF); maxubn = pcilscan(sbn, &p->bridge); - l = (maxubn<<16)|(sbn<<8)|bno; - - pcicfgw32(p, PciPBN, l); + pcicfgw32(p, PciPBN, maxubn<<16 | sbn<<8 | bno); } else { /* @@ -505,17 +244,6 @@ return maxubn; } -int -pciscan(int bno, Pcidev **list) -{ - int ubn; - - lock(&pcicfginitlock); - ubn = pcilscan(bno, list); - unlock(&pcicfginitlock); - return ubn; -} - static uchar pIIxget(Pcidev *router, uchar link) { @@ -554,74 +282,6 @@ pcicfgw8(router, 0x55 + (link>>1), pirq); } -static uchar -optiget(Pcidev *router, uchar link) -{ - uchar pirq = 0; - - /* link should be 0x02, 0x12, 0x22, 0x32 */ - if ((link & 0xcf) == 0x02) - pirq = pcicfgr8(router, 0xb8 + (link >> 5)); - return (link & 0x10)? (pirq >> 4): (pirq & 15); -} - -static void -optiset(Pcidev *router, uchar link, uchar irq) -{ - uchar pirq; - - pirq = pcicfgr8(router, 0xb8 + (link >> 5)); - pirq &= (link & 0x10)? 0x0f : 0xf0; - pirq |= (link & 0x10)? (irq << 4): (irq & 15); - pcicfgw8(router, 0xb8 + (link >> 5), pirq); -} - -static uchar -aliget(Pcidev *router, uchar link) -{ - /* No, you're not dreaming */ - static const uchar map[] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; - uchar pirq; - - /* link should be 0x01..0x08 */ - pirq = pcicfgr8(router, 0x48 + ((link-1)>>1)); - return (link & 1)? map[pirq&15]: map[pirq>>4]; -} - -static void -aliset(Pcidev *router, uchar link, uchar irq) -{ - /* Inverse of map in aliget */ - static const uchar map[] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; - uchar pirq; - - pirq = pcicfgr8(router, 0x48 + ((link-1)>>1)); - pirq &= (link & 1)? 0x0f: 0xf0; - pirq |= (link & 1)? (map[irq] << 4): (map[irq] & 15); - pcicfgw8(router, 0x48 + ((link-1)>>1), pirq); -} - -static uchar -cyrixget(Pcidev *router, uchar link) -{ - uchar pirq; - - /* link should be 1, 2, 3, 4 */ - pirq = pcicfgr8(router, 0x5c + ((link-1)>>1)); - return ((link & 1)? pirq >> 4: pirq & 15); -} - -static void -cyrixset(Pcidev *router, uchar link, uchar irq) -{ - uchar pirq; - - pirq = pcicfgr8(router, 0x5c + (link>>1)); - pirq &= (link & 1)? 0x0f: 0xf0; - pirq |= (link & 1)? (irq << 4): (irq & 15); - pcicfgw8(router, 0x5c + (link>>1), pirq); -} - typedef struct Bridge Bridge; struct Bridge { @@ -633,15 +293,7 @@ static Bridge southbridges[] = { { 0x8086, 0xffff, pIIxget, pIIxset }, // Intel * - { 0x1106, 0x0586, viaget, viaset }, // Viatech 82C586 - { 0x1106, 0x0596, viaget, viaset }, // Viatech 82C596 - { 0x1106, 0x0686, viaget, viaset }, // Viatech 82C686 { 0x1106, 0x3227, viaget, viaset }, // Viatech VT8237 - { 0x1045, 0xc700, optiget, optiset }, // Opti 82C700 - { 0x10b9, 0x1533, aliget, aliset }, // Al M1533 - { 0x1039, 0x0008, pIIxget, pIIxset }, // SI 503 - { 0x1039, 0x0496, pIIxget, pIIxset }, // SI 496 - { 0x1078, 0x0100, cyrixget, cyrixset }, // Cyrix 5530 Legacy { 0x1022, 0x746B, nil, nil }, // AMD 8111 { 0x10DE, 0x00D1, nil, nil }, // NVIDIA nForce 3 @@ -672,17 +324,16 @@ uchar checksum; }; -static ushort pciirqs; // Exclusive PCI irqs -static Bridge *southbridge; // Which southbridge to use. static void pcirouting(void) { + uchar *p, pin, irq, link, *map; + int size, i, fn, tbdf; + Bridge *southbridge; + Pcidev *sbpci, *pci; + Router *r; Slot *e; - Router *r; - int size, i, fn, tbdf; - Pcidev *sbpci, *pci; - uchar *p, pin, irq, link, *map; // Search for PCI interrupt routing table in BIOS for(p = (uchar *)KADDR(0xf0000); p < (uchar *)KADDR(0xfffff); p += 16) @@ -694,8 +345,9 @@ r = (Router *)p; - // print("PCI interrupt routing table version %d.%d at %.6uX\n", - // r->version[0], r->version[1], (ulong)r & 0xfffff); + if(0) + print("PCI interrupt routing table version %d.%d at %.6llux\n", + r->version[0], r->version[1], (uintptr)r & 0xfffff); tbdf = (BusPCI << 24)|(r->bus << 16)|(r->devfn << 8); sbpci = pcimatchtbdf(tbdf); @@ -710,27 +362,27 @@ break; if(i == nelem(southbridges)) { - print("pcirouting: ignoring south bridge %T %.4uX/%.4uX\n", tbdf, sbpci->vid, sbpci->did); + print("pcirouting: ignoring south bridge %T %.4ux/%.4ux\n", tbdf, sbpci->vid, sbpci->did); return; } southbridge = &southbridges[i]; if(southbridge->get == nil || southbridge->set == nil) return; - pciirqs = (r->pciirqs[1] << 8)|r->pciirqs[0]; - size = (r->size[1] << 8)|r->size[0]; for(e = (Slot *)&r[1]; (uchar *)e < p + size; e++) { - // print("%.2uX/%.2uX %.2uX: ", e->bus, e->dev, e->slot); - // for (i = 0; i != 4; i++) { - // uchar *m = &e->maps[i * 3]; - // print("[%d] %.2uX %.4uX ", - // i, m[0], (m[2] << 8)|m[1]); - // } - // print("\n"); + if(0){ + print("%.2ux/%.2ux %.2ux: ", e->bus, e->dev, e->slot); + for (i = 0; i != 4; i++) { + uchar *m = &e->maps[i * 3]; + print("[%d] %.2ux %.4ux ", + i, m[0], (m[2] << 8)|m[1]); + } + print("\n"); + } - for(fn = 0; fn != 8; fn++) { - tbdf = (BusPCI << 24)|(e->bus << 16)|((e->dev | fn) << 8); + for(fn = 0; fn <= Maxfn; fn++) { + tbdf = MKBUS(BusPCI, e->bus, e->dev, fn); pci = pcimatchtbdf(tbdf); if(pci == nil) continue; @@ -756,145 +408,77 @@ } } -static void pcireservemem(void); +static void +pcireservemem(void) +{ + int i; + Pcidev *p; + + for(p = nil; p = pcimatch(p, 0, 0); ) + for(i=0; imem); i++) + if(p->mem[i].bar && (p->mem[i].bar&1) == 0) + asmmapinit(p->mem[i].bar&~0x0F, p->mem[i].size, 5); +} static void pcicfginit(void) { - char *p; - Pcidev **list; - ulong mema, ioa; - int bno, n, pcibios; + int sbno, bno, n; + Pcidev **list, *p; + if(pcicfgmode != -1) + return; lock(&pcicfginitlock); - if(pcicfgmode != -1) - goto out; - - pcibios = 0; - if(getconf("*nobios")) - nobios = 1; - else if(getconf("*pcibios")) - pcibios = 1; - if(getconf("*nopcirouting")) - nopcirouting = 1; - - /* - * Try to determine which PCI configuration mode is implemented. - * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses - * a DWORD at 0xCF8 and another at 0xCFC and will pass through - * any non-DWORD accesses as normal I/O cycles. There shouldn't be - * a device behind these addresses so if Mode1 accesses fail try - * for Mode2 (Mode2 is deprecated). - */ - if(!pcibios){ - /* - * Bits [30:24] of PciADDR must be 0, - * according to the spec. - */ - n = inl(PciADDR); - if(!(n & 0x7F000000)){ - outl(PciADDR, 0x80000000); - outb(PciADDR+3, 0); - if(inl(PciADDR) & 0x80000000){ - pcicfgmode = 1; - pcimaxdno = 31; - } - } - outl(PciADDR, n); - - if(pcicfgmode < 0){ - /* - * The 'key' part of PciCSE should be 0. - */ - n = inb(PciCSE); - if(!(n & 0xF0)){ - outb(PciCSE, 0x0E); - if(inb(PciCSE) == 0x0E){ - pcicfgmode = 2; - pcimaxdno = 15; - } - } - outb(PciCSE, n); - } + if(pcicfgmode != -1){ + unlock(&pcicfginitlock); + return; } - - if(pcicfgmode < 0) - goto out; fmtinstall('T', tbdffmt); - if(p = getconf("*pcimaxbno")){ - n = strtoul(p, 0, 0); - if(n < pcimaxbno) - pcimaxbno = n; + /* + * Try to determine if PCI Mode1 configuration implemented. + * (Bits [30:24] of PciADDR must be 0, according to the spec.) + * Mode2 won't appear in 64-bit machines. + */ + n = inl(PciADDR); + if(!(n & 0x7F000000)){ + outl(PciADDR, 0x80000000); + outb(PciADDR+3, 0); + if(inl(PciADDR) & 0x80000000) + pcicfgmode = 1; } - if(p = getconf("*pcimaxdno")){ - n = strtoul(p, 0, 0); - if(n < pcimaxdno) - pcimaxdno = n; + outl(PciADDR, n); + + if(pcicfgmode < 0){ + unlock(&pcicfginitlock); + return; } list = &pciroot; - for(bno = 0; bno <= pcimaxbno; bno++) { - int sbno = bno; + for(bno = 0; bno <= Maxbus; bno++) { + sbno = bno; bno = pcilscan(bno, list); while(*list) list = &(*list)->link; - - if (sbno == 0) { - Pcidev *pci; - - /* - * If we have found a PCI-to-Cardbus bridge, make sure - * it has no valid mappings anymore. - */ - for(pci = pciroot; pci != nil; pci = pci->link){ - if (pci->ccrb == 6 && pci->ccru == 7) { - ushort bcr; - - /* reset the cardbus */ - bcr = pcicfgr16(pci, PciBCR); - pcicfgw16(pci, PciBCR, 0x40 | bcr); - delay(50); - } + if(sbno != 0) + continue; + /* + * If we have found a PCI-to-Cardbus bridge, make sure + * it has no valid mappings anymore. + */ + for(p = pciroot; p != nil; p = p->link){ + if (p->ccrb == 6 && p->ccru == 7) { + /* reset the cardbus */ + pcicfgw16(p, PciBCR, 0x40 | pcicfgr16(p, PciBCR)); + delay(50); } } } - if(pciroot == nil) - goto out; - - if(nobios) { - /* - * Work out how big the top bus is - */ - mema = 0; - ioa = 0; - pcibusmap(pciroot, &mema, &ioa, 0); - - DBG("Sizes: mem=%8.8lux size=%8.8lux io=%8.8lux\n", - mema, pcimask(mema), ioa); - - /* - * Align the windows and map it - */ - ioa = 0x1000; - mema = 0x90000000; - - pcilog("Mask sizes: mem=%lux io=%lux\n", mema, ioa); - - pcibusmap(pciroot, &mema, &ioa, 1); - DBG("Sizes2: mem=%lux io=%lux\n", mema, ioa); - - unlock(&pcicfginitlock); - return; - } - - if (!nopcirouting) + if(pciroot != nil && getconf("*nopcirouting") == nil) pcirouting(); - -out: pcireservemem(); unlock(&pcicfginitlock); @@ -902,208 +486,99 @@ pcihinv(nil); } -static void -pcireservemem(void) +static int +pcicfgrw(int tbdf, int r, int data, int rw, int w) { - int i; - Pcidev *p; - - /* - * mark all the physical address space claimed by pci devices - * as in use, so that upaalloc doesn't give it out. - */ - for(p=pciroot; p; p=p->list) - for(i=0; imem); i++) - if(p->mem[i].bar && (p->mem[i].bar&1) == 0) - asmmapinit(p->mem[i].bar&~0x0F, p->mem[i].size, 5); -} + int o, x, er; -static int -pcicfgrw8(int tbdf, int rno, int data, int read) -{ - int o, type, x; - - if(pcicfgmode == -1) - pcicfginit(); - - if(BUSBNO(tbdf)) - type = 0x01; - else - type = 0x00; - x = -1; - if(BUSDNO(tbdf) > pcimaxdno) - return x; + pcicfginit(); + if(pcicfgmode != 1) + return -1; + if(BUSDNO(tbdf) > Maxdev) + return -1; lock(&pcicfglock); - switch(pcicfgmode){ - - case 1: - o = rno & 0x03; - rno &= ~0x03; - outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); - if(read) + o = r & 4-w; + er = r&0xfc | (r & 0xf00)<<16; + outl(PciADDR, 0x80000000|BUSBDF(tbdf)|er); + if(rw == Read){ + x = -1; + switch(w){ + case 1: x = inb(PciDATA+o); - else + break; + case 2: + x = ins(PciDATA+o); + break; + case 4: + x = inl(PciDATA+o); + break; + } + }else{ + x = 0; + switch(w){ + case 1: outb(PciDATA+o, data); - outl(PciADDR, 0); - break; - - case 2: - outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); - outb(PciFORWARD, BUSBNO(tbdf)); - if(read) - x = inb((0xC000|(BUSDNO(tbdf)<<8)) + rno); - else - outb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); - outb(PciCSE, 0); - break; + break; + case 2: + outs(PciDATA+o, data); + break; + case 4: + outl(PciDATA+o, data); + break; + } } +// outl(PciADDR, 0); unlock(&pcicfglock); return x; } int -pcicfgr8(Pcidev* pcidev, int rno) +pcicfgr8(Pcidev *p, int rno) { - return pcicfgrw8(pcidev->tbdf, rno, 0, 1); + return pcicfgrw(p->tbdf, rno, 0, Read, 1); } void -pcicfgw8(Pcidev* pcidev, int rno, int data) +pcicfgw8(Pcidev *p, int rno, int data) { - pcicfgrw8(pcidev->tbdf, rno, data, 0); -} - -static int -pcicfgrw16(int tbdf, int rno, int data, int read) -{ - int o, type, x; - - if(pcicfgmode == -1) - pcicfginit(); - - if(BUSBNO(tbdf)) - type = 0x01; - else - type = 0x00; - x = -1; - if(BUSDNO(tbdf) > pcimaxdno) - return x; - - lock(&pcicfglock); - switch(pcicfgmode){ - - case 1: - o = rno & 0x02; - rno &= ~0x03; - outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); - if(read) - x = ins(PciDATA+o); - else - outs(PciDATA+o, data); - outl(PciADDR, 0); - break; - - case 2: - outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); - outb(PciFORWARD, BUSBNO(tbdf)); - if(read) - x = ins((0xC000|(BUSDNO(tbdf)<<8)) + rno); - else - outs((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); - outb(PciCSE, 0); - break; - } - unlock(&pcicfglock); - - return x; + pcicfgrw(p->tbdf, rno, data, Write, 1); } int -pcicfgr16(Pcidev* pcidev, int rno) +pcicfgr16(Pcidev *p, int rno) { - return pcicfgrw16(pcidev->tbdf, rno, 0, 1); + return pcicfgrw(p->tbdf, rno, 0, Read, 2); } void -pcicfgw16(Pcidev* pcidev, int rno, int data) +pcicfgw16(Pcidev *p, int rno, int data) { - pcicfgrw16(pcidev->tbdf, rno, data, 0); -} - -static int -pcicfgrw32(int tbdf, int rno, int data, int read) -{ - int type, x; - - if(pcicfgmode == -1) - pcicfginit(); - - if(BUSBNO(tbdf)) - type = 0x01; - else - type = 0x00; - x = -1; - if(BUSDNO(tbdf) > pcimaxdno) - return x; - - lock(&pcicfglock); - switch(pcicfgmode){ - - case 1: - rno &= ~0x03; - outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); - if(read) - x = inl(PciDATA); - else - outl(PciDATA, data); - outl(PciADDR, 0); - break; - - case 2: - outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); - outb(PciFORWARD, BUSBNO(tbdf)); - if(read) - x = inl((0xC000|(BUSDNO(tbdf)<<8)) + rno); - else - outl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); - outb(PciCSE, 0); - break; - } - unlock(&pcicfglock); - - return x; + pcicfgrw(p->tbdf, rno, data, Write, 2); } int -pcicfgr32(Pcidev* pcidev, int rno) +pcicfgr32(Pcidev *p, int rno) { - return pcicfgrw32(pcidev->tbdf, rno, 0, 1); + return pcicfgrw(p->tbdf, rno, 0, Read, 4); } void -pcicfgw32(Pcidev* pcidev, int rno, int data) +pcicfgw32(Pcidev *p, int rno, int data) { - pcicfgrw32(pcidev->tbdf, rno, data, 0); + pcicfgrw(p->tbdf, rno, data, Write, 4); } Pcidev* pcimatch(Pcidev* prev, int vid, int did) { - if(pcicfgmode == -1) - pcicfginit(); - - if(prev == nil) - prev = pcilist; - else - prev = prev->list; - - while(prev != nil){ + pcicfginit(); + prev = prev? prev->list: pcilist; + for(; prev != nil; prev = prev->list){ if((vid == 0 || prev->vid == vid) && (did == 0 || prev->did == did)) break; - prev = prev->list; } return prev; } @@ -1111,36 +586,12 @@ Pcidev* pcimatchtbdf(int tbdf) { - Pcidev *pcidev; + Pcidev *p; - if(pcicfgmode == -1) - pcicfginit(); - - for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) { - if(pcidev->tbdf == tbdf) + for(p = nil; p = pcimatch(p, 0, 0); ) + if(p->tbdf == tbdf) break; - } - return pcidev; -} - -uchar -pciipin(Pcidev *pci, uchar pin) -{ - if (pci == nil) - pci = pcilist; - - while (pci) { - uchar intl; - - if (pcicfgr8(pci, PciINTP) == pin && pci->intl != 0 && pci->intl != 0xff) - return pci->intl; - - if (pci->bridge && (intl = pciipin(pci->bridge, pin)) != 0) - return intl; - - pci = pci->list; - } - return 0; + return p; } static void @@ -1149,11 +600,6 @@ int i; Pcidev *t; - if(p == nil) { - putstrn(PCICONS.output, PCICONS.ptr); - p = pciroot; - print("bus dev type vid did intl memory\n"); - } for(t = p; t != nil; t = t->link) { print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d ", BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf), @@ -1162,8 +608,7 @@ for(i = 0; i < nelem(p->mem); i++) { if(t->mem[i].size == 0) continue; - print("%d:%.8lux %d ", i, - t->mem[i].bar, t->mem[i].size); + print("%d:%.8lux %d ", i, t->mem[i].bar, t->mem[i].size); } if(t->ioa.bar || t->ioa.size) print("ioa:%.8lux %d ", t->ioa.bar, t->ioa.size); @@ -1173,19 +618,20 @@ print("->%d", BUSBNO(t->bridge->tbdf)); print("\n"); } - while(p != nil) { + for(; p != nil; p = p->link) if(p->bridge != nil) pcilhinv(p->bridge); - p = p->link; - } } void pcihinv(Pcidev* p) { - if(pcicfgmode == -1) - pcicfginit(); + pcicfginit(); lock(&pcicfginitlock); + if(p == nil){ + p = pciroot; + print("bus dev type vid did intl memory\n"); + } pcilhinv(p); unlock(&pcicfginitlock); } @@ -1195,29 +641,10 @@ { Pcidev *p; - if(pcicfgmode == -1) - pcicfginit(); - - for(p = pcilist; p != nil; p = p->list) { + for(p = nil; p = pcimatch(p, 0, 0); ) /* don't mess with the bridges */ - if(p->ccrb == 0x06) - continue; - pciclrbme(p); - } -} - -void -pcisetioe(Pcidev* p) -{ - p->pcr |= IOen; - pcicfgw16(p, PciPCR, p->pcr); -} - -void -pciclrioe(Pcidev* p) -{ - p->pcr &= ~IOen; - pcicfgw16(p, PciPCR, p->pcr); + if(p->ccrb != 0x06) + pciclrbme(p); } void @@ -1282,40 +709,33 @@ return -1; } +enum { + Pmgcap = 2, /* capabilities; 2 bytes*/ + Pmgctl = 4, /* ctl/status; 2 bytes */ + Pmgbrg = 6, /* bridge support */ + Pmgdata = 7, +}; + int pcigetpms(Pcidev* p) { - int pmcsr, ptr; + int ptr; if((ptr = pcicap(p, PciCapPMG)) == -1) return -1; - - /* - * Power Management Register Block: - * offset 0: Capability ID - * 1: next item pointer - * 2: capabilities - * 4: control/status - * 6: bridge support extensions - * 7: data - */ - pmcsr = pcicfgr16(p, ptr+4); - - return pmcsr & 0x0003; + return pcicfgr16(p, ptr+Pmgctl) & 0x0003; } int pcisetpms(Pcidev* p, int state) { - int ostate, pmc, pmcsr, ptr; + int pmc, pmcsr, ptr; if((ptr = pcicap(p, PciCapPMG)) == -1) return -1; - pmc = pcicfgr16(p, ptr+2); - pmcsr = pcicfgr16(p, ptr+4); - ostate = pmcsr & 0x0003; - pmcsr &= ~0x0003; + pmc = pcicfgr16(p, ptr+Pmgcap); + pmcsr = pcicfgr16(p, ptr+Pmgctl); switch(state){ default: @@ -1333,8 +753,6 @@ case 3: break; } - pmcsr |= state; - pcicfgw16(p, ptr+4, pmcsr); - - return ostate; + pcicfgw16(p, ptr+4, (pmcsr & ~3) | state); + return pmcsr & 3; } diff -r dd5286addc1a -r 784debe5594b sys/src/nix/k10/fns.h --- a/sys/src/nix/k10/fns.h Tue Mar 06 23:39:47 2012 +0100 +++ b/sys/src/nix/k10/fns.h Tue Mar 06 23:46:39 2012 +0100 @@ -109,8 +109,6 @@ void outl(int, ulong); void outsl(int, void*, int); int pcicap(Pcidev*, int); -int pciscan(int, Pcidev**); -ulong pcibarsize(Pcidev*, int); int pcicfgr8(Pcidev*, int); int pcicfgr16(Pcidev*, int); int pcicfgr32(Pcidev*, int); @@ -118,16 +116,13 @@ void pcicfgw16(Pcidev*, int, int); void pcicfgw32(Pcidev*, int, int); void pciclrbme(Pcidev*); -void pciclrioe(Pcidev*); void pciclrmwi(Pcidev*); int pcigetpms(Pcidev*); void pcihinv(Pcidev*); -uchar pciipin(Pcidev*, uchar); -Pcidev* pcimatch(Pcidev*, int, int); -Pcidev* pcimatchtbdf(int); +Pcidev* pcimatch(Pcidev*, int, int); +Pcidev* pcimatchtbdf(int); void pcireset(void); void pcisetbme(Pcidev*); -void pcisetioe(Pcidev*); void pcisetmwi(Pcidev*); int pcisetpms(Pcidev*, int); void printcpufreq(void);