1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * Copyright (C) 2009 SoftPLC Corporation *
12 * Copyright (C) 2009 Zachary T Welch *
13 * zw@superlucidity.net *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
20 * This program is distributed in the hope that it will be useful, *
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
23 * GNU General Public License for more details. *
25 * You should have received a copy of the GNU General Public License *
26 * along with this program; if not, write to the *
27 * Free Software Foundation, Inc., *
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 ***************************************************************************/
35 #include "minidriver.h"
36 #include "interface.h"
37 #include "interfaces.h"
43 static const Jim_Nvp nvp_jtag_tap_event
[] = {
44 { .value
= JTAG_TRST_ASSERTED
, .name
= "post-reset" },
45 { .value
= JTAG_TAP_EVENT_SETUP
, .name
= "setup" },
46 { .value
= JTAG_TAP_EVENT_ENABLE
, .name
= "tap-enable" },
47 { .value
= JTAG_TAP_EVENT_DISABLE
, .name
= "tap-disable" },
49 { .name
= NULL
, .value
= -1 }
52 extern struct jtag_interface
*jtag_interface
;
54 static bool scan_is_safe(tap_state_t state
)
68 static int Jim_Command_drscan(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
71 struct scan_field
*fields
;
80 * args[3] = hex string
81 * ... repeat num bits and hex string ...
84 * args[N-2] = "-endstate"
85 * args[N-1] = statename
87 if ((argc
< 4) || ((argc
% 2) != 0))
89 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
95 script_debug(interp
, "drscan", argc
, args
);
97 /* validate arguments as numbers */
99 for (i
= 2; i
< argc
; i
+= 2)
104 e
= Jim_GetLong(interp
, args
[i
], &bits
);
105 /* If valid - try next arg */
110 /* Not valid.. are we at the end? */
111 if (((i
+ 2) != argc
)) {
112 /* nope, then error */
116 /* it could be: "-endstate FOO"
117 * e.g. DRPAUSE so we can issue more instructions
118 * before entering RUN/IDLE and executing them.
121 /* get arg as a string. */
122 cp
= Jim_GetString(args
[i
], NULL
);
123 /* is it the magic? */
124 if (0 == strcmp("-endstate", cp
)) {
125 /* is the statename valid? */
126 cp
= Jim_GetString(args
[i
+ 1], NULL
);
128 /* see if it is a valid state name */
129 endstate
= tap_state_by_name(cp
);
131 /* update the error message */
132 Jim_SetResult_sprintf(interp
,"endstate: %s invalid", cp
);
134 if (!scan_is_safe(endstate
))
135 LOG_WARNING("drscan with unsafe "
136 "endstate \"%s\"", cp
);
138 /* valid - so clear the error */
140 /* and remove the last 2 args */
145 /* Still an error? */
147 return e
; /* too bad */
149 } /* validate args */
151 tap
= jtag_tap_by_jim_obj(interp
, args
[1]);
156 num_fields
= (argc
-2)/2;
157 fields
= malloc(sizeof(struct scan_field
) * num_fields
);
158 for (i
= 2; i
< argc
; i
+= 2)
164 Jim_GetLong(interp
, args
[i
], &bits
);
165 str
= Jim_GetString(args
[i
+ 1], &len
);
167 fields
[field_count
].tap
= tap
;
168 fields
[field_count
].num_bits
= bits
;
169 fields
[field_count
].out_value
= malloc(DIV_ROUND_UP(bits
, 8));
170 str_to_buf(str
, len
, fields
[field_count
].out_value
, bits
, 0);
171 fields
[field_count
].in_value
= fields
[field_count
].out_value
;
175 jtag_add_dr_scan(num_fields
, fields
, endstate
);
177 retval
= jtag_execute_queue();
178 if (retval
!= ERROR_OK
)
180 Jim_SetResultString(interp
, "drscan: jtag execute failed",-1);
185 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
186 for (i
= 2; i
< argc
; i
+= 2)
191 Jim_GetLong(interp
, args
[i
], &bits
);
192 str
= buf_to_str(fields
[field_count
].in_value
, bits
, 16);
193 free(fields
[field_count
].out_value
);
195 Jim_ListAppendElement(interp
, list
, Jim_NewStringObj(interp
, str
, strlen(str
)));
200 Jim_SetResult(interp
, list
);
208 static int Jim_Command_pathmove(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
210 tap_state_t states
[8];
212 if ((argc
< 2) || ((size_t)argc
> (ARRAY_SIZE(states
) + 1)))
214 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
218 script_debug(interp
, "pathmove", argc
, args
);
221 for (i
= 0; i
< argc
-1; i
++)
224 cp
= Jim_GetString(args
[i
+ 1], NULL
);
225 states
[i
] = tap_state_by_name(cp
);
228 /* update the error message */
229 Jim_SetResult_sprintf(interp
,"endstate: %s invalid", cp
);
234 if ((jtag_add_statemove(states
[0]) != ERROR_OK
) || (jtag_execute_queue()!= ERROR_OK
))
236 Jim_SetResultString(interp
, "pathmove: jtag execute failed",-1);
240 jtag_add_pathmove(argc
-2, states
+ 1);
242 if (jtag_execute_queue()!= ERROR_OK
)
244 Jim_SetResultString(interp
, "pathmove: failed",-1);
252 static int Jim_Command_flush_count(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
254 script_debug(interp
, "flush_count", argc
, args
);
256 Jim_SetResult(interp
, Jim_NewIntObj(interp
, jtag_get_flush_queue_count()));
261 static const struct command_registration jtag_command_handlers_to_move
[] = {
264 .mode
= COMMAND_EXEC
,
265 .jim_handler
= &Jim_Command_drscan
,
266 .help
= "execute DR scan <device> "
267 "<num_bits> <value> <num_bits1> <value2> ...",
270 .name
= "flush_count",
271 .mode
= COMMAND_EXEC
,
272 .jim_handler
= &Jim_Command_flush_count
,
273 .help
= "returns number of times the JTAG queue has been flushed",
277 .mode
= COMMAND_EXEC
,
278 .jim_handler
= &Jim_Command_pathmove
,
279 .usage
= "<state1>,<state2>,<state3>... ",
280 .help
= "move JTAG to state1 then to state2, state3, etc.",
282 COMMAND_REGISTRATION_DONE
286 enum jtag_tap_cfg_param
{
290 static Jim_Nvp nvp_config_opts
[] = {
291 { .name
= "-event", .value
= JCFG_EVENT
},
293 { .name
= NULL
, .value
= -1 }
296 static int jtag_tap_configure_event(Jim_GetOptInfo
*goi
, struct jtag_tap
* tap
)
300 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name> ...");
305 int e
= Jim_GetOpt_Nvp(goi
, nvp_jtag_tap_event
, &n
);
308 Jim_GetOpt_NvpUnknown(goi
, nvp_jtag_tap_event
, 1);
312 if (goi
->isconfigure
) {
313 if (goi
->argc
!= 1) {
314 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name> <event-body>");
318 if (goi
->argc
!= 0) {
319 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name>");
324 struct jtag_tap_event_action
*jteap
= tap
->event_action
;
325 /* replace existing event body */
329 if (jteap
->event
== (enum jtag_event
)n
->value
)
337 Jim_SetEmptyResult(goi
->interp
);
339 if (goi
->isconfigure
)
342 jteap
= calloc(1, sizeof(*jteap
));
343 else if (NULL
!= jteap
->body
)
344 Jim_DecrRefCount(interp
, jteap
->body
);
346 jteap
->event
= n
->value
;
349 Jim_GetOpt_Obj(goi
, &o
);
350 jteap
->body
= Jim_DuplicateObj(goi
->interp
, o
);
351 Jim_IncrRefCount(jteap
->body
);
355 /* add to head of event list */
356 jteap
->next
= tap
->event_action
;
357 tap
->event_action
= jteap
;
362 Jim_SetResult(goi
->interp
,
363 Jim_DuplicateObj(goi
->interp
, jteap
->body
));
368 static int jtag_tap_configure_cmd(Jim_GetOptInfo
*goi
, struct jtag_tap
* tap
)
370 /* parse config or cget options */
371 while (goi
->argc
> 0)
373 Jim_SetEmptyResult (goi
->interp
);
376 int e
= Jim_GetOpt_Nvp(goi
, nvp_config_opts
, &n
);
379 Jim_GetOpt_NvpUnknown(goi
, nvp_config_opts
, 0);
386 e
= jtag_tap_configure_event(goi
, tap
);
391 Jim_SetResult_sprintf(goi
->interp
, "unknown event: %s", n
->name
);
399 static int is_bad_irval(int ir_length
, jim_wide w
)
409 static int jim_newtap_expected_id(Jim_Nvp
*n
, Jim_GetOptInfo
*goi
,
410 struct jtag_tap
*pTap
)
413 int e
= Jim_GetOpt_Wide(goi
, &w
);
415 Jim_SetResult_sprintf(goi
->interp
, "option: %s bad parameter", n
->name
);
419 unsigned expected_len
= sizeof(uint32_t) * pTap
->expected_ids_cnt
;
420 uint32_t *new_expected_ids
= malloc(expected_len
+ sizeof(uint32_t));
421 if (new_expected_ids
== NULL
)
423 Jim_SetResult_sprintf(goi
->interp
, "no memory");
427 memcpy(new_expected_ids
, pTap
->expected_ids
, expected_len
);
429 new_expected_ids
[pTap
->expected_ids_cnt
] = w
;
431 free(pTap
->expected_ids
);
432 pTap
->expected_ids
= new_expected_ids
;
433 pTap
->expected_ids_cnt
++;
438 #define NTAP_OPT_IRLEN 0
439 #define NTAP_OPT_IRMASK 1
440 #define NTAP_OPT_IRCAPTURE 2
441 #define NTAP_OPT_ENABLED 3
442 #define NTAP_OPT_DISABLED 4
443 #define NTAP_OPT_EXPECTED_ID 5
445 static int jim_newtap_ir_param(Jim_Nvp
*n
, Jim_GetOptInfo
*goi
,
446 struct jtag_tap
*pTap
)
449 int e
= Jim_GetOpt_Wide(goi
, &w
);
452 Jim_SetResult_sprintf(goi
->interp
,
453 "option: %s bad parameter", n
->name
);
454 free((void *)pTap
->dotted_name
);
459 if (w
> (jim_wide
) (8 * sizeof(pTap
->ir_capture_value
)))
461 LOG_WARNING("%s: huge IR length %d",
462 pTap
->dotted_name
, (int) w
);
466 case NTAP_OPT_IRMASK
:
467 if (is_bad_irval(pTap
->ir_length
, w
))
469 LOG_ERROR("%s: IR mask %x too big",
475 LOG_WARNING("%s: nonstandard IR mask", pTap
->dotted_name
);
476 pTap
->ir_capture_mask
= w
;
478 case NTAP_OPT_IRCAPTURE
:
479 if (is_bad_irval(pTap
->ir_length
, w
))
481 LOG_ERROR("%s: IR capture %x too big",
482 pTap
->dotted_name
, (int) w
);
486 LOG_WARNING("%s: nonstandard IR value",
488 pTap
->ir_capture_value
= w
;
496 static int jim_newtap_cmd(Jim_GetOptInfo
*goi
)
498 struct jtag_tap
*pTap
;
503 const Jim_Nvp opts
[] = {
504 { .name
= "-irlen" , .value
= NTAP_OPT_IRLEN
},
505 { .name
= "-irmask" , .value
= NTAP_OPT_IRMASK
},
506 { .name
= "-ircapture" , .value
= NTAP_OPT_IRCAPTURE
},
507 { .name
= "-enable" , .value
= NTAP_OPT_ENABLED
},
508 { .name
= "-disable" , .value
= NTAP_OPT_DISABLED
},
509 { .name
= "-expected-id" , .value
= NTAP_OPT_EXPECTED_ID
},
510 { .name
= NULL
, .value
= -1 },
513 pTap
= calloc(1, sizeof(struct jtag_tap
));
515 Jim_SetResult_sprintf(goi
->interp
, "no memory");
520 * we expect CHIP + TAP + OPTIONS
523 Jim_SetResult_sprintf(goi
->interp
, "Missing CHIP TAP OPTIONS ....");
527 Jim_GetOpt_String(goi
, &cp
, NULL
);
528 pTap
->chip
= strdup(cp
);
530 Jim_GetOpt_String(goi
, &cp
, NULL
);
531 pTap
->tapname
= strdup(cp
);
533 /* name + dot + name + null */
534 x
= strlen(pTap
->chip
) + 1 + strlen(pTap
->tapname
) + 1;
536 sprintf(cp
, "%s.%s", pTap
->chip
, pTap
->tapname
);
537 pTap
->dotted_name
= cp
;
539 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
540 pTap
->chip
, pTap
->tapname
, pTap
->dotted_name
, goi
->argc
);
542 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
543 * that the default. The "-irlen" and "-irmask" options are only
544 * needed to cope with nonstandard TAPs, or to specify more bits.
546 pTap
->ir_capture_mask
= 0x03;
547 pTap
->ir_capture_value
= 0x01;
550 e
= Jim_GetOpt_Nvp(goi
, opts
, &n
);
552 Jim_GetOpt_NvpUnknown(goi
, opts
, 0);
553 free((void *)pTap
->dotted_name
);
557 LOG_DEBUG("Processing option: %s", n
->name
);
559 case NTAP_OPT_ENABLED
:
560 pTap
->disabled_after_reset
= false;
562 case NTAP_OPT_DISABLED
:
563 pTap
->disabled_after_reset
= true;
565 case NTAP_OPT_EXPECTED_ID
:
566 e
= jim_newtap_expected_id(n
, goi
, pTap
);
569 free((void *)pTap
->dotted_name
);
575 case NTAP_OPT_IRMASK
:
576 case NTAP_OPT_IRCAPTURE
:
577 e
= jim_newtap_ir_param(n
, goi
, pTap
);
580 free((void *)pTap
->dotted_name
);
585 } /* switch (n->value) */
586 } /* while (goi->argc) */
588 /* default is enabled-after-reset */
589 pTap
->enabled
= !pTap
->disabled_after_reset
;
591 /* Did all the required option bits get cleared? */
592 if (pTap
->ir_length
!= 0)
598 Jim_SetResult_sprintf(goi
->interp
,
599 "newtap: %s missing IR length",
605 static void jtag_tap_handle_event(struct jtag_tap
*tap
, enum jtag_event e
)
607 struct jtag_tap_event_action
* jteap
;
609 for (jteap
= tap
->event_action
; jteap
!= NULL
; jteap
= jteap
->next
)
611 if (jteap
->event
!= e
)
614 Jim_Nvp
*nvp
= Jim_Nvp_value2name_simple(nvp_jtag_tap_event
, e
);
615 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
616 tap
->dotted_name
, e
, nvp
->name
,
617 Jim_GetString(jteap
->body
, NULL
));
619 if (Jim_EvalObj(interp
, jteap
->body
) != JIM_OK
)
621 Jim_PrintErrorMessage(interp
);
627 case JTAG_TAP_EVENT_ENABLE
:
628 case JTAG_TAP_EVENT_DISABLE
:
629 /* NOTE: we currently assume the handlers
630 * can't fail. Right here is where we should
631 * really be verifying the scan chains ...
633 tap
->enabled
= (e
== JTAG_TAP_EVENT_ENABLE
);
634 LOG_INFO("JTAG tap: %s %s", tap
->dotted_name
,
635 tap
->enabled
? "enabled" : "disabled");
643 static int jim_jtag_interface(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
646 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
648 /* return the name of the interface */
649 /* TCL code might need to know the exact type... */
650 /* FUTURE: we allow this as a means to "set" the interface. */
652 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
655 const char *name
= jtag_interface
? jtag_interface
->name
: NULL
;
656 Jim_SetResultString(goi
.interp
, name
? : "undefined", -1);
660 static int jim_jtag_arp_init(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
663 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
665 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
668 struct command_context
*context
= Jim_GetAssocData(interp
, "context");
669 int e
= jtag_init_inner(context
);
671 Jim_SetResult_sprintf(goi
.interp
, "error: %d", e
);
677 static int jim_jtag_arp_init_reset(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
680 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
682 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
685 struct command_context
*context
= Jim_GetAssocData(interp
, "context");
686 int e
= jtag_init_reset(context
);
688 Jim_SetResult_sprintf(goi
.interp
, "error: %d", e
);
694 static int jim_jtag_newtap(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
697 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
698 return jim_newtap_cmd(&goi
);
701 static bool jtag_tap_enable(struct jtag_tap
*t
)
705 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_ENABLE
);
709 /* FIXME add JTAG sanity checks, w/o TLR
710 * - scan chain length grew by one (this)
711 * - IDs and IR lengths are as expected
713 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE
);
716 static bool jtag_tap_disable(struct jtag_tap
*t
)
720 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_DISABLE
);
724 /* FIXME add JTAG sanity checks, w/o TLR
725 * - scan chain length shrank by one (this)
726 * - IDs and IR lengths are as expected
728 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE
);
732 static int jim_jtag_tap_enabler(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
734 const char *cmd_name
= Jim_GetString(argv
[0], NULL
);
736 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
738 Jim_SetResult_sprintf(goi
.interp
, "usage: %s <name>", cmd_name
);
744 t
= jtag_tap_by_jim_obj(goi
.interp
, goi
.argv
[0]);
748 if (strcasecmp(cmd_name
, "tapisenabled") == 0) {
749 // do nothing, just return the value
750 } else if (strcasecmp(cmd_name
, "tapenable") == 0) {
751 if (!jtag_tap_enable(t
))
752 LOG_WARNING("failed to disable tap");
753 } else if (strcasecmp(cmd_name
, "tapdisable") == 0) {
754 if (!jtag_tap_disable(t
))
755 LOG_WARNING("failed to disable tap");
757 LOG_ERROR("command '%s' unknown", cmd_name
);
761 Jim_SetResult(goi
.interp
, Jim_NewIntObj(goi
.interp
, e
));
765 static int jim_jtag_configure(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
767 const char *cmd_name
= Jim_GetString(argv
[0], NULL
);
769 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
770 goi
.isconfigure
= !strcmp(cmd_name
, "configure");
771 if (goi
.argc
< 2 + goi
.isconfigure
) {
772 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
773 "<tap_name> <attribute> ...");
780 Jim_GetOpt_Obj(&goi
, &o
);
781 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
786 return jtag_tap_configure_cmd(&goi
, t
);
789 static int jim_jtag_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
792 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
794 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
, "Too many parameters");
797 Jim_SetResult(goi
.interp
, Jim_NewListObj(goi
.interp
, NULL
, 0));
798 struct jtag_tap
*tap
;
800 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
) {
801 Jim_ListAppendElement(goi
.interp
,
802 Jim_GetResult(goi
.interp
),
803 Jim_NewStringObj(goi
.interp
,
804 tap
->dotted_name
, -1));
809 static const struct command_registration jtag_subcommand_handlers
[] = {
813 .jim_handler
= &jim_jtag_interface
,
814 .help
= "Returns the selected interface",
819 .jim_handler
= &jim_jtag_arp_init
,
822 .name
= "arp_init-reset",
824 .jim_handler
= &jim_jtag_arp_init_reset
,
828 .mode
= COMMAND_CONFIG
,
829 .jim_handler
= &jim_jtag_newtap
,
830 .help
= "Create a new TAP instance",
831 .usage
= "<name> <type> -irlen <count> [-ircapture <count>] "
832 "[-irmask <count>] [-enable|-disable]",
835 .name
= "tapisenabled",
836 .mode
= COMMAND_EXEC
,
837 .jim_handler
= &jim_jtag_tap_enabler
,
838 .help
= "Returns a integer indicating TAP state (0/1)",
843 .mode
= COMMAND_EXEC
,
844 .jim_handler
= &jim_jtag_tap_enabler
,
845 .help
= "Enable the specified TAP",
849 .name
= "tapdisable",
850 .mode
= COMMAND_EXEC
,
851 .jim_handler
= &jim_jtag_tap_enabler
,
852 .help
= "Enable the specified TAP",
857 .mode
= COMMAND_EXEC
,
858 .jim_handler
= &jim_jtag_configure
,
859 .help
= "Enable the specified TAP",
860 .usage
= "<name> [<key> <value> ...]",
864 .mode
= COMMAND_EXEC
,
865 .jim_handler
= &jim_jtag_configure
,
866 .help
= "Enable the specified TAP",
867 .usage
= "<name> [<key> <value> ...]",
872 .jim_handler
= &jim_jtag_names
,
873 .help
= "Returns list of all JTAG tap names",
876 .chain
= jtag_command_handlers_to_move
,
878 COMMAND_REGISTRATION_DONE
881 void jtag_notify_event(enum jtag_event event
)
883 struct jtag_tap
*tap
;
885 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
886 jtag_tap_handle_event(tap
, event
);
890 static int default_khz(int khz
, int *jtag_speed
)
892 LOG_ERROR("Translation from khz to jtag_speed not implemented");
896 static int default_speed_div(int speed
, int *khz
)
898 LOG_ERROR("Translation from jtag_speed to khz not implemented");
902 static int default_power_dropout(int *dropout
)
904 *dropout
= 0; /* by default we can't detect power dropout */
908 static int default_srst_asserted(int *srst_asserted
)
910 *srst_asserted
= 0; /* by default we can't detect srst asserted */
914 COMMAND_HANDLER(handle_interface_list_command
)
916 if (strcmp(CMD_NAME
, "interface_list") == 0 && CMD_ARGC
> 0)
917 return ERROR_COMMAND_SYNTAX_ERROR
;
919 command_print(CMD_CTX
, "The following JTAG interfaces are available:");
920 for (unsigned i
= 0; NULL
!= jtag_interfaces
[i
]; i
++)
922 const char *name
= jtag_interfaces
[i
]->name
;
923 command_print(CMD_CTX
, "%u: %s", i
+ 1, name
);
929 COMMAND_HANDLER(handle_interface_command
)
931 /* check whether the interface is already configured */
934 LOG_WARNING("Interface already configured, ignoring");
938 /* interface name is a mandatory argument */
939 if (CMD_ARGC
!= 1 || CMD_ARGV
[0][0] == '\0')
940 return ERROR_COMMAND_SYNTAX_ERROR
;
942 for (unsigned i
= 0; NULL
!= jtag_interfaces
[i
]; i
++)
944 if (strcmp(CMD_ARGV
[0], jtag_interfaces
[i
]->name
) != 0)
947 if (NULL
!= jtag_interfaces
[i
]->commands
)
949 int retval
= register_commands(CMD_CTX
, NULL
,
950 jtag_interfaces
[i
]->commands
);
951 if (ERROR_OK
!= retval
)
955 jtag_interface
= jtag_interfaces
[i
];
957 if (jtag_interface
->khz
== NULL
)
958 jtag_interface
->khz
= default_khz
;
959 if (jtag_interface
->speed_div
== NULL
)
960 jtag_interface
->speed_div
= default_speed_div
;
961 if (jtag_interface
->power_dropout
== NULL
)
962 jtag_interface
->power_dropout
= default_power_dropout
;
963 if (jtag_interface
->srst_asserted
== NULL
)
964 jtag_interface
->srst_asserted
= default_srst_asserted
;
969 /* no valid interface was found (i.e. the configuration option,
970 * didn't match one of the compiled-in interfaces
972 LOG_ERROR("The specified JTAG interface was not found (%s)", CMD_ARGV
[0]);
973 CALL_COMMAND_HANDLER(handle_interface_list_command
);
974 return ERROR_JTAG_INVALID_INTERFACE
;
977 COMMAND_HANDLER(handle_scan_chain_command
)
979 struct jtag_tap
*tap
;
981 tap
= jtag_all_taps();
982 command_print(CMD_CTX
, " TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr ");
983 command_print(CMD_CTX
, "---|--------------------|---------|------------|------------|------|------|------|---------");
986 uint32_t expected
, expected_mask
, cur_instr
, ii
;
987 expected
= buf_get_u32(tap
->expected
, 0, tap
->ir_length
);
988 expected_mask
= buf_get_u32(tap
->expected_mask
, 0, tap
->ir_length
);
989 cur_instr
= buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
);
991 command_print(CMD_CTX
,
992 "%2d | %-18s | %c | 0x%08x | 0x%08x | 0x%02x | 0x%02x | 0x%02x | 0x%02x",
993 tap
->abs_chain_position
,
995 tap
->enabled
? 'Y' : 'n',
996 (unsigned int)(tap
->idcode
),
997 (unsigned int)(tap
->expected_ids_cnt
> 0 ? tap
->expected_ids
[0] : 0),
998 (unsigned int)(tap
->ir_length
),
999 (unsigned int)(expected
),
1000 (unsigned int)(expected_mask
),
1001 (unsigned int)(cur_instr
));
1003 for (ii
= 1; ii
< tap
->expected_ids_cnt
; ii
++) {
1004 command_print(CMD_CTX
, " | | | | 0x%08x | | | | ",
1005 (unsigned int)(tap
->expected_ids
[ii
]));
1008 tap
= tap
->next_tap
;
1014 COMMAND_HANDLER(handle_reset_config_command
)
1019 /* Original versions cared about the order of these tokens:
1020 * reset_config signals [combination [trst_type [srst_type]]]
1021 * They also clobbered the previous configuration even on error.
1023 * Here we don't care about the order, and only change values
1024 * which have been explicitly specified.
1026 for (; CMD_ARGC
; CMD_ARGC
--, CMD_ARGV
++) {
1031 m
= RESET_SRST_NO_GATING
;
1032 if (strcmp(*CMD_ARGV
, "srst_gates_jtag") == 0)
1033 /* default: don't use JTAG while SRST asserted */;
1034 else if (strcmp(*CMD_ARGV
, "srst_nogate") == 0)
1035 tmp
= RESET_SRST_NO_GATING
;
1039 LOG_ERROR("extra reset_config %s spec (%s)",
1040 "gating", *CMD_ARGV
);
1041 return ERROR_INVALID_ARGUMENTS
;
1047 m
= RESET_HAS_TRST
| RESET_HAS_SRST
;
1048 if (strcmp(*CMD_ARGV
, "none") == 0)
1050 else if (strcmp(*CMD_ARGV
, "trst_only") == 0)
1051 tmp
= RESET_HAS_TRST
;
1052 else if (strcmp(*CMD_ARGV
, "srst_only") == 0)
1053 tmp
= RESET_HAS_SRST
;
1054 else if (strcmp(*CMD_ARGV
, "trst_and_srst") == 0)
1055 tmp
= RESET_HAS_TRST
| RESET_HAS_SRST
;
1059 LOG_ERROR("extra reset_config %s spec (%s)",
1060 "signal", *CMD_ARGV
);
1061 return ERROR_INVALID_ARGUMENTS
;
1066 /* combination (options for broken wiring) */
1067 m
= RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
;
1068 if (strcmp(*CMD_ARGV
, "separate") == 0)
1069 /* separate reset lines - default */;
1070 else if (strcmp(*CMD_ARGV
, "srst_pulls_trst") == 0)
1071 tmp
|= RESET_SRST_PULLS_TRST
;
1072 else if (strcmp(*CMD_ARGV
, "trst_pulls_srst") == 0)
1073 tmp
|= RESET_TRST_PULLS_SRST
;
1074 else if (strcmp(*CMD_ARGV
, "combined") == 0)
1075 tmp
|= RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
;
1079 LOG_ERROR("extra reset_config %s spec (%s)",
1080 "combination", *CMD_ARGV
);
1081 return ERROR_INVALID_ARGUMENTS
;
1086 /* trst_type (NOP without HAS_TRST) */
1087 m
= RESET_TRST_OPEN_DRAIN
;
1088 if (strcmp(*CMD_ARGV
, "trst_open_drain") == 0)
1089 tmp
|= RESET_TRST_OPEN_DRAIN
;
1090 else if (strcmp(*CMD_ARGV
, "trst_push_pull") == 0)
1091 /* push/pull from adapter - default */;
1095 LOG_ERROR("extra reset_config %s spec (%s)",
1096 "trst_type", *CMD_ARGV
);
1097 return ERROR_INVALID_ARGUMENTS
;
1102 /* srst_type (NOP without HAS_SRST) */
1103 m
|= RESET_SRST_PUSH_PULL
;
1104 if (strcmp(*CMD_ARGV
, "srst_push_pull") == 0)
1105 tmp
|= RESET_SRST_PUSH_PULL
;
1106 else if (strcmp(*CMD_ARGV
, "srst_open_drain") == 0)
1107 /* open drain from adapter - default */;
1111 LOG_ERROR("extra reset_config %s spec (%s)",
1112 "srst_type", *CMD_ARGV
);
1113 return ERROR_INVALID_ARGUMENTS
;
1118 /* caller provided nonsense; fail */
1119 LOG_ERROR("unknown reset_config flag (%s)", *CMD_ARGV
);
1120 return ERROR_INVALID_ARGUMENTS
;
1123 /* Remember the bits which were specified (mask)
1124 * and their new values (new_cfg).
1130 /* clear previous values of those bits, save new values */
1132 int old_cfg
= jtag_get_reset_config();
1136 jtag_set_reset_config(new_cfg
);
1138 new_cfg
= jtag_get_reset_config();
1142 * Display the (now-)current reset mode
1146 /* minimal JTAG has neither SRST nor TRST (so that's the default) */
1147 switch (new_cfg
& (RESET_HAS_TRST
| RESET_HAS_SRST
)) {
1148 case RESET_HAS_SRST
:
1149 modes
[0] = "srst_only";
1151 case RESET_HAS_TRST
:
1152 modes
[0] = "trst_only";
1154 case RESET_TRST_AND_SRST
:
1155 modes
[0] = "trst_and_srst";
1162 /* normally SRST and TRST are decoupled; but bugs happen ... */
1163 switch (new_cfg
& (RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
)) {
1164 case RESET_SRST_PULLS_TRST
:
1165 modes
[1] = "srst_pulls_trst";
1167 case RESET_TRST_PULLS_SRST
:
1168 modes
[1] = "trst_pulls_srst";
1170 case RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
:
1171 modes
[1] = "combined";
1174 modes
[1] = "separate";
1178 /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */
1179 if (new_cfg
& RESET_HAS_TRST
) {
1180 if (new_cfg
& RESET_TRST_OPEN_DRAIN
)
1181 modes
[3] = " trst_open_drain";
1183 modes
[3] = " trst_push_pull";
1187 /* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */
1188 if (new_cfg
& RESET_HAS_SRST
) {
1189 if (new_cfg
& RESET_SRST_NO_GATING
)
1190 modes
[2] = " srst_nogate";
1192 modes
[2] = " srst_gates_jtag";
1194 if (new_cfg
& RESET_SRST_PUSH_PULL
)
1195 modes
[4] = " srst_push_pull";
1197 modes
[4] = " srst_open_drain";
1203 command_print(CMD_CTX
, "%s %s%s%s%s",
1205 modes
[2], modes
[3], modes
[4]);
1210 COMMAND_HANDLER(handle_jtag_nsrst_delay_command
)
1213 return ERROR_COMMAND_SYNTAX_ERROR
;
1217 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1219 jtag_set_nsrst_delay(delay
);
1221 command_print(CMD_CTX
, "jtag_nsrst_delay: %u", jtag_get_nsrst_delay());
1225 COMMAND_HANDLER(handle_jtag_ntrst_delay_command
)
1228 return ERROR_COMMAND_SYNTAX_ERROR
;
1232 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1234 jtag_set_ntrst_delay(delay
);
1236 command_print(CMD_CTX
, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
1240 COMMAND_HANDLER(handle_jtag_nsrst_assert_width_command
)
1243 return ERROR_COMMAND_SYNTAX_ERROR
;
1247 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1249 jtag_set_nsrst_assert_width(delay
);
1251 command_print(CMD_CTX
, "jtag_nsrst_assert_width: %u", jtag_get_nsrst_assert_width());
1255 COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command
)
1258 return ERROR_COMMAND_SYNTAX_ERROR
;
1262 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1264 jtag_set_ntrst_assert_width(delay
);
1266 command_print(CMD_CTX
, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
1270 COMMAND_HANDLER(handle_jtag_khz_command
)
1273 return ERROR_COMMAND_SYNTAX_ERROR
;
1275 int retval
= ERROR_OK
;
1279 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], khz
);
1281 retval
= jtag_config_khz(khz
);
1282 if (ERROR_OK
!= retval
)
1286 int cur_speed
= jtag_get_speed_khz();
1287 retval
= jtag_get_speed_readable(&cur_speed
);
1288 if (ERROR_OK
!= retval
)
1292 command_print(CMD_CTX
, "%d kHz", cur_speed
);
1294 command_print(CMD_CTX
, "RCLK - adaptive");
1299 COMMAND_HANDLER(handle_jtag_rclk_command
)
1302 return ERROR_COMMAND_SYNTAX_ERROR
;
1304 int retval
= ERROR_OK
;
1308 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], khz
);
1310 retval
= jtag_config_rclk(khz
);
1311 if (ERROR_OK
!= retval
)
1315 int cur_khz
= jtag_get_speed_khz();
1316 retval
= jtag_get_speed_readable(&cur_khz
);
1317 if (ERROR_OK
!= retval
)
1321 command_print(CMD_CTX
, "RCLK not supported - fallback to %d kHz", cur_khz
);
1323 command_print(CMD_CTX
, "RCLK - adaptive");
1328 COMMAND_HANDLER(handle_jtag_reset_command
)
1331 return ERROR_COMMAND_SYNTAX_ERROR
;
1334 if (CMD_ARGV
[0][0] == '1')
1336 else if (CMD_ARGV
[0][0] == '0')
1339 return ERROR_COMMAND_SYNTAX_ERROR
;
1342 if (CMD_ARGV
[1][0] == '1')
1344 else if (CMD_ARGV
[1][0] == '0')
1347 return ERROR_COMMAND_SYNTAX_ERROR
;
1349 if (jtag_interface_init(CMD_CTX
) != ERROR_OK
)
1350 return ERROR_JTAG_INIT_FAILED
;
1352 jtag_add_reset(trst
, srst
);
1353 return jtag_execute_queue();
1356 COMMAND_HANDLER(handle_runtest_command
)
1359 return ERROR_COMMAND_SYNTAX_ERROR
;
1361 unsigned num_clocks
;
1362 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num_clocks
);
1364 jtag_add_runtest(num_clocks
, TAP_IDLE
);
1365 return jtag_execute_queue();
1369 * For "irscan" or "drscan" commands, the "end" (really, "next") state
1370 * should be stable ... and *NOT* a shift state, otherwise free-running
1371 * jtag clocks could change the values latched by the update state.
1372 * Not surprisingly, this is the same constraint as SVF; the "irscan"
1373 * and "drscan" commands are a write-only subset of what SVF provides.
1376 COMMAND_HANDLER(handle_irscan_command
)
1379 struct scan_field
*fields
;
1380 struct jtag_tap
*tap
;
1381 tap_state_t endstate
;
1383 if ((CMD_ARGC
< 2) || (CMD_ARGC
% 2))
1385 return ERROR_COMMAND_SYNTAX_ERROR
;
1388 /* optional "-endstate" "statename" at the end of the arguments,
1389 * so that e.g. IRPAUSE can let us load the data register before
1390 * entering RUN/IDLE to execute the instruction we load here.
1392 endstate
= TAP_IDLE
;
1394 if (CMD_ARGC
>= 4) {
1395 /* have at least one pair of numbers. */
1396 /* is last pair the magic text? */
1397 if (strcmp("-endstate", CMD_ARGV
[CMD_ARGC
- 2]) == 0) {
1398 endstate
= tap_state_by_name(CMD_ARGV
[CMD_ARGC
- 1]);
1399 if (endstate
== TAP_INVALID
)
1400 return ERROR_COMMAND_SYNTAX_ERROR
;
1401 if (!scan_is_safe(endstate
))
1402 LOG_WARNING("unstable irscan endstate \"%s\"",
1403 CMD_ARGV
[CMD_ARGC
- 1]);
1408 int num_fields
= CMD_ARGC
/ 2;
1409 size_t fields_len
= sizeof(struct scan_field
) * num_fields
;
1410 fields
= malloc(fields_len
);
1411 memset(fields
, 0, fields_len
);
1414 for (i
= 0; i
< num_fields
; i
++)
1416 tap
= jtag_tap_by_string(CMD_ARGV
[i
*2]);
1420 for (j
= 0; j
< i
; j
++)
1421 free(fields
[j
].out_value
);
1423 command_print(CMD_CTX
, "Tap: %s unknown", CMD_ARGV
[i
*2]);
1427 int field_size
= tap
->ir_length
;
1428 fields
[i
].tap
= tap
;
1429 fields
[i
].num_bits
= field_size
;
1430 fields
[i
].out_value
= malloc(DIV_ROUND_UP(field_size
, 8));
1433 retval
= parse_u32(CMD_ARGV
[i
* 2 + 1], &value
);
1434 if (ERROR_OK
!= retval
)
1436 buf_set_u32(fields
[i
].out_value
, 0, field_size
, value
);
1437 fields
[i
].in_value
= NULL
;
1440 /* did we have an endstate? */
1441 jtag_add_ir_scan(num_fields
, fields
, endstate
);
1443 retval
= jtag_execute_queue();
1446 for (i
= 0; i
< num_fields
; i
++)
1448 if (NULL
!= fields
[i
].out_value
)
1449 free(fields
[i
].out_value
);
1458 COMMAND_HANDLER(handle_verify_ircapture_command
)
1461 return ERROR_COMMAND_SYNTAX_ERROR
;
1466 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1467 jtag_set_verify_capture_ir(enable
);
1470 const char *status
= jtag_will_verify_capture_ir() ? "enabled": "disabled";
1471 command_print(CMD_CTX
, "verify Capture-IR is %s", status
);
1476 COMMAND_HANDLER(handle_verify_jtag_command
)
1479 return ERROR_COMMAND_SYNTAX_ERROR
;
1484 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1485 jtag_set_verify(enable
);
1488 const char *status
= jtag_will_verify() ? "enabled": "disabled";
1489 command_print(CMD_CTX
, "verify jtag capture is %s", status
);
1494 COMMAND_HANDLER(handle_tms_sequence_command
)
1497 return ERROR_COMMAND_SYNTAX_ERROR
;
1502 if (strcmp(CMD_ARGV
[0], "short") == 0)
1503 use_new_table
= true;
1504 else if (strcmp(CMD_ARGV
[0], "long") == 0)
1505 use_new_table
= false;
1507 return ERROR_COMMAND_SYNTAX_ERROR
;
1509 tap_use_new_tms_table(use_new_table
);
1512 command_print(CMD_CTX
, "tms sequence is %s",
1513 tap_uses_new_tms_table() ? "short": "long");
1518 static const struct command_registration jtag_command_handlers
[] = {
1520 .name
= "interface",
1521 .handler
= &handle_interface_command
,
1522 .mode
= COMMAND_CONFIG
,
1523 .help
= "select a JTAG interface",
1524 .usage
= "<driver_name>",
1527 .name
= "interface_list",
1528 .handler
= &handle_interface_list_command
,
1529 .mode
= COMMAND_ANY
,
1530 .help
= "list all built-in interfaces",
1534 .handler
= &handle_jtag_khz_command
,
1535 .mode
= COMMAND_ANY
,
1536 .help
= "set maximum jtag speed (if supported)",
1537 .usage
= "<khz:0=rtck>",
1540 .name
= "jtag_rclk",
1541 .handler
= &handle_jtag_rclk_command
,
1542 .mode
= COMMAND_ANY
,
1543 .help
= "set JTAG speed to RCLK or use fallback speed",
1544 .usage
= "<fallback_speed_khz>",
1547 .name
= "reset_config",
1548 .handler
= &handle_reset_config_command
,
1549 .mode
= COMMAND_ANY
,
1550 .help
= "configure JTAG reset behavior",
1551 .usage
= "[none|trst_only|srst_only|trst_and_srst] "
1552 "[srst_pulls_trst|trst_pulls_srst|combined|separate] "
1553 "[srst_gates_jtag|srst_nogate] "
1554 "[trst_push_pull|trst_open_drain] "
1555 "[srst_push_pull|srst_open_drain]",
1558 .name
= "jtag_nsrst_delay",
1559 .handler
= &handle_jtag_nsrst_delay_command
,
1560 .mode
= COMMAND_ANY
,
1561 .help
= "delay after deasserting srst in ms",
1565 .name
= "jtag_ntrst_delay",
1566 .handler
= &handle_jtag_ntrst_delay_command
,
1567 .mode
= COMMAND_ANY
,
1568 .help
= "delay after deasserting trst in ms",
1572 .name
= "jtag_nsrst_assert_width",
1573 .handler
= &handle_jtag_nsrst_assert_width_command
,
1574 .mode
= COMMAND_ANY
,
1575 .help
= "delay after asserting srst in ms",
1579 .name
= "jtag_ntrst_assert_width",
1580 .handler
= &handle_jtag_ntrst_assert_width_command
,
1581 .mode
= COMMAND_ANY
,
1582 .help
= "delay after asserting trst in ms",
1586 .name
= "scan_chain",
1587 .handler
= &handle_scan_chain_command
,
1588 .mode
= COMMAND_EXEC
,
1589 .help
= "print current scan chain configuration",
1592 .name
= "jtag_reset",
1593 .handler
= &handle_jtag_reset_command
,
1594 .mode
= COMMAND_EXEC
,
1595 .help
= "toggle reset lines",
1596 .usage
= "<trst> <srst>",
1600 .handler
= &handle_runtest_command
,
1601 .mode
= COMMAND_EXEC
,
1602 .help
= "move to Run-Test/Idle, and execute <num_cycles>",
1603 .usage
= "<num_cycles>"
1607 .handler
= &handle_irscan_command
,
1608 .mode
= COMMAND_EXEC
,
1609 .help
= "execute IR scan",
1610 .usage
= "<device> <instr> [dev2] [instr2] ...",
1613 .name
= "verify_ircapture",
1614 .handler
= &handle_verify_ircapture_command
,
1615 .mode
= COMMAND_ANY
,
1616 .help
= "verify value captured during Capture-IR",
1617 .usage
= "<enable | disable>",
1620 .name
= "verify_jtag",
1621 .handler
= &handle_verify_jtag_command
,
1622 .mode
= COMMAND_ANY
,
1623 .help
= "verify value capture",
1624 .usage
= "<enable | disable>",
1627 .name
= "tms_sequence",
1628 .handler
= &handle_tms_sequence_command
,
1629 .mode
= COMMAND_ANY
,
1630 .help
= "choose short(default) or long tms_sequence",
1631 .usage
= "<short | long>",
1635 .mode
= COMMAND_ANY
,
1636 .help
= "perform jtag tap actions",
1638 .chain
= jtag_subcommand_handlers
,
1641 .chain
= jtag_command_handlers_to_move
,
1643 COMMAND_REGISTRATION_DONE
1645 int jtag_register_commands(struct command_context
*cmd_ctx
)
1647 return register_commands(cmd_ctx
, NULL
, jtag_command_handlers
);
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)