19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* ===-- clear_cache.c - Implement __clear_cache ---------------------------=== 29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The LLVM Compiler Infrastructure 49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This file is dual licensed under the MIT and the University of Illinois Open 69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Source Licenses. See LICENSE.TXT for details. 79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * ===----------------------------------------------------------------------=== 99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include "int_lib.h" 129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#if __APPLE__ 149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #include <libkern/OSCacheControl.h> 159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#endif 169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#if defined(__NetBSD__) && defined(__arm__) 179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #include <machine/sysarch.h> 189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#endif 199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#if defined(ANDROID) && defined(__mips__) 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #include <sys/cachectl.h> 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#endif 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#if defined(ANDROID) && defined(__arm__) 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #include <asm/unistd.h> 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#endif 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The compiler generates calls to __clear_cache() when creating 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * trampoline functions on the stack for use with nested functions. 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * It is expected to invalidate the instruction cache for the 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * specified range. 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonCOMPILER_RT_EXPORT void 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson__clear_cache(void* start, void* end) 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{ 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#if __i386__ || __x86_64__ 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Intel processors have a unified instruction and data cache 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * so there is nothing to do 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#elif defined(__arm__) && !defined(__APPLE__) 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #if defined(__NetBSD__) 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson struct arm_sync_icache_args arg; 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson arg.addr = (uintptr_t)start; 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson arg.len = (uintptr_t)end - (uintptr_t)start; 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson sysarch(ARM_SYNC_ICACHE, &arg); 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #elif defined(ANDROID) 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson const register int start_reg __asm("r0") = (int) (intptr_t) start; 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson const register int end_reg __asm("r1") = (int) (intptr_t) end; 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson const register int flags __asm("r2") = 0; 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson const register int syscall_nr __asm("r7") = __ARM_NR_cacheflush; 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson __asm __volatile("svc 0x0" : "=r"(start_reg) 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson : "r"(syscall_nr), "r"(start_reg), "r"(end_reg), "r"(flags) : "r0"); 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (start_reg != 0) { 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson compilerrt_abort(); 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #else 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson compilerrt_abort(); 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #endif 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#elif defined(ANDROID) && defined(__mips__) 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson const uintptr_t start_int = (uintptr_t) start; 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson const uintptr_t end_int = (uintptr_t) end; 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _flush_cache(start, (end_int - start_int), BCACHE); 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#elif defined(__aarch64__) && !defined(__APPLE__) 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson uint64_t xstart = (uint64_t)(uintptr_t) start; 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson uint64_t xend = (uint64_t)(uintptr_t) end; 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Get Cache Type Info 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson uint64_t ctr_el0; 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson __asm __volatile("mrs %0, ctr_el0" : "=r"(ctr_el0)); 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /* 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * dc & ic instructions must use 64bit registers so we don't use 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * uintptr_t in case this runs in an IPL32 environment. 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson const size_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 15); 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for (uint64_t addr = xstart; addr < xend; addr += dcache_line_size) 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson __asm __volatile("dc cvau, %0" :: "r"(addr)); 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson __asm __volatile("dsb ish"); 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson const size_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15); 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for (uint64_t addr = xstart; addr < xend; addr += icache_line_size) 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson __asm __volatile("ic ivau, %0" :: "r"(addr)); 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson __asm __volatile("isb sy"); 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#else 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #if __APPLE__ 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /* On Darwin, sys_icache_invalidate() provides this functionality */ 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson sys_icache_invalidate(start, end-start); 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #else 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson compilerrt_abort(); 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson #endif 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#endif 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson