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