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 | } | ... | ... |