Merge commit 'gnu/master' into test
[qemu] / gdbstub.c
index 3c34741..9bd4375 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1156,6 +1156,36 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
 
     return 4;
 }
+#elif defined (TARGET_MICROBLAZE)
+
+#define NUM_CORE_REGS (32 + 5)
+
+static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+       GET_REG32(env->regs[n]);
+    } else {
+       GET_REG32(env->sregs[n - 32]);
+    }
+    return 0;
+}
+
+static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+{
+    uint32_t tmp;
+
+    if (n > NUM_CORE_REGS)
+       return 0;
+
+    tmp = ldl_p(mem_buf);
+
+    if (n < 32) {
+       env->regs[n] = tmp;
+    } else {
+       env->sregs[n - 32] = tmp;
+    }
+    return 4;
+}
 #elif defined (TARGET_CRIS)
 
 #define NUM_CORE_REGS 49
@@ -1528,6 +1558,8 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
     s->c_cpu->pc = pc;
 #elif defined (TARGET_MIPS)
     s->c_cpu->active_tc.PC = pc;
+#elif defined (TARGET_MICROBLAZE)
+    s->c_cpu->sregs[SR_PC] = pc;
 #elif defined (TARGET_CRIS)
     s->c_cpu->pc = pc;
 #elif defined (TARGET_ALPHA)
@@ -1535,11 +1567,34 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 #endif
 }
 
+static inline int gdb_id(CPUState *env)
+{
+#if defined(CONFIG_USER_ONLY) && defined(USE_NPTL)
+    return env->host_tid;
+#else
+    return env->cpu_index + 1;
+#endif
+}
+
+static CPUState *find_cpu(uint32_t thread_id)
+{
+    CPUState *env;
+
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        if (gdb_id(env) == thread_id) {
+            return env;
+        }
+    }
+
+    return NULL;
+}
+
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 {
     CPUState *env;
     const char *p;
-    int ch, reg_size, type, res, thread;
+    uint32_t thread;
+    int ch, reg_size, type, res;
     char buf[MAX_PACKET_LENGTH];
     uint8_t mem_buf[MAX_PACKET_LENGTH];
     uint8_t *registers;
@@ -1554,7 +1609,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     case '?':
         /* TODO: Make this return the correct value for user-mode.  */
         snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
-                 s->c_cpu->cpu_index+1);
+                 gdb_id(s->c_cpu));
         put_packet(s, buf);
         /* Remove all the breakpoints when this query is issued,
          * because gdb is doing and initial connect and the state
@@ -1718,9 +1773,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "OK");
             break;
         }
-        for (env = first_cpu; env != NULL; env = env->next_cpu)
-            if (env->cpu_index + 1 == thread)
-                break;
+        env = find_cpu(thread);
         if (env == NULL) {
             put_packet(s, "E22");
             break;
@@ -1741,14 +1794,13 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'T':
         thread = strtoull(p, (char **)&p, 16);
-#ifndef CONFIG_USER_ONLY
-        if (thread > 0 && thread < smp_cpus + 1)
-#else
-        if (thread == 1)
-#endif
-             put_packet(s, "OK");
-        else
+        env = find_cpu(thread);
+
+        if (env != NULL) {
+            put_packet(s, "OK");
+        } else {
             put_packet(s, "E22");
+        }
         break;
     case 'q':
     case 'Q':
@@ -1786,7 +1838,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         } else if (strcmp(p,"sThreadInfo") == 0) {
         report_cpuinfo:
             if (s->query_cpu) {
-                snprintf(buf, sizeof(buf), "m%x", s->query_cpu->cpu_index+1);
+                snprintf(buf, sizeof(buf), "m%x", gdb_id(s->query_cpu));
                 put_packet(s, buf);
                 s->query_cpu = s->query_cpu->next_cpu;
             } else
@@ -1794,16 +1846,15 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             break;
         } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
             thread = strtoull(p+16, (char **)&p, 16);
-            for (env = first_cpu; env != NULL; env = env->next_cpu)
-                if (env->cpu_index + 1 == thread) {
-                    cpu_synchronize_state(env, 0);
-                    len = snprintf((char *)mem_buf, sizeof(mem_buf),
-                                   "CPU#%d [%s]", env->cpu_index,
-                                   env->halted ? "halted " : "running");
-                    memtohex(buf, mem_buf, len);
-                    put_packet(s, buf);
-                    break;
-                }
+            env = find_cpu(thread);
+            if (env != NULL) {
+                cpu_synchronize_state(env, 0);
+                len = snprintf((char *)mem_buf, sizeof(mem_buf),
+                               "CPU#%d [%s]", env->cpu_index,
+                               env->halted ? "halted " : "running");
+                memtohex(buf, mem_buf, len);
+                put_packet(s, buf);
+            }
             break;
         }
 #ifdef CONFIG_USER_ONLY
@@ -1933,7 +1984,7 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
             }
             snprintf(buf, sizeof(buf),
                      "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
-                     GDB_SIGNAL_TRAP, env->cpu_index+1, type,
+                     GDB_SIGNAL_TRAP, gdb_id(env), type,
                      env->watchpoint_hit->vaddr);
             put_packet(s, buf);
             env->watchpoint_hit = NULL;
@@ -1944,7 +1995,7 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
     } else {
         ret = GDB_SIGNAL_INT;
     }
-    snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, env->cpu_index+1);
+    snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, gdb_id(env));
     put_packet(s, buf);
 }
 #endif