summaryrefslogtreecommitdiff
path: root/sys/src/9/bcm
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2021-02-06 13:47:45 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2021-02-06 13:47:45 +0100
commitefcfdd23d72178ed873982f957cbc95b2a1de4c5 (patch)
tree77996b64f4d7a944d455a173536546eb457e30e5 /sys/src/9/bcm
parent0e381493bfa4963c406cd6340ddcc0e43a4808e2 (diff)
bcm64: get inbound and outbound pci window base address from device tree
On the pi400, the xhci reset firmware mailbox request assumes that the pci windows match the ones specified in the device tree. The inbound window (pcidmawin) also varies now depending on the amount of memory installed. It is all pretty ridiculous, as the firmware could as well just read the pci controllers hardware register to determine the window configuration and the os could keep a nice simple 1:1 mapping (with pci dma addresses == physical addresses).
Diffstat (limited to 'sys/src/9/bcm')
-rw-r--r--sys/src/9/bcm/bootargs.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/sys/src/9/bcm/bootargs.c b/sys/src/9/bcm/bootargs.c
index aac14c501..b0feae75e 100644
--- a/sys/src/9/bcm/bootargs.c
+++ b/sys/src/9/bcm/bootargs.c
@@ -12,6 +12,7 @@ static char *confname[MAXCONF];
static char *confval[MAXCONF];
static int nconf;
static char maxmem[256];
+static char pciwin[38], pcidmawin[38];
static int
findconf(char *k)
@@ -89,23 +90,23 @@ beget4(uchar *p)
static void
devtreeprop(char *path, char *key, void *val, int len)
{
+ uvlong addr, size;
+ uchar *p = val;
+ char *s;
+
if((strcmp(path, "/memory") == 0 || strcmp(path, "/memory@0") == 0)
&& strcmp(key, "reg") == 0){
if(findconf("*maxmem") < 0 && len > 0 && (len % (3*4)) == 0){
- uvlong top;
- uchar *p = val;
- char *s;
-
- top = (uvlong)beget4(p)<<32 | beget4(p+4);
- top += beget4(p+8);
- s = seprint(maxmem, &maxmem[sizeof(maxmem)], "%#llux", top);
+ addr = (uvlong)beget4(p)<<32 | beget4(p+4);
+ addr += beget4(p+8);
+ s = seprint(maxmem, &maxmem[sizeof(maxmem)], "%#llux", addr);
p += 3*4;
len -= 3*4;
while(len > 0){
- top = (uvlong)beget4(p)<<32 | beget4(p+4);
- s = seprint(s, &maxmem[sizeof(maxmem)], " %#llux", top);
- top += beget4(p+8);
- s = seprint(s, &maxmem[sizeof(maxmem)], " %#llux", top);
+ addr = (uvlong)beget4(p)<<32 | beget4(p+4);
+ s = seprint(s, &maxmem[sizeof(maxmem)], " %#llux", addr);
+ addr += beget4(p+8);
+ s = seprint(s, &maxmem[sizeof(maxmem)], " %#llux", addr);
p += 3*4;
len -= 3*4;
}
@@ -113,6 +114,22 @@ devtreeprop(char *path, char *key, void *val, int len)
}
return;
}
+ if(strncmp(path, "/scb/pcie@", 10) == 0 && len == (3*4 + 4*4)){
+ if((beget4(p) & 0x3000000) == 0x2000000){
+ size = (uvlong)beget4(p+5*4)<<32 | beget4(p+5*4+4);
+ if(strcmp(key, "ranges") == 0 && findconf("*pciwin") < 0){
+ addr = (uvlong)beget4(p+3*4)<<32 | beget4(p+4*4);
+ snprint(pciwin, sizeof(pciwin), "%#llux %#llux", addr, addr+size);
+ addconf("*pciwin", pciwin);
+ } else if(strcmp(key, "dma-ranges") == 0 && findconf("*pcidmawin") < 0){
+ addr = (uvlong)beget4(p+1*4)<<32 | beget4(p+2*4);
+ addr -= (uvlong)beget4(p+3*4)<<32 | beget4(p+4*4);
+ snprint(pcidmawin, sizeof(pcidmawin), "%#llux %#llux", addr, addr+size);
+ addconf("*pcidmawin", pcidmawin);
+ }
+ }
+ return;
+ }
if(strcmp(path, "/chosen") == 0 && strcmp(key, "bootargs") == 0){
if(len > BOOTARGSLEN)
len = BOOTARGSLEN;