1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include "qemu/osdep.h"
20#include "exec/gdbstub.h"
21#include "cpu.h"
22
23int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
24{
25 RISCVCPU *cpu = RISCV_CPU(cs);
26 CPURISCVState *env = &cpu->env;
27
28 if (n < 32) {
29 return gdb_get_regl(mem_buf, env->gpr[n]);
30 } else if (n == 32) {
31 return gdb_get_regl(mem_buf, env->pc);
32 }
33 return 0;
34}
35
36int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
37{
38 RISCVCPU *cpu = RISCV_CPU(cs);
39 CPURISCVState *env = &cpu->env;
40
41 if (n == 0) {
42
43 return sizeof(target_ulong);
44 } else if (n < 32) {
45 env->gpr[n] = ldtul_p(mem_buf);
46 return sizeof(target_ulong);
47 } else if (n == 32) {
48 env->pc = ldtul_p(mem_buf);
49 return sizeof(target_ulong);
50 }
51 return 0;
52}
53
54static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
55{
56 if (n < 32) {
57 if (env->misa_ext & RVD) {
58 return gdb_get_reg64(buf, env->fpr[n]);
59 }
60 if (env->misa_ext & RVF) {
61 return gdb_get_reg32(buf, env->fpr[n]);
62 }
63
64 } else if (n < 36 && n > 32) {
65 target_ulong val = 0;
66 int result;
67
68
69
70
71
72 result = riscv_csrrw_debug(env, n - 32, &val,
73 0, 0);
74 if (result == RISCV_EXCP_NONE) {
75 return gdb_get_regl(buf, val);
76 }
77 }
78 return 0;
79}
80
81static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
82{
83 if (n < 32) {
84 env->fpr[n] = ldq_p(mem_buf);
85 return sizeof(uint64_t);
86
87 } else if (n < 36 && n > 32) {
88 target_ulong val = ldtul_p(mem_buf);
89 int result;
90
91
92
93
94
95 result = riscv_csrrw_debug(env, n - 32, NULL,
96 val, -1);
97 if (result == RISCV_EXCP_NONE) {
98 return sizeof(target_ulong);
99 }
100 }
101 return 0;
102}
103
104static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
105{
106 if (n < CSR_TABLE_SIZE) {
107 target_ulong val = 0;
108 int result;
109
110 result = riscv_csrrw_debug(env, n, &val, 0, 0);
111 if (result == RISCV_EXCP_NONE) {
112 return gdb_get_regl(buf, val);
113 }
114 }
115 return 0;
116}
117
118static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
119{
120 if (n < CSR_TABLE_SIZE) {
121 target_ulong val = ldtul_p(mem_buf);
122 int result;
123
124 result = riscv_csrrw_debug(env, n, NULL, val, -1);
125 if (result == RISCV_EXCP_NONE) {
126 return sizeof(target_ulong);
127 }
128 }
129 return 0;
130}
131
132static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n)
133{
134 if (n == 0) {
135#ifdef CONFIG_USER_ONLY
136 return gdb_get_regl(buf, 0);
137#else
138 return gdb_get_regl(buf, cs->priv);
139#endif
140 }
141 return 0;
142}
143
144static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
145{
146 if (n == 0) {
147#ifndef CONFIG_USER_ONLY
148 cs->priv = ldtul_p(mem_buf) & 0x3;
149 if (cs->priv == PRV_H) {
150 cs->priv = PRV_S;
151 }
152#endif
153 return sizeof(target_ulong);
154 }
155 return 0;
156}
157
158static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
159{
160 RISCVCPU *cpu = RISCV_CPU(cs);
161 CPURISCVState *env = &cpu->env;
162 GString *s = g_string_new(NULL);
163 riscv_csr_predicate_fn predicate;
164 int bitsize = 16 << env->misa_mxl_max;
165 int i;
166
167 g_string_printf(s, "<?xml version=\"1.0\"?>");
168 g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
169 g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
170
171 for (i = 0; i < CSR_TABLE_SIZE; i++) {
172 predicate = csr_ops[i].predicate;
173 if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
174 if (csr_ops[i].name) {
175 g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
176 } else {
177 g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
178 }
179 g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
180 g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
181 }
182 }
183
184 g_string_append_printf(s, "</feature>");
185
186 cpu->dyn_csr_xml = g_string_free(s, false);
187 return CSR_TABLE_SIZE;
188}
189
190void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
191{
192 RISCVCPU *cpu = RISCV_CPU(cs);
193 CPURISCVState *env = &cpu->env;
194 if (env->misa_ext & RVD) {
195 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
196 36, "riscv-64bit-fpu.xml", 0);
197 } else if (env->misa_ext & RVF) {
198 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
199 36, "riscv-32bit-fpu.xml", 0);
200 }
201#if defined(TARGET_RISCV32)
202 gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
203 1, "riscv-32bit-virtual.xml", 0);
204#elif defined(TARGET_RISCV64)
205 gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
206 1, "riscv-64bit-virtual.xml", 0);
207#endif
208
209 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
210 riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs),
211 "riscv-csr.xml", 0);
212}
213