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.
|
use the Program Buffer to access memory.
|
||||||
@end deffn
|
@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]
|
@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
|
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
|
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. */
|
/* Same, but for custom registers. */
|
||||||
range_t *expose_custom;
|
range_t *expose_custom;
|
||||||
|
|
||||||
|
static enum {
|
||||||
|
RO_NORMAL,
|
||||||
|
RO_REVERSED
|
||||||
|
} resume_order;
|
||||||
|
|
||||||
static int riscv_resume_go_all_harts(struct target *target);
|
static int riscv_resume_go_all_harts(struct target *target);
|
||||||
|
|
||||||
void select_dmi_via_bscan(struct target *target)
|
void select_dmi_via_bscan(struct target *target)
|
||||||
|
@ -2141,18 +2146,35 @@ COMMAND_HANDLER(riscv_set_ir)
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], 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);
|
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);
|
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);
|
buf_set_u32(ir_dbus, 0, 32, value);
|
||||||
|
else
|
||||||
|
return ERROR_FAIL;
|
||||||
|
|
||||||
return ERROR_OK;
|
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 {
|
} else {
|
||||||
|
LOG_ERROR("Unsupported resume order: %s", CMD_ARGV[0]);
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_HANDLER(riscv_use_bscan_tunnel)
|
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 "
|
"command resets those learned values after `wait` scans. It's only "
|
||||||
"useful for testing OpenOCD itself."
|
"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",
|
.name = "set_ir",
|
||||||
.handler = riscv_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)
|
static int riscv_resume_go_all_harts(struct target *target)
|
||||||
{
|
{
|
||||||
RISCV_INFO(r);
|
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))
|
if (!riscv_hart_enabled(target, i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue