Merge pull request #279 from riscv/work_area

Use work area instead of riscv-specific config
riscv-compliance
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;
/* 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)

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.*/
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,

View File

@ -128,9 +128,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