Skip to content

Commit

Permalink
gdbstub: Change gdb_get_reg_cb and gdb_set_reg_cb
Browse files Browse the repository at this point in the history
Align the parameters of gdb_get_reg_cb and gdb_set_reg_cb with the
gdb_read_register and gdb_write_register members of CPUClass to allow
to unify the logic to access registers of the core and coprocessors
in the future.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20240103173349.398526-32-alex.bennee@linaro.org>
Message-Id: <20231213-gdb-v17-6-777047380591@daynix.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
  • Loading branch information
akihikodaki authored and stsquad committed Jan 15, 2024
1 parent 165df5c commit 93f7969
Show file tree
Hide file tree
Showing 14 changed files with 236 additions and 91 deletions.
6 changes: 2 additions & 4 deletions gdbstub/gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,6 @@ const GDBFeature *gdb_find_static_feature(const char *xmlname)
static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
CPUArchState *env = cpu_env(cpu);
GDBRegisterState *r;

if (reg < cc->gdb_num_core_regs) {
Expand All @@ -513,7 +512,7 @@ static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
if (r->base_reg <= reg && reg < r->base_reg + r->feature->num_regs) {
return r->get_reg(env, buf, reg - r->base_reg);
return r->get_reg(cpu, buf, reg - r->base_reg);
}
}
}
Expand All @@ -523,7 +522,6 @@ static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
CPUArchState *env = cpu_env(cpu);
GDBRegisterState *r;

