sphinx/qapidoc: Drop code to generate doc for simple union tag
[qemu/kevin.git] / target / riscv / gdbstub.c
blob58b3ace0fe92fc17459eeb953caeec8f3712ef74
1 /*
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
13 * more details.
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"
22 #include "cpu.h"
24 struct TypeSize {
25 const char *gdb_type;
26 const char *id;
27 int size;
28 const char suffix;
31 static const struct TypeSize vec_lanes[] = {
32 /* quads */
33 { "uint128", "quads", 128, 'q' },
34 /* 64 bit */
35 { "uint64", "longs", 64, 'l' },
36 /* 32 bit */
37 { "uint32", "words", 32, 'w' },
38 /* 16 bit */
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' },
46 /* bytes */
47 { "uint8", "bytes", 8, 'b' },
50 int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
52 RISCVCPU *cpu = RISCV_CPU(cs);
53 CPURISCVState *env = &cpu->env;
54 target_ulong tmp;
56 if (n < 32) {
57 tmp = env->gpr[n];
58 } else if (n == 32) {
59 tmp = env->pc;
60 } else {
61 return 0;
64 switch (env->misa_mxl_max) {
65 case MXL_RV32:
66 return gdb_get_reg32(mem_buf, tmp);
67 case MXL_RV64:
68 case MXL_RV128:
69 return gdb_get_reg64(mem_buf, tmp);
70 default:
71 g_assert_not_reached();
73 return 0;
76 int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
78 RISCVCPU *cpu = RISCV_CPU(cs);
79 CPURISCVState *env = &cpu->env;
80 int length = 0;
81 target_ulong tmp;
83 switch (env->misa_mxl_max) {
84 case MXL_RV32:
85 tmp = (int32_t)ldl_p(mem_buf);
86 length = 4;
87 break;
88 case MXL_RV64:
89 case MXL_RV128:
90 if (env->xl < MXL_RV64) {
91 tmp = (int32_t)ldq_p(mem_buf);
92 } else {
93 tmp = ldq_p(mem_buf);
95 length = 8;
96 break;
97 default:
98 g_assert_not_reached();
100 if (n > 0 && n < 32) {
101 env->gpr[n] = tmp;
102 } else if (n == 32) {
103 env->pc = tmp;
106 return length;
109 static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
111 if (n < 32) {
112 if (env->misa_ext & RVD) {
113 return gdb_get_reg64(buf, env->fpr[n]);
115 if (env->misa_ext & RVF) {
116 return gdb_get_reg32(buf, env->fpr[n]);
119 return 0;
122 static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
124 if (n < 32) {
125 env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
126 return sizeof(uint64_t);
128 return 0;
131 static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
133 uint16_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
134 if (n < 32) {
135 int i;
136 int cnt = 0;
137 for (i = 0; i < vlenb; i += 8) {
138 cnt += gdb_get_reg64(buf,
139 env->vreg[(n * vlenb + i) / 8]);
141 return cnt;
144 return 0;
147 static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
149 uint16_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
150 if (n < 32) {
151 int i;
152 for (i = 0; i < vlenb; i += 8) {
153 env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
155 return vlenb;
158 return 0;
161 static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
163 if (n < CSR_TABLE_SIZE) {
164 target_ulong val = 0;
165 int result;
167 result = riscv_csrrw_debug(env, n, &val, 0, 0);
168 if (result == RISCV_EXCP_NONE) {
169 return gdb_get_regl(buf, val);
172 return 0;
175 static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
177 if (n < CSR_TABLE_SIZE) {
178 target_ulong val = ldtul_p(mem_buf);
179 int result;
181 result = riscv_csrrw_debug(env, n, NULL, val, -1);
182 if (result == RISCV_EXCP_NONE) {
183 return sizeof(target_ulong);
186 return 0;
189 static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n)
191 if (n == 0) {
192 #ifdef CONFIG_USER_ONLY
193 return gdb_get_regl(buf, 0);
194 #else
195 return gdb_get_regl(buf, cs->priv);
196 #endif
198 return 0;
201 static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
203 if (n == 0) {
204 #ifndef CONFIG_USER_ONLY
205 cs->priv = ldtul_p(mem_buf) & 0x3;
206 if (cs->priv == PRV_RESERVED) {
207 cs->priv = PRV_S;
209 #endif
210 return sizeof(target_ulong);
212 return 0;
215 static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
217 RISCVCPU *cpu = RISCV_CPU(cs);
218 CPURISCVState *env = &cpu->env;
219 GString *s = g_string_new(NULL);
220 riscv_csr_predicate_fn predicate;
221 int bitsize = 16 << env->misa_mxl_max;
222 int i;
224 #if !defined(CONFIG_USER_ONLY)
225 env->debugger = true;
226 #endif
228 /* Until gdb knows about 128-bit registers */
229 if (bitsize > 64) {
230 bitsize = 64;
233 g_string_printf(s, "<?xml version=\"1.0\"?>");
234 g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
235 g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
237 for (i = 0; i < CSR_TABLE_SIZE; i++) {
238 if (env->priv_ver < csr_ops[i].min_priv_ver) {
239 continue;
241 predicate = csr_ops[i].predicate;
242 if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
243 if (csr_ops[i].name) {
244 g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
245 } else {
246 g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
248 g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
249 g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
253 g_string_append_printf(s, "</feature>");
255 cpu->dyn_csr_xml = g_string_free(s, false);
257 #if !defined(CONFIG_USER_ONLY)
258 env->debugger = false;
259 #endif
261 return CSR_TABLE_SIZE;
264 static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
266 RISCVCPU *cpu = RISCV_CPU(cs);
267 GString *s = g_string_new(NULL);
268 g_autoptr(GString) ts = g_string_new("");
269 int reg_width = cpu->cfg.vlen;
270 int num_regs = 0;
271 int i;
273 g_string_printf(s, "<?xml version=\"1.0\"?>");
274 g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
275 g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.vector\">");
277 /* First define types and totals in a whole VL */
278 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
279 int count = reg_width / vec_lanes[i].size;
280 g_string_printf(ts, "%s", vec_lanes[i].id);
281 g_string_append_printf(s,
282 "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
283 ts->str, vec_lanes[i].gdb_type, count);
286 /* Define unions */
287 g_string_append_printf(s, "<union id=\"riscv_vector\">");
288 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
289 g_string_append_printf(s, "<field name=\"%c\" type=\"%s\"/>",
290 vec_lanes[i].suffix,
291 vec_lanes[i].id);
293 g_string_append(s, "</union>");
295 /* Define vector registers */
296 for (i = 0; i < 32; i++) {
297 g_string_append_printf(s,
298 "<reg name=\"v%d\" bitsize=\"%d\""
299 " regnum=\"%d\" group=\"vector\""
300 " type=\"riscv_vector\"/>",
301 i, reg_width, base_reg++);
302 num_regs++;
305 g_string_append_printf(s, "</feature>");
307 cpu->dyn_vreg_xml = g_string_free(s, false);
308 return num_regs;
311 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
313 RISCVCPU *cpu = RISCV_CPU(cs);
314 CPURISCVState *env = &cpu->env;
315 if (env->misa_ext & RVD) {
316 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
317 32, "riscv-64bit-fpu.xml", 0);
318 } else if (env->misa_ext & RVF) {
319 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
320 32, "riscv-32bit-fpu.xml", 0);
322 if (env->misa_ext & RVV) {
323 int base_reg = cs->gdb_num_regs;
324 gdb_register_coprocessor(cs, riscv_gdb_get_vector,
325 riscv_gdb_set_vector,
326 ricsv_gen_dynamic_vector_xml(cs, base_reg),
327 "riscv-vector.xml", 0);
329 switch (env->misa_mxl_max) {
330 case MXL_RV32:
331 gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
332 riscv_gdb_set_virtual,
333 1, "riscv-32bit-virtual.xml", 0);
334 break;
335 case MXL_RV64:
336 case MXL_RV128:
337 gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
338 riscv_gdb_set_virtual,
339 1, "riscv-64bit-virtual.xml", 0);
340 break;
341 default:
342 g_assert_not_reached();
345 if (cpu->cfg.ext_zicsr) {
346 int base_reg = cs->gdb_num_regs;
347 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
348 riscv_gen_dynamic_csr_xml(cs, base_reg),
349 "riscv-csr.xml", 0);