Fix register names.

Use the ABI ones for every register that we have one for.

Change-Id: I2a993abff416d2652dbe026b3fb498e144a5006f
update_defines
Tim Newsome 2017-11-27 14:47:33 -08:00
parent 7c989698a1
commit 26a54452d2
5 changed files with 108 additions and 46 deletions

View File

@ -4,12 +4,41 @@
// gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in
// its source tree. We must interpret the numbers the same here.
enum gdb_regno {
GDB_REGNO_XPR0 = 0,
GDB_REGNO_X0 = GDB_REGNO_XPR0 + 0,
GDB_REGNO_ZERO = GDB_REGNO_XPR0 + 0,
GDB_REGNO_S0 = GDB_REGNO_XPR0 + 8,
GDB_REGNO_S1 = GDB_REGNO_XPR0 + 9,
GDB_REGNO_XPR31 = GDB_REGNO_XPR0 + 31,
GDB_REGNO_ZERO = 0, /* Read-only register, always 0. */
GDB_REGNO_RA = 1, /* Return Address. */
GDB_REGNO_SP = 2, /* Stack Pointer. */
GDB_REGNO_GP = 3, /* Global Pointer. */
GDB_REGNO_TP = 4, /* Thread Pointer. */
GDB_REGNO_T0,
GDB_REGNO_T1,
GDB_REGNO_T2,
GDB_REGNO_S0 = 8,
GDB_REGNO_FP = 8, /* Frame Pointer. */
GDB_REGNO_S1,
GDB_REGNO_A0 = 10, /* First argument. */
GDB_REGNO_A1 = 11, /* Second argument. */
GDB_REGNO_A2,
GDB_REGNO_A3,
GDB_REGNO_A4,
GDB_REGNO_A5,
GDB_REGNO_A6,
GDB_REGNO_A7,
GDB_REGNO_S2,
GDB_REGNO_S3,
GDB_REGNO_S4,
GDB_REGNO_S5,
GDB_REGNO_S6,
GDB_REGNO_S7,
GDB_REGNO_S8,
GDB_REGNO_S9,
GDB_REGNO_S10,
GDB_REGNO_S11,
GDB_REGNO_T3,
GDB_REGNO_T4,
GDB_REGNO_T5,
GDB_REGNO_T6,
GDB_REGNO_XPR31 = GDB_REGNO_T6,
GDB_REGNO_PC = 32,
GDB_REGNO_FPR0 = 33,
GDB_REGNO_FPR31 = GDB_REGNO_FPR0 + 31,

View File

@ -45,7 +45,7 @@ int riscv_program_exec(struct riscv_program *p, struct target *t)
keep_alive();
riscv_reg_t saved_registers[GDB_REGNO_XPR31 + 1];
for (size_t i = GDB_REGNO_XPR0 + 1; i <= GDB_REGNO_XPR31; ++i) {
for (size_t i = GDB_REGNO_ZERO + 1; i <= GDB_REGNO_XPR31; ++i) {
if (p->writes_xreg[i]) {
LOG_DEBUG("Saving register %d as used by program", (int)i);
saved_registers[i] = riscv_get_register(t, i);
@ -72,7 +72,7 @@ int riscv_program_exec(struct riscv_program *p, struct target *t)
if (i >= riscv_debug_buffer_size(p->target))
p->debug_buffer[i] = riscv_read_debug_buffer(t, i);
for (size_t i = GDB_REGNO_XPR0; i <= GDB_REGNO_XPR31; ++i)
for (size_t i = GDB_REGNO_ZERO; i <= GDB_REGNO_XPR31; ++i)
if (p->writes_xreg[i])
riscv_set_register(t, i, saved_registers[i]);
@ -112,13 +112,13 @@ int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno
int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr)
{
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_ZERO, csr - GDB_REGNO_CSR0));
}
int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr)
{
assert(csr >= GDB_REGNO_CSR0);
return riscv_program_insert(p, csrrw(GDB_REGNO_X0, s, csr - GDB_REGNO_CSR0));
return riscv_program_insert(p, csrrw(GDB_REGNO_ZERO, s, csr - GDB_REGNO_CSR0));
}
int riscv_program_fence_i(struct riscv_program *p)

