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