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  unsigned int field_idx; /* index of field currently being processed */
22  unsigned 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  for (unsigned int i = 0; i < cmd->num_states; i++) {
112  if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
113  bitq_io(0, 0, 0);
114  else if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
115  bitq_io(1, 0, 0);
116  else {
117  LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(
118  tap_get_state()), tap_state_name(cmd->path[i]));
119  exit(-1);
120  }
121 
122  tap_set_state(cmd->path[i]);
123  }
124 
126 }
127 
128 static void bitq_runtest(unsigned int num_cycles)
129 {
130  /* only do a state_move when we're not already in IDLE */
131  if (tap_get_state() != TAP_IDLE)
133 
134  /* execute num_cycles */
135  for (unsigned int i = 0; i < num_cycles; i++)
136  bitq_io(0, 0, 0);
137 
138  /* finish in end_state */
139  if (tap_get_state() != tap_get_end_state())
141 }
142 
143 static void bitq_scan_field(struct scan_field *field, int do_pause)
144 {
145  int tdo_req;
146 
147  const uint8_t *out_ptr;
148  uint8_t out_mask;
149 
150  if (field->in_value)
151  tdo_req = 1;
152  else
153  tdo_req = 0;
154 
155  if (!field->out_value) {
156  /* just send zeros and request data from TDO */
157  for (unsigned int i = 0; i < (field->num_bits - 1); i++)
158  bitq_io(0, 0, tdo_req);
159 
160  bitq_io(do_pause, 0, tdo_req);
161  } else {
162  /* send data, and optionally request TDO */
163  out_mask = 0x01;
164  out_ptr = field->out_value;
165  for (unsigned int i = 0; i < (field->num_bits - 1); i++) {
166  bitq_io(0, ((*out_ptr) & out_mask) != 0, tdo_req);
167  if (out_mask == 0x80) {
168  out_mask = 0x01;
169  out_ptr++;
170  } else
171  out_mask <<= 1;
172  }
173 
174  bitq_io(do_pause, ((*out_ptr) & out_mask) != 0, tdo_req);
175  }
176 
177  if (do_pause) {
178  bitq_io(0, 0, 0);
179  if (tap_get_state() == TAP_IRSHIFT)
181  else if (tap_get_state() == TAP_DRSHIFT)
183  }
184 }
185 
186 static void bitq_scan(struct scan_command *cmd)
187 {
188  if (cmd->ir_scan)
190  else
192 
193  unsigned int i;
194  for (i = 0; i < cmd->num_fields - 1; i++)
195  bitq_scan_field(&cmd->fields[i], 0);
196 
197  bitq_scan_field(&cmd->fields[i], 1);
198 }
199 
200 int bitq_execute_queue(struct jtag_command *cmd_queue)
201 {
202  struct jtag_command *cmd = cmd_queue; /* currently processed command */
203 
204  bitq_in_state.cmd = cmd_queue;
208 
209  while (cmd) {
210  switch (cmd->type) {
211  case JTAG_RESET:
212  LOG_DEBUG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
213  if ((cmd->cmd.reset->trst == 1) ||
214  (cmd->cmd.reset->srst &&
217  bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
218  if (bitq_interface->in_rdy())
219  bitq_in_proc();
220  break;
221 
222  case JTAG_RUNTEST:
223  LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
224  bitq_end_state(cmd->cmd.runtest->end_state);
225  bitq_runtest(cmd->cmd.runtest->num_cycles);
226  break;
227 
228  case JTAG_TLR_RESET:
229  LOG_DEBUG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
230  bitq_end_state(cmd->cmd.statemove->end_state);
231  bitq_state_move(tap_get_end_state()); /* unconditional TAP move */
232  break;
233 
234  case JTAG_PATHMOVE:
235  LOG_DEBUG_IO("pathmove: %u states, end in %i", cmd->cmd.pathmove->num_states,
236  cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
237  bitq_path_move(cmd->cmd.pathmove);
238  break;
239 
240  case JTAG_SCAN:
241  LOG_DEBUG_IO("scan end in %i", cmd->cmd.scan->end_state);
242  LOG_DEBUG_IO("scan %s", cmd->cmd.scan->ir_scan ? "ir" : "dr");
243  bitq_end_state(cmd->cmd.scan->end_state);
244  bitq_scan(cmd->cmd.scan);
245  if (tap_get_state() != tap_get_end_state())
247  break;
248 
249  case JTAG_SLEEP:
250  LOG_DEBUG_IO("sleep %" PRIu32, cmd->cmd.sleep->us);
251  bitq_interface->sleep(cmd->cmd.sleep->us);
252  if (bitq_interface->in_rdy())
253  bitq_in_proc();
254  break;
255 
256  default:
257  LOG_ERROR("BUG: unknown JTAG command type encountered");
258  exit(-1);
259  }
260 
261  cmd = cmd->next;
262  }
263 
265  bitq_in_proc();
266 
267  if (bitq_in_state.cmd) {
268  LOG_ERROR("missing data from bitq interface");
270  }
271  if (bitq_interface->in() >= 0) {
272  LOG_ERROR("extra data from bitq interface");
274  }
275 
276  return bitq_in_state.status;
277 }
278 
279 void bitq_cleanup(void)
280 {
281 }
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:186
struct bitq_interface * bitq_interface
Definition: bitq.c:16
static void bitq_state_move(tap_state_t new_state)
Definition: bitq.c:88
static void bitq_path_move(struct pathmove_command *cmd)
Definition: bitq.c:109
static void bitq_in_proc(void)
Definition: bitq.c:31
int bitq_execute_queue(struct jtag_command *cmd_queue)
Definition: bitq.c:200
static void bitq_runtest(unsigned int num_cycles)
Definition: bitq.c:128
static void bitq_scan_field(struct scan_field *field, int do_pause)
Definition: bitq.c:143
static struct bitq_state bitq_in_state
Definition: bitq.c:25
void bitq_cleanup(void)
Definition: bitq.c:279
@ 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:56
@ TAP_DRPAUSE
Definition: jtag.h:44
@ TAP_IRSHIFT
Definition: jtag.h:51
@ TAP_IDLE
Definition: jtag.h:53
@ TAP_DRSHIFT
Definition: jtag.h:43
@ TAP_IRPAUSE
Definition: jtag.h:52
#define ERROR_JTAG_QUEUE_FAILED
Definition: jtag.h:557
@ RESET_SRST_PULLS_TRST
Definition: jtag.h:221
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:132
#define ERROR_OK
Definition: log.h:164
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
unsigned int bit_pos
Definition: bitq.c:22
unsigned int field_idx
Definition: bitq.c:21
struct jtag_command * cmd
Definition: bitq.c:20
int status
Definition: bitq.c:23
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 structures that should be scann...
Definition: commands.h:35
unsigned int num_fields
number of fields in *fields array
Definition: commands.h:39
struct scan_field * fields
pointer to an array of data scan fields
Definition: commands.h:41
This structure defines a single scan field in the scan.
Definition: jtag.h:87
uint8_t * in_value
A pointer to a 32-bit memory location for data scanned out.
Definition: jtag.h:93
const uint8_t * out_value
A pointer to value to be scanned into the device.
Definition: jtag.h:91
unsigned int num_bits
The number of bits this field specifies.
Definition: jtag.h:89
struct scan_command * scan
Definition: commands.h:113
uint8_t cmd
Definition: vdebug.c:1
uint8_t state[4]
Definition: vdebug.c:21