From 3f1339f8e8dc87b99ac12618a9c9c3a1abd45d07 Mon Sep 17 00:00:00 2001 From: liangzhen Date: Wed, 20 Sep 2023 15:27:35 +0800 Subject: [PATCH] target/riscv: use cacheable read/write function to handle DCSR Signed-off-by: liangzhen --- src/target/riscv/riscv-013.c | 39 +++++------------------------------- src/target/riscv/riscv.c | 23 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index bbd505847a..324a764255 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -4667,24 +4667,12 @@ static int riscv013_get_register(struct target *target, if (dm013_select_target(target) != ERROR_OK) return ERROR_FAIL; - int result = ERROR_OK; - if (rid == GDB_REGNO_PC) { - /* TODO: move this into riscv.c. */ - result = register_read_direct(target, value, GDB_REGNO_DPC); - } else if (rid == GDB_REGNO_PRIV) { - uint64_t dcsr; - /* TODO: move this into riscv.c. */ - if (register_read_direct(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)); - } else { - result = register_read_direct(target, value, rid); - if (result != ERROR_OK) - *value = -1; + if (register_read_direct(target, value, rid) != ERROR_OK) { + *value = -1; + return ERROR_FAIL; } - return result; + return ERROR_OK; } static int riscv013_set_register(struct target *target, enum gdb_regno rid, @@ -4696,24 +4684,7 @@ static int riscv013_set_register(struct target *target, enum gdb_regno rid, if (dm013_select_target(target) != ERROR_OK) return ERROR_FAIL; - if (rid <= GDB_REGNO_XPR31) { - return register_write_direct(target, rid, value); - } else if (rid == GDB_REGNO_PC) { - LOG_TARGET_DEBUG(target, "writing PC to DPC: 0x%" PRIx64, value); - return register_write_direct(target, GDB_REGNO_DPC, value); - } else if (rid == GDB_REGNO_PRIV) { - riscv_reg_t dcsr; - - if (register_read_direct(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK) - return ERROR_FAIL; - dcsr = set_field(dcsr, CSR_DCSR_PRV, get_field(value, VIRT_PRIV_PRV)); - dcsr = set_field(dcsr, CSR_DCSR_V, get_field(value, VIRT_PRIV_V)); - return register_write_direct(target, GDB_REGNO_DCSR, dcsr); - } else { - return register_write_direct(target, rid, value); - } - - return ERROR_OK; + return register_write_direct(target, rid, value); } static int dm013_select_hart(struct target *target, int hart_index) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index a544cbdfd7..2b2ef1ce19 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -4844,6 +4844,18 @@ static int riscv_set_or_write_register(struct target *target, keep_alive(); + if (regid == GDB_REGNO_PC) { + return riscv_set_or_write_register(target, GDB_REGNO_DPC, value, write_through); + } else if (regid == GDB_REGNO_PRIV) { + riscv_reg_t dcsr; + + if (riscv_get_register(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK) + return ERROR_FAIL; + dcsr = set_field(dcsr, CSR_DCSR_PRV, get_field(value, VIRT_PRIV_PRV)); + dcsr = set_field(dcsr, CSR_DCSR_V, get_field(value, VIRT_PRIV_V)); + return riscv_set_or_write_register(target, GDB_REGNO_DCSR, dcsr, write_through); + } + if (!target->reg_cache) { assert(!target_was_examined(target)); LOG_TARGET_DEBUG(target, @@ -4929,6 +4941,17 @@ int riscv_get_register(struct target *target, riscv_reg_t *value, keep_alive(); + 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)); LOG_TARGET_DEBUG(target, "No cache, reading %s from target",