Skip to content

Commit 4b5668b

Browse files
authored
Merge pull request riscv-collab#1087 from en-sc/en-sc/delay-types
target/riscv: replace `info->*_delay` with `riscv_scan_delays`
2 parents e9eca80 + aa9a3fa commit 4b5668b

File tree

3 files changed

+167
-110
lines changed

3 files changed

+167
-110
lines changed

src/target/riscv/batch.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans)
2929
out->allocated_scans = scans;
3030
out->last_scan = RISCV_SCAN_TYPE_INVALID;
3131
out->was_run = false;
32-
out->used_delay = 0;
32+
out->last_scan_delay = 0;
3333

3434
out->data_out = NULL;
3535
out->data_in = NULL;
@@ -109,7 +109,7 @@ static bool riscv_batch_was_scan_busy(const struct riscv_batch *batch,
109109
}
110110

111111
static void add_idle_before_batch(const struct riscv_batch *batch, size_t start_idx,
112-
struct riscv_scan_delays delays)
112+
const struct riscv_scan_delays *delays)
113113
{
114114
if (!batch->was_run)
115115
return;
@@ -121,29 +121,29 @@ static void add_idle_before_batch(const struct riscv_batch *batch, size_t start_
121121
? batch->delay_classes[start_idx - 1]
122122
: RISCV_DELAY_BASE;
123123
const unsigned int new_delay = riscv_scan_get_delay(delays, delay_class);
124-
if (new_delay <= batch->used_delay)
124+
if (new_delay <= batch->last_scan_delay)
125125
return;
126-
const unsigned int idle_change = new_delay - batch->used_delay;
126+
const unsigned int idle_change = new_delay - batch->last_scan_delay;
127127
LOG_TARGET_DEBUG(batch->target, "Adding %u idle cycles before the batch.",
128128
idle_change);
129129
assert(idle_change <= INT_MAX);
130130
jtag_add_runtest(idle_change, TAP_IDLE);
131131
}
132132

133133
static int get_delay(const struct riscv_batch *batch, size_t scan_idx,
134-
struct riscv_scan_delays delays)
134+
const struct riscv_scan_delays *delays)
135135
{
136136
assert(batch);
137137
assert(scan_idx < batch->used_scans);
138138
const enum riscv_scan_delay_class delay_class =
139139
batch->delay_classes[scan_idx];
140-
const unsigned int delay = riscv_scan_get_delay(delays, delay_class);
140+
const unsigned int delay = riscv_scan_get_delay(delays, delay_class);
141141
assert(delay <= INT_MAX);
142142
return delay;
143143
}
144144

145145
int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
146-
struct riscv_scan_delays delays, bool resets_delays,
146+
const struct riscv_scan_delays *delays, bool resets_delays,
147147
size_t reset_delays_after)
148148
{
149149
assert(batch->used_scans);
@@ -195,7 +195,7 @@ int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
195195
}
196196

197197
batch->was_run = true;
198-
batch->used_delay = get_delay(batch, batch->used_scans - 1, delays);
198+
batch->last_scan_delay = get_delay(batch, batch->used_scans - 1, delays);
199199
return ERROR_OK;
200200
}
201201

src/target/riscv/batch.h

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,40 +25,66 @@ enum riscv_scan_delay_class {
2525
/* Delay for System Bus read operation: */
2626
RISCV_DELAY_SYSBUS_READ,
2727
/* Delay for System Bus write operation: */
28-
RISCV_DELAY_SYSBUS_WRITE,
28+
RISCV_DELAY_SYSBUS_WRITE
2929
};
3030

31+
static inline const char *
32+
riscv_scan_delay_class_name(enum riscv_scan_delay_class delay_class)
33+
{
34+
switch (delay_class) {
35+
case RISCV_DELAY_BASE:
36+
return "DM access";
37+
case RISCV_DELAY_ABSTRACT_COMMAND:
38+
return "Abstract Command";
39+
case RISCV_DELAY_SYSBUS_READ:
40+
return "System Bus read";
41+
case RISCV_DELAY_SYSBUS_WRITE:
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+
3157
struct riscv_scan_delays {
32-
/* The purpose of these delays is to be passed to "jtag_add_runtest()",
33-
* which accepts an "int".
34-
* Therefore, they should be no greater then "INT_MAX".
35-
*/
3658
unsigned int base_delay;
3759
unsigned int ac_delay;
3860
unsigned int sb_read_delay;
3961
unsigned int sb_write_delay;
4062
};
4163

42-
static inline unsigned int riscv_scan_get_delay(struct riscv_scan_delays delays,
64+
static inline unsigned int
65+
riscv_scan_get_delay(const struct riscv_scan_delays *delays,
4366
enum riscv_scan_delay_class delay_class)
4467
{
4568
switch (delay_class) {
4669
case RISCV_DELAY_BASE:
47-
return delays.base_delay;
70+
return delays->base_delay;
4871
case RISCV_DELAY_ABSTRACT_COMMAND:
49-
return delays.ac_delay;
72+
return delays->base_delay + delays->ac_delay;
5073
case RISCV_DELAY_SYSBUS_READ:
51-
return delays.sb_read_delay;
74+
return delays->base_delay + delays->sb_read_delay;
5275
case RISCV_DELAY_SYSBUS_WRITE:
53-
return delays.sb_write_delay;
76+
return delays->base_delay + delays->sb_write_delay;
5477
}
78+
assert(0);
5579
return 0;
5680
}
5781

5882
static inline void riscv_scan_set_delay(struct riscv_scan_delays *delays,
5983
enum riscv_scan_delay_class delay_class, unsigned int delay)
6084
{
61-
assert(delay <= INT_MAX);
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);
6288
switch (delay_class) {
6389
case RISCV_DELAY_BASE:
6490
delays->base_delay = delay;
@@ -73,6 +99,25 @@ static inline void riscv_scan_set_delay(struct riscv_scan_delays *delays,
7399
delays->sb_write_delay = delay;
74100
return;
75101
}
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;
76121
}
77122

78123
/* A batch of multiple JTAG scans, which are grouped together to avoid the
@@ -113,7 +158,7 @@ struct riscv_batch {
113158
/* Number of RTI cycles used by the last scan on the last run.
114159
* Only valid when `was_run` is set.
115160
*/
116-
unsigned int used_delay;
161+
unsigned int last_scan_delay;
117162
};
118163

119164
/* Allocates (or frees) a new scan set. "scans" is the maximum number of JTAG
@@ -138,7 +183,7 @@ bool riscv_batch_full(struct riscv_batch *batch);
138183
* OpenOCD that are based on batches.
139184
*/
140185
int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
141-
struct riscv_scan_delays delays, bool resets_delays,
186+
const struct riscv_scan_delays *delays, bool resets_delays,
142187
size_t reset_delays_after);
143188

144189
/* Get the number of scans successfully executed form this batch. */

0 commit comments

Comments
 (0)