aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2017-07-16 12:47:41 -0700
committerGitHub <noreply@github.com>2017-07-16 12:47:41 -0700
commit79329f21a3f0b9bf0a26bf3c4eb46e5e12df579a (patch)
tree226434efa5d2cab02e76b2d7b498962ca1b2f1bd
parent43c6fd3b8feeb6a2b762d5dd183cd9e2284c3f32 (diff)
parentb032eb1bcc53d43c9cb7a7f04bf2d62ea39af26c (diff)
downloadriscv-openocd-79329f21a3f0b9bf0a26bf3c4eb46e5e12df579a.zip
riscv-openocd-79329f21a3f0b9bf0a26bf3c4eb46e5e12df579a.tar.gz
riscv-openocd-79329f21a3f0b9bf0a26bf3c4eb46e5e12df579a.tar.bz2
Merge pull request #84 from riscv/reset
Fix infinite loop in reset.
-rw-r--r--src/target/riscv/riscv-013.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index f82b9bc..4b0f71b 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -121,7 +121,8 @@ typedef enum slot {
/*** Info about the core being debugged. ***/
-#define WALL_CLOCK_TIMEOUT 2
+#define WALL_CLOCK_TIMEOUT 2
+#define WALL_CLOCK_RESET_TIMEOUT 30
struct trigger {
uint64_t address;
@@ -199,6 +200,14 @@ static void decode_dmi(char *text, unsigned address, unsigned data)
uint64_t mask;
const char *name;
} description[] = {
+ { DMI_DMCONTROL, DMI_DMCONTROL_HALTREQ, "haltreq" },
+ { DMI_DMCONTROL, DMI_DMCONTROL_RESUMEREQ, "resumereq" },
+ { DMI_DMCONTROL, DMI_DMCONTROL_HARTRESET, "hartreset" },
+ { DMI_DMCONTROL, DMI_DMCONTROL_HASEL, "hasel" },
+ { DMI_DMCONTROL, DMI_DMCONTROL_HARTSEL, "hartsel" },
+ { DMI_DMCONTROL, DMI_DMCONTROL_NDMRESET, "ndmreset" },
+ { DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE, "dmactive" },
+
{ DMI_DMSTATUS, DMI_DMSTATUS_ALLRESUMEACK, "allresumeack" },
{ DMI_DMSTATUS, DMI_DMSTATUS_ANYRESUMEACK, "anyresumeack" },
{ DMI_DMSTATUS, DMI_DMSTATUS_ALLNONEXISTENT, "allnonexistent" },
@@ -1874,7 +1883,19 @@ void riscv013_reset_current_hart(struct target *target)
control = set_field(control, DMI_DMCONTROL_NDMRESET, 0);
dmi_write(target, DMI_DMCONTROL, control);
- while (get_field(dmi_read(target, DMI_DMSTATUS), DMI_DMSTATUS_ALLHALTED) == 0);
+ time_t start = time(NULL);
+
+ while (1) {
+ uint32_t dmstatus = dmi_read(target, DMI_DMSTATUS);
+ if (get_field(dmstatus, DMI_DMSTATUS_ALLHALTED)) {
+ break;
+ }
+ if (time(NULL) - start > WALL_CLOCK_RESET_TIMEOUT) {
+ LOG_ERROR("Hart didn't halt coming out of reset in %ds; "
+ "dmstatus=0x%x", WALL_CLOCK_RESET_TIMEOUT, dmstatus);
+ return;
+ }
+ }
control = set_field(control, DMI_DMCONTROL_HALTREQ, 0);
dmi_write(target, DMI_DMCONTROL, control);