if (reg < cc->gdb_num_core_regs) {
Expand All @@ -534,7 +532,7 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
if (r->base_reg <= reg && reg < r->base_reg + r->feature->num_regs) {
return r->set_reg(env, mem_buf, reg - r->base_reg);
return r->set_reg(cpu, mem_buf, reg - r->base_reg);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions include/exec/gdbstub.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ typedef struct GDBFeatureBuilder {


/* Get or set a register. Returns the size of the register. */
typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg);
typedef int (*gdb_set_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
typedef int (*gdb_get_reg_cb)(CPUState *cpu, GByteArray *buf, int reg);
typedef int (*gdb_set_reg_cb)(CPUState *cpu, uint8_t *buf, int reg);

/**
* gdb_register_coprocessor() - register a supplemental set of registers
Expand Down
51 changes: 36 additions & 15 deletions target/arm/gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
return 0;
}

static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
static int vfp_gdb_get_reg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = env_archcpu(env);
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;

/* VFP data registers are always little-endian. */
Expand All @@ -130,9 +131,10 @@ static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
return 0;
}

static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
static int vfp_gdb_set_reg(CPUState *cs, uint8_t *buf, int reg)
{
ARMCPU *cpu = env_archcpu(env);
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;

if (reg < nregs) {
Expand All @@ -156,8 +158,11 @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
return 0;
}

static int vfp_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
static int vfp_gdb_get_sysreg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

switch (reg) {
case 0:
return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
Expand All @@ -167,8 +172,11 @@ static int vfp_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
return 0;
}

static int vfp_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
static int vfp_gdb_set_sysreg(CPUState *cs, uint8_t *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

switch (reg) {
case 0:
env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
Expand All @@ -180,8 +188,11 @@ static int vfp_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
return 0;
}

static int mve_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
static int mve_gdb_get_reg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

switch (reg) {
case 0:
return gdb_get_reg32(buf, env->v7m.vpr);
Expand All @@ -190,8 +201,11 @@ static int mve_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
}
}

static int mve_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
static int mve_gdb_set_reg(CPUState *cs, uint8_t *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

switch (reg) {
case 0:
env->v7m.vpr = ldl_p(buf);
Expand All @@ -210,9 +224,10 @@ static int mve_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
* We return the number of bytes copied
*/

static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
static int arm_gdb_get_sysreg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = env_archcpu(env);
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
const ARMCPRegInfo *ri;
uint32_t key;

Expand All @@ -228,7 +243,7 @@ static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
return 0;
}

static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
static int arm_gdb_set_sysreg(CPUState *cs, uint8_t *buf, int reg)
{
return 0;
}
Expand Down Expand Up @@ -367,8 +382,11 @@ static int m_sysreg_get(CPUARMState *env, GByteArray *buf,
return gdb_get_reg32(buf, *ptr);
}

static int arm_gdb_get_m_systemreg(CPUARMState *env, GByteArray *buf, int reg)
static int arm_gdb_get_m_systemreg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

/*
* Here, we emulate MRS instruction, where CONTROL has a mix of
* banked and non-banked bits.
Expand All @@ -379,7 +397,7 @@ static int arm_gdb_get_m_systemreg(CPUARMState *env, GByteArray *buf, int reg)
return m_sysreg_get(env, buf, reg, env->v7m.secure);
}

static int arm_gdb_set_m_systemreg(CPUARMState *env, uint8_t *buf, int reg)
static int arm_gdb_set_m_systemreg(CPUState *cs, uint8_t *buf, int reg)
{
return 0; /* TODO */
}
Expand Down Expand Up @@ -414,12 +432,15 @@ static GDBFeature *arm_gen_dynamic_m_systemreg_feature(CPUState *cs,
* For user-only, we see the non-secure registers via m_systemreg above.
* For secext, encode the non-secure view as even and secure view as odd.
*/
static int arm_gdb_get_m_secextreg(CPUARMState *env, GByteArray *buf, int reg)
static int arm_gdb_get_m_secextreg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

return m_sysreg_get(env, buf, reg >> 1, reg & 1);
}

static int arm_gdb_set_m_secextreg(CPUARMState *env, uint8_t *buf, int reg)
static int arm_gdb_set_m_secextreg(CPUState *cs, uint8_t *buf, int reg)
{
return 0; /* TODO */
}
Expand Down
27 changes: 19 additions & 8 deletions target/arm/gdbstub64.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
return 0;
}

int aarch64_gdb_get_fpu_reg(CPUARMState *env, GByteArray *buf, int reg)
int aarch64_gdb_get_fpu_reg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

switch (reg) {
case 0 ... 31:
{
Expand All @@ -92,8 +95,11 @@ int aarch64_gdb_get_fpu_reg(CPUARMState *env, GByteArray *buf, int reg)
}
}

int aarch64_gdb_set_fpu_reg(CPUARMState *env, uint8_t *buf, int reg)
int aarch64_gdb_set_fpu_reg(CPUState *cs, uint8_t *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

switch (reg) {
case 0 ... 31:
/* 128 bit FP register */
Expand All @@ -116,9 +122,10 @@ int aarch64_gdb_set_fpu_reg(CPUARMState *env, uint8_t *buf, int reg)
}
}

int aarch64_gdb_get_sve_reg(CPUARMState *env, GByteArray *buf, int reg)
int aarch64_gdb_get_sve_reg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = env_archcpu(env);
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

switch (reg) {
/* The first 32 registers are the zregs */
Expand Down Expand Up @@ -164,9 +171,10 @@ int aarch64_gdb_get_sve_reg(CPUARMState *env, GByteArray *buf, int reg)
return 0;
}

int aarch64_gdb_set_sve_reg(CPUARMState *env, uint8_t *buf, int reg)
int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)
{
ARMCPU *cpu = env_archcpu(env);
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

/* The first 32 registers are the zregs */
switch (reg) {
Expand Down Expand Up @@ -210,8 +218,11 @@ int aarch64_gdb_set_sve_reg(CPUARMState *env, uint8_t *buf, int reg)
return 0;
}

int aarch64_gdb_get_pauth_reg(CPUARMState *env, GByteArray *buf, int reg)
int aarch64_gdb_get_pauth_reg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

switch (reg) {
case 0: /* pauth_dmask */
case 1: /* pauth_cmask */
Expand Down Expand Up @@ -241,7 +252,7 @@ int aarch64_gdb_get_pauth_reg(CPUARMState *env, GByteArray *buf, int reg)
}
}

int aarch64_gdb_set_pauth_reg(CPUARMState *env, uint8_t *buf, int reg)
int aarch64_gdb_set_pauth_reg(CPUState *cs, uint8_t *buf, int reg)
{
/* All pseudo registers are read-only. */
return 0;
Expand Down
12 changes: 6 additions & 6 deletions target/arm/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -1447,12 +1447,12 @@ static inline uint64_t pmu_counter_mask(CPUARMState *env)

#ifdef TARGET_AARCH64
GDBFeature *arm_gen_dynamic_svereg_feature(CPUState *cpu, int base_reg);
int aarch64_gdb_get_sve_reg(CPUARMState *env, GByteArray *buf, int reg);
int aarch64_gdb_set_sve_reg(CPUARMState *env, uint8_t *buf, int reg);
int aarch64_gdb_get_fpu_reg(CPUARMState *env, GByteArray *buf, int reg);
int aarch64_gdb_set_fpu_reg(CPUARMState *env, uint8_t *buf, int reg);
int aarch64_gdb_get_pauth_reg(CPUARMState *env, GByteArray *buf, int reg);
int aarch64_gdb_set_pauth_reg(CPUARMState *env, uint8_t *buf, int reg);
int aarch64_gdb_get_sve_reg(CPUState *cs, GByteArray *buf, int reg);
int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg);
int aarch64_gdb_get_fpu_reg(CPUState *cs, GByteArray *buf, int reg);
int aarch64_gdb_set_fpu_reg(CPUState *cs, uint8_t *buf, int reg);
int aarch64_gdb_get_pauth_reg(CPUState *cs, GByteArray *buf, int reg);
int aarch64_gdb_set_pauth_reg(CPUState *cs, uint8_t *buf, int reg);
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp);
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
Expand Down
10 changes: 8 additions & 2 deletions target/hexagon/gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,11 @@ static int gdb_get_qreg(CPUHexagonState *env, GByteArray *mem_buf, int n)
return total;
}

