Skip to content

Commit

Permalink
Merge pull request #875 from zqb-all/support_multiple_DMs
Browse files Browse the repository at this point in the history
target/riscv: support multiple DMs
  • Loading branch information
timsifive authored Jul 27, 2023
2 parents aeb37cb + a9f28da commit 1997e68
Show file tree
Hide file tree
Showing 6 changed files with 396 additions and 166 deletions.
21 changes: 17 additions & 4 deletions doc/openocd.texi
Original file line number Diff line number Diff line change
Expand Up @@ -10891,15 +10891,28 @@ Write the 32-bit value to authdata or authdata0 (index=0), or authdata1

@subsection RISC-V DMI Commands

The following commands allow direct access to the Debug Module Interface, which
can be used to interact with custom debug features.
The following commands allow for direct low-level access to the registers
of the Debug Module (DM). They can be useful to access custom features in the DM.

@deffn {Command} {riscv dm_read} reg_address
Perform a 32-bit read from the register indicated by reg_address from the DM of the
current target.
@end deffn

@deffn {Command} {riscv dm_write} reg_address value
Write the 32-bit value to the register indicated by reg_address from the DM of the
current target.
@end deffn

The following commands allow for direct low-level access to the Debug Module
Interface (DMI). They can be useful to access any device that resides on the DMI.

@deffn {Command} {riscv dmi_read} address
Perform a 32-bit DMI read at address, returning the value.
Perform a 32-bit read from the given DMI address, returning the value.
@end deffn

@deffn {Command} {riscv dmi_write} address value
Perform a 32-bit DMI write of value at address.
Perform a 32-bit write to the given DMI address.
@end deffn

@subsection RISC-V Trigger Commands
Expand Down
16 changes: 8 additions & 8 deletions src/target/riscv/batch.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,33 +127,33 @@ int riscv_batch_run(struct riscv_batch *batch)
return ERROR_OK;
}

void riscv_batch_add_dmi_write(struct riscv_batch *batch, unsigned int address, uint64_t data,
void riscv_batch_add_dm_write(struct riscv_batch *batch, unsigned int address, uint64_t data,
bool read_back)
{
assert(batch->used_scans < batch->allocated_scans);
struct scan_field *field = batch->fields + batch->used_scans;
field->num_bits = riscv_dmi_write_u64_bits(batch->target);
field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
riscv_fill_dmi_write_u64(batch->target, (char *)field->out_value, address, data);
riscv_fill_dm_write_u64(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_dmi_nop_u64(batch->target, (char *)field->in_value);
riscv_fill_dm_nop_u64(batch->target, (char *)field->in_value);
} else {
field->in_value = NULL;
}
batch->last_scan = RISCV_SCAN_TYPE_WRITE;
batch->used_scans++;
}

size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, unsigned address)
size_t riscv_batch_add_dm_read(struct riscv_batch *batch, unsigned int address)
{
assert(batch->used_scans < batch->allocated_scans);
struct scan_field *field = batch->fields + batch->used_scans;
field->num_bits = riscv_dmi_write_u64_bits(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_dmi_read_u64(batch->target, (char *)field->out_value, address);
riscv_fill_dmi_nop_u64(batch->target, (char *)field->in_value);
riscv_fill_dm_read_u64(batch->target, (char *)field->out_value, address);
riscv_fill_dm_nop_u64(batch->target, (char *)field->in_value);
batch->last_scan = RISCV_SCAN_TYPE_READ;
batch->used_scans++;

Expand Down Expand Up @@ -188,8 +188,8 @@ void riscv_batch_add_nop(struct riscv_batch *batch)
field->num_bits = riscv_dmi_write_u64_bits(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_dmi_nop_u64(batch->target, (char *)field->out_value);
riscv_fill_dmi_nop_u64(batch->target, (char *)field->in_value);
riscv_fill_dm_nop_u64(batch->target, (char *)field->out_value);
riscv_fill_dm_nop_u64(batch->target, (char *)field->in_value);
batch->last_scan = RISCV_SCAN_TYPE_NOP;
batch->used_scans++;
}
Expand Down
8 changes: 4 additions & 4 deletions src/target/riscv/batch.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ bool riscv_batch_full(struct riscv_batch *batch);
/* Executes this scan batch. */
int riscv_batch_run(struct riscv_batch *batch);

/* Adds a DMI write to this batch. */
void riscv_batch_add_dmi_write(struct riscv_batch *batch, unsigned int address, uint64_t data,
/* Adds a DM register write to this batch. */
void riscv_batch_add_dm_write(struct riscv_batch *batch, unsigned int address, uint64_t data,
bool read_back);

/* DMI reads must be handled in two parts: the first one schedules a read and
/* 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_dmi_read(struct riscv_batch *batch, unsigned address);
size_t riscv_batch_add_dm_read(struct riscv_batch *batch, unsigned int address);
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 Down
Loading

0 comments on commit 1997e68

Please sign in to comment.