OpenOCD
bitq.c
Go to the documentation of this file.
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 */
39  struct scan_field *field;
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;
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 
80 {
81  if (!tap_is_state_stable(state)) {
82  LOG_ERROR("BUG: %i is not a valid end state", state);
83  exit(-1);
84  }
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 
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)
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())
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)
186  else if (tap_get_state() == TAP_DRSHIFT)
188  }
189 }
190 
191 static void bitq_scan(struct scan_command *cmd)
192 {
193  int i;
194 
195  if (cmd->ir_scan)
197  else
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 
207 {
208  struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
209 
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 &&
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())
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 
271  bitq_in_proc();
272 
273  if (bitq_in_state.cmd) {
274  LOG_ERROR("missing data from bitq interface");
276  }
277  if (bitq_interface->in() >= 0) {
278  LOG_ERROR("extra data from bitq interface");
280  }
281 
282  return bitq_in_state.status;
283 }
284 
285 void bitq_cleanup(void)
286 {
287 }
static void bitq_io(int tms, int tdi, int tdo_req)
Definition: bitq.c:71
static void bitq_end_state(tap_state_t state)
Definition: bitq.c:79
static void bitq_scan(struct scan_command *cmd)
Definition: bitq.c:191
struct bitq_interface * bitq_interface
Definition: bitq.c:16
static void bitq_state_move(tap_state_t new_state)
Definition: bitq.c:88
int bitq_execute_queue(void)
Definition: bitq.c:206
static void bitq_path_move(struct pathmove_command *cmd)
Definition: bitq.c:109
static void bitq_in_proc(void)
Definition: bitq.c:31
static void bitq_runtest(int num_cycles)
Definition: bitq.c:130
static void bitq_scan_field(struct scan_field *field, int do_pause)
Definition: bitq.c:147
static struct bitq_state bitq_in_state
Definition: bitq.c:25
void bitq_cleanup(void)
Definition: bitq.c:285
struct jtag_command * jtag_command_queue
The current queue of jtag_command_s structures.
Definition: commands.c:36
@ JTAG_TLR_RESET
Definition: commands.h:137
@ JTAG_SCAN
Definition: commands.h:129
@ JTAG_PATHMOVE
Definition: commands.h:140
@ JTAG_RUNTEST
Definition: commands.h:138
@ JTAG_SLEEP
Definition: commands.h:141
@ JTAG_RESET
Definition: commands.h:139
bool tap_is_state_stable(tap_state_t astate)
Function tap_is_state_stable returns true if the astate is stable.
Definition: interface.c:200
tap_state_t tap_state_transition(tap_state_t cur_state, bool tms)
Function tap_state_transition takes a current TAP state and returns the next state according to the t...
Definition: interface.c:223
const char * tap_state_name(tap_state_t state)
Function tap_state_name Returns a string suitable for display representing the JTAG tap_state.
Definition: interface.c:344
void tap_set_end_state(tap_state_t new_end_state)
This function sets the state of an "end state follower" which tracks the state that any cable driver ...
Definition: interface.c:48
tap_state_t tap_get_end_state(void)
For more information,.
Definition: interface.c:56
int tap_get_tms_path(tap_state_t from, tap_state_t to)
This function provides a "bit sequence" indicating what has to be done with TMS during a sequence of ...
Definition: interface.c:190
int tap_get_tms_path_len(tap_state_t from, tap_state_t to)
Function int tap_get_tms_path_len returns the total number of bits that represents a TMS path transit...
Definition: interface.c:195
tap_state_t tap_get_state(void)
This function gets the state of the "state follower" which tracks the state of the TAPs connected to ...
Definition: interface.c:37
#define tap_set_state(new_state)
This function sets the state of a "state follower" which tracks the state of the TAPs connected to th...
Definition: interface.h:49
enum reset_types jtag_get_reset_config(void)
Definition: jtag/core.c:1734
The JTAG interface can be implemented with a software or hardware fifo.
@ TAP_RESET
Definition: jtag.h:55
@ TAP_DRPAUSE
Definition: jtag.h:43
@ TAP_IRSHIFT
Definition: jtag.h:50
@ TAP_IDLE
Definition: jtag.h:52
@ TAP_DRSHIFT
Definition: jtag.h:42
@ TAP_IRPAUSE
Definition: jtag.h:51
#define ERROR_JTAG_QUEUE_FAILED
Definition: jtag.h:553
@ RESET_SRST_PULLS_TRST
Definition: jtag.h:217
enum tap_state tap_state_t
Defines JTAG Test Access Port states.
#define LOG_DEBUG_IO(expr ...)
Definition: log.h:101
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define ERROR_OK
Definition: log.h:155
int(* in_rdy)(void)
Definition: bitq.h:24
int(* sleep)(unsigned long us)
Definition: bitq.h:18
int(* flush)(void)
Definition: bitq.h:16
int(* in)(void)
Definition: bitq.h:25
int(* reset)(int trst, int srst)
Definition: bitq.h:19
int(* out)(int tms, int tdi, int tdo_req)
Definition: bitq.h:15
int bit_pos
Definition: bitq.c:22
struct jtag_command * cmd
Definition: bitq.c:20
int status
Definition: bitq.c:23
int field_idx
Definition: bitq.c:21
enum jtag_command_type type
Definition: commands.h:148
struct jtag_command * next
Definition: commands.h:149
union jtag_command_container cmd
Definition: commands.h:147
The scan_command provide a means of encapsulating a set of scan_field_s structures that should be sca...
Definition: commands.h:35
struct scan_field * fields
pointer to an array of data scan fields
Definition: commands.h:41
int num_fields
number of fields in *fields array
Definition: commands.h:39
This structure defines a single scan field in the scan.
Definition: jtag.h:86
int num_bits
The number of bits this field specifies.
Definition: jtag.h:88
uint8_t * in_value
A pointer to a 32-bit memory location for data scanned out.
Definition: jtag.h:92
const uint8_t * out_value
A pointer to value to be scanned into the device.
Definition: jtag.h:90
struct scan_command * scan
Definition: commands.h:113
uint8_t cmd
Definition: vdebug.c:1
uint8_t state[4]
Definition: vdebug.c:21