Commit 40a2e657a5e055f3962639dd9bdec788aaf415c5
1 parent
c304f7e2
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
Showing
4 changed files
with
110 additions
and
2 deletions
cpu-all.h
@@ -787,6 +787,20 @@ void cpu_set_log(int log_flags); | @@ -787,6 +787,20 @@ void cpu_set_log(int log_flags); | ||
787 | void cpu_set_log_filename(const char *filename); | 787 | void cpu_set_log_filename(const char *filename); |
788 | int cpu_str_to_log_mask(const char *str); | 788 | int cpu_str_to_log_mask(const char *str); |
789 | 789 | ||
790 | +#define CPU_SETTING_NO_CACHE (1 << 0) | ||
791 | + | ||
792 | +/* define translation settings */ | ||
793 | +typedef struct CPUTranslationSetting { | ||
794 | + int mask; | ||
795 | + const char *name; | ||
796 | + const char *help; | ||
797 | +} CPUTranslationSetting; | ||
798 | + | ||
799 | +extern CPUTranslationSetting cpu_translation_settings[]; | ||
800 | + | ||
801 | +void cpu_set_translation_settings(int translation_flags); | ||
802 | +int cpu_str_to_translation_mask(const char *str); | ||
803 | + | ||
790 | /* IO ports API */ | 804 | /* IO ports API */ |
791 | 805 | ||
792 | /* NOTE: as these functions may be even used when there is an isa | 806 | /* NOTE: as these functions may be even used when there is an isa |
cpu-exec.c
@@ -20,6 +20,7 @@ | @@ -20,6 +20,7 @@ | ||
20 | #include "config.h" | 20 | #include "config.h" |
21 | #include "exec.h" | 21 | #include "exec.h" |
22 | #include "disas.h" | 22 | #include "disas.h" |
23 | +#include <string.h> | ||
23 | 24 | ||
24 | #if !defined(CONFIG_SOFTMMU) | 25 | #if !defined(CONFIG_SOFTMMU) |
25 | #undef EAX | 26 | #undef EAX |
@@ -40,6 +41,9 @@ int tb_invalidated_flag; | @@ -40,6 +41,9 @@ int tb_invalidated_flag; | ||
40 | //#define DEBUG_EXEC | 41 | //#define DEBUG_EXEC |
41 | //#define DEBUG_SIGNAL | 42 | //#define DEBUG_SIGNAL |
42 | 43 | ||
44 | +/* translation settings */ | ||
45 | +int translation_settings = 0; | ||
46 | + | ||
43 | #define SAVE_GLOBALS() | 47 | #define SAVE_GLOBALS() |
44 | #define RESTORE_GLOBALS() | 48 | #define RESTORE_GLOBALS() |
45 | 49 | ||
@@ -120,6 +124,56 @@ void cpu_resume_from_signal(CPUState *env1, void *puc) | @@ -120,6 +124,56 @@ void cpu_resume_from_signal(CPUState *env1, void *puc) | ||
120 | longjmp(env->jmp_env, 1); | 124 | longjmp(env->jmp_env, 1); |
121 | } | 125 | } |
122 | 126 | ||
127 | +CPUTranslationSetting cpu_translation_settings[] = { | ||
128 | + { CPU_SETTING_NO_CACHE, "no-cache", | ||
129 | + "Do not use translation blocks cache (very slow!)" }, | ||
130 | + { 0, NULL, NULL }, | ||
131 | +}; | ||
132 | + | ||
133 | +void cpu_set_translation_settings(int translation_flags) | ||
134 | +{ | ||
135 | + translation_settings = translation_flags; | ||
136 | +} | ||
137 | + | ||
138 | +static int cmp1(const char *s1, int n, const char *s2) | ||
139 | +{ | ||
140 | + if (strlen(s2) != n) | ||
141 | + return 0; | ||
142 | + return memcmp(s1, s2, n) == 0; | ||
143 | +} | ||
144 | + | ||
145 | +/* takes a comma separated list of translation settings. Return 0 if error. */ | ||
146 | +int cpu_str_to_translation_mask(const char *str) | ||
147 | +{ | ||
148 | + CPUTranslationSetting *setting; | ||
149 | + int mask; | ||
150 | + const char *p, *p1; | ||
151 | + | ||
152 | + p = str; | ||
153 | + mask = 0; | ||
154 | + for(;;) { | ||
155 | + p1 = strchr(p, ','); | ||
156 | + if (!p1) | ||
157 | + p1 = p + strlen(p); | ||
158 | + if(cmp1(p,p1-p,"all")) { | ||
159 | + for(setting = cpu_translation_settings; setting->mask != 0; setting++) { | ||
160 | + mask |= setting->mask; | ||
161 | + } | ||
162 | + } else { | ||
163 | + for(setting = cpu_translation_settings; setting->mask != 0; setting++) { | ||
164 | + if (cmp1(p, p1 - p, setting->name)) | ||
165 | + goto found; | ||
166 | + } | ||
167 | + return 0; | ||
168 | + } | ||
169 | + found: | ||
170 | + mask |= setting->mask; | ||
171 | + if (*p1 != ',') | ||
172 | + break; | ||
173 | + p = p1 + 1; | ||
174 | + } | ||
175 | + return mask; | ||
176 | +} | ||
123 | 177 | ||
124 | static TranslationBlock *tb_find_slow(target_ulong pc, | 178 | static TranslationBlock *tb_find_slow(target_ulong pc, |
125 | target_ulong cs_base, | 179 | target_ulong cs_base, |
@@ -141,6 +195,9 @@ static TranslationBlock *tb_find_slow(target_ulong pc, | @@ -141,6 +195,9 @@ static TranslationBlock *tb_find_slow(target_ulong pc, | ||
141 | phys_pc = get_phys_addr_code(env, pc); | 195 | phys_pc = get_phys_addr_code(env, pc); |
142 | phys_page1 = phys_pc & TARGET_PAGE_MASK; | 196 | phys_page1 = phys_pc & TARGET_PAGE_MASK; |
143 | phys_page2 = -1; | 197 | phys_page2 = -1; |
198 | + if (translation_settings & CPU_SETTING_NO_CACHE) | ||
199 | + goto not_found; | ||
200 | + | ||
144 | h = tb_phys_hash_func(phys_pc); | 201 | h = tb_phys_hash_func(phys_pc); |
145 | ptb1 = &tb_phys_hash[h]; | 202 | ptb1 = &tb_phys_hash[h]; |
146 | for(;;) { | 203 | for(;;) { |
@@ -264,7 +321,10 @@ static inline TranslationBlock *tb_find_fast(void) | @@ -264,7 +321,10 @@ static inline TranslationBlock *tb_find_fast(void) | ||
264 | #else | 321 | #else |
265 | #error unsupported CPU | 322 | #error unsupported CPU |
266 | #endif | 323 | #endif |
267 | - tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; | 324 | + if (translation_settings & CPU_SETTING_NO_CACHE) |
325 | + tb = NULL; | ||
326 | + else | ||
327 | + tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; | ||
268 | if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base || | 328 | if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base || |
269 | tb->flags != flags, 0)) { | 329 | tb->flags != flags, 0)) { |
270 | tb = tb_find_slow(pc, cs_base, flags); | 330 | tb = tb_find_slow(pc, cs_base, flags); |
qemu-doc.texi
@@ -363,6 +363,17 @@ Set the initial date of the real time clock. Valid format for | @@ -363,6 +363,17 @@ Set the initial date of the real time clock. Valid format for | ||
363 | @var{date} are: @code{now} or @code{2006-06-17T16:01:21} or | 363 | @var{date} are: @code{now} or @code{2006-06-17T16:01:21} or |
364 | @code{2006-06-17}. The default value is @code{now}. | 364 | @code{2006-06-17}. The default value is @code{now}. |
365 | 365 | ||
366 | +@item -translation @var{setting1[,...]} | ||
367 | +Select dynamic translation options @var{setting}, @code{-translation ?} | ||
368 | +shows a list of settings. Valid settings are: | ||
369 | + | ||
370 | +@table @code | ||
371 | +@item @var{no-cache} | ||
372 | +This option disables caching of translated code. Is useful for low-level | ||
373 | +debugging of the emulated environment. This option incurs a massive | ||
374 | +slow-down in emulation speed. | ||
375 | +@end table | ||
376 | + | ||
366 | @item -pidfile @var{file} | 377 | @item -pidfile @var{file} |
367 | Store the QEMU process PID in @var{file}. It is useful if you launch QEMU | 378 | Store the QEMU process PID in @var{file}. It is useful if you launch QEMU |
368 | from a script. | 379 | from a script. |
vl.c
@@ -240,6 +240,8 @@ static CPUState *cur_cpu; | @@ -240,6 +240,8 @@ static CPUState *cur_cpu; | ||
240 | static CPUState *next_cpu; | 240 | static CPUState *next_cpu; |
241 | static int event_pending = 1; | 241 | static int event_pending = 1; |
242 | 242 | ||
243 | +extern char *logfilename; | ||
244 | + | ||
243 | #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) | 245 | #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) |
244 | 246 | ||
245 | /***********************************************************/ | 247 | /***********************************************************/ |
@@ -7661,6 +7663,9 @@ static void help(int exitcode) | @@ -7661,6 +7663,9 @@ static void help(int exitcode) | ||
7661 | #endif | 7663 | #endif |
7662 | "-clock force the use of the given methods for timer alarm.\n" | 7664 | "-clock force the use of the given methods for timer alarm.\n" |
7663 | " To see what timers are available use -clock help\n" | 7665 | " To see what timers are available use -clock help\n" |
7666 | + "-startdate select initial date of the Qemu clock\n" | ||
7667 | + "-translation setting1,... configures code translation\n" | ||
7668 | + " (use -translation ? for a list of settings)\n" | ||
7664 | "\n" | 7669 | "\n" |
7665 | "During emulation, the following keys are useful:\n" | 7670 | "During emulation, the following keys are useful:\n" |
7666 | "ctrl-alt-f toggle full screen\n" | 7671 | "ctrl-alt-f toggle full screen\n" |
@@ -7676,7 +7681,7 @@ static void help(int exitcode) | @@ -7676,7 +7681,7 @@ static void help(int exitcode) | ||
7676 | DEFAULT_NETWORK_DOWN_SCRIPT, | 7681 | DEFAULT_NETWORK_DOWN_SCRIPT, |
7677 | #endif | 7682 | #endif |
7678 | DEFAULT_GDBSTUB_PORT, | 7683 | DEFAULT_GDBSTUB_PORT, |
7679 | - "/tmp/qemu.log"); | 7684 | + logfilename); |
7680 | exit(exitcode); | 7685 | exit(exitcode); |
7681 | } | 7686 | } |
7682 | 7687 | ||
@@ -7763,6 +7768,7 @@ enum { | @@ -7763,6 +7768,7 @@ enum { | ||
7763 | QEMU_OPTION_old_param, | 7768 | QEMU_OPTION_old_param, |
7764 | QEMU_OPTION_clock, | 7769 | QEMU_OPTION_clock, |
7765 | QEMU_OPTION_startdate, | 7770 | QEMU_OPTION_startdate, |
7771 | + QEMU_OPTION_translation, | ||
7766 | }; | 7772 | }; |
7767 | 7773 | ||
7768 | typedef struct QEMUOption { | 7774 | typedef struct QEMUOption { |
@@ -7871,6 +7877,7 @@ const QEMUOption qemu_options[] = { | @@ -7871,6 +7877,7 @@ const QEMUOption qemu_options[] = { | ||
7871 | #endif | 7877 | #endif |
7872 | { "clock", HAS_ARG, QEMU_OPTION_clock }, | 7878 | { "clock", HAS_ARG, QEMU_OPTION_clock }, |
7873 | { "startdate", HAS_ARG, QEMU_OPTION_startdate }, | 7879 | { "startdate", HAS_ARG, QEMU_OPTION_startdate }, |
7880 | + { "translation", HAS_ARG, QEMU_OPTION_translation }, | ||
7874 | { NULL }, | 7881 | { NULL }, |
7875 | }; | 7882 | }; |
7876 | 7883 | ||
@@ -8713,6 +8720,22 @@ int main(int argc, char **argv) | @@ -8713,6 +8720,22 @@ int main(int argc, char **argv) | ||
8713 | } | 8720 | } |
8714 | } | 8721 | } |
8715 | break; | 8722 | break; |
8723 | + case QEMU_OPTION_translation: | ||
8724 | + { | ||
8725 | + int mask; | ||
8726 | + CPUTranslationSetting *setting; | ||
8727 | + | ||
8728 | + mask = cpu_str_to_translation_mask(optarg); | ||
8729 | + if (!mask) { | ||
8730 | + printf("Translation settings (comma separated):\n"); | ||
8731 | + for(setting = cpu_translation_settings; setting->mask != 0; setting++) { | ||
8732 | + printf("%-10s %s\n", setting->name, setting->help); | ||
8733 | + } | ||
8734 | + exit(1); | ||
8735 | + } | ||
8736 | + cpu_set_translation_settings(mask); | ||
8737 | + } | ||
8738 | + break; | ||
8716 | } | 8739 | } |
8717 | } | 8740 | } |
8718 | } | 8741 | } |