From e9af397dc7a178fba55477e58089723855b3a1af Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sat, 6 Feb 2021 13:33:27 +0100 Subject: [PATCH 1/3] pc, pc64: warn when running out of conf.mem[] entries in meminit() --- sys/src/9/pc/memory.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/src/9/pc/memory.c b/sys/src/9/pc/memory.c index 6df499728..8853d4c0b 100644 --- a/sys/src/9/pc/memory.c +++ b/sys/src/9/pc/memory.c @@ -568,13 +568,16 @@ meminit(void) size = memmapsize(base, BY2PG) & ~(BY2PG-1); if(size == 0) continue; + if(cm >= &conf.mem[nelem(conf.mem)]){ + print("meminit: out of entries, loosing: %#p (%llud)\n", base, (uvlong)size); + continue; + } cm->base = memmapalloc(base, size, BY2PG, MemRAM); if(cm->base == -1) continue; base = cm->base; cm->npage = size/BY2PG; - if(++cm >= &conf.mem[nelem(conf.mem)]) - break; + cm++; } if(0) memmapdump(); From 0e381493bfa4963c406cd6340ddcc0e43a4808e2 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sat, 6 Feb 2021 13:33:58 +0100 Subject: [PATCH 2/3] pc: increase number of Conf.mem[] entries from 4 to 16 --- sys/src/9/pc/dat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/src/9/pc/dat.h b/sys/src/9/pc/dat.h index ab9e4b1c7..1a63367ac 100644 --- a/sys/src/9/pc/dat.h +++ b/sys/src/9/pc/dat.h @@ -120,7 +120,7 @@ struct Conf ulong nmach; /* processors */ ulong nproc; /* processes */ ulong monitor; /* has monitor? */ - Confmem mem[4]; /* physical memory */ + Confmem mem[16]; /* physical memory */ ulong npage; /* total physical pages of memory */ ulong upages; /* user page pool */ ulong nimage; /* number of page cache image headers */ From efcfdd23d72178ed873982f957cbc95b2a1de4c5 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sat, 6 Feb 2021 13:47:45 +0100 Subject: [PATCH 3/3] 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). --- sys/src/9/bcm/bootargs.c | 39 ++++++++++++++++++++++++++++----------- sys/src/9/bcm64/dat.h | 3 ++- sys/src/9/bcm64/io.h | 2 +- sys/src/9/bcm64/pcibcm.c | 14 ++++++++++++-- 4 files changed, 43 insertions(+), 15 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; 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;