diff options
author | Andrew Hsieh <andrewhsieh@google.com> | 2014-06-16 14:58:18 -0700 |
---|---|---|
committer | Andrew Hsieh <andrewhsieh@google.com> | 2014-06-16 14:58:47 -0700 |
commit | 4f9b4718e8d836317c224955a1e87b7bb5252ae1 (patch) | |
tree | 9f6400714e31a3f18a2480cf96243b39648392ac | |
parent | b065fccd8ab47b4de4610093fb98514fc5df2362 (diff) | |
download | compiler-rt-release_34.tar.gz |
Update clear_cache to trunk@208591release_34
The current one abort for non-x86[_64]
Change-Id: Iede86d1a4369bf22b8447fd4e4b508dbea4a83a5
-rw-r--r-- | lib/clear_cache.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/lib/clear_cache.c b/lib/clear_cache.c index b934fd4bd..dc1af8c34 100644 --- a/lib/clear_cache.c +++ b/lib/clear_cache.c @@ -13,6 +13,17 @@ #if __APPLE__ #include <libkern/OSCacheControl.h> #endif +#if defined(__NetBSD__) && defined(__arm__) + #include <machine/sysarch.h> +#endif + +#if defined(__ANDROID__) && defined(__mips__) + #include <sys/cachectl.h> +#endif + +#if defined(__ANDROID__) && defined(__arm__) + #include <asm/unistd.h> +#endif /* * The compiler generates calls to __clear_cache() when creating @@ -28,6 +39,52 @@ void __clear_cache(void* start, void* end) * Intel processors have a unified instruction and data cache * so there is nothing to do */ +#elif defined(__arm__) && !defined(__APPLE__) + #if defined(__NetBSD__) + struct arm_sync_icache_args arg; + + arg.addr = (uintptr_t)start; + arg.len = (uintptr_t)end - (uintptr_t)start; + + sysarch(ARM_SYNC_ICACHE, &arg); + #elif defined(__ANDROID__) + const 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) : "r0"); + if (start_reg != 0) { + compilerrt_abort(); + } + #else + compilerrt_abort(); + #endif +#elif defined(__ANDROID__) && defined(__mips__) + const uintptr_t start_int = (uintptr_t) start; + const uintptr_t end_int = (uintptr_t) end; + _flush_cache(start, (end_int - start_int), BCACHE); +#elif defined(__aarch64__) && !defined(__APPLE__) + uint64_t xstart = (uint64_t)(uintptr_t) start; + uint64_t xend = (uint64_t)(uintptr_t) end; + + // 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 (uint64_t addr = xstart; addr < xend; addr += dcache_line_size) + __asm __volatile("dc cvau, %0" :: "r"(addr)); + __asm __volatile("dsb ish"); + + const size_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15); + for (uint64_t addr = xstart; addr < xend; addr += icache_line_size) + __asm __volatile("ic ivau, %0" :: "r"(addr)); + __asm __volatile("isb sy"); #else #if __APPLE__ /* On Darwin, sys_icache_invalidate() provides this functionality */ |