diff options
-rw-r--r-- | src/target/riscv/riscv-013.c | 24 | ||||
-rw-r--r-- | src/target/riscv/riscv.c | 10 | ||||
-rw-r--r-- | src/target/riscv/riscv.h | 1 | ||||
-rw-r--r-- | src/target/target_type.h | 6 |
4 files changed, 37 insertions, 4 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index a673265..417cb9f 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1727,6 +1727,29 @@ static int riscv013_hart_count(struct target *target) return dm->hart_count; } +static unsigned riscv013_data_bits(struct target *target) +{ + RISCV013_INFO(info); + /* TODO: Once there is a spec for discovering abstract commands, we can + * take those into account as well. For now we assume abstract commands + * support XLEN-wide accesses. */ + if (info->progbufsize >= 2 && !riscv_prefer_sba) + return riscv_xlen(target); + + if (get_field(info->sbcs, DMI_SBCS_SBACCESS128)) + return 128; + if (get_field(info->sbcs, DMI_SBCS_SBACCESS64)) + return 64; + if (get_field(info->sbcs, DMI_SBCS_SBACCESS32)) + return 32; + if (get_field(info->sbcs, DMI_SBCS_SBACCESS16)) + return 16; + if (get_field(info->sbcs, DMI_SBCS_SBACCESS8)) + return 8; + + return riscv_xlen(target); +} + static int init_target(struct command_context *cmd_ctx, struct target *target) { @@ -1759,6 +1782,7 @@ static int init_target(struct command_context *cmd_ctx, generic_info->test_sba_config_reg = &riscv013_test_sba_config_reg; generic_info->test_compliance = &riscv013_test_compliance; generic_info->hart_count = &riscv013_hart_count; + generic_info->data_bits = &riscv013_data_bits; generic_info->version_specific = calloc(1, sizeof(riscv013_info_t)); if (!generic_info->version_specific) return ERROR_FAIL; diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 41ac87c..ec00d9f 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -2462,6 +2462,14 @@ static unsigned riscv_xlen_nonconst(struct target *target) return riscv_xlen(target); } +static unsigned riscv_data_bits(struct target *target) +{ + RISCV_INFO(r); + if (r->data_bits) + return r->data_bits(target); + return riscv_xlen(target); +} + struct target_type riscv_target = { .name = "riscv", @@ -2501,7 +2509,7 @@ struct target_type riscv_target = { .commands = riscv_command_handlers, .address_bits = riscv_xlen_nonconst, - .data_bits = riscv_xlen_nonconst + .data_bits = riscv_data_bits }; /*** RISC-V Interface ***/ diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 3dfb4e5..855116a 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -146,6 +146,7 @@ typedef struct { /* How many harts are attached to the DM that this target is attached to? */ int (*hart_count)(struct target *target); + unsigned (*data_bits)(struct target *target); } riscv_info_t; typedef struct { diff --git a/src/target/target_type.h b/src/target/target_type.h index b94be12..87ef829 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -297,9 +297,9 @@ struct target_type { * implemented, it's assumed to be 32. */ unsigned (*address_bits)(struct target *target); - /* Return the number of data bits this target supports. This will - * typically be 32 for 32-bit targets, and 64 for 64-bit targets. If not - * implemented, it's assumed to be 32. */ + /* Return the number of system bus data bits this target supports. This + * will typically be 32 for 32-bit targets, and 64 for 64-bit targets. If + * not implemented, it's assumed to be 32. */ unsigned (*data_bits)(struct target *target); }; |