The following patches was applied:
[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 bitq_interface_t* bitq_interface; /* low level bit queue interface */
38
39 bitq_state_t bitq_in_state; /* state of input queue */
40
41 u8* bitq_in_buffer; /* buffer dynamically reallocated as needed */
42 unsigned long bitq_in_bufsize = 32; /* min. buffer size */
43
44 /*
45 * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
46 * also the buffer for incomming data is reallocated only if necessary
47 * no parameters, makes use of stored state information
48 */
49 void bitq_in_proc(void)
50 {
51 /* static information preserved between calls to increase performance */
52 static u8* in_buff; /* pointer to buffer for scanned data */
53 static int in_idx; /* index of byte being scanned */
54 static u8 in_mask; /* mask of next bit to be scanned */
55
56 scan_field_t* field;
57 int tdo;
58
59 /* loop through the queue */
60 while (bitq_in_state.cmd)
61 {
62 /* only JTAG_SCAN command may return data */
63 if (bitq_in_state.cmd->type==JTAG_SCAN)
64 {
65 /* loop through the fields */
66 while (bitq_in_state.field_idx<bitq_in_state.cmd->cmd.scan->num_fields)
67 {
68 field = &bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];
69 if (field->in_value || field->in_handler)
70 {
71 if (bitq_in_state.bit_pos==0)
72 {
73 /* initialize field scanning */
74 in_mask = 0x01;
75 in_idx = 0;
76 if (field->in_value)
77 in_buff = field->in_value;
78 else
79 {
80 /* buffer reallocation needed? */
81 if (field->num_bits>bitq_in_bufsize * 8)
82 {
83 /* buffer previously allocated? */
84 if (bitq_in_buffer!=NULL)
85 {
86 /* free it */
87 free(bitq_in_buffer);
88 bitq_in_buffer = NULL;
89 }
90 /* double the buffer size until it fits */
91 while (field->num_bits>bitq_in_bufsize * 8)
92 bitq_in_bufsize *= 2;
93 }
94 /* if necessary, allocate buffer and check for malloc error */
95 if (bitq_in_buffer==NULL && ( bitq_in_buffer = malloc(bitq_in_bufsize) )==NULL)
96 {
97 LOG_ERROR("malloc error");
98 exit(-1);
99 }
100 in_buff = (void*) bitq_in_buffer;
101 }
102 }
103
104 /* field scanning */
105 while (bitq_in_state.bit_pos<field->num_bits)
106 {
107 if ( ( tdo = bitq_interface->in() )<0 )
108 {
109 #ifdef _DEBUG_JTAG_IO_
110 LOG_DEBUG("bitq in EOF");
111 #endif
112 return;
113 }
114 if (in_mask==0x01)
115 in_buff[in_idx] = 0;
116 if (tdo)
117 in_buff[in_idx] |= in_mask;
118 if (in_mask==0x80)
119 {
120 in_mask = 0x01;
121 in_idx++;
122 }
123 else
124 in_mask <<= 1;
125 bitq_in_state.bit_pos++;
126 }
127
128
129 if (field->in_handler && bitq_in_state.status==ERROR_OK)
130 {
131 bitq_in_state.status = (*field->in_handler)(in_buff, field->in_handler_priv, field);
132 }
133 }
134
135 bitq_in_state.field_idx++; /* advance to next field */
136 bitq_in_state.bit_pos = 0; /* start next field from the first bit */
137 }
138 }
139 bitq_in_state.cmd = bitq_in_state.cmd->next; /* advance to next command */
140 bitq_in_state.field_idx = 0; /* preselect first field */
141 }
142 }
143
144
145 void bitq_io(int tms, int tdi, int tdo_req)
146 {
147 bitq_interface->out(tms, tdi, tdo_req);
148 /* check and process the input queue */
149 if ( bitq_interface->in_rdy() )
150 bitq_in_proc();
151 }
152
153
154 void bitq_end_state(tap_state_t state)
155 {
156 if (state==TAP_INVALID)
157 return;
158
159 if (!tap_is_state_stable(state))
160 {
161 LOG_ERROR("BUG: %i is not a valid end state", state);
162 exit(-1);
163 }
164 tap_set_end_state(state);
165 }
166
167
168 void bitq_state_move(tap_state_t new_state)
169 {
170 int i = 0;
171 u8 tms_scan;
172
173 if (!tap_is_state_stable(tap_get_state()) || !tap_is_state_stable(new_state))
174 {
175 LOG_ERROR("TAP move from or to unstable state");
176 exit(-1);
177 }
178
179 tms_scan = tap_get_tms_path(tap_get_state(), new_state);
180
181 for (i = 0; i<7; i++)
182 {
183 bitq_io(tms_scan & 1, 0, 0);
184 tms_scan >>= 1;
185 }
186
187 tap_set_state(new_state);
188 }
189
190
191 void bitq_path_move(pathmove_command_t* cmd)
192 {
193 int i;
194
195 for (i = 0; i<=cmd->num_states; i++)
196 {
197 if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
198 bitq_io(0, 0, 0);
199 else if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
200 bitq_io(1, 0, 0);
201 else
202 {
203 LOG_ERROR( "BUG: %s -> %s isn't a valid TAP transition", tap_state_name(
204 tap_get_state() ), tap_state_name(cmd->path[i]) );
205 exit(-1);
206 }
207
208 tap_set_state(cmd->path[i]);
209 }
210
211 tap_set_end_state( tap_get_state() );
212 }
213
214
215 void bitq_runtest(int num_cycles)
216 {
217 int i;
218
219 /* only do a state_move when we're not already in IDLE */
220 if (tap_get_state() != TAP_IDLE)
221 bitq_state_move(TAP_IDLE);
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 ( tap_get_state() != tap_get_end_state() )
229 bitq_state_move( tap_get_end_state() );
230 }
231
232
233 void bitq_scan_field(scan_field_t* field, int pause)
234 {
235 int bit_cnt;
236 int tdo_req;
237
238 u8* out_ptr;
239 u8 out_mask;
240
241 if (field->in_value || field->in_handler)
242 tdo_req = 1;
243 else
244 tdo_req = 0;
245
246 if (field->out_value==NULL)
247 {
248 /* just send zeros and request data from TDO */
249 for (bit_cnt = field->num_bits; bit_cnt>1; bit_cnt--)
250 bitq_io(0, 0, tdo_req);
251
252 bitq_io(pause, 0, tdo_req);
253 }
254 else
255 {
256 /* send data, and optionally request TDO */
257 out_mask = 0x01;
258 out_ptr = field->out_value;
259 for (bit_cnt = field->num_bits; bit_cnt>1; bit_cnt--)
260 {
261 bitq_io(0, ( (*out_ptr) & out_mask )!=0, tdo_req);
262 if (out_mask==0x80)
263 {
264 out_mask = 0x01;
265 out_ptr++;
266 }
267 else
268 out_mask <<= 1;
269 }
270
271 bitq_io(pause, ( (*out_ptr) & out_mask )!=0, tdo_req);
272 }
273
274 if (pause)
275 {
276 bitq_io(0, 0, 0);
277 if (tap_get_state()==TAP_IRSHIFT)
278 tap_set_state(TAP_IRPAUSE);
279 else if (tap_get_state()==TAP_DRSHIFT)
280 tap_set_state(TAP_DRPAUSE);
281 }
282 }
283
284
285 void bitq_scan(scan_command_t* cmd)
286 {
287 int i;
288
289 if (cmd->ir_scan)
290 bitq_state_move(TAP_IRSHIFT);
291 else
292 bitq_state_move(TAP_DRSHIFT);
293
294 for (i = 0; i < cmd->num_fields - 1; i++)
295 bitq_scan_field(&cmd->fields[i], 0);
296
297 bitq_scan_field(&cmd->fields[i], 1);
298 }
299
300
301 int bitq_execute_queue(void)
302 {
303 jtag_command_t* cmd = jtag_command_queue; /* currently processed command */
304
305 bitq_in_state.cmd = jtag_command_queue;
306 bitq_in_state.field_idx = 0;
307 bitq_in_state.bit_pos = 0;
308 bitq_in_state.status = ERROR_OK;
309
310 while (cmd)
311 {
312 switch (cmd->type)
313 {
314 case JTAG_END_STATE:
315 #ifdef _DEBUG_JTAG_IO_
316 LOG_DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
317 #endif
318 bitq_end_state(cmd->cmd.end_state->end_state);
319 break;
320
321 case JTAG_RESET:
322 #ifdef _DEBUG_JTAG_IO_
323 LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
324 #endif
325 if ( (cmd->cmd.reset->trst == 1) || ( cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST) ) )
326 {
327 tap_set_state(TAP_RESET);
328 }
329 bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
330 if ( bitq_interface->in_rdy() )
331 bitq_in_proc();
332 break;
333
334 case JTAG_RUNTEST:
335 #ifdef _DEBUG_JTAG_IO_
336 LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
337 #endif
338 bitq_end_state(cmd->cmd.runtest->end_state);
339 bitq_runtest(cmd->cmd.runtest->num_cycles);
340 break;
341
342 case JTAG_STATEMOVE:
343 #ifdef _DEBUG_JTAG_IO_
344 LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
345 #endif
346 bitq_end_state(cmd->cmd.statemove->end_state);
347 bitq_state_move( tap_get_end_state() ); /* uncoditional TAP move */
348 break;
349
350 case JTAG_PATHMOVE:
351 #ifdef _DEBUG_JTAG_IO_
352 LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
353 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
354 #endif
355 bitq_path_move(cmd->cmd.pathmove);
356 break;
357
358 case JTAG_SCAN:
359 #ifdef _DEBUG_JTAG_IO_
360 LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state);
361 if (cmd->cmd.scan->ir_scan)
362 LOG_DEBUG("scan ir");
363 else
364 LOG_DEBUG("scan dr");
365 #endif
366 bitq_end_state(cmd->cmd.scan->end_state);
367 bitq_scan(cmd->cmd.scan);
368 if ( tap_get_state() != tap_get_end_state() )
369 bitq_state_move( tap_get_end_state() );
370 break;
371
372 case JTAG_SLEEP:
373 #ifdef _DEBUG_JTAG_IO_
374 LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
375 #endif
376 bitq_interface->sleep(cmd->cmd.sleep->us);
377 if ( bitq_interface->in_rdy() )
378 bitq_in_proc();
379 break;
380
381 default:
382 LOG_ERROR("BUG: unknown JTAG command type encountered");
383 exit(-1);
384 }
385
386 cmd = cmd->next;
387 }
388
389 bitq_interface->flush();
390 bitq_in_proc();
391
392 if (bitq_in_state.cmd)
393 {
394 LOG_ERROR("missing data from bitq interface");
395 return ERROR_JTAG_QUEUE_FAILED;
396 }
397 if (bitq_interface->in()>=0)
398 {
399 LOG_ERROR("extra data from bitq interface");
400 return ERROR_JTAG_QUEUE_FAILED;
401 }
402
403 return bitq_in_state.status;
404 }
405
406
407 void bitq_cleanup(void)
408 {
409 if (bitq_in_buffer!=NULL)
410 {
411 free(bitq_in_buffer);
412 bitq_in_buffer = NULL;
413 }
414 }

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)