Skip to content

Commit

Permalink
target/riscv: single DMI accesses via batch
Browse files Browse the repository at this point in the history
* Eliminates the use of VLA, which is prohibited by `doc/manual
/style.txt`:
Link: https://github.com/riscv-collab/riscv-openocd/blob/c6bb902629924eb66aae2a08c0ab8654261c9d71/doc/manual/style.txt#L164-L166

* Unifies DMI access interface.

* Reduces code duplication.

Change-Id: I2d7b0595f171e21062049ff61f76fb5a3c992d11
Signed-off-by: Evgeniy Naydanov <[email protected]>
  • Loading branch information
en-sc committed Jul 9, 2024
1 parent 544400e commit 3ea4b46
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 272 deletions.
11 changes: 5 additions & 6 deletions src/target/riscv/batch.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,23 +190,22 @@ int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,

for (size_t i = start_idx; i < batch->used_scans; ++i) {
const int delay = get_delay(batch, i, delays);
riscv_log_dmi_scan(batch->target, delay, batch->fields + i,
/*discard_in*/ false);
riscv_log_dmi_scan(batch->target, delay, batch->fields + i);
}

batch->was_run = true;
batch->last_scan_delay = get_delay(batch, batch->used_scans - 1, delays);
return ERROR_OK;
}

void riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
bool read_back, enum riscv_scan_delay_class delay_class)
{
assert(batch->used_scans < batch->allocated_scans);
struct scan_field *field = batch->fields + batch->used_scans;
field->num_bits = riscv_get_dmi_scan_length(batch->target);
field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
riscv_fill_dm_write(batch->target, (char *)field->out_value, address, data);
riscv_fill_dmi_write(batch->target, (char *)field->out_value, address, data);
if (read_back) {
field->in_value = (void *)(batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE);
riscv_fill_dm_nop(batch->target, (char *)field->in_value);
Expand All @@ -218,15 +217,15 @@ void riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint3
batch->used_scans++;
}

size_t riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint64_t address,
enum riscv_scan_delay_class delay_class)
{
assert(batch->used_scans < batch->allocated_scans);
struct scan_field *field = batch->fields + batch->used_scans;
field->num_bits = riscv_get_dmi_scan_length(batch->target);
field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
field->in_value = (void *)(batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE);
riscv_fill_dm_read(batch->target, (char *)field->out_value, address);
riscv_fill_dmi_read(batch->target, (char *)field->out_value, address);
riscv_fill_dm_nop(batch->target, (char *)field->in_value);
batch->delay_classes[batch->used_scans] = delay_class;
batch->last_scan = RISCV_SCAN_TYPE_READ;
Expand Down
26 changes: 22 additions & 4 deletions src/target/riscv/batch.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,32 @@ int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
size_t riscv_batch_finished_scans(const struct riscv_batch *batch);

/* Adds a DM register write to this batch. */
void riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
bool read_back, enum riscv_scan_delay_class delay_class);

static inline void
riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
bool read_back, enum riscv_scan_delay_class delay_type)
{
return riscv_batch_add_dmi_write(batch,
riscv_get_dmi_address(batch->target, address), data,
read_back, delay_type);
}

/* DM register reads must be handled in two parts: the first one schedules a read and
* provides a key, the second one actually obtains the result of the read -
* status (op) and the actual data. */
size_t riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint64_t address,
enum riscv_scan_delay_class delay_class);

static inline size_t
riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
enum riscv_scan_delay_class delay_type)
{
return riscv_batch_add_dmi_read(batch,
riscv_get_dmi_address(batch->target, address), delay_type);
}

unsigned int riscv_batch_get_dmi_read_op(const struct riscv_batch *batch, size_t key);
uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t key);

Expand All @@ -213,7 +231,7 @@ bool riscv_batch_was_batch_busy(const struct riscv_batch *batch);
/* TODO: The function is defined in `riscv-013.c`. This is done to reduce the
* diff of the commit. The intention is to move the function definition to
* a separate module (e.g. `riscv013-jtag-dtm.c/h`) in another commit. */
void riscv_log_dmi_scan(const struct target *target, int idle, const struct scan_field *field,
bool discard_in);
void riscv_log_dmi_scan(const struct target *target, int idle,
const struct scan_field *field);

#endif
Loading

0 comments on commit 3ea4b46

Please sign in to comment.