9os

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

commit b7d1ae79887456cb1901d648497ad60d36411db1
parent 9eb96ea3f960237a04270b7e359bbd8d17803cc0
Author: Roberto Vargas <roberto.vargas@arm.com>
Date:   Thu, 15 Nov 2018 14:40:25 +0000

Merge branch 'master' of ssh://gerrit.oss.arm.com/trusted-firmware/rcode

Change-Id: Ic71197d1e4489a385ccfe289386377a08996a232

Diffstat:
March/amd64/crt-netbsd.s | 2+-
March/arm64/Makefile | 2++
March/arm64/arch.h | 3+++
March/arm64/arch.s | 10++++++++++
Aarch/arm64/cache.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
March/arm64/rom-rmode.c | 10+++++++---
March/arm64/sysreg.lst | 3+++
Minclude/rcode.h | 2+-
8 files changed, 116 insertions(+), 5 deletions(-)

diff --git a/arch/amd64/crt-netbsd.s b/arch/amd64/crt-netbsd.s @@ -9,4 +9,4 @@ .ascii "NetBSD\0\0" .long 800000000 - .include "crt-posix.s" + .include "crt-posix.s" diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile @@ -13,6 +13,7 @@ ROMOBJS = rom-crt-$(SYS).o \ $(DLANG) \ $(DRVDIR)/uart.o \ $(SRCDIR)/romfw/builtin.o \ + cache.o \ RAMOBJS = ram-crt-$(SYS).o \ ram-$(SYS).o \ @@ -30,6 +31,7 @@ ram-crt-none.o rom-crt-none.o: crt-none.s ram-crt-linux.o rom-crt-linux.o: crt-linux.s rom-rmode.o: sysreg.h +cache.o: sysreg.h sysreg.h: sysreg.lst ./gensysreg.sh -h sysreg.lst diff --git a/arch/arm64/arch.h b/arch/arm64/arch.h @@ -6,3 +6,6 @@ enum barrier_type { extern void wsysreg(enum sysreg, unsigned long long v); extern unsigned long long rsysreg(enum sysreg); extern void barrier(enum barrier_type type); +extern void invdcachesetway(void *addr); +extern void invdcache(void); +extern void invicache(void); diff --git a/arch/arm64/arch.s b/arch/arm64/arch.s @@ -4,6 +4,8 @@ .globl panic,dohalt,enaint,dopanic .globl barrier,vectbl,doswtch,inm8,inm16,inm32 .globl outm8,outm16,outm32 + .globl invdcachesetway,invicache,vectbl,doswtch + .globl inm8,inm16,inm32,outm8,outm16,outm32 enaint: msr daifclr,#15 @@ -21,6 +23,14 @@ barrier: dsb sy ret +invdcachesetway: + dc isw,x0 + ret + +invicache: + ic iallu + ret + badinst: adr x0,badimsg b panic diff --git a/arch/arm64/cache.c b/arch/arm64/cache.c @@ -0,0 +1,89 @@ +#include <rcode.h> + +#include "sysreg.h" +#include "arch.h" + +#define NR_LEVELS 7 + +/* clidr_el1 */ +#define LOC_SHIFT 24 +#define LOC_MASK 0x7 /* level of coherence */ +#define CTYPE_MASK 0x7 /* cache type */ + +/* ccsidr_el1 */ +#define NSETS_SHIFT 13 +#define NSETS_MASK 0x7fff /* (number of sets in cache) - 1 */ +#define NWAYS_SHIFT 3 +#define NWAYS_MASK 0x3ff /* (associativty of cache) - 1 */ +#define LINE_MASK 0x7 /* log2(cache line in bytes) - 4 */ + +/* csselr_el1 */ +#define LEVEL_SHIFT 1 /* cache level required */ + +static unsigned +log2(unsigned long long v, unsigned width) +{ + unsigned nbits, i; + + for (nbits = 0, i = width - 1; i >= 0; i--) { + if ((v & (1ull << i)) != 0) + break; + nbits++; + } + return width - nbits - 1; +} + +static void +invdcachelvl(unsigned l) +{ + unsigned long long ccsidr; + unsigned nsets, nways, size, shift, i, j; + + wsysreg(CSSELR_EL1, l << LEVEL_SHIFT); + barrier(ISB); + + ccsidr = rsysreg(CCSIDR_EL1); + nsets = ((ccsidr >> NSETS_SHIFT) & NSETS_MASK) + 1; + nways = ((ccsidr >> NWAYS_SHIFT) & NWAYS_MASK) + 1; + size = (ccsidr & LINE_MASK) + 4; + shift = 32 - log2(nways, 32); + + for (i = 0; i < nways; i++) { + for (j = 0; j < nsets; j++) { + uintptr_t addr; + + addr = (uintptr_t)i << shift | j << size | l << 1; + invdcachesetway((void *)addr); + } + } + barrier(DSB_SY); +} + +void +invdcache(void) +{ + unsigned long long clidr; + unsigned l; + enum cachetype { + NOCACHE, + ICACHE, + DCACHE, + HARVARD, + UNIFIED + } type; + + barrier(DSB_SY); + + clidr = rsysreg(CLIDR_EL1); + if (((clidr >> LOC_SHIFT) & LOC_MASK) == 0) + return; + + for (l = 0; l < NR_LEVELS; l++) { + type = clidr & CTYPE_MASK; + if (type == NOCACHE || type == ICACHE) + continue; + + invdcachelvl(l); + clidr >>= 3; + } +} diff --git a/arch/arm64/rom-rmode.c b/arch/arm64/rom-rmode.c @@ -22,14 +22,18 @@ main(void *text, void *ram, size_t ramsiz) bss->backtrace = 1; bss->dumpstack = 1; bss->uartbase = (void *)UARTBASE; - uartinit(UARTCLK, UARTBAUDRATE); - enaint(); - barrier(ISB); frame.sp = bp + ramsiz; frame.elr = (void *) rsysreg(RVBAR_EL3); frame.spsr = 0xf << 6 | 0xd; + uartinit(UARTCLK, UARTBAUDRATE); + enaint(); + barrier(ISB); + + invicache(); + invdcache(); + dbg("romfw: text = %p, ram = %p, ramsiz = 0x%llx\n", text, ram, (unsigned long long)ramsiz); diff --git a/arch/arm64/sysreg.lst b/arch/arm64/sysreg.lst @@ -4,3 +4,6 @@ RCR_R S3_6_C1_C1_6 RDSCR_R S3_6_C6_C15_6 SCTLR_R S3_6_C1_C0_6 RVBAR_EL3 S3_6_C12_C0_1 +CLIDR_EL1 S3_1_C0_C0_1 +CCSIDR_EL1 S3_1_C0_C0_0 +CSSELR_EL1 S3_2_C0_C0_0 diff --git a/include/rcode.h b/include/rcode.h @@ -158,7 +158,7 @@ extern uint16_t outm16(uint16_t, void *addr); extern uint32_t outm32(uint32_t, void *addr); /* global constant variables */ -extern const struct rowidx rowidx[]; +extern const struct rowidx rowidx[]; extern const void *const handler[]; extern const char *const ecstr[];