- renamed M5960 USB JTAG to "flyswatter"
[openocd.git] / src / jtag / bitq.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
3 * chromy@asix.cz *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "bitq.h"
25
26 /* project specific includes */
27 #include "log.h"
28 #include "types.h"
29 #include "jtag.h"
30 #include "configuration.h"
31
32 /* system includes */
33 #include <string.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36
37 #include <sys/time.h>
38 #include <time.h>
39
40
41 bitq_interface_t *bitq_interface; /* low level bit queue interface */
42
43 bitq_state_t bitq_in_state; /* state of input queue */
44
45 u8 *bitq_in_buffer; /* buffer dynamically reallocated as needed */
46 unsigned long bitq_in_bufsize=32; /* min. buffer size */
47
48
49 /*
50 * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
51 * also the buffer for incomming data is reallocated only if necessary
52 * no parameters, makes use of stored state information
53 */
54 void bitq_in_proc(void)
55 {
56 /* static information preserved between calls to increase performance */
57 static u8 *in_buff; /* pointer to buffer for scanned data */
58 static int in_idx; /* index of byte being scanned */
59 static u8 in_mask; /* mask of next bit to be scanned */
60
61 scan_field_t *field;
62 int tdo;
63
64 /* loop through the queue */
65 while (bitq_in_state.cmd) {
66 /* only JTAG_SCAN command may return data */
67 if (bitq_in_state.cmd->type==JTAG_SCAN) {
68 /* loop through the fields */
69 while (bitq_in_state.field_idx<bitq_in_state.cmd->cmd.scan->num_fields) {
70
71 field=&bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];
72 if (field->in_check_value || field->in_value || field->in_handler) {
73
74 if (bitq_in_state.bit_pos==0) {
75 /* initialize field scanning */
76 in_mask=0x01;
77 in_idx=0;
78 if (field->in_value) in_buff=field->in_value;
79 else {
80 /* buffer reallocation needed? */
81 if (field->num_bits>bitq_in_bufsize*8) {
82 /* buffer previously allocated? */
83 if (bitq_in_buffer!=NULL) {
84 /* free it */
85 free(bitq_in_buffer);
86 bitq_in_buffer=NULL;
87 }
88 /* double the buffer size until it fits */
89 while (field->num_bits>bitq_in_bufsize*8) bitq_in_bufsize*=2;
90 }
91 /* if necessary, allocate buffer and check for malloc error */
92 if (bitq_in_buffer==NULL && (bitq_in_buffer=malloc(bitq_in_bufsize))==NULL) {
93 ERROR("malloc error");
94 exit(-1);
95 }
96 in_buff=(void *)bitq_in_buffer;
97 }
98 }
99
100 /* field scanning */
101 while (bitq_in_state.bit_pos<field->num_bits) {
102 if ((tdo=bitq_interface->in())<0) {
103 #ifdef _DEBUG_JTAG_IO_
104 DEBUG("bitq in EOF");
105 #endif
106 return;
107 }
108 if (in_mask==0x01) in_buff[in_idx]=0;
109 if (tdo) in_buff[in_idx]|=in_mask;
110 if (in_mask==0x80) {
111 in_mask=0x01;
112 in_idx++;
113 }
114 else in_mask<<=1;
115 bitq_in_state.bit_pos++;
116 }
117
118 if (field->in_check_value) {
119 /* match scanned in value */
120 for (in_idx=0; in_idx*8<field->num_bits; in_idx++) {
121 if (field->in_check_mask) in_mask=field->in_check_mask[in_idx];
122 else in_mask=0xff;
123 if (field->num_bits-in_idx*8<8) in_mask>>=8-(field->num_bits-in_idx*8);
124 if (field->in_check_value[in_idx]&in_mask!=in_buff[in_idx]&in_mask) {
125 char *captured_char = buf_to_str(in_buff, (field->num_bits > 64) ? 64 : field->num_bits, 16);
126 char *in_check_value_char = buf_to_str(field->in_check_value, (field->num_bits > 64) ? 64 : field->num_bits, 16);
127 char *in_check_mask_char = buf_to_str(field->in_check_mask, (field->num_bits > 64) ? 64 : field->num_bits, 16);
128 /* TODO: error reporting */
129 WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char);
130 bitq_in_state.status=ERROR_JTAG_QUEUE_FAILED;
131 free(captured_char);
132 free(in_check_value_char);
133 free(in_check_mask_char);
134 break; /* leave the comparison loop upon first mismatch */
135 }
136 }
137 }
138
139 if (field->in_handler && bitq_in_state.status==ERROR_OK) {
140 bitq_in_state.status=(*field->in_handler)(in_buff, field->in_handler_priv);
141 }
142
143 }
144
145 bitq_in_state.field_idx++; /* advance to next field */
146 bitq_in_state.bit_pos=0; /* start next field from the first bit */
147 }
148
149 }
150 bitq_in_state.cmd=bitq_in_state.cmd->next; /* advance to next command */
151 bitq_in_state.field_idx=0; /* preselect first field */
152 }
153 }
154
155
156
157 void bitq_io(int tms, int tdi, int tdo_req)
158 {
159 bitq_interface->out(tms, tdi, tdo_req);
160 /* check and process the input queue */
161 if (bitq_interface->in_rdy()) bitq_in_proc();
162 }
163
164
165 void bitq_end_state(enum tap_state state)
166 {
167 if (state==-1) return;
168 if (tap_move_map[state]==-1) {
169 ERROR("BUG: %i is not a valid end state", state);
170 exit(-1);
171 }
172 end_state = state;
173 }
174
175
176 void bitq_state_move(enum tap_state new_state)
177 {
178 int i=0;
179 u8 tms_scan;
180
181 if (tap_move_map[cur_state]==-1 || tap_move_map[new_state]==-1) {
182 ERROR("TAP move from or to unstable state");
183 exit(-1);
184 }
185
186 tms_scan=TAP_MOVE(cur_state, new_state);
187
188 for (i=0; i<7; i++) {
189 bitq_io(tms_scan&1, 0, 0);
190 tms_scan>>=1;
191 }
192
193 cur_state = new_state;
194 }
195
196
197 void bitq_path_move(pathmove_command_t *cmd)
198 {
199 int i;
200
201 for (i=0; i<=cmd->num_states; i++) {
202 if (tap_transitions[cur_state].low == cmd->path[i]) bitq_io(0, 0, 0);
203 else if (tap_transitions[cur_state].high == cmd->path[i]) bitq_io(1, 0, 0);
204 else {
205 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[i]]);
206 exit(-1);
207 }
208
209 cur_state = cmd->path[i];
210 }
211
212 end_state = cur_state;
213 }
214
215
216 void bitq_runtest(int num_cycles)
217 {
218 int i;
219
220 /* only do a state_move when we're not already in RTI */
221 if (cur_state != TAP_RTI) bitq_state_move(TAP_RTI);
222
223 /* execute num_cycles */
224 for (i = 0; i < num_cycles; i++)
225 bitq_io(0, 0, 0);
226
227 /* finish in end_state */
228 if (cur_state != end_state) bitq_state_move(end_state);
229 }
230
231
232 void bitq_scan_field(scan_field_t *field, int pause)
233 {
234 int bit_cnt;
235 int tdo_req;
236
237 u8 *out_ptr;
238 u8 out_mask;
239
240 if (field->in_check_value || field->in_value || field->in_handler) tdo_req=1;
241 else tdo_req=0;
242
243 if (field->out_value==NULL) {
244 /* just send zeros and request data from TDO */
245 for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--)
246 bitq_io(0, 0, tdo_req);
247 bitq_io(pause, 0, tdo_req);
248 }
249 else {
250 /* send data, and optionally request TDO */
251 out_mask=0x01;
252 out_ptr=field->out_value;
253 for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--) {
254 bitq_io(0, ((*out_ptr)&out_mask)!=0, tdo_req);
255 if (out_mask==0x80) {
256 out_mask=0x01;
257 out_ptr++;
258 }
259 else out_mask<<=1;
260 }
261 bitq_io(pause, ((*out_ptr)&out_mask)!=0, tdo_req);
262 }
263
264 if (pause) {
265 bitq_io(0,0,0);
266 if (cur_state==TAP_SI) cur_state=TAP_PI;
267 else if (cur_state==TAP_SD) cur_state=TAP_PD;
268 }
269 }
270
271
272 void bitq_scan(scan_command_t *cmd)
273 {
274 int i;
275
276 if (cmd->ir_scan) bitq_state_move(TAP_SI);
277 else bitq_state_move(TAP_SD);
278
279 for (i=0; i < cmd->num_fields-1; i++)
280 bitq_scan_field(&cmd->fields[i], 0);
281 bitq_scan_field(&cmd->fields[i], 1);
282 }
283
284
285 int bitq_execute_queue(void)
286 {
287 jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
288
289 bitq_in_state.cmd = jtag_command_queue;
290 bitq_in_state.field_idx = 0;
291 bitq_in_state.bit_pos = 0;
292 bitq_in_state.status = ERROR_OK;
293
294 while (cmd) {
295
296 switch (cmd->type) {
297
298 case JTAG_END_STATE:
299 #ifdef _DEBUG_JTAG_IO_
300 DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
301 #endif
302 bitq_end_state(cmd->cmd.end_state->end_state);
303 break;
304
305 case JTAG_RESET:
306 #ifdef _DEBUG_JTAG_IO_
307 DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
308 #endif
309 bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
310 if (bitq_interface->in_rdy()) bitq_in_proc();
311 break;
312
313 case JTAG_RUNTEST:
314 #ifdef _DEBUG_JTAG_IO_
315 DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
316 #endif
317 bitq_end_state(cmd->cmd.runtest->end_state);
318 bitq_runtest(cmd->cmd.runtest->num_cycles);
319 break;
320
321 case JTAG_STATEMOVE:
322 #ifdef _DEBUG_JTAG_IO_
323 DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
324 #endif
325 bitq_end_state(cmd->cmd.statemove->end_state);
326 bitq_state_move(end_state); /* uncoditional TAP move */
327 break;
328
329 case JTAG_PATHMOVE:
330 #ifdef _DEBUG_JTAG_IO_
331 DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
332 #endif
333 bitq_path_move(cmd->cmd.pathmove);
334 break;
335
336 case JTAG_SCAN:
337 #ifdef _DEBUG_JTAG_IO_
338 DEBUG("scan end in %i", cmd->cmd.scan->end_state);
339 if (cmd->cmd.scan->ir_scan) DEBUG("scan ir");
340 else DEBUG("scan dr");
341 #endif
342 bitq_end_state(cmd->cmd.scan->end_state);
343 bitq_scan(cmd->cmd.scan);
344 if (cur_state != end_state) bitq_state_move(end_state);
345 break;
346
347 case JTAG_SLEEP:
348 #ifdef _DEBUG_JTAG_IO_
349 DEBUG("sleep %i", cmd->cmd.sleep->us);
350 #endif
351 bitq_interface->sleep(cmd->cmd.sleep->us);
352 if (bitq_interface->in_rdy()) bitq_in_proc();
353 break;
354
355 default:
356 ERROR("BUG: unknown JTAG command type encountered");
357 exit(-1);
358 }
359
360 cmd = cmd->next;
361 }
362
363 bitq_interface->flush();
364 bitq_in_proc();
365
366 if (bitq_in_state.cmd) {
367 ERROR("missing data from bitq interface");
368 return ERROR_JTAG_QUEUE_FAILED;
369 }
370 if (bitq_interface->in()>=0) {
371 ERROR("extra data from bitq interface");
372 return ERROR_JTAG_QUEUE_FAILED;
373 }
374
375 return bitq_in_state.status;
376 }
377
378
379 void bitq_cleanup(void)
380 {
381 if (bitq_in_buffer!=NULL)
382 {
383 free(bitq_in_buffer);
384 bitq_in_buffer=NULL;
385 }
386 }

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)