diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index d7ee34cfc..2a04d6162 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -2183,7 +2183,7 @@ static int read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) { RISCV013_INFO(info); - if (info->progbufsize >= 2) + if (info->progbufsize >= 2 && !riscv_prefer_sba) return read_memory_progbuf(target, address, size, count, buffer); if ((get_field(info->sbcs, DMI_SBCS_SBACCESS8) && size == 1) || @@ -2197,6 +2197,9 @@ static int read_memory(struct target *target, target_addr_t address, return read_memory_bus_v1(target, address, size, count, buffer); } + if (info->progbufsize >= 2) + return read_memory_progbuf(target, address, size, count, buffer); + LOG_ERROR("Don't know how to read memory on this target."); return ERROR_FAIL; } @@ -2550,8 +2553,9 @@ static int write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { RISCV013_INFO(info); - if (info->progbufsize >= 2) + if (info->progbufsize >= 2 && !riscv_prefer_sba) return write_memory_progbuf(target, address, size, count, buffer); + if ((get_field(info->sbcs, DMI_SBCS_SBACCESS8) && size == 1) || (get_field(info->sbcs, DMI_SBCS_SBACCESS16) && size == 2) || (get_field(info->sbcs, DMI_SBCS_SBACCESS32) && size == 4) || @@ -2563,6 +2567,9 @@ static int write_memory(struct target *target, target_addr_t address, return write_memory_bus_v1(target, address, size, count, buffer); } + if (info->progbufsize >= 2) + return write_memory_progbuf(target, address, size, count, buffer); + LOG_ERROR("Don't know how to write memory on this target."); return ERROR_FAIL; } diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 9f16a400a..9af9a5edc 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -188,6 +188,8 @@ int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC; bool riscv_use_scratch_ram; uint64_t riscv_scratch_ram_address; +bool riscv_prefer_sba; + /* In addition to the ones in the standard spec, we'll also expose additional * CSRs in this list. * The list is either NULL, or a series of ranges (inclusive), terminated with @@ -1227,6 +1229,16 @@ COMMAND_HANDLER(riscv_set_scratch_ram) return ERROR_OK; } +COMMAND_HANDLER(riscv_set_prefer_sba) +{ + if (CMD_ARGC != 1) { + LOG_ERROR("Command takes exactly 1 parameter"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + COMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_prefer_sba); + return ERROR_OK; +} + void parse_error(const char *string, char c, unsigned position) { char buf[position+2]; @@ -1438,6 +1450,14 @@ static const struct command_registration riscv_exec_command_handlers[] = { .usage = "riscv set_scratch_ram none|[address]", .help = "Set address of 16 bytes of scratch RAM the debugger can use, or 'none'." }, + { + .name = "set_prefer_sba", + .handler = riscv_set_prefer_sba, + .mode = COMMAND_ANY, + .usage = "riscv set_prefer_sba on|off", + .help = "When on, prefer to use System Bus Access to access memory. " + "When off, prefer to use the Program Buffer to access memory." + }, { .name = "expose_csrs", .handler = riscv_set_expose_csrs, diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 626b71f83..ad70f4caa 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -127,6 +127,8 @@ extern int riscv_reset_timeout_sec; extern bool riscv_use_scratch_ram; extern uint64_t riscv_scratch_ram_address; +extern bool riscv_prefer_sba; + /* Everything needs the RISC-V specific info structure, so here's a nice macro * that provides that. */ static inline riscv_info_t *riscv_info(const struct target *target) __attribute__((unused));