xref: /openbmc/qemu/target/riscv/gdbstub.c (revision 583edc4e)
19438fe7dSMichael Clark /*
29438fe7dSMichael Clark  * RISC-V GDB Server Stub
39438fe7dSMichael Clark  *
49438fe7dSMichael Clark  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
59438fe7dSMichael Clark  *
69438fe7dSMichael Clark  * This program is free software; you can redistribute it and/or modify it
79438fe7dSMichael Clark  * under the terms and conditions of the GNU General Public License,
89438fe7dSMichael Clark  * version 2 or later, as published by the Free Software Foundation.
99438fe7dSMichael Clark  *
109438fe7dSMichael Clark  * This program is distributed in the hope it will be useful, but WITHOUT
119438fe7dSMichael Clark  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
129438fe7dSMichael Clark  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
139438fe7dSMichael Clark  * more details.
149438fe7dSMichael Clark  *
159438fe7dSMichael Clark  * You should have received a copy of the GNU General Public License along with
169438fe7dSMichael Clark  * this program.  If not, see <http://www.gnu.org/licenses/>.
179438fe7dSMichael Clark  */
189438fe7dSMichael Clark 
199438fe7dSMichael Clark #include "qemu/osdep.h"
209438fe7dSMichael Clark #include "exec/gdbstub.h"
214ea5fe99SAlex Bennée #include "gdbstub/helpers.h"
229438fe7dSMichael Clark #include "cpu.h"
239438fe7dSMichael Clark 
24719d3561SHsiangkai Wang struct TypeSize {
25719d3561SHsiangkai Wang     const char *gdb_type;
26719d3561SHsiangkai Wang     const char *id;
27719d3561SHsiangkai Wang     int size;
28719d3561SHsiangkai Wang     const char suffix;
29719d3561SHsiangkai Wang };
30719d3561SHsiangkai Wang 
31719d3561SHsiangkai Wang static const struct TypeSize vec_lanes[] = {
32719d3561SHsiangkai Wang     /* quads */
33719d3561SHsiangkai Wang     { "uint128", "quads", 128, 'q' },
34719d3561SHsiangkai Wang     /* 64 bit */
35719d3561SHsiangkai Wang     { "uint64", "longs", 64, 'l' },
36719d3561SHsiangkai Wang     /* 32 bit */
37719d3561SHsiangkai Wang     { "uint32", "words", 32, 'w' },
38719d3561SHsiangkai Wang     /* 16 bit */
39719d3561SHsiangkai Wang     { "uint16", "shorts", 16, 's' },
40719d3561SHsiangkai Wang     /*
41719d3561SHsiangkai Wang      * TODO: currently there is no reliable way of telling
42719d3561SHsiangkai Wang      * if the remote gdb actually understands ieee_half so
43719d3561SHsiangkai Wang      * we don't expose it in the target description for now.
44719d3561SHsiangkai Wang      * { "ieee_half", 16, 'h', 'f' },
45719d3561SHsiangkai Wang      */
46719d3561SHsiangkai Wang     /* bytes */
47719d3561SHsiangkai Wang     { "uint8", "bytes", 8, 'b' },
48719d3561SHsiangkai Wang };
49719d3561SHsiangkai Wang 
riscv_cpu_gdb_read_register(CPUState * cs,GByteArray * mem_buf,int n)50a010bdbeSAlex Bennée int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
519438fe7dSMichael Clark {
52742cc269SAkihiko Odaki     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
539438fe7dSMichael Clark     RISCVCPU *cpu = RISCV_CPU(cs);
549438fe7dSMichael Clark     CPURISCVState *env = &cpu->env;
551191be09SLIU Zhiwei     target_ulong tmp;
569438fe7dSMichael Clark 
579438fe7dSMichael Clark     if (n < 32) {
581191be09SLIU Zhiwei         tmp = env->gpr[n];
599438fe7dSMichael Clark     } else if (n == 32) {
601191be09SLIU Zhiwei         tmp = env->pc;
611191be09SLIU Zhiwei     } else {
621191be09SLIU Zhiwei         return 0;
631191be09SLIU Zhiwei     }
641191be09SLIU Zhiwei 
65742cc269SAkihiko Odaki     switch (mcc->misa_mxl_max) {
661191be09SLIU Zhiwei     case MXL_RV32:
671191be09SLIU Zhiwei         return gdb_get_reg32(mem_buf, tmp);
681191be09SLIU Zhiwei     case MXL_RV64:
696c3a9247SFrédéric Pétrot     case MXL_RV128:
701191be09SLIU Zhiwei         return gdb_get_reg64(mem_buf, tmp);
711191be09SLIU Zhiwei     default:
721191be09SLIU Zhiwei         g_assert_not_reached();
739438fe7dSMichael Clark     }
749438fe7dSMichael Clark     return 0;
759438fe7dSMichael Clark }
769438fe7dSMichael Clark 
riscv_cpu_gdb_write_register(CPUState * cs,uint8_t * mem_buf,int n)779438fe7dSMichael Clark int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
789438fe7dSMichael Clark {
79742cc269SAkihiko Odaki     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
809438fe7dSMichael Clark     RISCVCPU *cpu = RISCV_CPU(cs);
819438fe7dSMichael Clark     CPURISCVState *env = &cpu->env;
821191be09SLIU Zhiwei     int length = 0;
831191be09SLIU Zhiwei     target_ulong tmp;
849438fe7dSMichael Clark 
85742cc269SAkihiko Odaki     switch (mcc->misa_mxl_max) {
861191be09SLIU Zhiwei     case MXL_RV32:
871191be09SLIU Zhiwei         tmp = (int32_t)ldl_p(mem_buf);
881191be09SLIU Zhiwei         length = 4;
891191be09SLIU Zhiwei         break;
901191be09SLIU Zhiwei     case MXL_RV64:
916c3a9247SFrédéric Pétrot     case MXL_RV128:
921191be09SLIU Zhiwei         if (env->xl < MXL_RV64) {
931191be09SLIU Zhiwei             tmp = (int32_t)ldq_p(mem_buf);
941191be09SLIU Zhiwei         } else {
951191be09SLIU Zhiwei             tmp = ldq_p(mem_buf);
965371f5cdSJim Wilson         }
971191be09SLIU Zhiwei         length = 8;
981191be09SLIU Zhiwei         break;
991191be09SLIU Zhiwei     default:
1001191be09SLIU Zhiwei         g_assert_not_reached();
1011191be09SLIU Zhiwei     }
1021191be09SLIU Zhiwei     if (n > 0 && n < 32) {
1031191be09SLIU Zhiwei         env->gpr[n] = tmp;
1041191be09SLIU Zhiwei     } else if (n == 32) {
1051191be09SLIU Zhiwei         env->pc = tmp;
1061191be09SLIU Zhiwei     }
1071191be09SLIU Zhiwei 
1081191be09SLIU Zhiwei     return length;
1095371f5cdSJim Wilson }
1105371f5cdSJim Wilson 
riscv_gdb_get_fpu(CPUState * cs,GByteArray * buf,int n)11166260159SAkihiko Odaki static int riscv_gdb_get_fpu(CPUState *cs, GByteArray *buf, int n)
1125371f5cdSJim Wilson {
11366260159SAkihiko Odaki     RISCVCPU *cpu = RISCV_CPU(cs);
11466260159SAkihiko Odaki     CPURISCVState *env = &cpu->env;
11566260159SAkihiko Odaki 
1165371f5cdSJim Wilson     if (n < 32) {
117e91a7227SRichard Henderson         if (env->misa_ext & RVD) {
118a010bdbeSAlex Bennée             return gdb_get_reg64(buf, env->fpr[n]);
119ae4a70c0SKeith Packard         }
120e91a7227SRichard Henderson         if (env->misa_ext & RVF) {
121a010bdbeSAlex Bennée             return gdb_get_reg32(buf, env->fpr[n]);
122ae4a70c0SKeith Packard         }
1235371f5cdSJim Wilson     }
1245371f5cdSJim Wilson     return 0;
1255371f5cdSJim Wilson }
1265371f5cdSJim Wilson 
riscv_gdb_set_fpu(CPUState * cs,uint8_t * mem_buf,int n)12766260159SAkihiko Odaki static int riscv_gdb_set_fpu(CPUState *cs, uint8_t *mem_buf, int n)
1285371f5cdSJim Wilson {
12966260159SAkihiko Odaki     RISCVCPU *cpu = RISCV_CPU(cs);
13066260159SAkihiko Odaki     CPURISCVState *env = &cpu->env;
13166260159SAkihiko Odaki 
1325371f5cdSJim Wilson     if (n < 32) {
1335371f5cdSJim Wilson         env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
1349438fe7dSMichael Clark         return sizeof(uint64_t);
1359438fe7dSMichael Clark     }
1369438fe7dSMichael Clark     return 0;
1379438fe7dSMichael Clark }
1385371f5cdSJim Wilson 
riscv_gdb_get_vector(CPUState * cs,GByteArray * buf,int n)13966260159SAkihiko Odaki static int riscv_gdb_get_vector(CPUState *cs, GByteArray *buf, int n)
140719d3561SHsiangkai Wang {
14166260159SAkihiko Odaki     RISCVCPU *cpu = RISCV_CPU(cs);
14266260159SAkihiko Odaki     CPURISCVState *env = &cpu->env;
14366260159SAkihiko Odaki     uint16_t vlenb = cpu->cfg.vlenb;
144719d3561SHsiangkai Wang     if (n < 32) {
145719d3561SHsiangkai Wang         int i;
146719d3561SHsiangkai Wang         int cnt = 0;
147719d3561SHsiangkai Wang         for (i = 0; i < vlenb; i += 8) {
148719d3561SHsiangkai Wang             cnt += gdb_get_reg64(buf,
149719d3561SHsiangkai Wang                                  env->vreg[(n * vlenb + i) / 8]);
150719d3561SHsiangkai Wang         }
151719d3561SHsiangkai Wang         return cnt;
152719d3561SHsiangkai Wang     }
153719d3561SHsiangkai Wang 
154719d3561SHsiangkai Wang     return 0;
155719d3561SHsiangkai Wang }
156719d3561SHsiangkai Wang 
riscv_gdb_set_vector(CPUState * cs,uint8_t * mem_buf,int n)15766260159SAkihiko Odaki static int riscv_gdb_set_vector(CPUState *cs, uint8_t *mem_buf, int n)
158719d3561SHsiangkai Wang {
15966260159SAkihiko Odaki     RISCVCPU *cpu = RISCV_CPU(cs);
16066260159SAkihiko Odaki     CPURISCVState *env = &cpu->env;
16166260159SAkihiko Odaki     uint16_t vlenb = cpu->cfg.vlenb;
162719d3561SHsiangkai Wang     if (n < 32) {
163719d3561SHsiangkai Wang         int i;
164719d3561SHsiangkai Wang         for (i = 0; i < vlenb; i += 8) {
165719d3561SHsiangkai Wang             env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
166719d3561SHsiangkai Wang         }
167719d3561SHsiangkai Wang         return vlenb;
168719d3561SHsiangkai Wang     }
169719d3561SHsiangkai Wang 
170719d3561SHsiangkai Wang     return 0;
171719d3561SHsiangkai Wang }
172719d3561SHsiangkai Wang 
riscv_gdb_get_csr(CPUState * cs,GByteArray * buf,int n)17366260159SAkihiko Odaki static int riscv_gdb_get_csr(CPUState *cs, GByteArray *buf, int n)
1745371f5cdSJim Wilson {
17566260159SAkihiko Odaki     RISCVCPU *cpu = RISCV_CPU(cs);
17666260159SAkihiko Odaki     CPURISCVState *env = &cpu->env;
17766260159SAkihiko Odaki 
178b93777e1SBin Meng     if (n < CSR_TABLE_SIZE) {
1795371f5cdSJim Wilson         target_ulong val = 0;
1805371f5cdSJim Wilson         int result;
1815371f5cdSJim Wilson 
182b93777e1SBin Meng         result = riscv_csrrw_debug(env, n, &val, 0, 0);
183533c91e8SAlistair Francis         if (result == RISCV_EXCP_NONE) {
184a010bdbeSAlex Bennée             return gdb_get_regl(buf, val);
1855371f5cdSJim Wilson         }
1865371f5cdSJim Wilson     }
1875371f5cdSJim Wilson     return 0;
1885371f5cdSJim Wilson }
1895371f5cdSJim Wilson 
riscv_gdb_set_csr(CPUState * cs,uint8_t * mem_buf,int n)19066260159SAkihiko Odaki static int riscv_gdb_set_csr(CPUState *cs, uint8_t *mem_buf, int n)
1915371f5cdSJim Wilson {
19266260159SAkihiko Odaki     RISCVCPU *cpu = RISCV_CPU(cs);
19366260159SAkihiko Odaki     CPURISCVState *env = &cpu->env;
19466260159SAkihiko Odaki 
195b93777e1SBin Meng     if (n < CSR_TABLE_SIZE) {
1965371f5cdSJim Wilson         target_ulong val = ldtul_p(mem_buf);
1975371f5cdSJim Wilson         int result;
1985371f5cdSJim Wilson 
199b93777e1SBin Meng         result = riscv_csrrw_debug(env, n, NULL, val, -1);
200533c91e8SAlistair Francis         if (result == RISCV_EXCP_NONE) {
2015371f5cdSJim Wilson             return sizeof(target_ulong);
2025371f5cdSJim Wilson         }
2035371f5cdSJim Wilson     }
2045371f5cdSJim Wilson     return 0;
2055371f5cdSJim Wilson }
2065371f5cdSJim Wilson 
riscv_gdb_get_virtual(CPUState * cs,GByteArray * buf,int n)20766260159SAkihiko Odaki static int riscv_gdb_get_virtual(CPUState *cs, GByteArray *buf, int n)
208ab9056ffSJonathan Behrens {
209ab9056ffSJonathan Behrens     if (n == 0) {
210ab9056ffSJonathan Behrens #ifdef CONFIG_USER_ONLY
211a010bdbeSAlex Bennée         return gdb_get_regl(buf, 0);
212ab9056ffSJonathan Behrens #else
21366260159SAkihiko Odaki         RISCVCPU *cpu = RISCV_CPU(cs);
21466260159SAkihiko Odaki         CPURISCVState *env = &cpu->env;
21566260159SAkihiko Odaki 
21666260159SAkihiko Odaki         return gdb_get_regl(buf, env->priv);
217ab9056ffSJonathan Behrens #endif
218ab9056ffSJonathan Behrens     }
219ab9056ffSJonathan Behrens     return 0;
220ab9056ffSJonathan Behrens }
221ab9056ffSJonathan Behrens 
riscv_gdb_set_virtual(CPUState * cs,uint8_t * mem_buf,int n)22266260159SAkihiko Odaki static int riscv_gdb_set_virtual(CPUState *cs, uint8_t *mem_buf, int n)
223ab9056ffSJonathan Behrens {
22481d2929cSJonathan Behrens     if (n == 0) {
22581d2929cSJonathan Behrens #ifndef CONFIG_USER_ONLY
22666260159SAkihiko Odaki         RISCVCPU *cpu = RISCV_CPU(cs);
22766260159SAkihiko Odaki         CPURISCVState *env = &cpu->env;
22866260159SAkihiko Odaki 
22966260159SAkihiko Odaki         env->priv = ldtul_p(mem_buf) & 0x3;
23066260159SAkihiko Odaki         if (env->priv == PRV_RESERVED) {
23166260159SAkihiko Odaki             env->priv = PRV_S;
23281d2929cSJonathan Behrens         }
23381d2929cSJonathan Behrens #endif
23481d2929cSJonathan Behrens         return sizeof(target_ulong);
23581d2929cSJonathan Behrens     }
236ab9056ffSJonathan Behrens     return 0;
237ab9056ffSJonathan Behrens }
238ab9056ffSJonathan Behrens 
riscv_gen_dynamic_csr_feature(CPUState * cs,int base_reg)23933a24910SAkihiko Odaki static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
240b93777e1SBin Meng {
241742cc269SAkihiko Odaki     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
242b93777e1SBin Meng     RISCVCPU *cpu = RISCV_CPU(cs);
243b93777e1SBin Meng     CPURISCVState *env = &cpu->env;
24433a24910SAkihiko Odaki     GDBFeatureBuilder builder;
245b93777e1SBin Meng     riscv_csr_predicate_fn predicate;
246afa42c21SConor Dooley     int bitsize = riscv_cpu_max_xlen(mcc);
24733a24910SAkihiko Odaki     const char *name;
248b93777e1SBin Meng     int i;
249b93777e1SBin Meng 
250a1f0083cSBin Meng #if !defined(CONFIG_USER_ONLY)
251a1f0083cSBin Meng     env->debugger = true;
252a1f0083cSBin Meng #endif
253a1f0083cSBin Meng 
254332dab68SFrédéric Pétrot     /* Until gdb knows about 128-bit registers */
255332dab68SFrédéric Pétrot     if (bitsize > 64) {
256332dab68SFrédéric Pétrot         bitsize = 64;
257332dab68SFrédéric Pétrot     }
258332dab68SFrédéric Pétrot 
25933a24910SAkihiko Odaki     gdb_feature_builder_init(&builder, &cpu->dyn_csr_feature,
26033a24910SAkihiko Odaki                              "org.gnu.gdb.riscv.csr", "riscv-csr.xml",
26133a24910SAkihiko Odaki                              base_reg);
262b93777e1SBin Meng 
263b93777e1SBin Meng     for (i = 0; i < CSR_TABLE_SIZE; i++) {
2640bc71ee0SBin Meng         if (env->priv_ver < csr_ops[i].min_priv_ver) {
2650bc71ee0SBin Meng             continue;
2660bc71ee0SBin Meng         }
267b93777e1SBin Meng         predicate = csr_ops[i].predicate;
26879a41289SBin Meng         if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
26933a24910SAkihiko Odaki             name = csr_ops[i].name;
27033a24910SAkihiko Odaki             if (!name) {
271eb37086fSAkihiko Odaki                 name = g_strdup_printf("csr%03x", i);
272b93777e1SBin Meng             }
27333a24910SAkihiko Odaki 
27433a24910SAkihiko Odaki             gdb_feature_builder_append_reg(&builder, name, bitsize, i,
27533a24910SAkihiko Odaki                                            "int", NULL);
276b93777e1SBin Meng         }
277b93777e1SBin Meng     }
278b93777e1SBin Meng 
27933a24910SAkihiko Odaki     gdb_feature_builder_end(&builder);
280a1f0083cSBin Meng 
281a1f0083cSBin Meng #if !defined(CONFIG_USER_ONLY)
282a1f0083cSBin Meng     env->debugger = false;
283a1f0083cSBin Meng #endif
284a1f0083cSBin Meng 
28533a24910SAkihiko Odaki     return &cpu->dyn_csr_feature;
286b93777e1SBin Meng }
287b93777e1SBin Meng 
ricsv_gen_dynamic_vector_feature(CPUState * cs,int base_reg)28833a24910SAkihiko Odaki static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
289719d3561SHsiangkai Wang {
290719d3561SHsiangkai Wang     RISCVCPU *cpu = RISCV_CPU(cs);
291*583edc4eSDaniel Henrique Barboza     int bitsize = cpu->cfg.vlenb << 3;
29233a24910SAkihiko Odaki     GDBFeatureBuilder builder;
293719d3561SHsiangkai Wang     int i;
294719d3561SHsiangkai Wang 
29533a24910SAkihiko Odaki     gdb_feature_builder_init(&builder, &cpu->dyn_vreg_feature,
29633a24910SAkihiko Odaki                              "org.gnu.gdb.riscv.vector", "riscv-vector.xml",
29733a24910SAkihiko Odaki                              base_reg);
298719d3561SHsiangkai Wang 
299719d3561SHsiangkai Wang     /* First define types and totals in a whole VL */
300719d3561SHsiangkai Wang     for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
301*583edc4eSDaniel Henrique Barboza         int count = bitsize / vec_lanes[i].size;
30233a24910SAkihiko Odaki         gdb_feature_builder_append_tag(
30333a24910SAkihiko Odaki             &builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
30433a24910SAkihiko Odaki             vec_lanes[i].id, vec_lanes[i].gdb_type, count);
305719d3561SHsiangkai Wang     }
306719d3561SHsiangkai Wang 
307719d3561SHsiangkai Wang     /* Define unions */
30833a24910SAkihiko Odaki     gdb_feature_builder_append_tag(&builder, "<union id=\"riscv_vector\">");
309719d3561SHsiangkai Wang     for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
31033a24910SAkihiko Odaki         gdb_feature_builder_append_tag(&builder,
31133a24910SAkihiko Odaki                                        "<field name=\"%c\" type=\"%s\"/>",
31233a24910SAkihiko Odaki                                        vec_lanes[i].suffix, vec_lanes[i].id);
313719d3561SHsiangkai Wang     }
31433a24910SAkihiko Odaki     gdb_feature_builder_append_tag(&builder, "</union>");
315719d3561SHsiangkai Wang 
316719d3561SHsiangkai Wang     /* Define vector registers */
317719d3561SHsiangkai Wang     for (i = 0; i < 32; i++) {
31833a24910SAkihiko Odaki         gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
319*583edc4eSDaniel Henrique Barboza                                        bitsize, i, "riscv_vector", "vector");
320719d3561SHsiangkai Wang     }
321719d3561SHsiangkai Wang 
32233a24910SAkihiko Odaki     gdb_feature_builder_end(&builder);
323719d3561SHsiangkai Wang 
32433a24910SAkihiko Odaki     return &cpu->dyn_vreg_feature;
325719d3561SHsiangkai Wang }
326719d3561SHsiangkai Wang 
riscv_cpu_register_gdb_regs_for_features(CPUState * cs)3275371f5cdSJim Wilson void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
3285371f5cdSJim Wilson {
329742cc269SAkihiko Odaki     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
3305371f5cdSJim Wilson     RISCVCPU *cpu = RISCV_CPU(cs);
3315371f5cdSJim Wilson     CPURISCVState *env = &cpu->env;
332e91a7227SRichard Henderson     if (env->misa_ext & RVD) {
333ae4a70c0SKeith Packard         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
334ac1e8671SAkihiko Odaki                                  gdb_find_static_feature("riscv-64bit-fpu.xml"),
335ac1e8671SAkihiko Odaki                                  0);
336e91a7227SRichard Henderson     } else if (env->misa_ext & RVF) {
3375371f5cdSJim Wilson         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
338ac1e8671SAkihiko Odaki                                  gdb_find_static_feature("riscv-32bit-fpu.xml"),
339ac1e8671SAkihiko Odaki                                  0);
3405371f5cdSJim Wilson     }
3414a909912SJason Chien     if (cpu->cfg.ext_zve32x) {
342246f8796SWeiwei Li         gdb_register_coprocessor(cs, riscv_gdb_get_vector,
343246f8796SWeiwei Li                                  riscv_gdb_set_vector,
344ac1e8671SAkihiko Odaki                                  ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
345ac1e8671SAkihiko Odaki                                  0);
346719d3561SHsiangkai Wang     }
347742cc269SAkihiko Odaki     switch (mcc->misa_mxl_max) {
3481191be09SLIU Zhiwei     case MXL_RV32:
3491191be09SLIU Zhiwei         gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
3501191be09SLIU Zhiwei                                  riscv_gdb_set_virtual,
351ac1e8671SAkihiko Odaki                                  gdb_find_static_feature("riscv-32bit-virtual.xml"),
352ac1e8671SAkihiko Odaki                                  0);
3531191be09SLIU Zhiwei         break;
3541191be09SLIU Zhiwei     case MXL_RV64:
3556c3a9247SFrédéric Pétrot     case MXL_RV128:
3561191be09SLIU Zhiwei         gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
3571191be09SLIU Zhiwei                                  riscv_gdb_set_virtual,
358ac1e8671SAkihiko Odaki                                  gdb_find_static_feature("riscv-64bit-virtual.xml"),
359ac1e8671SAkihiko Odaki                                  0);
3601191be09SLIU Zhiwei         break;
3611191be09SLIU Zhiwei     default:
3621191be09SLIU Zhiwei         g_assert_not_reached();
3631191be09SLIU Zhiwei     }
364b93777e1SBin Meng 
365960b389bSDaniel Henrique Barboza     if (cpu->cfg.ext_zicsr) {
366b93777e1SBin Meng         gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
367ac1e8671SAkihiko Odaki                                  riscv_gen_dynamic_csr_feature(cs, cs->gdb_num_regs),
368ac1e8671SAkihiko Odaki                                  0);
3695371f5cdSJim Wilson     }
370e17e2c7cSBin Meng }
371