summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-04-08 03:34:08 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2015-04-08 03:34:08 +0200
commitb7ceab84d3abd72058c6d6532ebaa7a76921d370 (patch)
tree9f744137f4c47e58968bb6b503884361ebd5aff0
parentfba26da490b453f58b727954184650f9767fab94 (diff)
downloadplan9front-b7ceab84d3abd72058c6d6532ebaa7a76921d370.tar.xz
pc, pc64: handle 64-bit pci membars
this avoids listing the upper half of 64-bit membars in Pcidev.mem[] array avoiding potential confusion in drivers. we also check if the upper half is programmed to zero by bios and otherwise zap the entry in Pcidev.mem[] and print a warning.
-rw-r--r--sys/src/9/pc/pci.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/src/9/pc/pci.c b/sys/src/9/pc/pci.c
index 1242892a5..cd8865f8f 100644
--- a/sys/src/9/pc/pci.c
+++ b/sys/src/9/pc/pci.c
@@ -249,6 +249,7 @@ pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg)
if(size == 0)
continue;
+ p->mem[i].size = size;
if(v & 1) {
itb->dev = p;
itb->bar = i;
@@ -260,9 +261,10 @@ pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg)
mtb->bar = i;
mtb->siz = size;
mtb++;
- }
- p->mem[i].size = size;
+ if((v & 7) == 4)
+ i++;
+ }
}
}
@@ -438,11 +440,24 @@ pcilscan(int bno, Pcidev** list, Pcidev *parent)
case 0x0C: /* serial bus controllers */
if((hdt & 0x7F) != 0)
break;
- rno = PciBAR0 - 4;
+ rno = PciBAR0;
for(i = 0; i < nelem(p->mem); i++) {
- rno += 4;
p->mem[i].bar = pcicfgr32(p, rno);
p->mem[i].size = pcibarsize(p, rno);
+ if((p->mem[i].bar & 7) == 4){
+ ulong hi;
+
+ rno += 4;
+ hi = pcicfgr32(p, rno);
+ if(hi != 0){
+ print("ignoring 64-bit bar %d: %llux %d from %T\n",
+ i, (uvlong)hi<<32 | p->mem[i].bar, p->mem[i].size, p->tbdf);
+ p->mem[i].bar = 0;
+ p->mem[i].size = 0;
+ }
+ i++;
+ }
+ rno += 4;
}
break;