]> git.proxmox.com Git - mirror_qemu.git/blob - target/riscv/gdbstub.c
Merge tag 'qemu-openbios-20230307' of https://github.com/mcayland/qemu into staging
[mirror_qemu.git] / target / riscv / gdbstub.c
1 /*
2 * RISC-V GDB Server Stub
3 *
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 *
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.
9 *
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.
14 *
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/>.
17 */
18
19 #include "qemu/osdep.h"
20 #include "exec/gdbstub.h"
21 #include "gdbstub/helpers.h"
22 #include "cpu.h"
23
24 struct TypeSize {
25 const char *gdb_type;
26 const char *id;
27 int size;
28 const char suffix;
29 };
30
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' },
40 /*
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' },
45 */
46 /* bytes */
47 { "uint8", "bytes", 8, 'b' },
48 };
49
50 int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
51 {
52 RISCVCPU *cpu = RISCV_CPU(cs);
53 CPURISCVState *env = &cpu->env;
54 target_ulong tmp;
55
56 if (n < 32) {
57 tmp = env->gpr[n];
58 } else if (n == 32) {
59 tmp = env->pc;
60 } else {
61 return 0;
62 }
63
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();
72 }
73 return 0;
74 }
75
76 int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
77 {
78 RISCVCPU *cpu = RISCV_CPU(cs);
79 CPURISCVState *env = &cpu->env;
80 int length = 0;
81 target_ulong tmp;
82
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);
94 }
95 length = 8;
96 break;
97 default:
98 g_assert_not_reached();
99 }
100 if (n > 0 && n < 32) {
101 env->gpr[n] = tmp;
102 } else if (n == 32) {
103 env->pc = tmp;
104 }
105
106 return length;
107 }
108
109 static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
110 {
111 if (n < 32) {
112 if (env->misa_ext & RVD) {
113 return gdb_get_reg64(buf, env->fpr[n]);
114 }
115 if (env->misa_ext & RVF) {
116 return gdb_get_reg32(buf, env->fpr[n]);
117 }
118 }
119 return 0;
120 }
121
122 static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
123 {
124 if (n < 32) {
125 env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
126 return sizeof(uint64_t);
127 }
128 return 0;
129 }
130
131 static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
132 {
133 uint16_t vlenb = env_archcpu(env)->cfg.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]);
140 }
141 return cnt;
142 }
143
144 return 0;
145 }
146
147 static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
148 {
149 uint16_t vlenb = env_archcpu(env)->cfg.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);
154 }
155 return vlenb;
156 }
157
158 return 0;
159 }
160
161 static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
162 {
163 if (n < CSR_TABLE_SIZE) {
164 target_ulong val = 0;
165 int result;
166
167 result = riscv_csrrw_debug(env, n, &val, 0, 0);
168 if (result == RISCV_EXCP_NONE) {
169 return gdb_get_regl(buf, val);
170 }
171 }
172 return 0;
173 }
174
175 static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
176 {
177 if (n < CSR_TABLE_SIZE) {
178 target_ulong val = ldtul_p(mem_buf);
179 int result;
180
181 result = riscv_csrrw_debug(env, n, NULL, val, -1);
182 if (result == RISCV_EXCP_NONE) {
183 return sizeof(target_ulong);
184 }
185 }
186 return 0;
187 }
188
189 static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n)
190 {
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
197 }
198 return 0;
199 }
200
201 static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
202 {
203 if (n == 0) {
204 #ifndef CONFIG_USER_ONLY
205 cs->priv = ldtul_p(mem_buf) & 0x3;
206 if (cs->priv == PRV_H) {
207 cs->priv = PRV_S;
208 }
209 #endif
210 return sizeof(target_ulong);
211 }
212 return 0;
213 }
214
215 static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
216 {
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;
223
224 #if !defined(CONFIG_USER_ONLY)
225 env->debugger = true;
226 #endif
227
228 /* Until gdb knows about 128-bit registers */
229 if (bitsize > 64) {
230 bitsize = 64;
231 }
232
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\">");
236
237 for (i = 0; i < CSR_TABLE_SIZE; i++) {
238 if (env->priv_ver < csr_ops[i].min_priv_ver) {
239 continue;
240 }
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);
247 }
248 g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
249 g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
250 }
251 }
252
253 g_string_append_printf(s, "</feature>");
254
255 cpu->dyn_csr_xml = g_string_free(s, false);
256
257 #if !defined(CONFIG_USER_ONLY)
258 env->debugger = false;
259 #endif
260
261 return CSR_TABLE_SIZE;
262 }
263
264 static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
265 {
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;
272
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\">");
276
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);
284 }
285
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);
292 }
293 g_string_append(s, "</union>");
294
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++;
303 }
304
305 g_string_append_printf(s, "</feature>");
306
307 cpu->dyn_vreg_xml = g_string_free(s, false);
308 return num_regs;
309 }
310
311 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
312 {
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);
321 }
322 if (env->misa_ext & RVV) {
323 int base_reg = cs->gdb_num_regs;
324 gdb_register_coprocessor(cs, riscv_gdb_get_vector, riscv_gdb_set_vector,
325 ricsv_gen_dynamic_vector_xml(cs, base_reg),
326 "riscv-vector.xml", 0);
327 }
328 switch (env->misa_mxl_max) {
329 case MXL_RV32:
330 gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
331 riscv_gdb_set_virtual,
332 1, "riscv-32bit-virtual.xml", 0);
333 break;
334 case MXL_RV64:
335 case MXL_RV128:
336 gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
337 riscv_gdb_set_virtual,
338 1, "riscv-64bit-virtual.xml", 0);
339 break;
340 default:
341 g_assert_not_reached();
342 }
343
344 if (cpu->cfg.ext_icsr) {
345 int base_reg = cs->gdb_num_regs;
346 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
347 riscv_gen_dynamic_csr_xml(cs, base_reg),
348 "riscv-csr.xml", 0);
349 }
350 }