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