Register read/write might be working.
Change-Id: I6c51d6157dde56d8cd666b4d30ec7bbc7a4bef9fmacbuild
parent
94e8250713
commit
e7bb815e87
|
@ -40,6 +40,7 @@ int riscv_program_init(struct riscv_program *p, struct target *target)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add ebreak and execute the program. */
|
||||||
int riscv_program_exec(struct riscv_program *p, struct target *t)
|
int riscv_program_exec(struct riscv_program *p, struct target *t)
|
||||||
{
|
{
|
||||||
keep_alive();
|
keep_alive();
|
||||||
|
@ -258,7 +259,7 @@ int riscv_program_sb(struct riscv_program *p, enum gdb_regno d, riscv_addr_t add
|
||||||
|
|
||||||
int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr)
|
int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr)
|
||||||
{
|
{
|
||||||
assert(csr >= GDB_REGNO_CSR0);
|
assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
|
||||||
return riscv_program_insert(p, csrrs(d, GDB_REGNO_X0, csr - GDB_REGNO_CSR0));
|
return riscv_program_insert(p, csrrs(d, GDB_REGNO_X0, csr - GDB_REGNO_CSR0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ static void riscv013_step_or_resume_current_hart(struct target *target, bool ste
|
||||||
//static void riscv013_set_autoexec(struct target *target, unsigned index,
|
//static void riscv013_set_autoexec(struct target *target, unsigned index,
|
||||||
//bool enabled);
|
//bool enabled);
|
||||||
//static int riscv013_debug_buffer_register(struct target *target, riscv_addr_t addr);
|
//static int riscv013_debug_buffer_register(struct target *target, riscv_addr_t addr);
|
||||||
//static void riscv013_clear_abstract_error(struct target *target);
|
static void riscv013_clear_abstract_error(struct target *target);
|
||||||
|
|
||||||
/* Implementations of the functions in riscv_info_t. */
|
/* Implementations of the functions in riscv_info_t. */
|
||||||
static riscv_reg_t riscv013_get_register(struct target *target, int hartid, int regid);
|
static riscv_reg_t riscv013_get_register(struct target *target, int hartid, int regid);
|
||||||
|
@ -62,6 +62,7 @@ static void riscv013_fill_dmi_write_u64(struct target *target, char *buf, int a,
|
||||||
static void riscv013_fill_dmi_read_u64(struct target *target, char *buf, int a);
|
static void riscv013_fill_dmi_read_u64(struct target *target, char *buf, int a);
|
||||||
static int riscv013_dmi_write_u64_bits(struct target *target);
|
static int riscv013_dmi_write_u64_bits(struct target *target);
|
||||||
static void riscv013_fill_dmi_nop_u64(struct target *target, char *buf);
|
static void riscv013_fill_dmi_nop_u64(struct target *target, char *buf);
|
||||||
|
static int register_read_direct(struct target *target, uint64_t *value, uint32_t number);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Since almost everything can be accomplish by scanning the dbus register, all
|
* Since almost everything can be accomplish by scanning the dbus register, all
|
||||||
|
@ -771,21 +772,21 @@ static int register_write_direct(struct target *target, unsigned number,
|
||||||
|
|
||||||
riscv_program_init(&program, target);
|
riscv_program_init(&program, target);
|
||||||
|
|
||||||
assert(0);
|
uint64_t s0;
|
||||||
#if 0
|
if (register_read_direct(target, &s0, GDB_REGNO_S0) != ERROR_OK)
|
||||||
riscv_addr_t input = riscv_program_alloc_d(&program);
|
return ERROR_FAIL;
|
||||||
riscv_program_write_ram(&program, input + 4, value >> 32);
|
|
||||||
riscv_program_write_ram(&program, input, value);
|
|
||||||
|
|
||||||
assert(GDB_REGNO_XPR0 == 0);
|
if (register_write_direct(target, GDB_REGNO_S0, value) != ERROR_OK)
|
||||||
if (number <= GDB_REGNO_XPR31) {
|
return ERROR_FAIL;
|
||||||
riscv_program_lx(&program, number, input);
|
|
||||||
} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
|
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
|
||||||
riscv_program_flx(&program, number, input);
|
if (supports_extension(target, 'D') && riscv_xlen(target) >= 64) {
|
||||||
|
riscv_program_insert(&program, fmv_x_d(S0, number - GDB_REGNO_FPR0));
|
||||||
|
} else {
|
||||||
|
riscv_program_insert(&program, fmv_x_s(S0, number - GDB_REGNO_FPR0));
|
||||||
|
}
|
||||||
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
|
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
|
||||||
enum gdb_regno temp = riscv_program_gettemp(&program);
|
riscv_program_csrw(&program, S0, number);
|
||||||
riscv_program_lx(&program, temp, input);
|
|
||||||
riscv_program_csrw(&program, temp, number);
|
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Unsupported register (enum gdb_regno)(%d)", number);
|
LOG_ERROR("Unsupported register (enum gdb_regno)(%d)", number);
|
||||||
abort();
|
abort();
|
||||||
|
@ -797,8 +798,11 @@ static int register_write_direct(struct target *target, unsigned number,
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore S0.
|
||||||
|
if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)
|
||||||
|
return ERROR_FAIL;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Actually read registers from the target right now. */
|
/** Actually read registers from the target right now. */
|
||||||
|
@ -810,7 +814,6 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
|
||||||
if (result != ERROR_OK) {
|
if (result != ERROR_OK) {
|
||||||
struct riscv_program program;
|
struct riscv_program program;
|
||||||
riscv_program_init(&program, target);
|
riscv_program_init(&program, target);
|
||||||
assert(0);
|
|
||||||
assert(number != GDB_REGNO_S0);
|
assert(number != GDB_REGNO_S0);
|
||||||
|
|
||||||
uint64_t s0;
|
uint64_t s0;
|
||||||
|
@ -818,43 +821,34 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
|
||||||
// Write program to move data into s0.
|
// Write program to move data into s0.
|
||||||
// Execute program.
|
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
|
||||||
// Read S0
|
// TODO: Possibly set F in mstatus.
|
||||||
if (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK)
|
// TODO: Fully support D extension on RV32.
|
||||||
return ERROR_FAIL;
|
if (supports_extension(target, 'D') && riscv_xlen(target) >= 64) {
|
||||||
// Restore S0.
|
riscv_program_insert(&program, fmv_d_x(number - GDB_REGNO_FPR0, S0));
|
||||||
if (register_write_direct(target, GDB_REGNO_S0, &s0) != ERROR_OK)
|
} else {
|
||||||
return ERROR_FAIL;
|
riscv_program_insert(&program, fmv_s_x(number - GDB_REGNO_FPR0, S0));
|
||||||
#if 0
|
}
|
||||||
riscv_addr_t output = riscv_program_alloc_d(&program);
|
|
||||||
riscv_program_write_ram(&program, output + 4, 0);
|
|
||||||
riscv_program_write_ram(&program, output, 0);
|
|
||||||
|
|
||||||
assert(GDB_REGNO_XPR0 == 0);
|
|
||||||
if (number <= GDB_REGNO_XPR31) {
|
|
||||||
riscv_program_sx(&program, number, output);
|
|
||||||
} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
|
|
||||||
riscv_program_fsx(&program, number, output);
|
|
||||||
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
|
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
|
||||||
LOG_DEBUG("reading CSR index=0x%03x", number - GDB_REGNO_CSR0);
|
riscv_program_csrr(&program, S0, number);
|
||||||
enum gdb_regno temp = riscv_program_gettemp(&program);
|
|
||||||
riscv_program_csrr(&program, temp, number);
|
|
||||||
riscv_program_sx(&program, temp, output);
|
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Unsupported register (enum gdb_regno)(%d)", number);
|
LOG_ERROR("Unsupported register (enum gdb_regno)(%d)", number);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute program.
|
||||||
int exec_out = riscv_program_exec(&program, target);
|
int exec_out = riscv_program_exec(&program, target);
|
||||||
if (exec_out != ERROR_OK) {
|
if (exec_out != ERROR_OK) {
|
||||||
riscv013_clear_abstract_error(target);
|
riscv013_clear_abstract_error(target);
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*value = 0;
|
// Read S0
|
||||||
*value |= ((uint64_t)(riscv_program_read_ram(&program, output + 4))) << 32;
|
if (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK)
|
||||||
*value |= riscv_program_read_ram(&program, output);
|
return ERROR_FAIL;
|
||||||
#endif
|
// Restore S0.
|
||||||
|
if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)
|
||||||
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("[%d] reg[0x%x] = 0x%" PRIx64, riscv_current_hartid(target),
|
LOG_DEBUG("[%d] reg[0x%x] = 0x%" PRIx64, riscv_current_hartid(target),
|
||||||
|
@ -2028,6 +2022,7 @@ int riscv013_debug_buffer_register(struct target *target, riscv_addr_t addr)
|
||||||
else
|
else
|
||||||
return DMI_PROGBUF0 + (addr - riscv013_progbuf_addr(target)) / 4;
|
return DMI_PROGBUF0 + (addr - riscv013_progbuf_addr(target)) / 4;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void riscv013_clear_abstract_error(struct target *target)
|
void riscv013_clear_abstract_error(struct target *target)
|
||||||
{
|
{
|
||||||
|
@ -2049,4 +2044,3 @@ void riscv013_clear_abstract_error(struct target *target)
|
||||||
// Clear the error status.
|
// Clear the error status.
|
||||||
dmi_write(target, DMI_ABSTRACTCS, abstractcs & DMI_ABSTRACTCS_CMDERR);
|
dmi_write(target, DMI_ABSTRACTCS, abstractcs & DMI_ABSTRACTCS_CMDERR);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
Loading…
Reference in New Issue