Merge pull request #208 from riscv/run_from_trigger

Handle resuming from a trigger...
sba_tests
Tim Newsome 2018-02-19 13:42:50 -08:00 committed by GitHub
commit 352e6b82ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 22 deletions

View File

@ -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);

View File

@ -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:

View File

@ -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);

View File

@ -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);