aboutsummaryrefslogtreecommitdiff
path: root/cpu-exec.c
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2008-01-23 19:01:12 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2008-01-23 19:01:12 +0000
commit40a2e657a5e055f3962639dd9bdec788aaf415c5 (patch)
treef77b32f9c468e652b771a3358be3c8c807310121 /cpu-exec.c
parentc304f7e23db91e7add1e72d8e11b839937ac39a0 (diff)
Add option to disable TB cache, by Herve Poussineau.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3930 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'cpu-exec.c')
-rw-r--r--cpu-exec.c62
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);