Merge pull request #100 from riscv/riscv_timeout_commands

riscv: Add commands for setting timeouts
macbuild
Tim Newsome 2017-08-25 09:49:15 -07:00 committed by GitHub
commit 4d0e88d887
4 changed files with 132 additions and 49 deletions

View File

@ -154,7 +154,6 @@ typedef enum slot {
/*** Info about the core being debugged. ***/
#define DBUS_ADDRESS_UNKNOWN 0xffff
#define WALL_CLOCK_TIMEOUT 2
// gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in
// its source tree. We must interpret the numbers the same here.
@ -730,8 +729,9 @@ static int wait_for_debugint_clear(struct target *target, bool ignore_first)
if (!bits.interrupt) {
return ERROR_OK;
}
if (time(NULL) - start > WALL_CLOCK_TIMEOUT) {
LOG_ERROR("Timed out waiting for debug int to clear.");
if (time(NULL) - start > riscv_command_timeout_sec) {
LOG_ERROR("Timed out waiting for debug int to clear."
"Increase timeout with riscv set_command_timeout_sec.");
return ERROR_FAIL;
}
}
@ -1016,8 +1016,9 @@ static int wait_for_state(struct target *target, enum target_state state)
if (target->state == state) {
return ERROR_OK;
}
if (time(NULL) - start > WALL_CLOCK_TIMEOUT) {
LOG_ERROR("Timed out waiting for state %d.", state);
if (time(NULL) - start > riscv_command_timeout_sec) {
LOG_ERROR("Timed out waiting for state %d. "
"Increase timeout with riscv set_command_timeout_sec.", state);
return ERROR_FAIL;
}
}
@ -1174,8 +1175,9 @@ static int full_step(struct target *target, bool announce)
return result;
if (target->state != TARGET_DEBUG_RUNNING)
break;
if (time(NULL) - start > WALL_CLOCK_TIMEOUT) {
LOG_ERROR("Timed out waiting for step to complete.");
if (time(NULL) - start > riscv_command_timeout_sec) {
LOG_ERROR("Timed out waiting for step to complete."
"Increase timeout with riscv set_command_timeout_sec");
return ERROR_FAIL;
}
}
@ -1471,6 +1473,7 @@ static int init_target(struct command_context *cmd_ctx,
riscv_info_t *generic_info = (riscv_info_t *) target->arch_info;
generic_info->get_register = get_register;
generic_info->set_register = set_register;
generic_info->version_specific = calloc(1, sizeof(riscv011_info_t));
if (!generic_info->version_specific)
return ERROR_FAIL;

View File

@ -121,9 +121,6 @@ typedef enum slot {
/*** Info about the core being debugged. ***/
#define WALL_CLOCK_TIMEOUT 2
#define WALL_CLOCK_RESET_TIMEOUT 30
struct trigger {
uint64_t address;
uint32_t length;
@ -562,7 +559,7 @@ static int wait_for_idle(struct target *target, uint32_t *abstractcs)
return ERROR_OK;
}
if (time(NULL) - start > WALL_CLOCK_TIMEOUT) {
if (time(NULL) - start > riscv_command_timeout_sec) {
info->cmderr = get_field(*abstractcs, DMI_ABSTRACTCS_CMDERR);
if (info->cmderr != CMDERR_NONE) {
const char *errors[8] = {
@ -579,7 +576,9 @@ static int wait_for_idle(struct target *target, uint32_t *abstractcs)
errors[info->cmderr], *abstractcs);
}
LOG_ERROR("Timed out waiting for busy to go low. (abstractcs=0x%x)",
LOG_ERROR("Timed out after %ds waiting for busy to go low. (abstractcs=0x%x)"
"Increase the timeout with riscv set_command_timeout_sec.",
riscv_command_timeout_sec,
*abstractcs);
return ERROR_FAIL;
}
@ -909,7 +908,6 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->fill_dmi_nop_u64 = &riscv013_fill_dmi_nop_u64;
generic_info->dmi_write_u64_bits = &riscv013_dmi_write_u64_bits;
generic_info->reset_current_hart = &riscv013_reset_current_hart;
generic_info->version_specific = calloc(1, sizeof(riscv013_info_t));
if (!generic_info->version_specific)
return ERROR_FAIL;
@ -1918,9 +1916,11 @@ void riscv013_reset_current_hart(struct target *target)
if (get_field(dmstatus, DMI_DMSTATUS_ALLHALTED)) {
break;
}
if (time(NULL) - start > WALL_CLOCK_RESET_TIMEOUT) {
if (time(NULL) - start > riscv_reset_timeout_sec) {
LOG_ERROR("Hart didn't halt coming out of reset in %ds; "
"dmstatus=0x%x", WALL_CLOCK_RESET_TIMEOUT, dmstatus);
"dmstatus=0x%x"
"Increase the timeout with riscv set_reset_timeout_sec.",
riscv_reset_timeout_sec, dmstatus);
return;
}
}

View File

@ -150,7 +150,6 @@ typedef enum slot {
/*** Info about the core being debugged. ***/
#define DBUS_ADDRESS_UNKNOWN 0xffff
#define WALL_CLOCK_TIMEOUT 2
// gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in
// its source tree. We must interpret the numbers the same here.
@ -195,6 +194,12 @@ struct trigger {
int unique_id;
};
/* Wall-clock timeout for a command/access. Settable via RISC-V Target commands.*/
int riscv_command_timeout_sec = DEFAULT_COMMAND_TIMEOUT_SEC;
/* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/
int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC;
static uint32_t dtmcontrol_scan(struct target *target, uint32_t out)
{
struct scan_field field;
@ -1132,6 +1137,71 @@ int riscv_openocd_deassert_reset(struct target *target)
return ERROR_OK;
}
/* Command Handlers */
COMMAND_HANDLER(riscv_set_command_timeout_sec) {
if (CMD_ARGC != 1) {
LOG_ERROR("Command takes exactly 1 parameter");
return ERROR_COMMAND_SYNTAX_ERROR;
}
int timeout = atoi(CMD_ARGV[0]);
if (timeout <= 0){
LOG_ERROR("%s is not a valid integer argument for command.", CMD_ARGV[0]);
return ERROR_FAIL;
}
riscv_command_timeout_sec = timeout;
return ERROR_OK;
}
COMMAND_HANDLER(riscv_set_reset_timeout_sec) {
if (CMD_ARGC != 1) {
LOG_ERROR("Command takes exactly 1 parameter");
return ERROR_COMMAND_SYNTAX_ERROR;
}
int timeout = atoi(CMD_ARGV[0]);
if (timeout <= 0){
LOG_ERROR("%s is not a valid integer argument for command.", CMD_ARGV[0]);
return ERROR_FAIL;
}
riscv_reset_timeout_sec = timeout;
return ERROR_OK;
}
static const struct command_registration riscv_exec_command_handlers[] = {
{
.name = "set_command_timeout_sec",
.handler = riscv_set_command_timeout_sec,
.mode = COMMAND_ANY,
.usage = "riscv set_command_timeout_sec [sec]",
.help = "Set the wall-clock timeout (in seconds) for individual commands"
},
{
.name = "set_reset_timeout_sec",
.handler = riscv_set_reset_timeout_sec,
.mode = COMMAND_ANY,
.usage = "riscv set_reset_timeout_sec [sec]",
.help = "Set the wall-clock timeout (in seconds) after reset is deasserted"
},
COMMAND_REGISTRATION_DONE
};
const struct command_registration riscv_command_handlers[] = {
{
.name = "riscv",
.mode = COMMAND_ANY,
.help = "RISC-V Command Group",
.usage = "",
.chain = riscv_exec_command_handlers
},
COMMAND_REGISTRATION_DONE
};
struct target_type riscv_target =
{
.name = "riscv",
@ -1167,6 +1237,8 @@ struct target_type riscv_target =
.arch_state = riscv_arch_state,
.run_algorithm = riscv_run_algorithm,
.commands = riscv_command_handlers
};
/*** RISC-V Interface ***/
@ -1576,7 +1648,6 @@ int riscv_enumerate_triggers(struct target *target)
tselect_rb &= ~(1ULL << (riscv_xlen(target)-1));
if (tselect_rb != t)
break;
uint64_t tdata1 = riscv_get_register_on_hart(target, hartid,
GDB_REGNO_TDATA1);
int type = get_field(tdata1, MCONTROL_TYPE(riscv_xlen(target)));

View File

@ -13,6 +13,9 @@ struct riscv_program;
#define RISCV_MAX_TRIGGERS 32
#define RISCV_MAX_HWBPS 16
#define DEFAULT_COMMAND_TIMEOUT_SEC 2
#define DEFAULT_RESET_TIMEOUT_SEC 30
extern struct target_type riscv011_target;
extern struct target_type riscv013_target;
@ -103,6 +106,12 @@ typedef struct {
void (*reset_current_hart)(struct target *target);
} riscv_info_t;
/* Wall-clock timeout for a command/access. Settable via RISC-V Target commands.*/
extern int riscv_command_timeout_sec;
/* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/
extern int riscv_reset_timeout_sec;
/* Everything needs the RISC-V specific info structure, so here's a nice macro
* that provides that. */
static inline riscv_info_t *riscv_info(const struct target *target) __attribute__((unused));