Commit 40a2e657a5e055f3962639dd9bdec788aaf415c5

Authored by ths
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
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.
@@ -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 }