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: I39852aedec293294b2b2638ab2cc45494fe77bebdebug-log-reg-failure
parent
c5dee66a71
commit
6983eda0e9
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue