filename | src/sh4/shadow.c |
changeset | 1217:677b1d85f1b4 |
prev | 1202:01ae5cbad4c8 |
next | 1298:d0eb2307b847 |
author | nkeynes |
date | Sat Jan 26 14:00:48 2013 +1000 (11 years ago) |
permissions | -rw-r--r-- |
last change | Change glib includes to #include <glib.h> rather than the individual headers, as recent glib versions are breaking on this |
file | annotate | diff | log | raw |
1.1 --- a/src/sh4/shadow.c Fri Dec 23 08:20:17 2011 +10001.2 +++ b/src/sh4/shadow.c Sat Jan 26 14:00:48 2013 +10001.3 @@ -23,18 +23,12 @@1.5 #include "clock.h"1.6 #include "mem.h"1.7 +#include "mmio.h"1.8 #include "sh4/sh4.h"1.9 #include "sh4/sh4core.h"1.10 #include "sh4/sh4trans.h"1.11 #include "sh4/mmu.h"1.13 -#ifdef HAVE_FRAME_ADDRESS1.14 -static FASTCALL __attribute__((noinline)) void *__first_arg(void *a, void *b) { return a; }1.15 -#define INIT_EXCEPTIONS(label) goto *__first_arg(&&fnstart,&&label); fnstart:1.16 -#else1.17 -#define INIT_EXCEPTIONS(label)1.18 -#endif1.19 -1.20 typedef enum {1.21 READ_LONG,1.22 WRITE_LONG,1.23 @@ -53,13 +47,17 @@1.24 MemOp op;1.25 sh4addr_t addr;1.26 uint32_t value;1.27 - sh4addr_t exception_pc;1.28 };1.30 static struct sh4_registers shadow_sh4r;1.31 -static struct mem_region_fn **log_address_space;1.32 -static struct mem_region_fn **check_address_space;1.33 -static struct mem_region_fn **real_address_space;1.34 +static struct mem_region_fn **shadow_address_space;1.35 +static struct mem_region_fn **p4_address_space;1.36 +1.37 +typedef enum {1.38 + SHADOW_LOG,1.39 + SHADOW_CHECK1.40 +} shadow_mode_t;1.41 +static shadow_mode_t shadow_address_mode = SHADOW_LOG;1.43 #define MEM_LOG_SIZE 40961.44 static struct mem_log_entry *mem_log;1.45 @@ -68,7 +66,7 @@1.47 #define IS_STORE_QUEUE(X) (((X)&0xFC000000) == 0xE0000000)1.49 -static void log_mem_op( MemOp op, sh4addr_t addr, uint32_t value, int exception )1.50 +static void log_mem_op( MemOp op, sh4addr_t addr, uint32_t value )1.51 {1.52 if( mem_log_posn == mem_log_size ) {1.53 struct mem_log_entry *tmp = realloc(mem_log, mem_log_size * sizeof(struct mem_log_entry) * 2);1.54 @@ -79,11 +77,6 @@1.55 mem_log[mem_log_posn].op = op;1.56 mem_log[mem_log_posn].addr = addr;1.57 mem_log[mem_log_posn].value = value;1.58 - if( exception ) {1.59 - mem_log[mem_log_posn].exception_pc = sh4r.pc;1.60 - } else {1.61 - mem_log[mem_log_posn].exception_pc = -1;1.62 - }1.63 mem_log_posn++;1.64 }1.66 @@ -103,7 +96,7 @@1.67 }1.68 }1.70 -static int32_t check_mem_op( MemOp op, sh4addr_t addr, uint32_t value, int *exception )1.71 +static int32_t check_mem_op( MemOp op, sh4addr_t addr, uint32_t value )1.72 {1.73 if( mem_check_posn >= mem_log_posn ) {1.74 fprintf( stderr, "Unexpected interpreter memory operation: " );1.75 @@ -121,14 +114,6 @@1.76 print_mem_op(stderr, op, addr, value );1.77 abort();1.78 }1.79 -1.80 - if( mem_log[mem_check_posn].exception_pc != -1 ) {1.81 - sh4_reraise_exception(mem_log[mem_check_posn].exception_pc);1.82 - *exception = 1;1.83 - } else {1.84 - *exception = 0;1.85 - }1.86 -1.87 return mem_log[mem_check_posn++].value;1.88 }1.90 @@ -201,202 +186,117 @@1.91 return isgood;1.92 }1.94 -static FASTCALL int32_t log_read_long( sh4addr_t addr, void *exc )1.95 +static mem_region_fn_t real_region( sh4addr_t addr )1.96 {1.97 - INIT_EXCEPTIONS(except);1.98 - int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_long)(addr, &&except);1.99 - log_mem_op( READ_LONG, addr, rv, 0 );1.100 - return rv;1.101 -except:1.102 - log_mem_op( READ_LONG, addr, rv, 1 );1.103 - SH4_EXCEPTION_EXIT();1.104 + if( addr >= 0xE0000000 )1.105 + return p4_address_space[VMA_TO_EXT_ADDR(addr)>>12];1.106 + else1.107 + return ext_address_space[VMA_TO_EXT_ADDR(addr)>>12];1.108 }1.110 -static FASTCALL int32_t log_read_word( sh4addr_t addr, void *exc )1.111 +static FASTCALL int32_t shadow_read_long( sh4addr_t addr )1.112 {1.113 - INIT_EXCEPTIONS(except);1.114 - int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_word)(addr, &&except);1.115 - log_mem_op( READ_WORD, addr, rv, 0 );1.116 - return rv;1.117 -except:1.118 - log_mem_op( READ_WORD, addr, rv, 1 );1.119 - SH4_EXCEPTION_EXIT();1.120 -}1.121 -1.122 -static FASTCALL int32_t log_read_byte( sh4addr_t addr, void *exc )1.123 -{1.124 - INIT_EXCEPTIONS(except);1.125 - int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_byte)(addr, &&except);1.126 - log_mem_op( READ_BYTE, addr, rv, 0 );1.127 - return rv;1.128 -except:1.129 - log_mem_op( READ_BYTE, addr, rv, 1 );1.130 - SH4_EXCEPTION_EXIT();1.131 -}1.132 -1.133 -static FASTCALL int32_t log_read_byte_for_write( sh4addr_t addr, void *exc )1.134 -{1.135 - INIT_EXCEPTIONS(except);1.136 - int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_byte_for_write)(addr, &&except);1.137 - log_mem_op( READ_BYTE_FOR_WRITE, addr, rv, 0 );1.138 - return rv;1.139 -except:1.140 - log_mem_op( READ_BYTE_FOR_WRITE, addr, rv, 1 );1.141 - SH4_EXCEPTION_EXIT();1.142 -}1.143 -1.144 -static FASTCALL void log_write_long( sh4addr_t addr, uint32_t val, void *exc )1.145 -{1.146 - INIT_EXCEPTIONS(except);1.147 - ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_long)(addr, val, &&except);1.148 - if( !IS_STORE_QUEUE(addr) )1.149 - log_mem_op( WRITE_LONG, addr, val, 0 );1.150 - return;1.151 -except:1.152 - if( !IS_STORE_QUEUE(addr) )1.153 - log_mem_op( WRITE_LONG, addr, val, 1 );1.154 - SH4_EXCEPTION_EXIT();1.155 -}1.156 -1.157 -static FASTCALL void log_write_word( sh4addr_t addr, uint32_t val, void *exc )1.158 -{1.159 - INIT_EXCEPTIONS(except);1.160 - ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_word)(addr, val, &&except);1.161 - if( !IS_STORE_QUEUE(addr) )1.162 - log_mem_op( WRITE_WORD, addr, val, 0 );1.163 - return;1.164 -except:1.165 - if( !IS_STORE_QUEUE(addr) )1.166 - log_mem_op( WRITE_WORD, addr, val, 1 );1.167 - SH4_EXCEPTION_EXIT();1.168 -}1.169 -1.170 -static FASTCALL void log_write_byte( sh4addr_t addr, uint32_t val, void *exc )1.171 -{1.172 - INIT_EXCEPTIONS(except);1.173 - ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_byte)(addr, val, &&except);1.174 - if( !IS_STORE_QUEUE(addr) )1.175 - log_mem_op( WRITE_BYTE, addr, val, 0 );1.176 - return;1.177 -except:1.178 - if( !IS_STORE_QUEUE(addr) )1.179 - log_mem_op( WRITE_BYTE, addr, val, 1 );1.180 - SH4_EXCEPTION_EXIT();1.181 -}1.182 -1.183 -static FASTCALL void log_prefetch( sh4addr_t addr, void *exc )1.184 -{1.185 - INIT_EXCEPTIONS(except);1.186 - ((mem_prefetch_exc_fn_t)real_address_space[addr>>12]->prefetch)(addr, &&except);1.187 - log_mem_op( PREFETCH, addr, 0, 0 );1.188 - return;1.189 -except:1.190 - log_mem_op( PREFETCH, addr, 0, 1 );1.191 - SH4_EXCEPTION_EXIT();1.192 -}1.193 -1.194 -static FASTCALL int32_t check_read_long( sh4addr_t addr, void *exc )1.195 -{1.196 - int except;1.197 - int32_t value = check_mem_op( READ_LONG, addr, 0, &except );1.198 - if( except ) {1.199 - SH4_EXCEPTION_EXIT();1.200 - }1.201 - return value;1.202 -}1.203 -1.204 -static FASTCALL int32_t check_read_word( sh4addr_t addr, void *exc )1.205 -{1.206 - int except;1.207 - int32_t value = check_mem_op( READ_WORD, addr, 0, &except );1.208 - if( except ) {1.209 - SH4_EXCEPTION_EXIT();1.210 - }1.211 - return value;1.212 -}1.213 -1.214 -static FASTCALL int32_t check_read_byte( sh4addr_t addr, void *exc )1.215 -{1.216 - int except;1.217 - int32_t value = check_mem_op( READ_BYTE, addr, 0, &except );1.218 - if( except ) {1.219 - SH4_EXCEPTION_EXIT();1.220 - }1.221 - return value;1.222 -}1.223 -1.224 -static FASTCALL int32_t check_read_byte_for_write( sh4addr_t addr, void *exc )1.225 -{1.226 - int except;1.227 - int32_t value = check_mem_op( READ_BYTE_FOR_WRITE, addr, 0, &except );1.228 - if( except ) {1.229 - SH4_EXCEPTION_EXIT();1.230 - }1.231 - return value;1.232 -}1.233 -1.234 -static FASTCALL void check_write_long( sh4addr_t addr, uint32_t value, void *exc )1.235 -{1.236 - if( !IS_STORE_QUEUE(addr) ) {1.237 - int except;1.238 - check_mem_op( WRITE_LONG, addr, value, &except );1.239 - if( except ) {1.240 - SH4_EXCEPTION_EXIT();1.241 - }1.242 + if( shadow_address_mode == SHADOW_LOG ) {1.243 + int32_t rv = real_region(addr)->read_long(addr);1.244 + log_mem_op( READ_LONG, addr, rv );1.245 + return rv;1.246 } else {1.247 - real_address_space[addr>>12]->write_long(addr, value);1.248 + return check_mem_op( READ_LONG, addr, 0 );1.249 }1.250 }1.252 -static FASTCALL void check_write_word( sh4addr_t addr, uint32_t value, void *exc )1.253 +static FASTCALL int32_t shadow_read_word( sh4addr_t addr )1.254 {1.255 - if( !IS_STORE_QUEUE(addr) ) {1.256 - int except;1.257 - check_mem_op( WRITE_WORD, addr, value, &except );1.258 - if( except ) {1.259 - SH4_EXCEPTION_EXIT();1.260 - }1.261 + if( shadow_address_mode == SHADOW_LOG ) {1.262 + int32_t rv = real_region(addr)->read_word(addr);1.263 + log_mem_op( READ_WORD, addr, rv );1.264 + return rv;1.265 } else {1.266 - real_address_space[addr>>12]->write_word(addr, value);1.267 + return check_mem_op( READ_WORD, addr, 0 );1.268 }1.269 }1.271 -static FASTCALL void check_write_byte( sh4addr_t addr, uint32_t value, void *exc )1.272 +static FASTCALL int32_t shadow_read_byte( sh4addr_t addr )1.273 {1.274 - if( !IS_STORE_QUEUE(addr) ){1.275 - int except;1.276 - check_mem_op( WRITE_BYTE, addr, value, &except );1.277 - if( except ) {1.278 - SH4_EXCEPTION_EXIT();1.279 - }1.280 + if( shadow_address_mode == SHADOW_LOG ) {1.281 + int32_t rv = real_region(addr)->read_byte(addr);1.282 + log_mem_op( READ_BYTE, addr, rv );1.283 + return rv;1.284 } else {1.285 - real_address_space[addr>>12]->write_byte(addr, value);1.286 + return check_mem_op( READ_BYTE, addr, 0 );1.287 }1.288 }1.290 -static FASTCALL void check_prefetch( sh4addr_t addr, void *exc )1.291 +static FASTCALL int32_t shadow_read_byte_for_write( sh4addr_t addr )1.292 {1.293 - int except;1.294 - check_mem_op( PREFETCH, addr, 0, &except );1.295 - if( except ) {1.296 - SH4_EXCEPTION_EXIT();1.297 + if( shadow_address_mode == SHADOW_LOG ) {1.298 + int32_t rv = real_region(addr)->read_byte_for_write(addr);1.299 + log_mem_op( READ_BYTE_FOR_WRITE, addr, rv );1.300 + return rv;1.301 + } else {1.302 + return check_mem_op( READ_BYTE_FOR_WRITE, addr, 0 );1.303 }1.304 }1.306 -struct mem_region_fn log_fns = {1.307 - (mem_read_fn_t)log_read_long, (mem_write_fn_t)log_write_long,1.308 - (mem_read_fn_t)log_read_word, (mem_write_fn_t)log_write_word,1.309 - (mem_read_fn_t)log_read_byte, (mem_write_fn_t)log_write_byte,1.310 - NULL, NULL, (mem_prefetch_fn_t)log_prefetch, (mem_read_fn_t)log_read_byte_for_write };1.311 +static FASTCALL void shadow_write_long( sh4addr_t addr, uint32_t val )1.312 +{1.313 + if( shadow_address_mode == SHADOW_LOG ) {1.314 + real_region(addr)->write_long(addr, val);1.315 + if( !IS_STORE_QUEUE(addr) )1.316 + log_mem_op( WRITE_LONG, addr, val );1.317 + } else {1.318 + if( !IS_STORE_QUEUE(addr) ) {1.319 + check_mem_op( WRITE_LONG, addr, val );1.320 + } else {1.321 + real_region(addr)->write_long(addr, val);1.322 + }1.323 + }1.324 +}1.326 -struct mem_region_fn check_fns = {1.327 - (mem_read_fn_t)check_read_long, (mem_write_fn_t)check_write_long,1.328 - (mem_read_fn_t)check_read_word, (mem_write_fn_t)check_write_word,1.329 - (mem_read_fn_t)check_read_byte, (mem_write_fn_t)check_write_byte,1.330 - NULL, NULL, (mem_prefetch_fn_t)check_prefetch, (mem_read_fn_t)check_read_byte_for_write };1.331 +static FASTCALL void shadow_write_word( sh4addr_t addr, uint32_t val )1.332 +{1.333 + if( shadow_address_mode == SHADOW_LOG ) {1.334 + real_region(addr)->write_word(addr, val);1.335 + if( !IS_STORE_QUEUE(addr) )1.336 + log_mem_op( WRITE_WORD, addr, val );1.337 + } else {1.338 + if( !IS_STORE_QUEUE(addr) ) {1.339 + check_mem_op( WRITE_WORD, addr, val );1.340 + } else {1.341 + real_region(addr)->write_word(addr, val);1.342 + }1.343 + }1.344 +}1.346 +static FASTCALL void shadow_write_byte( sh4addr_t addr, uint32_t val )1.347 +{1.348 + if( shadow_address_mode == SHADOW_LOG ) {1.349 + real_region(addr)->write_byte(addr, val);1.350 + if( !IS_STORE_QUEUE(addr) )1.351 + log_mem_op( WRITE_BYTE, addr, val );1.352 + } else {1.353 + if( !IS_STORE_QUEUE(addr) ) {1.354 + check_mem_op( WRITE_BYTE, addr, val );1.355 + } else {1.356 + real_region(addr)->write_byte(addr, val);1.357 + }1.358 + }1.359 +}1.361 -1.362 +static FASTCALL void shadow_prefetch( sh4addr_t addr )1.363 +{1.364 + if( shadow_address_mode == SHADOW_LOG ) {1.365 + real_region(addr)->prefetch(addr);1.366 + log_mem_op( PREFETCH, addr, 0 );1.367 + } else {1.368 + check_mem_op( PREFETCH, addr, 0 );1.369 + }1.370 +}1.371 +struct mem_region_fn shadow_fns = {1.372 + shadow_read_long, shadow_write_long,1.373 + shadow_read_word, shadow_write_word,1.374 + shadow_read_byte, shadow_write_byte,1.375 + NULL, NULL, shadow_prefetch, shadow_read_byte_for_write };1.377 void sh4_shadow_block_begin()1.378 {1.379 @@ -412,7 +312,7 @@1.380 memcpy( &temp_sh4r, &sh4r, sizeof(struct sh4_registers) );1.381 memcpy( &sh4r, &shadow_sh4r, sizeof(struct sh4_registers) );1.383 - sh4_address_space = check_address_space;1.384 + shadow_address_mode = SHADOW_CHECK;1.385 mem_check_posn = 0;1.386 sh4r.new_pc = sh4r.pc + 2;1.387 while( sh4r.slice_cycle < temp_sh4r.slice_cycle ) {1.388 @@ -434,18 +334,17 @@1.389 }1.390 abort();1.391 }1.392 - sh4_address_space = real_address_space;1.393 + shadow_address_mode = SHADOW_LOG;1.394 }1.397 void sh4_shadow_init()1.398 {1.399 - real_address_space = sh4_address_space;1.400 - log_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 256 );1.401 - check_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 256 );1.402 - for( unsigned i=0; i < (256 * 4096); i++ ) {1.403 - log_address_space[i] = &log_fns;1.404 - check_address_space[i] = &check_fns;1.405 + shadow_address_mode = SHADOW_LOG;1.406 + p4_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 32 );1.407 + shadow_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 32 );1.408 + for( unsigned i=0; i < (32 * 4096); i++ ) {1.409 + shadow_address_space[i] = &shadow_fns;1.410 }1.412 mem_log_size = MEM_LOG_SIZE;1.413 @@ -454,6 +353,10 @@1.415 sh4_translate_set_callbacks( sh4_shadow_block_begin, sh4_shadow_block_end );1.416 sh4_translate_set_fastmem( FALSE );1.417 - sh4_translate_set_address_space( log_address_space, log_address_space );1.418 + memcpy( p4_address_space, sh4_address_space + (0xE0000000>>LXDREAM_PAGE_BITS),1.419 + sizeof(mem_region_fn_t) * (0x20000000>>LXDREAM_PAGE_BITS) );1.420 + memcpy( sh4_address_space + (0xE0000000>>LXDREAM_PAGE_BITS), shadow_address_space,1.421 + sizeof(mem_region_fn_t) * (0x20000000>>LXDREAM_PAGE_BITS) );1.422 + mmu_set_ext_address_space(shadow_address_space);1.423 }
.