]> git.proxmox.com Git - qemu.git/commitdiff
log activation from gdb - gdb single step support for x86 - stop timer when cpu is...
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 5 Oct 2003 14:28:56 +0000 (14:28 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 5 Oct 2003 14:28:56 +0000 (14:28 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@402 c046a42c-6fe2-441c-8c8c-71466251a162

cpu-all.h
exec.c
gdbstub.c
target-i386/translate.c
vl.c

index 43c03c96cf459582099e6ccc129c0b78ab1b61f7..00b9399e55d805e924e255fa45c1b7f08850d47f 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -377,6 +377,10 @@ int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
 int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
 void cpu_single_step(CPUState *env, int enabled);
 
+#define CPU_LOG_ALL 1
+void cpu_set_log(int log_flags);
+void cpu_set_log_filename(const char *filename);
+
 /* memory API */
 
 typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
diff --git a/exec.c b/exec.c
index 46cccb5deb7f6f5da8c33ec0530d6f43c37088df..f4f6a9bc4159f421eaa7bd092048f0c9adceb207 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -78,6 +78,11 @@ CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 static int io_mem_nb;
 
+/* log support */
+char *logfilename = "/tmp/qemu.log";
+FILE *logfile;
+int loglevel;
+
 static void page_init(void)
 {
     /* NOTE: we can always suppose that host_page_size >=
@@ -676,6 +681,24 @@ void cpu_single_step(CPUState *env, int enabled)
 #endif
 }
 
+/* enable or disable low levels log */
+void cpu_set_log(int log_flags)
+{
+    loglevel = log_flags;
+    if (loglevel && !logfile) {
+        logfile = fopen(logfilename, "w");
+        if (!logfile) {
+            perror(logfilename);
+            _exit(1);
+        }
+        setvbuf(logfile, NULL, _IOLBF, 0);
+    }
+}
+
+void cpu_set_log_filename(const char *filename)
+{
+    logfilename = strdup(filename);
+}
 
 /* mask must never be zero */
 void cpu_interrupt(CPUState *env, int mask)
index d73a7efe3680e6ca56279d0ddef60c4337812e39..15b3940ed62348f024f64523971d2e8c755672ab 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -437,7 +437,24 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port)
                 goto breakpoint_error;
             }
             break;
+        case 'Q':
+            if (!strncmp(p, "Tinit", 5)) {
+                /* init traces */
+                put_packet("OK");
+            } else if (!strncmp(p, "TStart", 6)) {
+                /* start log (gdb 'tstart' command) */
+                cpu_set_log(CPU_LOG_ALL);
+                put_packet("OK");
+            } else if (!strncmp(p, "TStop", 5)) {
+                /* stop log (gdb 'tstop' command) */
+                cpu_set_log(0);
+                put_packet("OK");
+            } else {
+                goto unknown_command;
+            }
+            break;
         default:
+        unknown_command:
             /* put empty packet */
             buf[0] = '\0';
             put_packet(buf);
index 4d89ccbba93e6e55c6e1216c2c8bd9a79c80da59..43d3bbcbb8debca4d71be32d39f8ba45de95fd57 100644 (file)
@@ -60,6 +60,7 @@ typedef struct DisasContext {
     int cpl;
     int iopl;
     int tf;     /* TF cpu flag */
+    int singlestep_enabled; /* "hardware" single step enabled */
     int jmp_opt; /* use direct block chaining for direct jumps */
     int mem_index; /* select memory access functions */
     struct TranslationBlock *tb;
@@ -1712,7 +1713,9 @@ static void gen_eob(DisasContext *s)
 {
     if (s->cc_op != CC_OP_DYNAMIC)
         gen_op_set_cc_op(s->cc_op);
-    if (s->tf) {
+    if (s->singlestep_enabled) {
+        gen_op_debug();
+    } else if (s->tf) {
         gen_op_raise_exception(EXCP01_SSTP);
     } else {
         gen_op_movl_T0_0();
@@ -4368,6 +4371,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
     dc->iopl = (flags >> IOPL_SHIFT) & 3;
     dc->tf = (flags >> TF_SHIFT) & 1;
+    dc->singlestep_enabled = env->singlestep_enabled;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cs_base = cs_base;
     dc->tb = tb;
@@ -4425,7 +4429,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
             break;
         /* if single step mode, we generate only one instruction and
            generate an exception */
-        if (dc->tf) {
+        if (dc->tf || dc->singlestep_enabled) {
             gen_op_jmp_im(pc_ptr - dc->cs_base);
             gen_eob(dc);
             break;
diff --git a/vl.c b/vl.c
index 2978694d639516e3699c3c20c0a3a703e07c1baa..f027bebb9e878ab721f0f69c4da4a2badc2dda14 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -50,7 +50,6 @@
 
 #include "vl.h"
 
-#define DEBUG_LOGFILE "/tmp/vl.log"
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define BIOS_FILENAME "bios.bin"
 #define VGABIOS_FILENAME "vgabios.bin"
@@ -209,8 +208,6 @@ static const char *bios_dir = CONFIG_QEMU_SHAREDIR;
 char phys_ram_file[1024];
 CPUX86State *global_env;
 CPUX86State *cpu_single_env;
-FILE *logfile = NULL;
-int loglevel;
 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
 IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
 BlockDriverState *bs_table[MAX_DISKS];
@@ -832,20 +829,76 @@ int speaker_data_on;
 int dummy_refresh_clock;
 int pit_min_timer_count = 0;
 
-int64_t get_clock(void)
+
+#if defined(__powerpc__)
+
+static inline uint32_t get_tbl(void) 
 {
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    return tv.tv_sec * 1000000LL + tv.tv_usec;
+    uint32_t tbl;
+    asm volatile("mftb %0" : "=r" (tbl));
+    return tbl;
 }
 
-int64_t cpu_get_ticks(void)
+static inline uint32_t get_tbu(void) 
+{
+       uint32_t tbl;
+       asm volatile("mftbu %0" : "=r" (tbl));
+       return tbl;
+}
+
+int64_t cpu_get_real_ticks(void)
+{
+    uint32_t l, h, h1;
+    /* NOTE: we test if wrapping has occurred */
+    do {
+        h = get_tbu();
+        l = get_tbl();
+        h1 = get_tbu();
+    } while (h != h1);
+    return ((int64_t)h << 32) | l;
+}
+
+#elif defined(__i386__)
+
+int64_t cpu_get_real_ticks(void)
 {
     int64_t val;
     asm("rdtsc" : "=A" (val));
     return val;
 }
 
+#else
+#error unsupported CPU
+#endif
+
+static int64_t cpu_ticks_offset;
+static int64_t cpu_ticks_last;
+
+int64_t cpu_get_ticks(void)
+{
+    return cpu_get_real_ticks() + cpu_ticks_offset;
+}
+
+/* enable cpu_get_ticks() */
+void cpu_enable_ticks(void)
+{
+    cpu_ticks_offset = cpu_ticks_last - cpu_get_real_ticks();
+}
+
+/* disable cpu_get_ticks() : the clock is stopped. You must not call
+   cpu_get_ticks() after that.  */
+void cpu_disable_ticks(void)
+{
+    cpu_ticks_last = cpu_get_ticks();
+}
+
+int64_t get_clock(void)
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000LL + tv.tv_usec;
+}
+
 void cpu_calibrate_ticks(void)
 {
     int64_t usec, ticks;
@@ -3297,12 +3350,17 @@ int main_loop(void *opaque)
     }
 
     serial_ok = 1;
+    cpu_enable_ticks();
     for(;;) {
         ret = cpu_x86_exec(env);
-        if (reset_requested)
+        if (reset_requested) {
+            ret = EXCP_INTERRUPT; 
             break;
-        if (ret == EXCP_DEBUG)
-            return EXCP_DEBUG;
+        }
+        if (ret == EXCP_DEBUG) {
+            ret = EXCP_DEBUG;
+            break;
+        }
         /* if hlt instruction, we wait until the next IRQ */
         if (ret == EXCP_HLT) 
             timeout = 10;
@@ -3359,8 +3417,10 @@ int main_loop(void *opaque)
                 uint8_t buf[1];
                 /* stop emulation if requested by gdb */
                 n = read(gdbstub_fd, buf, 1);
-                if (n == 1)
+                if (n == 1) {
+                    ret = EXCP_INTERRUPT; 
                     break;
+                }
             }
         }
 
@@ -3377,7 +3437,8 @@ int main_loop(void *opaque)
             gui_refresh_pending = 0;
         }
     }
-    return EXCP_INTERRUPT;
+    cpu_disable_ticks();
+    return ret;
 }
 
 void help(void)
@@ -3535,7 +3596,7 @@ int main(int argc, char **argv)
             }
             break;
         case 'd':
-            loglevel = 1;
+            cpu_set_log(CPU_LOG_ALL);
             break;
         case 'n':
             pstrcpy(network_script, sizeof(network_script), optarg);
@@ -3563,14 +3624,6 @@ int main(int argc, char **argv)
 
     /* init debug */
     setvbuf(stdout, NULL, _IOLBF, 0);
-    if (loglevel) {
-        logfile = fopen(DEBUG_LOGFILE, "w");
-        if (!logfile) {
-            perror(DEBUG_LOGFILE);
-            _exit(1);
-        }
-        setvbuf(logfile, NULL, _IOLBF, 0);
-    }
 
     /* init network tun interface */
     if (net_fd < 0)