Skip to content

Commit

Permalink
riscv_debug: provide abstraction for dtm dmi reads and writes
Browse files Browse the repository at this point in the history
  • Loading branch information
perigoso committed Feb 23, 2023
1 parent a942708 commit 29c1626
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
27 changes: 21 additions & 6 deletions src/target/riscv_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ static void riscv_dm_init(riscv_dm_s *dbg_module);
static bool riscv_hart_init(riscv_hart_s *hart);
static void riscv_hart_free(void *priv);
static uint32_t riscv_shift_dtmcs(const riscv_dtm_s *dtm, uint32_t control);
static bool riscv_dmi_read(riscv_dtm_s *dtm, uint32_t address, uint32_t *value);
static bool riscv_dmi_write(riscv_dtm_s *dtm, uint32_t address, uint32_t value);
static bool riscv_jtag_dmi_read(riscv_dtm_s *dtm, uint32_t address, uint32_t *value);
static bool riscv_jtag_dmi_write(riscv_dtm_s *dtm, uint32_t address, uint32_t value);
static void riscv_dm_ref(riscv_dm_s *dbg_module);
static void riscv_dm_unref(riscv_dm_s *dbg_module);
static riscv_debug_version_e riscv_dtmcs_version(uint32_t dtmcs);
Expand All @@ -229,6 +229,18 @@ static void riscv_halt_resume(target_s *target, bool step);
static target_halt_reason_e riscv_halt_poll(target_s *target, target_addr_t *watch);
static void riscv_reset(target_s *target);

static bool riscv_dmi_read(riscv_dtm_s *dtm, uint32_t address, uint32_t *value)
{
/* dereference dmi_read from abstracted struct, there is no NULL check */
return dtm->dmi_read(dtm, address, value);
}

static bool riscv_dmi_write(riscv_dtm_s *dtm, uint32_t address, uint32_t value)
{
/* dereference dmi_write from abstracted struct, there is no NULL check */
return dtm->dmi_write(dtm, address, value);
}

void riscv_debug_dtm_handler(const uint8_t dev_index)
{
riscv_dtm_s *dtm = calloc(1, sizeof(*dtm));
Expand All @@ -237,6 +249,9 @@ void riscv_debug_dtm_handler(const uint8_t dev_index)
return;
}

dtm->dmi_read = riscv_jtag_dmi_read;
dtm->dmi_write = riscv_jtag_dmi_write;

/* Setup and try to discover the DMI bus */
dtm->dev_index = dev_index;
/*
Expand Down Expand Up @@ -502,27 +517,27 @@ static bool riscv_shift_dmi(riscv_dtm_s *const dtm, const uint8_t operation, con
return status == RV_DMI_SUCCESS;
}

static bool riscv_dmi_read(riscv_dtm_s *const dtm, const uint32_t address, uint32_t *const value)
static bool riscv_jtag_dmi_read(riscv_dtm_s *const dtm, const uint32_t address, uint32_t *const value)
{
/* Setup the location to read from */
bool result = riscv_shift_dmi(dtm, RV_DMI_READ, address, 0, NULL);
if (result)
/* If that worked, read back the value and check the operation status */
result = riscv_shift_dmi(dtm, RV_DMI_NOOP, 0, 0, value);
if (!result)
DEBUG_WARN("DMI read at 0x%08" PRIx32 " failed with status %u\n", address, dtm->fault);
DEBUG_WARN("JTAG DMI read at 0x%08" PRIx32 " failed with status %u\n", address, dtm->fault);
return result;
}

static bool riscv_dmi_write(riscv_dtm_s *const dtm, const uint32_t address, const uint32_t value)
static bool riscv_jtag_dmi_write(riscv_dtm_s *const dtm, const uint32_t address, const uint32_t value)
{
/* Write a value to the requested register */
bool result = riscv_shift_dmi(dtm, RV_DMI_WRITE, address, value, NULL);
if (result)
/* If that worked, read back the operation status to ensure the write actually worked */
result = riscv_shift_dmi(dtm, RV_DMI_NOOP, 0, 0, NULL);
if (!result)
DEBUG_WARN("DMI write at 0x%08" PRIx32 " failed with status %u\n", address, dtm->fault);
DEBUG_WARN("JTAG DMI write at 0x%08" PRIx32 " failed with status %u\n", address, dtm->fault);
return result;
}

Expand Down
9 changes: 7 additions & 2 deletions src/target/riscv_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,22 @@ typedef enum riscv_match_size {
} riscv_match_size_e;

/* This structure represents a agnostic interface to a RISC-V Debug Transport Module */
typedef struct riscv_dtm {
typedef struct riscv_dtm riscv_dtm_s;

struct riscv_dtm {
uint32_t ref_count;

uint16_t designer_code;
riscv_debug_version_e version;

bool (*dmi_read)(riscv_dtm_s *dtm, uint32_t address, uint32_t *value);
bool (*dmi_write)(riscv_dtm_s *dtm, uint32_t address, uint32_t value);

uint8_t dev_index;
uint8_t idle_cycles;
uint8_t dmi_address_bits;
uint8_t fault;
} riscv_dtm_s;
};

/* This represents a specific Debug Module on the DMI bus */
typedef struct riscv_dm {
Expand Down

0 comments on commit 29c1626

Please sign in to comment.