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

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)