From dc49ed8ae25b6ac99f11864ce0ec83a2589b4ad8 Mon Sep 17 00:00:00 2001 From: Evgeniy Naydanov <109669442+en-sc@users.noreply.github.com> Date: Tue, 15 Nov 2022 19:52:13 +0300 Subject: [PATCH] Workaround for fp register access in case fp unit is disabled (#766) On some boards there is a HW bug: if fp unit is disabled (fs in mstatus set to 0), accessing any fp register results in a hang (any abstract command timeouts, untill the board is rebooted). Signed-off-by: Evgeniy Naydanov Change-Id: I0c0d1033889f15dcc326c4078bf9cbb5a8558565 Signed-off-by: Evgeniy Naydanov --- src/target/riscv/riscv-013.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index e5a9d3354..cdb6bc252 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1304,6 +1304,10 @@ static int register_write_direct(struct target *target, unsigned number, { LOG_TARGET_DEBUG(target, "%s <- 0x%" PRIx64, gdb_regno_name(number), value); + uint64_t mstatus; + if (prep_for_register_access(target, &mstatus, number) != ERROR_OK) + return ERROR_FAIL; + int result = register_write_abstract(target, number, value, register_size(target, number)); if (result == ERROR_OK || !has_sufficient_progbuf(target, 2)) @@ -1315,10 +1319,6 @@ static int register_write_direct(struct target *target, unsigned number, if (riscv_save_register(target, GDB_REGNO_S0) != ERROR_OK) return ERROR_FAIL; - uint64_t mstatus; - if (prep_for_register_access(target, &mstatus, number) != ERROR_OK) - return ERROR_FAIL; - scratch_mem_t scratch; bool use_scratch = false; if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 && @@ -1406,6 +1406,10 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t if (dm013_select_target(target) != ERROR_OK) return ERROR_FAIL; + uint64_t mstatus; + if (prep_for_register_access(target, &mstatus, number) != ERROR_OK) + return ERROR_FAIL; + int result = register_read_abstract(target, value, number, register_size(target, number)); @@ -1423,10 +1427,6 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t /* Write program to move data into s0. */ - uint64_t mstatus; - if (prep_for_register_access(target, &mstatus, number) != ERROR_OK) - return ERROR_FAIL; - if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) { if (riscv_supports_extension(target, 'D') && riscv_xlen(target) < 64) { @@ -1475,11 +1475,11 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t if (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK) return ERROR_FAIL; } - - if (cleanup_after_register_access(target, mstatus, number) != ERROR_OK) - return ERROR_FAIL; } + if (cleanup_after_register_access(target, mstatus, number) != ERROR_OK) + return ERROR_FAIL; + if (result == ERROR_OK) LOG_TARGET_DEBUG(target, "%s = 0x%" PRIx64, gdb_regno_name(number), *value);