master
c 575 lines 17.5 KB
Raw
1 /*
2 * ARM gdb server stub
3 *
4 * Copyright (c) 2003-2005 Fabrice Bellard
5 * Copyright (c) 2013 SUSE LINUX Products GmbH
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "exec/gdbstub.h"
23 #include "gdbstub/helpers.h"
24 #include "gdbstub/commands.h"
25 #include "system/tcg.h"
26 #include "internals.h"
27 #include "cpu-features.h"
28 #include "cpregs.h"
29
30 typedef struct RegisterSysregFeatureParam {
31 CPUState *cs;
32 GDBFeatureBuilder builder;
33 int n;
34 } RegisterSysregFeatureParam;
35
36 /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect
37 whatever the target description contains. Due to a historical mishap
38 the FPA registers appear in between core integer regs and the CPSR.
39 We hack round this by giving the FPA regs zero size when talking to a
40 newer gdb. */
41
42 int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
43 {
44 ARMCPU *cpu = ARM_CPU(cs);
45 CPUARMState *env = &cpu->env;
46
47 if (arm_gdbstub_is_aarch64(cpu)) {
48 return aarch64_cpu_gdb_read_register(cs, mem_buf, n);
49 }
50
51 if (n < 16) {
52 /* Core integer register. */
53 return gdb_get_reg32(mem_buf, env->regs[n]);
54 }
55 if (n == 25) {
56 /* CPSR, or XPSR for M-profile */
57 if (arm_feature(env, ARM_FEATURE_M)) {
58 return gdb_get_reg32(mem_buf, xpsr_read(env));
59 } else {
60 return gdb_get_reg32(mem_buf, cpsr_read(env));
61 }
62 }
63 /* Unknown register. */
64 return 0;
65 }
66
67 int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
68 {
69 ARMCPU *cpu = ARM_CPU(cs);
70 CPUARMState *env = &cpu->env;
71 uint32_t tmp;
72
73 if (arm_gdbstub_is_aarch64(cpu)) {
74 return aarch64_cpu_gdb_write_register(cs, mem_buf, n);
75 }
76
77 tmp = ldl_p(mem_buf);
78
79 /*
80 * Mask out low bits of PC to workaround gdb bugs.
81 * This avoids an assert in thumb_tr_translate_insn, because it is
82 * architecturally impossible to misalign the pc.
83 * This will probably cause problems if we ever implement the
84 * Jazelle DBX extensions.
85 */
86 if (n == 15) {
87 tmp &= ~1;
88 }
89
90 if (n < 16) {
91 /* Core integer register. */
92 if (n == 13 && arm_feature(env, ARM_FEATURE_M)) {
93 /* M profile SP low bits are always 0 */
94 tmp &= ~3;
95 }
96 env->regs[n] = tmp;
97 return 4;
98 }
99 if (n == 25) {
100 /* CPSR, or XPSR for M-profile */
101 if (arm_feature(env, ARM_FEATURE_M)) {
102 /*
103 * Don't allow writing to XPSR.Exception as it can cause
104 * a transition into or out of handler mode (it's not
105 * writable via the MSR insn so this is a reasonable
106 * restriction). Other fields are safe to update.
107 */
108 xpsr_write(env, tmp, ~XPSR_EXCP);
109 } else {
110 cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub);
111 }
112 return 4;
113 }
114 /* Unknown register. */
115 return 0;
116 }
117
118 static int vfp_gdb_get_reg(CPUState *cs, GByteArray *buf, int reg)
119 {
120 ARMCPU *cpu = ARM_CPU(cs);
121 CPUARMState *env = &cpu->env;
122 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
123
124 /* VFP data registers are always little-endian. */
125 if (reg < nregs) {
126 return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg));
127 }
128 if (arm_feature(env, ARM_FEATURE_NEON)) {
129 /* Aliases for Q regs. */
130 nregs += 16;
131 if (reg < nregs) {
132 uint64_t *q = aa32_vfp_qreg(env, reg - 32);
133 return gdb_get_reg128(buf, q[0], q[1]);
134 }
135 }
136 switch (reg - nregs) {
137 case 0:
138 return gdb_get_reg32(buf, vfp_get_fpscr(env));
139 }
140 return 0;
141 }
142
143 static int vfp_gdb_set_reg(CPUState *cs, uint8_t *buf, int reg)
144 {
145 ARMCPU *cpu = ARM_CPU(cs);
146 CPUARMState *env = &cpu->env;
147 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
148
149 if (reg < nregs) {
150 *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
151 return 8;
152 }
153 if (arm_feature(env, ARM_FEATURE_NEON)) {
154 nregs += 16;
155 if (reg < nregs) {
156 uint64_t *q = aa32_vfp_qreg(env, reg - 32);
157 q[0] = ldq_le_p(buf);
158 q[1] = ldq_le_p(buf + 8);
159 return 16;
160 }
161 }
162 switch (reg - nregs) {
163 case 0:
164 vfp_set_fpscr(env, ldl_p(buf));
165 return 4;
166 }
167 return 0;
168 }
169
170 static int vfp_gdb_get_sysreg(CPUState *cs, GByteArray *buf, int reg)
171 {
172 ARMCPU *cpu = ARM_CPU(cs);
173 CPUARMState *env = &cpu->env;
174
175 switch (reg) {
176 case 0:
177 return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
178 case 1:
179 return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
180 }
181 return 0;
182 }
183
184 static int vfp_gdb_set_sysreg(CPUState *cs, uint8_t *buf, int reg)
185 {
186 ARMCPU *cpu = ARM_CPU(cs);
187 CPUARMState *env = &cpu->env;
188
189 switch (reg) {
190 case 0:
191 env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
192 return 4;
193 case 1:
194 env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
195 return 4;
196 }
197 return 0;
198 }
199
200 static int mve_gdb_get_reg(CPUState *cs, GByteArray *buf, int reg)
201 {
202 ARMCPU *cpu = ARM_CPU(cs);
203 CPUARMState *env = &cpu->env;
204
205 switch (reg) {
206 case 0:
207 return gdb_get_reg32(buf, env->v7m.vpr);
208 default:
209 return 0;
210 }
211 }
212
213 static int mve_gdb_set_reg(CPUState *cs, uint8_t *buf, int reg)
214 {
215 ARMCPU *cpu = ARM_CPU(cs);
216 CPUARMState *env = &cpu->env;
217
218 switch (reg) {
219 case 0:
220 env->v7m.vpr = ldl_p(buf);
221 return 4;
222 default:
223 return 0;
224 }
225 }
226
227 /**
228 * arm_get/set_gdb_*: get/set a gdb register
229 * @env: the CPU state
230 * @buf: a buffer to copy to/from
231 * @reg: register number (offset from start of group)
232 *
233 * We return the number of bytes copied
234 */
235
236 static int arm_gdb_get_sysreg(CPUState *cs, GByteArray *buf, int reg)
237 {
238 ARMCPU *cpu = ARM_CPU(cs);
239 CPUARMState *env = &cpu->env;
240 const ARMCPRegInfo *ri;
241 uint32_t key;
242
243 key = cpu->dyn_sysreg_feature.data.cpregs.keys[reg];
244 ri = get_arm_cp_reginfo(cpu->cp_regs, key);
245 if (ri) {
246 switch (cpreg_field_type(ri)) {
247 case MO_64:
248 if (ri->vhe_redir_to_el2 &&
249 (arm_hcr_el2_eff(env) & HCR_E2H) &&
250 arm_current_el(env) == 2) {
251 ri = get_arm_cp_reginfo(cpu->cp_regs, ri->vhe_redir_to_el2);
252 } else if (ri->vhe_redir_to_el01) {
253 ri = get_arm_cp_reginfo(cpu->cp_regs, ri->vhe_redir_to_el01);
254 }
255 return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri));
256 case MO_32:
257 return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));
258 default:
259 g_assert_not_reached();
260 }
261 }
262 return 0;
263 }
264
265 static int arm_gdb_set_sysreg(CPUState *cs, uint8_t *buf, int reg)
266 {
267 return 0;
268 }
269
270 static void arm_gen_one_feature_sysreg(GDBFeatureBuilder *builder,
271 DynamicGDBFeatureInfo *dyn_feature,
272 ARMCPRegInfo *ri, uint32_t ri_key,
273 int bitsize, int n)
274 {
275 gdb_feature_builder_append_reg(builder, ri->name, bitsize, n,
276 "int", "cp_regs");
277
278 dyn_feature->data.cpregs.keys[n] = ri_key;
279 }
280
281 static void arm_register_sysreg_for_feature(gpointer key, gpointer value,
282 gpointer p)
283 {
284 uint32_t ri_key = (uintptr_t)key;
285 ARMCPRegInfo *ri = value;
286 RegisterSysregFeatureParam *param = p;
287 ARMCPU *cpu = ARM_CPU(param->cs);
288 CPUARMState *env = &cpu->env;
289 DynamicGDBFeatureInfo *dyn_feature = &cpu->dyn_sysreg_feature;
290
291 if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_NO_GDB))) {
292 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
293 if (ri->state == ARM_CP_STATE_AA64) {
294 arm_gen_one_feature_sysreg(&param->builder, dyn_feature,
295 ri, ri_key, 64, param->n++);
296 }
297 } else {
298 if (ri->state == ARM_CP_STATE_AA32) {
299 if (!arm_feature(env, ARM_FEATURE_EL3) &&
300 (ri->secure & ARM_CP_SECSTATE_S)) {
301 return;
302 }
303 if (ri->type & ARM_CP_64BIT) {
304 arm_gen_one_feature_sysreg(&param->builder, dyn_feature,
305 ri, ri_key, 64, param->n++);
306 } else {
307 arm_gen_one_feature_sysreg(&param->builder, dyn_feature,
308 ri, ri_key, 32, param->n++);
309 }
310 }
311 }
312 }
313 }
314
315 static GDBFeature *arm_gen_dynamic_sysreg_feature(CPUState *cs, int base_reg)
316 {
317 ARMCPU *cpu = ARM_CPU(cs);
318 RegisterSysregFeatureParam param = {cs};
319 gsize num_regs = g_hash_table_size(cpu->cp_regs);
320
321 gdb_feature_builder_init(&param.builder,
322 &cpu->dyn_sysreg_feature.desc,
323 "org.qemu.gdb.arm.sys.regs",
324 "system-registers.xml",
325 base_reg);
326 cpu->dyn_sysreg_feature.data.cpregs.keys = g_new(uint32_t, num_regs);
327 g_hash_table_foreach(cpu->cp_regs, arm_register_sysreg_for_feature, &param);
328 gdb_feature_builder_end(&param.builder);
329 return &cpu->dyn_sysreg_feature.desc;
330 }
331
332 #ifdef CONFIG_TCG
333 typedef enum {
334 M_SYSREG_MSP,
335 M_SYSREG_PSP,
336 M_SYSREG_PRIMASK,
337 M_SYSREG_CONTROL,
338 M_SYSREG_BASEPRI,
339 M_SYSREG_FAULTMASK,
340 M_SYSREG_MSPLIM,
341 M_SYSREG_PSPLIM,
342 } MProfileSysreg;
343
344 static const struct {
345 const char *name;
346 int feature;
347 } m_sysreg_def[] = {
348 [M_SYSREG_MSP] = { "msp", ARM_FEATURE_M },
349 [M_SYSREG_PSP] = { "psp", ARM_FEATURE_M },
350 [M_SYSREG_PRIMASK] = { "primask", ARM_FEATURE_M },
351 [M_SYSREG_CONTROL] = { "control", ARM_FEATURE_M },
352 [M_SYSREG_BASEPRI] = { "basepri", ARM_FEATURE_M_MAIN },
353 [M_SYSREG_FAULTMASK] = { "faultmask", ARM_FEATURE_M_MAIN },
354 [M_SYSREG_MSPLIM] = { "msplim", ARM_FEATURE_V8 },
355 [M_SYSREG_PSPLIM] = { "psplim", ARM_FEATURE_V8 },
356 };
357
358 static uint32_t *m_sysreg_ptr(CPUARMState *env, MProfileSysreg reg, bool sec)
359 {
360 uint32_t *ptr;
361
362 switch (reg) {
363 case M_SYSREG_MSP:
364 ptr = arm_v7m_get_sp_ptr(env, sec, false, true);
365 break;
366 case M_SYSREG_PSP:
367 ptr = arm_v7m_get_sp_ptr(env, sec, true, true);
368 break;
369 case M_SYSREG_MSPLIM:
370 ptr = &env->v7m.msplim[sec];
371 break;
372 case M_SYSREG_PSPLIM:
373 ptr = &env->v7m.psplim[sec];
374 break;
375 case M_SYSREG_PRIMASK:
376 ptr = &env->v7m.primask[sec];
377 break;
378 case M_SYSREG_BASEPRI:
379 ptr = &env->v7m.basepri[sec];
380 break;
381 case M_SYSREG_FAULTMASK:
382 ptr = &env->v7m.faultmask[sec];
383 break;
384 case M_SYSREG_CONTROL:
385 ptr = &env->v7m.control[sec];
386 break;
387 default:
388 return NULL;
389 }
390 return arm_feature(env, m_sysreg_def[reg].feature) ? ptr : NULL;
391 }
392
393 static int m_sysreg_get(CPUARMState *env, GByteArray *buf,
394 MProfileSysreg reg, bool secure)
395 {
396 uint32_t *ptr = m_sysreg_ptr(env, reg, secure);
397
398 if (ptr == NULL) {
399 return 0;
400 }
401 return gdb_get_reg32(buf, *ptr);
402 }
403
404 static int arm_gdb_get_m_systemreg(CPUState *cs, GByteArray *buf, int reg)
405 {
406 ARMCPU *cpu = ARM_CPU(cs);
407 CPUARMState *env = &cpu->env;
408
409 /*
410 * Here, we emulate MRS instruction, where CONTROL has a mix of
411 * banked and non-banked bits.
412 */
413 if (reg == M_SYSREG_CONTROL) {
414 return gdb_get_reg32(buf, arm_v7m_mrs_control(env, env->v7m.secure));
415 }
416 return m_sysreg_get(env, buf, reg, env->v7m.secure);
417 }
418
419 static int arm_gdb_set_m_systemreg(CPUState *cs, uint8_t *buf, int reg)
420 {
421 return 0; /* TODO */
422 }
423
424 static GDBFeature *arm_gen_dynamic_m_systemreg_feature(CPUState *cs,
425 int base_reg)
426 {
427 ARMCPU *cpu = ARM_CPU(cs);
428 CPUARMState *env = &cpu->env;
429 GDBFeatureBuilder builder;
430 int reg = 0;
431 int i;
432
433 gdb_feature_builder_init(&builder, &cpu->dyn_m_systemreg_feature.desc,
434 "org.gnu.gdb.arm.m-system", "arm-m-system.xml",
435 base_reg);
436
437 for (i = 0; i < ARRAY_SIZE(m_sysreg_def); i++) {
438 if (arm_feature(env, m_sysreg_def[i].feature)) {
439 gdb_feature_builder_append_reg(&builder, m_sysreg_def[i].name, 32,
440 reg++, "int", NULL);
441 }
442 }
443
444 gdb_feature_builder_end(&builder);
445
446 return &cpu->dyn_m_systemreg_feature.desc;
447 }
448
449 #ifndef CONFIG_USER_ONLY
450 /*
451 * For user-only, we see the non-secure registers via m_systemreg above.
452 * For secext, encode the non-secure view as even and secure view as odd.
453 */
454 static int arm_gdb_get_m_secextreg(CPUState *cs, GByteArray *buf, int reg)
455 {
456 ARMCPU *cpu = ARM_CPU(cs);
457 CPUARMState *env = &cpu->env;
458
459 return m_sysreg_get(env, buf, reg >> 1, reg & 1);
460 }
461
462 static int arm_gdb_set_m_secextreg(CPUState *cs, uint8_t *buf, int reg)
463 {
464 return 0; /* TODO */
465 }
466
467 static GDBFeature *arm_gen_dynamic_m_secextreg_feature(CPUState *cs,
468 int base_reg)
469 {
470 ARMCPU *cpu = ARM_CPU(cs);
471 GDBFeatureBuilder builder;
472 char *name;
473 int reg = 0;
474 int i;
475
476 gdb_feature_builder_init(&builder, &cpu->dyn_m_secextreg_feature.desc,
477 "org.gnu.gdb.arm.secext", "arm-m-secext.xml",
478 base_reg);
479
480 for (i = 0; i < ARRAY_SIZE(m_sysreg_def); i++) {
481 name = g_strconcat(m_sysreg_def[i].name, "_ns", NULL);
482 gdb_feature_builder_append_reg(&builder, name, 32, reg++,
483 "int", NULL);
484 name = g_strconcat(m_sysreg_def[i].name, "_s", NULL);
485 gdb_feature_builder_append_reg(&builder, name, 32, reg++,
486 "int", NULL);
487 }
488
489 gdb_feature_builder_end(&builder);
490
491 return &cpu->dyn_m_secextreg_feature.desc;
492 }
493 #endif
494 #endif /* CONFIG_TCG */
495
496 void arm_cpu_register_gdb_commands(ARMCPU *cpu)
497 {
498 g_autoptr(GPtrArray) query_table = g_ptr_array_new();
499 g_autoptr(GPtrArray) set_table = g_ptr_array_new();
500 g_autoptr(GString) qsupported_features = g_string_new(NULL);
501
502 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
503 aarch64_cpu_register_gdb_commands(cpu, qsupported_features, query_table,
504 set_table);
505 }
506
507 /* Set arch-specific handlers for 'q' commands. */
508 if (query_table->len) {
509 gdb_extend_query_table(query_table);
510 }
511
512 /* Set arch-specific handlers for 'Q' commands. */
513 if (set_table->len) {
514 gdb_extend_set_table(set_table);
515 }
516
517 /* Set arch-specific qSupported feature. */
518 if (qsupported_features->len) {
519 gdb_extend_qsupported_features(qsupported_features->str);
520 }
521 }
522
523 void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
524 {
525 CPUState *cs = CPU(cpu);
526 CPUARMState *env = &cpu->env;
527
528 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
529 /*
530 * The lower part of each SVE register aliases to the FPU
531 * registers so we don't need to include both.
532 */
533 aarch64_cpu_register_gdb_regs_for_features(cpu);
534 } else {
535 if (arm_feature(env, ARM_FEATURE_NEON)) {
536 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
537 gdb_find_static_feature("arm-neon.xml"));
538 } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
539 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
540 gdb_find_static_feature("arm-vfp3.xml"));
541 } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
542 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
543 gdb_find_static_feature("arm-vfp.xml"));
544 }
545 if (!arm_feature(env, ARM_FEATURE_M)) {
546 /*
547 * A and R profile have FP sysregs FPEXC and FPSID that we
548 * expose to gdb.
549 */
550 gdb_register_coprocessor(cs, vfp_gdb_get_sysreg, vfp_gdb_set_sysreg,
551 gdb_find_static_feature("arm-vfp-sysregs.xml"));
552 }
553 }
554 if (cpu_isar_feature(aa32_mve, cpu) && tcg_enabled()) {
555 gdb_register_coprocessor(cs, mve_gdb_get_reg, mve_gdb_set_reg,
556 gdb_find_static_feature("arm-m-profile-mve.xml"));
557 }
558 gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
559 arm_gen_dynamic_sysreg_feature(cs, cs->gdb_num_regs));
560
561 #ifdef CONFIG_TCG
562 if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) {
563 gdb_register_coprocessor(cs,
564 arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg,
565 arm_gen_dynamic_m_systemreg_feature(cs, cs->gdb_num_regs));
566 #ifndef CONFIG_USER_ONLY
567 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
568 gdb_register_coprocessor(cs,
569 arm_gdb_get_m_secextreg, arm_gdb_set_m_secextreg,
570 arm_gen_dynamic_m_secextreg_feature(cs, cs->gdb_num_regs));
571 }
572 #endif
573 }
574 #endif /* CONFIG_TCG */
575 }