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

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)