summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Guillen Fandos2021-03-12 01:46:09 +0100
committerDavid Guillen Fandos2021-03-12 01:46:09 +0100
commit462f0e97843fad1e05b72e4512c99bef3347303d (patch)
tree132f1d34cb3297bb87d6f315e6d15fd9871941c6
parent7db08a3fcfc126553690a2ba8339ebecd5f35ff1 (diff)
downloadpicogpsp-462f0e97843fad1e05b72e4512c99bef3347303d.tar.gz
picogpsp-462f0e97843fad1e05b72e4512c99bef3347303d.tar.bz2
picogpsp-462f0e97843fad1e05b72e4512c99bef3347303d.zip
Improve cache flush magic
Make it better and more generic. Add support for MIPS32 and fix the messy PSP code.
-rw-r--r--cpu_threaded.c96
-rw-r--r--psp/mips_emit.h6
-rw-r--r--psp/mips_stub.S32
3 files changed, 44 insertions, 90 deletions
diff --git a/cpu_threaded.c b/cpu_threaded.c
index f0d38be..5bd9aed 100644
--- a/cpu_threaded.c
+++ b/cpu_threaded.c
@@ -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
-
+ #include "3ds/3ds_utils.h"
+ void platform_cache_sync(void *baseaddr, void *endptr) {
+ ctr_flush_invalidate_cache();
+ }
#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; \
+ 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;
diff --git a/psp/mips_emit.h b/psp/mips_emit.h
index f01fbe7..7c69091 100644
--- a/psp/mips_emit.h
+++ b/psp/mips_emit.h
@@ -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) \
diff --git a/psp/mips_stub.S b/psp/mips_stub.S
index c89a5b1..7f0f303 100644
--- a/psp/mips_stub.S
+++ b/psp/mips_stub.S
@@ -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