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; diff --git a/sys/src/9/bcm64/dat.h b/sys/src/9/bcm64/dat.h index fcbd42bba..c5e19ab0d 100644 --- a/sys/src/9/bcm64/dat.h +++ b/sys/src/9/bcm64/dat.h @@ -249,7 +249,8 @@ struct Soc { /* SoC dependent configuration */ uintptr physio; uintptr virtio; uintptr armlocal; - uintptr pciwin; + uintptr pciwin; /* PCI outbound window CPU->PCI */ + uintptr pcidmawin; /* PCI inbound window PCI->DRAM */ int oscfreq; }; extern Soc soc; diff --git a/sys/src/9/bcm64/io.h b/sys/src/9/bcm64/io.h index ef6fab282..dec69a5dc 100644 --- a/sys/src/9/bcm64/io.h +++ b/sys/src/9/bcm64/io.h @@ -6,5 +6,5 @@ enum { IRQether = IRQgic + 29, }; -#define PCIWINDOW 0 +#define PCIWINDOW soc.pcidmawin #define PCIWADDR(va) (PADDR(va)+PCIWINDOW) diff --git a/sys/src/9/bcm64/pcibcm.c b/sys/src/9/bcm64/pcibcm.c index 5a6780465..0ba9b5111 100644 --- a/sys/src/9/bcm64/pcibcm.c +++ b/sys/src/9/bcm64/pcibcm.c @@ -244,6 +244,16 @@ void pcibcmlink(void) { int log2dmasize = 30; // 1GB + char *s; + + if((s = getconf("*pciwin")) != nil){ + print("*pciwin: %s\n", s); + soc.pciwin = (uintptr)strtoll(s, nil, 16); + } + if((s = getconf("*pcidmawin")) != nil){ + print("*pcidmawin: %s\n", s); + soc.pcidmawin = (uintptr)strtoll(s, nil, 16); + } regs[RGR1_SW_INIT_1] |= 3; delay(200); @@ -266,8 +276,8 @@ pcibcmlink(void) // SCB_ACCESS_EN, CFG_READ_UR_MODE, MAX_BURST_SIZE_128, SCB0SIZE regs[MISC_MISC_CTRL] = 1<<12 | 1<<13 | 0<<20 | (log2dmasize-15)<<27; - regs[MISC_RC_BAR2_CONFIG_LO] = (log2dmasize-15); - regs[MISC_RC_BAR2_CONFIG_HI] = 0; + regs[MISC_RC_BAR2_CONFIG_LO] = ((u32int)soc.pcidmawin & ~0x1F) | (log2dmasize-15); + regs[MISC_RC_BAR2_CONFIG_HI] = soc.pcidmawin >> 32; regs[MISC_RC_BAR1_CONFIG_LO] = 0; regs[MISC_RC_BAR3_CONFIG_LO] = 0;