aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2019-07-15 10:32:28 -0700
committerGitHub <noreply@github.com>2019-07-15 10:32:28 -0700
commit6983eda0e9d83c49af1366f4363efb570f5b79bd (patch)
tree5c06e12ebbe4ae4e36bce80eeb9668afd6b39a94
parentc5dee66a71063bae612632c3a0889972a1963f2a (diff)
downloadriscv-openocd-6983eda0e9d83c49af1366f4363efb570f5b79bd.zip
riscv-openocd-6983eda0e9d83c49af1366f4363efb570f5b79bd.tar.gz
riscv-openocd-6983eda0e9d83c49af1366f4363efb570f5b79bd.tar.bz2
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
-rw-r--r--doc/openocd.texi11
-rw-r--r--src/target/riscv/riscv.c65
2 files changed, 69 insertions, 7 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 025e9e1..e70b53a 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -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
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 0218a98..2e3813d 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -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)
@@ -2281,6 +2303,15 @@ static const struct command_registration riscv_exec_command_handlers[] = {
"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,
.mode = COMMAND_ANY,
@@ -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;