aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2018-02-19 13:42:50 -0800
committerGitHub <noreply@github.com>2018-02-19 13:42:50 -0800
commit352e6b82ed463bc8997d3fa5da268f7b08f14741 (patch)
treeaad702c874233afcac08aee116a66b771c9e9ad2
parent6cbb45f7f1eb04470f69472917cb986a238deee4 (diff)
parentace6b7e49ac0b54961fd363343c702b1c5172062 (diff)
downloadriscv-openocd-352e6b82ed463bc8997d3fa5da268f7b08f14741.zip
riscv-openocd-352e6b82ed463bc8997d3fa5da268f7b08f14741.tar.gz
riscv-openocd-352e6b82ed463bc8997d3fa5da268f7b08f14741.tar.bz2
Merge pull request #208 from riscv/run_from_trigger
Handle resuming from a trigger...
-rw-r--r--src/rtos/riscv_debug.c2
-rw-r--r--src/target/riscv/riscv-013.c3
-rw-r--r--src/target/riscv/riscv.c63
-rw-r--r--src/target/riscv/riscv.h6
4 files changed, 52 insertions, 22 deletions
diff --git a/src/rtos/riscv_debug.c b/src/rtos/riscv_debug.c
index b1a714d..90caf40 100644
--- a/src/rtos/riscv_debug.c
+++ b/src/rtos/riscv_debug.c
@@ -248,7 +248,7 @@ static int riscv_gdb_v_packet(struct connection *connection, const char *packet,
if (strcmp(packet_stttrr, "vCont;c") == 0) {
target_call_event_callbacks(target, TARGET_EVENT_GDB_START);
target_call_event_callbacks(target, TARGET_EVENT_RESUME_START);
- riscv_resume_all_harts(target);
+ riscv_openocd_resume(target, 1, 0, 0, 0);
target->state = TARGET_RUNNING;
gdb_set_frontend_state_running(connection);
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 6b03fd9..e136c98 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -2039,8 +2039,9 @@ static enum riscv_halt_reason riscv013_halt_reason(struct target *target)
switch (get_field(dcsr, CSR_DCSR_CAUSE)) {
case CSR_DCSR_CAUSE_SWBP:
- case CSR_DCSR_CAUSE_TRIGGER:
return RISCV_HALT_BREAKPOINT;
+ case CSR_DCSR_CAUSE_TRIGGER:
+ return RISCV_HALT_TRIGGER;
case CSR_DCSR_CAUSE_STEP:
return RISCV_HALT_SINGLESTEP;
case CSR_DCSR_CAUSE_DEBUGINT:
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index f8a2739..03fa46b 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -640,6 +640,7 @@ static int old_or_new_riscv_step(
int handle_breakpoints
){
RISCV_INFO(r);
+ LOG_DEBUG("handle_breakpoints=%d", handle_breakpoints);
if (r->is_halted == NULL)
return oldriscv_step(target, current, address, handle_breakpoints);
else
@@ -728,6 +729,7 @@ static int old_or_new_riscv_resume(
int debug_execution
){
RISCV_INFO(r);
+ LOG_DEBUG("handle_breakpoints=%d", handle_breakpoints);
if (r->is_halted == NULL)
return oldriscv_resume(target, current, address, handle_breakpoints, debug_execution);
else
@@ -1027,6 +1029,9 @@ int riscv_openocd_poll(struct target *target)
case RISCV_HALT_BREAKPOINT:
target->debug_reason = DBG_REASON_BREAKPOINT;
break;
+ case RISCV_HALT_TRIGGER:
+ target->debug_reason = DBG_REASON_WATCHPOINT;
+ break;
case RISCV_HALT_INTERRUPT:
target->debug_reason = DBG_REASON_DBGRQ;
break;
@@ -1077,13 +1082,53 @@ int riscv_openocd_resume(
int current,
target_addr_t address,
int handle_breakpoints,
- int debug_execution
-) {
- LOG_DEBUG("resuming all harts");
+ int debug_execution)
+{
+ LOG_DEBUG("debug_reason=%d", target->debug_reason);
if (!current)
riscv_set_register(target, GDB_REGNO_PC, address);
+ if (target->debug_reason == DBG_REASON_WATCHPOINT) {
+ /* To be able to run off a trigger, disable all the triggers, step, and
+ * then resume as usual. */
+ struct watchpoint *watchpoint = target->watchpoints;
+ bool trigger_temporarily_cleared[RISCV_MAX_HWBPS] = {0};
+
+ int i = 0;
+ int result = ERROR_OK;
+ while (watchpoint && result == ERROR_OK) {
+ LOG_DEBUG("watchpoint %d: set=%d", i, watchpoint->set);
+ trigger_temporarily_cleared[i] = watchpoint->set;
+ if (watchpoint->set) {
+ result = riscv_remove_watchpoint(target, watchpoint);
+ }
+ watchpoint = watchpoint->next;
+ i++;
+ }
+
+ if (result == ERROR_OK) {
+ result = riscv_step_rtos_hart(target);
+ }
+
+ watchpoint = target->watchpoints;
+ i = 0;
+ while (watchpoint) {
+ LOG_DEBUG("watchpoint %d: cleared=%d", i, trigger_temporarily_cleared[i]);
+ if (trigger_temporarily_cleared[i]) {
+ if (result == ERROR_OK)
+ result = riscv_add_watchpoint(target, watchpoint);
+ else
+ riscv_add_watchpoint(target, watchpoint);
+ }
+ watchpoint = watchpoint->next;
+ i++;
+ }
+
+ if (result != ERROR_OK)
+ return result;
+ }
+
int out = riscv_resume_all_harts(target);
if (out != ERROR_OK) {
LOG_ERROR("unable to resume all harts");
@@ -1601,18 +1646,6 @@ enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid)
return r->halt_reason(target);
}
-int riscv_count_triggers(struct target *target)
-{
- return riscv_count_triggers_of_hart(target, riscv_current_hartid(target));
-}
-
-int riscv_count_triggers_of_hart(struct target *target, int hartid)
-{
- RISCV_INFO(r);
- assert(hartid < riscv_count_harts(target));
- return r->trigger_count[hartid];
-}
-
size_t riscv_debug_buffer_size(struct target *target)
{
RISCV_INFO(r);
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 5d3a212..478731d 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -30,6 +30,7 @@ enum riscv_halt_reason {
RISCV_HALT_INTERRUPT,
RISCV_HALT_BREAKPOINT,
RISCV_HALT_SINGLESTEP,
+ RISCV_HALT_TRIGGER,
RISCV_HALT_UNKNOWN
};
@@ -216,11 +217,6 @@ int riscv_get_register_on_hart(struct target *target, riscv_reg_t *value,
bool riscv_is_halted(struct target *target);
enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid);
-/* Returns the number of triggers availiable to either the current hart or to
- * the given hart. */
-int riscv_count_triggers(struct target *target);
-int riscv_count_triggers_of_hart(struct target *target, int hartid);
-
/* These helper functions let the generic program interface get target-specific
* information. */
size_t riscv_debug_buffer_size(struct target *target);