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)