xref: /openbmc/qemu/target/riscv/gdbstub.c (revision 06d4c71f)
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 /*
24  * The GDB CSR xml files list them in documentation order, not numerical order,
25  * and are missing entries for unnamed CSRs.  So we need to map the gdb numbers
26  * to the hardware numbers.
27  */
28 
29 static int csr_register_map[] = {
30     CSR_USTATUS,
31     CSR_UIE,
32     CSR_UTVEC,
33     CSR_USCRATCH,
34     CSR_UEPC,
35     CSR_UCAUSE,
36     CSR_UTVAL,
37     CSR_UIP,
38     CSR_FFLAGS,
39     CSR_FRM,
40     CSR_FCSR,
41     CSR_CYCLE,
42     CSR_TIME,
43     CSR_INSTRET,
44     CSR_HPMCOUNTER3,
45     CSR_HPMCOUNTER4,
46     CSR_HPMCOUNTER5,
47     CSR_HPMCOUNTER6,
48     CSR_HPMCOUNTER7,
49     CSR_HPMCOUNTER8,
50     CSR_HPMCOUNTER9,
51     CSR_HPMCOUNTER10,
52     CSR_HPMCOUNTER11,
53     CSR_HPMCOUNTER12,
54     CSR_HPMCOUNTER13,
55     CSR_HPMCOUNTER14,
56     CSR_HPMCOUNTER15,
57     CSR_HPMCOUNTER16,
58     CSR_HPMCOUNTER17,
59     CSR_HPMCOUNTER18,
60     CSR_HPMCOUNTER19,
61     CSR_HPMCOUNTER20,
62     CSR_HPMCOUNTER21,
63     CSR_HPMCOUNTER22,
64     CSR_HPMCOUNTER23,
65     CSR_HPMCOUNTER24,
66     CSR_HPMCOUNTER25,
67     CSR_HPMCOUNTER26,
68     CSR_HPMCOUNTER27,
69     CSR_HPMCOUNTER28,
70     CSR_HPMCOUNTER29,
71     CSR_HPMCOUNTER30,
72     CSR_HPMCOUNTER31,
73     CSR_CYCLEH,
74     CSR_TIMEH,
75     CSR_INSTRETH,
76     CSR_HPMCOUNTER3H,
77     CSR_HPMCOUNTER4H,
78     CSR_HPMCOUNTER5H,
79     CSR_HPMCOUNTER6H,
80     CSR_HPMCOUNTER7H,
81     CSR_HPMCOUNTER8H,
82     CSR_HPMCOUNTER9H,
83     CSR_HPMCOUNTER10H,
84     CSR_HPMCOUNTER11H,
85     CSR_HPMCOUNTER12H,
86     CSR_HPMCOUNTER13H,
87     CSR_HPMCOUNTER14H,
88     CSR_HPMCOUNTER15H,
89     CSR_HPMCOUNTER16H,
90     CSR_HPMCOUNTER17H,
91     CSR_HPMCOUNTER18H,
92     CSR_HPMCOUNTER19H,
93     CSR_HPMCOUNTER20H,
94     CSR_HPMCOUNTER21H,
95     CSR_HPMCOUNTER22H,
96     CSR_HPMCOUNTER23H,
97     CSR_HPMCOUNTER24H,
98     CSR_HPMCOUNTER25H,
99     CSR_HPMCOUNTER26H,
100     CSR_HPMCOUNTER27H,
101     CSR_HPMCOUNTER28H,
102     CSR_HPMCOUNTER29H,
103     CSR_HPMCOUNTER30H,
104     CSR_HPMCOUNTER31H,
105     CSR_SSTATUS,
106     CSR_SEDELEG,
107     CSR_SIDELEG,
108     CSR_SIE,
109     CSR_STVEC,
110     CSR_SCOUNTEREN,
111     CSR_SSCRATCH,
112     CSR_SEPC,
113     CSR_SCAUSE,
114     CSR_STVAL,
115     CSR_SIP,
116     CSR_SATP,
117     CSR_MVENDORID,
118     CSR_MARCHID,
119     CSR_MIMPID,
120     CSR_MHARTID,
121     CSR_MSTATUS,
122     CSR_MISA,
123     CSR_MEDELEG,
124     CSR_MIDELEG,
125     CSR_MIE,
126     CSR_MTVEC,
127     CSR_MCOUNTEREN,
128     CSR_MSCRATCH,
129     CSR_MEPC,
130     CSR_MCAUSE,
131     CSR_MTVAL,
132     CSR_MIP,
133     CSR_MTINST,
134     CSR_MTVAL2,
135     CSR_PMPCFG0,
136     CSR_PMPCFG1,
137     CSR_PMPCFG2,
138     CSR_PMPCFG3,
139     CSR_PMPADDR0,
140     CSR_PMPADDR1,
141     CSR_PMPADDR2,
142     CSR_PMPADDR3,
143     CSR_PMPADDR4,
144     CSR_PMPADDR5,
145     CSR_PMPADDR6,
146     CSR_PMPADDR7,
147     CSR_PMPADDR8,
148     CSR_PMPADDR9,
149     CSR_PMPADDR10,
150     CSR_PMPADDR11,
151     CSR_PMPADDR12,
152     CSR_PMPADDR13,
153     CSR_PMPADDR14,
154     CSR_PMPADDR15,
155     CSR_MCYCLE,
156     CSR_MINSTRET,
157     CSR_MHPMCOUNTER3,
158     CSR_MHPMCOUNTER4,
159     CSR_MHPMCOUNTER5,
160     CSR_MHPMCOUNTER6,
161     CSR_MHPMCOUNTER7,
162     CSR_MHPMCOUNTER8,
163     CSR_MHPMCOUNTER9,
164     CSR_MHPMCOUNTER10,
165     CSR_MHPMCOUNTER11,
166     CSR_MHPMCOUNTER12,
167     CSR_MHPMCOUNTER13,
168     CSR_MHPMCOUNTER14,
169     CSR_MHPMCOUNTER15,
170     CSR_MHPMCOUNTER16,
171     CSR_MHPMCOUNTER17,
172     CSR_MHPMCOUNTER18,
173     CSR_MHPMCOUNTER19,
174     CSR_MHPMCOUNTER20,
175     CSR_MHPMCOUNTER21,
176     CSR_MHPMCOUNTER22,
177     CSR_MHPMCOUNTER23,
178     CSR_MHPMCOUNTER24,
179     CSR_MHPMCOUNTER25,
180     CSR_MHPMCOUNTER26,
181     CSR_MHPMCOUNTER27,
182     CSR_MHPMCOUNTER28,
183     CSR_MHPMCOUNTER29,
184     CSR_MHPMCOUNTER30,
185     CSR_MHPMCOUNTER31,
186     CSR_MCYCLEH,
187     CSR_MINSTRETH,
188     CSR_MHPMCOUNTER3H,
189     CSR_MHPMCOUNTER4H,
190     CSR_MHPMCOUNTER5H,
191     CSR_MHPMCOUNTER6H,
192     CSR_MHPMCOUNTER7H,
193     CSR_MHPMCOUNTER8H,
194     CSR_MHPMCOUNTER9H,
195     CSR_MHPMCOUNTER10H,
196     CSR_MHPMCOUNTER11H,
197     CSR_MHPMCOUNTER12H,
198     CSR_MHPMCOUNTER13H,
199     CSR_MHPMCOUNTER14H,
200     CSR_MHPMCOUNTER15H,
201     CSR_MHPMCOUNTER16H,
202     CSR_MHPMCOUNTER17H,
203     CSR_MHPMCOUNTER18H,
204     CSR_MHPMCOUNTER19H,
205     CSR_MHPMCOUNTER20H,
206     CSR_MHPMCOUNTER21H,
207     CSR_MHPMCOUNTER22H,
208     CSR_MHPMCOUNTER23H,
209     CSR_MHPMCOUNTER24H,
210     CSR_MHPMCOUNTER25H,
211     CSR_MHPMCOUNTER26H,
212     CSR_MHPMCOUNTER27H,
213     CSR_MHPMCOUNTER28H,
214     CSR_MHPMCOUNTER29H,
215     CSR_MHPMCOUNTER30H,
216     CSR_MHPMCOUNTER31H,
217     CSR_MHPMEVENT3,
218     CSR_MHPMEVENT4,
219     CSR_MHPMEVENT5,
220     CSR_MHPMEVENT6,
221     CSR_MHPMEVENT7,
222     CSR_MHPMEVENT8,
223     CSR_MHPMEVENT9,
224     CSR_MHPMEVENT10,
225     CSR_MHPMEVENT11,
226     CSR_MHPMEVENT12,
227     CSR_MHPMEVENT13,
228     CSR_MHPMEVENT14,
229     CSR_MHPMEVENT15,
230     CSR_MHPMEVENT16,
231     CSR_MHPMEVENT17,
232     CSR_MHPMEVENT18,
233     CSR_MHPMEVENT19,
234     CSR_MHPMEVENT20,
235     CSR_MHPMEVENT21,
236     CSR_MHPMEVENT22,
237     CSR_MHPMEVENT23,
238     CSR_MHPMEVENT24,
239     CSR_MHPMEVENT25,
240     CSR_MHPMEVENT26,
241     CSR_MHPMEVENT27,
242     CSR_MHPMEVENT28,
243     CSR_MHPMEVENT29,
244     CSR_MHPMEVENT30,
245     CSR_MHPMEVENT31,
246     CSR_TSELECT,
247     CSR_TDATA1,
248     CSR_TDATA2,
249     CSR_TDATA3,
250     CSR_DCSR,
251     CSR_DPC,
252     CSR_DSCRATCH,
253     CSR_HSTATUS,
254     CSR_HEDELEG,
255     CSR_HIDELEG,
256     CSR_HIE,
257     CSR_HCOUNTEREN,
258     CSR_HTVAL,
259     CSR_HIP,
260     CSR_HTINST,
261     CSR_HGATP,
262     CSR_MBASE,
263     CSR_MBOUND,
264     CSR_MIBASE,
265     CSR_MIBOUND,
266     CSR_MDBASE,
267     CSR_MDBOUND,
268     CSR_MUCOUNTEREN,
269     CSR_MSCOUNTEREN,
270     CSR_MHCOUNTEREN,
271 };
272 
273 int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
274 {
275     RISCVCPU *cpu = RISCV_CPU(cs);
276     CPURISCVState *env = &cpu->env;
277 
278     if (n < 32) {
279         return gdb_get_regl(mem_buf, env->gpr[n]);
280     } else if (n == 32) {
281         return gdb_get_regl(mem_buf, env->pc);
282     }
283     return 0;
284 }
285 
286 int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
287 {
288     RISCVCPU *cpu = RISCV_CPU(cs);
289     CPURISCVState *env = &cpu->env;
290 
291     if (n == 0) {
292         /* discard writes to x0 */
293         return sizeof(target_ulong);
294     } else if (n < 32) {
295         env->gpr[n] = ldtul_p(mem_buf);
296         return sizeof(target_ulong);
297     } else if (n == 32) {
298         env->pc = ldtul_p(mem_buf);
299         return sizeof(target_ulong);
300     }
301     return 0;
302 }
303 
304 static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
305 {
306     if (n < 32) {
307         if (env->misa & RVD) {
308             return gdb_get_reg64(buf, env->fpr[n]);
309         }
310         if (env->misa & RVF) {
311             return gdb_get_reg32(buf, env->fpr[n]);
312         }
313     /* there is hole between ft11 and fflags in fpu.xml */
314     } else if (n < 36 && n > 32) {
315         target_ulong val = 0;
316         int result;
317         /*
318          * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
319          * register 33, so we recalculate the map index.
320          * This also works for CSR_FRM and CSR_FCSR.
321          */
322         result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], &val,
323                                    0, 0);
324         if (result == 0) {
325             return gdb_get_regl(buf, val);
326         }
327     }
328     return 0;
329 }
330 
331 static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
332 {
333     if (n < 32) {
334         env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
335         return sizeof(uint64_t);
336     /* there is hole between ft11 and fflags in fpu.xml */
337     } else if (n < 36 && n > 32) {
338         target_ulong val = ldtul_p(mem_buf);
339         int result;
340         /*
341          * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
342          * register 33, so we recalculate the map index.
343          * This also works for CSR_FRM and CSR_FCSR.
344          */
345         result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], NULL,
346                                    val, -1);
347         if (result == 0) {
348             return sizeof(target_ulong);
349         }
350     }
351     return 0;
352 }
353 
354 static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
355 {
356     if (n < ARRAY_SIZE(csr_register_map)) {
357         target_ulong val = 0;
358         int result;
359 
360         result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0);
361         if (result == 0) {
362             return gdb_get_regl(buf, val);
363         }
364     }
365     return 0;
366 }
367 
368 static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
369 {
370     if (n < ARRAY_SIZE(csr_register_map)) {
371         target_ulong val = ldtul_p(mem_buf);
372         int result;
373 
374         result = riscv_csrrw_debug(env, csr_register_map[n], NULL, val, -1);
375         if (result == 0) {
376             return sizeof(target_ulong);
377         }
378     }
379     return 0;
380 }
381 
382 static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n)
383 {
384     if (n == 0) {
385 #ifdef CONFIG_USER_ONLY
386         return gdb_get_regl(buf, 0);
387 #else
388         return gdb_get_regl(buf, cs->priv);
389 #endif
390     }
391     return 0;
392 }
393 
394 static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
395 {
396     if (n == 0) {
397 #ifndef CONFIG_USER_ONLY
398         cs->priv = ldtul_p(mem_buf) & 0x3;
399         if (cs->priv == PRV_H) {
400             cs->priv = PRV_S;
401         }
402 #endif
403         return sizeof(target_ulong);
404     }
405     return 0;
406 }
407 
408 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
409 {
410     RISCVCPU *cpu = RISCV_CPU(cs);
411     CPURISCVState *env = &cpu->env;
412     if (env->misa & RVD) {
413         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
414                                  36, "riscv-64bit-fpu.xml", 0);
415     } else if (env->misa & RVF) {
416         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
417                                  36, "riscv-32bit-fpu.xml", 0);
418     }
419 #if defined(TARGET_RISCV32)
420     gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
421                              240, "riscv-32bit-csr.xml", 0);
422 
423     gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
424                              1, "riscv-32bit-virtual.xml", 0);
425 #elif defined(TARGET_RISCV64)
426     gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
427                              240, "riscv-64bit-csr.xml", 0);
428 
429     gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
430                              1, "riscv-64bit-virtual.xml", 0);
431 #endif
432 }
433