Merge pull request #208 from riscv/run_from_trigger
Handle resuming from a trigger...
This commit is contained in:
commit
352e6b82ed
|
@ -248,7 +248,7 @@ static int riscv_gdb_v_packet(struct connection *connection, const char *packet,
|
||||||
if (strcmp(packet_stttrr, "vCont;c") == 0) {
|
if (strcmp(packet_stttrr, "vCont;c") == 0) {
|
||||||
target_call_event_callbacks(target, TARGET_EVENT_GDB_START);
|
target_call_event_callbacks(target, TARGET_EVENT_GDB_START);
|
||||||
target_call_event_callbacks(target, TARGET_EVENT_RESUME_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;
|
target->state = TARGET_RUNNING;
|
||||||
gdb_set_frontend_state_running(connection);
|
gdb_set_frontend_state_running(connection);
|
||||||
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
|
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
|
||||||
|
|
|
@ -2039,8 +2039,9 @@ static enum riscv_halt_reason riscv013_halt_reason(struct target *target)
|
||||||
|
|
||||||
switch (get_field(dcsr, CSR_DCSR_CAUSE)) {
|
switch (get_field(dcsr, CSR_DCSR_CAUSE)) {
|
||||||
case CSR_DCSR_CAUSE_SWBP:
|
case CSR_DCSR_CAUSE_SWBP:
|
||||||
case CSR_DCSR_CAUSE_TRIGGER:
|
|
||||||
return RISCV_HALT_BREAKPOINT;
|
return RISCV_HALT_BREAKPOINT;
|
||||||
|
case CSR_DCSR_CAUSE_TRIGGER:
|
||||||
|
return RISCV_HALT_TRIGGER;
|
||||||
case CSR_DCSR_CAUSE_STEP:
|
case CSR_DCSR_CAUSE_STEP:
|
||||||
return RISCV_HALT_SINGLESTEP;
|
return RISCV_HALT_SINGLESTEP;
|
||||||
case CSR_DCSR_CAUSE_DEBUGINT:
|
case CSR_DCSR_CAUSE_DEBUGINT:
|
||||||
|
|
|
@ -640,6 +640,7 @@ static int old_or_new_riscv_step(
|
||||||
int handle_breakpoints
|
int handle_breakpoints
|
||||||
){
|
){
|
||||||
RISCV_INFO(r);
|
RISCV_INFO(r);
|
||||||
|
LOG_DEBUG("handle_breakpoints=%d", handle_breakpoints);
|
||||||
if (r->is_halted == NULL)
|
if (r->is_halted == NULL)
|
||||||
return oldriscv_step(target, current, address, handle_breakpoints);
|
return oldriscv_step(target, current, address, handle_breakpoints);
|
||||||
else
|
else
|
||||||
|
@ -728,6 +729,7 @@ static int old_or_new_riscv_resume(
|
||||||
int debug_execution
|
int debug_execution
|
||||||
){
|
){
|
||||||
RISCV_INFO(r);
|
RISCV_INFO(r);
|
||||||
|
LOG_DEBUG("handle_breakpoints=%d", handle_breakpoints);
|
||||||
if (r->is_halted == NULL)
|
if (r->is_halted == NULL)
|
||||||
return oldriscv_resume(target, current, address, handle_breakpoints, debug_execution);
|
return oldriscv_resume(target, current, address, handle_breakpoints, debug_execution);
|
||||||
else
|
else
|
||||||
|
@ -1027,6 +1029,9 @@ int riscv_openocd_poll(struct target *target)
|
||||||
case RISCV_HALT_BREAKPOINT:
|
case RISCV_HALT_BREAKPOINT:
|
||||||
target->debug_reason = DBG_REASON_BREAKPOINT;
|
target->debug_reason = DBG_REASON_BREAKPOINT;
|
||||||
break;
|
break;
|
||||||
|
case RISCV_HALT_TRIGGER:
|
||||||
|
target->debug_reason = DBG_REASON_WATCHPOINT;
|
||||||
|
break;
|
||||||
case RISCV_HALT_INTERRUPT:
|
case RISCV_HALT_INTERRUPT:
|
||||||
target->debug_reason = DBG_REASON_DBGRQ;
|
target->debug_reason = DBG_REASON_DBGRQ;
|
||||||
break;
|
break;
|
||||||
|
@ -1077,13 +1082,53 @@ int riscv_openocd_resume(
|
||||||
int current,
|
int current,
|
||||||
target_addr_t address,
|
target_addr_t address,
|
||||||
int handle_breakpoints,
|
int handle_breakpoints,
|
||||||
int debug_execution
|
int debug_execution)
|
||||||
) {
|
{
|
||||||
LOG_DEBUG("resuming all harts");
|
LOG_DEBUG("debug_reason=%d", target->debug_reason);
|
||||||
|
|
||||||
if (!current)
|
if (!current)
|
||||||
riscv_set_register(target, GDB_REGNO_PC, address);
|
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);
|
int out = riscv_resume_all_harts(target);
|
||||||
if (out != ERROR_OK) {
|
if (out != ERROR_OK) {
|
||||||
LOG_ERROR("unable to resume all harts");
|
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);
|
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)
|
size_t riscv_debug_buffer_size(struct target *target)
|
||||||
{
|
{
|
||||||
RISCV_INFO(r);
|
RISCV_INFO(r);
|
||||||
|
|
|
@ -30,6 +30,7 @@ enum riscv_halt_reason {
|
||||||
RISCV_HALT_INTERRUPT,
|
RISCV_HALT_INTERRUPT,
|
||||||
RISCV_HALT_BREAKPOINT,
|
RISCV_HALT_BREAKPOINT,
|
||||||
RISCV_HALT_SINGLESTEP,
|
RISCV_HALT_SINGLESTEP,
|
||||||
|
RISCV_HALT_TRIGGER,
|
||||||
RISCV_HALT_UNKNOWN
|
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);
|
bool riscv_is_halted(struct target *target);
|
||||||
enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid);
|
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
|
/* These helper functions let the generic program interface get target-specific
|
||||||
* information. */
|
* information. */
|
||||||
size_t riscv_debug_buffer_size(struct target *target);
|
size_t riscv_debug_buffer_size(struct target *target);
|
||||||
|
|
Loading…
Reference in New Issue