Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'riscv set_ir' command to set IR value for JTAG registers. #345

Merged
merged 1 commit into from
Jan 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/openocd.texi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 1 addition & 10 deletions src/target/riscv/riscv-013.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
37 changes: 34 additions & 3 deletions src/target/riscv/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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
};

Expand Down
6 changes: 3 additions & 3 deletions src/target/riscv/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down