jtag: the post TAP state is now passed to the drivers
[openocd.git] / src / jtag / drivers / driver.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007-2009 Ø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
34 #include <jtag/jtag.h>
35 #include <jtag/interface.h>
36 #include <jtag/commands.h>
37 #include <jtag/minidriver.h>
38 #include <helper/command.h>
39
40 struct jtag_callback_entry
41 {
42 struct jtag_callback_entry *next;
43
44 jtag_callback_t callback;
45 jtag_callback_data_t data0;
46 jtag_callback_data_t data1;
47 jtag_callback_data_t data2;
48 jtag_callback_data_t data3;
49 };
50
51 static struct jtag_callback_entry *jtag_callback_queue_head = NULL;
52 static struct jtag_callback_entry *jtag_callback_queue_tail = NULL;
53
54 static void jtag_callback_queue_reset(void)
55 {
56 jtag_callback_queue_head = NULL;
57 jtag_callback_queue_tail = NULL;
58 }
59
60 /**
61 * Copy a struct scan_field for insertion into the queue.
62 *
63 * This allocates a new copy of out_value using cmd_queue_alloc.
64 */
65 static void cmd_queue_scan_field_clone(struct scan_field * dst, const struct scan_field * src)
66 {
67 dst->tap = src->tap;
68 dst->num_bits = src->num_bits;
69 dst->out_value = buf_cpy(src->out_value, cmd_queue_alloc(DIV_ROUND_UP(src->num_bits, 8)), src->num_bits);
70 dst->in_value = src->in_value;
71 }
72
73
74 /**
75 * see jtag_add_ir_scan()
76 *
77 */
78 int interface_jtag_add_ir_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
79 {
80 size_t num_taps = jtag_tap_count_enabled();
81
82 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
83 struct scan_command * scan = cmd_queue_alloc(sizeof(struct scan_command));
84 struct scan_field * out_fields = cmd_queue_alloc(num_taps * sizeof(struct scan_field));
85
86 jtag_queue_command(cmd);
87
88 cmd->type = JTAG_SCAN;
89 cmd->cmd.scan = scan;
90
91 scan->ir_scan = true;
92 scan->num_fields = num_taps; /* one field per device */
93 scan->fields = out_fields;
94 scan->end_state = state;
95
96
97 struct scan_field * field = out_fields; /* keep track where we insert data */
98
99 /* loop over all enabled TAPs */
100
101 for (struct jtag_tap * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
102 {
103 /* search the input field list for fields for the current TAP */
104
105 bool found = false;
106
107 for (int j = 0; j < in_num_fields; j++)
108 {
109 if (tap != in_fields[j].tap)
110 continue;
111
112 /* if TAP is listed in input fields, copy the value */
113
114 found = true;
115
116 tap->bypass = 0;
117
118 assert(in_fields[j].num_bits == tap->ir_length); /* input fields must have the same length as the TAP's IR */
119
120 cmd_queue_scan_field_clone(field, in_fields + j);
121
122 break;
123 }
124
125 if (!found)
126 {
127 /* if a TAP isn't listed in input fields, set it to BYPASS */
128
129 tap->bypass = 1;
130
131 field->tap = tap;
132 field->num_bits = tap->ir_length;
133 field->out_value = buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8)), tap->ir_length);
134 field->in_value = NULL; /* do not collect input for tap's in bypass */
135 }
136
137 /* update device information */
138 buf_cpy(field->out_value, tap->cur_instr, tap->ir_length);
139
140 field++;
141 }
142
143 assert(field == out_fields + num_taps); /* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */
144
145 return ERROR_OK;
146 }
147
148 /**
149 * see jtag_add_plain_ir_scan()
150 *
151 */
152 int interface_jtag_add_plain_ir_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
153 {
154
155 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
156 struct scan_command * scan = cmd_queue_alloc(sizeof(struct scan_command));
157 struct scan_field * out_fields = cmd_queue_alloc(in_num_fields * sizeof(struct scan_field));
158
159 jtag_queue_command(cmd);
160
161 cmd->type = JTAG_SCAN;
162 cmd->cmd.scan = scan;
163
164 scan->ir_scan = true;
165 scan->num_fields = in_num_fields;
166 scan->fields = out_fields;
167 scan->end_state = state;
168
169 for (int i = 0; i < in_num_fields; i++)
170 cmd_queue_scan_field_clone(out_fields + i, in_fields + i);
171
172 return ERROR_OK;
173 }
174
175
176
177 /**
178 * see jtag_add_dr_scan()
179 *
180 */
181 int interface_jtag_add_dr_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
182 {
183 /* count devices in bypass */
184
185 size_t bypass_devices = 0;
186
187 for (struct jtag_tap * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
188 {
189 if (tap->bypass)
190 bypass_devices++;
191 }
192
193 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
194 struct scan_command * scan = cmd_queue_alloc(sizeof(struct scan_command));
195 struct scan_field * out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(struct scan_field));
196
197 jtag_queue_command(cmd);
198
199 cmd->type = JTAG_SCAN;
200 cmd->cmd.scan = scan;
201
202 scan->ir_scan = false;
203 scan->num_fields = in_num_fields + bypass_devices;
204 scan->fields = out_fields;
205 scan->end_state = state;
206
207
208 struct scan_field * field = out_fields; /* keep track where we insert data */
209
210 /* loop over all enabled TAPs */
211
212 for (struct jtag_tap * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
213 {
214 /* if TAP is not bypassed insert matching input fields */
215
216 if (!tap->bypass)
217 {
218 #ifndef NDEBUG
219 /* remember initial position for assert() */
220 struct scan_field *start_field = field;
221 #endif /* NDEBUG */
222
223 for (int j = 0; j < in_num_fields; j++)
224 {
225 if (tap != in_fields[j].tap)
226 continue;
227
228 cmd_queue_scan_field_clone(field, in_fields + j);
229
230 field++;
231 }
232
233 assert(field > start_field); /* must have at least one input field per not bypassed TAP */
234 }
235
236 /* if a TAP is bypassed, generated a dummy bit*/
237 else
238 {
239 field->tap = tap;
240 field->num_bits = 1;
241 field->out_value = NULL;
242 field->in_value = NULL;
243
244 field++;
245 }
246 }
247
248 assert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */
249
250 return ERROR_OK;
251 }
252
253
254
255 /**
256 * Generate a DR SCAN using the array of output values passed to the function
257 *
258 * This function assumes that the parameter target_tap specifies the one TAP
259 * that is not bypassed. All other TAPs must be bypassed and the function will
260 * generate a dummy 1bit field for them.
261 *
262 * For the target_tap a sequence of output-only fields will be generated where
263 * each field has the size num_bits and the field's values are taken from
264 * the array value.
265 *
266 * The bypass status of TAPs is set by jtag_add_ir_scan().
267 *
268 */
269 void interface_jtag_add_dr_out(struct jtag_tap *target_tap,
270 int in_num_fields,
271 const int *num_bits,
272 const uint32_t *value,
273 tap_state_t end_state)
274 {
275 /* count devices in bypass */
276
277 size_t bypass_devices = 0;
278
279 for (struct jtag_tap * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
280 {
281 if (tap->bypass)
282 bypass_devices++;
283 }
284
285
286 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
287 struct scan_command * scan = cmd_queue_alloc(sizeof(struct scan_command));
288 struct scan_field * out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(struct scan_field));
289
290 jtag_queue_command(cmd);
291
292 cmd->type = JTAG_SCAN;
293 cmd->cmd.scan = scan;
294
295 scan->ir_scan = false;
296 scan->num_fields = in_num_fields + bypass_devices;
297 scan->fields = out_fields;
298 scan->end_state = end_state;
299
300
301 bool target_tap_match = false;
302
303 struct scan_field * field = out_fields; /* keep track where we insert data */
304
305 /* loop over all enabled TAPs */
306
307 for (struct jtag_tap * tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap))
308 {
309 /* if TAP is not bypassed insert matching input fields */
310
311 if (!tap->bypass)
312 {
313 assert(tap == target_tap); /* target_tap must match the one not bypassed TAP */
314
315 target_tap_match = true;
316
317 for (int j = 0; j < in_num_fields; j++)
318 {
319 uint8_t out_value[4];
320 size_t scan_size = num_bits[j];
321 buf_set_u32(out_value, 0, scan_size, value[j]);
322
323 field->tap = tap;
324 field->num_bits = scan_size;
325 field->out_value = buf_cpy(out_value, cmd_queue_alloc(DIV_ROUND_UP(scan_size, 8)), scan_size);
326 field->in_value = NULL;
327
328 field++;
329 }
330 }
331
332 /* if a TAP is bypassed, generated a dummy bit*/
333 else
334 {
335
336 field->tap = tap;
337 field->num_bits = 1;
338 field->out_value = NULL;
339 field->in_value = NULL;
340
341 field++;
342 }
343 }
344
345 assert(target_tap_match); /* target_tap should be enabled and not bypassed */
346 }
347
348 /**
349 * see jtag_add_plain_dr_scan()
350 *
351 */
352 int interface_jtag_add_plain_dr_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
353 {
354 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
355 struct scan_command * scan = cmd_queue_alloc(sizeof(struct scan_command));
356 struct scan_field * out_fields = cmd_queue_alloc(in_num_fields * sizeof(struct scan_field));
357
358 jtag_queue_command(cmd);
359
360 cmd->type = JTAG_SCAN;
361 cmd->cmd.scan = scan;
362
363 scan->ir_scan = false;
364 scan->num_fields = in_num_fields;
365 scan->fields = out_fields;
366 scan->end_state = state;
367
368 for (int i = 0; i < in_num_fields; i++)
369 cmd_queue_scan_field_clone(out_fields + i, in_fields + i);
370
371 return ERROR_OK;
372 }
373
374 int interface_jtag_add_tlr(void)
375 {
376 tap_state_t state = TAP_RESET;
377
378 /* allocate memory for a new list member */
379 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
380
381 jtag_queue_command(cmd);
382
383 cmd->type = JTAG_STATEMOVE;
384
385 cmd->cmd.statemove = cmd_queue_alloc(sizeof(struct statemove_command));
386 cmd->cmd.statemove->end_state = state;
387
388 return ERROR_OK;
389 }
390
391 int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state)
392 {
393 struct jtag_command *cmd;
394
395 cmd = cmd_queue_alloc(sizeof(struct jtag_command));
396 if (cmd == NULL)
397 return ERROR_FAIL;
398
399 cmd->type = JTAG_TMS;
400 cmd->cmd.tms = cmd_queue_alloc(sizeof(*cmd->cmd.tms));
401 if (!cmd->cmd.tms)
402 return ERROR_FAIL;
403
404 /* copy the bits; our caller doesn't guarantee they'll persist */
405 cmd->cmd.tms->num_bits = num_bits;
406 cmd->cmd.tms->bits = buf_cpy(seq,
407 cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);
408 if (!cmd->cmd.tms->bits)
409 return ERROR_FAIL;
410
411 jtag_queue_command(cmd);
412
413 return ERROR_OK;
414 }
415
416 int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
417 {
418 /* allocate memory for a new list member */
419 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
420
421 jtag_queue_command(cmd);
422
423 cmd->type = JTAG_PATHMOVE;
424
425 cmd->cmd.pathmove = cmd_queue_alloc(sizeof(struct pathmove_command));
426 cmd->cmd.pathmove->num_states = num_states;
427 cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states);
428
429 for (int i = 0; i < num_states; i++)
430 cmd->cmd.pathmove->path[i] = path[i];
431
432 return ERROR_OK;
433 }
434
435 int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
436 {
437 /* allocate memory for a new list member */
438 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
439
440 jtag_queue_command(cmd);
441
442 cmd->type = JTAG_RUNTEST;
443
444 cmd->cmd.runtest = cmd_queue_alloc(sizeof(struct runtest_command));
445 cmd->cmd.runtest->num_cycles = num_cycles;
446 cmd->cmd.runtest->end_state = state;
447
448 return ERROR_OK;
449 }
450
451 int interface_jtag_add_clocks(int num_cycles)
452 {
453 /* allocate memory for a new list member */
454 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
455
456 jtag_queue_command(cmd);
457
458 cmd->type = JTAG_STABLECLOCKS;
459
460 cmd->cmd.stableclocks = cmd_queue_alloc(sizeof(struct stableclocks_command));
461 cmd->cmd.stableclocks->num_cycles = num_cycles;
462
463 return ERROR_OK;
464 }
465
466 int interface_jtag_add_reset(int req_trst, int req_srst)
467 {
468 /* allocate memory for a new list member */
469 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
470
471 jtag_queue_command(cmd);
472
473 cmd->type = JTAG_RESET;
474
475 cmd->cmd.reset = cmd_queue_alloc(sizeof(struct reset_command));
476 cmd->cmd.reset->trst = req_trst;
477 cmd->cmd.reset->srst = req_srst;
478
479 return ERROR_OK;
480 }
481
482 int interface_jtag_add_sleep(uint32_t us)
483 {
484 /* allocate memory for a new list member */
485 struct jtag_command * cmd = cmd_queue_alloc(sizeof(struct jtag_command));
486
487 jtag_queue_command(cmd);
488
489 cmd->type = JTAG_SLEEP;
490
491 cmd->cmd.sleep = cmd_queue_alloc(sizeof(struct sleep_command));
492 cmd->cmd.sleep->us = us;
493
494 return ERROR_OK;
495 }
496
497 /* add callback to end of queue */
498 void interface_jtag_add_callback4(jtag_callback_t callback, jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
499 {
500 struct jtag_callback_entry *entry = cmd_queue_alloc(sizeof(struct jtag_callback_entry));
501
502 entry->next = NULL;
503 entry->callback = callback;
504 entry->data0 = data0;
505 entry->data1 = data1;
506 entry->data2 = data2;
507 entry->data3 = data3;
508
509 if (jtag_callback_queue_head == NULL)
510 {
511 jtag_callback_queue_head = entry;
512 jtag_callback_queue_tail = entry;
513 } else
514 {
515 jtag_callback_queue_tail->next = entry;
516 jtag_callback_queue_tail = entry;
517 }
518 }
519
520 int interface_jtag_execute_queue(void)
521 {
522 static int reentry = 0;
523
524 assert(reentry==0);
525 reentry++;
526
527 int retval = default_interface_jtag_execute_queue();
528 if (retval == ERROR_OK)
529 {
530 struct jtag_callback_entry *entry;
531 for (entry = jtag_callback_queue_head; entry != NULL; entry = entry->next)
532 {
533 retval = entry->callback(entry->data0, entry->data1, entry->data2, entry->data3);
534 if (retval != ERROR_OK)
535 break;
536 }
537 }
538
539 jtag_command_queue_reset();
540 jtag_callback_queue_reset();
541
542 reentry--;
543
544 return retval;
545 }
546
547 static int jtag_convert_to_callback4(jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
548 {
549 ((jtag_callback1_t)data1)(data0);
550 return ERROR_OK;
551 }
552
553 void interface_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0)
554 {
555 jtag_add_callback4(jtag_convert_to_callback4, data0, (jtag_callback_data_t)callback, 0, 0);
556 }
557
558
559 /* A minidriver can use use an inline versions of this API level fn */
560 void jtag_add_dr_out(struct jtag_tap* tap,
561 int num_fields, const int* num_bits, const uint32_t* value,
562 tap_state_t end_state)
563 {
564 assert(end_state != TAP_RESET);
565 assert(end_state != TAP_INVALID);
566
567 cmd_queue_cur_state = end_state;
568
569 interface_jtag_add_dr_out(tap,
570 num_fields, num_bits, value,
571 end_state);
572 }
573
574 void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0)
575 {
576 interface_jtag_add_callback(f, data0);
577 }
578
579 void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,
580 jtag_callback_data_t data1, jtag_callback_data_t data2,
581 jtag_callback_data_t data3)
582 {
583 interface_jtag_add_callback4(f, data0, data1, data2, data3);
584 }

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)