Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

target/riscv: reg cache entry is initialized before access #1101

Merged
merged 1 commit into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/target/riscv/riscv-011_reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ static const struct reg_arch_type *riscv011_gdb_regno_reg_type(uint32_t regno)

static int riscv011_init_reg(struct target *target, uint32_t regno)
{
return riscv_reg_impl_init_one(target, regno, riscv011_gdb_regno_reg_type(regno));
return riscv_reg_impl_init_cache_entry(target, regno,
riscv_reg_impl_gdb_regno_exist(target, regno),
riscv011_gdb_regno_reg_type(regno));
}

int riscv011_reg_init_all(struct target *target)
Expand Down
99 changes: 19 additions & 80 deletions src/target/riscv/riscv-013.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ static int abstract_cmd_batch_check_and_clear_cmderr(struct target *target,
return res;
}

static int execute_abstract_command(struct target *target, uint32_t command,
int riscv013_execute_abstract_command(struct target *target, uint32_t command,
uint32_t *cmderr)
{
assert(cmderr);
Expand Down Expand Up @@ -863,7 +863,7 @@ static int write_abstract_arg(struct target *target, unsigned index,
/**
* @par size in bits
*/
static uint32_t access_register_command(struct target *target, uint32_t number,
uint32_t riscv013_access_register_command(struct target *target, uint32_t number,
unsigned size, uint32_t flags)
{
uint32_t command = set_field(0, DM_COMMAND_CMDTYPE, 0);
Expand Down Expand Up @@ -920,11 +920,11 @@ static int register_read_abstract_with_size(struct target *target,
if (number >= GDB_REGNO_V0 && number <= GDB_REGNO_V31)
return ERROR_FAIL;

uint32_t command = access_register_command(target, number, size,
uint32_t command = riscv013_access_register_command(target, number, size,
AC_ACCESS_REGISTER_TRANSFER);

uint32_t cmderr;
int result = execute_abstract_command(target, command, &cmderr);
int result = riscv013_execute_abstract_command(target, command, &cmderr);
if (result != ERROR_OK) {
if (cmderr == CMDERR_NOT_SUPPORTED) {
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
Expand Down Expand Up @@ -969,7 +969,7 @@ static int register_write_abstract(struct target *target, enum gdb_regno number,
return ERROR_FAIL;

const unsigned int size_bits = register_size(target, number);
const uint32_t command = access_register_command(target, number, size_bits,
const uint32_t command = riscv013_access_register_command(target, number, size_bits,
AC_ACCESS_REGISTER_TRANSFER |
AC_ACCESS_REGISTER_WRITE);
LOG_DEBUG_REG(target, AC_ACCESS_REGISTER, command);
Expand Down Expand Up @@ -2112,70 +2112,9 @@ static int examine(struct target *target)
* program buffer. */
r->progbuf_size = info->progbufsize;

result = register_read_abstract_with_size(target, NULL, GDB_REGNO_S0, 64);
if (result == ERROR_OK)
r->xlen = 64;
else
r->xlen = 32;

/* Save s0 and s1. The register cache hasn't be initialized yet so we
* need to take care of this manually. */
uint64_t s0, s1;
if (register_read_abstract(target, &s0, GDB_REGNO_S0) != ERROR_OK) {
LOG_TARGET_ERROR(target, "Fatal: Failed to read s0.");
return ERROR_FAIL;
}
if (register_read_abstract(target, &s1, GDB_REGNO_S1) != ERROR_OK) {
LOG_TARGET_ERROR(target, "Fatal: Failed to read s1.");
return ERROR_FAIL;
}

if (register_read_direct(target, &r->misa, GDB_REGNO_MISA)) {
LOG_TARGET_ERROR(target, "Fatal: Failed to read MISA.");
return ERROR_FAIL;
}

uint64_t value;
if (register_read_direct(target, &value, GDB_REGNO_VLENB) != ERROR_OK) {
if (riscv_supports_extension(target, 'V'))
LOG_TARGET_WARNING(target, "Couldn't read vlenb; vector register access won't work.");
r->vlenb = 0;
} else {
r->vlenb = value;
LOG_TARGET_INFO(target, "Vector support with vlenb=%d", r->vlenb);
}

if (register_read_direct(target, &value, GDB_REGNO_MTOPI) == ERROR_OK) {
r->mtopi_readable = true;

if (register_read_direct(target, &value, GDB_REGNO_MTOPEI) == ERROR_OK) {
LOG_TARGET_INFO(target, "S?aia detected with IMSIC");
r->mtopei_readable = true;
} else {
r->mtopei_readable = false;
LOG_TARGET_INFO(target, "S?aia detected without IMSIC");
}
} else {
r->mtopi_readable = false;
}

/* Display this as early as possible to help people who are using
* really slow simulators. */
LOG_TARGET_DEBUG(target, " XLEN=%d, misa=0x%" PRIx64, r->xlen, r->misa);

/* Restore s0 and s1. */
if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK) {
LOG_TARGET_ERROR(target, "Fatal: Failed to write back s0.");
return ERROR_FAIL;
}
if (register_write_direct(target, GDB_REGNO_S1, s1) != ERROR_OK) {
LOG_TARGET_ERROR(target, "Fatal: Failed to write back s1.");
return ERROR_FAIL;
}

/* Now init registers based on what we discovered. */
if (riscv013_reg_init_all(target) != ERROR_OK)
return ERROR_FAIL;
result = riscv013_reg_examine_all(target);
if (result != ERROR_OK)
return result;

if (set_dcsr_ebreak(target, false) != ERROR_OK)
return ERROR_FAIL;
Expand Down Expand Up @@ -3651,7 +3590,7 @@ static int read_memory_abstract(struct target *target, target_addr_t address,

/* Execute the command */
uint32_t cmderr;
result = execute_abstract_command(target, command, &cmderr);
result = riscv013_execute_abstract_command(target, command, &cmderr);

/* TODO: we need to modify error handling here. */
/* NOTE: in case of timeout cmderr is set to CMDERR_NONE */
Expand All @@ -3673,7 +3612,7 @@ static int read_memory_abstract(struct target *target, target_addr_t address,
} else {
/* Try the same access but with postincrement disabled. */
command = access_memory_command(target, false, width, false, false);
result = execute_abstract_command(target, command, &cmderr);
result = riscv013_execute_abstract_command(target, command, &cmderr);
if (result == ERROR_OK) {
LOG_TARGET_DEBUG(target, "aampostincrement is not supported on this target.");
info->has_aampostincrement = YNM_NO;
Expand Down Expand Up @@ -3744,7 +3683,7 @@ static int write_memory_abstract(struct target *target, target_addr_t address,

/* Execute the command */
uint32_t cmderr;
result = execute_abstract_command(target, command, &cmderr);
result = riscv013_execute_abstract_command(target, command, &cmderr);

/* TODO: we need to modify error handling here. */
/* NOTE: in case of timeout cmderr is set to CMDERR_NONE */
Expand All @@ -3766,7 +3705,7 @@ static int write_memory_abstract(struct target *target, target_addr_t address,
} else {
/* Try the same access but with postincrement disabled. */
command = access_memory_command(target, false, width, false, true);
result = execute_abstract_command(target, command, &cmderr);
result = riscv013_execute_abstract_command(target, command, &cmderr);
if (result == ERROR_OK) {
LOG_TARGET_DEBUG(target, "aampostincrement is not supported on this target.");
info->has_aampostincrement = YNM_NO;
Expand Down Expand Up @@ -3812,11 +3751,11 @@ static int read_memory_progbuf_inner_startup(struct target *target,
/* AC_ACCESS_REGISTER_POSTEXEC is used to trigger first stage of the
* pipeline (memory -> s1) whenever this command is executed.
*/
const uint32_t startup_command = access_register_command(target,
const uint32_t startup_command = riscv013_access_register_command(target,
GDB_REGNO_S1, riscv_xlen(target),
AC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_POSTEXEC);
uint32_t cmderr;
if (execute_abstract_command(target, startup_command, &cmderr) != ERROR_OK)
if (riscv013_execute_abstract_command(target, startup_command, &cmderr) != ERROR_OK)
return ERROR_FAIL;
/* TODO: we need to modify error handling here. */
/* NOTE: in case of timeout cmderr is set to CMDERR_NONE */
Expand Down Expand Up @@ -4299,11 +4238,11 @@ static int read_memory_progbuf_inner_one(struct target *target,
if (write_abstract_arg(target, 0, access.target_address, riscv_xlen(target))
!= ERROR_OK)
return ERROR_FAIL;
uint32_t command = access_register_command(target, GDB_REGNO_S1,
uint32_t command = riscv013_access_register_command(target, GDB_REGNO_S1,
riscv_xlen(target), AC_ACCESS_REGISTER_WRITE |
AC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_POSTEXEC);
uint32_t cmderr;
if (execute_abstract_command(target, command, &cmderr) != ERROR_OK)
if (riscv013_execute_abstract_command(target, command, &cmderr) != ERROR_OK)
return ERROR_FAIL;

return read_word_from_s1(target, access, 0);
Expand Down Expand Up @@ -4642,14 +4581,14 @@ static int write_memory_progbuf_startup(struct target *target, target_addr_t *ad

/* Write and execute command that moves the value from data0 [, data1]
* into S1 and executes program buffer. */
uint32_t command = access_register_command(target,
uint32_t command = riscv013_access_register_command(target,
GDB_REGNO_S1, riscv_xlen(target),
AC_ACCESS_REGISTER_POSTEXEC |
AC_ACCESS_REGISTER_TRANSFER |
AC_ACCESS_REGISTER_WRITE);

uint32_t cmderr;
if (execute_abstract_command(target, command, &cmderr) != ERROR_OK)
if (riscv013_execute_abstract_command(target, command, &cmderr) != ERROR_OK)
return ERROR_FAIL;

log_memory_access64(*address_p, value, size, /*is_read*/ false);
Expand Down Expand Up @@ -5320,7 +5259,7 @@ static int riscv013_execute_progbuf(struct target *target, uint32_t *cmderr)
run_program = set_field(run_program, AC_ACCESS_REGISTER_TRANSFER, 0);
run_program = set_field(run_program, AC_ACCESS_REGISTER_REGNO, 0x1000);

return execute_abstract_command(target, run_program, cmderr);
return riscv013_execute_abstract_command(target, run_program, cmderr);
}

static void riscv013_fill_dmi_write(struct target *target, char *buf, uint64_t a, uint32_t d)
Expand Down
4 changes: 4 additions & 0 deletions src/target/riscv/riscv-013.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@ int riscv013_set_register(struct target *target, enum gdb_regno rid,
riscv_reg_t value);
int riscv013_set_register_buf(struct target *target, enum gdb_regno regno,
const uint8_t *value);
uint32_t riscv013_access_register_command(struct target *target, uint32_t number,
unsigned int size, uint32_t flags);
int riscv013_execute_abstract_command(struct target *target, uint32_t command,
uint32_t *cmderr);

#endif /* OPENOCD_TARGET_RISCV_RISCV_013_H */
Loading