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 | 787 | void cpu_set_log_filename(const char *filename); |
788 | 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 | 804 | /* IO ports API */ |
791 | 805 | |
792 | 806 | /* NOTE: as these functions may be even used when there is an isa | ... | ... |
cpu-exec.c
... | ... | @@ -20,6 +20,7 @@ |
20 | 20 | #include "config.h" |
21 | 21 | #include "exec.h" |
22 | 22 | #include "disas.h" |
23 | +#include <string.h> | |
23 | 24 | |
24 | 25 | #if !defined(CONFIG_SOFTMMU) |
25 | 26 | #undef EAX |
... | ... | @@ -40,6 +41,9 @@ int tb_invalidated_flag; |
40 | 41 | //#define DEBUG_EXEC |
41 | 42 | //#define DEBUG_SIGNAL |
42 | 43 | |
44 | +/* translation settings */ | |
45 | +int translation_settings = 0; | |
46 | + | |
43 | 47 | #define SAVE_GLOBALS() |
44 | 48 | #define RESTORE_GLOBALS() |
45 | 49 | |
... | ... | @@ -120,6 +124,56 @@ void cpu_resume_from_signal(CPUState *env1, void *puc) |
120 | 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 | 178 | static TranslationBlock *tb_find_slow(target_ulong pc, |
125 | 179 | target_ulong cs_base, |
... | ... | @@ -141,6 +195,9 @@ static TranslationBlock *tb_find_slow(target_ulong pc, |
141 | 195 | phys_pc = get_phys_addr_code(env, pc); |
142 | 196 | phys_page1 = phys_pc & TARGET_PAGE_MASK; |
143 | 197 | phys_page2 = -1; |
198 | + if (translation_settings & CPU_SETTING_NO_CACHE) | |
199 | + goto not_found; | |
200 | + | |
144 | 201 | h = tb_phys_hash_func(phys_pc); |
145 | 202 | ptb1 = &tb_phys_hash[h]; |
146 | 203 | for(;;) { |
... | ... | @@ -264,7 +321,10 @@ static inline TranslationBlock *tb_find_fast(void) |
264 | 321 | #else |
265 | 322 | #error unsupported CPU |
266 | 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 | 328 | if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base || |
269 | 329 | tb->flags != flags, 0)) { |
270 | 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 | 363 | @var{date} are: @code{now} or @code{2006-06-17T16:01:21} or |
364 | 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 | 377 | @item -pidfile @var{file} |
367 | 378 | Store the QEMU process PID in @var{file}. It is useful if you launch QEMU |
368 | 379 | from a script. | ... | ... |
vl.c
... | ... | @@ -240,6 +240,8 @@ static CPUState *cur_cpu; |
240 | 240 | static CPUState *next_cpu; |
241 | 241 | static int event_pending = 1; |
242 | 242 | |
243 | +extern char *logfilename; | |
244 | + | |
243 | 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 | 7663 | #endif |
7662 | 7664 | "-clock force the use of the given methods for timer alarm.\n" |
7663 | 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 | 7669 | "\n" |
7665 | 7670 | "During emulation, the following keys are useful:\n" |
7666 | 7671 | "ctrl-alt-f toggle full screen\n" |
... | ... | @@ -7676,7 +7681,7 @@ static void help(int exitcode) |
7676 | 7681 | DEFAULT_NETWORK_DOWN_SCRIPT, |
7677 | 7682 | #endif |
7678 | 7683 | DEFAULT_GDBSTUB_PORT, |
7679 | - "/tmp/qemu.log"); | |
7684 | + logfilename); | |
7680 | 7685 | exit(exitcode); |
7681 | 7686 | } |
7682 | 7687 | |
... | ... | @@ -7763,6 +7768,7 @@ enum { |
7763 | 7768 | QEMU_OPTION_old_param, |
7764 | 7769 | QEMU_OPTION_clock, |
7765 | 7770 | QEMU_OPTION_startdate, |
7771 | + QEMU_OPTION_translation, | |
7766 | 7772 | }; |
7767 | 7773 | |
7768 | 7774 | typedef struct QEMUOption { |
... | ... | @@ -7871,6 +7877,7 @@ const QEMUOption qemu_options[] = { |
7871 | 7877 | #endif |
7872 | 7878 | { "clock", HAS_ARG, QEMU_OPTION_clock }, |
7873 | 7879 | { "startdate", HAS_ARG, QEMU_OPTION_startdate }, |
7880 | + { "translation", HAS_ARG, QEMU_OPTION_translation }, | |
7874 | 7881 | { NULL }, |
7875 | 7882 | }; |
7876 | 7883 | |
... | ... | @@ -8713,6 +8720,22 @@ int main(int argc, char **argv) |
8713 | 8720 | } |
8714 | 8721 | } |
8715 | 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 | } | ... | ... |