int hexagon_hvx_gdb_read_register(CPUHexagonState *env, GByteArray *mem_buf, int n)
int hexagon_hvx_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
HexagonCPU *cpu = HEXAGON_CPU(cs);
CPUHexagonState *env = &cpu->env;

if (n < NUM_VREGS) {
return gdb_get_vreg(env, mem_buf, n);
}
Expand Down Expand Up @@ -115,8 +118,11 @@ static int gdb_put_qreg(CPUHexagonState *env, uint8_t *mem_buf, int n)
return MAX_VEC_SIZE_BYTES / 8;
}

int hexagon_hvx_gdb_write_register(CPUHexagonState *env, uint8_t *mem_buf, int n)
int hexagon_hvx_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
HexagonCPU *cpu = HEXAGON_CPU(cs);
CPUHexagonState *env = &cpu->env;

if (n < NUM_VREGS) {
return gdb_put_vreg(env, mem_buf, n);
}
Expand Down
4 changes: 2 additions & 2 deletions target/hexagon/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +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);
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);

void hexagon_debug_vreg(CPUHexagonState *env, int regnum);
void hexagon_debug_qreg(CPUHexagonState *env, int regnum);
Expand Down
11 changes: 7 additions & 4 deletions target/loongarch/gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,11 @@ int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
return length;
}

static int loongarch_gdb_get_fpu(CPULoongArchState *env,
GByteArray *mem_buf, int n)
static int loongarch_gdb_get_fpu(CPUState *cs, GByteArray *mem_buf, int n)
{
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;

if (0 <= n && n < 32) {
return gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(0));
} else if (32 <= n && n < 40) {
Expand All @@ -97,9 +99,10 @@ static int loongarch_gdb_get_fpu(CPULoongArchState *env,
return 0;
}

static int loongarch_gdb_set_fpu(CPULoongArchState *env,
uint8_t *mem_buf, int n)
static int loongarch_gdb_set_fpu(CPUState *cs, uint8_t *mem_buf, int n)
{
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
int length = 0;

if (0 <= n && n < 32) {
Expand Down
20 changes: 16 additions & 4 deletions target/m68k/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@

#define SIGNBIT (1u << 31)

static int cf_fpu_gdb_get_reg(CPUM68KState *env, GByteArray *mem_buf, int n)
static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
{
M68kCPU *cpu = M68K_CPU(cs);
CPUM68KState *env = &cpu->env;

if (n < 8) {
float_status s;
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
Expand All @@ -46,8 +49,11 @@ static int cf_fpu_gdb_get_reg(CPUM68KState *env, GByteArray *mem_buf, int n)
return 0;
}

static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
{
M68kCPU *cpu = M68K_CPU(cs);
CPUM68KState *env = &cpu->env;

if (n < 8) {
float_status s;
env->fregs[n].d = float64_to_floatx80(ldq_p(mem_buf), &s);
Expand All @@ -66,8 +72,11 @@ static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
return 0;
}

static int m68k_fpu_gdb_get_reg(CPUM68KState *env, GByteArray *mem_buf, int n)
static int m68k_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
{
M68kCPU *cpu = M68K_CPU(cs);
CPUM68KState *env = &cpu->env;

if (n < 8) {
int len = gdb_get_reg16(mem_buf, env->fregs[n].l.upper);
len += gdb_get_reg16(mem_buf, 0);
Expand All @@ -85,8 +94,11 @@ static int m68k_fpu_gdb_get_reg(CPUM68KState *env, GByteArray *mem_buf, int n)
return 0;
}

static int m68k_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
static int m68k_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
{
M68kCPU *cpu = M68K_CPU(cs);
CPUM68KState *env = &cpu->env;

if (n < 8) {
env->fregs[n].l.upper = lduw_be_p(mem_buf);
env->fregs[n].l.lower = ldq_be_p(mem_buf + 4);
Expand Down

0 comments on commit 93f7969

Please sign in to comment.