aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2017-11-27 14:47:33 -0800
committerTim Newsome <tim@sifive.com>2017-12-19 10:41:48 -0800
commit26a54452d2acb33e5343ee44b5982ad16e3af169 (patch)
treed9c520759f0ad8760e6adcdf94f24a899cae9ea4
parent7c989698a14b2626702ffb8812e78c7fd274af75 (diff)
downloadriscv-openocd-26a54452d2acb33e5343ee44b5982ad16e3af169.zip
riscv-openocd-26a54452d2acb33e5343ee44b5982ad16e3af169.tar.gz
riscv-openocd-26a54452d2acb33e5343ee44b5982ad16e3af169.tar.bz2
Fix register names.
Use the ABI ones for every register that we have one for. Change-Id: I2a993abff416d2652dbe026b3fb498e144a5006f
-rw-r--r--src/target/riscv/gdb_regs.h41
-rw-r--r--src/target/riscv/program.c8
-rw-r--r--src/target/riscv/riscv-011.c2
-rw-r--r--src/target/riscv/riscv-013.c82
-rw-r--r--src/target/riscv/riscv.c21
5 files changed, 108 insertions, 46 deletions
diff --git a/src/target/riscv/gdb_regs.h b/src/target/riscv/gdb_regs.h
index 2952e10..3f60d01 100644
--- a/src/target/riscv/gdb_regs.h
+++ b/src/target/riscv/gdb_regs.h
@@ -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,
diff --git a/src/target/riscv/program.c b/src/target/riscv/program.c
index e7238dd..0c0dbd8 100644
--- a/src/target/riscv/program.c
+++ b/src/target/riscv/program.c
@@ -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)
diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c
index 6e576fe..1382387 100644
--- a/src/target/riscv/riscv-011.c
+++ b/src/target/riscv/riscv-011.c
@@ -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;
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index a63d168..4238273 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -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");
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 431e06f..a196fdc 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -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) {