aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2017-02-14 12:55:03 -0800
committerTim Newsome <tim@sifive.com>2017-02-14 12:55:03 -0800
commitceb8dc048d1bb5793bd9fc6ec64feaf1825a0f3c (patch)
treec1c25716bf7143bc425b1988108b406c1a615807
parentae4fda27194729575cbd1b95149eed9f31c03e2c (diff)
downloadriscv-openocd-ceb8dc048d1bb5793bd9fc6ec64feaf1825a0f3c.zip
riscv-openocd-ceb8dc048d1bb5793bd9fc6ec64feaf1825a0f3c.tar.gz
riscv-openocd-ceb8dc048d1bb5793bd9fc6ec64feaf1825a0f3c.tar.bz2
Make general CSR reads work.
Change-Id: Ic9b7e065b7303b3707c28c9b7c496cc1c1e91acd
-rw-r--r--src/target/riscv/riscv-013.c58
1 files changed, 22 insertions, 36 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 20b0e44..3ae63fd 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -1146,6 +1146,7 @@ static int abstract_write_register(struct target *target,
return ERROR_OK;
}
+/** csr is the CSR index between 0 and 4096. */
static int read_csr(struct target *target, uint64_t *value, uint32_t csr)
{
int result = abstract_read_register(target, csr, xlen(target), value);
@@ -1320,6 +1321,15 @@ static int resume(struct target *target, int debug_execution, bool step)
return execute_resume(target, step);
}
+static void reg_cache_set(struct target *target, unsigned int number,
+ uint64_t value)
+{
+ struct reg *r = &target->reg_cache->reg_list[number];
+ LOG_DEBUG("%s <= 0x%" PRIx64, r->name, value);
+ r->valid = true;
+ buf_set_u64(r->value, 0, r->size, value);
+}
+
/** Update register sizes based on xlen. */
static void update_reg_list(struct target *target)
{
@@ -1342,6 +1352,8 @@ static void update_reg_list(struct target *target)
}
r->valid = false;
}
+
+ reg_cache_set(target, ZERO, 0);
}
static uint64_t reg_cache_get(struct target *target, unsigned int number)
@@ -1356,15 +1368,6 @@ static uint64_t reg_cache_get(struct target *target, unsigned int number)
return value;
}
-static void reg_cache_set(struct target *target, unsigned int number,
- uint64_t value)
-{
- struct reg *r = &target->reg_cache->reg_list[number];
- LOG_DEBUG("%s <= 0x%" PRIx64, r->name, value);
- r->valid = true;
- buf_set_u64(r->value, 0, r->size, value);
-}
-
static int update_mstatus_actual(struct target *target)
{
struct reg *mstatus_reg = &target->reg_cache->reg_list[REG_MSTATUS];
@@ -1387,6 +1390,8 @@ static int register_get(struct reg *reg)
maybe_write_tselect(target);
+ int result = ERROR_OK;
+ uint64_t value;
if (reg->number <= REG_XPR31) {
buf_set_u64(reg->value, 0, xlen(target), reg_cache_get(target, reg->number));
LOG_DEBUG("%s=0x%" PRIx64, reg->name, reg_cache_get(target, reg->number));
@@ -1397,7 +1402,7 @@ static int register_get(struct reg *reg)
LOG_DEBUG("%s=0x%" PRIx64 " (cached)", reg->name, info->dpc);
return ERROR_OK;
} else if (reg->number >= REG_FPR0 && reg->number <= REG_FPR31) {
- int result = update_mstatus_actual(target);
+ result = update_mstatus_actual(target);
if (result != ERROR_OK) {
return result;
}
@@ -1416,9 +1421,7 @@ static int register_get(struct reg *reg)
}
cache_set_jump(target, i++);
} else if (reg->number >= REG_CSR0 && reg->number <= REG_CSR4095) {
- cache_set32(target, 0, csrr(S0, reg->number - REG_CSR0));
- cache_set_store(target, 1, S0, SLOT0);
- cache_set_jump(target, 2);
+ result = read_csr(target, &value, reg->number - REG_CSR0);
} else if (reg->number == REG_PRIV) {
buf_set_u64(reg->value, 0, 8, get_field(info->dcsr, DCSR_PRV));
LOG_DEBUG("%s=%d (cached)", reg->name,
@@ -1429,19 +1432,9 @@ static int register_get(struct reg *reg)
return ERROR_FAIL;
}
- if (cache_write(target, 4, true) != ERROR_OK) {
- return ERROR_FAIL;
- }
-
- uint32_t exception = cache_get32(target, info->dramsize-1);
- if (exception) {
- LOG_ERROR("Got exception 0x%x when reading register %d", exception,
- reg->number);
- buf_set_u64(reg->value, 0, xlen(target), ~0);
- return ERROR_FAIL;
- }
+ if (result != ERROR_OK)
+ return result;
- uint64_t value = cache_get(target, SLOT0);
LOG_DEBUG("%s=0x%" PRIx64, reg->name, value);
buf_set_u64(reg->value, 0, xlen(target), value);
@@ -1548,15 +1541,7 @@ static int halt(struct target *target)
LOG_DEBUG("riscv_halt()");
select_dmi(target);
- cache_set32(target, 0, csrsi(CSR_DCSR, DCSR_HALT));
- cache_set32(target, 1, csrr(S0, CSR_MHARTID));
- cache_set32(target, 2, sw(S0, ZERO, SETHALTNOT));
- cache_set_jump(target, 3);
-
- if (cache_write(target, 4, true) != ERROR_OK) {
- LOG_ERROR("cache_write() failed.");
- return ERROR_FAIL;
- }
+ dmi_write(target, DMI_DMCONTROL, DMI_DMCONTROL_HALTREQ | DMI_DMCONTROL_DMACTIVE);
return ERROR_OK;
}
@@ -1957,8 +1942,9 @@ static int examine(struct target *target)
}
// Reset the Debug Module.
- dmi_write(target, DMI_DMCONTROL, 0);
- dmi_write(target, DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE);
+ dmi_write(target, DMI_DMCONTROL, dmcontrol & DMI_DMCONTROL_HALTREQ);
+ dmi_write(target, DMI_DMCONTROL, (dmcontrol & DMI_DMCONTROL_HALTREQ) |
+ DMI_DMCONTROL_DMACTIVE);
dmcontrol = dmi_read(target, DMI_DMCONTROL);
LOG_DEBUG("dmcontrol: 0x%08x", dmcontrol);