Merge pull request #103 from davidgfnet/cachestuff

Improve cache flush magic
This commit is contained in:
Autechre 2021-03-12 05:35:17 +01:00 committed by GitHub
commit e178b25425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 91 deletions

View File

@ -252,65 +252,48 @@ extern u8 bit_count[256];
/* Cache invalidation */ /* Cache invalidation */
#if defined(PSP) #if defined(PSP)
#define translate_invalidate_dcache() sceKernelDcacheWritebackAll() void platform_cache_sync(void *baseaddr, void *endptr) {
#define invalidate_icache_region(addr, size) (void)0 sceKernelDcacheWritebackRange(baseaddr, ((char*)endptr) - ((char*)baseaddr));
sceKernelIcacheInvalidateRange(baseaddr, ((char*)endptr) - ((char*)baseaddr));
}
#elif defined(VITA) #elif defined(VITA)
#define translate_invalidate_dcache_one(which) \ void platform_cache_sync(void *baseaddr, void *endptr) {
if (which##_translation_ptr > last_##which##_translation_ptr) \ sceKernelSyncVMDomain(baseaddr, ((char*)endptr) - ((char*)baseaddr) + 64);
{ \
sceKernelSyncVMDomain(sceBlock,last_##which##_translation_ptr, \
which##_translation_ptr - last_##which##_translation_ptr); \
last_##which##_translation_ptr = which##_translation_ptr; \
} }
#define translate_invalidate_dcache() \
{ \
translate_invalidate_dcache_one(rom) \
translate_invalidate_dcache_one(ram) \
translate_invalidate_dcache_one(bios) \
}
#define invalidate_icache_region(addr, size) (void)0
#elif defined(_3DS) #elif defined(_3DS)
#include "3ds/3ds_utils.h" #include "3ds/3ds_utils.h"
void platform_cache_sync(void *baseaddr, void *endptr) {
#define translate_invalidate_dcache() ctr_flush_invalidate_cache() ctr_flush_invalidate_cache();
#define invalidate_icache_region(addr, size) (void)0 }
#elif defined(ARM_ARCH)
#elif defined(ARM_ARCH) void platform_cache_sync(void *baseaddr, void *endptr) {
static void sys_cacheflush(void *addr, unsigned long size) __clear_cache(baseaddr, endptr);
{ }
void *start = (void*)addr; #elif defined(MIPS_ARCH)
void *end = (void*)(char *)addr + size; void platform_cache_sync(void *baseaddr, void *endptr) {
__clear_cache(start, end); icache_region_sync(baseaddr, ((char*)endptr) - ((char*)baseaddr));
}
#define translate_invalidate_dcache_one(which) \
if (which##_translation_ptr > last_##which##_translation_ptr) \
{ \
sys_cacheflush(last_##which##_translation_ptr, \
which##_translation_ptr - last_##which##_translation_ptr); \
sys_cacheflush(last_##which##_translation_ptr, 32);\
last_##which##_translation_ptr = which##_translation_ptr; \
} }
#define translate_invalidate_dcache() \
{ \
translate_invalidate_dcache_one(rom) \
translate_invalidate_dcache_one(ram) \
translate_invalidate_dcache_one(bios) \
}
#define invalidate_icache_region(addr, size) (void)0
#else #else
/* x86 CPUs have icache consistency checks */
#define translate_invalidate_dcache() (void)0 void platform_cache_sync(void *baseaddr, void *endptr) {}
#define invalidate_icache_region(addr, size) (void)0
#endif #endif
void translate_icache_sync() {
// Cache emitted code can only grow
if (last_rom_translation_ptr < rom_translation_ptr) {
platform_cache_sync(last_rom_translation_ptr, rom_translation_ptr);
last_rom_translation_ptr = rom_translation_ptr;
}
if (last_ram_translation_ptr < ram_translation_ptr) {
platform_cache_sync(last_ram_translation_ptr, ram_translation_ptr);
last_ram_translation_ptr = ram_translation_ptr;
}
if (last_bios_translation_ptr < bios_translation_ptr) {
platform_cache_sync(last_bios_translation_ptr, bios_translation_ptr);
last_bios_translation_ptr = bios_translation_ptr;
}
}
/* End of Cache invalidation */ /* End of Cache invalidation */
@ -2833,7 +2816,7 @@ u32 bios_block_tag_top = 0x0101;
} \ } \
\ \
if(translation_recursion_level == 0) \ if(translation_recursion_level == 0) \
translate_invalidate_dcache(); \ translate_icache_sync(); \
} \ } \
else \ else \
{ \ { \
@ -2924,7 +2907,7 @@ u8 function_cc *block_lookup_address_##type(u32 pc) \
} \ } \
\ \
if(translation_recursion_level == 0) \ if(translation_recursion_level == 0) \
translate_invalidate_dcache(); \ translate_icache_sync(); \
} \ } \
if(translation_recursion_level == 0) \ if(translation_recursion_level == 0) \
bios_region_read_protect(); \ bios_region_read_protect(); \
@ -3719,7 +3702,6 @@ void flush_translation_cache_ram(void)
flush_ram_count, reg[REG_PC], iwram_code_min, iwram_code_max, flush_ram_count, reg[REG_PC], iwram_code_min, iwram_code_max,
ewram_code_min, ewram_code_max); */ ewram_code_min, ewram_code_max); */
invalidate_icache_region(ram_translation_cache, (ram_translation_ptr - ram_translation_cache) + 0x100);
last_ram_translation_ptr = ram_translation_cache; last_ram_translation_ptr = ram_translation_cache;
ram_translation_ptr = ram_translation_cache; ram_translation_ptr = ram_translation_cache;
ram_block_tag_top = 0x0101; ram_block_tag_top = 0x0101;
@ -3769,8 +3751,6 @@ void flush_translation_cache_ram(void)
void flush_translation_cache_rom(void) void flush_translation_cache_rom(void)
{ {
invalidate_icache_region(rom_translation_cache, rom_translation_ptr - rom_translation_cache + 0x100);
last_rom_translation_ptr = rom_translation_cache; last_rom_translation_ptr = rom_translation_cache;
rom_translation_ptr = rom_translation_cache; rom_translation_ptr = rom_translation_cache;
@ -3779,8 +3759,6 @@ void flush_translation_cache_rom(void)
void flush_translation_cache_bios(void) void flush_translation_cache_bios(void)
{ {
invalidate_icache_region(bios_translation_cache, bios_translation_ptr - bios_translation_cache + 0x100);
bios_block_tag_top = 0x0101; bios_block_tag_top = 0x0101;
last_bios_translation_ptr = bios_translation_cache; last_bios_translation_ptr = bios_translation_cache;

View File

@ -631,12 +631,6 @@ u32 arm_to_mips_reg[] =
#define generate_block_prologue() \ #define generate_block_prologue() \
update_trampoline = translation_ptr; \ update_trampoline = translation_ptr; \
__asm__ \
( \
"cache 8, 0(%0)\n" \
"cache 8, 0(%0)" : : "r"(translation_ptr) \
); \
\
mips_emit_j(mips_absolute_offset(mips_update_gba)); \ mips_emit_j(mips_absolute_offset(mips_update_gba)); \
mips_emit_nop(); \ mips_emit_nop(); \
generate_load_imm(reg_pc, stored_pc) \ generate_load_imm(reg_pc, stored_pc) \

View File

@ -16,6 +16,7 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
.set mips32r2
.align 4 .align 4
.global mips_update_gba .global mips_update_gba
@ -43,8 +44,7 @@
.global execute_asr_flags_reg .global execute_asr_flags_reg
.global execute_ror_flags_reg .global execute_ror_flags_reg
.global execute_arm_translate .global execute_arm_translate
.global invalidate_icache_region .global icache_region_sync
.global invalidate_all_cache
.global reg_check .global reg_check
.global memory_map_read .global memory_map_read
@ -2808,42 +2808,24 @@ execute_arm_translate:
jr $2 # jump to return jr $2 # jump to return
nop nop
# sceKernelInvalidateIcacheRange gives me problems, trying this instead # This is only to be used with MIPS32
# Invalidates an n byte region starting at the start address
# $4: start location # $4: start location
# $5: length # $5: length
invalidate_icache_region: icache_region_sync:
ins $4, $0, 0, 6 # align to 64 bytes ins $4, $0, 0, 6 # align to 64 bytes
addiu $2, $5, 63 # align up to 64 bytes addiu $2, $5, 63 # align up to 64 bytes
srl $2, $2, 6 # divide by 64 srl $2, $2, 6 # divide by 64
beq $2, $0, done # exit early on 0
nop
iir_loop: 1:
cache 0x08, ($4) # hit invalidate icache line synci ($4) # sync caches
addiu $2, $2, -1 # next loop iteration addiu $2, $2, -1 # next loop iteration
bne $2, $0, iir_loop # loop bne $2, $0, 1b # loop
addiu $4, $4, 64 # go to next cache line (delay slot) addiu $4, $4, 64 # go to next cache line (delay slot)
done:
jr $ra # return jr $ra # return
nop nop
# Writes back dcache and invalidates icache.
invalidate_all_cache:
addu $4, $0, $0 # $4 = 0
addiu $5, $0, 0x4000 # $5 = 0x4000
iac_loop:
cache 0x14, 0($4) # index invalidate/writeback dcache index
addiu $4, $4, 0x40 # goto next cache line
bne $4, $5, iac_loop # next iteration
cache 0x04, -0x40($4) # index invalidate icache index.. maybe?
jr $ra # return
nop
memory_map_read: memory_map_read:
.space 0x8000 .space 0x8000