3 #include <sys/syscall.h>
6 #define FACTOR_CPU_STRING "arm.64"
8 #define __ARM_NR_cacheflush 0x0f0002
10 inline static void flush_icache(cell start, cell len) {
12 cell end = start + len;
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"
21 : "r"(syscall_nr), "r"(start_reg), "r"(end_reg), "r"(flags));
23 //critical_error("flush_icache() failed", result);
25 uint64_t xstart = (uint64_t)(uintptr_t)start;
26 uint64_t xend = (uint64_t)(uintptr_t)end;
29 // Get Cache Type Info
31 __asm __volatile("mrs %0, ctr_el0" : "=r"(ctr_el0));
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");
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");