filename | src/sh4/sh4.c |
changeset | 951:63483914846f |
prev | 948:545c85cc56f1 |
next | 1067:d3c00ffccfcd |
author | nkeynes |
date | Wed Jan 07 05:45:15 2009 +0000 (15 years ago) |
branch | lxdream-mem |
permissions | -rw-r--r-- |
last change | Tidy up exceptions+resets Implement manual reset on general exception when SR.BL == 1 |
file | annotate | diff | log | raw |
1.1 --- a/src/sh4/sh4.c Wed Jan 07 04:39:04 2009 +00001.2 +++ b/src/sh4/sh4.c Wed Jan 07 05:45:15 2009 +00001.3 @@ -36,7 +36,7 @@1.5 void sh4_init( void );1.6 void sh4_xlat_init( void );1.7 -void sh4_reset( void );1.8 +void sh4_poweron_reset( void );1.9 void sh4_start( void );1.10 void sh4_stop( void );1.11 void sh4_save_state( FILE *f );1.12 @@ -45,7 +45,7 @@1.13 uint32_t sh4_run_slice( uint32_t );1.14 uint32_t sh4_xlat_run_slice( uint32_t );1.16 -struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset,1.17 +struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_poweron_reset,1.18 sh4_start, sh4_run_slice, sh4_stop,1.19 sh4_save_state, sh4_load_state };1.21 @@ -81,7 +81,7 @@1.22 MMU_init();1.23 TMU_init();1.24 xlat_cache_init();1.25 - sh4_reset();1.26 + sh4_poweron_reset();1.27 #ifdef ENABLE_SH4STATS1.28 sh4_stats_reset();1.29 #endif1.30 @@ -92,15 +92,14 @@1.31 sh4_starting = TRUE;1.32 }1.34 -void sh4_reset(void)1.35 +void sh4_poweron_reset(void)1.36 {1.37 + /* zero everything out, for the sake of having a consistent state. */1.38 + memset( &sh4r, 0, sizeof(sh4r) );1.39 if( sh4_use_translator ) {1.40 xlat_flush_cache();1.41 }1.43 - /* zero everything out, for the sake of having a consistent state. */1.44 - memset( &sh4r, 0, sizeof(sh4r) );1.45 -1.46 /* Resume running if we were halted */1.47 sh4r.sh4_state = SH4_STATE_RUNNING;1.49 @@ -116,14 +115,10 @@1.50 /* Peripheral modules */1.51 CPG_reset();1.52 INTC_reset();1.53 - MMU_reset();1.54 PMM_reset();1.55 TMU_reset();1.56 SCIF_reset();1.57 -1.58 -#ifdef ENABLE_SH4STATS1.59 - sh4_stats_reset();1.60 -#endif1.61 + MMU_reset();1.62 }1.64 void sh4_stop(void)1.65 @@ -354,79 +349,88 @@1.66 return sh4r.sr;1.67 }1.69 +/**1.70 + * Raise a CPU reset exception with the specified exception code.1.71 + */1.72 +void FASTCALL sh4_raise_reset( int code )1.73 +{1.74 + MMIO_WRITE(MMU,EXPEVT,code);1.75 + sh4r.vbr = 0x00000000;1.76 + sh4r.pc = 0xA0000000;1.77 + sh4r.new_pc = sh4r.pc + 2;1.78 + sh4r.in_delay_slot = 0;1.79 + sh4_write_sr( (sh4r.sr|SR_MD|SR_BL|SR_RB|SR_IMASK)&(~SR_FD) );1.80 +1.81 + /* Peripheral manual reset (FIXME: incomplete) */1.82 + INTC_reset();1.83 + SCIF_reset();1.84 + MMU_reset();1.85 +}1.87 -1.88 -#define RAISE( x, v ) do{ \1.89 - if( sh4r.vbr == 0 ) { \1.90 - ERROR( "%08X: VBR not initialized while raising exception %03X, halting", sh4r.pc, x ); \1.91 - sh4_core_exit(CORE_EXIT_HALT); return FALSE; \1.92 - } else { \1.93 - sh4r.spc = sh4r.pc; \1.94 - sh4r.ssr = sh4_read_sr(); \1.95 - sh4r.sgr = sh4r.r[15]; \1.96 - MMIO_WRITE(MMU,EXPEVT,x); \1.97 - sh4r.pc = sh4r.vbr + v; \1.98 - sh4r.new_pc = sh4r.pc + 2; \1.99 - sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB ); \1.100 - sh4r.in_delay_slot = 0; \1.101 - } \1.102 - return TRUE; } while(0)1.103 +void FASTCALL sh4_raise_tlb_multihit( sh4vma_t vpn )1.104 +{1.105 + MMIO_WRITE( MMU, TEA, vpn );1.106 + MMIO_WRITE( MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00)) );1.107 + sh4_raise_reset( EXC_TLB_MULTI_HIT );1.108 +}1.110 /**1.111 * Raise a general CPU exception for the specified exception code.1.112 * (NOT for TRAPA or TLB exceptions)1.113 */1.114 -gboolean FASTCALL sh4_raise_exception( int code )1.115 +void FASTCALL sh4_raise_exception( int code )1.116 {1.117 - RAISE( code, EXV_EXCEPTION );1.118 -}1.119 -1.120 -/**1.121 - * Raise a CPU reset exception with the specified exception code.1.122 - */1.123 -gboolean FASTCALL sh4_raise_reset( int code )1.124 -{1.125 - // FIXME: reset modules as per "manual reset"1.126 - sh4_reset();1.127 - MMIO_WRITE(MMU,EXPEVT,code);1.128 - sh4r.vbr = 0;1.129 - sh4r.pc = 0xA0000000;1.130 - sh4r.new_pc = sh4r.pc + 2;1.131 - sh4_write_sr( (sh4r.sr|SR_MD|SR_BL|SR_RB|SR_IMASK)1.132 - &(~SR_FD) );1.133 - return TRUE;1.134 -}1.135 -1.136 -gboolean FASTCALL sh4_raise_trap( int trap )1.137 -{1.138 - MMIO_WRITE( MMU, TRA, trap<<2 );1.139 - RAISE( EXC_TRAP, EXV_EXCEPTION );1.140 -}1.141 -1.142 -gboolean FASTCALL sh4_raise_slot_exception( int normal_code, int slot_code ) {1.143 - if( sh4r.in_delay_slot ) {1.144 - return sh4_raise_exception(slot_code);1.145 + if( sh4r.sr & SR_BL ) {1.146 + sh4_raise_reset( EXC_MANUAL_RESET );1.147 } else {1.148 - return sh4_raise_exception(normal_code);1.149 + sh4r.spc = sh4r.pc;1.150 + sh4r.ssr = sh4_read_sr();1.151 + sh4r.sgr = sh4r.r[15];1.152 + MMIO_WRITE(MMU,EXPEVT, code);1.153 + sh4r.pc = sh4r.vbr + EXV_EXCEPTION;1.154 + sh4r.new_pc = sh4r.pc + 2;1.155 + sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB );1.156 + sh4r.in_delay_slot = 0;1.157 }1.158 }1.160 -gboolean FASTCALL sh4_raise_tlb_exception( int code )1.161 +void FASTCALL sh4_raise_trap( int trap )1.162 {1.163 - RAISE( code, EXV_TLBMISS );1.164 + MMIO_WRITE( MMU, TRA, trap<<2 );1.165 + MMIO_WRITE( MMU, EXPEVT, EXC_TRAP );1.166 + sh4r.spc = sh4r.pc;1.167 + sh4r.ssr = sh4_read_sr();1.168 + sh4r.sgr = sh4r.r[15];1.169 + sh4r.pc = sh4r.vbr + EXV_EXCEPTION;1.170 + sh4r.new_pc = sh4r.pc + 2;1.171 + sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB );1.172 + sh4r.in_delay_slot = 0;1.173 +}1.174 +1.175 +void FASTCALL sh4_raise_tlb_exception( int code, sh4vma_t vpn )1.176 +{1.177 + MMIO_WRITE( MMU, TEA, vpn );1.178 + MMIO_WRITE( MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00)) );1.179 + MMIO_WRITE( MMU, EXPEVT, code );1.180 + sh4r.spc = sh4r.pc;1.181 + sh4r.ssr = sh4_read_sr();1.182 + sh4r.sgr = sh4r.r[15];1.183 + sh4r.pc = sh4r.vbr + EXV_TLBMISS;1.184 + sh4r.new_pc = sh4r.pc + 2;1.185 + sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB );1.186 + sh4r.in_delay_slot = 0;1.187 }1.189 void FASTCALL sh4_accept_interrupt( void )1.190 {1.191 uint32_t code = intc_accept_interrupt();1.192 + MMIO_WRITE( MMU, INTEVT, code );1.193 sh4r.ssr = sh4_read_sr();1.194 sh4r.spc = sh4r.pc;1.195 sh4r.sgr = sh4r.r[15];1.196 sh4_write_sr( sh4r.ssr|SR_BL|SR_MD|SR_RB );1.197 - MMIO_WRITE( MMU, INTEVT, code );1.198 sh4r.pc = sh4r.vbr + 0x600;1.199 sh4r.new_pc = sh4r.pc + 2;1.200 - // WARN( "Accepting interrupt %03X, from %08X => %08X", code, sh4r.spc, sh4r.pc );1.201 }1.203 void FASTCALL signsat48( void )
.