aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2018-05-25 11:52:10 -0700
committerGitHub <noreply@github.com>2018-05-25 11:52:10 -0700
commitab7ab8a8675f21050cdd67b1198d85e579a4b9a1 (patch)
tree25c44aaba28a8d6fa8505dcce086c18971c6f1dd
parentc3ffbc66e6f3a5c005bc8b92380b34108ae649bb (diff)
parentb629bbeade8cb430be8d2b899fd521a02419e393 (diff)
downloadriscv-openocd-20180629.zip
riscv-openocd-20180629.tar.gz
riscv-openocd-20180629.tar.bz2
Merge pull request #261 from riscv/trigger_enumv20180629
Delay trigger enumeration until it's required.
-rw-r--r--src/target/riscv/riscv-013.c11
-rw-r--r--src/target/riscv/riscv.c11
-rw-r--r--src/target/riscv/riscv.h2
3 files changed, 19 insertions, 5 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 12194d6..ad3ef6e 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -1457,9 +1457,6 @@ static int examine(struct target *target)
return ERROR_FAIL;
}
- /* Then we check the number of triggers availiable to each hart. */
- riscv_enumerate_triggers(target);
-
/* Resumes all the harts, so the debugger can later pause them. */
/* TODO: Only do this if the harts were halted to start with. */
riscv_resume_all_harts(target);
@@ -1477,8 +1474,8 @@ static int examine(struct target *target)
riscv_count_harts(target));
for (int i = 0; i < riscv_count_harts(target); ++i) {
if (riscv_hart_enabled(target, i)) {
- LOG_INFO(" hart %d: XLEN=%d, misa=0x%" PRIx64 ", %d triggers", i,
- r->xlen[i], r->misa[i], r->trigger_count[i]);
+ LOG_INFO(" hart %d: XLEN=%d, misa=0x%" PRIx64, i, r->xlen[i],
+ r->misa[i]);
} else {
LOG_INFO(" hart %d: currently disabled", i);
}
@@ -2830,6 +2827,10 @@ static enum riscv_halt_reason riscv013_halt_reason(struct target *target)
case CSR_DCSR_CAUSE_SWBP:
return RISCV_HALT_BREAKPOINT;
case CSR_DCSR_CAUSE_TRIGGER:
+ /* We could get here before triggers are enumerated if a trigger was
+ * already set when we connected. Force enumeration now, which has the
+ * side effect of clearing any triggers we did not set. */
+ riscv_enumerate_triggers(target);
return RISCV_HALT_TRIGGER;
case CSR_DCSR_CAUSE_STEP:
return RISCV_HALT_SINGLESTEP;
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 39f4903..a0270a3 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -407,6 +407,9 @@ static int add_trigger(struct target *target, struct trigger *trigger)
{
RISCV_INFO(r);
+ if (riscv_enumerate_triggers(target) != ERROR_OK)
+ return ERROR_FAIL;
+
/* In RTOS mode, we need to set the same trigger in the same slot on every
* hart, to keep up the illusion that each hart is a thread running on the
* same core. */
@@ -531,6 +534,9 @@ static int remove_trigger(struct target *target, struct trigger *trigger)
{
RISCV_INFO(r);
+ if (riscv_enumerate_triggers(target) != ERROR_OK)
+ return ERROR_FAIL;
+
int first_hart = -1;
for (int hartid = 0; hartid < riscv_count_harts(target); ++hartid) {
if (!riscv_hart_enabled(target, hartid))
@@ -1892,6 +1898,11 @@ int riscv_enumerate_triggers(struct target *target)
{
RISCV_INFO(r);
+ if (r->triggers_enumerated)
+ return ERROR_OK;
+
+ r->triggers_enumerated = true; /* At the very least we tried. */
+
for (int hartid = 0; hartid < riscv_count_harts(target); ++hartid) {
if (!riscv_hart_enabled(target, hartid))
continue;
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 63a3b79..1cc32f9 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -87,6 +87,8 @@ typedef struct {
/* This hart contains an implicit ebreak at the end of the program buffer. */
bool impebreak;
+ bool triggers_enumerated;
+
/* Helper functions that target the various RISC-V debug spec
* implementations. */
int (*get_register)(struct target *target,