diff options
Diffstat (limited to 'target')
| -rw-r--r-- | target/hexagon/cpu.c | 6 | ||||
| -rw-r--r-- | target/hexagon/gdbstub.c | 68 | ||||
| -rw-r--r-- | target/hexagon/internal.h | 2 |
3 files changed, 76 insertions, 0 deletions
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index 575bcc190d..f155936289 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -24,6 +24,7 @@ #include "hw/qdev-properties.h" #include "fpu/softfloat-helpers.h" #include "tcg/tcg.h" +#include "exec/gdbstub.h" static void hexagon_v67_cpu_init(Object *obj) { } static void hexagon_v68_cpu_init(Object *obj) { } @@ -339,6 +340,11 @@ static void hexagon_cpu_realize(DeviceState *dev, Error **errp) return; } + gdb_register_coprocessor(cs, hexagon_hvx_gdb_read_register, + hexagon_hvx_gdb_write_register, + NUM_VREGS + NUM_QREGS, + "hexagon-hvx.xml", 0); + qemu_init_vcpu(cs); cpu_reset(cs); diff --git a/target/hexagon/gdbstub.c b/target/hexagon/gdbstub.c index a06fed9f18..54d37e006e 100644 --- a/target/hexagon/gdbstub.c +++ b/target/hexagon/gdbstub.c @@ -60,3 +60,71 @@ int hexagon_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) g_assert_not_reached(); } + +static int gdb_get_vreg(CPUHexagonState *env, GByteArray *mem_buf, int n) +{ + int total = 0; + int i; + for (i = 0; i < ARRAY_SIZE(env->VRegs[n].uw); i++) { + total += gdb_get_regl(mem_buf, env->VRegs[n].uw[i]); + } + return total; +} + +static int gdb_get_qreg(CPUHexagonState *env, GByteArray *mem_buf, int n) +{ + int total = 0; + int i; + for (i = 0; i < ARRAY_SIZE(env->QRegs[n].uw); i++) { + total += gdb_get_regl(mem_buf, env->QRegs[n].uw[i]); + } + return total; +} + +int hexagon_hvx_gdb_read_register(CPUHexagonState *env, GByteArray *mem_buf, int n) +{ + if (n < NUM_VREGS) { + return gdb_get_vreg(env, mem_buf, n); + } + n -= NUM_VREGS; + + if (n < NUM_QREGS) { + return gdb_get_qreg(env, mem_buf, n); + } + + g_assert_not_reached(); +} + +static int gdb_put_vreg(CPUHexagonState *env, uint8_t *mem_buf, int n) +{ + int i; + for (i = 0; i < ARRAY_SIZE(env->VRegs[n].uw); i++) { + env->VRegs[n].uw[i] = ldtul_p(mem_buf); + mem_buf += 4; + } + return MAX_VEC_SIZE_BYTES; +} + +static int gdb_put_qreg(CPUHexagonState *env, uint8_t *mem_buf, int n) +{ + int i; + for (i = 0; i < ARRAY_SIZE(env->QRegs[n].uw); i++) { + env->QRegs[n].uw[i] = ldtul_p(mem_buf); + mem_buf += 4; + } + return MAX_VEC_SIZE_BYTES / 8; +} + +int hexagon_hvx_gdb_write_register(CPUHexagonState *env, uint8_t *mem_buf, int n) +{ + if (n < NUM_VREGS) { + return gdb_put_vreg(env, mem_buf, n); + } + n -= NUM_VREGS; + + if (n < NUM_QREGS) { + return gdb_put_qreg(env, mem_buf, n); + } + + g_assert_not_reached(); +} diff --git a/target/hexagon/internal.h b/target/hexagon/internal.h index b1bfadc3f5..d732b6bb3c 100644 --- a/target/hexagon/internal.h +++ b/target/hexagon/internal.h @@ -33,6 +33,8 @@ 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(CPUHexagonState *env, GByteArray *mem_buf, int n); +int hexagon_hvx_gdb_write_register(CPUHexagonState *env, uint8_t *mem_buf, int n); void hexagon_debug_vreg(CPUHexagonState *env, int regnum); void hexagon_debug_qreg(CPUHexagonState *env, int regnum); |