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

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)