in_handler in_check_mask and in_check_value now removed from field. Last big patch...
[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 static bitq_state_t bitq_in_state; /* state of input queue */
40
41 static u8* bitq_in_buffer; /* buffer dynamically reallocated as needed */
42 static int 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)
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 bitq_in_state.field_idx++; /* advance to next field */
130 bitq_in_state.bit_pos = 0; /* start next field from the first bit */
131 }
132 }
133 bitq_in_state.cmd = bitq_in_state.cmd->next; /* advance to next command */
134 bitq_in_state.field_idx = 0; /* preselect first field */
135 }
136 }
137
138
139 void bitq_io(int tms, int tdi, int tdo_req)
140 {
141 bitq_interface->out(tms, tdi, tdo_req);
142 /* check and process the input queue */
143 if ( bitq_interface->in_rdy() )
144 bitq_in_proc();
145 }
146
147
148 void bitq_end_state(tap_state_t state)
149 {
150 if (state==TAP_INVALID)
151 return;
152
153 if (!tap_is_state_stable(state))
154 {
155 LOG_ERROR("BUG: %i is not a valid end state", state);
156 exit(-1);
157 }
158 tap_set_end_state(state);
159 }
160
161
162 void bitq_state_move(tap_state_t new_state)
163 {
164 int i = 0;
165 u8 tms_scan;
166
167 if (!tap_is_state_stable(tap_get_state()) || !tap_is_state_stable(new_state))
168 {
169 LOG_ERROR("TAP move from or to unstable state");
170 exit(-1);
171 }
172
173 tms_scan = tap_get_tms_path(tap_get_state(), new_state);
174
175 for (i = 0; i<7; i++)
176 {
177 bitq_io(tms_scan & 1, 0, 0);
178 tms_scan >>= 1;
179 }
180
181 tap_set_state(new_state);
182 }
183
184
185 void bitq_path_move(pathmove_command_t* cmd)
186 {
187 int i;
188
189 for (i = 0; i<=cmd->num_states; i++)
190 {
191 if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
192 bitq_io(0, 0, 0);
193 else if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
194 bitq_io(1, 0, 0);
195 else
196 {
197 LOG_ERROR( "BUG: %s -> %s isn't a valid TAP transition", tap_state_name(
198 tap_get_state() ), tap_state_name(cmd->path[i]) );
199 exit(-1);
200 }
201
202 tap_set_state(cmd->path[i]);
203 }
204
205 tap_set_end_state( tap_get_state() );
206 }
207
208
209 void bitq_runtest(int num_cycles)
210 {
211 int i;
212
213 /* only do a state_move when we're not already in IDLE */
214 if (tap_get_state() != TAP_IDLE)
215 bitq_state_move(TAP_IDLE);
216
217 /* execute num_cycles */
218 for (i = 0; i < num_cycles; i++)
219 bitq_io(0, 0, 0);
220
221 /* finish in end_state */
222 if ( tap_get_state() != tap_get_end_state() )
223 bitq_state_move( tap_get_end_state() );
224 }
225
226
227 void bitq_scan_field(scan_field_t* field, int pause)
228 {
229 int bit_cnt;
230 int tdo_req;
231
232 u8* out_ptr;
233 u8 out_mask;
234
235 if (field->in_value)
236 tdo_req = 1;
237 else
238 tdo_req = 0;
239
240 if (field->out_value==NULL)
241 {
242 /* just send zeros and request data from TDO */
243 for (bit_cnt = field->num_bits; bit_cnt>1; bit_cnt--)
244 bitq_io(0, 0, tdo_req);
245
246 bitq_io(pause, 0, tdo_req);
247 }
248 else
249 {
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 {
255 bitq_io(0, ( (*out_ptr) & out_mask )!=0, tdo_req);
256 if (out_mask==0x80)
257 {
258 out_mask = 0x01;
259 out_ptr++;
260 }
261 else
262 out_mask <<= 1;
263 }
264
265 bitq_io(pause, ( (*out_ptr) & out_mask )!=0, tdo_req);
266 }
267
268 if (pause)
269 {
270 bitq_io(0, 0, 0);
271 if (tap_get_state()==TAP_IRSHIFT)
272 tap_set_state(TAP_IRPAUSE);
273 else if (tap_get_state()==TAP_DRSHIFT)
274 tap_set_state(TAP_DRPAUSE);
275 }
276 }
277
278
279 void bitq_scan(scan_command_t* cmd)
280 {
281 int i;
282
283 if (cmd->ir_scan)
284 bitq_state_move(TAP_IRSHIFT);
285 else
286 bitq_state_move(TAP_DRSHIFT);
287
288 for (i = 0; i < cmd->num_fields - 1; i++)
289 bitq_scan_field(&cmd->fields[i], 0);
290
291 bitq_scan_field(&cmd->fields[i], 1);
292 }
293
294
295 int bitq_execute_queue(void)
296 {
297 jtag_command_t* cmd = jtag_command_queue; /* currently processed command */
298
299 bitq_in_state.cmd = jtag_command_queue;
300 bitq_in_state.field_idx = 0;
301 bitq_in_state.bit_pos = 0;
302 bitq_in_state.status = ERROR_OK;
303
304 while (cmd)
305 {
306 switch (cmd->type)
307 {
308 case JTAG_END_STATE:
309 #ifdef _DEBUG_JTAG_IO_
310 LOG_DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
311 #endif
312 bitq_end_state(cmd->cmd.end_state->end_state);
313 break;
314
315 case JTAG_RESET:
316 #ifdef _DEBUG_JTAG_IO_
317 LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
318 #endif
319 if ( (cmd->cmd.reset->trst == 1) || ( cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST) ) )
320 {
321 tap_set_state(TAP_RESET);
322 }
323 bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
324 if ( bitq_interface->in_rdy() )
325 bitq_in_proc();
326 break;
327
328 case JTAG_RUNTEST:
329 #ifdef _DEBUG_JTAG_IO_
330 LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
331 #endif
332 bitq_end_state(cmd->cmd.runtest->end_state);
333 bitq_runtest(cmd->cmd.runtest->num_cycles);
334 break;
335
336 case JTAG_STATEMOVE:
337 #ifdef _DEBUG_JTAG_IO_
338 LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
339 #endif
340 bitq_end_state(cmd->cmd.statemove->end_state);
341 bitq_state_move( tap_get_end_state() ); /* uncoditional TAP move */
342 break;
343
344 case JTAG_PATHMOVE:
345 #ifdef _DEBUG_JTAG_IO_
346 LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
347 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
348 #endif
349 bitq_path_move(cmd->cmd.pathmove);
350 break;
351
352 case JTAG_SCAN:
353 #ifdef _DEBUG_JTAG_IO_
354 LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state);
355 if (cmd->cmd.scan->ir_scan)
356 LOG_DEBUG("scan ir");
357 else
358 LOG_DEBUG("scan dr");
359 #endif
360 bitq_end_state(cmd->cmd.scan->end_state);
361 bitq_scan(cmd->cmd.scan);
362 if ( tap_get_state() != tap_get_end_state() )
363 bitq_state_move( tap_get_end_state() );
364 break;
365
366 case JTAG_SLEEP:
367 #ifdef _DEBUG_JTAG_IO_
368 LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
369 #endif
370 bitq_interface->sleep(cmd->cmd.sleep->us);
371 if ( bitq_interface->in_rdy() )
372 bitq_in_proc();
373 break;
374
375 default:
376 LOG_ERROR("BUG: unknown JTAG command type encountered");
377 exit(-1);
378 }
379
380 cmd = cmd->next;
381 }
382
383 bitq_interface->flush();
384 bitq_in_proc();
385
386 if (bitq_in_state.cmd)
387 {
388 LOG_ERROR("missing data from bitq interface");
389 return ERROR_JTAG_QUEUE_FAILED;
390 }
391 if (bitq_interface->in()>=0)
392 {
393 LOG_ERROR("extra data from bitq interface");
394 return ERROR_JTAG_QUEUE_FAILED;
395 }
396
397 return bitq_in_state.status;
398 }
399
400
401 void bitq_cleanup(void)
402 {
403 if (bitq_in_buffer!=NULL)
404 {
405 free(bitq_in_buffer);
406 bitq_in_buffer = NULL;
407 }
408 }

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)