Improve cache flush magic

Make it better and more generic. Add support for MIPS32 and fix the
messy PSP code.
This commit is contained in:
David Guillen Fandos 2021-03-12 01:46:09 +01:00
parent 7db08a3fcf
commit 462f0e9784
3 changed files with 45 additions and 91 deletions

View File

@ -252,65 +252,48 @@ extern u8 bit_count[256];
/* Cache invalidation */
#if defined(PSP)
#define translate_invalidate_dcache() sceKernelDcacheWritebackAll()
#define invalidate_icache_region(addr, size) (void)0
void platform_cache_sync(void *baseaddr, void *endptr) {
sceKernelDcacheWritebackRange(baseaddr, ((char*)endptr) - ((char*)baseaddr));
sceKernelIcacheInvalidateRange(baseaddr, ((char*)endptr) - ((char*)baseaddr));
}
#elif defined(VITA)
#define translate_invalidate_dcache_one(which) \
if (which##_translation_ptr > last_##which##_translation_ptr) \
{ \
sceKernelSyncVMDomain(sceBlock,last_##which##_translation_ptr, \
which##_translation_ptr - last_##which##_translation_ptr); \
last_##which##_translation_ptr = which##_translation_ptr; \
void platform_cache_sync(void *baseaddr, void *endptr) {
sceKernelSyncVMDomain(baseaddr, ((char*)endptr) - ((char*)baseaddr) + 64);
}
#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)
#include "3ds/3ds_utils.h"
#define translate_invalidate_dcache() ctr_flush_invalidate_cache()
#define invalidate_icache_region(addr, size) (void)0
#elif defined(ARM_ARCH)
static void sys_cacheflush(void *addr, unsigned long size)
{
void *start = (void*)addr;
void *end = (void*)(char *)addr + size;
__clear_cache(start, end);
}
#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; \
#include "3ds/3ds_utils.h"
void platform_cache_sync(void *baseaddr, void *endptr) {
ctr_flush_invalidate_cache();
}
#elif defined(ARM_ARCH)
void platform_cache_sync(void *baseaddr, void *endptr) {
__clear_cache(baseaddr, endptr);
}
#elif defined(MIPS_ARCH)
void platform_cache_sync(void *baseaddr, void *endptr) {
icache_region_sync(baseaddr, ((char*)endptr) - ((char*)baseaddr));
}
#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
#define translate_invalidate_dcache() (void)0
#define invalidate_icache_region(addr, size) (void)0
/* x86 CPUs have icache consistency checks */
void platform_cache_sync(void *baseaddr, void *endptr) {}
#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 */
@ -2833,7 +2816,7 @@ u32 bios_block_tag_top = 0x0101;
} \
\
if(translation_recursion_level == 0) \
translate_invalidate_dcache(); \
translate_icache_sync(); \
} \
else \
{ \
@ -2924,7 +2907,7 @@ u8 function_cc *block_lookup_address_##type(u32 pc) \
} \
\
if(translation_recursion_level == 0) \
translate_invalidate_dcache(); \
translate_icache_sync(); \
} \
if(translation_recursion_level == 0) \
bios_region_read_protect(); \
@ -2949,7 +2932,7 @@ u8 function_cc *block_lookup_address_##type(u32 pc) \
block_address = (u8 *)(-1); \
break; \
} \
\
\
return block_address; \
} \
@ -3719,7 +3702,6 @@ void flush_translation_cache_ram(void)
flush_ram_count, reg[REG_PC], iwram_code_min, iwram_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;
ram_translation_ptr = ram_translation_cache;
ram_block_tag_top = 0x0101;
@ -3769,8 +3751,6 @@ void flush_translation_cache_ram(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;
rom_translation_ptr = rom_translation_cache;
@ -3779,8 +3759,6 @@ void flush_translation_cache_rom(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;
last_bios_translation_ptr = bios_translation_cache;

View File

@ -631,12 +631,6 @@ u32 arm_to_mips_reg[] =
#define generate_block_prologue() \
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_nop(); \
generate_load_imm(reg_pc, stored_pc) \

View File

@ -16,6 +16,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
.set mips32r2
.align 4
.global mips_update_gba
@ -43,8 +44,7 @@
.global execute_asr_flags_reg
.global execute_ror_flags_reg
.global execute_arm_translate
.global invalidate_icache_region
.global invalidate_all_cache
.global icache_region_sync
.global reg_check
.global memory_map_read
@ -2808,42 +2808,24 @@ execute_arm_translate:
jr $2 # jump to return
nop
# sceKernelInvalidateIcacheRange gives me problems, trying this instead
# Invalidates an n byte region starting at the start address
# This is only to be used with MIPS32
# $4: start location
# $5: length
invalidate_icache_region:
icache_region_sync:
ins $4, $0, 0, 6 # align to 64 bytes
addiu $2, $5, 63 # align up to 64 bytes
srl $2, $2, 6 # divide by 64
beq $2, $0, done # exit early on 0
nop
iir_loop:
cache 0x08, ($4) # hit invalidate icache line
1:
synci ($4) # sync caches
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)
done:
jr $ra # return
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:
.space 0x8000