9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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:
Minclude/os9/os9.h | 1-
Msrc/os9/arch/arm64/arch.h | 2+-
Msrc/os9/arch/arm64/crt.s | 3++-
Msrc/os9/arch/arm64/fvp.c | 5-----
Msrc/os9/arch/arm64/mmu.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
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); }