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