You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1377 lines
35 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2007-2010 Øyvind Harboe *
  6. * oyvind.harboe@zylin.com *
  7. * *
  8. * Copyright (C) 2009 SoftPLC Corporation *
  9. * http://softplc.com *
  10. * dick@softplc.com *
  11. * *
  12. * Copyright (C) 2009 Zachary T Welch *
  13. * zw@superlucidity.net *
  14. * *
  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. *
  19. * *
  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. *
  24. * *
  25. * You should have received a copy of the GNU General Public License *
  26. * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  27. ***************************************************************************/
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. #include "jtag.h"
  32. #include "swd.h"
  33. #include "minidriver.h"
  34. #include "interface.h"
  35. #include "interfaces.h"
  36. #include "tcl.h"
  37. #ifdef HAVE_STRINGS_H
  38. #include <strings.h>
  39. #endif
  40. #include <helper/time_support.h>
  41. #include "transport/transport.h"
  42. /**
  43. * @file
  44. * Holds support for accessing JTAG-specific mechanisms from TCl scripts.
  45. */
  46. static const struct jim_nvp nvp_jtag_tap_event[] = {
  47. { .value = JTAG_TRST_ASSERTED, .name = "post-reset" },
  48. { .value = JTAG_TAP_EVENT_SETUP, .name = "setup" },
  49. { .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" },
  50. { .value = JTAG_TAP_EVENT_DISABLE, .name = "tap-disable" },
  51. { .name = NULL, .value = -1 }
  52. };
  53. struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
  54. {
  55. const char *cp = Jim_GetString(o, NULL);
  56. struct jtag_tap *t = cp ? jtag_tap_by_string(cp) : NULL;
  57. if (!cp)
  58. cp = "(unknown)";
  59. if (!t)
  60. Jim_SetResultFormatted(interp, "Tap '%s' could not be found", cp);
  61. return t;
  62. }
  63. static bool scan_is_safe(tap_state_t state)
  64. {
  65. switch (state) {
  66. case TAP_RESET:
  67. case TAP_IDLE:
  68. case TAP_DRPAUSE:
  69. case TAP_IRPAUSE:
  70. return true;
  71. default:
  72. return false;
  73. }
  74. }
  75. static int jim_command_drscan(Jim_Interp *interp, int argc, Jim_Obj * const *args)
  76. {
  77. int retval;
  78. struct scan_field *fields;
  79. int num_fields;
  80. int field_count = 0;
  81. int i, e;
  82. struct jtag_tap *tap;
  83. tap_state_t endstate;
  84. /* args[1] = device
  85. * args[2] = num_bits
  86. * args[3] = hex string
  87. * ... repeat num bits and hex string ...
  88. *
  89. * .. optionally:
  90. * args[N-2] = "-endstate"
  91. * args[N-1] = statename
  92. */
  93. if ((argc < 4) || ((argc % 2) != 0)) {
  94. Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
  95. return JIM_ERR;
  96. }
  97. endstate = TAP_IDLE;
  98. /* validate arguments as numbers */
  99. e = JIM_OK;
  100. for (i = 2; i < argc; i += 2) {
  101. long bits;
  102. const char *cp;
  103. e = Jim_GetLong(interp, args[i], &bits);
  104. /* If valid - try next arg */
  105. if (e == JIM_OK)
  106. continue;
  107. /* Not valid.. are we at the end? */
  108. if (((i + 2) != argc)) {
  109. /* nope, then error */
  110. return e;
  111. }
  112. /* it could be: "-endstate FOO"
  113. * e.g. DRPAUSE so we can issue more instructions
  114. * before entering RUN/IDLE and executing them.
  115. */
  116. /* get arg as a string. */
  117. cp = Jim_GetString(args[i], NULL);
  118. /* is it the magic? */
  119. if (strcmp("-endstate", cp) == 0) {
  120. /* is the statename valid? */
  121. cp = Jim_GetString(args[i + 1], NULL);
  122. /* see if it is a valid state name */
  123. endstate = tap_state_by_name(cp);
  124. if (endstate < 0) {
  125. /* update the error message */
  126. Jim_SetResultFormatted(interp, "endstate: %s invalid", cp);
  127. } else {
  128. if (!scan_is_safe(endstate))
  129. LOG_WARNING("drscan with unsafe "
  130. "endstate \"%s\"", cp);
  131. /* valid - so clear the error */
  132. e = JIM_OK;
  133. /* and remove the last 2 args */
  134. argc -= 2;
  135. }
  136. }
  137. /* Still an error? */
  138. if (e != JIM_OK)
  139. return e; /* too bad */
  140. } /* validate args */
  141. assert(e == JIM_OK);
  142. tap = jtag_tap_by_jim_obj(interp, args[1]);
  143. if (!tap)
  144. return JIM_ERR;
  145. num_fields = (argc-2)/2;
  146. if (num_fields <= 0) {
  147. Jim_SetResultString(interp, "drscan: no scan fields supplied", -1);
  148. return JIM_ERR;
  149. }
  150. fields = malloc(sizeof(struct scan_field) * num_fields);
  151. for (i = 2; i < argc; i += 2) {
  152. long bits;
  153. int len;
  154. const char *str;
  155. Jim_GetLong(interp, args[i], &bits);
  156. str = Jim_GetString(args[i + 1], &len);
  157. fields[field_count].num_bits = bits;
  158. void *t = malloc(DIV_ROUND_UP(bits, 8));
  159. fields[field_count].out_value = t;
  160. str_to_buf(str, len, t, bits, 0);
  161. fields[field_count].in_value = t;
  162. field_count++;
  163. }
  164. jtag_add_dr_scan(tap, num_fields, fields, endstate);
  165. retval = jtag_execute_queue();
  166. if (retval != ERROR_OK) {
  167. Jim_SetResultString(interp, "drscan: jtag execute failed", -1);
  168. for (i = 0; i < field_count; i++)
  169. free(fields[i].in_value);
  170. free(fields);
  171. return JIM_ERR;
  172. }
  173. field_count = 0;
  174. Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
  175. for (i = 2; i < argc; i += 2) {
  176. long bits;
  177. char *str;
  178. Jim_GetLong(interp, args[i], &bits);
  179. str = buf_to_hex_str(fields[field_count].in_value, bits);
  180. free(fields[field_count].in_value);
  181. Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str)));
  182. free(str);
  183. field_count++;
  184. }
  185. Jim_SetResult(interp, list);
  186. free(fields);
  187. return JIM_OK;
  188. }
  189. static int jim_command_pathmove(Jim_Interp *interp, int argc, Jim_Obj * const *args)
  190. {
  191. tap_state_t states[8];
  192. if ((argc < 2) || ((size_t)argc > (ARRAY_SIZE(states) + 1))) {
  193. Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
  194. return JIM_ERR;
  195. }
  196. int i;
  197. for (i = 0; i < argc-1; i++) {
  198. const char *cp;
  199. cp = Jim_GetString(args[i + 1], NULL);
  200. states[i] = tap_state_by_name(cp);
  201. if (states[i] < 0) {
  202. /* update the error message */
  203. Jim_SetResultFormatted(interp, "endstate: %s invalid", cp);
  204. return JIM_ERR;
  205. }
  206. }
  207. if ((jtag_add_statemove(states[0]) != ERROR_OK) || (jtag_execute_queue() != ERROR_OK)) {
  208. Jim_SetResultString(interp, "pathmove: jtag execute failed", -1);
  209. return JIM_ERR;
  210. }
  211. jtag_add_pathmove(argc - 2, states + 1);
  212. if (jtag_execute_queue() != ERROR_OK) {
  213. Jim_SetResultString(interp, "pathmove: failed", -1);
  214. return JIM_ERR;
  215. }
  216. return JIM_OK;
  217. }
  218. static int jim_command_flush_count(Jim_Interp *interp, int argc, Jim_Obj * const *args)
  219. {
  220. Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count()));
  221. return JIM_OK;
  222. }
  223. /* REVISIT Just what about these should "move" ... ?
  224. * These registrations, into the main JTAG table?
  225. *
  226. * There's a minor compatibility issue, these all show up twice;
  227. * that's not desirable:
  228. * - jtag drscan ... NOT DOCUMENTED!
  229. * - drscan ...
  230. *
  231. * The "irscan" command (for example) doesn't show twice.
  232. */
  233. static const struct command_registration jtag_command_handlers_to_move[] = {
  234. {
  235. .name = "drscan",
  236. .mode = COMMAND_EXEC,
  237. .jim_handler = jim_command_drscan,
  238. .help = "Execute Data Register (DR) scan for one TAP. "
  239. "Other TAPs must be in BYPASS mode.",
  240. .usage = "tap_name [num_bits value]* ['-endstate' state_name]",
  241. },
  242. {
  243. .name = "flush_count",
  244. .mode = COMMAND_EXEC,
  245. .jim_handler = jim_command_flush_count,
  246. .help = "Returns the number of times the JTAG queue "
  247. "has been flushed.",
  248. },
  249. {
  250. .name = "pathmove",
  251. .mode = COMMAND_EXEC,
  252. .jim_handler = jim_command_pathmove,
  253. .usage = "start_state state1 [state2 [state3 ...]]",
  254. .help = "Move JTAG state machine from current state "
  255. "(start_state) to state1, then state2, state3, etc.",
  256. },
  257. COMMAND_REGISTRATION_DONE
  258. };
  259. enum jtag_tap_cfg_param {
  260. JCFG_EVENT,
  261. JCFG_IDCODE,
  262. };
  263. static struct jim_nvp nvp_config_opts[] = {
  264. { .name = "-event", .value = JCFG_EVENT },
  265. { .name = "-idcode", .value = JCFG_IDCODE },
  266. { .name = NULL, .value = -1 }
  267. };
  268. static int jtag_tap_configure_event(struct jim_getopt_info *goi, struct jtag_tap *tap)
  269. {
  270. if (goi->argc == 0) {
  271. Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event <event-name> ...");
  272. return JIM_ERR;
  273. }
  274. struct jim_nvp *n;
  275. int e = jim_getopt_nvp(goi, nvp_jtag_tap_event, &n);
  276. if (e != JIM_OK) {
  277. jim_getopt_nvp_unknown(goi, nvp_jtag_tap_event, 1);
  278. return e;
  279. }
  280. if (goi->isconfigure) {
  281. if (goi->argc != 1) {
  282. Jim_WrongNumArgs(goi->interp,
  283. goi->argc,
  284. goi->argv,
  285. "-event <event-name> <event-body>");
  286. return JIM_ERR;
  287. }
  288. } else {
  289. if (goi->argc != 0) {
  290. Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event <event-name>");
  291. return JIM_ERR;
  292. }
  293. }
  294. struct jtag_tap_event_action *jteap = tap->event_action;
  295. /* replace existing event body */
  296. bool found = false;
  297. while (jteap) {
  298. if (jteap->event == (enum jtag_event)n->value) {
  299. found = true;
  300. break;
  301. }
  302. jteap = jteap->next;
  303. }
  304. Jim_SetEmptyResult(goi->interp);
  305. if (goi->isconfigure) {
  306. if (!found)
  307. jteap = calloc(1, sizeof(*jteap));
  308. else if (jteap->body)
  309. Jim_DecrRefCount(goi->interp, jteap->body);
  310. jteap->interp = goi->interp;
  311. jteap->event = n->value;
  312. Jim_Obj *o;
  313. jim_getopt_obj(goi, &o);
  314. jteap->body = Jim_DuplicateObj(goi->interp, o);
  315. Jim_IncrRefCount(jteap->body);
  316. if (!found) {
  317. /* add to head of event list */
  318. jteap->next = tap->event_action;
  319. tap->event_action = jteap;
  320. }
  321. } else if (found) {
  322. jteap->interp = goi->interp;
  323. Jim_SetResult(goi->interp,
  324. Jim_DuplicateObj(goi->interp, jteap->body));
  325. }
  326. return JIM_OK;
  327. }
  328. static int jtag_tap_configure_cmd(struct jim_getopt_info *goi, struct jtag_tap *tap)
  329. {
  330. /* parse config or cget options */
  331. while (goi->argc > 0) {
  332. Jim_SetEmptyResult(goi->interp);
  333. struct jim_nvp *n;
  334. int e = jim_getopt_nvp(goi, nvp_config_opts, &n);
  335. if (e != JIM_OK) {
  336. jim_getopt_nvp_unknown(goi, nvp_config_opts, 0);
  337. return e;
  338. }
  339. switch (n->value) {
  340. case JCFG_EVENT:
  341. e = jtag_tap_configure_event(goi, tap);
  342. if (e != JIM_OK)
  343. return e;
  344. break;
  345. case JCFG_IDCODE:
  346. if (goi->isconfigure) {
  347. Jim_SetResultFormatted(goi->interp,
  348. "not settable: %s", n->name);
  349. return JIM_ERR;
  350. } else {
  351. if (goi->argc != 0) {
  352. Jim_WrongNumArgs(goi->interp,
  353. goi->argc, goi->argv,
  354. "NO PARAMS");
  355. return JIM_ERR;
  356. }
  357. }
  358. Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, tap->idcode));
  359. break;
  360. default:
  361. Jim_SetResultFormatted(goi->interp, "unknown value: %s", n->name);
  362. return JIM_ERR;
  363. }
  364. }
  365. return JIM_OK;
  366. }
  367. static int is_bad_irval(int ir_length, jim_wide w)
  368. {
  369. jim_wide v = 1;
  370. v <<= ir_length;
  371. v -= 1;
  372. v = ~v;
  373. return (w & v) != 0;
  374. }
  375. static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi,
  376. struct jtag_tap *tap)
  377. {
  378. jim_wide w;
  379. int e = jim_getopt_wide(goi, &w);
  380. if (e != JIM_OK) {
  381. Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name);
  382. return e;
  383. }
  384. uint32_t *p = realloc(tap->expected_ids,
  385. (tap->expected_ids_cnt + 1) * sizeof(uint32_t));
  386. if (!p) {
  387. Jim_SetResultFormatted(goi->interp, "no memory");
  388. return JIM_ERR;
  389. }
  390. tap->expected_ids = p;
  391. tap->expected_ids[tap->expected_ids_cnt++] = w;
  392. return JIM_OK;
  393. }
  394. #define NTAP_OPT_IRLEN 0
  395. #define NTAP_OPT_IRMASK 1
  396. #define NTAP_OPT_IRCAPTURE 2
  397. #define NTAP_OPT_ENABLED 3
  398. #define NTAP_OPT_DISABLED 4
  399. #define NTAP_OPT_EXPECTED_ID 5
  400. #define NTAP_OPT_VERSION 6
  401. static int jim_newtap_ir_param(struct jim_nvp *n, struct jim_getopt_info *goi,
  402. struct jtag_tap *tap)
  403. {
  404. jim_wide w;
  405. int e = jim_getopt_wide(goi, &w);
  406. if (e != JIM_OK) {
  407. Jim_SetResultFormatted(goi->interp,
  408. "option: %s bad parameter", n->name);
  409. return e;
  410. }
  411. switch (n->value) {
  412. case NTAP_OPT_IRLEN:
  413. if (w > (jim_wide) (8 * sizeof(tap->ir_capture_value))) {
  414. LOG_WARNING("%s: huge IR length %d",
  415. tap->dotted_name, (int) w);
  416. }
  417. tap->ir_length = w;
  418. break;
  419. case NTAP_OPT_IRMASK:
  420. if (is_bad_irval(tap->ir_length, w)) {
  421. LOG_ERROR("%s: IR mask %x too big",
  422. tap->dotted_name,
  423. (int) w);
  424. return JIM_ERR;
  425. }
  426. if ((w & 3) != 3)
  427. LOG_WARNING("%s: nonstandard IR mask", tap->dotted_name);
  428. tap->ir_capture_mask = w;
  429. break;
  430. case NTAP_OPT_IRCAPTURE:
  431. if (is_bad_irval(tap->ir_length, w)) {
  432. LOG_ERROR("%s: IR capture %x too big",
  433. tap->dotted_name, (int) w);
  434. return JIM_ERR;
  435. }
  436. if ((w & 3) != 1)
  437. LOG_WARNING("%s: nonstandard IR value",
  438. tap->dotted_name);
  439. tap->ir_capture_value = w;
  440. break;
  441. default:
  442. return JIM_ERR;
  443. }
  444. return JIM_OK;
  445. }
  446. static int jim_newtap_cmd(struct jim_getopt_info *goi)
  447. {
  448. struct jtag_tap *tap;
  449. int x;
  450. int e;
  451. struct jim_nvp *n;
  452. char *cp;
  453. const struct jim_nvp opts[] = {
  454. { .name = "-irlen", .value = NTAP_OPT_IRLEN },
  455. { .name = "-irmask", .value = NTAP_OPT_IRMASK },
  456. { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE },
  457. { .name = "-enable", .value = NTAP_OPT_ENABLED },
  458. { .name = "-disable", .value = NTAP_OPT_DISABLED },
  459. { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID },
  460. { .name = "-ignore-version", .value = NTAP_OPT_VERSION },
  461. { .name = NULL, .value = -1 },
  462. };
  463. tap = calloc(1, sizeof(struct jtag_tap));
  464. if (!tap) {
  465. Jim_SetResultFormatted(goi->interp, "no memory");
  466. return JIM_ERR;
  467. }
  468. /*
  469. * we expect CHIP + TAP + OPTIONS
  470. * */
  471. if (goi->argc < 3) {
  472. Jim_SetResultFormatted(goi->interp, "Missing CHIP TAP OPTIONS ....");
  473. free(tap);
  474. return JIM_ERR;
  475. }
  476. const char *tmp;
  477. jim_getopt_string(goi, &tmp, NULL);
  478. tap->chip = strdup(tmp);
  479. jim_getopt_string(goi, &tmp, NULL);
  480. tap->tapname = strdup(tmp);
  481. /* name + dot + name + null */
  482. x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1;
  483. cp = malloc(x);
  484. sprintf(cp, "%s.%s", tap->chip, tap->tapname);
  485. tap->dotted_name = cp;
  486. LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
  487. tap->chip, tap->tapname, tap->dotted_name, goi->argc);
  488. if (!transport_is_jtag()) {
  489. /* SWD doesn't require any JTAG tap parameters */
  490. tap->enabled = true;
  491. jtag_tap_init(tap);
  492. return JIM_OK;
  493. }
  494. /* IEEE specifies that the two LSBs of an IR scan are 01, so make
  495. * that the default. The "-ircapture" and "-irmask" options are only
  496. * needed to cope with nonstandard TAPs, or to specify more bits.
  497. */
  498. tap->ir_capture_mask = 0x03;
  499. tap->ir_capture_value = 0x01;
  500. while (goi->argc) {
  501. e = jim_getopt_nvp(goi, opts, &n);
  502. if (e != JIM_OK) {
  503. jim_getopt_nvp_unknown(goi, opts, 0);
  504. free(cp);
  505. free(tap);
  506. return e;
  507. }
  508. LOG_DEBUG("Processing option: %s", n->name);
  509. switch (n->value) {
  510. case NTAP_OPT_ENABLED:
  511. tap->disabled_after_reset = false;
  512. break;
  513. case NTAP_OPT_DISABLED:
  514. tap->disabled_after_reset = true;
  515. break;
  516. case NTAP_OPT_EXPECTED_ID:
  517. e = jim_newtap_expected_id(n, goi, tap);
  518. if (e != JIM_OK) {
  519. free(cp);
  520. free(tap);
  521. return e;
  522. }
  523. break;
  524. case NTAP_OPT_IRLEN:
  525. case NTAP_OPT_IRMASK:
  526. case NTAP_OPT_IRCAPTURE:
  527. e = jim_newtap_ir_param(n, goi, tap);
  528. if (e != JIM_OK) {
  529. free(cp);
  530. free(tap);
  531. return e;
  532. }
  533. break;
  534. case NTAP_OPT_VERSION:
  535. tap->ignore_version = true;
  536. break;
  537. } /* switch (n->value) */
  538. } /* while (goi->argc) */
  539. /* default is enabled-after-reset */
  540. tap->enabled = !tap->disabled_after_reset;
  541. /* Did all the required option bits get cleared? */
  542. if (tap->ir_length != 0) {
  543. jtag_tap_init(tap);
  544. return JIM_OK;
  545. }
  546. Jim_SetResultFormatted(goi->interp,
  547. "newtap: %s missing IR length",
  548. tap->dotted_name);
  549. jtag_tap_free(tap);
  550. return JIM_ERR;
  551. }
  552. static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)
  553. {
  554. struct jtag_tap_event_action *jteap;
  555. int retval;
  556. for (jteap = tap->event_action; jteap; jteap = jteap->next) {
  557. if (jteap->event != e)
  558. continue;
  559. struct jim_nvp *nvp = jim_nvp_value2name_simple(nvp_jtag_tap_event, e);
  560. LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
  561. tap->dotted_name, e, nvp->name,
  562. Jim_GetString(jteap->body, NULL));
  563. retval = Jim_EvalObj(jteap->interp, jteap->body);
  564. if (retval == JIM_RETURN)
  565. retval = jteap->interp->returnCode;
  566. if (retval != JIM_OK) {
  567. Jim_MakeErrorMessage(jteap->interp);
  568. LOG_USER("%s", Jim_GetString(Jim_GetResult(jteap->interp), NULL));
  569. continue;
  570. }
  571. switch (e) {
  572. case JTAG_TAP_EVENT_ENABLE:
  573. case JTAG_TAP_EVENT_DISABLE:
  574. /* NOTE: we currently assume the handlers
  575. * can't fail. Right here is where we should
  576. * really be verifying the scan chains ...
  577. */
  578. tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);
  579. LOG_INFO("JTAG tap: %s %s", tap->dotted_name,
  580. tap->enabled ? "enabled" : "disabled");
  581. break;
  582. default:
  583. break;
  584. }
  585. }
  586. }
  587. static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
  588. {
  589. struct jim_getopt_info goi;
  590. jim_getopt_setup(&goi, interp, argc-1, argv + 1);
  591. if (goi.argc != 0) {
  592. Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
  593. return JIM_ERR;
  594. }
  595. struct command_context *context = current_command_context(interp);
  596. int e = jtag_init_inner(context);
  597. if (e != ERROR_OK) {
  598. Jim_Obj *obj = Jim_NewIntObj(goi.interp, e);
  599. Jim_SetResultFormatted(goi.interp, "error: %#s", obj);
  600. return JIM_ERR;
  601. }
  602. return JIM_OK;
  603. }
  604. static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
  605. {
  606. int e = ERROR_OK;
  607. struct jim_getopt_info goi;
  608. jim_getopt_setup(&goi, interp, argc-1, argv + 1);
  609. if (goi.argc != 0) {
  610. Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
  611. return JIM_ERR;
  612. }
  613. struct command_context *context = current_command_context(interp);
  614. if (transport_is_jtag())
  615. e = jtag_init_reset(context);
  616. else if (transport_is_swd())
  617. e = swd_init_reset(context);
  618. if (e != ERROR_OK) {
  619. Jim_Obj *obj = Jim_NewIntObj(goi.interp, e);
  620. Jim_SetResultFormatted(goi.interp, "error: %#s", obj);
  621. return JIM_ERR;
  622. }
  623. return JIM_OK;
  624. }
  625. int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
  626. {
  627. struct jim_getopt_info goi;
  628. jim_getopt_setup(&goi, interp, argc-1, argv + 1);
  629. return jim_newtap_cmd(&goi);
  630. }
  631. static bool jtag_tap_enable(struct jtag_tap *t)
  632. {
  633. if (t->enabled)
  634. return false;
  635. jtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE);
  636. if (!t->enabled)
  637. return false;
  638. /* FIXME add JTAG sanity checks, w/o TLR
  639. * - scan chain length grew by one (this)
  640. * - IDs and IR lengths are as expected
  641. */
  642. jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE);
  643. return true;
  644. }
  645. static bool jtag_tap_disable(struct jtag_tap *t)
  646. {
  647. if (!t->enabled)
  648. return false;
  649. jtag_tap_handle_event(t, JTAG_TAP_EVENT_DISABLE);
  650. if (t->enabled)
  651. return false;
  652. /* FIXME add JTAG sanity checks, w/o TLR
  653. * - scan chain length shrank by one (this)
  654. * - IDs and IR lengths are as expected
  655. */
  656. jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE);
  657. return true;
  658. }
  659. int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
  660. {
  661. struct command *c = jim_to_command(interp);
  662. const char *cmd_name = c->name;
  663. struct jim_getopt_info goi;
  664. jim_getopt_setup(&goi, interp, argc-1, argv + 1);
  665. if (goi.argc != 1) {
  666. Jim_SetResultFormatted(goi.interp, "usage: %s <name>", cmd_name);
  667. return JIM_ERR;
  668. }
  669. struct jtag_tap *t;
  670. t = jtag_tap_by_jim_obj(goi.interp, goi.argv[0]);
  671. if (!t)
  672. return JIM_ERR;
  673. if (strcasecmp(cmd_name, "tapisenabled") == 0) {
  674. /* do nothing, just return the value */
  675. } else if (strcasecmp(cmd_name, "tapenable") == 0) {
  676. if (!jtag_tap_enable(t)) {
  677. LOG_WARNING("failed to enable tap %s", t->dotted_name);
  678. return JIM_ERR;
  679. }
  680. } else if (strcasecmp(cmd_name, "tapdisable") == 0) {
  681. if (!jtag_tap_disable(t)) {
  682. LOG_WARNING("failed to disable tap %s", t->dotted_name);
  683. return JIM_ERR;
  684. }
  685. } else {
  686. LOG_ERROR("command '%s' unknown", cmd_name);
  687. return JIM_ERR;
  688. }
  689. bool e = t->enabled;
  690. Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, e));
  691. return JIM_OK;
  692. }
  693. int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
  694. {
  695. struct command *c = jim_to_command(interp);
  696. const char *cmd_name = c->name;
  697. struct jim_getopt_info goi;
  698. jim_getopt_setup(&goi, interp, argc-1, argv + 1);
  699. goi.isconfigure = !strcmp(cmd_name, "configure");
  700. if (goi.argc < 2 + goi.isconfigure) {
  701. Jim_WrongNumArgs(goi.interp, 0, NULL,
  702. "<tap_name> <attribute> ...");
  703. return JIM_ERR;
  704. }
  705. struct jtag_tap *t;
  706. Jim_Obj *o;
  707. jim_getopt_obj(&goi, &o);
  708. t = jtag_tap_by_jim_obj(goi.interp, o);
  709. if (!t)
  710. return JIM_ERR;
  711. return jtag_tap_configure_cmd(&goi, t);
  712. }
  713. static int jim_jtag_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
  714. {
  715. struct jim_getopt_info goi;
  716. jim_getopt_setup(&goi, interp, argc-1, argv + 1);
  717. if (goi.argc != 0) {
  718. Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
  719. return JIM_ERR;
  720. }
  721. Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
  722. struct jtag_tap *tap;
  723. for (tap = jtag_all_taps(); tap; tap = tap->next_tap) {
  724. Jim_ListAppendElement(goi.interp,
  725. Jim_GetResult(goi.interp),
  726. Jim_NewStringObj(goi.interp,
  727. tap->dotted_name, -1));
  728. }
  729. return JIM_OK;
  730. }
  731. COMMAND_HANDLER(handle_jtag_init_command)
  732. {
  733. if (CMD_ARGC != 0)
  734. return ERROR_COMMAND_SYNTAX_ERROR;
  735. static bool jtag_initialized;
  736. if (jtag_initialized) {
  737. LOG_INFO("'jtag init' has already been called");
  738. return ERROR_OK;
  739. }
  740. jtag_initialized = true;
  741. LOG_DEBUG("Initializing jtag devices...");
  742. return jtag_init(CMD_CTX);
  743. }
  744. static const struct command_registration jtag_subcommand_handlers[] = {
  745. {
  746. .name = "init",
  747. .mode = COMMAND_ANY,
  748. .handler = handle_jtag_init_command,
  749. .help = "initialize jtag scan chain",
  750. .usage = ""
  751. },
  752. {
  753. .name = "arp_init",
  754. .mode = COMMAND_ANY,
  755. .jim_handler = jim_jtag_arp_init,
  756. .help = "Validates JTAG scan chain against the list of "
  757. "declared TAPs using just the four standard JTAG "
  758. "signals.",
  759. },
  760. {
  761. .name = "arp_init-reset",
  762. .mode = COMMAND_ANY,
  763. .jim_handler = jim_jtag_arp_init_reset,
  764. .help = "Uses TRST and SRST to try resetting everything on "
  765. "the JTAG scan chain, then performs 'jtag arp_init'."
  766. },
  767. {
  768. .name = "newtap",
  769. .mode = COMMAND_CONFIG,
  770. .jim_handler = jim_jtag_newtap,
  771. .help = "Create a new TAP instance named basename.tap_type, "
  772. "and appends it to the scan chain.",
  773. .usage = "basename tap_type '-irlen' count "
  774. "['-enable'|'-disable'] "
  775. "['-expected_id' number] "
  776. "['-ignore-version'] "
  777. "['-ircapture' number] "
  778. "['-mask' number]",
  779. },
  780. {
  781. .name = "tapisenabled",
  782. .mode = COMMAND_EXEC,
  783. .jim_handler = jim_jtag_tap_enabler,
  784. .help = "Returns a Tcl boolean (0/1) indicating whether "
  785. "the TAP is enabled (1) or not (0).",
  786. .usage = "tap_name",
  787. },
  788. {
  789. .name = "tapenable",
  790. .mode = COMMAND_EXEC,
  791. .jim_handler = jim_jtag_tap_enabler,
  792. .help = "Try to enable the specified TAP using the "
  793. "'tap-enable' TAP event.",
  794. .usage = "tap_name",
  795. },
  796. {
  797. .name = "tapdisable",
  798. .mode = COMMAND_EXEC,
  799. .jim_handler = jim_jtag_tap_enabler,
  800. .help = "Try to disable the specified TAP using the "
  801. "'tap-disable' TAP event.",
  802. .usage = "tap_name",
  803. },
  804. {
  805. .name = "configure",
  806. .mode = COMMAND_ANY,
  807. .jim_handler = jim_jtag_configure,
  808. .help = "Provide a Tcl handler for the specified "
  809. "TAP event.",
  810. .usage = "tap_name '-event' event_name handler",
  811. },
  812. {
  813. .name = "cget",
  814. .mode = COMMAND_EXEC,
  815. .jim_handler = jim_jtag_configure,
  816. .help = "Return any Tcl handler for the specified "
  817. "TAP event.",
  818. .usage = "tap_name '-event' event_name",
  819. },
  820. {
  821. .name = "names",
  822. .mode = COMMAND_ANY,
  823. .jim_handler = jim_jtag_names,
  824. .help = "Returns list of all JTAG tap names.",
  825. },
  826. {
  827. .chain = jtag_command_handlers_to_move,
  828. },
  829. COMMAND_REGISTRATION_DONE
  830. };
  831. void jtag_notify_event(enum jtag_event event)
  832. {
  833. struct jtag_tap *tap;
  834. for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
  835. jtag_tap_handle_event(tap, event);
  836. }
  837. COMMAND_HANDLER(handle_scan_chain_command)
  838. {
  839. struct jtag_tap *tap;
  840. char expected_id[12];
  841. tap = jtag_all_taps();
  842. command_print(CMD,
  843. " TapName Enabled IdCode Expected IrLen IrCap IrMask");
  844. command_print(CMD,
  845. "-- ------------------- -------- ---------- ---------- ----- ----- ------");
  846. while (tap) {
  847. uint32_t expected, expected_mask, ii;
  848. snprintf(expected_id, sizeof(expected_id), "0x%08x",
  849. (unsigned)((tap->expected_ids_cnt > 0)
  850. ? tap->expected_ids[0]
  851. : 0));
  852. if (tap->ignore_version)
  853. expected_id[2] = '*';
  854. expected = buf_get_u32(tap->expected, 0, tap->ir_length);
  855. expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
  856. command_print(CMD,
  857. "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
  858. tap->abs_chain_position,
  859. tap->dotted_name,
  860. tap->enabled ? 'Y' : 'n',
  861. (unsigned int)(tap->idcode),
  862. expected_id,
  863. (unsigned int)(tap->ir_length),
  864. (unsigned int)(expected),
  865. (unsigned int)(expected_mask));
  866. for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
  867. snprintf(expected_id, sizeof(expected_id), "0x%08x",
  868. (unsigned) tap->expected_ids[ii]);
  869. if (tap->ignore_version)
  870. expected_id[2] = '*';
  871. command_print(CMD,
  872. " %s",
  873. expected_id);
  874. }
  875. tap = tap->next_tap;
  876. }
  877. return ERROR_OK;
  878. }
  879. COMMAND_HANDLER(handle_jtag_ntrst_delay_command)
  880. {
  881. if (CMD_ARGC > 1)
  882. return ERROR_COMMAND_SYNTAX_ERROR;
  883. if (CMD_ARGC == 1) {
  884. unsigned delay;
  885. COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
  886. jtag_set_ntrst_delay(delay);
  887. }
  888. command_print(CMD, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
  889. return ERROR_OK;
  890. }
  891. COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command)
  892. {
  893. if (CMD_ARGC > 1)
  894. return ERROR_COMMAND_SYNTAX_ERROR;
  895. if (CMD_ARGC == 1) {
  896. unsigned delay;
  897. COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
  898. jtag_set_ntrst_assert_width(delay);
  899. }
  900. command_print(CMD, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
  901. return ERROR_OK;
  902. }
  903. COMMAND_HANDLER(handle_jtag_rclk_command)
  904. {
  905. if (CMD_ARGC > 1)
  906. return ERROR_COMMAND_SYNTAX_ERROR;
  907. int retval = ERROR_OK;
  908. if (CMD_ARGC == 1) {
  909. unsigned khz = 0;
  910. COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);
  911. retval = jtag_config_rclk(khz);
  912. if (retval != ERROR_OK)
  913. return retval;
  914. }
  915. int cur_khz = jtag_get_speed_khz();
  916. retval = jtag_get_speed_readable(&cur_khz);
  917. if (retval != ERROR_OK)
  918. return retval;
  919. if (cur_khz)
  920. command_print(CMD, "RCLK not supported - fallback to %d kHz", cur_khz);
  921. else
  922. command_print(CMD, "RCLK - adaptive");
  923. return retval;
  924. }
  925. COMMAND_HANDLER(handle_runtest_command)
  926. {
  927. if (CMD_ARGC != 1)
  928. return ERROR_COMMAND_SYNTAX_ERROR;
  929. unsigned num_clocks;
  930. COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num_clocks);
  931. jtag_add_runtest(num_clocks, TAP_IDLE);
  932. return jtag_execute_queue();
  933. }
  934. /*
  935. * For "irscan" or "drscan" commands, the "end" (really, "next") state
  936. * should be stable ... and *NOT* a shift state, otherwise free-running
  937. * jtag clocks could change the values latched by the update state.
  938. * Not surprisingly, this is the same constraint as SVF; the "irscan"
  939. * and "drscan" commands are a write-only subset of what SVF provides.
  940. */
  941. COMMAND_HANDLER(handle_irscan_command)
  942. {
  943. int i;
  944. struct scan_field *fields;
  945. struct jtag_tap *tap = NULL;
  946. tap_state_t endstate;
  947. if ((CMD_ARGC < 2) || (CMD_ARGC % 2))
  948. return ERROR_COMMAND_SYNTAX_ERROR;
  949. /* optional "-endstate" "statename" at the end of the arguments,
  950. * so that e.g. IRPAUSE can let us load the data register before
  951. * entering RUN/IDLE to execute the instruction we load here.
  952. */
  953. endstate = TAP_IDLE;
  954. if (CMD_ARGC >= 4) {
  955. /* have at least one pair of numbers.
  956. * is last pair the magic text? */
  957. if (strcmp("-endstate", CMD_ARGV[CMD_ARGC - 2]) == 0) {
  958. endstate = tap_state_by_name(CMD_ARGV[CMD_ARGC - 1]);
  959. if (endstate == TAP_INVALID)
  960. return ERROR_COMMAND_SYNTAX_ERROR;
  961. if (!scan_is_safe(endstate))
  962. LOG_WARNING("unstable irscan endstate \"%s\"",
  963. CMD_ARGV[CMD_ARGC - 1]);
  964. CMD_ARGC -= 2;
  965. }
  966. }
  967. int num_fields = CMD_ARGC / 2;
  968. if (num_fields > 1) {
  969. /* we really should be looking at plain_ir_scan if we want
  970. * anything more fancy.
  971. */
  972. LOG_ERROR("Specify a single value for tap");
  973. return ERROR_COMMAND_SYNTAX_ERROR;
  974. }
  975. fields = calloc(num_fields, sizeof(*fields));
  976. int retval;
  977. for (i = 0; i < num_fields; i++) {
  978. tap = jtag_tap_by_string(CMD_ARGV[i*2]);
  979. if (!tap) {
  980. free(fields);
  981. command_print(CMD, "Tap: %s unknown", CMD_ARGV[i*2]);
  982. return ERROR_FAIL;
  983. }
  984. uint64_t value;
  985. retval = parse_u64(CMD_ARGV[i * 2 + 1], &value);
  986. if (retval != ERROR_OK)
  987. goto error_return;
  988. int field_size = tap->ir_length;
  989. fields[i].num_bits = field_size;
  990. uint8_t *v = calloc(1, DIV_ROUND_UP(field_size, 8));
  991. if (!v) {
  992. LOG_ERROR("Out of memory");
  993. goto error_return;
  994. }
  995. buf_set_u64(v, 0, field_size, value);
  996. fields[i].out_value = v;
  997. fields[i].in_value = NULL;
  998. }
  999. /* did we have an endstate? */
  1000. jtag_add_ir_scan(tap, fields, endstate);
  1001. retval = jtag_execute_queue();
  1002. error_return:
  1003. for (i = 0; i < num_fields; i++)
  1004. free((void *)fields[i].out_value);
  1005. free(fields);
  1006. return retval;
  1007. }
  1008. COMMAND_HANDLER(handle_verify_ircapture_command)
  1009. {
  1010. if (CMD_ARGC > 1)
  1011. return ERROR_COMMAND_SYNTAX_ERROR;
  1012. if (CMD_ARGC == 1) {
  1013. bool enable;
  1014. COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
  1015. jtag_set_verify_capture_ir(enable);
  1016. }
  1017. const char *status = jtag_will_verify_capture_ir() ? "enabled" : "disabled";
  1018. command_print(CMD, "verify Capture-IR is %s", status);
  1019. return ERROR_OK;
  1020. }
  1021. COMMAND_HANDLER(handle_verify_jtag_command)
  1022. {
  1023. if (CMD_ARGC > 1)
  1024. return ERROR_COMMAND_SYNTAX_ERROR;
  1025. if (CMD_ARGC == 1) {
  1026. bool enable;
  1027. COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
  1028. jtag_set_verify(enable);
  1029. }
  1030. const char *status = jtag_will_verify() ? "enabled" : "disabled";
  1031. command_print(CMD, "verify jtag capture is %s", status);
  1032. return ERROR_OK;
  1033. }
  1034. COMMAND_HANDLER(handle_tms_sequence_command)
  1035. {
  1036. if (CMD_ARGC > 1)
  1037. return ERROR_COMMAND_SYNTAX_ERROR;
  1038. if (CMD_ARGC == 1) {
  1039. bool use_new_table;
  1040. if (strcmp(CMD_ARGV[0], "short") == 0)
  1041. use_new_table = true;
  1042. else if (strcmp(CMD_ARGV[0], "long") == 0)
  1043. use_new_table = false;
  1044. else
  1045. return ERROR_COMMAND_SYNTAX_ERROR;
  1046. tap_use_new_tms_table(use_new_table);
  1047. }
  1048. command_print(CMD, "tms sequence is %s",
  1049. tap_uses_new_tms_table() ? "short" : "long");
  1050. return ERROR_OK;
  1051. }
  1052. COMMAND_HANDLER(handle_jtag_flush_queue_sleep)
  1053. {
  1054. if (CMD_ARGC != 1)
  1055. return ERROR_COMMAND_SYNTAX_ERROR;
  1056. int sleep_ms;
  1057. COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], sleep_ms);
  1058. jtag_set_flush_queue_sleep(sleep_ms);
  1059. return ERROR_OK;
  1060. }
  1061. COMMAND_HANDLER(handle_wait_srst_deassert)
  1062. {
  1063. if (CMD_ARGC != 1)
  1064. return ERROR_COMMAND_SYNTAX_ERROR;
  1065. int timeout_ms;
  1066. COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], timeout_ms);
  1067. if ((timeout_ms <= 0) || (timeout_ms > 100000)) {
  1068. LOG_ERROR("Timeout must be an integer between 0 and 100000");
  1069. return ERROR_FAIL;
  1070. }
  1071. LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms);
  1072. int asserted_yet;
  1073. int64_t then = timeval_ms();
  1074. while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {
  1075. if ((timeval_ms() - then) > timeout_ms) {
  1076. LOG_ERROR("Timed out");
  1077. return ERROR_FAIL;
  1078. }
  1079. if (asserted_yet)
  1080. break;
  1081. }
  1082. while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {
  1083. if ((timeval_ms() - then) > timeout_ms) {
  1084. LOG_ERROR("Timed out");
  1085. return ERROR_FAIL;
  1086. }
  1087. if (!asserted_yet)
  1088. break;
  1089. }
  1090. return ERROR_OK;
  1091. }
  1092. static const struct command_registration jtag_command_handlers[] = {
  1093. {
  1094. .name = "jtag_flush_queue_sleep",
  1095. .handler = handle_jtag_flush_queue_sleep,
  1096. .mode = COMMAND_ANY,
  1097. .help = "For debug purposes(simulate long delays of interface) "
  1098. "to test performance or change in behavior. Default 0ms.",
  1099. .usage = "[sleep in ms]",
  1100. },
  1101. {
  1102. .name = "jtag_rclk",
  1103. .handler = handle_jtag_rclk_command,
  1104. .mode = COMMAND_ANY,
  1105. .help = "With an argument, change to to use adaptive clocking "
  1106. "if possible; else to use the fallback speed. "
  1107. "With or without argument, display current setting.",
  1108. .usage = "[fallback_speed_khz]",
  1109. },
  1110. {
  1111. .name = "jtag_ntrst_delay",
  1112. .handler = handle_jtag_ntrst_delay_command,
  1113. .mode = COMMAND_ANY,
  1114. .help = "delay after deasserting trst in ms",
  1115. .usage = "[milliseconds]",
  1116. },
  1117. {
  1118. .name = "jtag_ntrst_assert_width",
  1119. .handler = handle_jtag_ntrst_assert_width_command,
  1120. .mode = COMMAND_ANY,
  1121. .help = "delay after asserting trst in ms",
  1122. .usage = "[milliseconds]",
  1123. },
  1124. {
  1125. .name = "scan_chain",
  1126. .handler = handle_scan_chain_command,
  1127. .mode = COMMAND_ANY,
  1128. .help = "print current scan chain configuration",
  1129. .usage = ""
  1130. },
  1131. {
  1132. .name = "runtest",
  1133. .handler = handle_runtest_command,
  1134. .mode = COMMAND_EXEC,
  1135. .help = "Move to Run-Test/Idle, and issue TCK for num_cycles.",
  1136. .usage = "num_cycles"
  1137. },
  1138. {
  1139. .name = "irscan",
  1140. .handler = handle_irscan_command,
  1141. .mode = COMMAND_EXEC,
  1142. .help = "Execute Instruction Register (IR) scan. The "
  1143. "specified opcodes are put into each TAP's IR, "
  1144. "and other TAPs are put in BYPASS.",
  1145. .usage = "[tap_name instruction]* ['-endstate' state_name]",
  1146. },
  1147. {
  1148. .name = "verify_ircapture",
  1149. .handler = handle_verify_ircapture_command,
  1150. .mode = COMMAND_ANY,
  1151. .help = "Display or assign flag controlling whether to "
  1152. "verify values captured during Capture-IR.",
  1153. .usage = "['enable'|'disable']",
  1154. },
  1155. {
  1156. .name = "verify_jtag",
  1157. .handler = handle_verify_jtag_command,
  1158. .mode = COMMAND_ANY,
  1159. .help = "Display or assign flag controlling whether to "
  1160. "verify values captured during IR and DR scans.",
  1161. .usage = "['enable'|'disable']",
  1162. },
  1163. {
  1164. .name = "tms_sequence",
  1165. .handler = handle_tms_sequence_command,
  1166. .mode = COMMAND_ANY,
  1167. .help = "Display or change what style TMS sequences to use "
  1168. "for JTAG state transitions: short (default) or "
  1169. "long. Only for working around JTAG bugs.",
  1170. /* Specifically for working around DRIVER bugs... */
  1171. .usage = "['short'|'long']",
  1172. },
  1173. {
  1174. .name = "wait_srst_deassert",
  1175. .handler = handle_wait_srst_deassert,
  1176. .mode = COMMAND_ANY,
  1177. .help = "Wait for an SRST deassert. "
  1178. "Useful for cases where you need something to happen within ms "
  1179. "of an srst deassert. Timeout in ms",
  1180. .usage = "ms",
  1181. },
  1182. {
  1183. .name = "jtag",
  1184. .mode = COMMAND_ANY,
  1185. .help = "perform jtag tap actions",
  1186. .usage = "",
  1187. .chain = jtag_subcommand_handlers,
  1188. },
  1189. {
  1190. .chain = jtag_command_handlers_to_move,
  1191. },
  1192. COMMAND_REGISTRATION_DONE
  1193. };
  1194. int jtag_register_commands(struct command_context *cmd_ctx)
  1195. {
  1196. return register_commands(cmd_ctx, NULL, jtag_command_handlers);
  1197. }