Fix reset() issue with dynarec flushing
On a reset bios_swi_entrypoint can end up pointing to code over the watermark, due to block_lookup_address_arm looking up the function instead of translating it. Fix it by making flush and init different functions (albeit similar). Tested by running and resetting games automatically, causing ~10% of games to crash.
This commit is contained in:
parent
84c347edad
commit
34eb7a3bf3
2
cheats.c
2
cheats.c
|
@ -60,7 +60,7 @@ static void update_hook_codebreaker(cheat_type *cheat)
|
|||
u32 pcaddr = 0x08000000 | (address & 0x1ffffff);
|
||||
#ifdef HAVE_DYNAREC
|
||||
if (cheat_master_hook != pcaddr)
|
||||
init_caches(); /* Flush caches to install hook */
|
||||
flush_dynarec_caches(); /* Flush caches to install hook */
|
||||
#endif
|
||||
cheat_master_hook = pcaddr;
|
||||
return; /* Only support for one hook */
|
||||
|
|
3
cpu.h
3
cpu.h
|
@ -164,7 +164,8 @@ extern u32 rom_branch_hash[ROM_BRANCH_HASH_SIZE];
|
|||
void flush_translation_cache_rom(void);
|
||||
void flush_translation_cache_ram(void);
|
||||
void dump_translation_cache(void);
|
||||
void init_caches(void);
|
||||
void init_dynarec_caches(void);
|
||||
void flush_dynarec_caches(void);
|
||||
void init_emitter(bool);
|
||||
void init_bios_hooks(void);
|
||||
|
||||
|
|
|
@ -3343,6 +3343,7 @@ void init_bios_hooks(void)
|
|||
|
||||
void flush_translation_cache_ram(void)
|
||||
{
|
||||
/* Flushes RAM caches avoiding doing too much work (ie. wiping unused memory) */
|
||||
flush_ram_count++;
|
||||
/*printf("ram flush %d (pc %x), %x to %x, %x to %x\n",
|
||||
flush_ram_count, reg[REG_PC], iwram_code_min, iwram_code_max,
|
||||
|
@ -3380,15 +3381,32 @@ void flush_translation_cache_ram(void)
|
|||
|
||||
void flush_translation_cache_rom(void)
|
||||
{
|
||||
/* We flush the generated code except for everything below the watermark. */
|
||||
last_rom_translation_ptr = &rom_translation_cache[rom_cache_watermark];
|
||||
rom_translation_ptr = &rom_translation_cache[rom_cache_watermark];
|
||||
|
||||
memset(rom_branch_hash, 0, sizeof(rom_branch_hash));
|
||||
}
|
||||
|
||||
void init_caches(void)
|
||||
void init_dynarec_caches(void)
|
||||
{
|
||||
/* Ensure we wipe everything including the SMC mirrors */
|
||||
/* Initialize caches so that we can start initalizing the emitter. */
|
||||
rom_translation_ptr = last_rom_translation_ptr = &rom_translation_cache[0];
|
||||
memset(rom_branch_hash, 0, sizeof(rom_branch_hash));
|
||||
|
||||
ram_translation_ptr = last_ram_translation_ptr = &ram_translation_cache[0];
|
||||
memset(iwram, 0, 0x8000);
|
||||
memset(&ewram[0x40000], 0, 0x40000);
|
||||
|
||||
ewram_code_min = 0;
|
||||
ewram_code_max = 0x40000;
|
||||
iwram_code_min = 0;
|
||||
iwram_code_max = 0x8000;
|
||||
}
|
||||
|
||||
void flush_dynarec_caches(void)
|
||||
{
|
||||
/* Flush ROM and RAM caches. */
|
||||
flush_translation_cache_rom();
|
||||
ewram_code_min = 0;
|
||||
ewram_code_max = 0x40000;
|
||||
|
|
|
@ -803,8 +803,9 @@ static void check_variables(int started_from_load)
|
|||
else if (strcmp(var.value, "enabled") == 0)
|
||||
dynarec_enable = 1;
|
||||
|
||||
/* Flush dynarec cache to ensure we do not execute old code */
|
||||
if (dynarec_enable != prevvalue)
|
||||
init_caches();
|
||||
flush_dynarec_caches();
|
||||
}
|
||||
else
|
||||
dynarec_enable = 1;
|
||||
|
|
2
main.c
2
main.c
|
@ -100,8 +100,8 @@ void init_main(void)
|
|||
video_count = 960;
|
||||
|
||||
#ifdef HAVE_DYNAREC
|
||||
init_dynarec_caches();
|
||||
init_emitter(gamepak_must_swap());
|
||||
init_caches();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ bool gba_load_state(const void* src)
|
|||
// Reset most of the frame state and dynarec state
|
||||
#ifdef HAVE_DYNAREC
|
||||
if (dynarec_enable)
|
||||
init_caches();
|
||||
flush_dynarec_caches();
|
||||
#endif
|
||||
|
||||
instruction_count = 0;
|
||||
|
|
Loading…
Reference in New Issue