Make resume order configurable. (#388)

* Make resume order configurable.

This is a customer requirement. Using this option is discouraged.

Change-Id: I520ec19cc23d7837cb8576f69dadf2b922fa2628

* Fix style.

Change-Id: If8e515984c92ce8df52aa69e87abde023897409f

* Make mingw32-gcc happy.

Change-Id: I39852aedec293294b2b2638ab2cc45494fe77beb
debug-log-reg-failure
Tim Newsome 2019-07-15 10:32:28 -07:00 committed by GitHub
parent c5dee66a71
commit 6983eda0e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 7 deletions

View File

@ -9491,6 +9491,17 @@ When on, prefer to use System Bus Access to access memory. When off, prefer to
use the Program Buffer to access memory.
@end deffn
@deffn Command {riscv resume_order} normal|reversed
Some software assumes all harts are executing nearly continuously. Such
software may be sensitive to the order that harts are resumed in. On harts
that don't support hasel, this option allows the user to choose the order the
harts are resumed in. If you are using this option, it's probably masking a
race condition problem in your code.
Normal order is from lowest hart index to highest. This is the default
behavior. Reversed order is from highest hart index to lowest.
@end deffn
@deffn Command {riscv set_ir} (@option{idcode}|@option{dtmcs}|@option{dmi}) [value]
Set the IR value for the specified JTAG register. This is useful, for
example, when using the existing JTAG interface on a Xilinx FPGA by

View File

@ -264,6 +264,11 @@ range_t *expose_csr;
/* Same, but for custom registers. */
range_t *expose_custom;
static enum {
RO_NORMAL,
RO_REVERSED
} resume_order;
static int riscv_resume_go_all_harts(struct target *target);
void select_dmi_via_bscan(struct target *target)
@ -2141,18 +2146,35 @@ COMMAND_HANDLER(riscv_set_ir)
uint32_t value;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
if (!strcmp(CMD_ARGV[0], "idcode")) {
if (!strcmp(CMD_ARGV[0], "idcode"))
buf_set_u32(ir_idcode, 0, 32, value);
return ERROR_OK;
} else if (!strcmp(CMD_ARGV[0], "dtmcs")) {
else if (!strcmp(CMD_ARGV[0], "dtmcs"))
buf_set_u32(ir_dtmcontrol, 0, 32, value);
return ERROR_OK;
} else if (!strcmp(CMD_ARGV[0], "dmi")) {
else if (!strcmp(CMD_ARGV[0], "dmi"))
buf_set_u32(ir_dbus, 0, 32, value);
return ERROR_OK;
else
return ERROR_FAIL;
return ERROR_OK;
}
COMMAND_HANDLER(riscv_resume_order)
{
if (CMD_ARGC > 1) {
LOG_ERROR("Command takes at most one argument");
return ERROR_COMMAND_SYNTAX_ERROR;
}
if (!strcmp(CMD_ARGV[0], "normal")) {
resume_order = RO_NORMAL;
} else if (!strcmp(CMD_ARGV[0], "reversed")) {
resume_order = RO_REVERSED;
} else {
LOG_ERROR("Unsupported resume order: %s", CMD_ARGV[0]);
return ERROR_FAIL;
}
return ERROR_OK;
}
COMMAND_HANDLER(riscv_use_bscan_tunnel)
@ -2280,6 +2302,15 @@ static const struct command_registration riscv_exec_command_handlers[] = {
"command resets those learned values after `wait` scans. It's only "
"useful for testing OpenOCD itself."
},
{
.name = "resume_order",
.handler = riscv_resume_order,
.mode = COMMAND_ANY,
.usage = "resume_order normal|reversed",
.help = "Choose the order that harts are resumed in when `hasel` is not "
"supported. Normal order is from lowest hart index to highest. "
"Reversed order is from highest hart index to lowest."
},
{
.name = "set_ir",
.handler = riscv_set_ir,
@ -2437,7 +2468,27 @@ void riscv_info_init(struct target *target, riscv_info_t *r)
static int riscv_resume_go_all_harts(struct target *target)
{
RISCV_INFO(r);
for (int i = 0; i < riscv_count_harts(target); ++i) {
/* Dummy variables to make mingw32-gcc happy. */
int first = 0;
int last = 1;
int step = 1;
switch (resume_order) {
case RO_NORMAL:
first = 0;
last = riscv_count_harts(target) - 1;
step = 1;
break;
case RO_REVERSED:
first = riscv_count_harts(target) - 1;
last = 0;
step = -1;
break;
default:
assert(0);
}
for (int i = first; i != last + step; i += step) {
if (!riscv_hart_enabled(target, i))
continue;