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.log_output
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.
|
use the Program Buffer to access memory.
|
||||||
@end deffn
|
@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
|
@subsection RISC-V Authentication Commands
|
||||||
|
|
||||||
The following commands can be used to authenticate to a RISC-V system. Eg. a
|
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 void select_dmi(struct target *target)
|
||||||
{
|
{
|
||||||
static uint8_t ir_dmi[1] = {DTM_DMI};
|
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t dtmcontrol_scan(struct target *target, uint32_t out)
|
static uint32_t dtmcontrol_scan(struct target *target, uint32_t out)
|
||||||
|
|
|
@ -154,17 +154,17 @@ typedef enum slot {
|
||||||
#define MAX_HWBPS 16
|
#define MAX_HWBPS 16
|
||||||
#define DRAM_CACHE_SIZE 16
|
#define DRAM_CACHE_SIZE 16
|
||||||
|
|
||||||
uint8_t ir_dtmcontrol[1] = {DTMCONTROL};
|
uint8_t ir_dtmcontrol[4] = {DTMCONTROL};
|
||||||
struct scan_field select_dtmcontrol = {
|
struct scan_field select_dtmcontrol = {
|
||||||
.in_value = NULL,
|
.in_value = NULL,
|
||||||
.out_value = ir_dtmcontrol
|
.out_value = ir_dtmcontrol
|
||||||
};
|
};
|
||||||
uint8_t ir_dbus[1] = {DBUS};
|
uint8_t ir_dbus[4] = {DBUS};
|
||||||
struct scan_field select_dbus = {
|
struct scan_field select_dbus = {
|
||||||
.in_value = NULL,
|
.in_value = NULL,
|
||||||
.out_value = ir_dbus
|
.out_value = ir_dbus
|
||||||
};
|
};
|
||||||
uint8_t ir_idcode[1] = {0x1};
|
uint8_t ir_idcode[4] = {0x1};
|
||||||
struct scan_field select_idcode = {
|
struct scan_field select_idcode = {
|
||||||
.in_value = NULL,
|
.in_value = NULL,
|
||||||
.out_value = ir_idcode
|
.out_value = ir_idcode
|
||||||
|
@ -1626,6 +1626,30 @@ COMMAND_HANDLER(riscv_reset_delays)
|
||||||
return ERROR_OK;
|
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[] = {
|
static const struct command_registration riscv_exec_command_handlers[] = {
|
||||||
{
|
{
|
||||||
.name = "test_compliance",
|
.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 "
|
"command resets those learned values after `wait` scans. It's only "
|
||||||
"useful for testing OpenOCD itself."
|
"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
|
COMMAND_REGISTRATION_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -151,11 +151,11 @@ static inline riscv_info_t *riscv_info(const struct target *target)
|
||||||
{ return target->arch_info; }
|
{ return target->arch_info; }
|
||||||
#define RISCV_INFO(R) riscv_info_t *R = riscv_info(target);
|
#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 struct scan_field select_dtmcontrol;
|
||||||
extern uint8_t ir_dbus[1];
|
extern uint8_t ir_dbus[4];
|
||||||
extern struct scan_field select_dbus;
|
extern struct scan_field select_dbus;
|
||||||
extern uint8_t ir_idcode[1];
|
extern uint8_t ir_idcode[4];
|
||||||
extern struct scan_field select_idcode;
|
extern struct scan_field select_idcode;
|
||||||
|
|
||||||
/*** OpenOCD Interface */
|
/*** OpenOCD Interface */
|
||||||
|
|
Loading…
Reference in New Issue