9os

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

commit cd323a673a99270ad88f44cab30710e235248190
parent 8b42b98721e026b97cee7cfd7031167838ac2ff2
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sun, 27 Sep 2020 09:50:47 +0200

os9/arm64: Enable MMU

This commit enables the MMU with a 1:1 mapping. It assumes that
the physical memory is in the lower 4GB of the physical space, which
is a plausible assumption.

Change-Id: Id86eba6e44ed29df780275dfd36d299eaa076baf

Diffstat:
MREADME | 2+-
Mconfig/arm64-os9.mk | 2+-
Mscripts/fvp.sh | 8+++++---
Msrc/os9/arch/arm64/Makefile | 1+
Msrc/os9/arch/arm64/arch.h | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/os9/arch/arm64/arch.s | 23+++++++++--------------
Msrc/os9/arch/arm64/crt.s | 78+++++++++++++++++++++++++++++++++++-------------------------------------------
Asrc/os9/arch/arm64/defines.inc | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/os9/arch/arm64/fvp.c | 7+++++++
Msrc/os9/arch/arm64/main.c | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/os9/arch/arm64/sysreg.lst | 4++++
11 files changed, 299 insertions(+), 99 deletions(-)

diff --git a/README b/README @@ -16,7 +16,7 @@ Building TF-A with a preloaded BL33 =================================== export CROSS_COMPILE=aarch64-linux-gnu -make PLAT=fvp DEBUG=1 RESET_TO_BL31=1 PRELOADED_BL33_BASE=0x880000000 all +make PLAT=fvp DEBUG=1 RESET_TO_BL31=1 PRELOADED_BL33_BASE=0x80000000 all Running 9os ============= diff --git a/config/arm64-os9.mk b/config/arm64-os9.mk @@ -3,5 +3,5 @@ SYS = os9 MODE = native SYSASFLAGS = $(ARMV81_ASFLAGS) SYSCFLAGS = $(OS9_CFLAGS) -SYSLDFLAGS = -Ttext=0x880000000 +SYSLDFLAGS = -Ttext=0xFFFF000000000000 OS9 = 9fvp diff --git a/scripts/fvp.sh b/scripts/fvp.sh @@ -11,9 +11,7 @@ $FVP_PATH/FVP_Base_RevC-2xAEMv8A \ -C pctl.startup=0.0.0.0 \ -C cache_state_modelled=1 \ -C bp.pl011_uart0.uart_enable=1 \ - -C bp.pl011_uart0.out_file=$uart0 \ -C bp.pl011_uart3.uart_enable=1 \ - -C bp.pl011_uart3.out_file=$uart3 \ -C cluster0.cpu0.RVBAR=0x04001000 \ -C cluster0.cpu1.RVBAR=0x04001000 \ -C cluster0.cpu2.RVBAR=0x04001000 \ @@ -23,4 +21,8 @@ $FVP_PATH/FVP_Base_RevC-2xAEMv8A \ -C cluster1.cpu2.RVBAR=0x04001000 \ -C cluster1.cpu3.RVBAR=0x04001000 \ --data cluster0.cpu0=$bl31@0x04001000 \ - --data cluster0.cpu0=$os@0x880000000 \ + --data cluster0.cpu0=$os@0x80000000 \ + +# --plugin /home/k0ga/models/FVP_Base_RevC-2xAEMv8A/plugins/Linux64_GCC-6.4/TarmacTrace.so \ +# -C bp.pl011_uart0.out_file=$uart0 \ +# -C bp.pl011_uart3.out_file=$uart3 \ diff --git a/src/os9/arch/arm64/Makefile b/src/os9/arch/arm64/Makefile @@ -11,6 +11,7 @@ OBJS =\ debug_lock.o \ sysreg.o \ cache.o \ + fvp.o\ $(SRCDIR)/os9/builtin.o \ TARGET = $(BINDIR)/os9.bin diff --git a/src/os9/arch/arm64/arch.h b/src/os9/arch/arm64/arch.h @@ -3,9 +3,96 @@ enum barrier_type { DSB_SY, }; -extern void wsysreg(enum sysreg, unsigned long long v); +/* SCTLR_EL1 */ +#define SCTLR (3ul<<28 | 3ul<<22 | 1ul<<20 | 1ul<<11) +#define M (1ul << 0) +#define A (1ul << 1) +#define C (1ul << 2) +#define SA (1ul << 3) +#define SA0 (1ul << 4) +#define CP15BEN (1ul << 5) +#define THEE (1ul << 6) +#define ITD (1ul << 7) +#define SED (1ul << 8) +#define UMA (1ul << 9) +#define I (1ul << 12) +#define DZE (1ul << 14) +#define UCT (1ul << 15) +#define nTWI (1ul << 16) +#define nTWE (1ul << 18) +#define WXM (1ul << 19) +#define E0E (1ul << 24) +#define EE (1ul << 25) +#define UCI (1ul << 26) + +/* TCR_EL1 */ +#define NS 1ull +#define OS 2ull +#define IS 3ull +#define NC 0ull +#define WBA 1ull +#define WTA 2ull +#define WT 3ull +#define G16K 1ull +#define G4K 2ull +#define G64K 3ull + +#define TBI1 (1ull << 38) +#define TBI0 (1ull << 37) +#define AS (1ull << 36) +#define IPS4GB (0ull << 32) +#define IPS64GB (1ull << 32) +#define IPS1TB (2ull << 32) +#define IPS4TB (3ull << 32) +#define IPS16TB (4ull << 32) +#define TG1(x) ((x) << 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 SH0(x) ((x) << 12) +#define ORGN0(x) ((x) << 10) +#define IRGN0(x) ((x) << 8) +#define EDP0 (1ull << 7) +#define T0SZ(x) ((x) << 0) + +/* MMU */ +#define KiB 1024u +#define MiB (1024u * KiB) +#define GiB (1024ul * MiB) + +#define UXN(x) ((pte_t) (x) << 54) +#define PXN(x) ((pte_t) (x) << 53) +#define CONT(x) ((pte_t) (x) << 52) + +#define RDWR 0 +#define EL0 1 +#define RDONLY 2 + +#define NG(x) ((pte_t) (x) << 11) +#define AF(x) ((pte_t) (x) << 10) +#define SH(x) ((pte_t) (x) << 8) +#define AP(x) ((pte_t) (x) << 6) +#define IDX(x) ((pte_t) (x) << 2) +#define BLOCK64(pa) (((pa) & (-1ull>>64-47 | ~0ull<<47)) | 1) + +typedef struct mach Mach; +typedef unsigned long long pte_t, phyaddr_t; + +struct mach { + phyaddr_t phystack; + phyaddr_t ktzero; + phyaddr_t ptable; +}; + +extern void main(Mach *); +extern void wsysreg(enum sysreg, unsigned long long); extern unsigned long long rsysreg(enum sysreg); -extern void barrier(enum barrier_type type); -extern void invdcachesetway(void *addr); +extern void barrier(int); +extern void invdcachesetway(void *); extern void invdcache(void); extern void invicache(void); +extern void invtlb(void); diff --git a/src/os9/arch/arm64/arch.s b/src/os9/arch/arm64/arch.s @@ -1,15 +1,14 @@ .FILE "arch.s" - .TEXT .GLOBL panic,halt,intr,swtch,getcontext .GLOBL barrier,vectbl,doswtch,inm8,inm16,inm32 .GLOBL outm8,outm16,outm32 - .GLOBL invdcachesetway,invicache,vectbl + .GLOBL invdcachesetway,invicache,vectbl,invtlb .GLOBL inm8,inm16,inm32,outm8,outm16,outm32 + .TEXT intr: - CMP X0,#0 - B.NE 1f + CBNZ X0,1f MSR DAIFSET,#15 RET 1: @@ -23,11 +22,16 @@ barrier: BR X1 1: - ISb + ISB RET + DSB SY RET +invtlb: + TLBI VMALLE1IS + RET + invdcachesetway: DC ISW,X0 RET @@ -36,15 +40,6 @@ invicache: IC IALLU RET -badinst: - ADR X0,badimsg - B panic - - .SECTION .rodata -badimsg: - .ASCIZ "invalid instruction" - - .TEXT inm8: LDRB W0,[X0] RET diff --git a/src/os9/arch/arm64/crt.s b/src/os9/arch/arm64/crt.s @@ -1,58 +1,50 @@ .FILE "crt.s" + + .INCLUDE "defines.inc" + .TEXT .GLOBL _start - _start: - MRS X0,CURRENTEL - UBFX X0,X0,#2,#2 - CMP X0,1 - BEQ el1 + MRS X10,CURRENTEL + UBFX X10,X10,#2,#2 + CMP X10,1 + BEQ EL1 - /* small bootloader for fvp */ - LDR W0,=0x3C5 - MSR SPSR_EL2,X0 + MOV X10,A | D | IRQ | FIQ | EL1h + MSR SPSR_EL2,X10 - LDR W0,=0x30D00830 - MSR SCTLR_EL1,X0 + LDR W10,=SCTLR | SA0 | SA | A + MSR SCTLR_EL1,X10 - LDR W0,=0x80000000 - MSR HCR_EL2,X0 + LDR W10,=RW + MSR HCR_EL2,X10 - LDR X0,=_start - MSR ELR_EL2,X0 + ADR X10,EL1 + MSR ELR_EL2,X10 ERET -el1: - ADR X0,vectbl - MSR VBAR_EL1,X0 - ISB - - /* Differentiate between cold and warm boot (FVP only) */ - MRS X2,MPIDR_EL1 - LDR X1,=0x1C100000 - STR W2,[X1,0x10] - LDR W2,[X1,0x10] - UBFX W2,W2,24,2 - CMP W2,2 - BEQ warm - CMP W2,3 - BEQ warm - - LDR X0,=0x880080000 /* Set initial stack */ - MOV SP,X0 - - LDR X0,=edata /* BSS clean */ - MOV X1,#0 - LDR X2,=end - SUB X2,X2,X0 - BL memset - - SUB X29,X29,X29 +EL1: + ADR X0,mach + LDR X9,[X0] + MOV SP,X9 + MOV X29,0 + + LDR X9,[X0,8] + LDR X10,=edata + LDR X11,=end + SUB X11,X11,X10 + LSR X11,X11,3 + SUB X10,X10,X9 + +.L1: + STR XZR,[X10],8 + SUB X11,X11,1 + CBNZ X11,.L1 + BL main -warm: - ADR X0,outsync + ADR X0,OUTSYN B panic .DATA -outsync: +OUTSYN: .ASCIZ "out of sync" diff --git a/src/os9/arch/arm64/defines.inc b/src/os9/arch/arm64/defines.inc @@ -0,0 +1,74 @@ +// SCTLR_EL1 + .set SCTLR,3<<28 | 3<<22 | 1<<20 | 1<<11 + .set M,1<<0 + .set A,1<<1 + .set C,1<<2 + .set SA,1<<3 + .set SA0,1<<4 + .set CP15BEN,1<<5 + .set THEE,1<<6 + .set ITD,1<<7 + .set SED,1<<8 + .set UMA,1<<9 + .set I,1<<12 + .set DZE,1<<14 + .set UCT,1<<15 + .set nTWI,1<<16 + .set nTWE,1<<18 + .set WXN,1<<19 + .set E0E,1<<24 + .set EE,1<<25 + .set UCI,1<<26 + +// HCR_EL2 + .set ID,1<<33 + .set CD,1<<32 + .set RW,1<<31 + .set TRVM,1<<30 + .set HCD,1<<29 + .set TDZ,1<<28 + .set TGE,1<<27 + .set TVM,1<<26 + .set TTLB,1<<24 + .set TPU,1<<23 + .set TPC,1<<22 + .set TSW,1<<21 + .set TACR,1<<20 + .set TIDCP,1<<19 + .set TSC,1<<18 + .set TID3,1<<17 + .set TID2,1<<16 + .set TID1,1<<15 + .set TID0,1<<14 + .set TWE,1<<13 + .set TWI,1<<12 + .set DC,1<<11 + .set BSU,1<<10 + .set FB,1<<9 + .set VSE,1<<8 + .set VI,1<<7 + .set VF,1<<6 + .set AMO,1<<5 + .set IMO,1<<4 + .set FMO,1<<3 + .set PTW,1<<2 + .set SWIO,1<<1 + .set VM,1<<0 + +//SPSR_EL2 + .set NFLAG,1<<31 + .set ZFLAG,1<<30 + .set CFLAG,1<<29 + .set VFLAG,1<<28 + .set SS,1<<21 + .set IL,1<<20 + .set D,1<<9 + .set A,1<<8 + .set IRQ,1<<7 + .set FIQ,1<<7 + .set M32,1<<4 + .set EL0t,0 + .set EL1t,4 + .set EL1h,5 + .set EL2t,8 + .set EL2h,9 diff --git a/src/os9/arch/arm64/fvp.c b/src/os9/arch/arm64/fvp.c @@ -0,0 +1,7 @@ +#include "arch.h" + +Mach mach = { + .phystack = 0x80020000, + .ktzero = 0xFFFF000000000000 - 0x80000000, + .ptable = 0xA0000000, +}; diff --git a/src/os9/arch/arm64/main.c b/src/os9/arch/arm64/main.c @@ -1,4 +1,5 @@ #include <errno.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> @@ -10,68 +11,106 @@ #include "sysreg.h" #include "arch.h" -#define STACKSIZ 1792 -#define HEAPSIZ 1792 +#define HEAPSIZ (512 *KiB) -typedef struct mach Mach; +#define DEVICE 7 +#define NORMAL 0 -struct mach { - void *sp; - size_t stacksiz; +union bucket { + long long ll; + uintptr_t up; }; -Context ctx; - void * alloc(size_t size) { - static char heap[HEAPSIZ]; - static char *base = heap; + static union bucket heap[HEAPSIZ / sizeof(union bucket)]; + static union bucket *base = heap; static int lock; - char *bp; + size_t n; + union bucket *bp; if (size == 0) { lock = 1; return NULL; } + n = size-1 / sizeof(union bucket) + 1; if (lock) - panic("alloc"); + panic("alloc with lock"); bp = base; if (&bp[size] > &heap[HEAPSIZ]) - return NULL; - base += size; + panic("out of memory"); + base += n; + return bp; } +static uint64_t +firstmap(Mach *m) +{ + pte_t *bp; + phyaddr_t pa, ttbr; + pte_t attr = CONT(1) | AF(1) | SH(OS) | AP(RDWR) | IDX(DEVICE); + + bp = (pte_t *) m->ptable; + for (pa = 0; pa < 4*GiB; pa += 512*MiB) + *bp++ = BLOCK64(pa) | attr; + + ttbr = m->ptable; + ttbr &= -1ull>>47 | ~0ull<<28 ; + + return ttbr; +} + static void -imach(Mach *mp, void *stackp) +imach(Mach *m) { - memset(&ctx, 0, sizeof(ctx)); + extern void *vectbl; + uint64_t tcr, sctlr, ttbr; + + wsysreg(VBAR_EL1, (phyaddr_t) vectbl); + barrier(ISB); - mp->sp = stackp; - mp->stacksiz = STACKSIZ; + invtlb(); + invicache(); + invdcache(); + + sctlr = rsysreg(SCTLR_EL1); + tcr = + IPS4GB | + TG1(G64K) | TG0(G64K) | + SH1(OS) | SH0(OS) | + ORGN1(WBA) | ORGN0(WBA) | + IRGN1(WBA) | IRGN0(WBA) | + T1SZ(32) | T0SZ(32); + ttbr = firstmap(m); + + sctlr |= C | I; + wsysreg(SCTLR_EL1, sctlr); + wsysreg(MAIR_EL1, 0xFF); + wsysreg(TTBR0_EL1, ttbr); + wsysreg(TCR_EL1, tcr); + barrier(DSB_SY); + barrier(ISB); + + sctlr |= M; + wsysreg(SCTLR_EL1, sctlr); + barrier(ISB); - ctx.r[SP] = (unsigned long long) mp->sp; - ctx.r[ELR] = 0x4022000; - ctx.r[SPSR] = 0xf << 6 | 0xd; wsysreg(CPACR_EL1, 3<<20); wsysreg(FPCR, 0); wsysreg(FPSR, 0); - - invicache(); - invdcache(); + barrier(ISB); } static void -info(Mach *mp) +info(void) { dbg(kout, - "os9: version %s\n" - "sp = %p, stacksiz = 0x%zx\n", - OS9VERSION, - mp->sp, mp->stacksiz); + "os9: version %s\n", + OS9VERSION); } static void @@ -117,16 +156,15 @@ namespace(void) } void -main(void *stackp) +main(Mach *m) { - Mach mach; - - imach(&mach, stackp); + imach(m); + halt(); idev(); intr(IENABLE); barrier(ISB); namespace(); - info(&mach); + info(); debug(); panic("main"); } diff --git a/src/os9/arch/arm64/sysreg.lst b/src/os9/arch/arm64/sysreg.lst @@ -9,3 +9,7 @@ CSSELR_EL1 S3_2_C0_C0_0 CPACR_EL1 S3_0_C1_C0_2 FPCR S3_3_C4_C4_0 FPSR S3_3_C4_C4_1 +MAIR_EL1 S3_0_C10_C2_0 +TTBR0_EL1 S3_0_C2_C0_0 +TTBR1_EL1 S3_0_C2_C0_1 +TCR_EL1 S3_0_C2_C0_2