Skip to content

Commit

Permalink
target/riscv: move read redirection for priv to riscv-013.c
Browse files Browse the repository at this point in the history
The reason for the change is a conflict: `dcsr[5]` is `dcsr.v` in
current spec, but it is `dcsr.debugint` in 0.11. This causes `priv`
register to be read incorrectly.

Change-Id: If2d8fdcd8536afa4c7149c453101b00ce0df1ce0
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
  • Loading branch information
en-sc committed Jan 17, 2024
1 parent 4fc0d86 commit 2bf5f9c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 9 deletions.
13 changes: 13 additions & 0 deletions src/target/riscv/riscv-013.c
Original file line number Diff line number Diff line change
Expand Up @@ -4851,6 +4851,19 @@ struct target_type riscv013_target = {
static int riscv013_get_register(struct target *target,
riscv_reg_t *value, enum gdb_regno rid)
{
/* This would be nice to move this redirection, to version-independent part,
* but there is a conflict:
* `dcsr[5]` is `dcsr.v` in current spec, but it is `dcsr.debugint` in 0.11.
*/
if (regid == GDB_REGNO_PRIV) {
uint64_t dcsr;
if (riscv_get_register(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK)
return ERROR_FAIL;
*value = set_field(0, VIRT_PRIV_V, get_field(dcsr, CSR_DCSR_V));
*value = set_field(*value, VIRT_PRIV_PRV, get_field(dcsr, CSR_DCSR_PRV));
return ERROR_OK;
}

LOG_TARGET_DEBUG(target, "reading register %s", gdb_regno_name(target, rid));

if (dm013_select_target(target) != ERROR_OK)
Expand Down
10 changes: 1 addition & 9 deletions src/target/riscv/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -5244,16 +5244,8 @@ int riscv_get_register(struct target *target, riscv_reg_t *value,
if (openocd_is_shutdown_pending())
return ERROR_SERVER_INTERRUPTED;

if (regid == GDB_REGNO_PC) {
if (regid == GDB_REGNO_PC)
return riscv_get_register(target, value, GDB_REGNO_DPC);
} else if (regid == GDB_REGNO_PRIV) {
uint64_t dcsr;
if (riscv_get_register(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK)
return ERROR_FAIL;
*value = set_field(0, VIRT_PRIV_V, get_field(dcsr, CSR_DCSR_V));
*value = set_field(*value, VIRT_PRIV_PRV, get_field(dcsr, CSR_DCSR_PRV));
return ERROR_OK;
}

if (!target->reg_cache) {
assert(!target_was_examined(target));
Expand Down

0 comments on commit 2bf5f9c

Please sign in to comment.