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