commit 9493d9941e215a86acdc468fdbb399d8a55a0aeb
parent 1cf609461d03e920016b9f9bb7b8043ffbee57a2
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sun, 18 Oct 2020 20:44:02 +0200
os9/arm64: Add taskmap()
Change-Id: Id62446667eb6d95bdcb1a146a5ec5e710358f5c8
Diffstat:
5 files changed, 64 insertions(+), 41 deletions(-)
diff --git a/include/os9/os9.h b/include/os9/os9.h
@@ -110,7 +110,6 @@ struct mach {
phyaddr_t phystack;
phyaddr_t phytext;
phyaddr_t kzero;
- phyaddr_t ptable;
Map *maps;
};
diff --git a/src/os9/arch/arm64/arch.h b/src/os9/arch/arm64/arch.h
@@ -15,7 +15,7 @@
#define UCT (1ul << 15)
#define nTWI (1ul << 16)
#define nTWE (1ul << 18)
-#define WXM (1ul << 19)
+#define WXN (1ul << 19)
#define E0E (1ul << 24)
#define EE (1ul << 25)
#define UCI (1ul << 26)
diff --git a/src/os9/arch/arm64/crt.s b/src/os9/arch/arm64/crt.s
@@ -49,8 +49,9 @@ EL1:
BL imach
BL icache
- BL initmap
BL immu
+ BL initmap
+ BL mmuon
BL kernelmap
BL hmem
diff --git a/src/os9/arch/arm64/fvp.c b/src/os9/arch/arm64/fvp.c
@@ -7,15 +7,10 @@
static uint32_t *early = (uint32_t *) 0x1C090000;
-/*
- * FIXME: ptable is aligned to 512MB, but this is not needed
- * because it only has to be aligned to 64K
- */
Mach mach = {
.phystack = 0x80080000,
.phytext = 0x80000000,
.kzero = 0xFFFFFF0000000000 - 0x80000000,
- .ptable = 0xA0000000,
};
void
diff --git a/src/os9/arch/arm64/mmu.c b/src/os9/arch/arm64/mmu.c
@@ -32,19 +32,19 @@
#define TBI0 (1ull << 37)
#define AS (1ull << 36)
#define IPS(x) ((x) << 32)
-#define TG1(x) ((x) << 30)
+#define TG1(x) (((x)&3) << 30)
#define SH1(x) ((x) << 28)
#define ORGN1(x) ((x) << 26)
#define IRGN1(x) ((x) << 24)
#define EDP1 (1ull << 23)
#define A1 (1ull << 22)
-#define T1SZ(x) ((x) << 16)
-#define TG0(x) ((x) << 14)
+#define T1SZ(x) (((x)&63) << 16)
+#define TG0(x) (((x)&3) << 14)
#define SH0(x) ((x) << 12)
#define ORGN0(x) ((x) << 10)
#define IRGN0(x) ((x) << 8)
#define EDP0 (1ull << 7)
-#define T0SZ(x) ((x) << 0)
+#define T0SZ(x) (((x)&63) << 0)
/* MMU */
#define RDWR 0
@@ -180,18 +180,18 @@ vmap(phyaddr_t pa, uintptr_t va, int perm)
if (va & 1ull<<63)
attr |= EL0;
- p = walker(va);
-
/*
* locking is needed if we are in a system
* with SMMUv3 and page tables are shared.
- *
- * Here is needed to do a break-before-make as
- * the architecture specifies. The first invalidation is
- * needed to avoid race conditions in multi processor
- * systems.
*/
lock(&m);
+ p = walker(va);
+
+ /*
+ * Here is needed to do a break-before-make as
+ * the architecture specifies to avoid a race condition
+ * in multi processor systems.
+ */
*p = INVALID;
invtlb(va);
@@ -202,7 +202,7 @@ vmap(phyaddr_t pa, uintptr_t va, int perm)
dbg("page %p: %llx\n", p, MASK(pa) | attr);
}
-int
+void
mapseg(Map *mp)
{
phyaddr_t pa;
@@ -230,14 +230,35 @@ mapseg(Map *mp)
pa += 4*KiB;
va += 4*KiB;
}
+}
- return 0;
+void
+taskmap(void)
+{
+ uint64_t tcr;
+
+ tcr = sysrd(TCR_EL1);
+ tcr &= ~(TG0(-1) | T0SZ(-1));
+ tcr |= TG0(G4K) | T0SZ(24);
+ syswr(TCR_EL1, tcr);
+ barrier(CODE);
+
+ /*
+ * TODO: setup SCTLR_EL1.WXN
+ */
}
void
kernelmap(void)
{
Map *mp;
+ uint64_t tcr;
+
+ tcr = sysrd(TCR_EL1);
+ tcr &= ~T1SZ(-1);
+ tcr |= T1SZ(24);
+ syswr(TCR_EL1, tcr);
+ barrier(CODE);
/*
* FIXME: We are using a full page when
@@ -247,10 +268,8 @@ kernelmap(void)
dbg("TTBR1_EL1=%llx\n", sysrd(TTBR1_EL1));
- for (mp = mach.maps; mp->siz != 0; mp++) {
- if (mapseg(mp) < 0)
- panic("invalid mach map");
- }
+ for (mp = mach.maps; mp->siz != 0; mp++)
+ mapseg(mp);
barrier(DATA);
barrier(CODE);
}
@@ -258,23 +277,41 @@ kernelmap(void)
void
initmap(void)
{
- pte_t *bp;
+ pte_t *bp, *tbl;
phyaddr_t pa;
+ uint64_t tcr;
pte_t attr = CONT | AF(1) | SH(OS) | AP(RDWR) | IDX(DEV) | BLOCK;
- bp = (pte_t *) mach.ptable;
- for (pa = 0; pa < 4*GiB; pa += 512*MiB)
+ tcr = sysrd(TCR_EL1);
+ tcr &= ~T0SZ(-1);
+ tcr |= T0SZ(32);
+ syswr(TCR_EL1, tcr);
+ barrier(CODE);
+
+ tbl = bp = allocb(1);
+ for (pa = 0; pa < 4*GiB; pa += 1*GiB)
*bp++ = pa | attr;
- syswr(TTBR0_EL1, mach.ptable);
+ syswr(TTBR0_EL1, (uint64_t) tbl);
barrier(DATA);
barrier(CODE);
}
void
+mmuon(void)
+{
+ uint64_t sctlr;
+
+ sctlr = sysrd(SCTLR_EL1);
+ sctlr |= M;
+ syswr(SCTLR_EL1, sctlr);
+ barrier(CODE);
+}
+
+void
immu(void)
{
- uint64_t sctlr, tcr, mair, id;
+ uint64_t tcr, mair, id;
id = sysrd(ID_AA64MMFR0_EL1);
if (TGRAN4(id) != 0 || TGRAN64(id) != 0 || PAR(id) < I1TB)
@@ -292,22 +329,13 @@ immu(void)
tcr =
IPS(I1TB) |
- TG1(G4K) | TG0(G64K) |
+ TG1(G4K) | TG0(G4K) |
SH1(OS) | SH0(OS) |
ORGN1(WBA) | ORGN0(WBA) |
- IRGN1(WBA) | IRGN0(WBA) |
- T1SZ(24) | T0SZ(32);
+ IRGN1(WBA) | IRGN0(WBA);
- /*
- * TODO: setup SCTLR_EL1.WXN
- */
invalltlb();
syswr(MAIR_EL1, mair);
syswr(TCR_EL1, tcr);
barrier(CODE);
-
- sctlr = sysrd(SCTLR_EL1);
- sctlr |= M;
- syswr(SCTLR_EL1, sctlr);
- barrier(CODE);
}