On Fri, Oct 29, 2021 at 8:24 PM <frank.ch...@sifive.com> wrote: > > From: Hsiangkai Wang <kai.w...@sifive.com> > > Signed-off-by: Hsiangkai Wang <kai.w...@sifive.com> > Signed-off-by: Greentime Hu <greentime...@sifive.com> > Signed-off-by: Frank Chang <frank.ch...@sifive.com>
Acked-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > 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 c760ea08621..860f356bd99 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -675,6 +675,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 5d93ccdfa71..dc10f27093b 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -291,6 +291,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 23429179e2e..881ab333924 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_ext & 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.25.1 > >