Search
lxdream.org :: lxdream/src/sh4/xltcache.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/xltcache.c
changeset 571:9bc09948d0f2
prev569:a1c49e1e8776
next580:508dc852a8eb
author nkeynes
date Mon Jan 14 09:08:58 2008 +0000 (16 years ago)
branchlxdream-mmu
permissions -rw-r--r--
last change Fix TRAPA in emulator core
file annotate diff log raw
1.1 --- a/src/sh4/xltcache.c Fri Jan 04 11:54:17 2008 +0000
1.2 +++ b/src/sh4/xltcache.c Mon Jan 14 09:08:58 2008 +0000
1.3 @@ -208,27 +208,33 @@
1.4 return result;
1.5 }
1.6
1.7 -void *xlat_get_code_by_vma( sh4vma_t vma )
1.8 +xlat_recovery_record_t xlat_get_recovery( void *code, void *native_pc, gboolean recover_after )
1.9 {
1.10 - void *result = NULL;
1.11 -
1.12 -
1.13 - if( !IS_IN_ICACHE(vma) ) {
1.14 - if( !mmu_update_icache(sh4r.pc) ) {
1.15 - // fault - off to the fault handler
1.16 - if( !mmu_update_icache(sh4r.pc) ) {
1.17 - // double fault - halt
1.18 - dreamcast_stop();
1.19 - ERROR( "Double fault - halting" );
1.20 + if( code != NULL ) {
1.21 + xlat_cache_block_t block = BLOCK_FOR_CODE(code);
1.22 + uint32_t count = block->recover_table_size;
1.23 + xlat_recovery_record_t records = block->recover_table;
1.24 + uint32_t posn;
1.25 + if( recover_after ) {
1.26 + if( records[count-1].xlat_pc <= (uintptr_t)native_pc ) {
1.27 return NULL;
1.28 }
1.29 + for( posn=count-1; posn > 0; posn-- ) {
1.30 + if( records[posn-1].xlat_pc <= (uintptr_t)native_pc ) {
1.31 + return &records[posn];
1.32 + }
1.33 + }
1.34 + return &records[0]; // shouldn't happen
1.35 + } else {
1.36 + for( posn = 1; posn < count; posn++ ) {
1.37 + if( records[posn].xlat_pc > (uintptr_t)native_pc ) {
1.38 + return &records[posn-1];
1.39 + }
1.40 + }
1.41 + return &records[count-1];
1.42 }
1.43 }
1.44 - if( sh4_icache.page_vma != -1 ) {
1.45 - result = xlat_get_code( GET_ICACHE_PHYS(vma) );
1.46 - }
1.47 -
1.48 - return result;
1.49 + return NULL;
1.50 }
1.51
1.52 void **xlat_get_lut_entry( sh4addr_t address )
1.53 @@ -254,6 +260,16 @@
1.54 return xlt->size;
1.55 }
1.56
1.57 +uint32_t xlat_get_code_size( void *block )
1.58 +{
1.59 + xlat_cache_block_t xlt = (xlat_cache_block_t)(((char *)block)-sizeof(struct xlat_cache_block));
1.60 + if( xlt->recover_table == NULL ) {
1.61 + return xlt->size;
1.62 + } else {
1.63 + return ((uint8_t *)xlt->recover_table) - ((uint8_t *)block);
1.64 + }
1.65 +}
1.66 +
1.67 /**
1.68 * Cut the specified block so that it has the given size, with the remaining data
1.69 * forming a new free block. If the free block would be less than the minimum size,
.