summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/pcipc.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2020-11-03 20:46:09 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2020-11-03 20:46:09 +0100
commit0ba91ae22a06af3a7561db15973dd98f715cc9eb (patch)
tree6f5871cee6c3880847b6548902855a2f45e397da /sys/src/9/pc/pcipc.c
parentaad55ccc2d1e4004574ce96389ee8e5cd9bb2444 (diff)
pc, pc64: allocate i/o port space for unassigned pci bars, move ioalloc() to port/iomap.c
With some newer UEFI firmware, not all pci bars get programmed and we have to assign them ourselfs. This was already done for memory bars. This change adds the same for i/o port space, by providing a ioreservewin() function which can be used to allocate port space within the parent pci-pci bridge window. Also, the pci code now allocates the pci config space i/o ports 0xCF8/0xCFC so userspace needs to use devpnp to access pci config space now. (see latest realemu change). Also, this moves the ioalloc()/iofree() code out of devarch into port/iomap.c as it can be shared with the ppc mtx kernel.
Diffstat (limited to 'sys/src/9/pc/pcipc.c')
-rw-r--r--sys/src/9/pc/pcipc.c95
1 files changed, 62 insertions, 33 deletions
diff --git a/sys/src/9/pc/pcipc.c b/sys/src/9/pc/pcipc.c
index a6850d37f..364fa81d2 100644
--- a/sys/src/9/pc/pcipc.c
+++ b/sys/src/9/pc/pcipc.c
@@ -528,59 +528,78 @@ pcirouting(void)
}
static void
-pcireservemem(void)
+pcireserve(void)
{
+ char tag[64];
Pcidev *p;
uvlong pa;
+ ulong io;
int i;
/*
- * mark all valid physical address space claimed by pci devices
- * as in use, so that upaalloc doesn't give it out.
+ * mark all valid io/mem address space claimed by pci devices
+ * so that ioreserve/upaalloc doesn't give it out.
*/
for(p=pciroot; p != nil; p=p->list){
+ snprint(tag, sizeof(tag), "%T", p->tbdf);
for(i=0; i<nelem(p->mem); i++){
if(p->mem[i].size == 0)
continue;
- if(p->mem[i].bar & 1)
- continue;
- if((p->mem[i].bar & ~0xFULL) == 0)
- continue;
- upaalloc(p->mem[i].bar&~0xFULL, p->mem[i].size, 0);
+ if(p->mem[i].bar & 1){
+ io = p->mem[i].bar & ~3ULL;
+ if(io == 0)
+ continue;
+ ioreserve(io, p->mem[i].size, 0, tag);
+ } else {
+ pa = p->mem[i].bar & ~0xFULL;
+ if(pa == 0)
+ continue;
+ upaalloc(pa, p->mem[i].size, 0);
+ }
}
}
/*
- * allocate physical address space for unassigned membars.
+ * allocate io/mem address space for unassigned membars.
*/
for(p=pciroot; p != nil; p=p->list){
+ snprint(tag, sizeof(tag), "%T", p->tbdf);
for(i=0; i<nelem(p->mem); i++){
if(p->mem[i].size == 0)
continue;
- if(p->mem[i].bar & ~0xEULL)
- continue;
-
- if(p->parent == nil){
- pa = upaalloc(-1ULL,
- p->mem[i].size, p->mem[i].size);
- } else if(p->mem[i].bar & 8){
- pa = upaallocwin(p->parent->prefa.bar, p->parent->prefa.size,
- p->mem[i].size, p->mem[i].size);
- if(pa == -1ULL)
- goto Mem;
+ if(p->mem[i].bar & 1){
+ if(p->mem[i].bar & ~0x3ULL)
+ continue;
+ if(p->parent == nil){
+ io = ioreserve(-1, p->mem[i].size, p->mem[i].size, tag);
+ } else {
+ io = ioreservewin(p->parent->ioa.bar, p->parent->ioa.size,
+ p->mem[i].size, p->mem[i].size, tag);
+ }
+ if(io == -1)
+ continue;
+ p->mem[i].bar |= io;
} else {
- Mem:
- pa = upaallocwin(p->parent->mema.bar, p->parent->mema.size,
- p->mem[i].size, p->mem[i].size);
+ if(p->mem[i].bar & ~0xFULL)
+ continue;
+ if(p->parent == nil){
+ pa = upaalloc(-1ULL, p->mem[i].size, p->mem[i].size);
+ } else if(p->mem[i].bar & 8){
+ pa = upaallocwin(p->parent->prefa.bar, p->parent->prefa.size,
+ p->mem[i].size, p->mem[i].size);
+ if(pa == -1ULL)
+ goto Mem;
+ } else {
+ Mem:
+ pa = upaallocwin(p->parent->mema.bar, p->parent->mema.size,
+ p->mem[i].size, p->mem[i].size);
+ }
+ if(pa == -1ULL)
+ continue;
+ p->mem[i].bar |= pa;
}
- if(pa == -1ULL)
- continue;
-
- p->mem[i].bar |= pa;
pcisetbar(p, PciBAR0 + i*4, p->mem[i].bar);
-
- DBG("%T: bar%d: fixed %.8lluX %d\n",
- p->tbdf, i, p->mem[i].bar, p->mem[i].size);
+ DBG("%s: bar%d: fixed %.8lluX %d\n", tag, i, p->mem[i].bar, p->mem[i].size);
}
}
}
@@ -620,6 +639,9 @@ pcicfginit(void)
outl(PciADDR, 0x80000000);
outb(PciADDR+3, 0);
if(inl(PciADDR) & 0x80000000){
+ ioalloc(PciADDR, 4, 0, "pcicfg.addr");
+ ioalloc(PciDATA, 4, 0, "pcicfg.data");
+
pcicfgmode = 1;
pcimaxdno = 31;
}
@@ -634,6 +656,10 @@ pcicfginit(void)
if(!(n & 0xF0)){
outb(PciCSE, 0x0E);
if(inb(PciCSE) == 0x0E){
+ ioalloc(PciCSE, 1, 0, "pcicfg.cse");
+ ioalloc(PciFORWARD, 1, 0, "pcicfg.forward");
+ ioalloc(0xC000, 0x1000, 0, "pcicfg.io");
+
pcicfgmode = 2;
pcimaxdno = 15;
}
@@ -705,16 +731,19 @@ pcicfginit(void)
*/
mema = upaalloc(-1ULL, mema, mema);
if(mema == -1ULL)
- panic("pcicfginit: can't allocate pci window");
+ panic("pcicfginit: can't allocate pci mem window");
+
+ ioa = ioreserve(-1, ioa, ioa, "pci");
+ if(ioa == -1UL)
+ panic("pcicfginit: can't allocate pci io window");
- ioa = 0x1000;
DBG("Base: mem=%.8llux io=%lux\n", mema, ioa);
pcibusmap(pciroot, &mema, &ioa, 1);
DBG("Limit: mem=%.8llux io=%lux\n", mema, ioa);
goto out;
}
- pcireservemem();
+ pcireserve();
if(!nopcirouting)
pcirouting();