View File

@ -1344,7 +1344,7 @@ static int register_write(struct target *target, unsigned int number,
cache_set_store(target, 1, S0, SLOT_LAST);
cache_set_jump(target, 2);
} else if (number <= GDB_REGNO_XPR31) {
cache_set_load(target, 0, number - GDB_REGNO_XPR0, SLOT0);
cache_set_load(target, 0, number - GDB_REGNO_ZERO, SLOT0);
cache_set_jump(target, 1);
} else if (number == GDB_REGNO_PC) {
info->dpc = value;

View File

@ -647,7 +647,7 @@ static uint32_t access_register_command(uint32_t number, unsigned size,
if (number <= GDB_REGNO_XPR31) {
command = set_field(command, AC_ACCESS_REGISTER_REGNO,
0x1000 + number - GDB_REGNO_XPR0);
0x1000 + number - GDB_REGNO_ZERO);
} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
command = set_field(command, AC_ACCESS_REGISTER_REGNO,
0x1020 + number - GDB_REGNO_FPR0);
@ -1104,6 +1104,16 @@ static struct reg_arch_type riscv_reg_arch_type = {
.set = register_set
};
struct csr_info {
unsigned number;
const char *name;
};
static int cmp_csr_info(const void *p1, const void *p2)
{
return (int) (((struct csr_info *)p1)->number) - (int) (((struct csr_info *)p2)->number);
}
static int init_registers(struct target *target)
{
riscv013_info_t *info = get_info(target);
@ -1148,6 +1158,14 @@ static int init_registers(struct target *target)
.type = REG_TYPE_IEEE_DOUBLE,
.id = "ieee_double"
};
struct csr_info csr_info[] = {
#define DECLARE_CSR(name, number) { number, #name },
#include "encoding.h"
#undef DECLARE_CSR
};
// encoding.h does not contain the registers in sorted order.
qsort(csr_info, DIM(csr_info), sizeof(*csr_info), cmp_csr_info);
unsigned csr_info_index = 0;
// When gdb request register N, gdb_get_register_packet() assumes that this
// is register at index N in reg_list. So if there are certain registers
@ -1167,7 +1185,40 @@ static int init_registers(struct target *target)
// target is in theory allowed to change XLEN on us. But I expect a lot
// of other things to break in that case as well.
if (number <= GDB_REGNO_XPR31) {
sprintf(reg_name, "x%d", number);
switch (number) {
case GDB_REGNO_ZERO: r->name = "zero"; break;
case GDB_REGNO_RA: r->name = "ra"; break;
case GDB_REGNO_SP: r->name = "sp"; break;
case GDB_REGNO_GP: r->name = "gp"; break;
case GDB_REGNO_TP: r->name = "tp"; break;
case GDB_REGNO_T0: r->name = "t0"; break;
case GDB_REGNO_T1: r->name = "t1"; break;
case GDB_REGNO_T2: r->name = "t2"; break;
case GDB_REGNO_FP: r->name = "fp"; break;
case GDB_REGNO_S1: r->name = "s1"; break;
case GDB_REGNO_A0: r->name = "a0"; break;
case GDB_REGNO_A1: r->name = "a1"; break;
case GDB_REGNO_A2: r->name = "a2"; break;
case GDB_REGNO_A3: r->name = "a3"; break;
case GDB_REGNO_A4: r->name = "a4"; break;
case GDB_REGNO_A5: r->name = "a5"; break;
case GDB_REGNO_A6: r->name = "a6"; break;
case GDB_REGNO_A7: r->name = "a7"; break;
case GDB_REGNO_S2: r->name = "s2"; break;
case GDB_REGNO_S3: r->name = "s3"; break;
case GDB_REGNO_S4: r->name = "s4"; break;
case GDB_REGNO_S5: r->name = "s5"; break;
case GDB_REGNO_S6: r->name = "s6"; break;
case GDB_REGNO_S7: r->name = "s7"; break;
case GDB_REGNO_S8: r->name = "s8"; break;
case GDB_REGNO_S9: r->name = "s9"; break;
case GDB_REGNO_S10: r->name = "s10"; break;
case GDB_REGNO_S11: r->name = "s11"; break;
case GDB_REGNO_T3: r->name = "t3"; break;
case GDB_REGNO_T4: r->name = "t4"; break;
case GDB_REGNO_T5: r->name = "t5"; break;
case GDB_REGNO_T6: r->name = "t6"; break;
}
r->group = "general";
r->feature = &feature_cpu;
} else if (number == GDB_REGNO_PC) {
@ -1189,36 +1240,33 @@ static int init_registers(struct target *target)
r->group = "csr";
r->feature = &feature_csr;
r->exist = true;
switch (number) {
unsigned csr_number = number - GDB_REGNO_CSR0;
while (csr_info[csr_info_index].number < csr_number) {
csr_info_index++;
}
if (csr_info[csr_info_index].number == csr_number) {
r->name = csr_info[csr_info_index].name;
} else {
sprintf(reg_name, "csr%d", csr_number);
}
switch (csr_number) {
case CSR_FFLAGS:
strcpy(reg_name, "fflags");
r->exist = riscv_supports_extension(target, 'F');
r->group = "float";
r->feature = &feature_fpu;
break;
case CSR_FRM:
strcpy(reg_name, "frm");
r->exist = riscv_supports_extension(target, 'F');
r->group = "float";
r->feature = &feature_fpu;
break;
case CSR_FCSR:
strcpy(reg_name, "fcsr");
r->exist = riscv_supports_extension(target, 'F');
r->group = "float";
r->feature = &feature_fpu;
break;
case CSR_CYCLE:
strcpy(reg_name, "cycle");
break;
case CSR_TIME:
strcpy(reg_name, "time");
break;
case CSR_INSTRET:
strcpy(reg_name, "instret");
break;
default:
sprintf(reg_name, "csr%d", number - GDB_REGNO_CSR0);
}
} else if (number == GDB_REGNO_PRIV) {
sprintf(reg_name, "priv");

View File

@ -151,21 +151,6 @@ typedef enum slot {
#define DBUS_ADDRESS_UNKNOWN 0xffff
// gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in
// its source tree. We must interpret the numbers the same here.
enum {
REG_XPR0 = 0,
REG_XPR31 = 31,
REG_PC = 32,
REG_FPR0 = 33,
REG_FPR31 = 64,
REG_CSR0 = 65,
REG_MSTATUS = CSR_MSTATUS + REG_CSR0,
REG_CSR4095 = 4160,
REG_PRIV = 4161,
REG_COUNT
};
#define MAX_HWBPS 16
#define DRAM_CACHE_SIZE 16
@ -842,7 +827,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
return ERROR_FAIL;
}
if (r->number > REG_XPR31) {
if (r->number > GDB_REGNO_XPR31) {
LOG_ERROR("Only GPRs can be use as argument registers.");
return ERROR_FAIL;
}
@ -1404,7 +1389,7 @@ void riscv_set_current_hartid(struct target *target, int hartid)
/* Avoid invalidating the register cache all the time. */
if (r->registers_initialized
&& (!riscv_rtos_enabled(target) || (previous_hartid == hartid))
&& target->reg_cache->reg_list[GDB_REGNO_XPR0].size == (unsigned)riscv_xlen(target)
&& target->reg_cache->reg_list[GDB_REGNO_ZERO].size == (unsigned)riscv_xlen(target)
&& (!riscv_rtos_enabled(target) || (r->rtos_hartid != -1))) {
return;
} else
@ -1694,7 +1679,7 @@ const char *gdb_regno_name(enum gdb_regno regno)
return "priv";
default:
if (regno <= GDB_REGNO_XPR31) {
sprintf(buf, "x%d", regno - GDB_REGNO_XPR0);
sprintf(buf, "x%d", regno - GDB_REGNO_ZERO);
} else if (regno >= GDB_REGNO_CSR0 && regno <= GDB_REGNO_CSR4095) {
sprintf(buf, "csr%d", regno - GDB_REGNO_CSR0);
} else if (regno >= GDB_REGNO_FPR0 && regno <= GDB_REGNO_FPR31) {