Fix register names.
Use the ABI ones for every register that we have one for. Change-Id: I2a993abff416d2652dbe026b3fb498e144a5006fupdate_defines
parent
7c989698a1
commit
26a54452d2
|
@ -4,12 +4,41 @@
|
||||||
// gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in
|
// 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.
|
// its source tree. We must interpret the numbers the same here.
|
||||||
enum gdb_regno {
|
enum gdb_regno {
|
||||||
GDB_REGNO_XPR0 = 0,
|
GDB_REGNO_ZERO = 0, /* Read-only register, always 0. */
|
||||||
GDB_REGNO_X0 = GDB_REGNO_XPR0 + 0,
|
GDB_REGNO_RA = 1, /* Return Address. */
|
||||||
GDB_REGNO_ZERO = GDB_REGNO_XPR0 + 0,
|
GDB_REGNO_SP = 2, /* Stack Pointer. */
|
||||||
GDB_REGNO_S0 = GDB_REGNO_XPR0 + 8,
|
GDB_REGNO_GP = 3, /* Global Pointer. */
|
||||||
GDB_REGNO_S1 = GDB_REGNO_XPR0 + 9,
|
GDB_REGNO_TP = 4, /* Thread Pointer. */
|
||||||
GDB_REGNO_XPR31 = GDB_REGNO_XPR0 + 31,
|
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_PC = 32,
|
||||||
GDB_REGNO_FPR0 = 33,
|
GDB_REGNO_FPR0 = 33,
|
||||||
GDB_REGNO_FPR31 = GDB_REGNO_FPR0 + 31,
|
GDB_REGNO_FPR31 = GDB_REGNO_FPR0 + 31,
|
||||||
|
|
|
@ -45,7 +45,7 @@ int riscv_program_exec(struct riscv_program *p, struct target *t)
|
||||||
keep_alive();
|
keep_alive();
|
||||||
|
|
||||||
riscv_reg_t saved_registers[GDB_REGNO_XPR31 + 1];
|
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]) {
|
if (p->writes_xreg[i]) {
|
||||||
LOG_DEBUG("Saving register %d as used by program", (int)i);
|
LOG_DEBUG("Saving register %d as used by program", (int)i);
|
||||||
saved_registers[i] = riscv_get_register(t, 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))
|
if (i >= riscv_debug_buffer_size(p->target))
|
||||||
p->debug_buffer[i] = riscv_read_debug_buffer(t, i);
|
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])
|
if (p->writes_xreg[i])
|
||||||
riscv_set_register(t, i, saved_registers[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)
|
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);
|
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)
|
int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr)
|
||||||
{
|
{
|
||||||
assert(csr >= GDB_REGNO_CSR0);
|
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)
|
int riscv_program_fence_i(struct riscv_program *p)
|
||||||
|
|
|
@ -1344,7 +1344,7 @@ static int register_write(struct target *target, unsigned int number,
|
||||||
cache_set_store(target, 1, S0, SLOT_LAST);
|
cache_set_store(target, 1, S0, SLOT_LAST);
|
||||||
cache_set_jump(target, 2);
|
cache_set_jump(target, 2);
|
||||||
} else if (number <= GDB_REGNO_XPR31) {
|
} 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);
|
cache_set_jump(target, 1);
|
||||||
} else if (number == GDB_REGNO_PC) {
|
} else if (number == GDB_REGNO_PC) {
|
||||||
info->dpc = value;
|
info->dpc = value;
|
||||||
|
|
|
@ -647,7 +647,7 @@ static uint32_t access_register_command(uint32_t number, unsigned size,
|
||||||
|
|
||||||
if (number <= GDB_REGNO_XPR31) {
|
if (number <= GDB_REGNO_XPR31) {
|
||||||
command = set_field(command, AC_ACCESS_REGISTER_REGNO,
|
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) {
|
} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
|
||||||
command = set_field(command, AC_ACCESS_REGISTER_REGNO,
|
command = set_field(command, AC_ACCESS_REGISTER_REGNO,
|
||||||
0x1020 + number - GDB_REGNO_FPR0);
|
0x1020 + number - GDB_REGNO_FPR0);
|
||||||
|
@ -1104,6 +1104,16 @@ static struct reg_arch_type riscv_reg_arch_type = {
|
||||||
.set = register_set
|
.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)
|
static int init_registers(struct target *target)
|
||||||
{
|
{
|
||||||
riscv013_info_t *info = get_info(target);
|
riscv013_info_t *info = get_info(target);
|
||||||
|
@ -1148,6 +1158,14 @@ static int init_registers(struct target *target)
|
||||||
.type = REG_TYPE_IEEE_DOUBLE,
|
.type = REG_TYPE_IEEE_DOUBLE,
|
||||||
.id = "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
|
// 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
|
// 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
|
// 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.
|
// of other things to break in that case as well.
|
||||||
if (number <= GDB_REGNO_XPR31) {
|
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->group = "general";
|
||||||
r->feature = &feature_cpu;
|
r->feature = &feature_cpu;
|
||||||
} else if (number == GDB_REGNO_PC) {
|
} else if (number == GDB_REGNO_PC) {
|
||||||
|
@ -1189,36 +1240,33 @@ static int init_registers(struct target *target)
|
||||||
r->group = "csr";
|
r->group = "csr";
|
||||||
r->feature = &feature_csr;
|
r->feature = &feature_csr;
|
||||||
r->exist = true;
|
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:
|
case CSR_FFLAGS:
|
||||||
strcpy(reg_name, "fflags");
|
|
||||||
r->exist = riscv_supports_extension(target, 'F');
|
r->exist = riscv_supports_extension(target, 'F');
|
||||||
r->group = "float";
|
r->group = "float";
|
||||||
r->feature = &feature_fpu;
|
r->feature = &feature_fpu;
|
||||||
break;
|
break;
|
||||||
case CSR_FRM:
|
case CSR_FRM:
|
||||||
strcpy(reg_name, "frm");
|
|
||||||
r->exist = riscv_supports_extension(target, 'F');
|
r->exist = riscv_supports_extension(target, 'F');
|
||||||
r->group = "float";
|
r->group = "float";
|
||||||
r->feature = &feature_fpu;
|
r->feature = &feature_fpu;
|
||||||
break;
|
break;
|
||||||
case CSR_FCSR:
|
case CSR_FCSR:
|
||||||
strcpy(reg_name, "fcsr");
|
|
||||||
r->exist = riscv_supports_extension(target, 'F');
|
r->exist = riscv_supports_extension(target, 'F');
|
||||||
r->group = "float";
|
r->group = "float";
|
||||||
r->feature = &feature_fpu;
|
r->feature = &feature_fpu;
|
||||||
break;
|
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) {
|
} else if (number == GDB_REGNO_PRIV) {
|
||||||
sprintf(reg_name, "priv");
|
sprintf(reg_name, "priv");
|
||||||
|
|
|
@ -151,21 +151,6 @@ typedef enum slot {
|
||||||
|
|
||||||
#define DBUS_ADDRESS_UNKNOWN 0xffff
|
#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 MAX_HWBPS 16
|
||||||
#define DRAM_CACHE_SIZE 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;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->number > REG_XPR31) {
|
if (r->number > GDB_REGNO_XPR31) {
|
||||||
LOG_ERROR("Only GPRs can be use as argument registers.");
|
LOG_ERROR("Only GPRs can be use as argument registers.");
|
||||||
return ERROR_FAIL;
|
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. */
|
/* Avoid invalidating the register cache all the time. */
|
||||||
if (r->registers_initialized
|
if (r->registers_initialized
|
||||||
&& (!riscv_rtos_enabled(target) || (previous_hartid == hartid))
|
&& (!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))) {
|
&& (!riscv_rtos_enabled(target) || (r->rtos_hartid != -1))) {
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
|
@ -1694,7 +1679,7 @@ const char *gdb_regno_name(enum gdb_regno regno)
|
||||||
return "priv";
|
return "priv";
|
||||||
default:
|
default:
|
||||||
if (regno <= GDB_REGNO_XPR31) {
|
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) {
|
} else if (regno >= GDB_REGNO_CSR0 && regno <= GDB_REGNO_CSR4095) {
|
||||||
sprintf(buf, "csr%d", regno - GDB_REGNO_CSR0);
|
sprintf(buf, "csr%d", regno - GDB_REGNO_CSR0);
|
||||||
} else if (regno >= GDB_REGNO_FPR0 && regno <= GDB_REGNO_FPR31) {
|
} else if (regno >= GDB_REGNO_FPR0 && regno <= GDB_REGNO_FPR31) {
|
||||||
|
|
Loading…
Reference in New Issue