From 239f56efebb1d50949bd2fa040ffdc68d49cb32e Mon Sep 17 00:00:00 2001 From: Evgeniy Naydanov Date: Wed, 17 Jan 2024 17:34:46 +0300 Subject: [PATCH] target/riscv: move read redirection for `priv` to `riscv-013.c` 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 --- src/target/riscv/riscv-013.c | 13 +++++++++++++ src/target/riscv/riscv.c | 10 +--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 651342acd0..26e1f76e4d 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) { + /* 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 (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 47674ad01b..b3a8bfdcf2 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -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));