nix support for 64-bit bars. this wasn't done till now since no hardware had been encountered with 64-bit bars, and it's not clear what benefit 64-bit bars have. 32-bit oses and boot environments can't use them, and it's irrelevant for 64-bit oses. so it's a mystery why this option is provided for pcs. regardless, the consequence for not supporting 64-bit bars is a unbootable system that's difficult to diagnose. vmap() works, but mmio access does not. Reference: /n/atom/patch/applied/nix64bitbar Date: Sat Jan 11 11:25:44 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/k10/ether82563.c Sat Jan 11 11:12:44 2014 +++ /sys/src/nix/k10/ether82563.c Sat Jan 11 11:12:45 2014 @@ -1093,6 +1093,7 @@ } if(i != 0){ ctlr->rdt = rdt; + sfence(); csr32w(ctlr, Rdt, rdt); } return 0; @@ -1144,6 +1145,7 @@ ctlr->rb[i] = nil; freeb(bp); } + if(cttab[ctlr->type].flag & F75) csr32w(ctlr, Rxdctl, 1<phyerrata == 0){ c->phyerrata++; phywrite(c, phyno, Phyprst, Prst); /* try a port reset */ - print("%s: phy port reset\n", cname(c)); + print("ether%d: %s: phy port reset\n", e->ctlrno, cname(c)); } else c->phyerrata = 0; @@ -1397,10 +1399,13 @@ e = v; c = e->ctlr; phyno = cttab[c->type].phyno; +uint dbg = c->type == i82563; +if(dbg)print("#l%d lproc\n", e->ctlrno); if(c->type == i82573 && (phy = phyread(c, 1, Phyier)) != ~0) phywrite(c, phyno, Phyier, phy | Lscie | Ancie | Spdie | Panie); for(;;){ +if(dbg)print("phyread(c, %d, Physsr)\n", phyno); phy = phyread(c, phyno, Physsr); if(phy == ~0){ phy = 0; @@ -1748,8 +1753,9 @@ static int fload(Ctlr *c) { - uint data, io, r, adr; + uint data, r, adr; u16int sum; + uintmem io; Flash f; io = c->pcidev->mem[1].bar & ~(uintmem)0xf; --- /sys/src/nix/k10/pci.c Sat Jan 11 11:12:47 2014 +++ /sys/src/nix/k10/pci.c Sat Jan 11 11:12:47 2014 @@ -133,11 +133,37 @@ return -(size & ~0x0F); } +static void +pcibars(Pcidev *p) +{ + int i, o; + u32int bar; + + for(i = 0; i < nelem(p->mem); i++) { + o = PciBAR0+4*i; + p->mem[i].bar = (u32int)pcicfgr32(p, o); + p->mem[i].size = pcibarsize(p, o); + if(i&1 || (p->mem[i].bar & 2<<1) == 0) + continue; + bar = pcicfgr32(p, o+4); + if(sizeof(uintmem) >= sizeof(u64int)) + p->mem[i].bar |= (u64int)bar<<32; + else if(bar != 0){ + print("%T: warning 64-bit bar %d too large\n", p->tbdf, i); + p->mem[i].bar = 0; + p->mem[i].size = 0; + } + i++; + p->mem[i].bar = 0; + p->mem[i].size = 0; + } +} + static int pcilscan(int bno, Pcidev** list) { Pcidev *p, *head, *tail; - int dno, fno, i, hdt, l, maxfno, maxubn, sbn, tbdf, ubn; + int dno, fno, hdt, l, maxfno, maxubn, sbn, tbdf, ubn; maxubn = bno; head = nil; @@ -192,12 +218,8 @@ */ switch(p->ccrb) { default: - if((hdt & 0x7F) != 0) - break; - for(i = 0; i < nelem(p->mem); i++) { - p->mem[i].bar = (u32int)pcicfgr32(p, PciBAR0+4*i); - p->mem[i].size = pcibarsize(p, PciBAR0+4*i); - } + if((hdt & 0x7F) == 0) + pcibars(p); break; case 0x00: @@ -603,18 +625,15 @@ for(i = 0; i < nelem(p->mem); i++) { if(t->mem[i].size == 0) continue; - print("%d:%#P %d ", i, - t->mem[i].bar, t->mem[i].size); + print("%d:%#P %d ", i, t->mem[i].bar, t->mem[i].size); } if(t->bridge != nil) print("->%d", BUSBNO(t->bridge->tbdf)); print("\n"); } - while(p != nil) { + for(; p != nil; p = p->link) if(p->bridge != nil) pcihinv(p->bridge); - p = p->link; - } } void --- /sys/src/nix/k10/etherbcm.c Sat Jan 11 11:12:49 2014 +++ /sys/src/nix/k10/etherbcm.c Sat Jan 11 11:12:50 2014 @@ -30,7 +30,7 @@ u32int *nic, *status; u32int *recvret, *recvprod, *sendr; - uintptr port; + uintmem port; uint recvreti, recvprodi, sendri, sendcleani; Block **sends; Block **rxs; --- /sys/src/nix/k10/etheriwl.c Sat Jan 11 11:12:52 2014 +++ /sys/src/nix/k10/etheriwl.c Sat Jan 11 11:12:53 2014 @@ -315,7 +315,7 @@ Wifi *wifi; int type; - int port; + uintmem port; int active; int attached; --- /sys/src/nix/k10/usbohci.c Sat Jan 11 11:12:56 2014 +++ /sys/src/nix/k10/usbohci.c Sat Jan 11 11:12:58 2014 @@ -2382,7 +2382,7 @@ */ if(p->ccrb != 0xc || p->ccru != 3 || p->ccrp != 0x10) continue; - pa = p->mem[0].bar & ~0x0F; + pa = p->mem[0].bar & ~(uintmem)0xf; if(p->intl == 0xFF || p->intl == 0) { print("usb: ohci: no irq assigned for port %#P\n", pa); continue; --- /sys/src/nix/k10/usbuhci.c Sat Jan 11 11:13:00 2014 +++ /sys/src/nix/k10/usbuhci.c Sat Jan 11 11:13:02 2014 @@ -2076,11 +2076,10 @@ static void scanpci(void) { - static int already = 0; - int io; - int i; + int i, io; Ctlr *ctlr; Pcidev *p; + static int already = 0; if(already) return; @@ -2094,7 +2093,7 @@ continue; switch(p->ccrp){ case 0: - io = p->mem[4].bar & ~0x0F; + io = p->mem[4].bar & ~(uintmem)0xf; break; default: continue;