2 * RISC-V GDB Server Stub
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2 or later, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
20 #include "exec/gdbstub.h"
30 static const struct TypeSize vec_lanes
[] = {
32 { "uint128", "quads", 128, 'q' },
34 { "uint64", "longs", 64, 'l' },
36 { "uint32", "words", 32, 'w' },
38 { "uint16", "shorts", 16, 's' },
40 * TODO: currently there is no reliable way of telling
41 * if the remote gdb actually understands ieee_half so
42 * we don't expose it in the target description for now.
43 * { "ieee_half", 16, 'h', 'f' },
46 { "uint8", "bytes", 8, 'b' },
49 int riscv_cpu_gdb_read_register(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
51 RISCVCPU
*cpu
= RISCV_CPU(cs
);
52 CPURISCVState
*env
= &cpu
->env
;
63 switch (env
->misa_mxl_max
) {
65 return gdb_get_reg32(mem_buf
, tmp
);
68 return gdb_get_reg64(mem_buf
, tmp
);
70 g_assert_not_reached();
75 int riscv_cpu_gdb_write_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
77 RISCVCPU
*cpu
= RISCV_CPU(cs
);
78 CPURISCVState
*env
= &cpu
->env
;
82 switch (env
->misa_mxl_max
) {
84 tmp
= (int32_t)ldl_p(mem_buf
);
89 if (env
->xl
< MXL_RV64
) {
90 tmp
= (int32_t)ldq_p(mem_buf
);
97 g_assert_not_reached();
99 if (n
> 0 && n
< 32) {
101 } else if (n
== 32) {
108 static int riscv_gdb_get_fpu(CPURISCVState
*env
, GByteArray
*buf
, int n
)
111 if (env
->misa_ext
& RVD
) {
112 return gdb_get_reg64(buf
, env
->fpr
[n
]);
114 if (env
->misa_ext
& RVF
) {
115 return gdb_get_reg32(buf
, env
->fpr
[n
]);
121 static int riscv_gdb_set_fpu(CPURISCVState
*env
, uint8_t *mem_buf
, int n
)
124 env
->fpr
[n
] = ldq_p(mem_buf
); /* always 64-bit */
125 return sizeof(uint64_t);
130 static int riscv_gdb_get_vector(CPURISCVState
*env
, GByteArray
*buf
, int n
)
132 uint16_t vlenb
= env_archcpu(env
)->cfg
.vlen
>> 3;
136 for (i
= 0; i
< vlenb
; i
+= 8) {
137 cnt
+= gdb_get_reg64(buf
,
138 env
->vreg
[(n
* vlenb
+ i
) / 8]);
146 static int riscv_gdb_set_vector(CPURISCVState
*env
, uint8_t *mem_buf
, int n
)
148 uint16_t vlenb
= env_archcpu(env
)->cfg
.vlen
>> 3;
151 for (i
= 0; i
< vlenb
; i
+= 8) {
152 env
->vreg
[(n
* vlenb
+ i
) / 8] = ldq_p(mem_buf
+ i
);
160 static int riscv_gdb_get_csr(CPURISCVState
*env
, GByteArray
*buf
, int n
)
162 if (n
< CSR_TABLE_SIZE
) {
163 target_ulong val
= 0;
166 result
= riscv_csrrw_debug(env
, n
, &val
, 0, 0);
167 if (result
== RISCV_EXCP_NONE
) {
168 return gdb_get_regl(buf
, val
);
174 static int riscv_gdb_set_csr(CPURISCVState
*env
, uint8_t *mem_buf
, int n
)
176 if (n
< CSR_TABLE_SIZE
) {
177 target_ulong val
= ldtul_p(mem_buf
);
180 result
= riscv_csrrw_debug(env
, n
, NULL
, val
, -1);
181 if (result
== RISCV_EXCP_NONE
) {
182 return sizeof(target_ulong
);
188 static int riscv_gdb_get_virtual(CPURISCVState
*cs
, GByteArray
*buf
, int n
)
191 #ifdef CONFIG_USER_ONLY
192 return gdb_get_regl(buf
, 0);
194 return gdb_get_regl(buf
, cs
->priv
);
200 static int riscv_gdb_set_virtual(CPURISCVState
*cs
, uint8_t *mem_buf
, int n
)
203 #ifndef CONFIG_USER_ONLY
204 cs
->priv
= ldtul_p(mem_buf
) & 0x3;
205 if (cs
->priv
== PRV_H
) {
209 return sizeof(target_ulong
);
214 static int riscv_gen_dynamic_csr_xml(CPUState
*cs
, int base_reg
)
216 RISCVCPU
*cpu
= RISCV_CPU(cs
);
217 CPURISCVState
*env
= &cpu
->env
;
218 GString
*s
= g_string_new(NULL
);
219 riscv_csr_predicate_fn predicate
;
220 int bitsize
= 16 << env
->misa_mxl_max
;
223 #if !defined(CONFIG_USER_ONLY)
224 env
->debugger
= true;
227 /* Until gdb knows about 128-bit registers */
232 g_string_printf(s
, "<?xml version=\"1.0\"?>");
233 g_string_append_printf(s
, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
234 g_string_append_printf(s
, "<feature name=\"org.gnu.gdb.riscv.csr\">");
236 for (i
= 0; i
< CSR_TABLE_SIZE
; i
++) {
237 if (env
->priv_ver
< csr_ops
[i
].min_priv_ver
) {
240 predicate
= csr_ops
[i
].predicate
;
241 if (predicate
&& (predicate(env
, i
) == RISCV_EXCP_NONE
)) {
242 if (csr_ops
[i
].name
) {
243 g_string_append_printf(s
, "<reg name=\"%s\"", csr_ops
[i
].name
);
245 g_string_append_printf(s
, "<reg name=\"csr%03x\"", i
);
247 g_string_append_printf(s
, " bitsize=\"%d\"", bitsize
);
248 g_string_append_printf(s
, " regnum=\"%d\"/>", base_reg
+ i
);
252 g_string_append_printf(s
, "</feature>");
254 cpu
->dyn_csr_xml
= g_string_free(s
, false);
256 #if !defined(CONFIG_USER_ONLY)
257 env
->debugger
= false;
260 return CSR_TABLE_SIZE
;
263 static int ricsv_gen_dynamic_vector_xml(CPUState
*cs
, int base_reg
)
265 RISCVCPU
*cpu
= RISCV_CPU(cs
);
266 GString
*s
= g_string_new(NULL
);
267 g_autoptr(GString
) ts
= g_string_new("");
268 int reg_width
= cpu
->cfg
.vlen
;
272 g_string_printf(s
, "<?xml version=\"1.0\"?>");
273 g_string_append_printf(s
, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
274 g_string_append_printf(s
, "<feature name=\"org.gnu.gdb.riscv.vector\">");
276 /* First define types and totals in a whole VL */
277 for (i
= 0; i
< ARRAY_SIZE(vec_lanes
); i
++) {
278 int count
= reg_width
/ vec_lanes
[i
].size
;
279 g_string_printf(ts
, "%s", vec_lanes
[i
].id
);
280 g_string_append_printf(s
,
281 "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
282 ts
->str
, vec_lanes
[i
].gdb_type
, count
);
286 g_string_append_printf(s
, "<union id=\"riscv_vector\">");
287 for (i
= 0; i
< ARRAY_SIZE(vec_lanes
); i
++) {
288 g_string_append_printf(s
, "<field name=\"%c\" type=\"%s\"/>",
292 g_string_append(s
, "</union>");
294 /* Define vector registers */
295 for (i
= 0; i
< 32; i
++) {
296 g_string_append_printf(s
,
297 "<reg name=\"v%d\" bitsize=\"%d\""
298 " regnum=\"%d\" group=\"vector\""
299 " type=\"riscv_vector\"/>",
300 i
, reg_width
, base_reg
++);
304 g_string_append_printf(s
, "</feature>");
306 cpu
->dyn_vreg_xml
= g_string_free(s
, false);
310 void riscv_cpu_register_gdb_regs_for_features(CPUState
*cs
)
312 RISCVCPU
*cpu
= RISCV_CPU(cs
);
313 CPURISCVState
*env
= &cpu
->env
;
314 if (env
->misa_ext
& RVD
) {
315 gdb_register_coprocessor(cs
, riscv_gdb_get_fpu
, riscv_gdb_set_fpu
,
316 32, "riscv-64bit-fpu.xml", 0);
317 } else if (env
->misa_ext
& RVF
) {
318 gdb_register_coprocessor(cs
, riscv_gdb_get_fpu
, riscv_gdb_set_fpu
,
319 32, "riscv-32bit-fpu.xml", 0);
321 if (env
->misa_ext
& RVV
) {
322 int base_reg
= cs
->gdb_num_regs
;
323 gdb_register_coprocessor(cs
, riscv_gdb_get_vector
, riscv_gdb_set_vector
,
324 ricsv_gen_dynamic_vector_xml(cs
, base_reg
),
325 "riscv-vector.xml", 0);
327 switch (env
->misa_mxl_max
) {
329 gdb_register_coprocessor(cs
, riscv_gdb_get_virtual
,
330 riscv_gdb_set_virtual
,
331 1, "riscv-32bit-virtual.xml", 0);
335 gdb_register_coprocessor(cs
, riscv_gdb_get_virtual
,
336 riscv_gdb_set_virtual
,
337 1, "riscv-64bit-virtual.xml", 0);
340 g_assert_not_reached();
343 if (cpu
->cfg
.ext_icsr
) {
344 int base_reg
= cs
->gdb_num_regs
;
345 gdb_register_coprocessor(cs
, riscv_gdb_get_csr
, riscv_gdb_set_csr
,
346 riscv_gen_dynamic_csr_xml(cs
, base_reg
),