Skip to content

Commit

Permalink
target/riscv: stop using register_get/set for 0.11 targets
Browse files Browse the repository at this point in the history
Caching is somewhat handled in `riscv-011.c`. Handling it additionaly in
`riscv.c` may cause problems. Sice there is no simulator that supports
RISC-V Debug Specification v0.11, so it is not feaseable to automate
testing.
This commit separates 0.11 register accesses and unlocks further
development in this area.

Change-Id: I73ff17ef85106c4ababa38319f446f6c384a1750
Signed-off-by: Evgeniy Naydanov <[email protected]>
  • Loading branch information
en-sc committed Apr 26, 2024
1 parent e51f869 commit 123ad3e
Showing 1 changed file with 68 additions and 11 deletions.
79 changes: 68 additions & 11 deletions src/target/riscv/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -5131,7 +5131,10 @@ static int riscv_set_or_write_register(struct target *target,
enum gdb_regno regid, riscv_reg_t value, bool write_through)
{
RISCV_INFO(r);
assert(r);
assert(r->set_register);
if (r->dtm_version == DTM_DTMCS_VERSION_0_11)
return r->set_register(target, regid, value);

keep_alive();

Expand Down Expand Up @@ -5228,7 +5231,10 @@ int riscv_get_register(struct target *target, riscv_reg_t *value,
enum gdb_regno regid)
{
RISCV_INFO(r);
assert(r);
assert(r->get_register);
if (r->dtm_version == DTM_DTMCS_VERSION_0_11)
return r->get_register(target, value, regid);

keep_alive();

Expand Down Expand Up @@ -5684,13 +5690,17 @@ const char *gdb_regno_name(const struct target *target, enum gdb_regno regno)
return NULL;
}

static struct target *get_target_from_reg(const struct reg *reg);

/**
* This function is the handler of user's request to read a register.
*/
static int register_get(struct reg *reg)
static int riscv013_reg_get(struct reg *reg)
{
struct target *target = ((riscv_reg_info_t *)reg->arch_info)->target;
struct target *target = get_target_from_reg(reg);
RISCV_INFO(r);
assert(r);
assert(r->dtm_version == DTM_DTMCS_VERSION_1_0);

/* TODO: Hack to deal with gdb that thinks these registers still exist. */
if (reg->number > GDB_REGNO_XPR15 && reg->number <= GDB_REGNO_XPR31 &&
Expand Down Expand Up @@ -5728,10 +5738,12 @@ static int register_get(struct reg *reg)
/**
* This function is the handler of user's request to write a register.
*/
static int register_set(struct reg *reg, uint8_t *buf)
static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
{
struct target *target = ((riscv_reg_info_t *)reg->arch_info)->target;
struct target *target = get_target_from_reg(reg);
RISCV_INFO(r);
assert(r);
assert(r->dtm_version == DTM_DTMCS_VERSION_1_0);

char *str = buf_to_hex_str(buf, reg->size);
LOG_TARGET_DEBUG(target, "Write 0x%s to %s (valid=%d).", str, reg->name,
Expand Down Expand Up @@ -5777,11 +5789,6 @@ static int register_set(struct reg *reg, uint8_t *buf)
return ERROR_OK;
}

static struct reg_arch_type riscv_reg_arch_type = {
.get = register_get,
.set = register_set
};

static int init_custom_register_names(struct list_head *expose_custom,
struct reg_name_table *custom_register_names)
{
Expand Down Expand Up @@ -5832,7 +5839,7 @@ static bool is_known_standard_csr(unsigned int csr_num)
return is_csr_in_buf[csr_num];
}

bool reg_is_initialized(const struct reg *reg)
static bool reg_is_initialized(const struct reg *reg)
{
assert(reg);
if (!reg->feature) {
Expand All @@ -5847,6 +5854,56 @@ bool reg_is_initialized(const struct reg *reg)
return true;
}

static struct target *get_target_from_reg(const struct reg *reg)
{
assert(reg_is_initialized(reg));
return ((const riscv_reg_info_t *)reg->arch_info)->target;
}

static int riscv011_reg_get(struct reg *reg)
{
struct target * const target = get_target_from_reg(reg);
RISCV_INFO(info);
assert(info);
assert(info->dtm_version == DTM_DTMCS_VERSION_0_11);
riscv_reg_t value;
const int result = info->get_register(target, &value, reg->number);
if (result != ERROR_OK)
return result;
buf_set_u64(reg->value, 0, reg->size, value);
return ERROR_OK;
}

static int riscv011_reg_set(struct reg *reg, uint8_t *buf)
{
const riscv_reg_t value = buf_get_u64(buf, 0, reg->size);
struct target * const target = get_target_from_reg(reg);
RISCV_INFO(info);
assert(info);
assert(info->dtm_version == DTM_DTMCS_VERSION_0_11);
return info->set_register(target, reg->number, value);
}

static struct reg_arch_type *gdb_regno_reg_type(const struct target *target,
uint32_t regno)
{
RISCV_INFO(info);
assert(info);
if (info->dtm_version == DTM_DTMCS_VERSION_0_11) {
static struct reg_arch_type riscv011_reg_type = {
.get = riscv011_reg_get,
.set = riscv011_reg_set
};
return &riscv011_reg_type;
}

static struct reg_arch_type riscv013_reg_type = {
.get = riscv013_reg_get,
.set = riscv013_reg_set
};
return &riscv013_reg_type;
}

static struct reg_feature *gdb_regno_feature(uint32_t regno)
{
if (regno <= GDB_REGNO_XPR31 || regno == GDB_REGNO_PC) {
Expand Down Expand Up @@ -6220,7 +6277,7 @@ static int init_reg(struct target *target, uint32_t regno)
if (reg_is_initialized(reg))
return ERROR_OK;
reg->number = regno;
reg->type = &riscv_reg_arch_type;
reg->type = gdb_regno_reg_type(target, regno);
reg->dirty = false;
reg->valid = false;
reg->hidden = false;
Expand Down

0 comments on commit 123ad3e

Please sign in to comment.