diff options
author | notaz | 2011-02-16 21:31:19 +0200 |
---|---|---|
committer | notaz | 2011-02-17 00:48:38 +0200 |
commit | dd3a91a17c7b45c56cde69ff39ea35185f476898 (patch) | |
tree | 3806aa27d160d766342b53bb6c0a8d453e4ac6b2 | |
parent | 535d208a8473e9255919b1e5bfe0b5aa88f6992a (diff) | |
download | pcsx_rearmed-dd3a91a17c7b45c56cde69ff39ea35185f476898.tar.gz pcsx_rearmed-dd3a91a17c7b45c56cde69ff39ea35185f476898.tar.bz2 pcsx_rearmed-dd3a91a17c7b45c56cde69ff39ea35185f476898.zip |
drc: merge Ari64's patch: 07_clear_cache
-rw-r--r-- | libpcsxcore/new_dynarec/assem_arm.c | 34 | ||||
-rw-r--r-- | libpcsxcore/new_dynarec/new_dynarec.c | 39 |
2 files changed, 49 insertions, 24 deletions
diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index ed89bb0..0153bfc 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -68,6 +68,8 @@ const u_int jump_vaddr_reg[16] = { #include "fpu.h" +unsigned int needs_clear_cache[1<<(TARGET_SIZE_2-17)]; + /* Linker */ void set_jump_target(int addr,u_int target) @@ -4784,6 +4786,38 @@ void wb_invalidate_arm(signed char pre[],signed char entry[],uint64_t dirty,uint #define wb_invalidate wb_invalidate_arm */ +// Clearing the cache is rather slow on ARM Linux, so mark the areas +// that need to be cleared, and then only clear these areas once. +void do_clear_cache() +{ + int i,j; + for (i=0;i<(1<<(TARGET_SIZE_2-17));i++) + { + u_int bitmap=needs_clear_cache[i]; + if(bitmap) { + u_int start,end; + for(j=0;j<32;j++) + { + if(bitmap&(1<<j)) { + start=BASE_ADDR+i*131072+j*4096; + end=start+4095; + j++; + while(j<32) { + if(bitmap&(1<<j)) { + end+=4096; + j++; + }else{ + __clear_cache((void *)start,(void *)end); + break; + } + } + } + } + needs_clear_cache[i]=0; + } + } +} + // CPU-architecture-specific initialization void arch_init() { #ifndef DISABLE_COP1 diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 28a0245..fb6ace4 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -1086,7 +1086,6 @@ void ll_clear(struct ll_entry **head) // Dereference the pointers and remove if it matches void ll_kill_pointers(struct ll_entry *head,int addr,int shift) { - u_int old_host_addr=0; while(head) { int ptr=get_pointer(head->addr); inv_debug("EXP: Lookup pointer to %x at %x (%x)\n",(int)ptr,(int)head->addr,head->vaddr); @@ -1095,20 +1094,12 @@ void ll_kill_pointers(struct ll_entry *head,int addr,int shift) { inv_debug("EXP: Kill pointer at %x (%x)\n",(int)head->addr,head->vaddr); u_int host_addr=(u_int)kill_pointer(head->addr); - - if((host_addr>>12)!=(old_host_addr>>12)) { - #ifdef __arm__ - __clear_cache((void *)(old_host_addr&~0xfff),(void *)(old_host_addr|0xfff)); - #endif - old_host_addr=host_addr; - } + #ifdef __arm__ + needs_clear_cache[(host_addr-(u_int)BASE_ADDR)>>17]|=1<<(((host_addr-(u_int)BASE_ADDR)>>12)&31); + #endif } head=head->next; } - #ifdef __arm__ - if (old_host_addr) - __clear_cache((void *)(old_host_addr&~0xfff),(void *)(old_host_addr|0xfff)); - #endif } // This is called when we write to a compiled block (see do_invstub) @@ -1116,7 +1107,6 @@ void invalidate_page(u_int page) { struct ll_entry *head; struct ll_entry *next; - u_int old_host_addr=0; head=jump_in[page]; jump_in[page]=0; while(head!=NULL) { @@ -1131,21 +1121,13 @@ void invalidate_page(u_int page) while(head!=NULL) { inv_debug("INVALIDATE: kill pointer to %x (%x)\n",head->vaddr,(int)head->addr); u_int host_addr=(u_int)kill_pointer(head->addr); - - if((host_addr>>12)!=(old_host_addr>>12)) { - #ifdef __arm__ - __clear_cache((void *)(old_host_addr&~0xfff),(void *)(old_host_addr|0xfff)); - #endif - old_host_addr=host_addr; - } + #ifdef __arm__ + needs_clear_cache[(host_addr-(u_int)BASE_ADDR)>>17]|=1<<(((host_addr-(u_int)BASE_ADDR)>>12)&31); + #endif next=head->next; free(head); head=next; } - #ifdef __arm__ - if (old_host_addr) - __clear_cache((void *)(old_host_addr&~0xfff),(void *)(old_host_addr|0xfff)); - #endif } void invalidate_block(u_int block) { @@ -1192,6 +1174,9 @@ void invalidate_block(u_int block) for(first=page+1;first<last;first++) { invalidate_page(first); } + #ifdef __arm__ + do_clear_cache(); + #endif // Don't trap writes invalid_code[block]=1; @@ -1216,6 +1201,8 @@ void invalidate_addr(u_int addr) { invalidate_block(addr>>12); } +// This is called when loading a save state. +// Anything could have changed, so invalidate everything. void invalidate_all_pages() { u_int page,n; @@ -11041,6 +11028,10 @@ int new_recompile_block(int addr) break; case 3: // Clear jump_out + #ifdef __arm__ + if((expirep&2047)==0) + do_clear_cache(); + #endif ll_remove_matching_addrs(jump_out+(expirep&2047),base,shift); ll_remove_matching_addrs(jump_out+2048+(expirep&2047),base,shift); break; |