xref: /openbmc/qemu/target/riscv/gdbstub.c (revision 19f70347)
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_PMPCFG0,
134     CSR_PMPCFG1,
135     CSR_PMPCFG2,
136     CSR_PMPCFG3,
137     CSR_PMPADDR0,
138     CSR_PMPADDR1,
139     CSR_PMPADDR2,
140     CSR_PMPADDR3,
141     CSR_PMPADDR4,
142     CSR_PMPADDR5,
143     CSR_PMPADDR6,
144     CSR_PMPADDR7,
145     CSR_PMPADDR8,
146     CSR_PMPADDR9,
147     CSR_PMPADDR10,
148     CSR_PMPADDR11,
149     CSR_PMPADDR12,
150     CSR_PMPADDR13,
151     CSR_PMPADDR14,
152     CSR_PMPADDR15,
153     CSR_MCYCLE,
154     CSR_MINSTRET,
155     CSR_MHPMCOUNTER3,
156     CSR_MHPMCOUNTER4,
157     CSR_MHPMCOUNTER5,
158     CSR_MHPMCOUNTER6,
159     CSR_MHPMCOUNTER7,
160     CSR_MHPMCOUNTER8,
161     CSR_MHPMCOUNTER9,
162     CSR_MHPMCOUNTER10,
163     CSR_MHPMCOUNTER11,
164     CSR_MHPMCOUNTER12,
165     CSR_MHPMCOUNTER13,
166     CSR_MHPMCOUNTER14,
167     CSR_MHPMCOUNTER15,
168     CSR_MHPMCOUNTER16,
169     CSR_MHPMCOUNTER17,
170     CSR_MHPMCOUNTER18,
171     CSR_MHPMCOUNTER19,
172     CSR_MHPMCOUNTER20,
173     CSR_MHPMCOUNTER21,
174     CSR_MHPMCOUNTER22,
175     CSR_MHPMCOUNTER23,
176     CSR_MHPMCOUNTER24,
177     CSR_MHPMCOUNTER25,
178     CSR_MHPMCOUNTER26,
179     CSR_MHPMCOUNTER27,
180     CSR_MHPMCOUNTER28,
181     CSR_MHPMCOUNTER29,
182     CSR_MHPMCOUNTER30,
183     CSR_MHPMCOUNTER31,
184     CSR_MCYCLEH,
185     CSR_MINSTRETH,
186     CSR_MHPMCOUNTER3H,
187     CSR_MHPMCOUNTER4H,
188     CSR_MHPMCOUNTER5H,
189     CSR_MHPMCOUNTER6H,
190     CSR_MHPMCOUNTER7H,
191     CSR_MHPMCOUNTER8H,
192     CSR_MHPMCOUNTER9H,
193     CSR_MHPMCOUNTER10H,
194     CSR_MHPMCOUNTER11H,
195     CSR_MHPMCOUNTER12H,
196     CSR_MHPMCOUNTER13H,
197     CSR_MHPMCOUNTER14H,
198     CSR_MHPMCOUNTER15H,
199     CSR_MHPMCOUNTER16H,
200     CSR_MHPMCOUNTER17H,
201     CSR_MHPMCOUNTER18H,
202     CSR_MHPMCOUNTER19H,
203     CSR_MHPMCOUNTER20H,
204     CSR_MHPMCOUNTER21H,
205     CSR_MHPMCOUNTER22H,
206     CSR_MHPMCOUNTER23H,
207     CSR_MHPMCOUNTER24H,
208     CSR_MHPMCOUNTER25H,
209     CSR_MHPMCOUNTER26H,
210     CSR_MHPMCOUNTER27H,
211     CSR_MHPMCOUNTER28H,
212     CSR_MHPMCOUNTER29H,
213     CSR_MHPMCOUNTER30H,
214     CSR_MHPMCOUNTER31H,
215     CSR_MHPMEVENT3,
216     CSR_MHPMEVENT4,
217     CSR_MHPMEVENT5,
218     CSR_MHPMEVENT6,
219     CSR_MHPMEVENT7,
220     CSR_MHPMEVENT8,
221     CSR_MHPMEVENT9,
222     CSR_MHPMEVENT10,
223     CSR_MHPMEVENT11,
224     CSR_MHPMEVENT12,
225     CSR_MHPMEVENT13,
226     CSR_MHPMEVENT14,
227     CSR_MHPMEVENT15,
228     CSR_MHPMEVENT16,
229     CSR_MHPMEVENT17,
230     CSR_MHPMEVENT18,
231     CSR_MHPMEVENT19,
232     CSR_MHPMEVENT20,
233     CSR_MHPMEVENT21,
234     CSR_MHPMEVENT22,
235     CSR_MHPMEVENT23,
236     CSR_MHPMEVENT24,
237     CSR_MHPMEVENT25,
238     CSR_MHPMEVENT26,
239     CSR_MHPMEVENT27,
240     CSR_MHPMEVENT28,
241     CSR_MHPMEVENT29,
242     CSR_MHPMEVENT30,
243     CSR_MHPMEVENT31,
244     CSR_TSELECT,
245     CSR_TDATA1,
246     CSR_TDATA2,
247     CSR_TDATA3,
248     CSR_DCSR,
249     CSR_DPC,
250     CSR_DSCRATCH,
251     CSR_HSTATUS,
252     CSR_HEDELEG,
253     CSR_HIDELEG,
254     CSR_HIE,
255     CSR_HTVEC,
256     CSR_HSCRATCH,
257     CSR_HEPC,
258     CSR_HCAUSE,
259     CSR_HBADADDR,
260     CSR_HIP,
261     CSR_MBASE,
262     CSR_MBOUND,
263     CSR_MIBASE,
264     CSR_MIBOUND,
265     CSR_MDBASE,
266     CSR_MDBOUND,
267     CSR_MUCOUNTEREN,
268     CSR_MSCOUNTEREN,
269     CSR_MHCOUNTEREN,
270 };
271 
272 int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
273 {
274     RISCVCPU *cpu = RISCV_CPU(cs);
275     CPURISCVState *env = &cpu->env;
276 
277     if (n < 32) {
278         return gdb_get_regl(mem_buf, env->gpr[n]);
279     } else if (n == 32) {
280         return gdb_get_regl(mem_buf, env->pc);
281     }
282     return 0;
283 }
284 
285 int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
286 {
287     RISCVCPU *cpu = RISCV_CPU(cs);
288     CPURISCVState *env = &cpu->env;
289 
290     if (n == 0) {
291         /* discard writes to x0 */
292         return sizeof(target_ulong);
293     } else if (n < 32) {
294         env->gpr[n] = ldtul_p(mem_buf);
295         return sizeof(target_ulong);
296     } else if (n == 32) {
297         env->pc = ldtul_p(mem_buf);
298         return sizeof(target_ulong);
299     }
300     return 0;
301 }
302 
303 static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
304 {
305     if (n < 32) {
306         if (env->misa & RVD) {
307             return gdb_get_reg64(mem_buf, env->fpr[n]);
308         }
309         if (env->misa & RVF) {
310             return gdb_get_reg32(mem_buf, env->fpr[n]);
311         }
312     /* there is hole between ft11 and fflags in fpu.xml */
313     } else if (n < 36 && n > 32) {
314         target_ulong val = 0;
315         int result;
316         /*
317          * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
318          * register 33, so we recalculate the map index.
319          * This also works for CSR_FRM and CSR_FCSR.
320          */
321         result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], &val,
322                                    0, 0);
323         if (result == 0) {
324             return gdb_get_regl(mem_buf, val);
325         }
326     }
327     return 0;
328 }
329 
330 static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
331 {
332     if (n < 32) {
333         env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
334         return sizeof(uint64_t);
335     /* there is hole between ft11 and fflags in fpu.xml */
336     } else if (n < 36 && n > 32) {
337         target_ulong val = ldtul_p(mem_buf);
338         int result;
339         /*
340          * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
341          * register 33, so we recalculate the map index.
342          * This also works for CSR_FRM and CSR_FCSR.
343          */
344         result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], NULL,
345                                    val, -1);
346         if (result == 0) {
347             return sizeof(target_ulong);
348         }
349     }
350     return 0;
351 }
352 
353 static int riscv_gdb_get_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
354 {
355     if (n < ARRAY_SIZE(csr_register_map)) {
356         target_ulong val = 0;
357         int result;
358 
359         result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0);
360         if (result == 0) {
361             return gdb_get_regl(mem_buf, val);
362         }
363     }
364     return 0;
365 }
366 
367 static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
368 {
369     if (n < ARRAY_SIZE(csr_register_map)) {
370         target_ulong val = ldtul_p(mem_buf);
371         int result;
372 
373         result = riscv_csrrw_debug(env, csr_register_map[n], NULL, val, -1);
374         if (result == 0) {
375             return sizeof(target_ulong);
376         }
377     }
378     return 0;
379 }
380 
381 static int riscv_gdb_get_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
382 {
383     if (n == 0) {
384 #ifdef CONFIG_USER_ONLY
385         return gdb_get_regl(mem_buf, 0);
386 #else
387         return gdb_get_regl(mem_buf, cs->priv);
388 #endif
389     }
390     return 0;
391 }
392 
393 static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
394 {
395     if (n == 0) {
396 #ifndef CONFIG_USER_ONLY
397         cs->priv = ldtul_p(mem_buf) & 0x3;
398         if (cs->priv == PRV_H) {
399             cs->priv = PRV_S;
400         }
401 #endif
402         return sizeof(target_ulong);
403     }
404     return 0;
405 }
406 
407 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
408 {
409     RISCVCPU *cpu = RISCV_CPU(cs);
410     CPURISCVState *env = &cpu->env;
411     if (env->misa & RVD) {
412         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
413                                  36, "riscv-64bit-fpu.xml", 0);
414     } else if (env->misa & RVF) {
415         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
416                                  36, "riscv-32bit-fpu.xml", 0);
417     }
418 #if defined(TARGET_RISCV32)
419     gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
420                              240, "riscv-32bit-csr.xml", 0);
421 
422     gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
423                              1, "riscv-32bit-virtual.xml", 0);
424 #elif defined(TARGET_RISCV64)
425     gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
426                              240, "riscv-64bit-csr.xml", 0);
427 
428     gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
429                              1, "riscv-64bit-virtual.xml", 0);
430 #endif
431 }
432