4 * Copyright (c) 2003-2005 Fabrice Bellard
5 * Copyright (c) 2013 SUSE LINUX Products GmbH
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.
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.
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/>.
20 #include "qemu/osdep.h"
22 #include "exec/gdbstub.h"
23 #include "gdbstub/helpers.h"
24 #include "gdbstub/commands.h"
25 #include "sysemu/tcg.h"
26 #include "internals.h"
27 #include "cpu-features.h"
30 typedef struct RegisterSysregFeatureParam
{
32 GDBFeatureBuilder builder
;
34 } RegisterSysregFeatureParam
;
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
42 int arm_cpu_gdb_read_register(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
44 ARMCPU
*cpu
= ARM_CPU(cs
);
45 CPUARMState
*env
= &cpu
->env
;
48 /* Core integer register. */
49 return gdb_get_reg32(mem_buf
, env
->regs
[n
]);
52 /* CPSR, or XPSR for M-profile */
53 if (arm_feature(env
, ARM_FEATURE_M
)) {
54 return gdb_get_reg32(mem_buf
, xpsr_read(env
));
56 return gdb_get_reg32(mem_buf
, cpsr_read(env
));
59 /* Unknown register. */
63 int arm_cpu_gdb_write_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
65 ARMCPU
*cpu
= ARM_CPU(cs
);
66 CPUARMState
*env
= &cpu
->env
;
72 * Mask out low bits of PC to workaround gdb bugs.
73 * This avoids an assert in thumb_tr_translate_insn, because it is
74 * architecturally impossible to misalign the pc.
75 * This will probably cause problems if we ever implement the
76 * Jazelle DBX extensions.
83 /* Core integer register. */
84 if (n
== 13 && arm_feature(env
, ARM_FEATURE_M
)) {
85 /* M profile SP low bits are always 0 */
92 /* CPSR, or XPSR for M-profile */
93 if (arm_feature(env
, ARM_FEATURE_M
)) {
95 * Don't allow writing to XPSR.Exception as it can cause
96 * a transition into or out of handler mode (it's not
97 * writable via the MSR insn so this is a reasonable
98 * restriction). Other fields are safe to update.
100 xpsr_write(env
, tmp
, ~XPSR_EXCP
);
102 cpsr_write(env
, tmp
, 0xffffffff, CPSRWriteByGDBStub
);
106 /* Unknown register. */
110 static int vfp_gdb_get_reg(CPUState
*cs
, GByteArray
*buf
, int reg
)
112 ARMCPU
*cpu
= ARM_CPU(cs
);
113 CPUARMState
*env
= &cpu
->env
;
114 int nregs
= cpu_isar_feature(aa32_simd_r32
, cpu
) ? 32 : 16;
116 /* VFP data registers are always little-endian. */
118 return gdb_get_reg64(buf
, *aa32_vfp_dreg(env
, reg
));
120 if (arm_feature(env
, ARM_FEATURE_NEON
)) {
121 /* Aliases for Q regs. */
124 uint64_t *q
= aa32_vfp_qreg(env
, reg
- 32);
125 return gdb_get_reg128(buf
, q
[0], q
[1]);
128 switch (reg
- nregs
) {
130 return gdb_get_reg32(buf
, vfp_get_fpscr(env
));
135 static int vfp_gdb_set_reg(CPUState
*cs
, uint8_t *buf
, int reg
)
137 ARMCPU
*cpu
= ARM_CPU(cs
);
138 CPUARMState
*env
= &cpu
->env
;
139 int nregs
= cpu_isar_feature(aa32_simd_r32
, cpu
) ? 32 : 16;
142 *aa32_vfp_dreg(env
, reg
) = ldq_le_p(buf
);
145 if (arm_feature(env
, ARM_FEATURE_NEON
)) {
148 uint64_t *q
= aa32_vfp_qreg(env
, reg
- 32);
149 q
[0] = ldq_le_p(buf
);
150 q
[1] = ldq_le_p(buf
+ 8);
154 switch (reg
- nregs
) {
156 vfp_set_fpscr(env
, ldl_p(buf
));
162 static int vfp_gdb_get_sysreg(CPUState
*cs
, GByteArray
*buf
, int reg
)
164 ARMCPU
*cpu
= ARM_CPU(cs
);
165 CPUARMState
*env
= &cpu
->env
;
169 return gdb_get_reg32(buf
, env
->vfp
.xregs
[ARM_VFP_FPSID
]);
171 return gdb_get_reg32(buf
, env
->vfp
.xregs
[ARM_VFP_FPEXC
]);
176 static int vfp_gdb_set_sysreg(CPUState
*cs
, uint8_t *buf
, int reg
)
178 ARMCPU
*cpu
= ARM_CPU(cs
);
179 CPUARMState
*env
= &cpu
->env
;
183 env
->vfp
.xregs
[ARM_VFP_FPSID
] = ldl_p(buf
);
186 env
->vfp
.xregs
[ARM_VFP_FPEXC
] = ldl_p(buf
) & (1 << 30);
192 static int mve_gdb_get_reg(CPUState
*cs
, GByteArray
*buf
, int reg
)
194 ARMCPU
*cpu
= ARM_CPU(cs
);
195 CPUARMState
*env
= &cpu
->env
;
199 return gdb_get_reg32(buf
, env
->v7m
.vpr
);
205 static int mve_gdb_set_reg(CPUState
*cs
, uint8_t *buf
, int reg
)
207 ARMCPU
*cpu
= ARM_CPU(cs
);
208 CPUARMState
*env
= &cpu
->env
;
212 env
->v7m
.vpr
= ldl_p(buf
);
220 * arm_get/set_gdb_*: get/set a gdb register
221 * @env: the CPU state
222 * @buf: a buffer to copy to/from
223 * @reg: register number (offset from start of group)
225 * We return the number of bytes copied
228 static int arm_gdb_get_sysreg(CPUState
*cs
, GByteArray
*buf
, int reg
)
230 ARMCPU
*cpu
= ARM_CPU(cs
);
231 CPUARMState
*env
= &cpu
->env
;
232 const ARMCPRegInfo
*ri
;
235 key
= cpu
->dyn_sysreg_feature
.data
.cpregs
.keys
[reg
];
236 ri
= get_arm_cp_reginfo(cpu
->cp_regs
, key
);
238 if (cpreg_field_is_64bit(ri
)) {
239 return gdb_get_reg64(buf
, (uint64_t)read_raw_cp_reg(env
, ri
));
241 return gdb_get_reg32(buf
, (uint32_t)read_raw_cp_reg(env
, ri
));
247 static int arm_gdb_set_sysreg(CPUState
*cs
, uint8_t *buf
, int reg
)
252 static void arm_gen_one_feature_sysreg(GDBFeatureBuilder
*builder
,
253 DynamicGDBFeatureInfo
*dyn_feature
,
254 ARMCPRegInfo
*ri
, uint32_t ri_key
,
257 gdb_feature_builder_append_reg(builder
, ri
->name
, bitsize
, n
,
260 dyn_feature
->data
.cpregs
.keys
[n
] = ri_key
;
263 static void arm_register_sysreg_for_feature(gpointer key
, gpointer value
,
266 uint32_t ri_key
= (uintptr_t)key
;
267 ARMCPRegInfo
*ri
= value
;
268 RegisterSysregFeatureParam
*param
= p
;
269 ARMCPU
*cpu
= ARM_CPU(param
->cs
);
270 CPUARMState
*env
= &cpu
->env
;
271 DynamicGDBFeatureInfo
*dyn_feature
= &cpu
->dyn_sysreg_feature
;
273 if (!(ri
->type
& (ARM_CP_NO_RAW
| ARM_CP_NO_GDB
))) {
274 if (arm_feature(env
, ARM_FEATURE_AARCH64
)) {
275 if (ri
->state
== ARM_CP_STATE_AA64
) {
276 arm_gen_one_feature_sysreg(¶m
->builder
, dyn_feature
,
277 ri
, ri_key
, 64, param
->n
++);
280 if (ri
->state
== ARM_CP_STATE_AA32
) {
281 if (!arm_feature(env
, ARM_FEATURE_EL3
) &&
282 (ri
->secure
& ARM_CP_SECSTATE_S
)) {
285 if (ri
->type
& ARM_CP_64BIT
) {
286 arm_gen_one_feature_sysreg(¶m
->builder
, dyn_feature
,
287 ri
, ri_key
, 64, param
->n
++);
289 arm_gen_one_feature_sysreg(¶m
->builder
, dyn_feature
,
290 ri
, ri_key
, 32, param
->n
++);
297 static GDBFeature
*arm_gen_dynamic_sysreg_feature(CPUState
*cs
, int base_reg
)
299 ARMCPU
*cpu
= ARM_CPU(cs
);
300 RegisterSysregFeatureParam param
= {cs
};
301 gsize num_regs
= g_hash_table_size(cpu
->cp_regs
);
303 gdb_feature_builder_init(¶m
.builder
,
304 &cpu
->dyn_sysreg_feature
.desc
,
305 "org.qemu.gdb.arm.sys.regs",
306 "system-registers.xml",
308 cpu
->dyn_sysreg_feature
.data
.cpregs
.keys
= g_new(uint32_t, num_regs
);
309 g_hash_table_foreach(cpu
->cp_regs
, arm_register_sysreg_for_feature
, ¶m
);
310 gdb_feature_builder_end(¶m
.builder
);
311 return &cpu
->dyn_sysreg_feature
.desc
;
326 static const struct {
330 [M_SYSREG_MSP
] = { "msp", ARM_FEATURE_M
},
331 [M_SYSREG_PSP
] = { "psp", ARM_FEATURE_M
},
332 [M_SYSREG_PRIMASK
] = { "primask", ARM_FEATURE_M
},
333 [M_SYSREG_CONTROL
] = { "control", ARM_FEATURE_M
},
334 [M_SYSREG_BASEPRI
] = { "basepri", ARM_FEATURE_M_MAIN
},
335 [M_SYSREG_FAULTMASK
] = { "faultmask", ARM_FEATURE_M_MAIN
},
336 [M_SYSREG_MSPLIM
] = { "msplim", ARM_FEATURE_V8
},
337 [M_SYSREG_PSPLIM
] = { "psplim", ARM_FEATURE_V8
},
340 static uint32_t *m_sysreg_ptr(CPUARMState
*env
, MProfileSysreg reg
, bool sec
)
346 ptr
= arm_v7m_get_sp_ptr(env
, sec
, false, true);
349 ptr
= arm_v7m_get_sp_ptr(env
, sec
, true, true);
351 case M_SYSREG_MSPLIM
:
352 ptr
= &env
->v7m
.msplim
[sec
];
354 case M_SYSREG_PSPLIM
:
355 ptr
= &env
->v7m
.psplim
[sec
];
357 case M_SYSREG_PRIMASK
:
358 ptr
= &env
->v7m
.primask
[sec
];
360 case M_SYSREG_BASEPRI
:
361 ptr
= &env
->v7m
.basepri
[sec
];
363 case M_SYSREG_FAULTMASK
:
364 ptr
= &env
->v7m
.faultmask
[sec
];
366 case M_SYSREG_CONTROL
:
367 ptr
= &env
->v7m
.control
[sec
];
372 return arm_feature(env
, m_sysreg_def
[reg
].feature
) ? ptr
: NULL
;
375 static int m_sysreg_get(CPUARMState
*env
, GByteArray
*buf
,
376 MProfileSysreg reg
, bool secure
)
378 uint32_t *ptr
= m_sysreg_ptr(env
, reg
, secure
);
383 return gdb_get_reg32(buf
, *ptr
);
386 static int arm_gdb_get_m_systemreg(CPUState
*cs
, GByteArray
*buf
, int reg
)
388 ARMCPU
*cpu
= ARM_CPU(cs
);
389 CPUARMState
*env
= &cpu
->env
;
392 * Here, we emulate MRS instruction, where CONTROL has a mix of
393 * banked and non-banked bits.
395 if (reg
== M_SYSREG_CONTROL
) {
396 return gdb_get_reg32(buf
, arm_v7m_mrs_control(env
, env
->v7m
.secure
));
398 return m_sysreg_get(env
, buf
, reg
, env
->v7m
.secure
);
401 static int arm_gdb_set_m_systemreg(CPUState
*cs
, uint8_t *buf
, int reg
)
406 static GDBFeature
*arm_gen_dynamic_m_systemreg_feature(CPUState
*cs
,
409 ARMCPU
*cpu
= ARM_CPU(cs
);
410 CPUARMState
*env
= &cpu
->env
;
411 GDBFeatureBuilder builder
;
415 gdb_feature_builder_init(&builder
, &cpu
->dyn_m_systemreg_feature
.desc
,
416 "org.gnu.gdb.arm.m-system", "arm-m-system.xml",
419 for (i
= 0; i
< ARRAY_SIZE(m_sysreg_def
); i
++) {
420 if (arm_feature(env
, m_sysreg_def
[i
].feature
)) {
421 gdb_feature_builder_append_reg(&builder
, m_sysreg_def
[i
].name
, 32,
426 gdb_feature_builder_end(&builder
);
428 return &cpu
->dyn_m_systemreg_feature
.desc
;
431 #ifndef CONFIG_USER_ONLY
433 * For user-only, we see the non-secure registers via m_systemreg above.
434 * For secext, encode the non-secure view as even and secure view as odd.
436 static int arm_gdb_get_m_secextreg(CPUState
*cs
, GByteArray
*buf
, int reg
)
438 ARMCPU
*cpu
= ARM_CPU(cs
);
439 CPUARMState
*env
= &cpu
->env
;
441 return m_sysreg_get(env
, buf
, reg
>> 1, reg
& 1);
444 static int arm_gdb_set_m_secextreg(CPUState
*cs
, uint8_t *buf
, int reg
)
449 static GDBFeature
*arm_gen_dynamic_m_secextreg_feature(CPUState
*cs
,
452 ARMCPU
*cpu
= ARM_CPU(cs
);
453 GDBFeatureBuilder builder
;
458 gdb_feature_builder_init(&builder
, &cpu
->dyn_m_secextreg_feature
.desc
,
459 "org.gnu.gdb.arm.secext", "arm-m-secext.xml",
462 for (i
= 0; i
< ARRAY_SIZE(m_sysreg_def
); i
++) {
463 name
= g_strconcat(m_sysreg_def
[i
].name
, "_ns", NULL
);
464 gdb_feature_builder_append_reg(&builder
, name
, 32, reg
++,
466 name
= g_strconcat(m_sysreg_def
[i
].name
, "_s", NULL
);
467 gdb_feature_builder_append_reg(&builder
, name
, 32, reg
++,
471 gdb_feature_builder_end(&builder
);
473 return &cpu
->dyn_m_secextreg_feature
.desc
;
476 #endif /* CONFIG_TCG */
478 void arm_cpu_register_gdb_commands(ARMCPU
*cpu
)
480 g_autoptr(GPtrArray
) query_table
= g_ptr_array_new();
481 g_autoptr(GPtrArray
) set_table
= g_ptr_array_new();
482 g_autoptr(GString
) qsupported_features
= g_string_new(NULL
);
484 if (arm_feature(&cpu
->env
, ARM_FEATURE_AARCH64
)) {
485 #ifdef TARGET_AARCH64
486 aarch64_cpu_register_gdb_commands(cpu
, qsupported_features
, query_table
,
491 /* Set arch-specific handlers for 'q' commands. */
492 if (query_table
->len
) {
493 gdb_extend_query_table(query_table
);
496 /* Set arch-specific handlers for 'Q' commands. */
497 if (set_table
->len
) {
498 gdb_extend_set_table(set_table
);
501 /* Set arch-specific qSupported feature. */
502 if (qsupported_features
->len
) {
503 gdb_extend_qsupported_features(qsupported_features
->str
);
507 void arm_cpu_register_gdb_regs_for_features(ARMCPU
*cpu
)
509 CPUState
*cs
= CPU(cpu
);
510 CPUARMState
*env
= &cpu
->env
;
512 if (arm_feature(env
, ARM_FEATURE_AARCH64
)) {
514 * The lower part of each SVE register aliases to the FPU
515 * registers so we don't need to include both.
517 #ifdef TARGET_AARCH64
518 if (isar_feature_aa64_sve(&cpu
->isar
)) {
519 GDBFeature
*feature
= arm_gen_dynamic_svereg_feature(cs
, cs
->gdb_num_regs
);
520 gdb_register_coprocessor(cs
, aarch64_gdb_get_sve_reg
,
521 aarch64_gdb_set_sve_reg
, feature
, 0);
523 gdb_register_coprocessor(cs
, aarch64_gdb_get_fpu_reg
,
524 aarch64_gdb_set_fpu_reg
,
525 gdb_find_static_feature("aarch64-fpu.xml"),
529 * Note that we report pauth information via the feature name
530 * org.gnu.gdb.aarch64.pauth_v2, not org.gnu.gdb.aarch64.pauth.
531 * GDB versions 9 through 12 have a bug where they will crash
532 * if they see the latter XML from QEMU.
534 if (isar_feature_aa64_pauth(&cpu
->isar
)) {
535 gdb_register_coprocessor(cs
, aarch64_gdb_get_pauth_reg
,
536 aarch64_gdb_set_pauth_reg
,
537 gdb_find_static_feature("aarch64-pauth.xml"),
541 #ifdef CONFIG_USER_ONLY
542 /* Memory Tagging Extension (MTE) 'tag_ctl' pseudo-register. */
543 if (cpu_isar_feature(aa64_mte
, cpu
)) {
544 gdb_register_coprocessor(cs
, aarch64_gdb_get_tag_ctl_reg
,
545 aarch64_gdb_set_tag_ctl_reg
,
546 gdb_find_static_feature("aarch64-mte.xml"),
552 if (arm_feature(env
, ARM_FEATURE_NEON
)) {
553 gdb_register_coprocessor(cs
, vfp_gdb_get_reg
, vfp_gdb_set_reg
,
554 gdb_find_static_feature("arm-neon.xml"),
556 } else if (cpu_isar_feature(aa32_simd_r32
, cpu
)) {
557 gdb_register_coprocessor(cs
, vfp_gdb_get_reg
, vfp_gdb_set_reg
,
558 gdb_find_static_feature("arm-vfp3.xml"),
560 } else if (cpu_isar_feature(aa32_vfp_simd
, cpu
)) {
561 gdb_register_coprocessor(cs
, vfp_gdb_get_reg
, vfp_gdb_set_reg
,
562 gdb_find_static_feature("arm-vfp.xml"), 0);
564 if (!arm_feature(env
, ARM_FEATURE_M
)) {
566 * A and R profile have FP sysregs FPEXC and FPSID that we
569 gdb_register_coprocessor(cs
, vfp_gdb_get_sysreg
, vfp_gdb_set_sysreg
,
570 gdb_find_static_feature("arm-vfp-sysregs.xml"),
574 if (cpu_isar_feature(aa32_mve
, cpu
) && tcg_enabled()) {
575 gdb_register_coprocessor(cs
, mve_gdb_get_reg
, mve_gdb_set_reg
,
576 gdb_find_static_feature("arm-m-profile-mve.xml"),
579 gdb_register_coprocessor(cs
, arm_gdb_get_sysreg
, arm_gdb_set_sysreg
,
580 arm_gen_dynamic_sysreg_feature(cs
, cs
->gdb_num_regs
),
584 if (arm_feature(env
, ARM_FEATURE_M
) && tcg_enabled()) {
585 gdb_register_coprocessor(cs
,
586 arm_gdb_get_m_systemreg
, arm_gdb_set_m_systemreg
,
587 arm_gen_dynamic_m_systemreg_feature(cs
, cs
->gdb_num_regs
), 0);
588 #ifndef CONFIG_USER_ONLY
589 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
590 gdb_register_coprocessor(cs
,
591 arm_gdb_get_m_secextreg
, arm_gdb_set_m_secextreg
,
592 arm_gen_dynamic_m_secextreg_feature(cs
, cs
->gdb_num_regs
), 0);
596 #endif /* CONFIG_TCG */