This is an automated email from Gerrit. "Henrik Nordström <henrik.nordst...@addiva.se>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8041
-- gerrit commit edb016eaee35cda89cacf2a999e84babc16dfedb Author: Henrik Nordstrom <henrik.nordst...@addiva.se> Date: Mon Sep 4 19:44:31 2023 +0200 jtag: add -ir-bypass option 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 Nordstrom <henrik.nordst...@addiva.se> diff --git a/doc/openocd.texi b/doc/openocd.texi index db7315fe44..bc59e02f94 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4406,6 +4406,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} +@*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 diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c index 409b800874..9dba58d979 100644 --- a/src/jtag/drivers/driver.c +++ b/src/jtag/drivers/driver.c @@ -85,7 +85,13 @@ int interface_jtag_add_ir_scan(struct jtag_tap *active, tap->bypass = 1; 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 */ } diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 04d1b4a2b5..5f2cb2884a 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -133,6 +133,9 @@ struct jtag_tap { /** Bypass register selected */ int bypass; + /** Bypass instruction value */ + uint64_t ir_bypass_value; + struct jtag_tap_event_action *event_action; struct jtag_tap *next_tap; diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 85a66aaf62..3d6408b5b4 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -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; --