1.1 --- a/src/sh4/shadow.c Fri Dec 23 08:20:17 2011 +1000
1.2 +++ b/src/sh4/shadow.c Sat Mar 03 15:52:59 2012 +1000
1.9 #include "sh4/sh4core.h"
1.10 #include "sh4/sh4trans.h"
1.11 #include "sh4/mmu.h"
1.13 -#ifdef HAVE_FRAME_ADDRESS
1.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.17 -#define INIT_EXCEPTIONS(label)
1.27 - sh4addr_t exception_pc;
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.41 +static shadow_mode_t shadow_address_mode = SHADOW_LOG;
1.43 #define MEM_LOG_SIZE 4096
1.44 static struct mem_log_entry *mem_log;
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.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.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.59 - mem_log[mem_log_posn].exception_pc = sh4r.pc;
1.61 - mem_log[mem_log_posn].exception_pc = -1;
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.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.80 - if( mem_log[mem_check_posn].exception_pc != -1 ) {
1.81 - sh4_reraise_exception(mem_log[mem_check_posn].exception_pc);
1.87 return mem_log[mem_check_posn++].value;
1.90 @@ -201,202 +186,117 @@
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.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.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.107 + return ext_address_space[VMA_TO_EXT_ADDR(addr)>>12];
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.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.118 - log_mem_op( READ_WORD, addr, rv, 1 );
1.119 - SH4_EXCEPTION_EXIT();
1.122 -static FASTCALL int32_t log_read_byte( sh4addr_t addr, void *exc )
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.129 - log_mem_op( READ_BYTE, addr, rv, 1 );
1.130 - SH4_EXCEPTION_EXIT();
1.133 -static FASTCALL int32_t log_read_byte_for_write( sh4addr_t addr, void *exc )
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.140 - log_mem_op( READ_BYTE_FOR_WRITE, addr, rv, 1 );
1.141 - SH4_EXCEPTION_EXIT();
1.144 -static FASTCALL void log_write_long( sh4addr_t addr, uint32_t val, void *exc )
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.152 - if( !IS_STORE_QUEUE(addr) )
1.153 - log_mem_op( WRITE_LONG, addr, val, 1 );
1.154 - SH4_EXCEPTION_EXIT();
1.157 -static FASTCALL void log_write_word( sh4addr_t addr, uint32_t val, void *exc )
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.165 - if( !IS_STORE_QUEUE(addr) )
1.166 - log_mem_op( WRITE_WORD, addr, val, 1 );
1.167 - SH4_EXCEPTION_EXIT();
1.170 -static FASTCALL void log_write_byte( sh4addr_t addr, uint32_t val, void *exc )
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.178 - if( !IS_STORE_QUEUE(addr) )
1.179 - log_mem_op( WRITE_BYTE, addr, val, 1 );
1.180 - SH4_EXCEPTION_EXIT();
1.183 -static FASTCALL void log_prefetch( sh4addr_t addr, void *exc )
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.190 - log_mem_op( PREFETCH, addr, 0, 1 );
1.191 - SH4_EXCEPTION_EXIT();
1.194 -static FASTCALL int32_t check_read_long( sh4addr_t addr, void *exc )
1.197 - int32_t value = check_mem_op( READ_LONG, addr, 0, &except );
1.199 - SH4_EXCEPTION_EXIT();
1.204 -static FASTCALL int32_t check_read_word( sh4addr_t addr, void *exc )
1.207 - int32_t value = check_mem_op( READ_WORD, addr, 0, &except );
1.209 - SH4_EXCEPTION_EXIT();
1.214 -static FASTCALL int32_t check_read_byte( sh4addr_t addr, void *exc )
1.217 - int32_t value = check_mem_op( READ_BYTE, addr, 0, &except );
1.219 - SH4_EXCEPTION_EXIT();
1.224 -static FASTCALL int32_t check_read_byte_for_write( sh4addr_t addr, void *exc )
1.227 - int32_t value = check_mem_op( READ_BYTE_FOR_WRITE, addr, 0, &except );
1.229 - SH4_EXCEPTION_EXIT();
1.234 -static FASTCALL void check_write_long( sh4addr_t addr, uint32_t value, void *exc )
1.236 - if( !IS_STORE_QUEUE(addr) ) {
1.238 - check_mem_op( WRITE_LONG, addr, value, &except );
1.240 - SH4_EXCEPTION_EXIT();
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.247 - real_address_space[addr>>12]->write_long(addr, value);
1.248 + return check_mem_op( READ_LONG, addr, 0 );
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.255 - if( !IS_STORE_QUEUE(addr) ) {
1.257 - check_mem_op( WRITE_WORD, addr, value, &except );
1.259 - SH4_EXCEPTION_EXIT();
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.266 - real_address_space[addr>>12]->write_word(addr, value);
1.267 + return check_mem_op( READ_WORD, addr, 0 );
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.274 - if( !IS_STORE_QUEUE(addr) ){
1.276 - check_mem_op( WRITE_BYTE, addr, value, &except );
1.278 - SH4_EXCEPTION_EXIT();
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.285 - real_address_space[addr>>12]->write_byte(addr, value);
1.286 + return check_mem_op( READ_BYTE, addr, 0 );
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.294 - check_mem_op( PREFETCH, addr, 0, &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.302 + return check_mem_op( READ_BYTE_FOR_WRITE, addr, 0 );
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.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.318 + if( !IS_STORE_QUEUE(addr) ) {
1.319 + check_mem_op( WRITE_LONG, addr, val );
1.321 + real_region(addr)->write_long(addr, val);
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.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.338 + if( !IS_STORE_QUEUE(addr) ) {
1.339 + check_mem_op( WRITE_WORD, addr, val );
1.341 + real_region(addr)->write_word(addr, val);
1.346 +static FASTCALL void shadow_write_byte( sh4addr_t addr, uint32_t val )
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.353 + if( !IS_STORE_QUEUE(addr) ) {
1.354 + check_mem_op( WRITE_BYTE, addr, val );
1.356 + real_region(addr)->write_byte(addr, val);
1.362 +static FASTCALL void shadow_prefetch( sh4addr_t addr )
1.364 + if( shadow_address_mode == SHADOW_LOG ) {
1.365 + real_region(addr)->prefetch(addr);
1.366 + log_mem_op( PREFETCH, addr, 0 );
1.368 + check_mem_op( PREFETCH, addr, 0 );
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.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.392 - sh4_address_space = real_address_space;
1.393 + shadow_address_mode = SHADOW_LOG;
1.397 void sh4_shadow_init()
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.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);