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);
131 * Convert register index number passed by GDB to the correspond
132 * vector CSR number. Vector CSRs are defined after vector registers
133 * in dynamic generated riscv-vector.xml, thus the starting register index
134 * of vector CSRs is 32.
135 * Return 0 if register index number is out of range.
137 static int riscv_gdb_vector_csrno(int num_regs
)
140 * The order of vector CSRs in the switch case
141 * should match with the order defined in csr_ops[].
159 /* Unknown register. */
164 static int riscv_gdb_get_vector(CPURISCVState
*env
, GByteArray
*buf
, int n
)
166 uint16_t vlenb
= env_archcpu(env
)->cfg
.vlen
>> 3;
170 for (i
= 0; i
< vlenb
; i
+= 8) {
171 cnt
+= gdb_get_reg64(buf
,
172 env
->vreg
[(n
* vlenb
+ i
) / 8]);
177 int csrno
= riscv_gdb_vector_csrno(n
);
183 target_ulong val
= 0;
184 int result
= riscv_csrrw_debug(env
, csrno
, &val
, 0, 0);
186 if (result
== RISCV_EXCP_NONE
) {
187 return gdb_get_regl(buf
, val
);
193 static int riscv_gdb_set_vector(CPURISCVState
*env
, uint8_t *mem_buf
, int n
)
195 uint16_t vlenb
= env_archcpu(env
)->cfg
.vlen
>> 3;
198 for (i
= 0; i
< vlenb
; i
+= 8) {
199 env
->vreg
[(n
* vlenb
+ i
) / 8] = ldq_p(mem_buf
+ i
);
204 int csrno
= riscv_gdb_vector_csrno(n
);
210 target_ulong val
= ldtul_p(mem_buf
);
211 int result
= riscv_csrrw_debug(env
, csrno
, NULL
, val
, -1);
213 if (result
== RISCV_EXCP_NONE
) {
214 return sizeof(target_ulong
);
220 static int riscv_gdb_get_csr(CPURISCVState
*env
, GByteArray
*buf
, int n
)
222 if (n
< CSR_TABLE_SIZE
) {
223 target_ulong val
= 0;
226 result
= riscv_csrrw_debug(env
, n
, &val
, 0, 0);
227 if (result
== RISCV_EXCP_NONE
) {
228 return gdb_get_regl(buf
, val
);
234 static int riscv_gdb_set_csr(CPURISCVState
*env
, uint8_t *mem_buf
, int n
)
236 if (n
< CSR_TABLE_SIZE
) {
237 target_ulong val
= ldtul_p(mem_buf
);
240 result
= riscv_csrrw_debug(env
, n
, NULL
, val
, -1);
241 if (result
== RISCV_EXCP_NONE
) {
242 return sizeof(target_ulong
);
248 static int riscv_gdb_get_virtual(CPURISCVState
*cs
, GByteArray
*buf
, int n
)
251 #ifdef CONFIG_USER_ONLY
252 return gdb_get_regl(buf
, 0);
254 return gdb_get_regl(buf
, cs
->priv
);
260 static int riscv_gdb_set_virtual(CPURISCVState
*cs
, uint8_t *mem_buf
, int n
)
263 #ifndef CONFIG_USER_ONLY
264 cs
->priv
= ldtul_p(mem_buf
) & 0x3;
265 if (cs
->priv
== PRV_H
) {
269 return sizeof(target_ulong
);
274 static int riscv_gen_dynamic_csr_xml(CPUState
*cs
, int base_reg
)
276 RISCVCPU
*cpu
= RISCV_CPU(cs
);
277 CPURISCVState
*env
= &cpu
->env
;
278 GString
*s
= g_string_new(NULL
);
279 riscv_csr_predicate_fn predicate
;
280 int bitsize
= 16 << env
->misa_mxl_max
;
283 /* Until gdb knows about 128-bit registers */
288 g_string_printf(s
, "<?xml version=\"1.0\"?>");
289 g_string_append_printf(s
, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
290 g_string_append_printf(s
, "<feature name=\"org.gnu.gdb.riscv.csr\">");
292 for (i
= 0; i
< CSR_TABLE_SIZE
; i
++) {
293 predicate
= csr_ops
[i
].predicate
;
294 if (predicate
&& (predicate(env
, i
) == RISCV_EXCP_NONE
)) {
295 if (csr_ops
[i
].name
) {
296 g_string_append_printf(s
, "<reg name=\"%s\"", csr_ops
[i
].name
);
298 g_string_append_printf(s
, "<reg name=\"csr%03x\"", i
);
300 g_string_append_printf(s
, " bitsize=\"%d\"", bitsize
);
301 g_string_append_printf(s
, " regnum=\"%d\"/>", base_reg
+ i
);
305 g_string_append_printf(s
, "</feature>");
307 cpu
->dyn_csr_xml
= g_string_free(s
, false);
308 return CSR_TABLE_SIZE
;
311 static int ricsv_gen_dynamic_vector_xml(CPUState
*cs
, int base_reg
)
313 RISCVCPU
*cpu
= RISCV_CPU(cs
);
314 GString
*s
= g_string_new(NULL
);
315 g_autoptr(GString
) ts
= g_string_new("");
316 int reg_width
= cpu
->cfg
.vlen
;
320 g_string_printf(s
, "<?xml version=\"1.0\"?>");
321 g_string_append_printf(s
, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
322 g_string_append_printf(s
, "<feature name=\"org.gnu.gdb.riscv.vector\">");
324 /* First define types and totals in a whole VL */
325 for (i
= 0; i
< ARRAY_SIZE(vec_lanes
); i
++) {
326 int count
= reg_width
/ vec_lanes
[i
].size
;
327 g_string_printf(ts
, "%s", vec_lanes
[i
].id
);
328 g_string_append_printf(s
,
329 "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
330 ts
->str
, vec_lanes
[i
].gdb_type
, count
);
334 g_string_append_printf(s
, "<union id=\"riscv_vector\">");
335 for (i
= 0; i
< ARRAY_SIZE(vec_lanes
); i
++) {
336 g_string_append_printf(s
, "<field name=\"%c\" type=\"%s\"/>",
340 g_string_append(s
, "</union>");
342 /* Define vector registers */
343 for (i
= 0; i
< 32; i
++) {
344 g_string_append_printf(s
,
345 "<reg name=\"v%d\" bitsize=\"%d\""
346 " regnum=\"%d\" group=\"vector\""
347 " type=\"riscv_vector\"/>",
348 i
, reg_width
, base_reg
++);
352 /* Define vector CSRs */
353 const char *vector_csrs
[7] = {
354 "vstart", "vxsat", "vxrm", "vcsr",
355 "vl", "vtype", "vlenb"
358 for (i
= 0; i
< 7; i
++) {
359 g_string_append_printf(s
,
360 "<reg name=\"%s\" bitsize=\"%d\""
361 " regnum=\"%d\" group=\"vector\""
363 vector_csrs
[i
], TARGET_LONG_BITS
, base_reg
++);
367 g_string_append_printf(s
, "</feature>");
369 cpu
->dyn_vreg_xml
= g_string_free(s
, false);
373 void riscv_cpu_register_gdb_regs_for_features(CPUState
*cs
)
375 RISCVCPU
*cpu
= RISCV_CPU(cs
);
376 CPURISCVState
*env
= &cpu
->env
;
377 if (env
->misa_ext
& RVD
) {
378 gdb_register_coprocessor(cs
, riscv_gdb_get_fpu
, riscv_gdb_set_fpu
,
379 32, "riscv-64bit-fpu.xml", 0);
380 } else if (env
->misa_ext
& RVF
) {
381 gdb_register_coprocessor(cs
, riscv_gdb_get_fpu
, riscv_gdb_set_fpu
,
382 32, "riscv-32bit-fpu.xml", 0);
384 if (env
->misa_ext
& RVV
) {
385 gdb_register_coprocessor(cs
, riscv_gdb_get_vector
, riscv_gdb_set_vector
,
386 ricsv_gen_dynamic_vector_xml(cs
,
388 "riscv-vector.xml", 0);
390 switch (env
->misa_mxl_max
) {
392 gdb_register_coprocessor(cs
, riscv_gdb_get_virtual
,
393 riscv_gdb_set_virtual
,
394 1, "riscv-32bit-virtual.xml", 0);
398 gdb_register_coprocessor(cs
, riscv_gdb_get_virtual
,
399 riscv_gdb_set_virtual
,
400 1, "riscv-64bit-virtual.xml", 0);
403 g_assert_not_reached();
406 gdb_register_coprocessor(cs
, riscv_gdb_get_csr
, riscv_gdb_set_csr
,
407 riscv_gen_dynamic_csr_xml(cs
, cs
->gdb_num_regs
),