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.
 
 
 
 
 
 

521 lines
14 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2007,2008 Ø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, write to the *
  27. * Free Software Foundation, Inc., *
  28. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  29. ***************************************************************************/
  30. #ifdef HAVE_CONFIG_H
  31. #include "config.h"
  32. #endif
  33. #include "interface.h"
  34. #include "minidriver.h"
  35. #include "command.h"
  36. struct jtag_callback_entry
  37. {
  38. struct jtag_callback_entry *next;
  39. jtag_callback_t callback;
  40. uint8_t *in;
  41. jtag_callback_data_t data1;
  42. jtag_callback_data_t data2;
  43. jtag_callback_data_t data3;
  44. };
  45. static struct jtag_callback_entry *jtag_callback_queue_head = NULL;
  46. static struct jtag_callback_entry *jtag_callback_queue_tail = NULL;
  47. static void jtag_callback_queue_reset(void)
  48. {
  49. jtag_callback_queue_head = NULL;
  50. jtag_callback_queue_tail = NULL;
  51. }
  52. /**
  53. * Copy a scan_field_t for insertion into the queue.
  54. *
  55. * This allocates a new copy of out_value using cmd_queue_alloc.
  56. */
  57. static void cmd_queue_scan_field_clone(scan_field_t * dst, const scan_field_t * src)
  58. {
  59. dst->tap = src->tap;
  60. dst->num_bits = src->num_bits;
  61. dst->out_value = buf_cpy(src->out_value, cmd_queue_alloc(CEIL(src->num_bits, 8)), src->num_bits);
  62. dst->in_value = src->in_value;
  63. }
  64. /**
  65. * see jtag_add_ir_scan()
  66. *
  67. */
  68. int interface_jtag_add_ir_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
  69. {
  70. size_t num_taps = jtag_tap_count_enabled();
  71. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  72. scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t));
  73. scan_field_t * out_fields = cmd_queue_alloc(num_taps * sizeof(scan_field_t));
  74. jtag_queue_command(cmd);
  75. cmd->type = JTAG_SCAN;
  76. cmd->cmd.scan = scan;
  77. scan->ir_scan = true;
  78. scan->num_fields = num_taps; /* one field per device */
  79. scan->fields = out_fields;
  80. scan->end_state = state;
  81. scan_field_t * field = out_fields; /* keep track where we insert data */
  82. /* loop over all enabled TAPs */
  83. for (jtag_tap_t * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
  84. {
  85. /* search the input field list for fields for the current TAP */
  86. bool found = false;
  87. for (int j = 0; j < in_num_fields; j++)
  88. {
  89. if (tap != in_fields[j].tap)
  90. continue;
  91. /* if TAP is listed in input fields, copy the value */
  92. found = true;
  93. tap->bypass = 0;
  94. assert(in_fields[j].num_bits == tap->ir_length); /* input fields must have the same length as the TAP's IR */
  95. cmd_queue_scan_field_clone(field, in_fields + j);
  96. break;
  97. }
  98. if (!found)
  99. {
  100. /* if a TAP isn't listed in input fields, set it to BYPASS */
  101. tap->bypass = 1;
  102. field->tap = tap;
  103. field->num_bits = tap->ir_length;
  104. field->out_value = buf_set_ones(cmd_queue_alloc(CEIL(tap->ir_length, 8)), tap->ir_length);
  105. field->in_value = NULL; /* do not collect input for tap's in bypass */
  106. }
  107. /* update device information */
  108. buf_cpy(field->out_value, tap->cur_instr, tap->ir_length);
  109. field++;
  110. }
  111. assert(field == out_fields + num_taps); /* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */
  112. return ERROR_OK;
  113. }
  114. /**
  115. * see jtag_add_plain_ir_scan()
  116. *
  117. */
  118. int interface_jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
  119. {
  120. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  121. scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t));
  122. scan_field_t * out_fields = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t));
  123. jtag_queue_command(cmd);
  124. cmd->type = JTAG_SCAN;
  125. cmd->cmd.scan = scan;
  126. scan->ir_scan = true;
  127. scan->num_fields = in_num_fields;
  128. scan->fields = out_fields;
  129. scan->end_state = state;
  130. for (int i = 0; i < in_num_fields; i++)
  131. cmd_queue_scan_field_clone(out_fields + i, in_fields + i);
  132. return ERROR_OK;
  133. }
  134. /**
  135. * see jtag_add_dr_scan()
  136. *
  137. */
  138. int interface_jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
  139. {
  140. /* count devices in bypass */
  141. size_t bypass_devices = 0;
  142. for (jtag_tap_t * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
  143. {
  144. if (tap->bypass)
  145. bypass_devices++;
  146. }
  147. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  148. scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t));
  149. scan_field_t * out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
  150. jtag_queue_command(cmd);
  151. cmd->type = JTAG_SCAN;
  152. cmd->cmd.scan = scan;
  153. scan->ir_scan = false;
  154. scan->num_fields = in_num_fields + bypass_devices;
  155. scan->fields = out_fields;
  156. scan->end_state = state;
  157. scan_field_t * field = out_fields; /* keep track where we insert data */
  158. /* loop over all enabled TAPs */
  159. for (jtag_tap_t * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
  160. {
  161. /* if TAP is not bypassed insert matching input fields */
  162. if (!tap->bypass)
  163. {
  164. scan_field_t * start_field = field; /* keep initial position for assert() */
  165. for (int j = 0; j < in_num_fields; j++)
  166. {
  167. if (tap != in_fields[j].tap)
  168. continue;
  169. cmd_queue_scan_field_clone(field, in_fields + j);
  170. field++;
  171. }
  172. assert(field > start_field); /* must have at least one input field per not bypassed TAP */
  173. }
  174. /* if a TAP is bypassed, generated a dummy bit*/
  175. else
  176. {
  177. field->tap = tap;
  178. field->num_bits = 1;
  179. field->out_value = NULL;
  180. field->in_value = NULL;
  181. field++;
  182. }
  183. }
  184. assert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */
  185. return ERROR_OK;
  186. }
  187. /**
  188. * Generate a DR SCAN using the array of output values passed to the function
  189. *
  190. * This function assumes that the parameter target_tap specifies the one TAP
  191. * that is not bypassed. All other TAPs must be bypassed and the function will
  192. * generate a dummy 1bit field for them.
  193. *
  194. * For the target_tap a sequence of output-only fields will be generated where
  195. * each field has the size num_bits and the field's values are taken from
  196. * the array value.
  197. *
  198. * The bypass status of TAPs is set by jtag_add_ir_scan().
  199. *
  200. */
  201. void interface_jtag_add_dr_out(jtag_tap_t *target_tap,
  202. int in_num_fields,
  203. const int *num_bits,
  204. const u32 *value,
  205. tap_state_t end_state)
  206. {
  207. /* count devices in bypass */
  208. size_t bypass_devices = 0;
  209. for (jtag_tap_t * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
  210. {
  211. if (tap->bypass)
  212. bypass_devices++;
  213. }
  214. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  215. scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t));
  216. scan_field_t * out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
  217. jtag_queue_command(cmd);
  218. cmd->type = JTAG_SCAN;
  219. cmd->cmd.scan = scan;
  220. scan->ir_scan = false;
  221. scan->num_fields = in_num_fields + bypass_devices;
  222. scan->fields = out_fields;
  223. scan->end_state = end_state;
  224. bool target_tap_match = false;
  225. scan_field_t * field = out_fields; /* keep track where we insert data */
  226. /* loop over all enabled TAPs */
  227. for (jtag_tap_t * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
  228. {
  229. /* if TAP is not bypassed insert matching input fields */
  230. if (!tap->bypass)
  231. {
  232. assert(tap == target_tap); /* target_tap must match the one not bypassed TAP */
  233. target_tap_match = true;
  234. for (int j = 0; j < in_num_fields; j++)
  235. {
  236. uint8_t out_value[4];
  237. size_t scan_size = num_bits[j];
  238. buf_set_u32(out_value, 0, scan_size, value[j]);
  239. field->tap = tap;
  240. field->num_bits = scan_size;
  241. field->out_value = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
  242. field->in_value = NULL;
  243. field++;
  244. }
  245. }
  246. /* if a TAP is bypassed, generated a dummy bit*/
  247. else
  248. {
  249. field->tap = tap;
  250. field->num_bits = 1;
  251. field->out_value = NULL;
  252. field->in_value = NULL;
  253. field++;
  254. }
  255. }
  256. assert(target_tap_match); /* target_tap should be enabled and not bypassed */
  257. }
  258. /**
  259. * see jtag_add_plain_dr_scan()
  260. *
  261. */
  262. int interface_jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
  263. {
  264. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  265. scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t));
  266. scan_field_t * out_fields = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t));
  267. jtag_queue_command(cmd);
  268. cmd->type = JTAG_SCAN;
  269. cmd->cmd.scan = scan;
  270. scan->ir_scan = false;
  271. scan->num_fields = in_num_fields;
  272. scan->fields = out_fields;
  273. scan->end_state = state;
  274. for (int i = 0; i < in_num_fields; i++)
  275. cmd_queue_scan_field_clone(out_fields + i, in_fields + i);
  276. return ERROR_OK;
  277. }
  278. int interface_jtag_add_tlr(void)
  279. {
  280. tap_state_t state = TAP_RESET;
  281. /* allocate memory for a new list member */
  282. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  283. jtag_queue_command(cmd);
  284. cmd->type = JTAG_STATEMOVE;
  285. cmd->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t));
  286. cmd->cmd.statemove->end_state = state;
  287. return ERROR_OK;
  288. }
  289. int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
  290. {
  291. /* allocate memory for a new list member */
  292. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  293. jtag_queue_command(cmd);
  294. cmd->type = JTAG_PATHMOVE;
  295. cmd->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t));
  296. cmd->cmd.pathmove->num_states = num_states;
  297. cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states);
  298. for (int i = 0; i < num_states; i++)
  299. cmd->cmd.pathmove->path[i] = path[i];
  300. return ERROR_OK;
  301. }
  302. int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
  303. {
  304. /* allocate memory for a new list member */
  305. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  306. jtag_queue_command(cmd);
  307. cmd->type = JTAG_RUNTEST;
  308. cmd->cmd.runtest = cmd_queue_alloc(sizeof(runtest_command_t));
  309. cmd->cmd.runtest->num_cycles = num_cycles;
  310. cmd->cmd.runtest->end_state = state;
  311. return ERROR_OK;
  312. }
  313. int interface_jtag_add_clocks( int num_cycles )
  314. {
  315. /* allocate memory for a new list member */
  316. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  317. jtag_queue_command(cmd);
  318. cmd->type = JTAG_STABLECLOCKS;
  319. cmd->cmd.stableclocks = cmd_queue_alloc(sizeof(stableclocks_command_t));
  320. cmd->cmd.stableclocks->num_cycles = num_cycles;
  321. return ERROR_OK;
  322. }
  323. int interface_jtag_add_reset(int req_trst, int req_srst)
  324. {
  325. /* allocate memory for a new list member */
  326. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  327. jtag_queue_command(cmd);
  328. cmd->type = JTAG_RESET;
  329. cmd->cmd.reset = cmd_queue_alloc(sizeof(reset_command_t));
  330. cmd->cmd.reset->trst = req_trst;
  331. cmd->cmd.reset->srst = req_srst;
  332. return ERROR_OK;
  333. }
  334. int interface_jtag_add_sleep(u32 us)
  335. {
  336. /* allocate memory for a new list member */
  337. jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
  338. jtag_queue_command(cmd);
  339. cmd->type = JTAG_SLEEP;
  340. cmd->cmd.sleep = cmd_queue_alloc(sizeof(sleep_command_t));
  341. cmd->cmd.sleep->us = us;
  342. return ERROR_OK;
  343. }
  344. /* add callback to end of queue */
  345. void interface_jtag_add_callback4(jtag_callback_t callback, uint8_t *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
  346. {
  347. struct jtag_callback_entry *entry=cmd_queue_alloc(sizeof(struct jtag_callback_entry));
  348. entry->next=NULL;
  349. entry->callback=callback;
  350. entry->in=in;
  351. entry->data1=data1;
  352. entry->data2=data2;
  353. entry->data3=data3;
  354. if (jtag_callback_queue_head==NULL)
  355. {
  356. jtag_callback_queue_head=entry;
  357. jtag_callback_queue_tail=entry;
  358. } else
  359. {
  360. jtag_callback_queue_tail->next=entry;
  361. jtag_callback_queue_tail=entry;
  362. }
  363. }
  364. int interface_jtag_execute_queue(void)
  365. {
  366. int retval = default_interface_jtag_execute_queue();
  367. if (retval == ERROR_OK)
  368. {
  369. struct jtag_callback_entry *entry;
  370. for (entry=jtag_callback_queue_head; entry!=NULL; entry=entry->next)
  371. {
  372. retval=entry->callback(entry->in, entry->data1, entry->data2, entry->data3);
  373. if (retval!=ERROR_OK)
  374. break;
  375. }
  376. }
  377. jtag_command_queue_reset();
  378. jtag_callback_queue_reset();
  379. return retval;
  380. }
  381. static int jtag_convert_to_callback4(uint8_t *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
  382. {
  383. ((jtag_callback1_t)data1)(in);
  384. return ERROR_OK;
  385. }
  386. void interface_jtag_add_callback(jtag_callback1_t callback, uint8_t *in)
  387. {
  388. jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0);
  389. }