xref: /openbmc/qemu/target/riscv/gdbstub.c (revision c8c89a6a)
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 "cpu.h"
22 
23 struct TypeSize {
24     const char *gdb_type;
25     const char *id;
26     int size;
27     const char suffix;
28 };
29 
30 static const struct TypeSize vec_lanes[] = {
31     /* quads */
32     { "uint128", "quads", 128, 'q' },
33     /* 64 bit */
34     { "uint64", "longs", 64, 'l' },
35     /* 32 bit */
36     { "uint32", "words", 32, 'w' },
37     /* 16 bit */
38     { "uint16", "shorts", 16, 's' },
39     /*
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' },
44      */
45     /* bytes */
46     { "uint8", "bytes", 8, 'b' },
47 };
48 
49 int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
50 {
51     RISCVCPU *cpu = RISCV_CPU(cs);
52     CPURISCVState *env = &cpu->env;
53     target_ulong tmp;
54 
55     if (n < 32) {
56         tmp = env->gpr[n];
57     } else if (n == 32) {
58         tmp = env->pc;
59     } else {
60         return 0;
61     }
62 
63     switch (env->misa_mxl_max) {
64     case MXL_RV32:
65         return gdb_get_reg32(mem_buf, tmp);
66     case MXL_RV64:
67         return gdb_get_reg64(mem_buf, tmp);
68     default:
69         g_assert_not_reached();
70     }
71     return 0;
72 }
73 
74 int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
75 {
76     RISCVCPU *cpu = RISCV_CPU(cs);
77     CPURISCVState *env = &cpu->env;
78     int length = 0;
79     target_ulong tmp;
80 
81     switch (env->misa_mxl_max) {
82     case MXL_RV32:
83         tmp = (int32_t)ldl_p(mem_buf);
84         length = 4;
85         break;
86     case MXL_RV64:
87         if (env->xl < MXL_RV64) {
88             tmp = (int32_t)ldq_p(mem_buf);
89         } else {
90             tmp = ldq_p(mem_buf);
91         }
92         length = 8;
93         break;
94     default:
95         g_assert_not_reached();
96     }
97     if (n > 0 && n < 32) {
98         env->gpr[n] = tmp;
99     } else if (n == 32) {
100         env->pc = tmp;
101     }
102 
103     return length;
104 }
105 
106 static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
107 {
108     if (n < 32) {
109         if (env->misa_ext & RVD) {
110             return gdb_get_reg64(buf, env->fpr[n]);
111         }
112         if (env->misa_ext & RVF) {
113             return gdb_get_reg32(buf, env->fpr[n]);
114         }
115     /* there is hole between ft11 and fflags in fpu.xml */
116     } else if (n < 36 && n > 32) {
117         target_ulong val = 0;
118         int result;
119         /*
120          * CSR_FFLAGS is at index 1 in csr_register, and gdb says it is FP
121          * register 33, so we recalculate the map index.
122          * This also works for CSR_FRM and CSR_FCSR.
123          */
124         result = riscv_csrrw_debug(env, n - 32, &val,
125                                    0, 0);
126         if (result == RISCV_EXCP_NONE) {
127             return gdb_get_regl(buf, val);
128         }
129     }
130     return 0;
131 }
132 
133 static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
134 {
135     if (n < 32) {
136         env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
137         return sizeof(uint64_t);
138     /* there is hole between ft11 and fflags in fpu.xml */
139     } else if (n < 36 && n > 32) {
140         target_ulong val = ldtul_p(mem_buf);
141         int result;
142         /*
143          * CSR_FFLAGS is at index 1 in csr_register, and gdb says it is FP
144          * register 33, so we recalculate the map index.
145          * This also works for CSR_FRM and CSR_FCSR.
146          */
147         result = riscv_csrrw_debug(env, n - 32, NULL,
148                                    val, -1);
149         if (result == RISCV_EXCP_NONE) {
150             return sizeof(target_ulong);
151         }
152     }
153     return 0;
154 }
155 
156 /*
157  * Convert register index number passed by GDB to the correspond
158  * vector CSR number. Vector CSRs are defined after vector registers
159  * in dynamic generated riscv-vector.xml, thus the starting register index
160  * of vector CSRs is 32.
161  * Return 0 if register index number is out of range.
162  */
163 static int riscv_gdb_vector_csrno(int num_regs)
164 {
165     /*
166      * The order of vector CSRs in the switch case
167      * should match with the order defined in csr_ops[].
168      */
169     switch (num_regs) {
170     case 32:
171         return CSR_VSTART;
172     case 33:
173         return CSR_VXSAT;
174     case 34:
175         return CSR_VXRM;
176     case 35:
177         return CSR_VCSR;
178     case 36:
179         return CSR_VL;
180     case 37:
181         return CSR_VTYPE;
182     case 38:
183         return CSR_VLENB;
184     default:
185         /* Unknown register. */
186         return 0;
187     }
188 }
189 
190 static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
191 {
192     uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
193     if (n < 32) {
194         int i;
195         int cnt = 0;
196         for (i = 0; i < vlenb; i += 8) {
197             cnt += gdb_get_reg64(buf,
198                                  env->vreg[(n * vlenb + i) / 8]);
199         }
200         return cnt;
201     }
202 
203     int csrno = riscv_gdb_vector_csrno(n);
204 
205     if (!csrno) {
206         return 0;
207     }
208 
209     target_ulong val = 0;
210     int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
211 
212     if (result == 0) {
213         return gdb_get_regl(buf, val);
214     }
215 
216     return 0;
217 }
218 
219 static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
220 {
221     uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
222     if (n < 32) {
223         int i;
224         for (i = 0; i < vlenb; i += 8) {
225             env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
226         }
227         return vlenb;
228     }
229 
230     int csrno = riscv_gdb_vector_csrno(n);
231 
232     if (!csrno) {
233         return 0;
234     }
235 
236     target_ulong val = ldtul_p(mem_buf);
237     int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
238 
239     if (result == 0) {
240         return sizeof(target_ulong);
241     }
242 
243     return 0;
244 }
245 
246 static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
247 {
248     if (n < CSR_TABLE_SIZE) {
249         target_ulong val = 0;
250         int result;
251 
252         result = riscv_csrrw_debug(env, n, &val, 0, 0);
253         if (result == RISCV_EXCP_NONE) {
254             return gdb_get_regl(buf, val);
255         }
256     }
257     return 0;
258 }
259 
260 static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
261 {
262     if (n < CSR_TABLE_SIZE) {
263         target_ulong val = ldtul_p(mem_buf);
264         int result;
265 
266         result = riscv_csrrw_debug(env, n, NULL, val, -1);
267         if (result == RISCV_EXCP_NONE) {
268             return sizeof(target_ulong);
269         }
270     }
271     return 0;
272 }
273 
274 static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n)
275 {
276     if (n == 0) {
277 #ifdef CONFIG_USER_ONLY
278         return gdb_get_regl(buf, 0);
279 #else
280         return gdb_get_regl(buf, cs->priv);
281 #endif
282     }
283     return 0;
284 }
285 
286 static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
287 {
288     if (n == 0) {
289 #ifndef CONFIG_USER_ONLY
290         cs->priv = ldtul_p(mem_buf) & 0x3;
291         if (cs->priv == PRV_H) {
292             cs->priv = PRV_S;
293         }
294 #endif
295         return sizeof(target_ulong);
296     }
297     return 0;
298 }
299 
300 static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
301 {
302     RISCVCPU *cpu = RISCV_CPU(cs);
303     CPURISCVState *env = &cpu->env;
304     GString *s = g_string_new(NULL);
305     riscv_csr_predicate_fn predicate;
306     int bitsize = 16 << env->misa_mxl_max;
307     int i;
308 
309     /* Until gdb knows about 128-bit registers */
310     if (bitsize > 64) {
311         bitsize = 64;
312     }
313 
314     g_string_printf(s, "<?xml version=\"1.0\"?>");
315     g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
316     g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
317 
318     for (i = 0; i < CSR_TABLE_SIZE; i++) {
319         predicate = csr_ops[i].predicate;
320         if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
321             if (csr_ops[i].name) {
322                 g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
323             } else {
324                 g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
325             }
326             g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
327             g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
328         }
329     }
330 
331     g_string_append_printf(s, "</feature>");
332 
333     cpu->dyn_csr_xml = g_string_free(s, false);
334     return CSR_TABLE_SIZE;
335 }
336 
337 static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
338 {
339     RISCVCPU *cpu = RISCV_CPU(cs);
340     GString *s = g_string_new(NULL);
341     g_autoptr(GString) ts = g_string_new("");
342     int reg_width = cpu->cfg.vlen;
343     int num_regs = 0;
344     int i;
345 
346     g_string_printf(s, "<?xml version=\"1.0\"?>");
347     g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
348     g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.vector\">");
349 
350     /* First define types and totals in a whole VL */
351     for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
352         int count = reg_width / vec_lanes[i].size;
353         g_string_printf(ts, "%s", vec_lanes[i].id);
354         g_string_append_printf(s,
355                                "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
356                                ts->str, vec_lanes[i].gdb_type, count);
357     }
358 
359     /* Define unions */
360     g_string_append_printf(s, "<union id=\"riscv_vector\">");
361     for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
362         g_string_append_printf(s, "<field name=\"%c\" type=\"%s\"/>",
363                                vec_lanes[i].suffix,
364                                vec_lanes[i].id);
365     }
366     g_string_append(s, "</union>");
367 
368     /* Define vector registers */
369     for (i = 0; i < 32; i++) {
370         g_string_append_printf(s,
371                                "<reg name=\"v%d\" bitsize=\"%d\""
372                                " regnum=\"%d\" group=\"vector\""
373                                " type=\"riscv_vector\"/>",
374                                i, reg_width, base_reg++);
375         num_regs++;
376     }
377 
378     /* Define vector CSRs */
379     const char *vector_csrs[7] = {
380         "vstart", "vxsat", "vxrm", "vcsr",
381         "vl", "vtype", "vlenb"
382     };
383 
384     for (i = 0; i < 7; i++) {
385         g_string_append_printf(s,
386                                "<reg name=\"%s\" bitsize=\"%d\""
387                                " regnum=\"%d\" group=\"vector\""
388                                " type=\"int\"/>",
389                                vector_csrs[i], TARGET_LONG_BITS, base_reg++);
390         num_regs++;
391     }
392 
393     g_string_append_printf(s, "</feature>");
394 
395     cpu->dyn_vreg_xml = g_string_free(s, false);
396     return num_regs;
397 }
398 
399 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
400 {
401     RISCVCPU *cpu = RISCV_CPU(cs);
402     CPURISCVState *env = &cpu->env;
403     if (env->misa_ext & RVD) {
404         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
405                                  36, "riscv-64bit-fpu.xml", 0);
406     } else if (env->misa_ext & RVF) {
407         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
408                                  36, "riscv-32bit-fpu.xml", 0);
409     }
410     if (env->misa_ext & RVV) {
411         gdb_register_coprocessor(cs, riscv_gdb_get_vector, riscv_gdb_set_vector,
412                                  ricsv_gen_dynamic_vector_xml(cs,
413                                                               cs->gdb_num_regs),
414                                  "riscv-vector.xml", 0);
415     }
416     switch (env->misa_mxl_max) {
417     case MXL_RV32:
418         gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
419                                  riscv_gdb_set_virtual,
420                                  1, "riscv-32bit-virtual.xml", 0);
421         break;
422     case MXL_RV64:
423         gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
424                                  riscv_gdb_set_virtual,
425                                  1, "riscv-64bit-virtual.xml", 0);
426         break;
427     default:
428         g_assert_not_reached();
429     }
430 
431     gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
432                              riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs),
433                              "riscv-csr.xml", 0);
434 }
435