revision 951:63483914846f
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 951:63483914846f |
parent | 950:cc1e88104360 |
child | 952:18e579840923 |
author | nkeynes |
date | Wed Jan 07 05:45:15 2009 +0000 (15 years ago) |
branch | lxdream-mem |
Tidy up exceptions+resets
Implement manual reset on general exception when SR.BL == 1
Implement manual reset on general exception when SR.BL == 1
src/dreamcast.c | view | annotate | diff | log | ||
src/sh4/mmu.c | view | annotate | diff | log | ||
src/sh4/sh4.c | view | annotate | diff | log | ||
src/sh4/sh4core.h | view | annotate | diff | log | ||
src/sh4/sh4core.in | view | annotate | diff | log | ||
src/test/testsh4x86.c | view | annotate | diff | log |
1.1 --- a/src/dreamcast.c Wed Jan 07 04:54:32 2009 +00001.2 +++ b/src/dreamcast.c Wed Jan 07 05:45:15 2009 +00001.3 @@ -277,6 +277,7 @@1.4 dreamcast_program_name = g_strdup(name);1.5 dreamcast_entry_point = entry_point;1.6 sh4_set_pc(entry_point);1.7 + sh4_write_sr( sh4_read_sr() & (~SR_BL) ); /* Unmask interrupts */1.8 bios_install();1.9 dcload_install();1.10 gui_update_state();
2.1 --- a/src/sh4/mmu.c Wed Jan 07 04:54:32 2009 +00002.2 +++ b/src/sh4/mmu.c Wed Jan 07 05:45:15 2009 +00002.3 @@ -27,18 +27,12 @@2.4 #include "mem.h"2.5 #include "mmu.h"2.7 -#define RAISE_TLB_ERROR(code, vpn) \2.8 - MMIO_WRITE(MMU, TEA, vpn); \2.9 - MMIO_WRITE(MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00))); \2.10 - sh4_raise_tlb_exception(code);2.11 +#define RAISE_TLB_ERROR(code, vpn) sh4_raise_tlb_exception(code, vpn)2.12 #define RAISE_MEM_ERROR(code, vpn) \2.13 MMIO_WRITE(MMU, TEA, vpn); \2.14 MMIO_WRITE(MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00))); \2.15 sh4_raise_exception(code);2.16 -#define RAISE_TLB_MULTIHIT_ERROR(vpn) \2.17 - sh4_raise_reset(EXC_TLB_MULTI_HIT); \2.18 - MMIO_WRITE(MMU, TEA, vpn); \2.19 - MMIO_WRITE(MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00)));2.20 +#define RAISE_TLB_MULTIHIT_ERROR(vpn) sh4_raise_tlb_multihit(vpn)2.22 /* An entry is a 1K entry if it's one of the mmu_utlb_1k_pages entries */2.23 #define IS_1K_PAGE_ENTRY(ent) ( ((uintptr_t)(((struct utlb_1k_entry *)ent) - &mmu_utlb_1k_pages[0])) < UTLB_ENTRY_COUNT )2.24 @@ -1418,24 +1412,18 @@2.26 static int32_t FASTCALL tlb_multi_hit_read( sh4addr_t addr, void *exc )2.27 {2.28 - MMIO_WRITE(MMU, TEA, addr);2.29 - MMIO_WRITE(MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (addr&0xFFFFFC00)));2.30 - sh4_raise_reset(EXC_TLB_MULTI_HIT);2.31 + sh4_raise_tlb_multihit(addr);2.32 EXCEPTION_EXIT();2.33 }2.35 static int32_t FASTCALL tlb_multi_hit_read_burst( unsigned char *dest, sh4addr_t addr, void *exc )2.36 {2.37 - MMIO_WRITE(MMU, TEA, addr);2.38 - MMIO_WRITE(MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (addr&0xFFFFFC00)));2.39 - sh4_raise_reset(EXC_TLB_MULTI_HIT);2.40 + sh4_raise_tlb_multihit(addr);2.41 EXCEPTION_EXIT();2.42 }2.43 static void FASTCALL tlb_multi_hit_write( sh4addr_t addr, uint32_t val, void *exc )2.44 {2.45 - MMIO_WRITE(MMU, TEA, addr);2.46 - MMIO_WRITE(MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (addr&0xFFFFFC00)));2.47 - sh4_raise_reset(EXC_TLB_MULTI_HIT);2.48 + sh4_raise_tlb_multihit(addr);2.49 EXCEPTION_EXIT();2.50 }
3.1 --- a/src/sh4/sh4.c Wed Jan 07 04:54:32 2009 +00003.2 +++ b/src/sh4/sh4.c Wed Jan 07 05:45:15 2009 +00003.3 @@ -36,7 +36,7 @@3.5 void sh4_init( void );3.6 void sh4_xlat_init( void );3.7 -void sh4_reset( void );3.8 +void sh4_poweron_reset( void );3.9 void sh4_start( void );3.10 void sh4_stop( void );3.11 void sh4_save_state( FILE *f );3.12 @@ -45,7 +45,7 @@3.13 uint32_t sh4_run_slice( uint32_t );3.14 uint32_t sh4_xlat_run_slice( uint32_t );3.16 -struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset,3.17 +struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_poweron_reset,3.18 sh4_start, sh4_run_slice, sh4_stop,3.19 sh4_save_state, sh4_load_state };3.21 @@ -81,7 +81,7 @@3.22 MMU_init();3.23 TMU_init();3.24 xlat_cache_init();3.25 - sh4_reset();3.26 + sh4_poweron_reset();3.27 #ifdef ENABLE_SH4STATS3.28 sh4_stats_reset();3.29 #endif3.30 @@ -92,15 +92,14 @@3.31 sh4_starting = TRUE;3.32 }3.34 -void sh4_reset(void)3.35 +void sh4_poweron_reset(void)3.36 {3.37 + /* zero everything out, for the sake of having a consistent state. */3.38 + memset( &sh4r, 0, sizeof(sh4r) );3.39 if( sh4_use_translator ) {3.40 xlat_flush_cache();3.41 }3.43 - /* zero everything out, for the sake of having a consistent state. */3.44 - memset( &sh4r, 0, sizeof(sh4r) );3.45 -3.46 /* Resume running if we were halted */3.47 sh4r.sh4_state = SH4_STATE_RUNNING;3.49 @@ -116,14 +115,10 @@3.50 /* Peripheral modules */3.51 CPG_reset();3.52 INTC_reset();3.53 - MMU_reset();3.54 PMM_reset();3.55 TMU_reset();3.56 SCIF_reset();3.57 -3.58 -#ifdef ENABLE_SH4STATS3.59 - sh4_stats_reset();3.60 -#endif3.61 + MMU_reset();3.62 }3.64 void sh4_stop(void)3.65 @@ -354,79 +349,88 @@3.66 return sh4r.sr;3.67 }3.69 +/**3.70 + * Raise a CPU reset exception with the specified exception code.3.71 + */3.72 +void FASTCALL sh4_raise_reset( int code )3.73 +{3.74 + MMIO_WRITE(MMU,EXPEVT,code);3.75 + sh4r.vbr = 0x00000000;3.76 + sh4r.pc = 0xA0000000;3.77 + sh4r.new_pc = sh4r.pc + 2;3.78 + sh4r.in_delay_slot = 0;3.79 + sh4_write_sr( (sh4r.sr|SR_MD|SR_BL|SR_RB|SR_IMASK)&(~SR_FD) );3.80 +3.81 + /* Peripheral manual reset (FIXME: incomplete) */3.82 + INTC_reset();3.83 + SCIF_reset();3.84 + MMU_reset();3.85 +}3.87 -3.88 -#define RAISE( x, v ) do{ \3.89 - if( sh4r.vbr == 0 ) { \3.90 - ERROR( "%08X: VBR not initialized while raising exception %03X, halting", sh4r.pc, x ); \3.91 - sh4_core_exit(CORE_EXIT_HALT); return FALSE; \3.92 - } else { \3.93 - sh4r.spc = sh4r.pc; \3.94 - sh4r.ssr = sh4_read_sr(); \3.95 - sh4r.sgr = sh4r.r[15]; \3.96 - MMIO_WRITE(MMU,EXPEVT,x); \3.97 - sh4r.pc = sh4r.vbr + v; \3.98 - sh4r.new_pc = sh4r.pc + 2; \3.99 - sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB ); \3.100 - sh4r.in_delay_slot = 0; \3.101 - } \3.102 - return TRUE; } while(0)3.103 +void FASTCALL sh4_raise_tlb_multihit( sh4vma_t vpn )3.104 +{3.105 + MMIO_WRITE( MMU, TEA, vpn );3.106 + MMIO_WRITE( MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00)) );3.107 + sh4_raise_reset( EXC_TLB_MULTI_HIT );3.108 +}3.110 /**3.111 * Raise a general CPU exception for the specified exception code.3.112 * (NOT for TRAPA or TLB exceptions)3.113 */3.114 -gboolean FASTCALL sh4_raise_exception( int code )3.115 +void FASTCALL sh4_raise_exception( int code )3.116 {3.117 - RAISE( code, EXV_EXCEPTION );3.118 -}3.119 -3.120 -/**3.121 - * Raise a CPU reset exception with the specified exception code.3.122 - */3.123 -gboolean FASTCALL sh4_raise_reset( int code )3.124 -{3.125 - // FIXME: reset modules as per "manual reset"3.126 - sh4_reset();3.127 - MMIO_WRITE(MMU,EXPEVT,code);3.128 - sh4r.vbr = 0;3.129 - sh4r.pc = 0xA0000000;3.130 - sh4r.new_pc = sh4r.pc + 2;3.131 - sh4_write_sr( (sh4r.sr|SR_MD|SR_BL|SR_RB|SR_IMASK)3.132 - &(~SR_FD) );3.133 - return TRUE;3.134 -}3.135 -3.136 -gboolean FASTCALL sh4_raise_trap( int trap )3.137 -{3.138 - MMIO_WRITE( MMU, TRA, trap<<2 );3.139 - RAISE( EXC_TRAP, EXV_EXCEPTION );3.140 -}3.141 -3.142 -gboolean FASTCALL sh4_raise_slot_exception( int normal_code, int slot_code ) {3.143 - if( sh4r.in_delay_slot ) {3.144 - return sh4_raise_exception(slot_code);3.145 + if( sh4r.sr & SR_BL ) {3.146 + sh4_raise_reset( EXC_MANUAL_RESET );3.147 } else {3.148 - return sh4_raise_exception(normal_code);3.149 + sh4r.spc = sh4r.pc;3.150 + sh4r.ssr = sh4_read_sr();3.151 + sh4r.sgr = sh4r.r[15];3.152 + MMIO_WRITE(MMU,EXPEVT, code);3.153 + sh4r.pc = sh4r.vbr + EXV_EXCEPTION;3.154 + sh4r.new_pc = sh4r.pc + 2;3.155 + sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB );3.156 + sh4r.in_delay_slot = 0;3.157 }3.158 }3.160 -gboolean FASTCALL sh4_raise_tlb_exception( int code )3.161 +void FASTCALL sh4_raise_trap( int trap )3.162 {3.163 - RAISE( code, EXV_TLBMISS );3.164 + MMIO_WRITE( MMU, TRA, trap<<2 );3.165 + MMIO_WRITE( MMU, EXPEVT, EXC_TRAP );3.166 + sh4r.spc = sh4r.pc;3.167 + sh4r.ssr = sh4_read_sr();3.168 + sh4r.sgr = sh4r.r[15];3.169 + sh4r.pc = sh4r.vbr + EXV_EXCEPTION;3.170 + sh4r.new_pc = sh4r.pc + 2;3.171 + sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB );3.172 + sh4r.in_delay_slot = 0;3.173 +}3.174 +3.175 +void FASTCALL sh4_raise_tlb_exception( int code, sh4vma_t vpn )3.176 +{3.177 + MMIO_WRITE( MMU, TEA, vpn );3.178 + MMIO_WRITE( MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00)) );3.179 + MMIO_WRITE( MMU, EXPEVT, code );3.180 + sh4r.spc = sh4r.pc;3.181 + sh4r.ssr = sh4_read_sr();3.182 + sh4r.sgr = sh4r.r[15];3.183 + sh4r.pc = sh4r.vbr + EXV_TLBMISS;3.184 + sh4r.new_pc = sh4r.pc + 2;3.185 + sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB );3.186 + sh4r.in_delay_slot = 0;3.187 }3.189 void FASTCALL sh4_accept_interrupt( void )3.190 {3.191 uint32_t code = intc_accept_interrupt();3.192 + MMIO_WRITE( MMU, INTEVT, code );3.193 sh4r.ssr = sh4_read_sr();3.194 sh4r.spc = sh4r.pc;3.195 sh4r.sgr = sh4r.r[15];3.196 sh4_write_sr( sh4r.ssr|SR_BL|SR_MD|SR_RB );3.197 - MMIO_WRITE( MMU, INTEVT, code );3.198 sh4r.pc = sh4r.vbr + 0x600;3.199 sh4r.new_pc = sh4r.pc + 2;3.200 - // WARN( "Accepting interrupt %03X, from %08X => %08X", code, sh4r.spc, sh4r.pc );3.201 }3.203 void FASTCALL signsat48( void )
4.1 --- a/src/sh4/sh4core.h Wed Jan 07 04:54:32 2009 +00004.2 +++ b/src/sh4/sh4core.h Wed Jan 07 05:45:15 2009 +00004.3 @@ -232,11 +232,11 @@4.4 #define EXV_TLBMISS 0x400 /* TLB-miss exception vector */4.5 #define EXV_INTERRUPT 0x600 /* External interrupt vector */4.7 -gboolean FASTCALL sh4_raise_exception( int );4.8 -gboolean FASTCALL sh4_raise_reset( int );4.9 -gboolean FASTCALL sh4_raise_trap( int );4.10 -gboolean FASTCALL sh4_raise_slot_exception( int, int );4.11 -gboolean FASTCALL sh4_raise_tlb_exception( int );4.12 +void FASTCALL sh4_raise_exception( int );4.13 +void FASTCALL sh4_raise_reset( int );4.14 +void FASTCALL sh4_raise_trap( int );4.15 +void FASTCALL sh4_raise_tlb_exception( int, sh4vma_t );4.16 +void FASTCALL sh4_raise_tlb_multihit( sh4vma_t );4.17 void FASTCALL sh4_accept_interrupt( void );4.19 /**
5.1 --- a/src/sh4/sh4core.in Wed Jan 07 04:54:32 2009 +00005.2 +++ b/src/sh4/sh4core.in Wed Jan 07 05:45:15 2009 +00005.3 @@ -149,17 +149,27 @@5.4 #define TRACE_RETURN( source, dest )5.5 #endif5.7 -#define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL )5.8 -#define CHECKRALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )5.9 -#define CHECKRALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )5.10 -#define CHECKRALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )5.11 -#define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )5.12 -#define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )5.13 -#define CHECKWALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )5.14 +static gboolean FASTCALL sh4_raise_slot_exception( int normal_code, int slot_code ) {5.15 + if( sh4r.in_delay_slot ) {5.16 + sh4_raise_exception(slot_code);5.17 + } else {5.18 + sh4_raise_exception(normal_code);5.19 + }5.20 + return TRUE;5.21 +}5.22 +5.23 +5.24 +#define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) { return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL ); }5.25 +#define CHECKRALIGN16(addr) if( (addr)&0x01 ) { sh4_raise_exception( EXC_DATA_ADDR_READ ); return TRUE; }5.26 +#define CHECKRALIGN32(addr) if( (addr)&0x03 ) { sh4_raise_exception( EXC_DATA_ADDR_READ ); return TRUE; }5.27 +#define CHECKRALIGN64(addr) if( (addr)&0x07 ) { sh4_raise_exception( EXC_DATA_ADDR_READ ); return TRUE; }5.28 +#define CHECKWALIGN16(addr) if( (addr)&0x01 ) { sh4_raise_exception( EXC_DATA_ADDR_WRITE ); return TRUE; }5.29 +#define CHECKWALIGN32(addr) if( (addr)&0x03 ) { sh4_raise_exception( EXC_DATA_ADDR_WRITE ); return TRUE; }5.30 +#define CHECKWALIGN64(addr) if( (addr)&0x07 ) { sh4_raise_exception( EXC_DATA_ADDR_WRITE ); return TRUE; }5.32 #define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPU_DISABLED, EXC_SLOT_FPU_DISABLED ); } }5.33 #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); sh4_core_exit(CORE_EXIT_HALT); return FALSE; }5.34 -#define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)5.35 +#define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) { sh4_raise_exception(EXC_SLOT_ILLEGAL); return TRUE; }5.37 #define ADDRSPACE (IS_SH4_PRIVMODE() ? sh4_address_space : sh4_user_address_space)5.38 #define SQADDRSPACE (IS_SH4_PRIVMODE() ? storequeue_address_space : storequeue_user_address_space)
6.1 --- a/src/test/testsh4x86.c Wed Jan 07 04:54:32 2009 +00006.2 +++ b/src/test/testsh4x86.c Wed Jan 07 05:45:15 2009 +00006.3 @@ -98,10 +98,11 @@6.4 void syscall_invoke( uint32_t val ) { }6.5 void dreamcast_stop() {}6.6 void dreamcast_reset() {}6.7 -gboolean FASTCALL sh4_raise_reset( int exc ) { return TRUE; }6.8 -gboolean FASTCALL sh4_raise_exception( int exc ) { return TRUE; }6.9 -gboolean FASTCALL sh4_raise_tlb_exception( int exc ) { return TRUE; }6.10 -gboolean FASTCALL sh4_raise_trap( int exc ) { return TRUE; }6.11 +void FASTCALL sh4_raise_reset( int exc ) { }6.12 +void FASTCALL sh4_raise_exception( int exc ) { }6.13 +void FASTCALL sh4_raise_tlb_exception( int exc, sh4vma_t vma ) { }6.14 +void FASTCALL sh4_raise_tlb_multihit( sh4vma_t vma) { }6.15 +void FASTCALL sh4_raise_trap( int exc ) { }6.16 void FASTCALL sh4_flush_store_queue( sh4addr_t addr ) { }6.17 void FASTCALL sh4_flush_store_queue_mmu( sh4addr_t addr, void *exc ) { }6.18 uint32_t sh4_sleep_run_slice(uint32_t nanosecs) { return nanosecs; }
.