Skip to content

Commit

Permalink
Add 'riscv set_ir' command to set IR value for JTAG registers.
Browse files Browse the repository at this point in the history
This allows using different TAP addresses, for example, if using
BSCANE2 primitives on a Xilinx FPGA.
  • Loading branch information
darius-bluespec committed Jan 9, 2019
1 parent afb450a commit 0b50ba6
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 16 deletions.
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
40 changes: 37 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 @@ -1608,6 +1608,33 @@ COMMAND_HANDLER(riscv_test_sba_config_reg)
}
}

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 @@ -1697,6 +1724,13 @@ static const struct command_registration riscv_exec_command_handlers[] = {
", an illegal, 128-byte aligned address for error flag/handling cases,"
"and whether sbbusyerror test should be run."
},
{
.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 @@ -147,11 +147,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

0 comments on commit 0b50ba6

Please sign in to comment.