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"
21 #include "gdbstub/helpers.h"
31 static const struct TypeSize vec_lanes
[] = {
33 { "uint128", "quads", 128, 'q' },
35 { "uint64", "longs", 64, 'l' },
37 { "uint32", "words", 32, 'w' },
39 { "uint16", "shorts", 16, 's' },
41 * TODO: currently there is no reliable way of telling
42 * if the remote gdb actually understands ieee_half so
43 * we don't expose it in the target description for now.
44 * { "ieee_half", 16, 'h', 'f' },
47 { "uint8", "bytes", 8, 'b' },
50 int riscv_cpu_gdb_read_register(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
52 RISCVCPUClass
*mcc
= RISCV_CPU_GET_CLASS(cs
);
53 RISCVCPU
*cpu
= RISCV_CPU(cs
);
54 CPURISCVState
*env
= &cpu
->env
;
65 switch (mcc
->misa_mxl_max
) {
67 return gdb_get_reg32(mem_buf
, tmp
);
70 return gdb_get_reg64(mem_buf
, tmp
);
72 g_assert_not_reached();
77 int riscv_cpu_gdb_write_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
79 RISCVCPUClass
*mcc
= RISCV_CPU_GET_CLASS(cs
);
80 RISCVCPU
*cpu
= RISCV_CPU(cs
);
81 CPURISCVState
*env
= &cpu
->env
;
85 switch (mcc
->misa_mxl_max
) {
87 tmp
= (int32_t)ldl_p(mem_buf
);
92 if (env
->xl
< MXL_RV64
) {
93 tmp
= (int32_t)ldq_p(mem_buf
);
100 g_assert_not_reached();
102 if (n
> 0 && n
< 32) {
104 } else if (n
== 32) {
111 static int riscv_gdb_get_fpu(CPUState
*cs
, GByteArray
*buf
, int n
)
113 RISCVCPU
*cpu
= RISCV_CPU(cs
);
114 CPURISCVState
*env
= &cpu
->env
;
117 if (env
->misa_ext
& RVD
) {
118 return gdb_get_reg64(buf
, env
->fpr
[n
]);
120 if (env
->misa_ext
& RVF
) {
121 return gdb_get_reg32(buf
, env
->fpr
[n
]);
127 static int riscv_gdb_set_fpu(CPUState
*cs
, uint8_t *mem_buf
, int n
)
129 RISCVCPU
*cpu
= RISCV_CPU(cs
);
130 CPURISCVState
*env
= &cpu
->env
;
133 env
->fpr
[n
] = ldq_p(mem_buf
); /* always 64-bit */
134 return sizeof(uint64_t);
139 static int riscv_gdb_get_vector(CPUState
*cs
, GByteArray
*buf
, int n
)
141 RISCVCPU
*cpu
= RISCV_CPU(cs
);
142 CPURISCVState
*env
= &cpu
->env
;
143 uint16_t vlenb
= cpu
->cfg
.vlenb
;
147 for (i
= 0; i
< vlenb
; i
+= 8) {
148 cnt
+= gdb_get_reg64(buf
,
149 env
->vreg
[(n
* vlenb
+ i
) / 8]);
157 static int riscv_gdb_set_vector(CPUState
*cs
, uint8_t *mem_buf
, int n
)
159 RISCVCPU
*cpu
= RISCV_CPU(cs
);
160 CPURISCVState
*env
= &cpu
->env
;
161 uint16_t vlenb
= cpu
->cfg
.vlenb
;
164 for (i
= 0; i
< vlenb
; i
+= 8) {
165 env
->vreg
[(n
* vlenb
+ i
) / 8] = ldq_p(mem_buf
+ i
);
173 static int riscv_gdb_get_csr(CPUState
*cs
, GByteArray
*buf
, int n
)
175 RISCVCPU
*cpu
= RISCV_CPU(cs
);
176 CPURISCVState
*env
= &cpu
->env
;
178 if (n
< CSR_TABLE_SIZE
) {
179 target_ulong val
= 0;
182 result
= riscv_csrrw_debug(env
, n
, &val
, 0, 0);
183 if (result
== RISCV_EXCP_NONE
) {
184 return gdb_get_regl(buf
, val
);
190 static int riscv_gdb_set_csr(CPUState
*cs
, uint8_t *mem_buf
, int n
)
192 RISCVCPU
*cpu
= RISCV_CPU(cs
);
193 CPURISCVState
*env
= &cpu
->env
;
195 if (n
< CSR_TABLE_SIZE
) {
196 target_ulong val
= ldtul_p(mem_buf
);
199 result
= riscv_csrrw_debug(env
, n
, NULL
, val
, -1);
200 if (result
== RISCV_EXCP_NONE
) {
201 return sizeof(target_ulong
);
207 static int riscv_gdb_get_virtual(CPUState
*cs
, GByteArray
*buf
, int n
)
210 #ifdef CONFIG_USER_ONLY
211 return gdb_get_regl(buf
, 0);
213 RISCVCPU
*cpu
= RISCV_CPU(cs
);
214 CPURISCVState
*env
= &cpu
->env
;
216 return gdb_get_regl(buf
, env
->priv
);
222 static int riscv_gdb_set_virtual(CPUState
*cs
, uint8_t *mem_buf
, int n
)
225 #ifndef CONFIG_USER_ONLY
226 RISCVCPU
*cpu
= RISCV_CPU(cs
);
227 CPURISCVState
*env
= &cpu
->env
;
229 env
->priv
= ldtul_p(mem_buf
) & 0x3;
230 if (env
->priv
== PRV_RESERVED
) {
234 return sizeof(target_ulong
);
239 static GDBFeature
*riscv_gen_dynamic_csr_feature(CPUState
*cs
, int base_reg
)
241 RISCVCPUClass
*mcc
= RISCV_CPU_GET_CLASS(cs
);
242 RISCVCPU
*cpu
= RISCV_CPU(cs
);
243 CPURISCVState
*env
= &cpu
->env
;
244 GDBFeatureBuilder builder
;
245 riscv_csr_predicate_fn predicate
;
246 int bitsize
= riscv_cpu_max_xlen(mcc
);
250 #if !defined(CONFIG_USER_ONLY)
251 env
->debugger
= true;
254 /* Until gdb knows about 128-bit registers */
259 gdb_feature_builder_init(&builder
, &cpu
->dyn_csr_feature
,
260 "org.gnu.gdb.riscv.csr", "riscv-csr.xml",
263 for (i
= 0; i
< CSR_TABLE_SIZE
; i
++) {
264 if (env
->priv_ver
< csr_ops
[i
].min_priv_ver
) {
267 predicate
= csr_ops
[i
].predicate
;
268 if (predicate
&& (predicate(env
, i
) == RISCV_EXCP_NONE
)) {
269 name
= csr_ops
[i
].name
;
271 name
= g_strdup_printf("csr%03x", i
);
274 gdb_feature_builder_append_reg(&builder
, name
, bitsize
, i
,
279 gdb_feature_builder_end(&builder
);
281 #if !defined(CONFIG_USER_ONLY)
282 env
->debugger
= false;
285 return &cpu
->dyn_csr_feature
;
288 static GDBFeature
*ricsv_gen_dynamic_vector_feature(CPUState
*cs
, int base_reg
)
290 RISCVCPU
*cpu
= RISCV_CPU(cs
);
291 int reg_width
= cpu
->cfg
.vlenb
;
292 GDBFeatureBuilder builder
;
295 gdb_feature_builder_init(&builder
, &cpu
->dyn_vreg_feature
,
296 "org.gnu.gdb.riscv.vector", "riscv-vector.xml",
299 /* First define types and totals in a whole VL */
300 for (i
= 0; i
< ARRAY_SIZE(vec_lanes
); i
++) {
301 int count
= reg_width
/ vec_lanes
[i
].size
;
302 gdb_feature_builder_append_tag(
303 &builder
, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
304 vec_lanes
[i
].id
, vec_lanes
[i
].gdb_type
, count
);
308 gdb_feature_builder_append_tag(&builder
, "<union id=\"riscv_vector\">");
309 for (i
= 0; i
< ARRAY_SIZE(vec_lanes
); i
++) {
310 gdb_feature_builder_append_tag(&builder
,
311 "<field name=\"%c\" type=\"%s\"/>",
312 vec_lanes
[i
].suffix
, vec_lanes
[i
].id
);
314 gdb_feature_builder_append_tag(&builder
, "</union>");
316 /* Define vector registers */
317 for (i
= 0; i
< 32; i
++) {
318 gdb_feature_builder_append_reg(&builder
, g_strdup_printf("v%d", i
),
319 reg_width
, i
, "riscv_vector", "vector");
322 gdb_feature_builder_end(&builder
);
324 return &cpu
->dyn_vreg_feature
;
327 void riscv_cpu_register_gdb_regs_for_features(CPUState
*cs
)
329 RISCVCPUClass
*mcc
= RISCV_CPU_GET_CLASS(cs
);
330 RISCVCPU
*cpu
= RISCV_CPU(cs
);
331 CPURISCVState
*env
= &cpu
->env
;
332 if (env
->misa_ext
& RVD
) {
333 gdb_register_coprocessor(cs
, riscv_gdb_get_fpu
, riscv_gdb_set_fpu
,
334 gdb_find_static_feature("riscv-64bit-fpu.xml"),
336 } else if (env
->misa_ext
& RVF
) {
337 gdb_register_coprocessor(cs
, riscv_gdb_get_fpu
, riscv_gdb_set_fpu
,
338 gdb_find_static_feature("riscv-32bit-fpu.xml"),
341 if (env
->misa_ext
& RVV
) {
342 gdb_register_coprocessor(cs
, riscv_gdb_get_vector
,
343 riscv_gdb_set_vector
,
344 ricsv_gen_dynamic_vector_feature(cs
, cs
->gdb_num_regs
),
347 switch (mcc
->misa_mxl_max
) {
349 gdb_register_coprocessor(cs
, riscv_gdb_get_virtual
,
350 riscv_gdb_set_virtual
,
351 gdb_find_static_feature("riscv-32bit-virtual.xml"),
356 gdb_register_coprocessor(cs
, riscv_gdb_get_virtual
,
357 riscv_gdb_set_virtual
,
358 gdb_find_static_feature("riscv-64bit-virtual.xml"),
362 g_assert_not_reached();
365 if (cpu
->cfg
.ext_zicsr
) {
366 gdb_register_coprocessor(cs
, riscv_gdb_get_csr
, riscv_gdb_set_csr
,
367 riscv_gen_dynamic_csr_feature(cs
, cs
->gdb_num_regs
),