diff options
author | Joerg Sonnenberger <joerg@bec.de> | 2014-01-28 14:02:22 +0000 |
---|---|---|
committer | Joerg Sonnenberger <joerg@bec.de> | 2014-01-28 14:02:22 +0000 |
commit | 1dcc332a4b5b807e8f6aaf30c863235f966ebffc (patch) | |
tree | 2c83a6feeca0bc1d409f06657ecb12cdd159d633 | |
parent | 2ccebea3cda760f36da0374213d8eff6636dabaf (diff) | |
download | compiler-rt-1dcc332a4b5b807e8f6aaf30c863235f966ebffc.tar.gz |
Cache invalidation for AARCH64. Disabled for Apple for now as requested
by Tim Northover. Written by Matt Thomas.
Differential Revision: http://llvm-reviews.chandlerc.com/D2631
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@200317 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/clear_cache.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/clear_cache.c b/lib/clear_cache.c index 18c441ff2..7aee28590 100644 --- a/lib/clear_cache.c +++ b/lib/clear_cache.c @@ -38,6 +38,27 @@ void __clear_cache(void* start, void* end) arg.len = (uintptr_t)end - (uintptr_t)start; sysarch(ARM_SYNC_ICACHE, &arg); +#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 */ |