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.
 
 
 
 
 
 

422 lines
12 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/jtag.h>
  32. #include <jtag/interface.h>
  33. #include <jtag/commands.h>
  34. #include <jtag/minidriver.h>
  35. #include <helper/command.h>
  36. struct jtag_callback_entry {
  37. struct jtag_callback_entry *next;
  38. jtag_callback_t callback;
  39. jtag_callback_data_t data0;
  40. jtag_callback_data_t data1;
  41. jtag_callback_data_t data2;
  42. jtag_callback_data_t data3;
  43. };
  44. static struct jtag_callback_entry *jtag_callback_queue_head;
  45. static struct jtag_callback_entry *jtag_callback_queue_tail;
  46. static void jtag_callback_queue_reset(void)
  47. {
  48. jtag_callback_queue_head = NULL;
  49. jtag_callback_queue_tail = NULL;
  50. }
  51. /**
  52. * Copy a struct scan_field for insertion into the queue.
  53. *
  54. * This allocates a new copy of out_value using cmd_queue_alloc.
  55. */
  56. static void cmd_queue_scan_field_clone(struct scan_field *dst, const struct scan_field *src)
  57. {
  58. dst->num_bits = src->num_bits;
  59. dst->out_value = buf_cpy(src->out_value, cmd_queue_alloc(DIV_ROUND_UP(src->num_bits, 8)), src->num_bits);
  60. dst->in_value = src->in_value;
  61. }
  62. /**
  63. * see jtag_add_ir_scan()
  64. *
  65. */
  66. int interface_jtag_add_ir_scan(struct jtag_tap *active,
  67. const struct scan_field *in_fields, tap_state_t state)
  68. {
  69. size_t num_taps = jtag_tap_count_enabled();
  70. struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  71. struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));
  72. struct scan_field *out_fields = cmd_queue_alloc(num_taps * sizeof(struct scan_field));
  73. jtag_queue_command(cmd);
  74. cmd->type = JTAG_SCAN;
  75. cmd->cmd.scan = scan;
  76. scan->ir_scan = true;
  77. scan->num_fields = num_taps; /* one field per device */
  78. scan->fields = out_fields;
  79. scan->end_state = state;
  80. struct scan_field *field = out_fields; /* keep track where we insert data */
  81. /* loop over all enabled TAPs */
  82. for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap)) {
  83. /* search the input field list for fields for the current TAP */
  84. if (tap == active) {
  85. /* if TAP is listed in input fields, copy the value */
  86. tap->bypass = 0;
  87. cmd_queue_scan_field_clone(field, in_fields);
  88. } else {
  89. /* if a TAP isn't listed in input fields, set it to BYPASS */
  90. tap->bypass = 1;
  91. field->num_bits = tap->ir_length;
  92. field->out_value = buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8)), tap->ir_length);
  93. field->in_value = NULL; /* do not collect input for tap's in bypass */
  94. }
  95. /* update device information */
  96. buf_cpy(field->out_value, tap->cur_instr, tap->ir_length);
  97. field++;
  98. }
  99. /* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */
  100. assert(field == out_fields + num_taps);
  101. return ERROR_OK;
  102. }
  103. /**
  104. * see jtag_add_dr_scan()
  105. *
  106. */
  107. int interface_jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields,
  108. const struct scan_field *in_fields, tap_state_t state)
  109. {
  110. /* count devices in bypass */
  111. size_t bypass_devices = 0;
  112. for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap)) {
  113. if (tap->bypass)
  114. bypass_devices++;
  115. }
  116. struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  117. struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));
  118. struct scan_field *out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(struct scan_field));
  119. jtag_queue_command(cmd);
  120. cmd->type = JTAG_SCAN;
  121. cmd->cmd.scan = scan;
  122. scan->ir_scan = false;
  123. scan->num_fields = in_num_fields + bypass_devices;
  124. scan->fields = out_fields;
  125. scan->end_state = state;
  126. struct scan_field *field = out_fields; /* keep track where we insert data */
  127. /* loop over all enabled TAPs */
  128. for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap)) {
  129. /* if TAP is not bypassed insert matching input fields */
  130. if (!tap->bypass) {
  131. assert(active == tap);
  132. #ifndef NDEBUG
  133. /* remember initial position for assert() */
  134. struct scan_field *start_field = field;
  135. #endif /* NDEBUG */
  136. for (int j = 0; j < in_num_fields; j++) {
  137. cmd_queue_scan_field_clone(field, in_fields + j);
  138. field++;
  139. }
  140. assert(field > start_field); /* must have at least one input field per not bypassed TAP */
  141. }
  142. /* if a TAP is bypassed, generated a dummy bit*/
  143. else {
  144. field->num_bits = 1;
  145. field->out_value = NULL;
  146. field->in_value = NULL;
  147. field++;
  148. }
  149. }
  150. assert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */
  151. return ERROR_OK;
  152. }
  153. static int jtag_add_plain_scan(int num_bits, const uint8_t *out_bits,
  154. uint8_t *in_bits, tap_state_t state, bool ir_scan)
  155. {
  156. struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  157. struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));
  158. struct scan_field *out_fields = cmd_queue_alloc(sizeof(struct scan_field));
  159. jtag_queue_command(cmd);
  160. cmd->type = JTAG_SCAN;
  161. cmd->cmd.scan = scan;
  162. scan->ir_scan = ir_scan;
  163. scan->num_fields = 1;
  164. scan->fields = out_fields;
  165. scan->end_state = state;
  166. out_fields->num_bits = num_bits;
  167. out_fields->out_value = buf_cpy(out_bits, cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);
  168. out_fields->in_value = in_bits;
  169. return ERROR_OK;
  170. }
  171. int interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)
  172. {
  173. return jtag_add_plain_scan(num_bits, out_bits, in_bits, state, false);
  174. }
  175. int interface_jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)
  176. {
  177. return jtag_add_plain_scan(num_bits, out_bits, in_bits, state, true);
  178. }
  179. int interface_jtag_add_tlr(void)
  180. {
  181. tap_state_t state = TAP_RESET;
  182. /* allocate memory for a new list member */
  183. struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  184. jtag_queue_command(cmd);
  185. cmd->type = JTAG_TLR_RESET;
  186. cmd->cmd.statemove = cmd_queue_alloc(sizeof(struct statemove_command));
  187. cmd->cmd.statemove->end_state = state;
  188. return ERROR_OK;
  189. }
  190. int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state)
  191. {
  192. struct jtag_command *cmd;
  193. cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  194. if (cmd == NULL)
  195. return ERROR_FAIL;
  196. cmd->type = JTAG_TMS;
  197. cmd->cmd.tms = cmd_queue_alloc(sizeof(*cmd->cmd.tms));
  198. if (!cmd->cmd.tms)
  199. return ERROR_FAIL;
  200. /* copy the bits; our caller doesn't guarantee they'll persist */
  201. cmd->cmd.tms->num_bits = num_bits;
  202. cmd->cmd.tms->bits = buf_cpy(seq,
  203. cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);
  204. if (!cmd->cmd.tms->bits)
  205. return ERROR_FAIL;
  206. jtag_queue_command(cmd);
  207. return ERROR_OK;
  208. }
  209. int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
  210. {
  211. /* allocate memory for a new list member */
  212. struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  213. jtag_queue_command(cmd);
  214. cmd->type = JTAG_PATHMOVE;
  215. cmd->cmd.pathmove = cmd_queue_alloc(sizeof(struct pathmove_command));
  216. cmd->cmd.pathmove->num_states = num_states;
  217. cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states);
  218. for (int i = 0; i < num_states; i++)
  219. cmd->cmd.pathmove->path[i] = path[i];
  220. return ERROR_OK;
  221. }
  222. int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
  223. {
  224. /* allocate memory for a new list member */
  225. struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  226. jtag_queue_command(cmd);
  227. cmd->type = JTAG_RUNTEST;
  228. cmd->cmd.runtest = cmd_queue_alloc(sizeof(struct runtest_command));
  229. cmd->cmd.runtest->num_cycles = num_cycles;
  230. cmd->cmd.runtest->end_state = state;
  231. return ERROR_OK;
  232. }
  233. int interface_jtag_add_clocks(int num_cycles)
  234. {
  235. /* allocate memory for a new list member */
  236. struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  237. jtag_queue_command(cmd);
  238. cmd->type = JTAG_STABLECLOCKS;
  239. cmd->cmd.stableclocks = cmd_queue_alloc(sizeof(struct stableclocks_command));
  240. cmd->cmd.stableclocks->num_cycles = num_cycles;
  241. return ERROR_OK;
  242. }
  243. int interface_jtag_add_reset(int req_trst, int req_srst)
  244. {
  245. /* allocate memory for a new list member */
  246. struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  247. jtag_queue_command(cmd);
  248. cmd->type = JTAG_RESET;
  249. cmd->cmd.reset = cmd_queue_alloc(sizeof(struct reset_command));
  250. cmd->cmd.reset->trst = req_trst;
  251. cmd->cmd.reset->srst = req_srst;
  252. return ERROR_OK;
  253. }
  254. int interface_jtag_add_sleep(uint32_t us)
  255. {
  256. /* allocate memory for a new list member */
  257. struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
  258. jtag_queue_command(cmd);
  259. cmd->type = JTAG_SLEEP;
  260. cmd->cmd.sleep = cmd_queue_alloc(sizeof(struct sleep_command));
  261. cmd->cmd.sleep->us = us;
  262. return ERROR_OK;
  263. }
  264. /* add callback to end of queue */
  265. void interface_jtag_add_callback4(jtag_callback_t callback,
  266. jtag_callback_data_t data0, jtag_callback_data_t data1,
  267. jtag_callback_data_t data2, jtag_callback_data_t data3)
  268. {
  269. struct jtag_callback_entry *entry = cmd_queue_alloc(sizeof(struct jtag_callback_entry));
  270. entry->next = NULL;
  271. entry->callback = callback;
  272. entry->data0 = data0;
  273. entry->data1 = data1;
  274. entry->data2 = data2;
  275. entry->data3 = data3;
  276. if (jtag_callback_queue_head == NULL) {
  277. jtag_callback_queue_head = entry;
  278. jtag_callback_queue_tail = entry;
  279. } else {
  280. jtag_callback_queue_tail->next = entry;
  281. jtag_callback_queue_tail = entry;
  282. }
  283. }
  284. int interface_jtag_execute_queue(void)
  285. {
  286. static int reentry;
  287. assert(reentry == 0);
  288. reentry++;
  289. int retval = default_interface_jtag_execute_queue();
  290. if (retval == ERROR_OK) {
  291. struct jtag_callback_entry *entry;
  292. for (entry = jtag_callback_queue_head; entry != NULL; entry = entry->next) {
  293. retval = entry->callback(entry->data0, entry->data1, entry->data2, entry->data3);
  294. if (retval != ERROR_OK)
  295. break;
  296. }
  297. }
  298. jtag_command_queue_reset();
  299. jtag_callback_queue_reset();
  300. reentry--;
  301. return retval;
  302. }
  303. static int jtag_convert_to_callback4(jtag_callback_data_t data0,
  304. jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
  305. {
  306. ((jtag_callback1_t)data1)(data0);
  307. return ERROR_OK;
  308. }
  309. void interface_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0)
  310. {
  311. jtag_add_callback4(jtag_convert_to_callback4, data0, (jtag_callback_data_t)callback, 0, 0);
  312. }
  313. void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0)
  314. {
  315. interface_jtag_add_callback(f, data0);
  316. }
  317. void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,
  318. jtag_callback_data_t data1, jtag_callback_data_t data2,
  319. jtag_callback_data_t data3)
  320. {
  321. interface_jtag_add_callback4(f, data0, data1, data2, data3);
  322. }