shithub: riscv

Download patch

ref: f35d5ee5b036b7b4fa59b1839f52fca15b7f99f9
parent: 3fc8d1bdae10955e0b31ee1766d17367e0d0caa1
author: cinap_lenrek <[email protected]>
date: Sun Aug 18 17:16:30 EDT 2019

bcm64: add support for more than 1GB of ram (untested)

this adds a 4GB KMAP window into the kernel address space
so we can access all physical ram on raspberry pi 4 for
user pages.

note that kernel memory above KZERO is still limited
to 1GB because of DMA restrictions.

--- a/sys/src/9/bcm64/archbcm4.c
+++ b/sys/src/9/bcm64/archbcm4.c
@@ -17,7 +17,7 @@
 #define	POWERREGS	(VIRTIO+0x100000)
 
 Soc soc = {
-	.dramsize	= 0x40000000,
+	.dramsize	= 0xFC000000,
 	.busdram	= 0xC0000000,
 	.iosize		= 0x03000000,
 	.busio		= 0x7C000000,
--- a/sys/src/9/bcm64/mem.h
+++ b/sys/src/9/bcm64/mem.h
@@ -39,7 +39,8 @@
 #define STACKALIGN(sp)	((sp) & ~7)		/* bug: assure with alloc */
 #define TRAPFRAMESIZE	(38*8)
 
-#define KSEG0		(0xFFFFFFFF00000000ULL)
+#define KSEG0		(0xFFFFFFFE00000000ULL)
+#define KMAP		(0xFFFFFFFE00000000ULL)
 #define FRAMEBUFFER	(0xFFFFFFFF00000000ULL|PTEWT)
 #define	VGPIO		0			/* virtual gpio for pi3 ACT LED */
 
@@ -54,7 +55,6 @@
 
 #define SPINTABLE	(KZERO+0xd8)
 #define CONFADDR	(KZERO+0x100)
-#define VECTORSEL2	(0x1000)
 #define	REBOOTADDR	(0x1c00)		/* reboot code - physical address */
 #define	VCBUFFER	(KZERO+0x3400)		/* videocore mailbox buffer */
 
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -28,11 +28,30 @@
 	}
 	if(PTLEVELS > 2)
 	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
-		l1[PTL1X(pa, 2)] = (uintptr)&l1[L1TABLEX(pa, 1)] | PTEVALID | PTETABLE;
+		l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
 	if(PTLEVELS > 3)
 	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
-		l1[PTL1X(pa, 3)] = (uintptr)&l1[L1TABLEX(pa, 2)] | PTEVALID | PTETABLE;
+		l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
 
+	/* KMAP */
+	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTEPXN | PTESH(SHARE_INNER);
+	pe = PHYSDRAM + soc.dramsize;
+	for(pa = PHYSDRAM, va = KMAP; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
+		if(pe - pa < PGLSZ(1)){
+			l1[PTL1X(va, 1)] = (uintptr)l1 | PTEVALID | PTETABLE;
+			for(; pa < pe; pa += PGLSZ(0), va += PGLSZ(0))
+				l1[PTLX(va, 0)] = pa | PTEVALID | PTEPAGE | attr;
+			break;
+		}
+		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
+	}
+	if(PTLEVELS > 2)
+	for(pa = PHYSDRAM, va = KMAP; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
+		l1[PTL1X(va, 2)] = (uintptr)&l1[L1TABLEX(va, 1)] | PTEVALID | PTETABLE;
+	if(PTLEVELS > 3)
+	for(pa = PHYSDRAM, va = KMAP; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
+		l1[PTL1X(va, 3)] = (uintptr)&l1[L1TABLEX(va, 2)] | PTEVALID | PTETABLE;
+
 	/* VIRTIO */
 	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTEPXN | PTESH(SHARE_OUTER) | PTEDEVICE;
 	pe = soc.physio + soc.iosize;
@@ -130,6 +149,7 @@
 	mmuswitch(nil);
 }
 
+/* KZERO maps the first 1GB of ram */
 uintptr
 paddr(void *va)
 {
@@ -156,15 +176,19 @@
 	return nil;
 }
 
-void
-kmapinval(void)
+/* KMAP maps all of ram (up to 4GB) */
+static void*
+kmapaddr(uintptr pa)
 {
+	if(pa < (uintptr)-KZERO)
+		return (void*)(pa + KZERO);
+	return (void*)(pa + KMAP);
 }
 
 KMap*
 kmap(Page *p)
 {
-	return kaddr(p->pa);
+	return kmapaddr(p->pa);
 }
 
 void
@@ -172,6 +196,11 @@
 {
 }
 
+void
+kmapinval(void)
+{
+}
+
 uintptr
 mmukmap(uintptr va, uintptr pa, usize size)
 {
@@ -228,7 +257,6 @@
 			if(pte & (0xFFFFULL<<48))
 				iprint("strange pte %#p va %#p\n", pte, va);
 			pte &= ~(0xFFFFULL<<48 | BY2PG-1);
-			table = KADDR(pte);
 		} else {
 			pg = up->mmufree;
 			if(pg == nil)
@@ -238,11 +266,12 @@
 			if((pg->next = up->mmuhead[i+1]) == nil)
 				up->mmutail[i+1] = pg;
 			up->mmuhead[i+1] = pg;
-			memset(KADDR(pg->pa), 0, BY2PG);
+			pte = pg->pa;
+			memset(kmapaddr(pte), 0, BY2PG);
 			coherence();
-			table[x] = pg->pa | PTEVALID | PTETABLE;
-			table = KADDR(pg->pa);
+			table[x] = pte | PTEVALID | PTETABLE;
 		}
+		table = kmapaddr(pte);
 		x = PTLX(va, (uintptr)i);
 	}
 	return &table[x];
@@ -333,7 +362,7 @@
 	*pte = pa | PTEPAGE | PTEUSER | PTEPXN | PTENG | PTEAF | PTESH(SHARE_INNER);
 	if(pg->txtflush & (1UL<<m->machno)){
 		/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
-		cachedwbinvse((void*)KADDR(pg->pa), BY2PG);
+		cachedwbinvse(kmap(pg), BY2PG);
 		cacheiinvse((void*)va, BY2PG);
 		pg->txtflush &= ~(1UL<<m->machno);
 	}