Reimplement cache invalidation code
This commit is contained in:
		
							parent
							
								
									97166d5cbd
								
							
						
					
					
						commit
						5b59ef3acc
					
				
					 8 changed files with 58 additions and 180 deletions
				
			
		|  | @ -32,9 +32,7 @@ endif | |||
| 
 | ||||
| endif | ||||
| 
 | ||||
| # Special optimized routines | ||||
| ifeq ($(CPU_ARCH), arm) | ||||
| SOURCES_C   += $(CORE_DIR)/arm/warm.c | ||||
| SOURCES_ASM += $(CORE_DIR)/arm/video_blend.S | ||||
| endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -636,33 +636,8 @@ u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations) | |||
|     }                                                                         \ | ||||
|   }                                                                           \ | ||||
| 
 | ||||
| u8 *last_rom_translation_ptr = NULL; | ||||
| u8 *last_ram_translation_ptr = NULL; | ||||
| u8 *last_bios_translation_ptr = NULL; | ||||
| 
 | ||||
| #define translate_invalidate_dcache_one(which)                                \ | ||||
|   if (which##_translation_ptr > last_##which##_translation_ptr)               \ | ||||
|   {                                                                           \ | ||||
|     warm_cache_op_range(WOP_D_CLEAN, last_##which##_translation_ptr,          \ | ||||
|       which##_translation_ptr - last_##which##_translation_ptr);              \ | ||||
|     warm_cache_op_range(WOP_I_INVALIDATE, last_##which##_translation_ptr, 32);\ | ||||
|     last_##which##_translation_ptr = which##_translation_ptr;                 \ | ||||
|   } | ||||
| 
 | ||||
| #define translate_invalidate_dcache()                                         \ | ||||
| {                                                                             \ | ||||
|   translate_invalidate_dcache_one(rom)                                        \ | ||||
|   translate_invalidate_dcache_one(ram)                                        \ | ||||
|   translate_invalidate_dcache_one(bios)                                       \ | ||||
| } | ||||
| 
 | ||||
| #define invalidate_icache_region(addr, size)                                  \ | ||||
|   warm_cache_op_range(WOP_I_INVALIDATE, addr, size) | ||||
| 
 | ||||
| 
 | ||||
| #define block_prologue_size 0 | ||||
| 
 | ||||
| 
 | ||||
| // It should be okay to still generate result flags, spsr will overwrite them.
 | ||||
| // This is pretty infrequent (returning from interrupt handlers, et al) so
 | ||||
| // probably not worth optimizing for.
 | ||||
|  |  | |||
							
								
								
									
										67
									
								
								arm/warm.c
									
										
									
									
									
								
							
							
						
						
									
										67
									
								
								arm/warm.c
									
										
									
									
									
								
							|  | @ -1,67 +0,0 @@ | |||
| /*
 | ||||
|  * wARM - exporting ARM processor specific privileged services to userspace | ||||
|  * userspace part | ||||
|  * | ||||
|  * Copyright (c) Gražvydas "notaz" Ignotas, 2009 | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the organization nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
|  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
|  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
|  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
|  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/syscall.h> | ||||
| #include <errno.h> | ||||
| 
 | ||||
| #include "warm.h" | ||||
| 
 | ||||
| static void sys_cacheflush(void *start, void *end) | ||||
| { | ||||
| #ifdef __ARM_EABI__ | ||||
| 	/* EABI version */ | ||||
| 	int num = __ARM_NR_cacheflush; | ||||
| 	__asm__("mov  r0, %0 ;" | ||||
| 		"mov  r1, %1 ;" | ||||
| 		"mov  r2, #0 ;" | ||||
| 		"mov  r7, %2 ;" | ||||
| 		"swi  0" : : "r" (start), "r" (end), "r" (num) | ||||
| 			: "r0", "r1", "r2", "r3", "r7"); | ||||
| #else | ||||
| 	/* OABI */ | ||||
| 	__asm__("mov  r0, %0 ;" | ||||
| 		"mov  r1, %1 ;" | ||||
| 		"mov  r2, #0 ;" | ||||
| 		"swi  %2" : : "r" (start), "r" (end), "i" __ARM_NR_cacheflush | ||||
| 			: "r0", "r1", "r2", "r3"); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| int warm_cache_op_range(int op, void *addr, unsigned long size) | ||||
| { | ||||
|    sys_cacheflush(addr, (char *)addr + size); | ||||
|    return -1; | ||||
| } | ||||
							
								
								
									
										53
									
								
								arm/warm.h
									
										
									
									
									
								
							
							
						
						
									
										53
									
								
								arm/warm.h
									
										
									
									
									
								
							|  | @ -1,53 +0,0 @@ | |||
| /*
 | ||||
|  * wARM - exporting ARM processor specific privileged services to userspace | ||||
|  * library functions | ||||
|  * | ||||
|  * Copyright (c) Gražvydas "notaz" Ignotas, 2009 | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the organization nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
|  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
|  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
|  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
|  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| #ifndef __WARM_H__ | ||||
| #define __WARM_H__ 1 | ||||
| 
 | ||||
| /* cache operations (warm_cache_op_*):
 | ||||
|  * o clean - write dirty data to memory, but also leave in cache. | ||||
|  * o invalidate - throw away everything in cache, losing dirty data. | ||||
|  * | ||||
|  * Write buffer is always drained, no ops will only drain WB | ||||
|  */ | ||||
| #define WOP_D_CLEAN		(1 << 0) | ||||
| #define WOP_D_INVALIDATE	(1 << 1) | ||||
| #define WOP_I_INVALIDATE	(1 << 2) | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" | ||||
| { | ||||
| #endif | ||||
| 
 | ||||
| int warm_cache_op_range(int ops, void *virt_addr, unsigned long size); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif /* __WARM_H__ */ | ||||
							
								
								
									
										4
									
								
								common.h
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								common.h
									
										
									
									
									
								
							|  | @ -210,8 +210,4 @@ typedef u32 fixed8_24; | |||
| #include "main.h" | ||||
| #include "cheats.h" | ||||
| 
 | ||||
| #ifdef ARM_ARCH | ||||
|   #include "arm/warm.h" | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -23,6 +23,10 @@ | |||
| 
 | ||||
| #include "common.h" | ||||
| 
 | ||||
| u8 *last_rom_translation_ptr = NULL; | ||||
| u8 *last_ram_translation_ptr = NULL; | ||||
| u8 *last_bios_translation_ptr = NULL; | ||||
| 
 | ||||
| #if defined(HAVE_MMAP) | ||||
| u8* rom_translation_cache; | ||||
| u8* ram_translation_cache; | ||||
|  | @ -218,6 +222,51 @@ extern u8 bit_count[256]; | |||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /* Cache invalidation */ | ||||
| 
 | ||||
| #if defined(PSP_BUILD) | ||||
| #define translate_invalidate_dcache() sceKernelDcacheWritebackAll() | ||||
| 
 | ||||
| #elif defined(ARM_ARCH) | ||||
| static int sys_cacheflush(void *addr, unsigned long size) | ||||
| { | ||||
|    void *start = (void*)addr; | ||||
|    void *end   = (void*)(char *)addr + size; | ||||
| 
 | ||||
| 	register const unsigned char *r0 asm("r0") = start; | ||||
| 	register const unsigned char *r1 asm("r1") = end; | ||||
| 	register const int r2 asm("r2") = 0; | ||||
| 	register const int r7 asm("r7") = 0xf0002; | ||||
| 	asm volatile ("svc 0x0" :: "r" (r0), "r" (r1), "r" (r2), "r" (r7)); | ||||
|    return -1; | ||||
| } | ||||
| 
 | ||||
| #define translate_invalidate_dcache_one(which)                                \ | ||||
|   if (which##_translation_ptr > last_##which##_translation_ptr)               \ | ||||
|   {                                                                           \ | ||||
|     sys_cacheflush(last_##which##_translation_ptr,          \ | ||||
|       which##_translation_ptr - last_##which##_translation_ptr);              \ | ||||
|     sys_cacheflush(last_##which##_translation_ptr, 32);\ | ||||
|     last_##which##_translation_ptr = which##_translation_ptr;                 \ | ||||
|   } | ||||
| 
 | ||||
| #define translate_invalidate_dcache()                                         \ | ||||
| {                                                                             \ | ||||
|   translate_invalidate_dcache_one(rom)                                        \ | ||||
|   translate_invalidate_dcache_one(ram)                                        \ | ||||
|   translate_invalidate_dcache_one(bios)                                       \ | ||||
| } | ||||
| #define invalidate_icache_region(addr, size) (void)0 | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| #define translate_invalidate_dcache() (void)0 | ||||
| #define invalidate_icache_region(addr, size) (void)0 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /* End of Cache invalidation */ | ||||
| 
 | ||||
| 
 | ||||
| #define check_pc_region(pc)                                                   \ | ||||
|   new_pc_region = (pc >> 15);                                                 \ | ||||
|  | @ -3632,13 +3681,8 @@ void flush_translation_cache_ram(void) | |||
|    flush_ram_count, reg[REG_PC], iwram_code_min, iwram_code_max, | ||||
|    ewram_code_min, ewram_code_max); */ | ||||
| 
 | ||||
| #if defined(ARM_ARCH) || defined(MIPS_ARCH) | ||||
|   invalidate_icache_region(ram_translation_cache, | ||||
|    (ram_translation_ptr - ram_translation_cache) + 0x100); | ||||
| #endif | ||||
| #ifdef ARM_ARCH | ||||
|   invalidate_icache_region(ram_translation_cache, (ram_translation_ptr - ram_translation_cache) + 0x100); | ||||
|   last_ram_translation_ptr = ram_translation_cache; | ||||
| #endif | ||||
|   ram_translation_ptr = ram_translation_cache; | ||||
|   ram_block_tag_top = 0x0101; | ||||
|   if(iwram_code_min != 0xFFFFFFFF) | ||||
|  | @ -3673,9 +3717,7 @@ void flush_translation_cache_ram(void) | |||
|     else | ||||
|     { | ||||
|       for(i = ewram_code_min_page + 1; i < ewram_code_max_page; i++) | ||||
|       { | ||||
|         memset(ewram + (i * 0x10000), 0, 0x8000); | ||||
|       } | ||||
| 
 | ||||
|       memset(ewram, 0, ewram_code_max_offset); | ||||
|     } | ||||
|  | @ -3689,30 +3731,23 @@ void flush_translation_cache_ram(void) | |||
| 
 | ||||
| void flush_translation_cache_rom(void) | ||||
| { | ||||
| #if defined(ARM_ARCH) || defined(MIPS_ARCH) | ||||
|   invalidate_icache_region(rom_translation_cache, | ||||
|    rom_translation_ptr - rom_translation_cache + 0x100); | ||||
| #endif | ||||
| #ifdef ARM_ARCH | ||||
|   last_rom_translation_ptr = rom_translation_cache; | ||||
| #endif | ||||
|   invalidate_icache_region(rom_translation_cache, rom_translation_ptr - rom_translation_cache + 0x100); | ||||
| 
 | ||||
|   last_rom_translation_ptr = rom_translation_cache; | ||||
|   rom_translation_ptr      = rom_translation_cache; | ||||
| 
 | ||||
|   rom_translation_ptr = rom_translation_cache; | ||||
|   memset(rom_branch_hash, 0, sizeof(rom_branch_hash)); | ||||
| } | ||||
| 
 | ||||
| void flush_translation_cache_bios(void) | ||||
| { | ||||
| #if defined(ARM_ARCH) || defined(MIPS_ARCH) | ||||
|   invalidate_icache_region(bios_translation_cache, | ||||
|    bios_translation_ptr - bios_translation_cache + 0x100); | ||||
| #endif | ||||
| #ifdef ARM_ARCH | ||||
|   last_bios_translation_ptr = bios_translation_cache; | ||||
| #endif | ||||
|   invalidate_icache_region(bios_translation_cache, bios_translation_ptr - bios_translation_cache + 0x100); | ||||
| 
 | ||||
|   bios_block_tag_top = 0x0101; | ||||
| 
 | ||||
|   last_bios_translation_ptr = bios_translation_cache; | ||||
|   bios_translation_ptr = bios_translation_cache; | ||||
| 
 | ||||
|   memset(bios_rom + 0x4000, 0, 0x4000); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -641,9 +641,6 @@ u32 arm_to_mips_reg[] = | |||
|   mips_emit_nop();                                                            \ | ||||
|   generate_load_imm(reg_pc, stored_pc)                                        \ | ||||
| 
 | ||||
| #define translate_invalidate_dcache()                                         \ | ||||
|   sceKernelDcacheWritebackAll()                                               \ | ||||
| 
 | ||||
| #define block_prologue_size 8 | ||||
| 
 | ||||
| #define check_generate_n_flag                                                 \ | ||||
|  |  | |||
|  | @ -492,9 +492,6 @@ typedef enum | |||
| 
 | ||||
| #define generate_block_extra_vars_thumb()                                     \ | ||||
| 
 | ||||
| 
 | ||||
| #define translate_invalidate_dcache()                                         \ | ||||
| 
 | ||||
| #define block_prologue_size 0 | ||||
| 
 | ||||
| #define calculate_z_flag(dest)                                                \ | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue