shithub: riscv

Download patch

ref: e4b215d77ff0f63eaf42d737a1a4f75d2a2037aa
parent: 3c2093e47aaee2557aaf54bc8e0f2a68011651dd
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Jun 20 15:01:48 EDT 2023

bcm64: apply same mmu improvements from imx8

--- a/sys/src/9/bcm64/fns.h
+++ b/sys/src/9/bcm64/fns.h
@@ -73,8 +73,6 @@
 extern void vunmap(void*, vlong);
 
 extern void mmu0init(uintptr*);
-extern void mmu0clear(uintptr*);
-extern void mmuidmap(uintptr*);
 extern void mmu1init(void);
 extern void meminit(void);
 
--- a/sys/src/9/bcm64/l.s
+++ b/sys/src/9/bcm64/l.s
@@ -33,7 +33,7 @@
 	CBNZ	R1, _startup
 
 	/* clear page table and machs */
-	MOV	$(L1-KZERO), R1
+	MOV	$(L1BOT-KZERO), R1
 	MOV	$(MACHADDR(-1)-KZERO), R2
 _zerol1:
 	MOV	ZR, (R1)8!
@@ -49,6 +49,9 @@
 	BNE	_zerobss
 
 	/* setup page tables */
+	MOV	$(L1BOT-KZERO), R0
+	BL	mmuidmap(SB)
+
 	MOV	$(L1-KZERO), R0
 	BL	mmu0init(SB)
 
@@ -199,10 +202,11 @@
 	ISB	$SY
 
 	/* load the page tables */
-	MOV	$(L1TOP-KZERO), R0
+	MOV	$(L1BOT-KZERO), R0
+	MOV	$(L1TOP-KZERO), R1
 	ISB	$SY
 	MSR	R0, TTBR0_EL1
-	MSR	R0, TTBR1_EL1
+	MSR	R1, TTBR1_EL1
 	ISB	$SY
 
 	/* enable MMU and caches */
--- a/sys/src/9/bcm64/main.c
+++ b/sys/src/9/bcm64/main.c
@@ -165,7 +165,6 @@
 		cpuidprint();
 		synccycles();
 		timersinit();
-		flushtlb();
 		mmu1init();
 		m->ticks = MACHP(0)->ticks;
 		schedinit();
@@ -197,8 +196,6 @@
 	chandevreset();
 	userinit();
 	mpinit();
-	mmu0clear((uintptr*)L1);
-	flushtlb();
 	mmu1init();
 	schedinit();
 }
@@ -211,7 +208,7 @@
 	intrcpushutdown();
 
 	/* redo identity map */
-	mmuidmap((uintptr*)L1);
+	setttbr(PADDR(L1BOT));
 
 	/* setup reboot trampoline function */
 	f = (void*)REBOOTADDR;
--- a/sys/src/9/bcm64/mem.h
+++ b/sys/src/9/bcm64/mem.h
@@ -62,6 +62,10 @@
 #define	REBOOTADDR	(0x1c00)		/* reboot code - physical address */
 #define	VCBUFFER	(KZERO+0x3400)		/* videocore mailbox buffer */
 
+/* temporary identity map for TTBR0 (using only top-level) */
+#define L1BOT		((L1-L1TOPSIZE)&-BY2PG)
+
+/* shared kernel page table for TTBR1 */
 #define L1		(L1TOP-L1SIZE)
 #define L1SIZE		((L1TABLES+PTLEVELS-2)*BY2PG)
 #define L1TOP		((MACHADDR(MAXMACH-1)-L1TOPSIZE)&-BY2PG)
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -5,7 +5,29 @@
 #include "fns.h"
 #include "sysreg.h"
 
+#define INITMAP	(ROUND((uintptr)end + BY2PG, PGLSZ(1))-KZERO)
+
+/*
+ * Create initial identity map in top-level page table
+ * (L1BOT) for TTBR0. This page table is only used until
+ * mmu1init() loads m->mmutop.
+ */
 void
+mmuidmap(uintptr *l1bot)
+{
+	uintptr pa, pe, attr;
+
+	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTESH(SHARE_INNER);
+	pe = -KZERO;
+	for(pa = PHYSDRAM; pa < pe; pa += PGLSZ(PTLEVELS-1))
+		l1bot[PTLX(pa, PTLEVELS-1)] = pa | PTEVALID | PTEBLOCK | attr;
+}
+
+/*
+ * Create initial shared kernel page table (L1) for TTBR1.
+ * This page table coveres the KZERO and VIRTIO.
+ */
+void
 mmu0init(uintptr *l1)
 {
 	uintptr va, pa, pe, attr;
@@ -13,10 +35,8 @@
 	/* KZERO */
 	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTESH(SHARE_INNER);
 	pe = -KZERO;
-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1)){
+	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
 		l1[PTL1X(va, 1)] = pa | PTEVALID | PTEBLOCK | attr;
-		l1[PTL1X(pa, 1)] = pa | PTEVALID | PTEBLOCK | attr;
-	}
 
 	/* VIRTIO */
 	attr = PTEWRITE | PTEAF | PTEKERNEL | PTEUXN | PTEPXN | PTESH(SHARE_OUTER) | PTEDEVICE;
@@ -57,45 +77,6 @@
 }
 
 void
-mmu0clear(uintptr *l1)
-{
-	uintptr va, pa, pe;
-
-	pe = -KZERO;
-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
-		if(PTL1X(pa, 1) != PTL1X(va, 1))
-			l1[PTL1X(pa, 1)] = 0;
-	if(PTLEVELS > 2)
-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
-		if(PTL1X(pa, 2) != PTL1X(va, 2))
-			l1[PTL1X(pa, 2)] = 0;
-	if(PTLEVELS > 3)
-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
-		if(PTL1X(pa, 3) != PTL1X(va, 3))
-			l1[PTL1X(pa, 3)] = 0;
-}
-
-void
-mmuidmap(uintptr *l1)
-{
-	uintptr va, pa, pe;
-
-	pe = PHYSDRAM + soc.dramsize;
-	if(pe > (uintptr)-KZERO)
-		pe = (uintptr)-KZERO;
-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
-		l1[PTL1X(pa, 1)] = l1[PTL1X(va, 1)];
-	if(PTLEVELS > 2)
-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
-		l1[PTL1X(pa, 2)] = l1[PTL1X(va, 2)];
-	if(PTLEVELS > 3)
-	for(pa = PHYSDRAM, va = KZERO; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
-		l1[PTL1X(pa, 3)] = l1[PTL1X(va, 3)];
-	setttbr(PADDR(&l1[L1TABLEX(0, PTLEVELS-1)]));
-	flushtlb();
-}
-
-void
 mmu1init(void)
 {
 	m->mmutop = mallocalign(L1TOPSIZE, BY2PG, 0, 0);
@@ -157,8 +138,6 @@
 kmapinval(void)
 {
 }
-
-#define INITMAP	(ROUND((uintptr)end + BY2PG, PGLSZ(1))-KZERO)
 
 static void*
 rampage(void)