bitq: remove dead code
[openocd.git] / src / jtag / drivers / 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 <jtag/jtag.h>
25 #include "bitq.h"
26 #include <jtag/interface.h>
27
28
29 struct bitq_interface* bitq_interface; /* low level bit queue interface */
30
31 /* state of input queue */
32 struct bitq_state {
33 struct jtag_command *cmd; /* command currently processed */
34 int field_idx; /* index of field currently being processed */
35 int bit_pos; /* position of bit curently being processed */
36 int status; /* processing status */
37 };
38 static struct bitq_state bitq_in_state;
39
40 /*
41 * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
42 * no parameters, makes use of stored state information
43 */
44 void bitq_in_proc(void)
45 {
46 /* static information preserved between calls to increase performance */
47 static uint8_t* in_buff; /* pointer to buffer for scanned data */
48 static int in_idx; /* index of byte being scanned */
49 static uint8_t in_mask; /* mask of next bit to be scanned */
50
51 struct scan_field* field;
52 int tdo;
53
54 /* loop through the queue */
55 while (bitq_in_state.cmd)
56 {
57 /* only JTAG_SCAN command may return data */
58 if (bitq_in_state.cmd->type == JTAG_SCAN)
59 {
60 /* loop through the fields */
61 while (bitq_in_state.field_idx < bitq_in_state.cmd->cmd.scan->num_fields)
62 {
63 field = &bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];
64 if (field->in_value)
65 {
66 if (bitq_in_state.bit_pos == 0)
67 {
68 /* initialize field scanning */
69 in_mask = 0x01;
70 in_idx = 0;
71 in_buff = field->in_value;
72 }
73
74 /* field scanning */
75 while (bitq_in_state.bit_pos < field->num_bits)
76 {
77 if ((tdo = bitq_interface->in()) < 0)
78 {
79 #ifdef _DEBUG_JTAG_IO_
80 LOG_DEBUG("bitq in EOF");
81 #endif
82 return;
83 }
84 if (in_mask == 0x01)
85 in_buff[in_idx] = 0;
86 if (tdo)
87 in_buff[in_idx] |= in_mask;
88 if (in_mask == 0x80)
89 {
90 in_mask = 0x01;
91 in_idx++;
92 }
93 else
94 in_mask <<= 1;
95 bitq_in_state.bit_pos++;
96 }
97 }
98
99 bitq_in_state.field_idx++; /* advance to next field */
100 bitq_in_state.bit_pos = 0; /* start next field from the first bit */
101 }
102 }
103 bitq_in_state.cmd = bitq_in_state.cmd->next; /* advance to next command */
104 bitq_in_state.field_idx = 0; /* preselect first field */
105 }
106 }
107
108
109 void bitq_io(int tms, int tdi, int tdo_req)
110 {
111 bitq_interface->out(tms, tdi, tdo_req);
112 /* check and process the input queue */
113 if (bitq_interface->in_rdy())
114 bitq_in_proc();
115 }
116
117
118 void bitq_end_state(tap_state_t state)
119 {
120 if (!tap_is_state_stable(state))
121 {
122 LOG_ERROR("BUG: %i is not a valid end state", state);
123 exit(-1);
124 }
125 tap_set_end_state(state);
126 }
127
128
129 void bitq_state_move(tap_state_t new_state)
130 {
131 int i = 0;
132 uint8_t tms_scan;
133
134 if (!tap_is_state_stable(tap_get_state()) || !tap_is_state_stable(new_state))
135 {
136 LOG_ERROR("TAP move from or to unstable state");
137 exit(-1);
138 }
139
140 tms_scan = tap_get_tms_path(tap_get_state(), new_state);
141 int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
142
143 for (i = 0; i < tms_count; i++)
144 {
145 bitq_io(tms_scan & 1, 0, 0);
146 tms_scan >>= 1;
147 }
148
149 tap_set_state(new_state);
150 }
151
152
153 void bitq_path_move(struct pathmove_command* cmd)
154 {
155 int i;
156
157 for (i = 0; i <= cmd->num_states; i++)
158 {
159 if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
160 bitq_io(0, 0, 0);
161 else if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
162 bitq_io(1, 0, 0);
163 else
164 {
165 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(
166 tap_get_state()), tap_state_name(cmd->path[i]));
167 exit(-1);
168 }
169
170 tap_set_state(cmd->path[i]);
171 }
172
173 tap_set_end_state(tap_get_state());
174 }
175
176
177 void bitq_runtest(int num_cycles)
178 {
179 int i;
180
181 /* only do a state_move when we're not already in IDLE */
182 if (tap_get_state() != TAP_IDLE)
183 bitq_state_move(TAP_IDLE);
184
185 /* execute num_cycles */
186 for (i = 0; i < num_cycles; i++)
187 bitq_io(0, 0, 0);
188
189 /* finish in end_state */
190 if (tap_get_state() != tap_get_end_state())
191 bitq_state_move(tap_get_end_state());
192 }
193
194
195 void bitq_scan_field(struct scan_field* field, int do_pause)
196 {
197 int bit_cnt;
198 int tdo_req;
199
200 const uint8_t* out_ptr;
201 uint8_t out_mask;
202
203 if (field->in_value)
204 tdo_req = 1;
205 else
206 tdo_req = 0;
207
208 if (field->out_value == NULL)
209 {
210 /* just send zeros and request data from TDO */
211 for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--)
212 bitq_io(0, 0, tdo_req);
213
214 bitq_io(do_pause, 0, tdo_req);
215 }
216 else
217 {
218 /* send data, and optionally request TDO */
219 out_mask = 0x01;
220 out_ptr = field->out_value;
221 for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--)
222 {
223 bitq_io(0, ((*out_ptr) & out_mask) != 0, tdo_req);
224 if (out_mask == 0x80)
225 {
226 out_mask = 0x01;
227 out_ptr++;
228 }
229 else
230 out_mask <<= 1;
231 }
232
233 bitq_io(do_pause, ((*out_ptr) & out_mask) != 0, tdo_req);
234 }
235
236 if (do_pause)
237 {
238 bitq_io(0, 0, 0);
239 if (tap_get_state() == TAP_IRSHIFT)
240 tap_set_state(TAP_IRPAUSE);
241 else if (tap_get_state() == TAP_DRSHIFT)
242 tap_set_state(TAP_DRPAUSE);
243 }
244 }
245
246
247 void bitq_scan(struct scan_command* cmd)
248 {
249 int i;
250
251 if (cmd->ir_scan)
252 bitq_state_move(TAP_IRSHIFT);
253 else
254 bitq_state_move(TAP_DRSHIFT);
255
256 for (i = 0; i < cmd->num_fields - 1; i++)
257 bitq_scan_field(&cmd->fields[i], 0);
258
259 bitq_scan_field(&cmd->fields[i], 1);
260 }
261
262
263 int bitq_execute_queue(void)
264 {
265 struct jtag_command* cmd = jtag_command_queue; /* currently processed command */
266
267 bitq_in_state.cmd = jtag_command_queue;
268 bitq_in_state.field_idx = 0;
269 bitq_in_state.bit_pos = 0;
270 bitq_in_state.status = ERROR_OK;
271
272 while (cmd)
273 {
274 switch (cmd->type)
275 {
276 case JTAG_RESET:
277 #ifdef _DEBUG_JTAG_IO_
278 LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
279 #endif
280 if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
281 {
282 tap_set_state(TAP_RESET);
283 }
284 bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
285 if (bitq_interface->in_rdy())
286 bitq_in_proc();
287 break;
288
289 case JTAG_RUNTEST:
290 #ifdef _DEBUG_JTAG_IO_
291 LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
292 #endif
293 bitq_end_state(cmd->cmd.runtest->end_state);
294 bitq_runtest(cmd->cmd.runtest->num_cycles);
295 break;
296
297 case JTAG_TLR_RESET:
298 #ifdef _DEBUG_JTAG_IO_
299 LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
300 #endif
301 bitq_end_state(cmd->cmd.statemove->end_state);
302 bitq_state_move(tap_get_end_state()); /* uncoditional TAP move */
303 break;
304
305 case JTAG_PATHMOVE:
306 #ifdef _DEBUG_JTAG_IO_
307 LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
308 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
309 #endif
310 bitq_path_move(cmd->cmd.pathmove);
311 break;
312
313 case JTAG_SCAN:
314 #ifdef _DEBUG_JTAG_IO_
315 LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state);
316 if (cmd->cmd.scan->ir_scan)
317 LOG_DEBUG("scan ir");
318 else
319 LOG_DEBUG("scan dr");
320 #endif
321 bitq_end_state(cmd->cmd.scan->end_state);
322 bitq_scan(cmd->cmd.scan);
323 if (tap_get_state() != tap_get_end_state())
324 bitq_state_move(tap_get_end_state());
325 break;
326
327 case JTAG_SLEEP:
328 #ifdef _DEBUG_JTAG_IO_
329 LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
330 #endif
331 bitq_interface->sleep(cmd->cmd.sleep->us);
332 if (bitq_interface->in_rdy())
333 bitq_in_proc();
334 break;
335
336 default:
337 LOG_ERROR("BUG: unknown JTAG command type encountered");
338 exit(-1);
339 }
340
341 cmd = cmd->next;
342 }
343
344 bitq_interface->flush();
345 bitq_in_proc();
346
347 if (bitq_in_state.cmd)
348 {
349 LOG_ERROR("missing data from bitq interface");
350 return ERROR_JTAG_QUEUE_FAILED;
351 }
352 if (bitq_interface->in() >= 0)
353 {
354 LOG_ERROR("extra data from bitq interface");
355 return ERROR_JTAG_QUEUE_FAILED;
356 }
357
358 return bitq_in_state.status;
359 }
360
361
362 void bitq_cleanup(void)
363 {
364 }

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)