aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2019-06-14 15:55:56 -0700
committerGitHub <noreply@github.com>2019-06-14 15:55:56 -0700
commitc05ad1a92a9379295f2e0eef481e88e89e4eff6f (patch)
tree186f4fc2221afae716e169187f8f126b64564762
parentfd9c54b1feea13f6846c69fc9e1e8dc3a7879717 (diff)
downloadriscv-openocd-c05ad1a92a9379295f2e0eef481e88e89e4eff6f.zip
riscv-openocd-c05ad1a92a9379295f2e0eef481e88e89e4eff6f.tar.gz
riscv-openocd-c05ad1a92a9379295f2e0eef481e88e89e4eff6f.tar.bz2
Set mstatus.FS to access FPU CSRs. (#380)
This improves behavior when executing function calls from mainline gdb. Change-Id: Ia37507a16cd76fc03d26457e84fd68402969c534
-rw-r--r--src/target/riscv/riscv-013.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 7f12779..0b60399 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -1311,6 +1311,14 @@ static int register_read(struct target *target, uint64_t *value, uint32_t number
return ERROR_OK;
}
+static int is_fpu_reg(uint32_t gdb_regno)
+{
+ return (gdb_regno >= GDB_REGNO_FPR0 && gdb_regno <= GDB_REGNO_FPR31) ||
+ (gdb_regno == GDB_REGNO_CSR0 + CSR_FFLAGS) ||
+ (gdb_regno == GDB_REGNO_CSR0 + CSR_FRM) ||
+ (gdb_regno == GDB_REGNO_CSR0 + CSR_FCSR);
+}
+
/** Actually read registers from the target right now. */
static int register_read_direct(struct target *target, uint64_t *value, uint32_t number)
{
@@ -1336,14 +1344,16 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
/* Write program to move data into s0. */
uint64_t mstatus;
- if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
+ if (is_fpu_reg(number)) {
if (register_read(target, &mstatus, GDB_REGNO_MSTATUS) != ERROR_OK)
return ERROR_FAIL;
if ((mstatus & MSTATUS_FS) == 0)
if (register_write_direct(target, GDB_REGNO_MSTATUS,
set_field(mstatus, MSTATUS_FS, 1)) != ERROR_OK)
return ERROR_FAIL;
+ }
+ if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
if (riscv_supports_extension(target, riscv_current_hartid(target), 'D')
&& riscv_xlen(target) < 64) {
/* There are no instructions to move all the bits from a
@@ -1388,8 +1398,7 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
return ERROR_FAIL;
}
- if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 &&
- (mstatus & MSTATUS_FS) == 0)
+ if (is_fpu_reg(number) && (mstatus & MSTATUS_FS) == 0)
if (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus) != ERROR_OK)
return ERROR_FAIL;