jtag: add -ir-bypass option to newtap

Some devices with an internal multi-tap JTAG router require a vendor
specific bypass instruction to bypass the master TAP when addressing
slave taps internal to the same device. On these devices the standard
bypass instruction bypasses the whole device.

Change-Id: I4506f0e67c9e4dfe39b7fa18c63d67900313e594
Signed-off-by: Henrik Nordström <henrik.nordstrom@addiva.se>
Reviewed-on: https://review.openocd.org/c/openocd/+/8041
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Tested-by: jenkins
This commit is contained in:
Henrik Nordström 2023-12-17 23:14:37 +01:00 committed by Antonio Borneo
parent fc268f8326
commit 8d3728f931
7 changed files with 31 additions and 1 deletions

View File

@ -4424,6 +4424,10 @@ there seems to be no problems with JTAG scan chain operations.
register during initial examination and when checking the sticky error bit.
This bit is normally checked after setting the CSYSPWRUPREQ bit, but some
devices do not set the ack bit until sometime later.
@item @code{-ir-bypass} @var{NUMBER}
@*Vendor specific bypass instruction, required by some hierarchical JTAG
routers where the normal BYPASS instruction bypasses the whole router and
a vendor specific bypass instruction is required to access child nodes.
@end itemize
@end deffn

View File

@ -85,7 +85,13 @@ int interface_jtag_add_ir_scan(struct jtag_tap *active,
tap->bypass = true;
field->num_bits = tap->ir_length;
field->out_value = buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8)), tap->ir_length);
if (tap->ir_bypass_value) {
uint8_t *v = cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8));
buf_set_u64(v, 0, tap->ir_length, tap->ir_bypass_value);
field->out_value = v;
} else {
field->out_value = buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8)), tap->ir_length);
}
field->in_value = NULL; /* do not collect input for tap's in bypass */
}

View File

@ -45,6 +45,7 @@ static const struct command_registration hl_swd_transport_subcommand_handlers[]
"['-ignore-version'] "
"['-ignore-bypass'] "
"['-ircapture' number] "
"['-ir-bypass' number] "
"['-mask' number]",
},
COMMAND_REGISTRATION_DONE
@ -74,6 +75,7 @@ static const struct command_registration hl_transport_jtag_subcommand_handlers[]
"['-ignore-version'] "
"['-ignore-bypass'] "
"['-ircapture' number] "
"['-ir-bypass' number] "
"['-mask' number]",
},
{

View File

@ -133,6 +133,9 @@ struct jtag_tap {
/** Bypass register selected */
bool bypass;
/** Bypass instruction value */
uint64_t ir_bypass_value;
struct jtag_tap_event_action *event_action;
struct jtag_tap *next_tap;

View File

@ -386,6 +386,7 @@ static int jtag_tap_configure_cmd(struct jim_getopt_info *goi, struct jtag_tap *
#define NTAP_OPT_EXPECTED_ID 5
#define NTAP_OPT_VERSION 6
#define NTAP_OPT_BYPASS 7
#define NTAP_OPT_IRBYPASS 8
static const struct nvp jtag_newtap_opts[] = {
{ .name = "-irlen", .value = NTAP_OPT_IRLEN },
@ -396,6 +397,7 @@ static const struct nvp jtag_newtap_opts[] = {
{ .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID },
{ .name = "-ignore-version", .value = NTAP_OPT_VERSION },
{ .name = "-ignore-bypass", .value = NTAP_OPT_BYPASS },
{ .name = "-ir-bypass", .value = NTAP_OPT_IRBYPASS },
{ .name = NULL, .value = -1 },
};
@ -499,6 +501,15 @@ static COMMAND_HELPER(handle_jtag_newtap_args, struct jtag_tap *tap)
tap->ignore_bypass = true;
break;
case NTAP_OPT_IRBYPASS:
if (!CMD_ARGC)
return ERROR_COMMAND_ARGUMENT_INVALID;
COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], tap->ir_bypass_value);
CMD_ARGC--;
CMD_ARGV++;
break;
default:
nvp_unknown_command_print(CMD, jtag_newtap_opts, NULL, CMD_ARGV[-1]);
return ERROR_COMMAND_ARGUMENT_INVALID;
@ -752,6 +763,7 @@ static const struct command_registration jtag_subcommand_handlers[] = {
"['-ignore-version'] "
"['-ignore-bypass'] "
"['-ircapture' number] "
"['-ir-bypass' number] "
"['-mask' number]",
},
{

View File

@ -66,6 +66,7 @@ static const struct command_registration dapdirect_jtag_subcommand_handlers[] =
"['-ignore-version'] "
"['-ignore-bypass'] "
"['-ircapture' number] "
"['-ir-bypass' number] "
"['-mask' number]",
},
{
@ -156,6 +157,7 @@ static const struct command_registration dapdirect_swd_subcommand_handlers[] = {
"['-ignore-version'] "
"['-ignore-bypass'] "
"['-ircapture' number] "
"['-ir-bypass' number] "
"['-mask' number]",
},
COMMAND_REGISTRATION_DONE

View File

@ -705,6 +705,7 @@ static const struct command_registration swd_commands[] = {
"['-ignore-version'] "
"['-ignore-bypass'] "
"['-ircapture' number] "
"['-ir-bypass' number] "
"['-mask' number]",
},
COMMAND_REGISTRATION_DONE