mirror of
https://github.com/mupen64plus-ae/mupen64plus-core.git
synced 2024-11-26 23:20:26 +00:00
__clear_cache fix for ARM 64 devices plus ANDROID cleanup
This commit is contained in:
parent
8336328ce1
commit
d84ca04f83
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user