[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC v5 66/68] target/riscv: gdb: support vector registers for rv64 & rv
From: |
frank . chang |
Subject: |
[RFC v5 66/68] target/riscv: gdb: support vector registers for rv64 & rv32 |
Date: |
Wed, 30 Sep 2020 03:04:41 +0800 |
From: Hsiangkai Wang <kai.wang@sifive.com>
Signed-off-by: Hsiangkai Wang <kai.wang@sifive.com>
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
gdb-xml/riscv-32bit-csr.xml | 7 ++
gdb-xml/riscv-64bit-csr.xml | 7 ++
target/riscv/cpu.c | 1 +
target/riscv/cpu.h | 25 ++++++
target/riscv/gdbstub.c | 172 +++++++++++++++++++++++++++++++++++-
5 files changed, 210 insertions(+), 2 deletions(-)
diff --git a/gdb-xml/riscv-32bit-csr.xml b/gdb-xml/riscv-32bit-csr.xml
index 3d2031da7d..1901071470 100644
--- a/gdb-xml/riscv-32bit-csr.xml
+++ b/gdb-xml/riscv-32bit-csr.xml
@@ -248,4 +248,11 @@
<reg name="mucounteren" bitsize="32"/>
<reg name="mscounteren" bitsize="32"/>
<reg name="mhcounteren" bitsize="32"/>
+ <reg name="vstart" bitsize="32"/>
+ <reg name="vxsat" bitsize="32"/>
+ <reg name="vxrm" bitsize="32"/>
+ <reg name="vcsr" bitsize="32"/>
+ <reg name="vl" bitsize="32"/>
+ <reg name="vtype" bitsize="32"/>
+ <reg name="vlenb" bitsize="32"/>
</feature>
diff --git a/gdb-xml/riscv-64bit-csr.xml b/gdb-xml/riscv-64bit-csr.xml
index 9039456293..28a7c9a9f3 100644
--- a/gdb-xml/riscv-64bit-csr.xml
+++ b/gdb-xml/riscv-64bit-csr.xml
@@ -248,4 +248,11 @@
<reg name="mucounteren" bitsize="64"/>
<reg name="mscounteren" bitsize="64"/>
<reg name="mhcounteren" bitsize="64"/>
+ <reg name="vstart" bitsize="64"/>
+ <reg name="vxsat" bitsize="64"/>
+ <reg name="vxrm" bitsize="64"/>
+ <reg name="vcsr" bitsize="64"/>
+ <reg name="vl" bitsize="64"/>
+ <reg name="vtype" bitsize="64"/>
+ <reg name="vlenb" bitsize="64"/>
</feature>
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 17c138bb90..b6cd217054 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -556,6 +556,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
#elif defined(TARGET_RISCV64)
cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
#endif
+ cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
cc->gdb_stop_before_watchpoint = true;
cc->disas_set_info = riscv_cpu_disas_set_info;
#ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ca78b7f352..12f11fc2a1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -102,6 +102,16 @@ FIELD(VTYPE, VEDIV, 8, 2)
FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
+/**
+ * DynamicGDBXMLInfo:
+ * @desc: Contains the XML descriptions.
+ * @num: Number of the registers in this XML seen by GDB.
+ */
+typedef struct DynamicGDBXMLInfo {
+ char *desc;
+ int num;
+} DynamicGDBXMLInfo;
+
struct CPURISCVState {
target_ulong gpr[32];
uint64_t fpr[32]; /* assume both F and D extensions */
@@ -296,6 +306,8 @@ typedef struct RISCVCPU {
bool pmp;
uint64_t resetvec;
} cfg;
+
+ DynamicGDBXMLInfo dyn_vreg_xml;
} RISCVCPU;
static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
@@ -489,6 +501,19 @@ typedef struct {
void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
+/*
+ * Helpers to dynamically generates XML descriptions of the
+ * vector registers. Returns the number of registers in each set.
+ */
+int ricsv_gen_dynamic_vector_xml(CPUState *cpu, int base_reg);
+
+/*
+ * Returns the dynamically generated XML for the gdb stub.
+ * Returns a pointer to the XML contents for the specified XML file or NULL
+ * if the XML name doesn't match the predefined one.
+ */
+const char *riscv_gdb_get_dynamic_xml(CPUState *cpu, const char *xmlname);
+
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
#endif /* RISCV_CPU_H */
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index f7c5212e27..41e686265d 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -268,6 +268,39 @@ static int csr_register_map[] = {
CSR_MUCOUNTEREN,
CSR_MSCOUNTEREN,
CSR_MHCOUNTEREN,
+ CSR_VSTART,
+ CSR_VXSAT,
+ CSR_VXRM,
+ CSR_VCSR,
+ CSR_VL,
+ CSR_VTYPE,
+ CSR_VLENB,
+};
+
+struct TypeSize {
+ const char *gdb_type;
+ const char *id;
+ int size;
+ const char suffix;
+};
+
+static const struct TypeSize vec_lanes[] = {
+ /* quads */
+ { "uint128", "quads", 128, 'q' },
+ /* 64 bit */
+ { "uint64", "longs", 64, 'l' },
+ /* 32 bit */
+ { "uint32", "words", 32, 'w' },
+ /* 16 bit */
+ { "uint16", "shorts", 16, 's' },
+ /*
+ * TODO: currently there is no reliable way of telling
+ * if the remote gdb actually understands ieee_half so
+ * we don't expose it in the target description for now.
+ * { "ieee_half", 16, 'h', 'f' },
+ */
+ /* bytes */
+ { "uint8", "bytes", 8, 'b' },
};
int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
@@ -351,6 +384,65 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t
*mem_buf, int n)
return 0;
}
+static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
+{
+ uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+ if (n < 32) {
+ int i;
+ int cnt = 0;
+ for (i = 0; i < vlenb; i += 8) {
+ cnt += gdb_get_reg64(buf,
+ env->vreg[(n * vlenb + i) / 8]);
+ }
+ return cnt;
+ } else if (n >= 32 && n <= 38) {
+ int csrno;
+ switch (n) {
+ case 32:
+ csrno = CSR_VSTART;
+ break;
+ case 33:
+ csrno = CSR_VXSAT;
+ break;
+ case 34:
+ csrno = CSR_VXRM;
+ break;
+ case 35:
+ csrno = CSR_VCSR;
+ break;
+ case 36:
+ csrno = CSR_VL;
+ break;
+ case 37:
+ csrno = CSR_VTYPE;
+ break;
+ case 38:
+ csrno = CSR_VLENB;
+ break;
+ }
+
+ target_ulong val = 0;
+ int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
+ if (result == 0) {
+ return gdb_get_regl(buf, val);
+ }
+ }
+ return 0;
+}
+
+static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
+{
+ uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+ if (n < 32) {
+ int i;
+ for (i = 0; i < vlenb; i += 8) {
+ env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
+ }
+ return vlenb;
+ }
+ return 0;
+}
+
static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
{
if (n < ARRAY_SIZE(csr_register_map)) {
@@ -405,6 +497,66 @@ static int riscv_gdb_set_virtual(CPURISCVState *cs,
uint8_t *mem_buf, int n)
return 0;
}
+int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
+{
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ GString *s = g_string_new(NULL);
+ DynamicGDBXMLInfo *info = &cpu->dyn_vreg_xml;
+ g_autoptr(GString) ts = g_string_new("");
+ int i, reg_width = cpu->cfg.vlen;
+ info->num = 0;
+ g_string_printf(s, "<?xml version=\"1.0\"?>");
+ g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
+ g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.vector\">");
+
+ /* First define types and totals in a whole VL */
+ for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
+ int count = reg_width / vec_lanes[i].size;
+ g_string_printf(ts, "%s", vec_lanes[i].id);
+ g_string_append_printf(s,
+ "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
+ ts->str, vec_lanes[i].gdb_type, count);
+ }
+
+ /* Define unions */
+ g_string_append_printf(s, "<union id=\"riscv_vector\">");
+ for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
+ g_string_append_printf(s, "<field name=\"%c\" type=\"%s\"/>",
+ vec_lanes[i].suffix,
+ vec_lanes[i].id);
+ }
+ g_string_append(s, "</union>");
+
+ /* Define vector registers */
+ for (i = 0; i < 32; i++) {
+ g_string_append_printf(s,
+ "<reg name=\"v%d\" bitsize=\"%d\""
+ " regnum=\"%d\" group=\"vector\""
+ " type=\"riscv_vector\"/>",
+ i, reg_width, base_reg++);
+ info->num++;
+ }
+
+ /* Define vector CSRs */
+ const char *vector_csrs[7] = {
+ "vstart", "vxsat", "vxrm", "vcsr",
+ "vl", "vtype", "vlenb"
+ };
+
+ for (i = 0; i < 7; i++) {
+ g_string_append_printf(s,
+ "<reg name=\"%s\" bitsize=\"%d\""
+ " regnum=\"%d\" group=\"vector\""
+ " type=\"int\"/>",
+ vector_csrs[i], TARGET_LONG_BITS, base_reg++);
+ info->num++;
+ }
+
+ g_string_append_printf(s, "</feature>");
+ cpu->dyn_vreg_xml.desc = g_string_free(s, false);
+ return cpu->dyn_vreg_xml.num;
+}
+
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
{
RISCVCPU *cpu = RISCV_CPU(cs);
@@ -416,17 +568,33 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState
*cs)
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
36, "riscv-32bit-fpu.xml", 0);
}
+ if (env->misa & RVV) {
+ gdb_register_coprocessor(cs, riscv_gdb_get_vector,
riscv_gdb_set_vector,
+ ricsv_gen_dynamic_vector_xml(cs,
+
cs->gdb_num_regs),
+ "riscv-vector.xml", 0);
+ }
#if defined(TARGET_RISCV32)
gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
- 241, "riscv-32bit-csr.xml", 0);
+ 248, "riscv-32bit-csr.xml", 0);
gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
1, "riscv-32bit-virtual.xml", 0);
#elif defined(TARGET_RISCV64)
gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
- 241, "riscv-64bit-csr.xml", 0);
+ 248, "riscv-64bit-csr.xml", 0);
gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
1, "riscv-64bit-virtual.xml", 0);
#endif
}
+
+const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
+{
+ RISCVCPU *cpu = RISCV_CPU(cs);
+
+ if (strcmp(xmlname, "riscv-vector.xml") == 0) {
+ return cpu->dyn_vreg_xml.desc;
+ }
+ return NULL;
+}
--
2.17.1
- [RFC v5 56/68] target/riscv: rvv-1.0: remove vmford.vv and vmford.vf, (continued)
- [RFC v5 56/68] target/riscv: rvv-1.0: remove vmford.vv and vmford.vf, frank . chang, 2020/09/29
- [RFC v5 57/68] target/riscv: rvv-1.0: remove integer extract instruction, frank . chang, 2020/09/29
- [RFC v5 58/68] target/riscv: rvv-1.0: floating-point min/max instructions, frank . chang, 2020/09/29
- [RFC v5 59/68] target/riscv: introduce floating-point rounding mode enum, frank . chang, 2020/09/29
- [RFC v5 60/68] target/riscv: rvv-1.0: floating-point/integer type-convert instructions, frank . chang, 2020/09/29
- [RFC v5 61/68] target/riscv: rvv-1.0: widening floating-point/integer type-convert, frank . chang, 2020/09/29
- [RFC v5 62/68] target/riscv: add "set round to odd" rounding mode helper function, frank . chang, 2020/09/29
- [RFC v5 63/68] target/riscv: rvv-1.0: narrowing floating-point/integer type-convert, frank . chang, 2020/09/29
- [RFC v5 64/68] target/riscv: rvv-1.0: relax RV_VLEN_MAX to 1024-bits, frank . chang, 2020/09/29
- [RFC v5 65/68] target/riscv: gdb: modify gdb csr xml file to align with csr register map, frank . chang, 2020/09/29
- [RFC v5 66/68] target/riscv: gdb: support vector registers for rv64 & rv32,
frank . chang <=
- [RFC v5 68/68] target/riscv: trigger illegal instruction exception if frm is not valid, frank . chang, 2020/09/29
- [RFC v5 67/68] target/riscv: implement vstart CSR, frank . chang, 2020/09/29