From 3a295420567c45ee85ff4c3e492ed7a3f7a6daf6 Mon Sep 17 00:00:00 2001 From: Evgeniy Naydanov Date: Tue, 16 May 2023 20:27:43 +0300 Subject: [PATCH] target/riscv: fix register access on running target Register access on running target should fail if mstatus needs to be modified. Change-Id: Iec8e8d514ef2f5ca42606a5534cce55aaaa99180 Signed-off-by: Evgeniy Naydanov --- src/target/riscv/riscv-013.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index b4e165595..9b0d292b5 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1087,13 +1087,8 @@ static int prep_for_register_access(struct target *target, LOG_TARGET_DEBUG(target, "Preparing mstatus to access %s", gdb_regno_name(regno)); - /* FIXME: On a running target, there is no way to make sure mstatus won't - * change between reading and writing it, so - * if target->state != TARGET_HALTED an error should be returned here. - * However, this would not allow access to FPU registers on the running - * target. - * See https://github.com/riscv/riscv-openocd/pull/842#discussion_r1178500114 - */ + assert(target->state == TARGET_HALTED && + "The target must be halted to modify and then restore mstatus"); if (riscv_get_register(target, orig_mstatus, GDB_REGNO_MSTATUS) != ERROR_OK) return ERROR_FAIL; @@ -1484,6 +1479,9 @@ static int register_write_direct(struct target *target, enum gdb_regno number, LOG_TARGET_DEBUG(target, "Writing 0x%" PRIx64 " to %s", value, gdb_regno_name(number)); + if (target->state != TARGET_HALTED) + return register_write_abstract(target, number, value); + riscv_reg_t mstatus; if (prep_for_register_access(target, &mstatus, number) != ERROR_OK) return ERROR_FAIL; @@ -1509,6 +1507,9 @@ static int register_read_direct(struct target *target, riscv_reg_t *value, { LOG_TARGET_DEBUG(target, "Reading %s", gdb_regno_name(number)); + if (target->state != TARGET_HALTED) + return register_read_abstract(target, value, number); + riscv_reg_t mstatus; if (prep_for_register_access(target, &mstatus, number) != ERROR_OK)