diff options
author | Evgeniy Naydanov <evgeniy.naydanov@syntacore.com> | 2024-01-17 17:34:46 +0300 |
---|---|---|
committer | Evgeniy Naydanov <evgeniy.naydanov@syntacore.com> | 2024-01-23 17:50:01 +0300 |
commit | ca3abcaa06e2d799bde7f883329dfc3b001d5dc5 (patch) | |
tree | eacd8e8ffbcbb84304c9d50a2c7fd8e759f3ae6c | |
parent | 78a719fad3ed151dd525dbcc2e2ea7b3140e142e (diff) | |
download | riscv-openocd-ca3abcaa06e2d799bde7f883329dfc3b001d5dc5.zip riscv-openocd-ca3abcaa06e2d799bde7f883329dfc3b001d5dc5.tar.gz riscv-openocd-ca3abcaa06e2d799bde7f883329dfc3b001d5dc5.tar.bz2 |
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 <evgeniy.naydanov@syntacore.com>
-rw-r--r-- | src/target/riscv/riscv-013.c | 13 | ||||
-rw-r--r-- | 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 b2d68b2..3166b9e 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 3ebc76a..8e3871d 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)); |