]> gitweb.factorcode.org Git - factor.git/blob - vm/cpu-arm.64.hpp
xmode: fix handling of HASH_CHAR and always rules
[factor.git] / vm / cpu-arm.64.hpp
1 namespace factor {
2
3 #include <sys/syscall.h>
4 #include <unistd.h>
5
6 #define FACTOR_CPU_STRING "arm.64"
7
8 #define __ARM_NR_cacheflush 0x0f0002
9
10 inline static void flush_icache(cell start, cell len) {
11   int result;
12   cell end = start + len;
13
14   // From compiler-rt, Apache-2.0 WITH LLVM-exception
15   register int start_reg __asm("r0") = (int)(intptr_t)start;
16   const register int end_reg __asm("r1") = (int)(intptr_t)end;
17   const register int flags __asm("r2") = 0;
18   const register int syscall_nr __asm("r7") = __ARM_NR_cacheflush;
19   __asm __volatile("svc 0x0"
20                    : "=r"(start_reg)
21                    : "r"(syscall_nr), "r"(start_reg), "r"(end_reg), "r"(flags));
22   //if (start_reg == 0)
23     //critical_error("flush_icache() failed", result);
24
25   uint64_t xstart = (uint64_t)(uintptr_t)start;
26   uint64_t xend = (uint64_t)(uintptr_t)end;
27   uint64_t addr;
28
29   // Get Cache Type Info
30   uint64_t ctr_el0;
31   __asm __volatile("mrs %0, ctr_el0" : "=r"(ctr_el0));
32
33   // dc & ic instructions must use 64bit registers so we don't use
34   // uintptr_t in case this runs in an IPL32 environment.
35   const size_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 15);
36   for (addr = xstart & ~(dcache_line_size - 1); addr < xend;
37        addr += dcache_line_size)
38     __asm __volatile("dc cvau, %0" ::"r"(addr));
39   __asm __volatile("dsb ish");
40
41   const size_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15);
42   for (addr = xstart & ~(icache_line_size - 1); addr < xend;
43        addr += icache_line_size)
44     __asm __volatile("ic ivau, %0" ::"r"(addr));
45   __asm __volatile("isb sy");
46 }
47
48 }