diff options
Diffstat (limited to 'cpu-exec.c')
-rw-r--r-- | cpu-exec.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/cpu-exec.c b/cpu-exec.c index 8134c229c5..af5c58f8a7 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -20,6 +20,7 @@ #include "config.h" #include "exec.h" #include "disas.h" +#include <string.h> #if !defined(CONFIG_SOFTMMU) #undef EAX @@ -40,6 +41,9 @@ int tb_invalidated_flag; //#define DEBUG_EXEC //#define DEBUG_SIGNAL +/* translation settings */ +int translation_settings = 0; + #define SAVE_GLOBALS() #define RESTORE_GLOBALS() @@ -120,6 +124,56 @@ void cpu_resume_from_signal(CPUState *env1, void *puc) longjmp(env->jmp_env, 1); } +CPUTranslationSetting cpu_translation_settings[] = { + { CPU_SETTING_NO_CACHE, "no-cache", + "Do not use translation blocks cache (very slow!)" }, + { 0, NULL, NULL }, +}; + +void cpu_set_translation_settings(int translation_flags) +{ + translation_settings = translation_flags; +} + +static int cmp1(const char *s1, int n, const char *s2) +{ + if (strlen(s2) != n) + return 0; + return memcmp(s1, s2, n) == 0; +} + +/* takes a comma separated list of translation settings. Return 0 if error. */ +int cpu_str_to_translation_mask(const char *str) +{ + CPUTranslationSetting *setting; + int mask; + const char *p, *p1; + + p = str; + mask = 0; + for(;;) { + p1 = strchr(p, ','); + if (!p1) + p1 = p + strlen(p); + if(cmp1(p,p1-p,"all")) { + for(setting = cpu_translation_settings; setting->mask != 0; setting++) { + mask |= setting->mask; + } + } else { + for(setting = cpu_translation_settings; setting->mask != 0; setting++) { + if (cmp1(p, p1 - p, setting->name)) + goto found; + } + return 0; + } + found: + mask |= setting->mask; + if (*p1 != ',') + break; + p = p1 + 1; + } + return mask; +} static TranslationBlock *tb_find_slow(target_ulong pc, target_ulong cs_base, @@ -141,6 +195,9 @@ static TranslationBlock *tb_find_slow(target_ulong pc, phys_pc = get_phys_addr_code(env, pc); phys_page1 = phys_pc & TARGET_PAGE_MASK; phys_page2 = -1; + if (translation_settings & CPU_SETTING_NO_CACHE) + goto not_found; + h = tb_phys_hash_func(phys_pc); ptb1 = &tb_phys_hash[h]; for(;;) { @@ -264,7 +321,10 @@ static inline TranslationBlock *tb_find_fast(void) #else #error unsupported CPU #endif - tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; + if (translation_settings & CPU_SETTING_NO_CACHE) + tb = NULL; + else + tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base || tb->flags != flags, 0)) { tb = tb_find_slow(pc, cs_base, flags); |