drivers/am335xgpio: Add AM335x driver for bitbang support on BeagleBones
[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-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
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <jtag/jtag.h>
34 #include <jtag/interface.h>
35 #include <jtag/commands.h>
36 #include <jtag/minidriver.h>
37 #include <helper/command.h>
38
39 struct jtag_callback_entry {
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;
50 static struct jtag_callback_entry *jtag_callback_queue_tail;
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  * see jtag_add_ir_scan()
60  *
61  */
62 int interface_jtag_add_ir_scan(struct jtag_tap *active,
63                 const struct scan_field *in_fields, tap_state_t state)
64 {
65         size_t num_taps = jtag_tap_count_enabled();
66
67         struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
68         struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));
69         struct scan_field *out_fields = cmd_queue_alloc(num_taps  * sizeof(struct scan_field));
70
71         jtag_queue_command(cmd);
72
73         cmd->type = JTAG_SCAN;
74         cmd->cmd.scan = scan;
75
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
81         struct scan_field *field = out_fields;  /* keep track where we insert data */
82
83         /* loop over all enabled TAPs */
84
85         for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {
86                 /* search the input field list for fields for the current TAP */
87
88                 if (tap == active) {
89                         /* if TAP is listed in input fields, copy the value */
90                         tap->bypass = 0;
91
92                         jtag_scan_field_clone(field, in_fields);
93                 } else {
94                         /* if a TAP isn't listed in input fields, set it to BYPASS */
95
96                         tap->bypass = 1;
97
98                         field->num_bits = tap->ir_length;
99                         field->out_value = buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8)), tap->ir_length);
100                         field->in_value = NULL; /* do not collect input for tap's in bypass */
101                 }
102
103                 /* update device information */
104                 buf_cpy(field->out_value, tap->cur_instr, tap->ir_length);
105
106                 field++;
107         }
108         /* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */
109         assert(field == out_fields + num_taps);
110
111         return ERROR_OK;
112 }
113
114 /**
115  * see jtag_add_dr_scan()
116  *
117  */
118 int interface_jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields,
119                 const struct scan_field *in_fields, tap_state_t state)
120 {
121         /* count devices in bypass */
122
123         size_t bypass_devices = 0;
124
125         for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {
126                 if (tap->bypass)
127                         bypass_devices++;
128         }
129
130         struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
131         struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));
132         struct scan_field *out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(struct scan_field));
133
134         jtag_queue_command(cmd);
135
136         cmd->type = JTAG_SCAN;
137         cmd->cmd.scan = scan;
138
139         scan->ir_scan = false;
140         scan->num_fields = in_num_fields + bypass_devices;
141         scan->fields = out_fields;
142         scan->end_state = state;
143
144         struct scan_field *field = out_fields;  /* keep track where we insert data */
145
146         /* loop over all enabled TAPs */
147
148         for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {
149                 /* if TAP is not bypassed insert matching input fields */
150
151                 if (!tap->bypass) {
152                         assert(active == tap);
153 #ifndef NDEBUG
154                         /* remember initial position for assert() */
155                         struct scan_field *start_field = field;
156 #endif /* NDEBUG */
157
158                         for (int j = 0; j < in_num_fields; j++) {
159                                 jtag_scan_field_clone(field, in_fields + j);
160
161                                 field++;
162                         }
163
164                         assert(field > start_field);    /* must have at least one input field per not bypassed TAP */
165                 }
166
167                 /* if a TAP is bypassed, generated a dummy bit*/
168                 else {
169                         field->num_bits = 1;
170                         field->out_value = NULL;
171                         field->in_value = NULL;
172
173                         field++;
174                 }
175         }
176
177         assert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */
178
179         return ERROR_OK;
180 }
181
182 static int jtag_add_plain_scan(int num_bits, const uint8_t *out_bits,
183                 uint8_t *in_bits, tap_state_t state, bool ir_scan)
184 {
185         struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
186         struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));
187         struct scan_field *out_fields = cmd_queue_alloc(sizeof(struct scan_field));
188
189         jtag_queue_command(cmd);
190
191         cmd->type = JTAG_SCAN;
192         cmd->cmd.scan = scan;
193
194         scan->ir_scan = ir_scan;
195         scan->num_fields = 1;
196         scan->fields = out_fields;
197         scan->end_state = state;
198
199         out_fields->num_bits = num_bits;
200         out_fields->out_value = buf_cpy(out_bits, cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);
201         out_fields->in_value = in_bits;
202
203         return ERROR_OK;
204 }
205
206 int interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)
207 {
208         return jtag_add_plain_scan(num_bits, out_bits, in_bits, state, false);
209 }
210
211 int interface_jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)
212 {
213         return jtag_add_plain_scan(num_bits, out_bits, in_bits, state, true);
214 }
215
216 int interface_jtag_add_tlr(void)
217 {
218         tap_state_t state = TAP_RESET;
219
220         /* allocate memory for a new list member */
221         struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
222
223         jtag_queue_command(cmd);
224
225         cmd->type = JTAG_TLR_RESET;
226
227         cmd->cmd.statemove = cmd_queue_alloc(sizeof(struct statemove_command));
228         cmd->cmd.statemove->end_state = state;
229
230         return ERROR_OK;
231 }
232
233 int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state)
234 {
235         struct jtag_command *cmd;
236
237         cmd = cmd_queue_alloc(sizeof(struct jtag_command));
238         if (!cmd)
239                 return ERROR_FAIL;
240
241         cmd->type = JTAG_TMS;
242         cmd->cmd.tms = cmd_queue_alloc(sizeof(*cmd->cmd.tms));
243         if (!cmd->cmd.tms)
244                 return ERROR_FAIL;
245
246         /* copy the bits; our caller doesn't guarantee they'll persist */
247         cmd->cmd.tms->num_bits = num_bits;
248         cmd->cmd.tms->bits = buf_cpy(seq,
249                         cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);
250         if (!cmd->cmd.tms->bits)
251                 return ERROR_FAIL;
252
253         jtag_queue_command(cmd);
254
255         return ERROR_OK;
256 }
257
258 int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
259 {
260         /* allocate memory for a new list member */
261         struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
262
263         jtag_queue_command(cmd);
264
265         cmd->type = JTAG_PATHMOVE;
266
267         cmd->cmd.pathmove = cmd_queue_alloc(sizeof(struct pathmove_command));
268         cmd->cmd.pathmove->num_states = num_states;
269         cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states);
270
271         for (int i = 0; i < num_states; i++)
272                 cmd->cmd.pathmove->path[i] = path[i];
273
274         return ERROR_OK;
275 }
276
277 int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
278 {
279         /* allocate memory for a new list member */
280         struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
281
282         jtag_queue_command(cmd);
283
284         cmd->type = JTAG_RUNTEST;
285
286         cmd->cmd.runtest = cmd_queue_alloc(sizeof(struct runtest_command));
287         cmd->cmd.runtest->num_cycles = num_cycles;
288         cmd->cmd.runtest->end_state = state;
289
290         return ERROR_OK;
291 }
292
293 int interface_jtag_add_clocks(int num_cycles)
294 {
295         /* allocate memory for a new list member */
296         struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
297
298         jtag_queue_command(cmd);
299
300         cmd->type = JTAG_STABLECLOCKS;
301
302         cmd->cmd.stableclocks = cmd_queue_alloc(sizeof(struct stableclocks_command));
303         cmd->cmd.stableclocks->num_cycles = num_cycles;
304
305         return ERROR_OK;
306 }
307
308 int interface_jtag_add_reset(int req_trst, int req_srst)
309 {
310         /* allocate memory for a new list member */
311         struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
312
313         jtag_queue_command(cmd);
314
315         cmd->type = JTAG_RESET;
316
317         cmd->cmd.reset = cmd_queue_alloc(sizeof(struct reset_command));
318         cmd->cmd.reset->trst = req_trst;
319         cmd->cmd.reset->srst = req_srst;
320
321         return ERROR_OK;
322 }
323
324 int interface_jtag_add_sleep(uint32_t us)
325 {
326         /* allocate memory for a new list member */
327         struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
328
329         jtag_queue_command(cmd);
330
331         cmd->type = JTAG_SLEEP;
332
333         cmd->cmd.sleep = cmd_queue_alloc(sizeof(struct sleep_command));
334         cmd->cmd.sleep->us = us;
335
336         return ERROR_OK;
337 }
338
339 /* add callback to end of queue */
340 void interface_jtag_add_callback4(jtag_callback_t callback,
341                 jtag_callback_data_t data0, jtag_callback_data_t data1,
342                 jtag_callback_data_t data2, jtag_callback_data_t data3)
343 {
344         struct jtag_callback_entry *entry = cmd_queue_alloc(sizeof(struct jtag_callback_entry));
345
346         entry->next = NULL;
347         entry->callback = callback;
348         entry->data0 = data0;
349         entry->data1 = data1;
350         entry->data2 = data2;
351         entry->data3 = data3;
352
353         if (!jtag_callback_queue_head) {
354                 jtag_callback_queue_head = entry;
355                 jtag_callback_queue_tail = entry;
356         } else {
357                 jtag_callback_queue_tail->next = entry;
358                 jtag_callback_queue_tail = entry;
359         }
360 }
361
362 int interface_jtag_execute_queue(void)
363 {
364         static int reentry;
365
366         assert(reentry == 0);
367         reentry++;
368
369         int retval = default_interface_jtag_execute_queue();
370         if (retval == ERROR_OK) {
371                 struct jtag_callback_entry *entry;
372                 for (entry = jtag_callback_queue_head; entry; entry = entry->next) {
373                         retval = entry->callback(entry->data0, entry->data1, entry->data2, entry->data3);
374                         if (retval != ERROR_OK)
375                                 break;
376                 }
377         }
378
379         jtag_command_queue_reset();
380         jtag_callback_queue_reset();
381
382         reentry--;
383
384         return retval;
385 }
386
387 static int jtag_convert_to_callback4(jtag_callback_data_t data0,
388                 jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
389 {
390         ((jtag_callback1_t)data1)(data0);
391         return ERROR_OK;
392 }
393
394 void interface_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0)
395 {
396         jtag_add_callback4(jtag_convert_to_callback4, data0, (jtag_callback_data_t)callback, 0, 0);
397 }
398
399 void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0)
400 {
401         interface_jtag_add_callback(f, data0);
402 }
403
404 void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,
405                 jtag_callback_data_t data1, jtag_callback_data_t data2,
406                 jtag_callback_data_t data3)
407 {
408         interface_jtag_add_callback4(f, data0, data1, data2, data3);
409 }