Merge pull request #279 from riscv/work_area

Use work area instead of riscv-specific config
This commit is contained in:
Tim Newsome 2018-07-17 12:06:09 -07:00 committed by GitHub
commit 8b25d2f2ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 52 deletions

View File

@ -923,22 +923,25 @@ typedef struct {
riscv_addr_t hart_address; riscv_addr_t hart_address;
/* Memory address to access the scratch memory from the debugger. */ /* Memory address to access the scratch memory from the debugger. */
riscv_addr_t debug_address; riscv_addr_t debug_address;
struct working_area *area;
} scratch_mem_t; } scratch_mem_t;
/** /**
* Find some scratch memory to be used with the given program. * 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, scratch_mem_t *scratch,
struct riscv_program *program, struct riscv_program *program,
unsigned size_bytes) unsigned size_bytes)
{ {
riscv013_info_t *info = get_info(target);
riscv_addr_t alignment = 1; riscv_addr_t alignment = 1;
while (alignment < size_bytes) while (alignment < size_bytes)
alignment *= 2; alignment *= 2;
scratch->area = NULL;
riscv013_info_t *info = get_info(target);
if (info->dataaccess == 1) { if (info->dataaccess == 1) {
/* Sign extend dataaddr. */ /* Sign extend dataaddr. */
scratch->hart_address = info->dataaddr; scratch->hart_address = info->dataaddr;
@ -969,8 +972,9 @@ static int scratch_find(struct target *target,
return ERROR_OK; return ERROR_OK;
} }
if (riscv_use_scratch_ram) { if (target_alloc_working_area(target, size_bytes + alignment - 1,
scratch->hart_address = (riscv_scratch_ram_address + alignment - 1) & &scratch->area) == ERROR_OK) {
scratch->hart_address = (scratch->area->address + alignment - 1) &
~(alignment - 1); ~(alignment - 1);
scratch->memory_space = SPACE_DMI_RAM; scratch->memory_space = SPACE_DMI_RAM;
scratch->debug_address = scratch->hart_address; 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 " 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; 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, static int scratch_read64(struct target *target, scratch_mem_t *scratch,
uint64_t *value) 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) if (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
scratch_mem_t scratch;
bool use_scratch = false;
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 && if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 &&
riscv_supports_extension(target, riscv_current_hartid(target), 'D') && riscv_supports_extension(target, riscv_current_hartid(target), 'D') &&
riscv_xlen(target) < 64) { riscv_xlen(target) < 64) {
/* There are no instructions to move all the bits from a register, so /* There are no instructions to move all the bits from a register, so
* we need to use some scratch RAM. */ * we need to use some scratch RAM. */
use_scratch = true;
riscv_program_insert(&program, fld(number - GDB_REGNO_FPR0, S0, 0)); riscv_program_insert(&program, fld(number - GDB_REGNO_FPR0, S0, 0));
scratch_mem_t scratch; if (scratch_reserve(target, &scratch, &program, 8) != ERROR_OK)
if (scratch_find(target, &scratch, &program, 8) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
if (register_write_direct(target, GDB_REGNO_S0, scratch.hart_address) if (register_write_direct(target, GDB_REGNO_S0, scratch.hart_address)
!= ERROR_OK) != ERROR_OK) {
scratch_release(target, &scratch);
return ERROR_FAIL; 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; return ERROR_FAIL;
}
} else { } else {
if (register_write_direct(target, GDB_REGNO_S0, value) != ERROR_OK) 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; reg->valid = true;
} }
if (use_scratch)
scratch_release(target, &scratch);
/* Restore S0. */ /* Restore S0. */
if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK) if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)
return ERROR_FAIL; 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, riscv_program_insert(&program, fsd(number - GDB_REGNO_FPR0, S0,
0)); 0));
if (scratch_find(target, &scratch, &program, 8) != ERROR_OK) if (scratch_reserve(target, &scratch, &program, 8) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
use_scratch = true; use_scratch = true;
if (register_write_direct(target, GDB_REGNO_S0, 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; return ERROR_FAIL;
}
} else if (riscv_supports_extension(target, } else if (riscv_supports_extension(target,
riscv_current_hartid(target), 'D')) { riscv_current_hartid(target), 'D')) {
riscv_program_insert(&program, fmv_x_d(S0, number - GDB_REGNO_FPR0)); 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. */ /* Don't message on error. Probably the register doesn't exist. */
if (use_scratch) { if (use_scratch) {
if (scratch_read64(target, &scratch, value) != ERROR_OK) result = scratch_read64(target, &scratch, value);
return ERROR_FAIL; scratch_release(target, &scratch);
if (result != ERROR_OK)
return result;
} else { } else {
/* Read S0 */ /* Read S0 */
if (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK) if (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK)

View File

@ -185,9 +185,6 @@ int riscv_command_timeout_sec = DEFAULT_COMMAND_TIMEOUT_SEC;
/* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/ /* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/
int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC; int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC;
bool riscv_use_scratch_ram;
uint64_t riscv_scratch_ram_address;
bool riscv_prefer_sba; bool riscv_prefer_sba;
/* In addition to the ones in the standard spec, we'll also expose additional /* 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; 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) COMMAND_HANDLER(riscv_set_prefer_sba)
{ {
if (CMD_ARGC != 1) { if (CMD_ARGC != 1) {
@ -1469,13 +1441,6 @@ static const struct command_registration riscv_exec_command_handlers[] = {
.usage = "riscv set_reset_timeout_sec [sec]", .usage = "riscv set_reset_timeout_sec [sec]",
.help = "Set the wall-clock timeout (in seconds) after reset is deasserted" .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", .name = "set_prefer_sba",
.handler = riscv_set_prefer_sba, .handler = riscv_set_prefer_sba,

View File

@ -128,9 +128,6 @@ extern int riscv_command_timeout_sec;
/* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/ /* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/
extern int riscv_reset_timeout_sec; extern int riscv_reset_timeout_sec;
extern bool riscv_use_scratch_ram;
extern uint64_t riscv_scratch_ram_address;
extern bool riscv_prefer_sba; extern bool riscv_prefer_sba;
/* Everything needs the RISC-V specific info structure, so here's a nice macro /* Everything needs the RISC-V specific info structure, so here's a nice macro