aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2018-07-16 14:43:15 -0700
committerTim Newsome <tim@sifive.com>2018-07-16 14:43:15 -0700
commitead2a595b8491ed48ce2ced81d2935dc8a4c4973 (patch)
tree65829e9d3ec6c9e700264bcebc64909a75d36ea2
parent5d9f48640461fbac5c30958f63a01e666ee64dd4 (diff)
downloadriscv-openocd-ead2a595b8491ed48ce2ced81d2935dc8a4c4973.zip
riscv-openocd-ead2a595b8491ed48ce2ced81d2935dc8a4c4973.tar.gz
riscv-openocd-ead2a595b8491ed48ce2ced81d2935dc8a4c4973.tar.bz2
Use work area instead of riscv-specific config
Per review requested at http://openocd.zylin.com/#/c/4578/3 Change-Id: I1a8117665d38844dc1479f33b4f9b7c8f9f101c8
-rw-r--r--src/target/riscv/riscv-013.c54
-rw-r--r--src/target/riscv/riscv.c35
-rw-r--r--src/target/riscv/riscv.h3
3 files changed, 40 insertions, 52 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 896184d..83627ef 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 f6a1a8d..8d76c4a 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) {
@@ -1470,13 +1442,6 @@ static const struct command_registration riscv_exec_command_handlers[] = {
.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,
.mode = COMMAND_ANY,
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 4fb0f77..2210ab6 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