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.
This commit is contained in:
parent
fe1280438b
commit
00b591a09a
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue