From ead2a595b8491ed48ce2ced81d2935dc8a4c4973 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 16 Jul 2018 14:43:15 -0700 Subject: [PATCH] Use work area instead of riscv-specific config Per review requested at http://openocd.zylin.com/#/c/4578/3 Change-Id: I1a8117665d38844dc1479f33b4f9b7c8f9f101c8 --- src/target/riscv/riscv-013.c | 54 ++++++++++++++++++++++++++---------- src/target/riscv/riscv.c | 35 ----------------------- src/target/riscv/riscv.h | 3 -- 3 files changed, 40 insertions(+), 52 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 896184d7c..83627effb 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -923,22 +923,25 @@ typedef struct { riscv_addr_t hart_address; /* Memory address to access the scratch memory from the debugger. */ riscv_addr_t debug_address; + struct working_area *area; } scratch_mem_t; /** * Find some scratch memory to be used with the given program. */ -static int scratch_find(struct target *target, +static int scratch_reserve(struct target *target, scratch_mem_t *scratch, struct riscv_program *program, unsigned size_bytes) { - riscv013_info_t *info = get_info(target); - riscv_addr_t alignment = 1; while (alignment < size_bytes) alignment *= 2; + scratch->area = NULL; + + riscv013_info_t *info = get_info(target); + if (info->dataaccess == 1) { /* Sign extend dataaddr. */ scratch->hart_address = info->dataaddr; @@ -969,8 +972,9 @@ static int scratch_find(struct target *target, return ERROR_OK; } - if (riscv_use_scratch_ram) { - scratch->hart_address = (riscv_scratch_ram_address + alignment - 1) & + if (target_alloc_working_area(target, size_bytes + alignment - 1, + &scratch->area) == ERROR_OK) { + scratch->hart_address = (scratch->area->address + alignment - 1) & ~(alignment - 1); scratch->memory_space = SPACE_DMI_RAM; scratch->debug_address = scratch->hart_address; @@ -978,10 +982,19 @@ static int scratch_find(struct target *target, } LOG_ERROR("Couldn't find %d bytes of scratch RAM to use. Please configure " - "an address with 'riscv set_scratch_ram'.", size_bytes); + "a work area with 'configure -work-area-phys'.", size_bytes); return ERROR_FAIL; } +static int scratch_release(struct target *target, + scratch_mem_t *scratch) +{ + if (scratch->area) + return target_free_working_area(target, scratch->area); + + return ERROR_OK; +} + static int scratch_read64(struct target *target, scratch_mem_t *scratch, uint64_t *value) { @@ -1096,23 +1109,29 @@ static int register_write_direct(struct target *target, unsigned number, if (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK) return ERROR_FAIL; + scratch_mem_t scratch; + bool use_scratch = false; if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 && riscv_supports_extension(target, riscv_current_hartid(target), 'D') && riscv_xlen(target) < 64) { /* There are no instructions to move all the bits from a register, so * we need to use some scratch RAM. */ + use_scratch = true; riscv_program_insert(&program, fld(number - GDB_REGNO_FPR0, S0, 0)); - scratch_mem_t scratch; - if (scratch_find(target, &scratch, &program, 8) != ERROR_OK) + if (scratch_reserve(target, &scratch, &program, 8) != ERROR_OK) return ERROR_FAIL; if (register_write_direct(target, GDB_REGNO_S0, scratch.hart_address) - != ERROR_OK) + != ERROR_OK) { + scratch_release(target, &scratch); return ERROR_FAIL; + } - if (scratch_write64(target, &scratch, value) != ERROR_OK) + if (scratch_write64(target, &scratch, value) != ERROR_OK) { + scratch_release(target, &scratch); return ERROR_FAIL; + } } else { if (register_write_direct(target, GDB_REGNO_S0, value) != ERROR_OK) @@ -1139,6 +1158,9 @@ static int register_write_direct(struct target *target, unsigned number, reg->valid = true; } + if (use_scratch) + scratch_release(target, &scratch); + /* Restore S0. */ if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK) return ERROR_FAIL; @@ -1215,13 +1237,15 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t riscv_program_insert(&program, fsd(number - GDB_REGNO_FPR0, S0, 0)); - if (scratch_find(target, &scratch, &program, 8) != ERROR_OK) + if (scratch_reserve(target, &scratch, &program, 8) != ERROR_OK) return ERROR_FAIL; use_scratch = true; if (register_write_direct(target, GDB_REGNO_S0, - scratch.hart_address) != ERROR_OK) + scratch.hart_address) != ERROR_OK) { + scratch_release(target, &scratch); return ERROR_FAIL; + } } else if (riscv_supports_extension(target, riscv_current_hartid(target), 'D')) { riscv_program_insert(&program, fmv_x_d(S0, number - GDB_REGNO_FPR0)); @@ -1240,8 +1264,10 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t /* Don't message on error. Probably the register doesn't exist. */ if (use_scratch) { - if (scratch_read64(target, &scratch, value) != ERROR_OK) - return ERROR_FAIL; + result = scratch_read64(target, &scratch, value); + scratch_release(target, &scratch); + if (result != ERROR_OK) + return result; } else { /* Read S0 */ if (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index f6a1a8d93..8d76c4aa4 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -185,9 +185,6 @@ int riscv_command_timeout_sec = DEFAULT_COMMAND_TIMEOUT_SEC; /* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/ 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 @@ -1230,31 +1227,6 @@ COMMAND_HANDLER(riscv_set_reset_timeout_sec) return ERROR_OK; } -COMMAND_HANDLER(riscv_set_scratch_ram) -{ - if (CMD_ARGC != 1) { - LOG_ERROR("Command takes exactly 1 parameter"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if (!strcmp(CMD_ARGV[0], "none")) { - riscv_use_scratch_ram = false; - return ERROR_OK; - } - - /* TODO: use COMMAND_PARSE_NUMBER */ - long long unsigned int address; - int result = sscanf(CMD_ARGV[0], "%llx", &address); - if (result != (int) strlen(CMD_ARGV[0])) { - LOG_ERROR("%s is not a valid address for command.", CMD_ARGV[0]); - riscv_use_scratch_ram = false; - return ERROR_FAIL; - } - - riscv_scratch_ram_address = address; - riscv_use_scratch_ram = true; - return ERROR_OK; -} - COMMAND_HANDLER(riscv_set_prefer_sba) { if (CMD_ARGC != 1) { @@ -1469,13 +1441,6 @@ static const struct command_registration riscv_exec_command_handlers[] = { .usage = "riscv set_reset_timeout_sec [sec]", .help = "Set the wall-clock timeout (in seconds) after reset is deasserted" }, - { - .name = "set_scratch_ram", - .handler = riscv_set_scratch_ram, - .mode = COMMAND_ANY, - .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, diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 4fb0f776a..2210ab600 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -126,9 +126,6 @@ extern int riscv_command_timeout_sec; /* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/ 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