aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi4
-rw-r--r--src/jtag/drivers/driver.c8
-rw-r--r--src/jtag/hla/hla_transport.c2
-rw-r--r--src/jtag/jtag.h3
-rw-r--r--src/jtag/tcl.c12
-rw-r--r--src/target/adi_v5_dapdirect.c2
-rw-r--r--src/target/adi_v5_swd.c1
7 files changed, 31 insertions, 1 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index ec7c996..7467e6a 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -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
diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c
index 7732315..fae2aad 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 = 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 */
}
diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c
index 08ee18f..c0443d8 100644
--- a/src/jtag/hla/hla_transport.c
+++ b/src/jtag/hla/hla_transport.c
@@ -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]",
},
{
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index 1d1c495..470ae18 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -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;
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 85a66aa..407aeb1 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;
@@ -752,6 +763,7 @@ static const struct command_registration jtag_subcommand_handlers[] = {
"['-ignore-version'] "
"['-ignore-bypass'] "
"['-ircapture' number] "
+ "['-ir-bypass' number] "
"['-mask' number]",
},
{
diff --git a/src/target/adi_v5_dapdirect.c b/src/target/adi_v5_dapdirect.c
index 575092c..f3a90c0 100644
--- a/src/target/adi_v5_dapdirect.c
+++ b/src/target/adi_v5_dapdirect.c
@@ -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
diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c
index edcad74..6d6f287 100644
--- a/src/target/adi_v5_swd.c
+++ b/src/target/adi_v5_swd.c
@@ -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