aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarius Rad <darius@bluespec.com>2019-01-08 13:30:26 -0500
committerDarius Rad <darius@bluespec.com>2019-01-09 17:20:39 -0500
commit00b591a09a6a56adb5e33381a3803a973bd50ef0 (patch)
tree42bc7d95b9cd484c859138795e0b0cde2413e239
parentfe1280438b9b069cd7711d9c5ba01bc8032465ef (diff)
downloadriscv-openocd-00b591a09a6a56adb5e33381a3803a973bd50ef0.zip
riscv-openocd-00b591a09a6a56adb5e33381a3803a973bd50ef0.tar.gz
riscv-openocd-00b591a09a6a56adb5e33381a3803a973bd50ef0.tar.bz2
Add 'riscv set_ir' command to set IR value for JTAG registers.
This allows using different TAP addresses, for example, if using BSCANE2 primitives on a Xilinx FPGA.
-rw-r--r--doc/openocd.texi11
-rw-r--r--src/target/riscv/riscv-013.c11
-rw-r--r--src/target/riscv/riscv.c37
-rw-r--r--src/target/riscv/riscv.h6
4 files changed, 49 insertions, 16 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 5992320..7914515 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -9145,6 +9145,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 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
+way of BSCANE2 primitives that only permit a limited selection of IR
+values.
+
+When utilizing version 0.11 of the RISC-V Debug Specification,
+@option{dtmcs} and @option{dmi} set the IR values for the DTMCONTROL
+and DBUS registers, respectively.
+@end deffn
+
@subsection RISC-V Authentication Commands
The following commands can be used to authenticate to a RISC-V system. Eg. a
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 87f3846..1ef7307 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -396,16 +396,7 @@ static void dump_field(int idle, const struct scan_field *field)
static void select_dmi(struct target *target)
{
- static uint8_t ir_dmi[1] = {DTM_DMI};
- struct scan_field field = {
- .num_bits = target->tap->ir_length,
- .out_value = ir_dmi,
- .in_value = NULL,
- .check_value = NULL,
- .check_mask = NULL
- };
-
- jtag_add_ir_scan(target->tap, &field, TAP_IDLE);
+ jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
}
static uint32_t dtmcontrol_scan(struct target *target, uint32_t out)
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index ee576b9..6e56218 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -154,17 +154,17 @@ typedef enum slot {
#define MAX_HWBPS 16
#define DRAM_CACHE_SIZE 16
-uint8_t ir_dtmcontrol[1] = {DTMCONTROL};
+uint8_t ir_dtmcontrol[4] = {DTMCONTROL};
struct scan_field select_dtmcontrol = {
.in_value = NULL,
.out_value = ir_dtmcontrol
};
-uint8_t ir_dbus[1] = {DBUS};
+uint8_t ir_dbus[4] = {DBUS};
struct scan_field select_dbus = {
.in_value = NULL,
.out_value = ir_dbus
};
-uint8_t ir_idcode[1] = {0x1};
+uint8_t ir_idcode[4] = {0x1};
struct scan_field select_idcode = {
.in_value = NULL,
.out_value = ir_idcode
@@ -1626,6 +1626,30 @@ COMMAND_HANDLER(riscv_reset_delays)
return ERROR_OK;
}
+COMMAND_HANDLER(riscv_set_ir)
+{
+ if (CMD_ARGC != 2) {
+ LOG_ERROR("Command takes exactly 2 arguments");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ uint32_t value;
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
+
+ if (!strcmp(CMD_ARGV[0], "idcode")) {
+ buf_set_u32(ir_idcode, 0, 32, value);
+ return ERROR_OK;
+ } 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")) {
+ buf_set_u32(ir_dbus, 0, 32, value);
+ return ERROR_OK;
+ } else {
+ return ERROR_FAIL;
+ }
+}
+
static const struct command_registration riscv_exec_command_handlers[] = {
{
.name = "test_compliance",
@@ -1725,6 +1749,13 @@ 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 = "set_ir",
+ .handler = riscv_set_ir,
+ .mode = COMMAND_ANY,
+ .usage = "riscv set_ir_idcode [idcode|dtmcs|dmi] value",
+ .help = "Set IR value for specified JTAG register."
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 4b6ab8c..59414fc 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -151,11 +151,11 @@ static inline riscv_info_t *riscv_info(const struct target *target)
{ return target->arch_info; }
#define RISCV_INFO(R) riscv_info_t *R = riscv_info(target);
-extern uint8_t ir_dtmcontrol[1];
+extern uint8_t ir_dtmcontrol[4];
extern struct scan_field select_dtmcontrol;
-extern uint8_t ir_dbus[1];
+extern uint8_t ir_dbus[4];
extern struct scan_field select_dbus;
-extern uint8_t ir_idcode[1];
+extern uint8_t ir_idcode[4];
extern struct scan_field select_idcode;
/*** OpenOCD Interface */