OpenOCD
batch.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #ifndef OPENOCD_TARGET_RISCV_BATCH_H
4 #define OPENOCD_TARGET_RISCV_BATCH_H
5 
6 #include "target/target.h"
7 #include "jtag/jtag.h"
8 #include "riscv.h"
9 
15 };
16 
17 /* These types are used to specify how many JTAG RTI cycles to add after a
18  * scan.
19  */
21  /* Delay needed for accessing debug module registers: */
23  /* Delay for execution of an abstract command: */
25  /* Delay for System Bus read operation: */
27  /* Delay for System Bus write operation: */
29 };
30 
31 static inline const char *
33 {
34  switch (delay_class) {
35  case RISCV_DELAY_BASE:
36  return "DM access";
38  return "Abstract Command";
40  return "System Bus read";
42  return "System Bus write";
43  }
44  assert(0);
45  return NULL;
46 }
47 
48 /* The scan delay values are passed to "jtag_add_runtest()", which accepts an
49  * "int". Therefore, the passed value should be no greater than "INT_MAX".
50  *
51  * Since the resulting delay value can be a sum of two individual delays,
52  * individual delays are limited to "INT_MAX / 2" to prevent overflow of the
53  * final sum.
54  */
55 #define RISCV_SCAN_DELAY_MAX (INT_MAX / 2)
56 
58  unsigned int base_delay;
59  unsigned int ac_delay;
60  unsigned int sb_read_delay;
61  unsigned int sb_write_delay;
62 };
63 
64 static inline unsigned int
66  enum riscv_scan_delay_class delay_class)
67 {
68  switch (delay_class) {
69  case RISCV_DELAY_BASE:
70  return delays->base_delay;
72  return delays->base_delay + delays->ac_delay;
74  return delays->base_delay + delays->sb_read_delay;
76  return delays->base_delay + delays->sb_write_delay;
77  }
78  assert(0);
79  return 0;
80 }
81 
82 static inline void riscv_scan_set_delay(struct riscv_scan_delays *delays,
83  enum riscv_scan_delay_class delay_class, unsigned int delay)
84 {
85  assert(delay <= RISCV_SCAN_DELAY_MAX);
86  LOG_DEBUG("%s delay is set to %u.",
87  riscv_scan_delay_class_name(delay_class), delay);
88  switch (delay_class) {
89  case RISCV_DELAY_BASE:
90  delays->base_delay = delay;
91  return;
93  delays->ac_delay = delay;
94  return;
96  delays->sb_read_delay = delay;
97  return;
99  delays->sb_write_delay = delay;
100  return;
101  }
102  assert(0);
103 }
104 
105 static inline int riscv_scan_increase_delay(struct riscv_scan_delays *delays,
106  enum riscv_scan_delay_class delay_class)
107 {
108  const unsigned int delay = riscv_scan_get_delay(delays, delay_class);
109  const unsigned int delay_step = delay / 10 + 1;
110  if (delay > RISCV_SCAN_DELAY_MAX - delay_step) {
111  /* It's not clear if this issue actually occurs in real
112  * use-cases, so stick with a simple solution until the
113  * first bug report.
114  */
115  LOG_ERROR("Delay for %s (%d) is not increased anymore (maximum was reached).",
116  riscv_scan_delay_class_name(delay_class), delay);
117  return ERROR_FAIL;
118  }
119  riscv_scan_set_delay(delays, delay_class, delay + delay_step);
120  return ERROR_OK;
121 }
122 
123 /* A batch of multiple JTAG scans, which are grouped together to avoid the
124  * overhead of some JTAG adapters when sending single commands. This is
125  * designed to support block copies, as that's what we actually need to go
126  * fast. */
127 struct riscv_batch {
128  struct target *target;
129 
131  size_t used_scans;
132 
133  uint8_t *data_out;
134  uint8_t *data_in;
137 
138  /* If in BSCAN mode, this field will be allocated (one per scan),
139  and utilized to tunnel all the scans in the batch. If not in
140  BSCAN mode, this field is unallocated and stays NULL */
142 
143  /* In JTAG we scan out the previous value's output when performing a
144  * scan. This is a pain for users, so we just provide them the
145  * illusion of not having to do this by eliding all but the last NOP.
146  * */
148 
149  /* The read keys. */
150  size_t *read_keys;
152 
153  /* Flag indicating that the last run of the batch finished without an error
154  * from the underlying JTAG layer of OpenOCD - all scans were performed.
155  * However, RISC-V DMI "busy" condition could still have occurred.
156  */
157  bool was_run;
158  /* Number of RTI cycles used by the last scan on the last run.
159  * Only valid when `was_run` is set.
160  */
161  unsigned int last_scan_delay;
162 };
163 
164 /* Allocates (or frees) a new scan set. "scans" is the maximum number of JTAG
165  * scans that can be issued to this object. */
166 struct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans);
167 void riscv_batch_free(struct riscv_batch *batch);
168 
169 /* Checks to see if this batch is full. */
170 bool riscv_batch_full(struct riscv_batch *batch);
171 
172 /* Executes this batch of JTAG DTM DMI scans, starting form "start" scan.
173  *
174  * If batch is run for the first time, it is expected that "start" is zero.
175  * It is expected that the batch ends with a DMI NOP operation.
176  *
177  * "idle_counts" specifies the number of JTAG Run-Test-Idle cycles to add
178  * after each scan depending on the delay class of the scan.
179  *
180  * If "resets_delays" is true, the algorithm will stop inserting idle cycles
181  * (JTAG Run-Test-Idle) after "reset_delays_after" number of scans is
182  * performed. This is useful for stress-testing of RISC-V algorithms in
183  * OpenOCD that are based on batches.
184  */
185 int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
186  const struct riscv_scan_delays *delays, bool resets_delays,
187  size_t reset_delays_after);
188 
189 /* Get the number of scans successfully executed form this batch. */
190 size_t riscv_batch_finished_scans(const struct riscv_batch *batch);
191 
192 /* Adds a DM register write to this batch. */
193 void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint32_t address, uint32_t data,
194  bool read_back, enum riscv_scan_delay_class delay_class);
195 
196 static inline void
197 riscv_batch_add_dm_write(struct riscv_batch *batch, uint32_t address, uint32_t data,
198  bool read_back, enum riscv_scan_delay_class delay_type)
199 {
200  return riscv_batch_add_dmi_write(batch,
201  riscv_get_dmi_address(batch->target, address), data,
202  read_back, delay_type);
203 }
204 
205 /* DM register reads must be handled in two parts: the first one schedules a read and
206  * provides a key, the second one actually obtains the result of the read -
207  * status (op) and the actual data. */
208 size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint32_t address,
209  enum riscv_scan_delay_class delay_class);
210 
211 static inline size_t
213  enum riscv_scan_delay_class delay_type)
214 {
215  return riscv_batch_add_dmi_read(batch,
216  riscv_get_dmi_address(batch->target, address), delay_type);
217 }
218 
219 uint32_t riscv_batch_get_dmi_read_op(const struct riscv_batch *batch, size_t key);
220 uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t key);
221 
222 /* Scans in a NOP. */
223 void riscv_batch_add_nop(struct riscv_batch *batch);
224 
225 /* Returns the number of available scans. */
226 size_t riscv_batch_available_scans(struct riscv_batch *batch);
227 
228 /* Return true iff the last scan in the batch returned DMI_OP_BUSY. */
229 bool riscv_batch_was_batch_busy(const struct riscv_batch *batch);
230 
231 #endif /* OPENOCD_TARGET_RISCV_BATCH_H */
bool riscv_batch_was_batch_busy(const struct riscv_batch *batch)
Definition: batch.c:438
static int riscv_scan_increase_delay(struct riscv_scan_delays *delays, enum riscv_scan_delay_class delay_class)
Definition: batch.h:105
uint32_t riscv_batch_get_dmi_read_op(const struct riscv_batch *batch, size_t key)
Definition: batch.c:389
struct riscv_batch * riscv_batch_alloc(struct target *target, size_t scans)
Definition: batch.c:31
void riscv_batch_add_nop(struct riscv_batch *batch)
Definition: batch.c:409
void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint32_t address, uint32_t data, bool read_back, enum riscv_scan_delay_class delay_class)
Definition: batch.c:331
riscv_scan_delay_class
Definition: batch.h:20
@ RISCV_DELAY_ABSTRACT_COMMAND
Definition: batch.h:24
@ RISCV_DELAY_SYSBUS_READ
Definition: batch.h:26
@ RISCV_DELAY_BASE
Definition: batch.h:22
@ RISCV_DELAY_SYSBUS_WRITE
Definition: batch.h:28
size_t riscv_batch_available_scans(struct riscv_batch *batch)
Definition: batch.c:432
static size_t riscv_batch_add_dm_read(struct riscv_batch *batch, uint32_t address, enum riscv_scan_delay_class delay_type)
Definition: batch.h:212
static void riscv_scan_set_delay(struct riscv_scan_delays *delays, enum riscv_scan_delay_class delay_class, unsigned int delay)
Definition: batch.h:82
uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t key)
Definition: batch.c:399
size_t riscv_batch_finished_scans(const struct riscv_batch *batch)
Definition: batch.c:446
#define RISCV_SCAN_DELAY_MAX
Definition: batch.h:55
static unsigned int riscv_scan_get_delay(const struct riscv_scan_delays *delays, enum riscv_scan_delay_class delay_class)
Definition: batch.h:65
static void riscv_batch_add_dm_write(struct riscv_batch *batch, uint32_t address, uint32_t data, bool read_back, enum riscv_scan_delay_class delay_type)
Definition: batch.h:197
riscv_scan_type
Definition: batch.h:10
@ RISCV_SCAN_TYPE_INVALID
Definition: batch.h:11
@ RISCV_SCAN_TYPE_WRITE
Definition: batch.h:14
@ RISCV_SCAN_TYPE_NOP
Definition: batch.h:12
@ RISCV_SCAN_TYPE_READ
Definition: batch.h:13
void riscv_batch_free(struct riscv_batch *batch)
Definition: batch.c:96
size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint32_t address, enum riscv_scan_delay_class delay_class)
Definition: batch.c:361
static const char * riscv_scan_delay_class_name(enum riscv_scan_delay_class delay_class)
Definition: batch.h:32
int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx, const struct riscv_scan_delays *delays, bool resets_delays, size_t reset_delays_after)
Definition: batch.c:278
bool riscv_batch_full(struct riscv_batch *batch)
Definition: batch.c:107
uint32_t address
Starting address. Sector aligned.
Definition: dw-spi-helper.h:0
The JTAG interface can be implemented with a software or hardware fifo.
#define ERROR_FAIL
Definition: log.h:175
#define LOG_ERROR(expr ...)
Definition: log.h:134
#define LOG_DEBUG(expr ...)
Definition: log.h:111
#define ERROR_OK
Definition: log.h:169
uint32_t riscv_get_dmi_address(const struct target *target, uint32_t dm_address)
Definition: riscv.c:4649
uint8_t * data_in
Definition: batch.h:134
riscv_bscan_tunneled_scan_context_t * bscan_ctxt
Definition: batch.h:141
size_t allocated_scans
Definition: batch.h:130
struct target * target
Definition: batch.h:128
enum riscv_scan_type last_scan
Definition: batch.h:147
enum riscv_scan_delay_class * delay_classes
Definition: batch.h:136
bool was_run
Definition: batch.h:157
size_t * read_keys
Definition: batch.h:150
uint8_t * data_out
Definition: batch.h:133
size_t read_keys_used
Definition: batch.h:151
unsigned int last_scan_delay
Definition: batch.h:161
size_t used_scans
Definition: batch.h:131
struct scan_field * fields
Definition: batch.h:135
unsigned int sb_read_delay
Definition: batch.h:60
unsigned int ac_delay
Definition: batch.h:59
unsigned int base_delay
Definition: batch.h:58
unsigned int sb_write_delay
Definition: batch.h:61
This structure defines a single scan field in the scan.
Definition: jtag.h:87
Definition: target.h:119
#define NULL
Definition: usb.h:16