Search
lxdream.org :: lxdream :: r740:dd11269ee48b
lxdream 0.9.1
released Jun 29
Download Now
changeset740:dd11269ee48b
parent739:46fa527d9fef
child741:0c6f6567280c
authornkeynes
dateWed Jul 16 10:40:10 2008 +0000 (11 years ago)
Rationalize the two SH4 run slice impls into sh4.c, and tidy up the vm exits.
Fixes broken soft-reset with emulator core
Fixes broken build without translator
src/dreamcast.c
src/main.c
src/sh4/mmu.c
src/sh4/sh4.c
src/sh4/sh4.h
src/sh4/sh4core.c
src/sh4/sh4core.h
src/sh4/sh4core.in
src/sh4/sh4mem.c
src/sh4/sh4trans.c
src/sh4/sh4trans.h
src/test/testsh4x86.c
1.1 --- a/src/dreamcast.c Wed Jul 16 10:34:55 2008 +0000
1.2 +++ b/src/dreamcast.c Wed Jul 16 10:40:10 2008 +0000
1.3 @@ -20,6 +20,7 @@
1.4 #include <errno.h>
1.5 #include <glib.h>
1.6 #include "lxdream.h"
1.7 +#include "dream.h"
1.8 #include "mem.h"
1.9 #include "dreamcast.h"
1.10 #include "asic.h"
1.11 @@ -29,7 +30,7 @@
1.12 #include "gdrom/ide.h"
1.13 #include "maple/maple.h"
1.14 #include "sh4/sh4.h"
1.15 -#include "sh4/sh4trans.h"
1.16 +#include "sh4/sh4core.h"
1.17
1.18 /**
1.19 * Current state of the DC virtual machine
1.20 @@ -145,9 +146,6 @@
1.21 void dreamcast_reset( void )
1.22 {
1.23 int i;
1.24 - if( sh4_xlat_is_running() ) {
1.25 - sh4_translate_exit( XLAT_EXIT_SYSRESET );
1.26 - }
1.27 for( i=0; i<num_modules; i++ ) {
1.28 if( modules[i]->reset != NULL )
1.29 modules[i]->reset();
1.30 @@ -211,9 +209,7 @@
1.31
1.32 void dreamcast_stop( void )
1.33 {
1.34 - if( sh4_xlat_is_running() ) {
1.35 - sh4_translate_exit( XLAT_EXIT_HALT );
1.36 - }
1.37 + sh4_core_exit(CORE_EXIT_HALT); // returns only if not inside SH4 core
1.38 if( dreamcast_state == STATE_RUNNING )
1.39 dreamcast_state = STATE_STOPPING;
1.40 }
2.1 --- a/src/main.c Wed Jul 16 10:34:55 2008 +0000
2.2 +++ b/src/main.c Wed Jul 16 10:40:10 2008 +0000
2.3 @@ -252,7 +252,7 @@
2.4 }
2.5 }
2.6
2.7 - sh4_set_use_xlat( use_xlat );
2.8 + sh4_translate_set_enabled( use_xlat );
2.9
2.10 if( headless ) {
2.11 dreamcast_run();
3.1 --- a/src/sh4/mmu.c Wed Jul 16 10:34:55 2008 +0000
3.2 +++ b/src/sh4/mmu.c Wed Jul 16 10:40:10 2008 +0000
3.3 @@ -160,12 +160,12 @@
3.4 mmu_lrui = (val >> 26) & 0x3F;
3.5 val &= 0x00000301;
3.6 tmp = MMIO_READ( MMU, MMUCR );
3.7 - if( ((val ^ tmp) & MMUCR_AT) && sh4_is_using_xlat() ) {
3.8 + if( (val ^ tmp) & MMUCR_AT ) {
3.9 // AT flag has changed state - flush the xlt cache as all bets
3.10 // are off now. We also need to force an immediate exit from the
3.11 // current block
3.12 MMIO_WRITE( MMU, MMUCR, val );
3.13 - sh4_translate_flush_cache();
3.14 + sh4_flush_icache();
3.15 }
3.16 break;
3.17 case CCR:
4.1 --- a/src/sh4/sh4.c Wed Jul 16 10:34:55 2008 +0000
4.2 +++ b/src/sh4/sh4.c Wed Jul 16 10:40:10 2008 +0000
4.3 @@ -19,6 +19,7 @@
4.4
4.5 #define MODULE sh4_module
4.6 #include <math.h>
4.7 +#include <setjmp.h>
4.8 #include <assert.h>
4.9 #include "lxdream.h"
4.10 #include "dreamcast.h"
4.11 @@ -54,24 +55,23 @@
4.12 sh4ptr_t sh4_main_ram;
4.13 gboolean sh4_starting = FALSE;
4.14 static gboolean sh4_use_translator = FALSE;
4.15 +static jmp_buf sh4_exit_jmp_buf;
4.16 +static gboolean sh4_running = FALSE;
4.17 struct sh4_icache_struct sh4_icache = { NULL, -1, -1, 0 };
4.18
4.19 -void sh4_set_use_xlat( gboolean use )
4.20 +void sh4_translate_set_enabled( gboolean use )
4.21 {
4.22 // No-op if the translator was not built
4.23 #ifdef SH4_TRANSLATOR
4.24 + xlat_cache_init();
4.25 if( use ) {
4.26 - xlat_cache_init();
4.27 sh4_translate_init();
4.28 - sh4_module.run_time_slice = sh4_xlat_run_slice;
4.29 - } else {
4.30 - sh4_module.run_time_slice = sh4_run_slice;
4.31 }
4.32 sh4_use_translator = use;
4.33 #endif
4.34 }
4.35
4.36 -gboolean sh4_is_using_xlat()
4.37 +gboolean sh4_translate_is_enabled()
4.38 {
4.39 return sh4_use_translator;
4.40 }
4.41 @@ -136,6 +136,91 @@
4.42
4.43 }
4.44
4.45 +/**
4.46 + * Execute a timeslice using translated code only (ie translate/execute loop)
4.47 + */
4.48 +uint32_t sh4_run_slice( uint32_t nanosecs )
4.49 +{
4.50 + sh4r.slice_cycle = 0;
4.51 +
4.52 + if( sh4r.sh4_state != SH4_STATE_RUNNING ) {
4.53 + sh4_sleep_run_slice(nanosecs);
4.54 + }
4.55 +
4.56 + /* Setup for sudden vm exits */
4.57 + switch( setjmp(sh4_exit_jmp_buf) ) {
4.58 + case CORE_EXIT_BREAKPOINT:
4.59 + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
4.60 + /* fallthrough */
4.61 + case CORE_EXIT_HALT:
4.62 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
4.63 + TMU_run_slice( sh4r.slice_cycle );
4.64 + SCIF_run_slice( sh4r.slice_cycle );
4.65 + dreamcast_stop();
4.66 + return sh4r.slice_cycle;
4.67 + }
4.68 + case CORE_EXIT_SYSRESET:
4.69 + dreamcast_reset();
4.70 + break;
4.71 + case CORE_EXIT_SLEEP:
4.72 + sh4_sleep_run_slice(nanosecs);
4.73 + break;
4.74 + case CORE_EXIT_FLUSH_ICACHE:
4.75 +#ifdef SH4_TRANSLATOR
4.76 + xlat_flush_cache();
4.77 +#endif
4.78 + break;
4.79 + }
4.80 +
4.81 + sh4_running = TRUE;
4.82 +
4.83 + /* Execute the core's real slice */
4.84 +#ifdef SH4_TRANSLATOR
4.85 + if( sh4_use_translator ) {
4.86 + sh4_translate_run_slice(nanosecs);
4.87 + } else {
4.88 + sh4_emulate_run_slice(nanosecs);
4.89 + }
4.90 +#else
4.91 + sh4_emulate_run_slice(nanosecs);
4.92 +#endif
4.93 +
4.94 + /* And finish off the peripherals afterwards */
4.95 +
4.96 + sh4_running = FALSE;
4.97 + sh4_starting = FALSE;
4.98 + sh4r.slice_cycle = nanosecs;
4.99 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
4.100 + TMU_run_slice( nanosecs );
4.101 + SCIF_run_slice( nanosecs );
4.102 + }
4.103 + return nanosecs;
4.104 +}
4.105 +
4.106 +void sh4_core_exit( int exit_code )
4.107 +{
4.108 + if( sh4_running ) {
4.109 +#ifdef SH4_TRANSLATOR
4.110 + if( sh4_use_translator ) {
4.111 + sh4_translate_exit_recover();
4.112 + }
4.113 +#endif
4.114 + // longjmp back into sh4_run_slice
4.115 + sh4_running = FALSE;
4.116 + longjmp(sh4_exit_jmp_buf, exit_code);
4.117 + }
4.118 +}
4.119 +
4.120 +void sh4_flush_icache()
4.121 +{
4.122 +#ifdef SH4_TRANSLATOR
4.123 + // FIXME: Special case needs to be generalized
4.124 + if( sh4_translate_flush_cache() ) {
4.125 + longjmp(sh4_exit_jmp_buf, CORE_EXIT_CONTINUE);
4.126 + }
4.127 +#endif
4.128 +}
4.129 +
4.130 void sh4_save_state( FILE *f )
4.131 {
4.132 if( sh4_use_translator ) {
4.133 @@ -271,7 +356,7 @@
4.134 #define RAISE( x, v ) do{ \
4.135 if( sh4r.vbr == 0 ) { \
4.136 ERROR( "%08X: VBR not initialized while raising exception %03X, halting", sh4r.pc, x ); \
4.137 - dreamcast_stop(); return FALSE; \
4.138 + sh4_core_exit(CORE_EXIT_HALT); return FALSE; \
4.139 } else { \
4.140 sh4r.spc = sh4r.pc; \
4.141 sh4r.ssr = sh4_read_sr(); \
4.142 @@ -380,9 +465,7 @@
4.143 sh4r.sh4_state = SH4_STATE_SLEEP;
4.144 }
4.145 }
4.146 - if( sh4_xlat_is_running() ) {
4.147 - sh4_translate_exit( XLAT_EXIT_SLEEP );
4.148 - }
4.149 + sh4_core_exit( CORE_EXIT_SLEEP );
4.150 }
4.151
4.152 /**
5.1 --- a/src/sh4/sh4.h Wed Jul 16 10:34:55 2008 +0000
5.2 +++ b/src/sh4/sh4.h Wed Jul 16 10:40:10 2008 +0000
5.3 @@ -97,12 +97,12 @@
5.4 *
5.5 * @param use TRUE for translation mode, FALSE for emulation mode.
5.6 */
5.7 -void sh4_set_use_xlat( gboolean use );
5.8 +void sh4_translate_set_enabled( gboolean use );
5.9
5.10 /**
5.11 * Test if system is currently using the translation engine.
5.12 */
5.13 -gboolean sh4_is_using_xlat();
5.14 +gboolean sh4_translate_is_enabled();
5.15
5.16 /**
5.17 * Explicitly set the SH4 PC to the supplied value - this will be the next
6.1 --- a/src/sh4/sh4core.c Wed Jul 16 10:34:55 2008 +0000
6.2 +++ b/src/sh4/sh4core.c Wed Jul 16 10:40:10 2008 +0000
6.3 @@ -40,14 +40,9 @@
6.4
6.5 /********************** SH4 Module Definition ****************************/
6.6
6.7 -uint32_t sh4_run_slice( uint32_t nanosecs )
6.8 +uint32_t sh4_emulate_run_slice( uint32_t nanosecs )
6.9 {
6.10 int i;
6.11 - sh4r.slice_cycle = 0;
6.12 -
6.13 - if( sh4r.sh4_state != SH4_STATE_RUNNING ) {
6.14 - sh4_sleep_run_slice(nanosecs);
6.15 - }
6.16
6.17 if( sh4_breakpoint_count == 0 ) {
6.18 for( ; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
6.19 @@ -85,10 +80,7 @@
6.20 }
6.21 }
6.22 if( i != sh4_breakpoint_count ) {
6.23 - dreamcast_stop();
6.24 - if( sh4_breakpoints[i].type == BREAK_ONESHOT )
6.25 - sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
6.26 - break;
6.27 + sh4_core_exit( CORE_EXIT_BREAKPOINT );
6.28 }
6.29 #endif
6.30 }
6.31 @@ -111,7 +103,7 @@
6.32 /********************** SH4 emulation core ****************************/
6.33
6.34 #define UNDEF(ir) return sh4_raise_slot_exception(EXC_ILLEGAL, EXC_SLOT_ILLEGAL)
6.35 -#define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)
6.36 +#define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); sh4_core_exit(CORE_EXIT_HALT); return FALSE; }while(0)
6.37
6.38 #if(SH4_CALLTRACE == 1)
6.39 #define MAX_CALLSTACK 32
6.40 @@ -169,7 +161,7 @@
6.41 #define CHECKWALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )
6.42
6.43 #define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPU_DISABLED, EXC_SLOT_FPU_DISABLED ); } }
6.44 -#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }
6.45 +#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); sh4_core_exit(CORE_EXIT_HALT); return FALSE; }
6.46 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)
6.47
6.48 #define MEM_READ_BYTE( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_byte(memtmp); }
6.49 @@ -262,7 +254,7 @@
6.50 if( !mmu_update_icache(sh4r.pc) ) {
6.51 // double fault - halt
6.52 ERROR( "Double fault - halting" );
6.53 - dreamcast_stop();
6.54 + sh4_core_exit(CORE_EXIT_HALT);
6.55 return FALSE;
6.56 }
6.57 }
7.1 --- a/src/sh4/sh4core.h Wed Jul 16 10:34:55 2008 +0000
7.2 +++ b/src/sh4/sh4core.h Wed Jul 16 10:40:10 2008 +0000
7.3 @@ -72,6 +72,42 @@
7.4 */
7.5 #define GET_ICACHE_END() (sh4_icache.page_vma + (~sh4_icache.mask) + 1)
7.6
7.7 +
7.8 +/**
7.9 + * SH4 vm-exit flag - exit the current block but continue (eg exception handling)
7.10 + */
7.11 +#define CORE_EXIT_CONTINUE 1
7.12 +
7.13 +/**
7.14 + * SH4 vm-exit flag - exit the current block and halt immediately (eg fatal error)
7.15 + */
7.16 +#define CORE_EXIT_HALT 2
7.17 +
7.18 +/**
7.19 + * SH4 vm-exit flag - exit the current block and halt immediately for a system
7.20 + * breakpoint.
7.21 + */
7.22 +#define CORE_EXIT_BREAKPOINT 3
7.23 +
7.24 +/**
7.25 + * SH4 vm-exit flag - exit the current block and continue after performing a full
7.26 + * system reset (dreamcast_reset())
7.27 + */
7.28 +#define CORE_EXIT_SYSRESET 4
7.29 +
7.30 +/**
7.31 + * SH4 vm-exit flag - exit the current block and continue after the next IRQ.
7.32 + */
7.33 +#define CORE_EXIT_SLEEP 5
7.34 +
7.35 +/**
7.36 + * SH4 vm-exit flag - exit the current block and flush all instruction caches (ie
7.37 + * if address translation has changed)
7.38 + */
7.39 +#define CORE_EXIT_FLUSH_ICACHE 6
7.40 +
7.41 +typedef uint32_t (*sh4_run_slice_fn)(uint32_t);
7.42 +
7.43 /* SH4 module functions */
7.44 void sh4_init( void );
7.45 void sh4_reset( void );
7.46 @@ -81,6 +117,25 @@
7.47 uint32_t sh4_xlat_run_slice( uint32_t nanos ); // Run single timeslice using translator
7.48 uint32_t sh4_sleep_run_slice( uint32_t nanos ); // Run single timeslice while the CPU is asleep
7.49
7.50 +/**
7.51 + * Immediately exit from the currently executing instruction with the given
7.52 + * exit code. This method does not return.
7.53 + */
7.54 +void sh4_core_exit( int exit_code );
7.55 +
7.56 +/**
7.57 + * Exit the current block at the end of the current instruction, flush the
7.58 + * translation cache (completely) and return control to sh4_xlat_run_slice.
7.59 + *
7.60 + * As a special case, if the current instruction is actually the last
7.61 + * instruction in the block (ie it's in a delay slot), this function
7.62 + * returns to allow normal completion of the translation block. Otherwise
7.63 + * this function never returns.
7.64 + *
7.65 + * Must only be invoked (indirectly) from within translated code.
7.66 + */
7.67 +void sh4_flush_icache();
7.68 +
7.69 /* SH4 peripheral module functions */
7.70 void CPG_reset( void );
7.71 void DMAC_reset( void );
8.1 --- a/src/sh4/sh4core.in Wed Jul 16 10:34:55 2008 +0000
8.2 +++ b/src/sh4/sh4core.in Wed Jul 16 10:40:10 2008 +0000
8.3 @@ -40,14 +40,9 @@
8.4
8.5 /********************** SH4 Module Definition ****************************/
8.6
8.7 -uint32_t sh4_run_slice( uint32_t nanosecs )
8.8 +uint32_t sh4_emulate_run_slice( uint32_t nanosecs )
8.9 {
8.10 int i;
8.11 - sh4r.slice_cycle = 0;
8.12 -
8.13 - if( sh4r.sh4_state != SH4_STATE_RUNNING ) {
8.14 - sh4_sleep_run_slice(nanosecs);
8.15 - }
8.16
8.17 if( sh4_breakpoint_count == 0 ) {
8.18 for( ; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
8.19 @@ -85,10 +80,7 @@
8.20 }
8.21 }
8.22 if( i != sh4_breakpoint_count ) {
8.23 - dreamcast_stop();
8.24 - if( sh4_breakpoints[i].type == BREAK_ONESHOT )
8.25 - sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
8.26 - break;
8.27 + sh4_core_exit( CORE_EXIT_BREAKPOINT );
8.28 }
8.29 #endif
8.30 }
8.31 @@ -111,7 +103,7 @@
8.32 /********************** SH4 emulation core ****************************/
8.33
8.34 #define UNDEF(ir) return sh4_raise_slot_exception(EXC_ILLEGAL, EXC_SLOT_ILLEGAL)
8.35 -#define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)
8.36 +#define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); sh4_core_exit(CORE_EXIT_HALT); return FALSE; }while(0)
8.37
8.38 #if(SH4_CALLTRACE == 1)
8.39 #define MAX_CALLSTACK 32
8.40 @@ -169,7 +161,7 @@
8.41 #define CHECKWALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )
8.42
8.43 #define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPU_DISABLED, EXC_SLOT_FPU_DISABLED ); } }
8.44 -#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }
8.45 +#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); sh4_core_exit(CORE_EXIT_HALT); return FALSE; }
8.46 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)
8.47
8.48 #define MEM_READ_BYTE( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_byte(memtmp); }
8.49 @@ -262,7 +254,7 @@
8.50 if( !mmu_update_icache(sh4r.pc) ) {
8.51 // double fault - halt
8.52 ERROR( "Double fault - halting" );
8.53 - dreamcast_stop();
8.54 + sh4_core_exit(CORE_EXIT_HALT);
8.55 return FALSE;
8.56 }
8.57 }
9.1 --- a/src/sh4/sh4mem.c Wed Jul 16 10:34:55 2008 +0000
9.2 +++ b/src/sh4/sh4mem.c Wed Jul 16 10:40:10 2008 +0000
9.3 @@ -39,12 +39,12 @@
9.4 #define CHECK_READ_WATCH( addr, size ) \
9.5 if( mem_is_watched(addr,size,WATCH_READ) != NULL ) { \
9.6 WARN( "Watch triggered at %08X by %d byte read", addr, size ); \
9.7 - dreamcast_stop(); \
9.8 + sh4_core_exit(CORE_EXIT_HALT); \
9.9 }
9.10 #define CHECK_WRITE_WATCH( addr, size, val ) \
9.11 if( mem_is_watched(addr,size,WATCH_WRITE) != NULL ) { \
9.12 WARN( "Watch triggered at %08X by %d byte write <= %0*X", addr, size, size*2, val ); \
9.13 - dreamcast_stop(); \
9.14 + sh4_core_exit(CORE_EXIT_HALT); \
9.15 }
9.16 #else
9.17 #define CHECK_READ_WATCH( addr, size )
10.1 --- a/src/sh4/sh4trans.c Wed Jul 16 10:34:55 2008 +0000
10.2 +++ b/src/sh4/sh4trans.c Wed Jul 16 10:40:10 2008 +0000
10.3 @@ -17,7 +17,6 @@
10.4 * GNU General Public License for more details.
10.5 */
10.6 #include <assert.h>
10.7 -#include <setjmp.h>
10.8 #include "eventq.h"
10.9 #include "syscall.h"
10.10 #include "clock.h"
10.11 @@ -27,45 +26,11 @@
10.12 #include "sh4/xltcache.h"
10.13
10.14
10.15 -static jmp_buf xlat_jmp_buf;
10.16 -static gboolean xlat_running = FALSE;
10.17 -
10.18 -gboolean sh4_xlat_is_running()
10.19 -{
10.20 - return xlat_running;
10.21 -}
10.22 -
10.23 /**
10.24 * Execute a timeslice using translated code only (ie translate/execute loop)
10.25 */
10.26 -uint32_t sh4_xlat_run_slice( uint32_t nanosecs )
10.27 +uint32_t sh4_translate_run_slice( uint32_t nanosecs )
10.28 {
10.29 - sh4r.slice_cycle = 0;
10.30 -
10.31 - if( sh4r.sh4_state != SH4_STATE_RUNNING ) {
10.32 - sh4_sleep_run_slice(nanosecs);
10.33 - }
10.34 -
10.35 - switch( setjmp(xlat_jmp_buf) ) {
10.36 - case XLAT_EXIT_BREAKPOINT:
10.37 - sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );
10.38 - /* fallthrough */
10.39 - case XLAT_EXIT_HALT:
10.40 - if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
10.41 - TMU_run_slice( sh4r.slice_cycle );
10.42 - SCIF_run_slice( sh4r.slice_cycle );
10.43 - dreamcast_stop();
10.44 - return sh4r.slice_cycle;
10.45 - }
10.46 - case XLAT_EXIT_SYSRESET:
10.47 - dreamcast_reset();
10.48 - break;
10.49 - case XLAT_EXIT_SLEEP:
10.50 - sh4_sleep_run_slice(nanosecs);
10.51 - break;
10.52 - }
10.53 -
10.54 - xlat_running = TRUE;
10.55 void * (*code)() = NULL;
10.56 while( sh4r.slice_cycle < nanosecs ) {
10.57 if( sh4r.event_pending <= sh4r.slice_cycle ) {
10.58 @@ -93,14 +58,6 @@
10.59 }
10.60 code = code();
10.61 }
10.62 -
10.63 - xlat_running = FALSE;
10.64 - sh4_starting = FALSE;
10.65 - sh4r.slice_cycle = nanosecs;
10.66 - if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
10.67 - TMU_run_slice( nanosecs );
10.68 - SCIF_run_slice( nanosecs );
10.69 - }
10.70 return nanosecs;
10.71 }
10.72
10.73 @@ -197,26 +154,7 @@
10.74 sh4r.pc += (recovery->sh4_icount<<1);
10.75 }
10.76
10.77 -void sh4_translate_unwind_stack( gboolean abort_after, unwind_thunk_t thunk )
10.78 -{
10.79 - void *pc = xlat_get_native_pc();
10.80 -
10.81 - assert( pc != NULL );
10.82 - void *code = xlat_get_code( sh4r.pc );
10.83 - xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);
10.84 - if( recover != NULL ) {
10.85 - // Can be null if there is no recovery necessary
10.86 - sh4_translate_run_recovery(recover);
10.87 - }
10.88 - if( thunk != NULL ) {
10.89 - thunk();
10.90 - }
10.91 - // finally longjmp back into sh4_xlat_run_slice
10.92 - xlat_running = FALSE;
10.93 - longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);
10.94 -}
10.95 -
10.96 -void sh4_translate_exit( int exit_code )
10.97 +void sh4_translate_exit_recover( )
10.98 {
10.99 void *pc = xlat_get_native_pc();
10.100 if( pc != NULL ) {
10.101 @@ -228,9 +166,6 @@
10.102 sh4_translate_run_recovery(recover);
10.103 }
10.104 }
10.105 - // finally longjmp back into sh4_xlat_run_slice
10.106 - xlat_running = FALSE;
10.107 - longjmp(xlat_jmp_buf, exit_code);
10.108 }
10.109
10.110 void sh4_translate_breakpoint_hit(uint32_t pc)
10.111 @@ -238,7 +173,7 @@
10.112 if( sh4_starting && sh4r.slice_cycle == 0 && pc == sh4r.pc ) {
10.113 return;
10.114 }
10.115 - sh4_translate_exit( XLAT_EXIT_BREAKPOINT );
10.116 + sh4_core_exit( CORE_EXIT_BREAKPOINT );
10.117 }
10.118
10.119 /**
10.120 @@ -252,7 +187,7 @@
10.121 *
10.122 * Must only be invoked (indirectly) from within translated code.
10.123 */
10.124 -void sh4_translate_flush_cache()
10.125 +gboolean sh4_translate_flush_cache()
10.126 {
10.127 void *pc = xlat_get_native_pc();
10.128 assert( pc != NULL );
10.129 @@ -263,11 +198,10 @@
10.130 // Can be null if there is no recovery necessary
10.131 sh4_translate_run_recovery(recover);
10.132 xlat_flush_cache();
10.133 - xlat_running = FALSE;
10.134 - longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);
10.135 + return TRUE;
10.136 } else {
10.137 xlat_flush_cache();
10.138 - return;
10.139 + return FALSE;
10.140 }
10.141 }
10.142
10.143 @@ -289,7 +223,7 @@
10.144 if( !mmu_update_icache(sh4r.pc) ) {
10.145 // double fault - halt
10.146 ERROR( "Double fault - halting" );
10.147 - dreamcast_stop();
10.148 + sh4_core_exit(CORE_EXIT_HALT);
10.149 return NULL;
10.150 }
10.151 }
11.1 --- a/src/sh4/sh4trans.h Wed Jul 16 10:34:55 2008 +0000
11.2 +++ b/src/sh4/sh4trans.h Wed Jul 16 10:40:10 2008 +0000
11.3 @@ -42,33 +42,6 @@
11.4 #define MAX_RECOVERY_SIZE 2049
11.5
11.6 /**
11.7 - * Translation flag - exit the current block but continue (eg exception handling)
11.8 - */
11.9 -#define XLAT_EXIT_CONTINUE 1
11.10 -
11.11 -/**
11.12 - * Translation flag - exit the current block and halt immediately (eg fatal error)
11.13 - */
11.14 -#define XLAT_EXIT_HALT 2
11.15 -
11.16 -/**
11.17 - * Translation flag - exit the current block and halt immediately for a system
11.18 - * breakpoint.
11.19 - */
11.20 -#define XLAT_EXIT_BREAKPOINT 3
11.21 -
11.22 -/**
11.23 - * Translation flag - exit the current block and continue after performing a full
11.24 - * system reset (dreamcast_reset())
11.25 - */
11.26 -#define XLAT_EXIT_SYSRESET 4
11.27 -
11.28 -/**
11.29 - * Translation flag - exit the current block and continue after the next IRQ.
11.30 - */
11.31 -#define XLAT_EXIT_SLEEP 5
11.32 -
11.33 -/**
11.34 */
11.35 uint32_t sh4_xlat_run_slice( uint32_t nanosecs );
11.36
11.37 @@ -134,17 +107,17 @@
11.38 void sh4_translate_unwind_stack( gboolean is_completion, unwind_thunk_t thunk );
11.39
11.40 /**
11.41 - * From within the translator, immediately exit the current translation block with
11.42 - * the specified exit code (one of the XLAT_EXIT_* values).
11.43 + * Called when doing a break out of the translator - finalizes the system state up to
11.44 + * the end of the current instruction.
11.45 */
11.46 -void sh4_translate_exit( int exit_code );
11.47 +void sh4_translate_exit_recover( );
11.48
11.49 /**
11.50 * From within the translator, exit the current block at the end of the
11.51 - * current instruction, flush the translation cache (completely) and return
11.52 - * control to sh4_xlat_run_slice.
11.53 + * current instruction, flush the translation cache (completely)
11.54 + * @return TRUE to perform a vm-exit/continue after the flush
11.55 */
11.56 -void sh4_translate_flush_cache( void );
11.57 +gboolean sh4_translate_flush_cache( void );
11.58
11.59 /**
11.60 * Support function called from the translator when a breakpoint is hit.
12.1 --- a/src/test/testsh4x86.c Wed Jul 16 10:34:55 2008 +0000
12.2 +++ b/src/test/testsh4x86.c Wed Jul 16 10:40:10 2008 +0000
12.3 @@ -73,8 +73,9 @@
12.4 void sh4_accept_interrupt() {}
12.5 void sh4_set_breakpoint( uint32_t pc, breakpoint_type_t type ) { }
12.6 gboolean sh4_clear_breakpoint( uint32_t pc, breakpoint_type_t type ) { }
12.7 -gboolean sh4_is_using_xlat() { return TRUE; }
12.8 int sh4_get_breakpoint( uint32_t pc ) { }
12.9 +void sh4_core_exit( int exit_code ){}
12.10 +void sh4_flush_icache(){}
12.11 void event_execute() {}
12.12 void TMU_run_slice( uint32_t nanos ) {}
12.13 void SCIF_run_slice( uint32_t nanos ) {}
.