From b3819178351790e3225e1545dbf51d667517e5bf Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Wed, 17 Mar 2021 00:48:43 -0500 Subject: [PATCH] cpu-arm.64: flush_icache from compiler-rt --- vm/cpu-arm.64.hpp | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/vm/cpu-arm.64.hpp b/vm/cpu-arm.64.hpp index f30d17138e..545c1d3fea 100644 --- a/vm/cpu-arm.64.hpp +++ b/vm/cpu-arm.64.hpp @@ -1,15 +1,48 @@ namespace factor { +#include +#include + #define FACTOR_CPU_STRING "arm.64" -// register cell ds asm("r5"); -// register cell rs asm("r6"); +#define __ARM_NR_cacheflush 0x0f0002 + inline static void flush_icache(cell start, cell len) { - //__asm("ic ialluis"); - //__asm volatile ("dmb sy" ::: "memory"); + int result; + cell end = start + len; + + // From compiler-rt, Apache-2.0 WITH LLVM-exception + register int start_reg __asm("r0") = (int)(intptr_t)start; + const register int end_reg __asm("r1") = (int)(intptr_t)end; + const register int flags __asm("r2") = 0; + const register int syscall_nr __asm("r7") = __ARM_NR_cacheflush; + __asm __volatile("svc 0x0" + : "=r"(start_reg) + : "r"(syscall_nr), "r"(start_reg), "r"(end_reg), "r"(flags)); + //if (start_reg == 0) + //critical_error("flush_icache() failed", result); + + uint64_t xstart = (uint64_t)(uintptr_t)start; + uint64_t xend = (uint64_t)(uintptr_t)end; + uint64_t addr; + + // Get Cache Type Info + uint64_t ctr_el0; + __asm __volatile("mrs %0, ctr_el0" : "=r"(ctr_el0)); + + // dc & ic instructions must use 64bit registers so we don't use + // uintptr_t in case this runs in an IPL32 environment. + const size_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 15); + for (addr = xstart & ~(dcache_line_size - 1); addr < xend; + addr += dcache_line_size) + __asm __volatile("dc cvau, %0" ::"r"(addr)); + __asm __volatile("dsb ish"); - //dsb(nsh); - //isb(); + const size_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15); + for (addr = xstart & ~(icache_line_size - 1); addr < xend; + addr += icache_line_size) + __asm __volatile("ic ivau, %0" ::"r"(addr)); + __asm __volatile("isb sy"); } } -- 2.34.1