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  * "unsigned int".
50  */
51 
53  unsigned int base_delay;
54  unsigned int ac_delay;
55  unsigned int sb_read_delay;
56  unsigned int sb_write_delay;
57 };
58 
59 static inline unsigned int
61  enum riscv_scan_delay_class delay_class)
62 {
63  switch (delay_class) {
64  case RISCV_DELAY_BASE:
65  return delays->base_delay;
67  return delays->base_delay + delays->ac_delay;
69  return delays->base_delay + delays->sb_read_delay;
71  return delays->base_delay + delays->sb_write_delay;
72  }
73  assert(0);
74  return 0;
75 }
76 
77 static inline void riscv_scan_set_delay(struct riscv_scan_delays *delays,
78  enum riscv_scan_delay_class delay_class, unsigned int delay)
79 {
80  LOG_DEBUG("%s delay is set to %u.",
81  riscv_scan_delay_class_name(delay_class), delay);
82  switch (delay_class) {
83  case RISCV_DELAY_BASE:
84  delays->base_delay = delay;
85  return;
87  delays->ac_delay = delay;
88  return;
90  delays->sb_read_delay = delay;
91  return;
93  delays->sb_write_delay = delay;
94  return;
95  }
96  assert(0);
97 }
98 
99 static inline int riscv_scan_increase_delay(struct riscv_scan_delays *delays,
100  enum riscv_scan_delay_class delay_class)
101 {
102  const unsigned int delay = riscv_scan_get_delay(delays, delay_class);
103  const unsigned int delay_step = delay / 10 + 1;
104  if (delay + delay_step < delay) {
105  LOG_ERROR("Delay for %s (%u) is not increased anymore (maximum was reached).",
106  riscv_scan_delay_class_name(delay_class), delay);
107  return ERROR_FAIL;
108  }
109  riscv_scan_set_delay(delays, delay_class, delay + delay_step);
110  return ERROR_OK;
111 }
112 
113 /* A batch of multiple JTAG scans, which are grouped together to avoid the
114  * overhead of some JTAG adapters when sending single commands. This is
115  * designed to support block copies, as that's what we actually need to go
116  * fast. */
117 struct riscv_batch {
118  struct target *target;
119 
121  size_t used_scans;
122 
123  uint8_t *data_out;
124  uint8_t *data_in;
127 
128  /* If in BSCAN mode, this field will be allocated (one per scan),
129  and utilized to tunnel all the scans in the batch. If not in
130  BSCAN mode, this field is unallocated and stays NULL */
132 
133  /* In JTAG we scan out the previous value's output when performing a
134  * scan. This is a pain for users, so we just provide them the
135  * illusion of not having to do this by eliding all but the last NOP.
136  * */
138 
139  /* The read keys. */
140  size_t *read_keys;
142 
143  /* Flag indicating that the last run of the batch finished without an error
144  * from the underlying JTAG layer of OpenOCD - all scans were performed.
145  * However, RISC-V DMI "busy" condition could still have occurred.
146  */
147  bool was_run;
148  /* Number of RTI cycles used by the last scan on the last run.
149  * Only valid when `was_run` is set.
150  */
151  unsigned int last_scan_delay;
152 };
153 
154 /* Allocates (or frees) a new scan set. "scans" is the maximum number of JTAG
155  * scans that can be issued to this object. */
156 struct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans);
157 void riscv_batch_free(struct riscv_batch *batch);
158 
159 /* Checks to see if this batch is full. */
160 bool riscv_batch_full(struct riscv_batch *batch);
161 
162 /* Executes this batch of JTAG DTM DMI scans, starting form "start" scan.
163  *
164  * If batch is run for the first time, it is expected that "start" is zero.
165  * It is expected that the batch ends with a DMI NOP operation.
166  *
167  * "idle_counts" specifies the number of JTAG Run-Test-Idle cycles to add
168  * after each scan depending on the delay class of the scan.
169  *
170  * If "resets_delays" is true, the algorithm will stop inserting idle cycles
171  * (JTAG Run-Test-Idle) after "reset_delays_after" number of scans is
172  * performed. This is useful for stress-testing of RISC-V algorithms in
173  * OpenOCD that are based on batches.
174  */
175 int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
176  const struct riscv_scan_delays *delays, bool resets_delays,
177  size_t reset_delays_after);
178 
179 /* Get the number of scans successfully executed form this batch. */
180 size_t riscv_batch_finished_scans(const struct riscv_batch *batch);
181 
182 /* Adds a DM register write to this batch. */
183 void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint32_t address, uint32_t data,
184  bool read_back, enum riscv_scan_delay_class delay_class);
185 
186 static inline void
187 riscv_batch_add_dm_write(struct riscv_batch *batch, uint32_t address, uint32_t data,
188  bool read_back, enum riscv_scan_delay_class delay_type)
189 {
190  return riscv_batch_add_dmi_write(batch,
191  riscv_get_dmi_address(batch->target, address), data,
192  read_back, delay_type);
193 }
194 
195 /* DM register reads must be handled in two parts: the first one schedules a read and
196  * provides a key, the second one actually obtains the result of the read -
197  * status (op) and the actual data. */
198 size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint32_t address,
199  enum riscv_scan_delay_class delay_class);
200 
201 static inline size_t
203  enum riscv_scan_delay_class delay_type)
204 {
205  return riscv_batch_add_dmi_read(batch,
206  riscv_get_dmi_address(batch->target, address), delay_type);
207 }
208 
209 uint32_t riscv_batch_get_dmi_read_op(const struct riscv_batch *batch, size_t key);
210 uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t key);
211 
212 /* Scans in a NOP. */
213 void riscv_batch_add_nop(struct riscv_batch *batch);
214 
215 /* Returns the number of available scans. */
216 size_t riscv_batch_available_scans(struct riscv_batch *batch);
217 
218 /* Return true iff the last scan in the batch returned DMI_OP_BUSY. */
219 bool riscv_batch_was_batch_busy(const struct riscv_batch *batch);
220 
221 #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:99
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:202
static void riscv_scan_set_delay(struct riscv_scan_delays *delays, enum riscv_scan_delay_class delay_class, unsigned int delay)
Definition: batch.h:77
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
static unsigned int riscv_scan_get_delay(const struct riscv_scan_delays *delays, enum riscv_scan_delay_class delay_class)
Definition: batch.h:60
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:187
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:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
uint32_t riscv_get_dmi_address(const struct target *target, uint32_t dm_address)
Definition: riscv.c:4679
uint8_t * data_in
Definition: batch.h:124
riscv_bscan_tunneled_scan_context_t * bscan_ctxt
Definition: batch.h:131
size_t allocated_scans
Definition: batch.h:120
struct target * target
Definition: batch.h:118
enum riscv_scan_type last_scan
Definition: batch.h:137
enum riscv_scan_delay_class * delay_classes
Definition: batch.h:126
bool was_run
Definition: batch.h:147
size_t * read_keys
Definition: batch.h:140
uint8_t * data_out
Definition: batch.h:123
size_t read_keys_used
Definition: batch.h:141
unsigned int last_scan_delay
Definition: batch.h:151
size_t used_scans
Definition: batch.h:121
struct scan_field * fields
Definition: batch.h:125
unsigned int sb_read_delay
Definition: batch.h:55
unsigned int ac_delay
Definition: batch.h:54
unsigned int base_delay
Definition: batch.h:53
unsigned int sb_write_delay
Definition: batch.h:56
This structure defines a single scan field in the scan.
Definition: jtag.h:87
Definition: target.h:119
#define NULL
Definition: usb.h:16