diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index b2d68b2a3..3166b9e7f 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -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) { + /* It would be beneficial to move this redirection to the + * version-independent section, but there is a conflict: + * `dcsr[5]` is `dcsr.v` in current spec, but it is `dcsr.debugint` in 0.11. + */ + if (rid == 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) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 3ebc76aa4..8e3871d2c 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -5232,16 +5232,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));