123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- From 2b5684000804bcda8519d35e51e015d436ac9c02 Mon Sep 17 00:00:00 2001
- From: Hsiangkai Wang <kai.wang@sifive.com>
- Date: Tue, 12 Jan 2021 16:44:49 +0800
- Subject: [PATCH 076/107] target/riscv: gdb: support vector registers for rv64
- & rv32
- 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>
- ---
- target/riscv/cpu.c | 2 +
- target/riscv/cpu.h | 1 +
- target/riscv/gdbstub.c | 184 +++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 187 insertions(+)
- diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
- index 4a29175e20..f6d79c5aa9 100644
- --- a/target/riscv/cpu.c
- +++ b/target/riscv/cpu.c
- @@ -577,6 +577,8 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
-
- if (strcmp(xmlname, "riscv-csr.xml") == 0) {
- return cpu->dyn_csr_xml;
- + } else if (strcmp(xmlname, "riscv-vector.xml") == 0) {
- + return cpu->dyn_vreg_xml;
- }
-
- return NULL;
- diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
- index d613520211..e223ab550b 100644
- --- a/target/riscv/cpu.h
- +++ b/target/riscv/cpu.h
- @@ -279,6 +279,7 @@ struct RISCVCPU {
- CPURISCVState env;
-
- char *dyn_csr_xml;
- + char *dyn_vreg_xml;
-
- /* Configuration Settings */
- struct {
- diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
- index 5f96b7ea2a..dd883612c7 100644
- --- a/target/riscv/gdbstub.c
- +++ b/target/riscv/gdbstub.c
- @@ -20,6 +20,32 @@
- #include "exec/gdbstub.h"
- #include "cpu.h"
-
- +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)
- {
- RISCVCPU *cpu = RISCV_CPU(cs);
- @@ -101,6 +127,96 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
- return 0;
- }
-
- +/*
- + * Convert register index number passed by GDB to the correspond
- + * vector CSR number. Vector CSRs are defined after vector registers
- + * in dynamic generated riscv-vector.xml, thus the starting register index
- + * of vector CSRs is 32.
- + * Return 0 if register index number is out of range.
- + */
- +static int riscv_gdb_vector_csrno(int num_regs)
- +{
- + /*
- + * The order of vector CSRs in the switch case
- + * should match with the order defined in csr_ops[].
- + */
- + switch (num_regs) {
- + case 32:
- + return CSR_VSTART;
- + case 33:
- + return CSR_VXSAT;
- + case 34:
- + return CSR_VXRM;
- + case 35:
- + return CSR_VCSR;
- + case 36:
- + return CSR_VL;
- + case 37:
- + return CSR_VTYPE;
- + case 38:
- + return CSR_VLENB;
- + default:
- + /* Unknown register. */
- + 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;
- + }
- +
- + int csrno = riscv_gdb_vector_csrno(n);
- +
- + if (!csrno) {
- + return 0;
- + }
- +
- + 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;
- + }
- +
- + int csrno = riscv_gdb_vector_csrno(n);
- +
- + if (!csrno) {
- + return 0;
- + }
- +
- + target_ulong val = ldtul_p(mem_buf);
- + int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
- +
- + if (result == 0) {
- + return sizeof(target_ulong);
- + }
- +
- + return 0;
- +}
- +
- static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
- {
- if (n < CSR_TABLE_SIZE) {
- @@ -187,6 +303,68 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
- return CSR_TABLE_SIZE;
- }
-
- +static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
- +{
- + RISCVCPU *cpu = RISCV_CPU(cs);
- + GString *s = g_string_new(NULL);
- + g_autoptr(GString) ts = g_string_new("");
- + int reg_width = cpu->cfg.vlen;
- + int num_regs = 0;
- + int i;
- +
- + 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++);
- + num_regs++;
- + }
- +
- + /* 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++);
- + num_regs++;
- + }
- +
- + g_string_append_printf(s, "</feature>");
- +
- + cpu->dyn_vreg_xml = g_string_free(s, false);
- + return num_regs;
- +}
- +
- void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
- {
- RISCVCPU *cpu = RISCV_CPU(cs);
- @@ -198,6 +376,12 @@ 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_virtual, riscv_gdb_set_virtual,
- 1, "riscv-32bit-virtual.xml", 0);
- --
- 2.33.1
|