master
c 380 lines 10.5 KB
Raw
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 "gdbstub/helpers.h"
22 #include "cpu.h"
23 #include "internals.h"
24 #include "target/riscv/tcg/csr.h"
25
26 struct TypeSize {
27 const char *gdb_type;
28 const char *id;
29 int size;
30 const char suffix;
31 };
32
33 static const struct TypeSize vec_lanes[] = {
34 /* quads */
35 { "uint128", "quads", 128, 'q' },
36 /* 64 bit */
37 { "uint64", "longs", 64, 'l' },
38 /* 32 bit */
39 { "uint32", "words", 32, 'w' },
40 /* 16 bit */
41 { "uint16", "shorts", 16, 's' },
42 /*
43 * TODO: currently there is no reliable way of telling
44 * if the remote gdb actually understands ieee_half so
45 * we don't expose it in the target description for now.
46 * { "ieee_half", 16, 'h', 'f' },
47 */
48 /* bytes */
49 { "uint8", "bytes", 8, 'b' },
50 };
51
52 static uint64_t ldn(CPURISCVState *env, uint8_t *mem_buf, size_t regsz)
53 {
54 return (mo_endian_env(env) == MO_LE ? ldn_le_p : ldn_be_p)(mem_buf, regsz);
55 }
56
57 int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
58 {
59 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
60 RISCVCPU *cpu = RISCV_CPU(cs);
61 CPURISCVState *env = &cpu->env;
62 uint64_t tmp;
63
64 if (n < 32) {
65 tmp = env->gpr[n];
66 } else if (n == 32) {
67 tmp = env->pc;
68 } else {
69 return 0;
70 }
71
72 switch (mcc->def->misa_mxl_max) {
73 case MXL_RV32:
74 return gdb_get_reg32(mem_buf, tmp);
75 case MXL_RV64:
76 case MXL_RV128:
77 return gdb_get_reg64(mem_buf, tmp);
78 default:
79 g_assert_not_reached();
80 }
81 return 0;
82 }
83
84 int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
85 {
86 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
87 RISCVCPU *cpu = RISCV_CPU(cs);
88 CPURISCVState *env = &cpu->env;
89 const size_t regsize = mcc->def->misa_mxl_max == MXL_RV32 ? 4 : 8;
90 uint64_t tmp = ldn(env, mem_buf, regsize);
91
92 if (env->xl < MXL_RV64) {
93 tmp = (int32_t)tmp;
94 }
95
96 if (n > 0 && n < 32) {
97 env->gpr[n] = tmp;
98 } else if (n == 32) {
99 env->pc = tmp;
100 }
101
102 return regsize;
103 }
104
105 static int riscv_gdb_get_fpu(CPUState *cs, GByteArray *buf, int n)
106 {
107 RISCVCPU *cpu = RISCV_CPU(cs);
108 CPURISCVState *env = &cpu->env;
109
110 if (n < 32) {
111 if (env->misa_ext & RVD) {
112 return gdb_get_reg64(buf, env->fpr[n]);
113 }
114 if (env->misa_ext & RVF) {
115 return gdb_get_reg32(buf, env->fpr[n]);
116 }
117 }
118 return 0;
119 }
120
121 static int riscv_gdb_set_fpu(CPUState *cs, uint8_t *mem_buf, int n)
122 {
123 RISCVCPU *cpu = RISCV_CPU(cs);
124 CPURISCVState *env = &cpu->env;
125
126 if (n < 32) {
127 env->fpr[n] = ldn(env, mem_buf, 8); /* always 64-bit */
128 return sizeof(uint64_t);
129 }
130 return 0;
131 }
132
133 static int riscv_gdb_get_vector(CPUState *cs, GByteArray *buf, int n)
134 {
135 RISCVCPU *cpu = RISCV_CPU(cs);
136 CPURISCVState *env = &cpu->env;
137 uint16_t vlenb = cpu->cfg.vlenb;
138 if (n < 32) {
139 int i;
140 int cnt = 0;
141 for (i = 0; i < vlenb; i += 8) {
142 cnt += gdb_get_reg64(buf,
143 env->vreg[(n * vlenb + i) / 8]);
144 }
145 return cnt;
146 }
147
148 return 0;
149 }
150
151 static int riscv_gdb_set_vector(CPUState *cs, uint8_t *mem_buf, int n)
152 {
153 RISCVCPU *cpu = RISCV_CPU(cs);
154 CPURISCVState *env = &cpu->env;
155 uint16_t vlenb = cpu->cfg.vlenb;
156 if (n < 32) {
157 int i;
158 for (i = 0; i < vlenb; i += 8) {
159 env->vreg[(n * vlenb + i) / 8] = ldn(env, mem_buf + i, 8);
160 }
161 return vlenb;
162 }
163
164 return 0;
165 }
166
167 #ifdef CONFIG_TCG
168 static int riscv_gdb_get_csr(CPUState *cs, GByteArray *buf, int n)
169 {
170 RISCVCPU *cpu = RISCV_CPU(cs);
171 CPURISCVState *env = &cpu->env;
172
173 if (n < CSR_TABLE_SIZE) {
174 target_ulong val = 0;
175 int result;
176
177 result = riscv_csrrw_debug(env, n, &val, 0, 0);
178 if (result == RISCV_EXCP_NONE) {
179 return gdb_get_regl(buf, val);
180 }
181 }
182 return 0;
183 }
184
185 static int riscv_gdb_set_csr(CPUState *cs, uint8_t *mem_buf, int n)
186 {
187 RISCVCPU *cpu = RISCV_CPU(cs);
188 CPURISCVState *env = &cpu->env;
189 const unsigned regsz = riscv_cpu_is_32bit(cpu) ? 4 : 8;
190
191 if (n < CSR_TABLE_SIZE) {
192 uint64_t val = ldn(env, mem_buf, regsz);
193 int result;
194
195 result = riscv_csrrw_debug(env, n, NULL, val, -1);
196 if (result == RISCV_EXCP_NONE) {
197 return regsz;
198 }
199 }
200 return 0;
201 }
202
203 static int riscv_gdb_get_virtual(CPUState *cs, GByteArray *buf, int n)
204 {
205 if (n == 0) {
206 #ifdef CONFIG_USER_ONLY
207 return gdb_get_regl(buf, 0);
208 #else
209 RISCVCPU *cpu = RISCV_CPU(cs);
210 CPURISCVState *env = &cpu->env;
211
212 /* Per RiscV debug spec v1.0.0 rc4 */
213 uint32_t vbit = (env->virt_enabled) ? BIT(2) : 0;
214
215 return gdb_get_regl(buf, env->priv | vbit);
216 #endif
217 }
218 return 0;
219 }
220
221 static int riscv_gdb_set_virtual(CPUState *cs, uint8_t *mem_buf, int n)
222 {
223 if (n == 0) {
224 RISCVCPU *cpu = RISCV_CPU(cs);
225 const unsigned regsz = riscv_cpu_is_32bit(cpu) ? 4 : 8;
226 #ifndef CONFIG_USER_ONLY
227 CPURISCVState *env = &cpu->env;
228 privilege_mode_t new_priv = ldn(env, mem_buf, regsz) & 0x3;
229 bool new_virt = 0;
230
231 if (new_priv == PRV_RESERVED) {
232 new_priv = PRV_S;
233 }
234
235 if (new_priv != PRV_M) {
236 new_virt = (ldn(env, mem_buf, regsz) & BIT(2)) >> 2;
237 }
238
239 if (riscv_has_ext(env, RVH) && new_virt != env->virt_enabled) {
240 riscv_cpu_swap_hypervisor_regs(env);
241 }
242
243 riscv_cpu_set_mode(env, new_priv, new_virt);
244 #endif
245 return regsz;
246 }
247 return 0;
248 }
249
250 static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
251 {
252 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
253 RISCVCPU *cpu = RISCV_CPU(cs);
254 CPURISCVState *env = &cpu->env;
255 GDBFeatureBuilder builder;
256 riscv_csr_predicate_fn predicate;
257 int bitsize = riscv_cpu_max_xlen(mcc);
258 const char *name;
259 int i;
260
261 #if !defined(CONFIG_USER_ONLY)
262 env->debugger = true;
263 #endif
264
265 /* Until gdb knows about 128-bit registers */
266 if (bitsize > 64) {
267 bitsize = 64;
268 }
269
270 gdb_feature_builder_init(&builder, &cpu->dyn_csr_feature,
271 "org.gnu.gdb.riscv.csr", "riscv-csr.xml",
272 base_reg);
273
274 for (i = 0; i < CSR_TABLE_SIZE; i++) {
275 if (env->priv_ver < csr_ops[i].min_priv_ver) {
276 continue;
277 }
278 predicate = csr_ops[i].predicate;
279 if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
280 name = csr_ops[i].name;
281 if (!name) {
282 name = g_strdup_printf("csr%03x", i);
283 }
284
285 gdb_feature_builder_append_reg(&builder, name, bitsize, i,
286 "int", NULL);
287 }
288 }
289
290 gdb_feature_builder_end(&builder);
291
292 #if !defined(CONFIG_USER_ONLY)
293 env->debugger = false;
294 #endif
295
296 return &cpu->dyn_csr_feature;
297 }
298 #endif /* CONFIG_TCG */
299
300 static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
301 {
302 RISCVCPU *cpu = RISCV_CPU(cs);
303 int bitsize = cpu->cfg.vlenb << 3;
304 GDBFeatureBuilder builder;
305 int i;
306
307 gdb_feature_builder_init(&builder, &cpu->dyn_vreg_feature,
308 "org.gnu.gdb.riscv.vector", "riscv-vector.xml",
309 base_reg);
310
311 /* First define types and totals in a whole VL */
312 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
313 int count = bitsize / vec_lanes[i].size;
314 gdb_feature_builder_append_tag(
315 &builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
316 vec_lanes[i].id, vec_lanes[i].gdb_type, count);
317 }
318
319 /* Define unions */
320 gdb_feature_builder_append_tag(&builder, "<union id=\"riscv_vector\">");
321 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
322 gdb_feature_builder_append_tag(&builder,
323 "<field name=\"%c\" type=\"%s\"/>",
324 vec_lanes[i].suffix, vec_lanes[i].id);
325 }
326 gdb_feature_builder_append_tag(&builder, "</union>");
327
328 /* Define vector registers */
329 for (i = 0; i < 32; i++) {
330 gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
331 bitsize, i, "riscv_vector", "vector");
332 }
333
334 gdb_feature_builder_end(&builder);
335
336 return &cpu->dyn_vreg_feature;
337 }
338
339 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
340 {
341 RISCVCPU *cpu = RISCV_CPU(cs);
342 CPURISCVState *env = &cpu->env;
343 if (env->misa_ext & RVD) {
344 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
345 gdb_find_static_feature("riscv-64bit-fpu.xml"));
346 } else if (env->misa_ext & RVF) {
347 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
348 gdb_find_static_feature("riscv-32bit-fpu.xml"));
349 }
350 if (cpu->cfg.ext_zve32x) {
351 gdb_register_coprocessor(cs, riscv_gdb_get_vector,
352 riscv_gdb_set_vector,
353 ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs));
354 }
355
356 #ifdef CONFIG_TCG
357 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
358
359 switch (mcc->def->misa_mxl_max) {
360 case MXL_RV32:
361 gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
362 riscv_gdb_set_virtual,
363 gdb_find_static_feature("riscv-32bit-virtual.xml"));
364 break;
365 case MXL_RV64:
366 case MXL_RV128:
367 gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
368 riscv_gdb_set_virtual,
369 gdb_find_static_feature("riscv-64bit-virtual.xml"));
370 break;
371 default:
372 g_assert_not_reached();
373 }
374
375 if (cpu->cfg.ext_zicsr) {
376 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
377 riscv_gen_dynamic_csr_feature(cs, cs->gdb_num_regs));
378 }
379 #endif
380 }