__clear_cache fix for ARM 64 devices plus ANDROID cleanup

This commit is contained in:
fzurita 2019-02-02 22:54:18 -05:00 committed by Gilles Siberlin
parent 8336328ce1
commit d84ca04f83
5 changed files with 43 additions and 25 deletions

View File

@ -230,6 +230,11 @@ static u_int jump_table_symbols[] = {
(int)breakpoint
};
static void cache_flush(char* start, char* end)
{
__clear_cache(start, end);
}
/* Linker */
static void set_jump_target(int addr,u_int target)
{
@ -325,7 +330,7 @@ static void *add_pointer(void *src, void* addr)
//assert((*(int*)((u_int)ptr2+20)&0x0ff00000)==0x01a00000); //mov
#endif
*ptr=(*ptr&0xFF000000)|((((u_int)addr-(u_int)ptr-8)<<6)>>8);
__clear_cache((void*)ptr, (void*)((u_int)ptr+4));
cache_flush((void*)ptr, (void*)((u_int)ptr+4));
return ptr2;
}
@ -4507,8 +4512,7 @@ static void do_clear_cache(void)
end+=4096;
j++;
}else{
__clear_cache((void *)start,(void *)end);
//cacheflush((void *)start,(void *)end,0);
cache_flush((void *)start,(void *)end);
break;
}
}

View File

@ -42,10 +42,4 @@
#define TARGET_SIZE_2 25 // 2^25 = 32 megabytes
#define JUMP_TABLE_SIZE (sizeof(jump_table_symbols)*2)
/* bug-fix to implement __clear_cache (missing in Android; http://code.google.com/p/android/issues/detail?id=1803) */
void __clear_cache_bugfix(char* begin, char *end);
#ifdef ANDROID
#define __clear_cache __clear_cache_bugfix
#endif
#endif /* M64P_DEVICE_R4300_NEW_DYNAREC_ARM_ASSEM_ARM_H */

View File

@ -372,13 +372,4 @@ GLOBAL_FUNCTION(breakpoint):
/* Set breakpoint here for debugging */
mov pc, lr
GLOBAL_FUNCTION(__clear_cache_bugfix):
/* The following bug-fix implements __clear_cache (missing in Android) */
push {r7, lr}
mov r2, #0
mov r7, #0x2
add r7, r7, #0xf0000
svc 0x00000000
pop {r7, pc}
END_SECTION

View File

@ -259,6 +259,38 @@ static uintptr_t jump_table_symbols[] = {
(intptr_t)breakpoint
};
static void cache_flush(char* start, char* end)
{
// Don't rely on GCC's __clear_cache implementation, as it caches
// icache/dcache cache line sizes, that can vary between cores on
// big.LITTLE architectures.
uint64_t addr, ctr_el0;
static size_t icache_line_size = 0xffff, dcache_line_size = 0xffff;
size_t isize, dsize;
__asm__ volatile("mrs %0, ctr_el0" : "=r"(ctr_el0));
isize = 4 << ((ctr_el0 >> 0) & 0xf);
dsize = 4 << ((ctr_el0 >> 16) & 0xf);
// use the global minimum cache line size
icache_line_size = isize = icache_line_size < isize ? icache_line_size : isize;
dcache_line_size = dsize = dcache_line_size < dsize ? dcache_line_size : dsize;
addr = (uint64_t)start & ~(uint64_t)(dsize - 1);
for (; addr < (uint64_t)end; addr += dsize)
// use "civac" instead of "cvau", as this is the suggested workaround for
// Cortex-A53 errata 819472, 826319, 827319 and 824069.
__asm__ volatile("dc civac, %0" : : "r"(addr) : "memory");
__asm__ volatile("dsb ish" : : : "memory");
addr = (uint64_t)start & ~(uint64_t)(isize - 1);
for (; addr < (uint64_t)end; addr += isize)
__asm__ volatile("ic ivau, %0" : : "r"(addr) : "memory");
__asm__ volatile("dsb ish" : : : "memory");
__asm__ volatile("isb" : : : "memory");
}
/* Linker */
static void set_jump_target(intptr_t addr,uintptr_t target)
{
@ -307,7 +339,7 @@ static void *add_pointer(void *src, void* addr)
//assert((ptr2[4]&0xfffffc1f)==0xd61f0000); //br
set_jump_target((intptr_t)src,(intptr_t)addr);
intptr_t ptr_rx=((intptr_t)ptr-(intptr_t)base_addr)+(intptr_t)base_addr_rx;
__clear_cache((void*)ptr_rx, (void*)(ptr_rx+4));
cache_flush((void*)ptr_rx, (void*)(ptr_rx+4));
return ptr2;
}
@ -5090,8 +5122,7 @@ static void do_clear_cache(void)
end+=4096;
j++;
}else{
__clear_cache((char *)start,(char *)end);
//cacheflush((void *)start,(void *)end,0);
cache_flush((char *)start,(char *)end);
break;
}
}

View File

@ -2319,8 +2319,7 @@ static void invalidate_all_pages(void)
}
}
#if NEW_DYNAREC >= NEW_DYNAREC_ARM
__clear_cache((char *)base_addr_rx,(char *)base_addr_rx+(1<<TARGET_SIZE_2));
//cacheflush((void *)base_addr,(void *)base_addr+(1<<TARGET_SIZE_2),0);
cache_flush((char *)base_addr_rx,(char *)base_addr_rx+(1<<TARGET_SIZE_2));
#endif
#ifdef USE_MINI_HT
memset(g_dev.r4300.new_dynarec_hot_state.mini_ht,-1,sizeof(g_dev.r4300.new_dynarec_hot_state.mini_ht));
@ -10883,8 +10882,7 @@ int new_recompile_block(int addr)
#if NEW_DYNAREC >= NEW_DYNAREC_ARM
intptr_t beginning_rx=((intptr_t)beginning-(intptr_t)base_addr)+(intptr_t)base_addr_rx;
intptr_t out_rx=((intptr_t)out-(intptr_t)base_addr)+(intptr_t)base_addr_rx;
__clear_cache((char *)beginning_rx,(char *)out_rx);
//cacheflush((void *)beginning,out,0);
cache_flush((char *)beginning_rx,(char *)out_rx);
#endif
// If we're within 256K of the end of the buffer,