Add support for the system and guest registers to the gdbstub.

Reviewed-by: Pierrick Bouvier <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
 target/hexagon/cpu.h      |  1 +
 target/hexagon/internal.h |  4 +++
 target/hexagon/cpu.c      | 13 ++++++--
 target/hexagon/gdbstub.c  | 63 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index df4c0182247..ea54af621d2 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -241,6 +241,7 @@ G_NORETURN void hexagon_raise_exception_err(CPUHexagonState 
*env,
  */
 bool hexagon_thread_is_enabled(const CPUHexagonState *thread_env);
 uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t reg);
+void hexagon_greg_write(CPUHexagonState *env, uint32_t reg, uint32_t val);
 void hexagon_cpu_soft_reset(CPUHexagonState *env);
 #endif
 
diff --git a/target/hexagon/internal.h b/target/hexagon/internal.h
index 05d1129916e..3ed83904eb7 100644
--- a/target/hexagon/internal.h
+++ b/target/hexagon/internal.h
@@ -24,6 +24,10 @@ int hexagon_gdb_read_register(CPUState *cpu, GByteArray 
*buf, int reg);
 int hexagon_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 int hexagon_hvx_gdb_read_register(CPUState *env, GByteArray *mem_buf, int n);
 int hexagon_hvx_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n);
+#ifndef CONFIG_USER_ONLY
+int hexagon_sys_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);
+int hexagon_sys_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
+#endif
 
 void hexagon_debug_vreg(CPUHexagonState *env, int regnum);
 void hexagon_debug_qreg(CPUHexagonState *env, int regnum);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 1f7d8a8df70..ec4ced7e3c3 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -494,6 +494,10 @@ static void hexagon_cpu_realize(DeviceState *dev, Error 
**errp)
                              gdb_find_static_feature("hexagon-hvx.xml"));
 
 #ifndef CONFIG_USER_ONLY
+    gdb_register_coprocessor(cs, hexagon_sys_gdb_read_register,
+                             hexagon_sys_gdb_write_register,
+                             gdb_find_static_feature("hexagon-sys.xml"));
+
     if (!HEXAGON_CPU(dev)->tlb) {
         error_setg(errp, "hexagon cpu requires 'tlb' link property to be set");
         return;
@@ -858,11 +862,14 @@ uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t 
reg)
     case HEX_GREG_GPCYCLEHI:
         return ssr_ce ? hexagon_get_sys_pcycle_count_high(env) : 0;
     default:
-        qemu_log_mask(LOG_UNIMP, "reading greg %" PRId32
-                " not yet supported.\n", reg);
-        return 0;
+        return env->greg[reg];
     }
 }
+
+void hexagon_greg_write(CPUHexagonState *env, uint32_t reg, uint32_t val)
+{
+    env->greg[reg] = val;
+}
 #endif
 
 static void hexagon_cpu_class_base_init(ObjectClass *c, const void *data)
diff --git a/target/hexagon/gdbstub.c b/target/hexagon/gdbstub.c
index 76ab5235f6e..30b4d710cdb 100644
--- a/target/hexagon/gdbstub.c
+++ b/target/hexagon/gdbstub.c
@@ -16,9 +16,14 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/main-loop.h"
 #include "gdbstub/helpers.h"
 #include "cpu.h"
 #include "internal.h"
+#ifndef CONFIG_USER_ONLY
+#include "cpu_helper.h"
+#include "hw/hexagon/hexagon_globalreg.h"
+#endif
 
 int hexagon_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 {
@@ -76,6 +81,64 @@ int hexagon_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
     g_assert_not_reached();
 }
 
+#ifndef CONFIG_USER_ONLY
+int hexagon_sys_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
+{
+    CPUHexagonState *env = cpu_env(cs);
+    HexagonCPU *cpu = env_archcpu(env);
+    BQL_LOCK_GUARD();
+
+    if (n < NUM_SREGS) {
+        uint32_t val;
+        if (n < HEX_SREG_GLB_START) {
+            val = env->t_sreg[n];
+        } else {
+            val = cpu->globalregs ?
+                hexagon_globalreg_read(cpu->globalregs, n, env->threadId) : 0;
+        }
+        return gdb_get_regl(mem_buf, val);
+    }
+    n -= NUM_SREGS;
+
+    if (n < NUM_GREGS) {
+        return gdb_get_regl(mem_buf, hexagon_greg_read(env, n));
+    }
+    n -= NUM_GREGS;
+
+    g_assert_not_reached();
+}
+
+int hexagon_sys_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    CPUHexagonState *env = cpu_env(cs);
+    HexagonCPU *cpu = env_archcpu(env);
+    BQL_LOCK_GUARD();
+
+    if (n < NUM_SREGS) {
+        uint32_t val = ldl_le_p(mem_buf);
+        if (n == HEX_SREG_SSR) {
+            uint32_t old = env->t_sreg[HEX_SREG_SSR];
+            env->t_sreg[HEX_SREG_SSR] = val;
+            hexagon_modify_ssr(env, val, old);
+        } else if (n < HEX_SREG_GLB_START) {
+            env->t_sreg[n] = val;
+        } else if (cpu->globalregs) {
+            hexagon_globalreg_write(cpu->globalregs, n, val, env->threadId);
+        }
+        return sizeof(uint32_t);
+    }
+    n -= NUM_SREGS;
+
+    if (n < NUM_GREGS) {
+        hexagon_greg_write(env, n, ldl_le_p(mem_buf));
+        return sizeof(uint32_t);
+    }
+    n -= NUM_GREGS;
+
+    g_assert_not_reached();
+}
+#endif
+
 static int gdb_get_vreg(CPUHexagonState *env, GByteArray *mem_buf, int n)
 {
     int total = 0;
-- 
2.34.1

Reply via email to