diff --git a/doc/openocd.texi b/doc/openocd.texi index 1dcb7f3f5a..11a9c8fc22 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -11522,9 +11522,9 @@ dump_sample_buf}. @end deffn @deffn {Command} {riscv repeat_read} count address [size=4] -Quickly read count words of the given size from address. This can be useful -to read out a buffer that's memory-mapped to be accessed through a single -address, or to sample a changing value in a memory-mapped device. +Quickly read count words of the given size from physical address. This can +be useful to read out a buffer that's memory-mapped to be accessed through +a single address, or to sample a changing value in a memory-mapped device. @end deffn @deffn {Command} {riscv info} diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index 54de6a10db..d1fbf1eb87 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -2339,7 +2339,8 @@ static int write_memory(struct target *target, const riscv_mem_access_args_t arg return ERROR_FAIL; } -static int access_memory(struct target *target, const riscv_mem_access_args_t args) +static int access_memory(struct target *target, + const riscv_mem_access_args_t args, const bool is_virtual) { assert(riscv_mem_access_is_valid(args)); const bool is_write = riscv_mem_access_is_write(args); diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 46c61cab8d..b5e660931b 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -64,7 +64,8 @@ static int register_read_direct(struct target *target, riscv_reg_t *value, enum gdb_regno number); static int register_write_direct(struct target *target, enum gdb_regno number, riscv_reg_t value); -static int riscv013_access_memory(struct target *target, const riscv_mem_access_args_t args); +static int riscv013_access_memory(struct target *target, + const riscv_mem_access_args_t args, const bool is_virtual); static bool riscv013_get_impebreak(const struct target *target); static unsigned int riscv013_get_progbufsize(const struct target *target); @@ -1277,7 +1278,8 @@ static int scratch_read64(struct target *target, scratch_mem_t *scratch, .count = 2, .increment = 4, }; - if (riscv013_access_memory(target, args) != ERROR_OK) + if (riscv013_access_memory(target, args, + /* is_virtual */ false) != ERROR_OK) return ERROR_FAIL; *value = buf_get_u64(buffer, /* first = */ 0, /* bit_num = */ 64); @@ -1319,7 +1321,8 @@ static int scratch_write64(struct target *target, scratch_mem_t *scratch, .count = 2, .increment = 4, }; - if (riscv013_access_memory(target, args) != ERROR_OK) + if (riscv013_access_memory(target, args, + /* is_virtual */ false) != ERROR_OK) return ERROR_FAIL; } break; @@ -4551,8 +4554,8 @@ access_memory_abstract(struct target *target, const riscv_mem_access_args_t args write_memory_abstract(target, args); } -static int -riscv013_access_memory(struct target *target, const riscv_mem_access_args_t args) +static int riscv013_access_memory(struct target *target, + const riscv_mem_access_args_t args, const bool is_virtual) { assert(riscv_mem_access_is_valid(args)); @@ -4580,12 +4583,15 @@ riscv013_access_memory(struct target *target, const riscv_mem_access_args_t args riscv_mem_access_method_t method = r->mem_access_methods[i]; switch (method) { case RISCV_MEM_ACCESS_PROGBUF: + // TODO: pass is_virtual here in future commits skip_reason[method] = access_memory_progbuf(target, args); break; case RISCV_MEM_ACCESS_SYSBUS: + // TODO: pass is_virtual here in future commits skip_reason[method] = access_memory_sysbus(target, args); break; case RISCV_MEM_ACCESS_ABSTRACT: + // TODO: pass is_virtual here in future commits skip_reason[method] = access_memory_abstract(target, args); break; default: diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index aae5eb35a9..905fa8daf2 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -155,6 +155,13 @@ bool riscv_virt2phys_mode_is_sw(const struct target *target) return r->virt2phys_mode == RISCV_VIRT2PHYS_MODE_SW; } +bool riscv_virt2phys_mode_is_off(const struct target *target) +{ + assert(target); + RISCV_INFO(r); + return r->virt2phys_mode == RISCV_VIRT2PHYS_MODE_OFF; +} + const char *riscv_virt2phys_mode_to_str(riscv_virt2phys_mode_t mode) { assert(mode == RISCV_VIRT2PHYS_MODE_OFF @@ -3017,9 +3024,6 @@ static int riscv_mmu(struct target *target, int *enabled) { *enabled = 0; - if (!riscv_virt2phys_mode_is_sw(target)) - return ERROR_OK; - /* Don't use MMU in explicit or effective M (machine) mode */ riscv_reg_t priv; if (riscv_reg_get(target, &priv, GDB_REGNO_PRIV) != ERROR_OK) { @@ -3152,7 +3156,7 @@ static int riscv_address_translate(struct target *target, .increment = 4, .count = (1 << info->pte_shift) / 4, }; - int retval = r->access_memory(target, args); + int retval = r->access_memory(target, args, /* is_virtual */ false); if (retval != ERROR_OK) return ERROR_FAIL; @@ -3385,6 +3389,14 @@ static int check_virt_memory_access(struct target *target, target_addr_t address return ERROR_OK; } +static int riscv_access_phys_memory(struct target *target, + const riscv_mem_access_args_t args) +{ + RISCV_INFO(r); + return r->access_memory(target, args, /* is_virtual */ false); +} + + static int riscv_read_phys_memory(struct target *target, target_addr_t phys_address, uint32_t size, uint32_t count, uint8_t *buffer) { @@ -3395,8 +3407,7 @@ static int riscv_read_phys_memory(struct target *target, target_addr_t phys_addr .count = count, .increment = size, }; - RISCV_INFO(r); - return r->access_memory(target, args); + return riscv_access_phys_memory(target, args); } static int riscv_write_phys_memory(struct target *target, target_addr_t phys_address, @@ -3409,12 +3420,11 @@ static int riscv_write_phys_memory(struct target *target, target_addr_t phys_add .count = count, .increment = size, }; - - RISCV_INFO(r); - return r->access_memory(target, args); + return riscv_access_phys_memory(target, args); } -static int riscv_rw_memory(struct target *target, const riscv_mem_access_args_t args) +static int riscv_access_virt_memory(struct target *target, + const riscv_mem_access_args_t args) { assert(riscv_mem_access_is_valid(args)); @@ -3425,16 +3435,14 @@ static int riscv_rw_memory(struct target *target, const riscv_mem_access_args_t return ERROR_OK; } - int mmu_enabled; - int result = riscv_mmu(target, &mmu_enabled); - if (result != ERROR_OK) - return result; - RISCV_INFO(r); - if (!mmu_enabled) - return r->access_memory(target, args); + if (riscv_virt2phys_mode_is_off(target)) + return r->access_memory(target, args, /* is_virtual */ false); + + if (riscv_virt2phys_mode_is_hw(target)) + return r->access_memory(target, args, /* is_virtual */ true); - result = check_virt_memory_access(target, args.address, + int result = check_virt_memory_access(target, args.address, args.size, args.count, is_write); if (result != ERROR_OK) return result; @@ -3464,7 +3472,8 @@ static int riscv_rw_memory(struct target *target, const riscv_mem_access_args_t else current_access.read_buffer += current_count * args.size; - result = r->access_memory(target, current_access); + result = r->access_memory(target, + current_access, /* is_virtual */ false); if (result != ERROR_OK) return result; @@ -3485,7 +3494,7 @@ static int riscv_read_memory(struct target *target, target_addr_t address, .increment = size, }; - return riscv_rw_memory(target, args); + return riscv_access_virt_memory(target, args); } static int riscv_write_memory(struct target *target, target_addr_t address, @@ -3499,7 +3508,7 @@ static int riscv_write_memory(struct target *target, target_addr_t address, .increment = size, }; - return riscv_rw_memory(target, args); + return riscv_access_virt_memory(target, args); } static const char *riscv_get_gdb_arch(const struct target *target) @@ -5232,7 +5241,9 @@ COMMAND_HANDLER(handle_repeat_read) .count = count, .increment = 0, }; - int result = r->access_memory(target, args); + /* TODO: Add a command parameter that enables + * choosing between virtual and physical access */ + int result = r->access_memory(target, args, /* is_virtual */ false); if (result == ERROR_OK) { target_handle_md_output(cmd, target, address, size, count, buffer, false); @@ -5615,7 +5626,7 @@ static const struct command_registration riscv_exec_command_handlers[] = { .handler = handle_repeat_read, .mode = COMMAND_ANY, .usage = "count address [size=4]", - .help = "Repeatedly read the value at address." + .help = "Repeatedly read the value at physical address." }, { .name = "set_command_timeout_sec", diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 082445e40a..adf8dc12c0 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -303,7 +303,8 @@ struct riscv_info { riscv_sample_config_t *config, int64_t until_ms); - int (*access_memory)(struct target *target, const riscv_mem_access_args_t args); + int (*access_memory)(struct target *target, + const riscv_mem_access_args_t args, const bool is_virtual); unsigned int (*data_bits)(struct target *target); @@ -411,6 +412,7 @@ typedef struct { bool riscv_virt2phys_mode_is_hw(const struct target *target); bool riscv_virt2phys_mode_is_sw(const struct target *target); +bool riscv_virt2phys_mode_is_off(const struct target *target); /* Wall-clock timeout for a command/access. Settable via RISC-V Target commands.*/ int riscv_get_command_timeout_sec(void);