Skip to content

Commit

Permalink
i#1569 AArch64: Replace cache_sync_asm with clear_icache, in C.
Browse files Browse the repository at this point in the history
At the same time, replace the clear_icache defined in tools.h with
tools_clear_icache.

Review-URL: https://codereview.appspot.com/318780043
  • Loading branch information
egrimley-arm committed Nov 16, 2016
1 parent 4d7d542 commit c3bd1ca
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 50 deletions.
40 changes: 0 additions & 40 deletions core/arch/aarch64/aarch64_shared.asm
Original file line number Diff line number Diff line change
Expand Up @@ -73,44 +73,4 @@ GLOBAL_LABEL(FUNCNAME:)
END_FUNC(FUNCNAME)
#undef FUNCNAME

/* CTR_EL0 [19:16] : Log2 of number of words in smallest dcache line
* CTR_EL0 [3:0] : Log2 of number of words in smallest icache line
*
* PoC = Point of Coherency
* PoU = Point of Unification
*
* void cache_sync_asm(void *beg, void *end);
*
* FIXME i#1569: The values read from CTR_EL0 should be cached as
* MRS Xt, CTR_EL0 may be emulated by kernel. This function could
* be implemented in C with inline assembly.
*/
DECLARE_FUNC(cache_sync_asm)
GLOBAL_LABEL(cache_sync_asm:)
mrs x3, ctr_el0
mov w4, #4
ubfx w2, w3, #16, #4
lsl w2, w4, w2 /* bytes in dcache line */
and w3, w3, #15
lsl w3, w4, w3 /* bytes in icache line */
sub w4, w2, #1
bic x4, x0, x4 /* aligned beg */
b 2f
1: dc cvau, x4 /* Data Cache Clean by VA to PoU */
add x4, x4, x2
2: cmp x4, x1
b.cc 1b
dsb ish /* Data Synchronization Barrier, Inner Shareable */
sub w4, w3, #1
bic x4, x0, x4 /* aligned beg */
b 4f
3: ic ivau, x4 /* Instruction Cache Invalidate by VA to PoU */
add x4, x4, x3
4: cmp x4, x1
b.cc 3b
dsb ish /* Data Synchronization Barrier, Inner Shareable */
isb /* Instruction Synchronization Barrier */
ret
END_FUNC(cache_sync_asm)

END_FILE
2 changes: 1 addition & 1 deletion core/arch/aarch64/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ proc_has_feature(feature_bit_t f)
void
machine_cache_sync(void *pc_start, void *pc_end, bool flush_icache)
{
cache_sync_asm(pc_start, pc_end);
clear_icache(pc_start, pc_end);
}

DR_API
Expand Down
4 changes: 0 additions & 4 deletions core/arch/arch_exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -1185,10 +1185,6 @@ void dr_fxsave32(byte *buf_aligned);
void dr_fxrstor32(byte *buf_aligned);
#endif

#ifdef AARCH64
void cache_sync_asm(void *beg, void *end);
#endif

/* Keep in synch with x86.asm. This is the difference between the SP saved in
* the mcontext and the SP of the caller of dr_app_start() and
* dynamorio_app_take_over().
Expand Down
49 changes: 49 additions & 0 deletions core/lib/dr_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,52 @@ internal_error(const char *file, int line, const char *expr)
{
/* do nothing by default */
}

#ifdef AARCH64
void
clear_icache(void *beg, void *end)
{
static uint cache_info = 0;
size_t dcache_line_size;
size_t icache_line_size;
ptr_uint_t beg_uint = (ptr_uint_t)beg;
ptr_uint_t end_uint = (ptr_uint_t)end;
ptr_uint_t addr;

if (beg_uint >= end_uint)
return;

/* "Cache Type Register" contains:
* CTR_EL0 [31] : 1
* CTR_EL0 [19:16] : Log2 of number of 4-byte words in smallest dcache line
* CTR_EL0 [3:0] : Log2 of number of 4-byte words in smallest icache line
*/
if (cache_info == 0)
__asm__ __volatile__("mrs %0, ctr_el0" : "=r"(cache_info));
dcache_line_size = 4 << (cache_info >> 16 & 0xf);
icache_line_size = 4 << (cache_info & 0xf);

/* Flush data cache to point of unification, one line at a time. */
addr = ALIGN_BACKWARD(beg_uint, dcache_line_size);
do {
__asm__ __volatile__("dc cvau, %0" : : "r"(addr) : "memory");
addr += dcache_line_size;
} while (addr != ALIGN_FORWARD(end_uint, dcache_line_size));

/* Data Synchronization Barrier */
__asm__ __volatile__("dsb ish" : : : "memory");

/* Invalidate instruction cache to point of unification, one line at a time. */
addr = ALIGN_BACKWARD(beg_uint, icache_line_size);
do {
__asm__ __volatile__("ic ivau, %0" : : "r"(addr) : "memory");
addr += icache_line_size;
} while (addr != ALIGN_FORWARD(end_uint, icache_line_size));

/* Data Synchronization Barrier */
__asm__ __volatile__("dsb ish" : : : "memory");

/* Instruction Synchronization Barrier */
__asm__ __volatile__("isb" : : : "memory");
}
#endif
2 changes: 1 addition & 1 deletion core/lib/dr_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ ptr_int_t dynamorio_syscall(uint sysnum, uint num_args, ...);
#endif

#ifdef AARCH64
void cache_sync_asm(void *beg, void *end);
void clear_icache(void *beg, void *end);
#endif

void dr_fpu_exception_init(void);
Expand Down
4 changes: 2 additions & 2 deletions suite/tests/tools.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ GLOBAL_LABEL(FUNCNAME:)
* roll our own.
*/
# undef FUNCNAME
# define FUNCNAME flush_icache
# define FUNCNAME tools_clear_icache
DECLARE_FUNC(FUNCNAME)
GLOBAL_LABEL(FUNCNAME:)
# ifndef X64
Expand All @@ -680,7 +680,7 @@ GLOBAL_LABEL(FUNCNAME:)
pop {r7}
bx lr
# else
b cache_sync_asm
b clear_icache
# endif
END_FUNC(FUNCNAME)
#endif
Expand Down
4 changes: 2 additions & 2 deletions suite/tests/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ int code_inc(int foo);
int code_dec(int foo);
int dummy(void);
#ifdef AARCHXX
void flush_icache(byte *start, byte *end);
void tools_clear_icache(void *start, void *end);
#endif

/* This function implements a trampoline that portably gets its return address
Expand Down Expand Up @@ -451,7 +451,7 @@ copy_to_buf_normal(char *buf, size_t buf_len, size_t *copied_len, Code_Snippet f
}
memcpy(buf, start, len);
#if defined(LINUX) && defined(AARCHXX)
flush_icache((byte *)buf, (byte *)buf + len);
tools_clear_icache(buf, buf + len);
#endif
if (copied_len != NULL)
*copied_len = len;
Expand Down

0 comments on commit c3bd1ca

Please sign in to comment.