diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 12194d6d7..ad3ef6eae 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 39f49037d..a0270a3e2 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 63a3b79ef..1cc32f950 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,