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 "sysemu/tcg.h"
25 #include "internals.h"
26 #include "cpu-features.h"
29 typedef struct RegisterSysregFeatureParam
{
31 GDBFeatureBuilder builder
;
33 } RegisterSysregFeatureParam
;
35 /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect
36 whatever the target description contains. Due to a historical mishap
37 the FPA registers appear in between core integer regs and the CPSR.
38 We hack round this by giving the FPA regs zero size when talking to a
41 int arm_cpu_gdb_read_register(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
43 ARMCPU
*cpu
= ARM_CPU(cs
);
44 CPUARMState
*env
= &cpu
->env
;
47 /* Core integer register. */
48 return gdb_get_reg32(mem_buf
, env
->regs
[n
]);
51 /* CPSR, or XPSR for M-profile */
52 if (arm_feature(env
, ARM_FEATURE_M
)) {
53 return gdb_get_reg32(mem_buf
, xpsr_read(env
));
55 return gdb_get_reg32(mem_buf
, cpsr_read(env
));
58 /* Unknown register. */
62 int arm_cpu_gdb_write_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
64 ARMCPU
*cpu
= ARM_CPU(cs
);
65 CPUARMState
*env
= &cpu
->env
;
71 * Mask out low bits of PC to workaround gdb bugs.
72 * This avoids an assert in thumb_tr_translate_insn, because it is
73 * architecturally impossible to misalign the pc.
74 * This will probably cause problems if we ever implement the
75 * Jazelle DBX extensions.
82 /* Core integer register. */
83 if (n
== 13 && arm_feature(env
, ARM_FEATURE_M
)) {
84 /* M profile SP low bits are always 0 */
91 /* CPSR, or XPSR for M-profile */
92 if (arm_feature(env
, ARM_FEATURE_M
)) {
94 * Don't allow writing to XPSR.Exception as it can cause
95 * a transition into or out of handler mode (it's not
96 * writable via the MSR insn so this is a reasonable
97 * restriction). Other fields are safe to update.
99 xpsr_write(env
, tmp
, ~XPSR_EXCP
);
101 cpsr_write(env
, tmp
, 0xffffffff, CPSRWriteByGDBStub
);
105 /* Unknown register. */
109 static int vfp_gdb_get_reg(CPUState
*cs
, GByteArray
*buf
, int reg
)
111 ARMCPU
*cpu
= ARM_CPU(cs
);
112 CPUARMState
*env
= &cpu
->env
;
113 int nregs
= cpu_isar_feature(aa32_simd_r32
, cpu
) ? 32 : 16;
115 /* VFP data registers are always little-endian. */
117 return gdb_get_reg64(buf
, *aa32_vfp_dreg(env
, reg
));
119 if (arm_feature(env
, ARM_FEATURE_NEON
)) {
120 /* Aliases for Q regs. */
123 uint64_t *q
= aa32_vfp_qreg(env
, reg
- 32);
124 return gdb_get_reg128(buf
, q
[0], q
[1]);
127 switch (reg
- nregs
) {
129 return gdb_get_reg32(buf
, vfp_get_fpscr(env
));
134 static int vfp_gdb_set_reg(CPUState
*cs
, uint8_t *buf
, int reg
)
136 ARMCPU
*cpu
= ARM_CPU(cs
);
137 CPUARMState
*env
= &cpu
->env
;
138 int nregs
= cpu_isar_feature(aa32_simd_r32
, cpu
) ? 32 : 16;
141 *aa32_vfp_dreg(env
, reg
) = ldq_le_p(buf
);
144 if (arm_feature(env
, ARM_FEATURE_NEON
)) {
147 uint64_t *q
= aa32_vfp_qreg(env
, reg
- 32);
148 q
[0] = ldq_le_p(buf
);
149 q
[1] = ldq_le_p(buf
+ 8);
153 switch (reg
- nregs
) {
155 vfp_set_fpscr(env
, ldl_p(buf
));
161 static int vfp_gdb_get_sysreg(CPUState
*cs
, GByteArray
*buf
, int reg
)
163 ARMCPU
*cpu
= ARM_CPU(cs
);
164 CPUARMState
*env
= &cpu
->env
;
168 return gdb_get_reg32(buf
, env
->vfp
.xregs
[ARM_VFP_FPSID
]);
170 return gdb_get_reg32(buf
, env
->vfp
.xregs
[ARM_VFP_FPEXC
]);
175 static int vfp_gdb_set_sysreg(CPUState
*cs
, uint8_t *buf
, int reg
)
177 ARMCPU
*cpu
= ARM_CPU(cs
);
178 CPUARMState
*env
= &cpu
->env
;
182 env
->vfp
.xregs
[ARM_VFP_FPSID
] = ldl_p(buf
);
185 env
->vfp
.xregs
[ARM_VFP_FPEXC
] = ldl_p(buf
) & (1 << 30);
191 static int mve_gdb_get_reg(CPUState
*cs
, GByteArray
*buf
, int reg
)
193 ARMCPU
*cpu
= ARM_CPU(cs
);
194 CPUARMState
*env
= &cpu
->env
;
198 return gdb_get_reg32(buf
, env
->v7m
.vpr
);
204 static int mve_gdb_set_reg(CPUState
*cs
, uint8_t *buf
, int reg
)
206 ARMCPU
*cpu
= ARM_CPU(cs
);
207 CPUARMState
*env
= &cpu
->env
;
211 env
->v7m
.vpr
= ldl_p(buf
);
219 * arm_get/set_gdb_*: get/set a gdb register
220 * @env: the CPU state
221 * @buf: a buffer to copy to/from
222 * @reg: register number (offset from start of group)
224 * We return the number of bytes copied
227 static int arm_gdb_get_sysreg(CPUState
*cs
, GByteArray
*buf
, int reg
)
229 ARMCPU
*cpu
= ARM_CPU(cs
);
230 CPUARMState
*env
= &cpu
->env
;
231 const ARMCPRegInfo
*ri
;
234 key
= cpu
->dyn_sysreg_feature
.data
.cpregs
.keys
[reg
];
235 ri
= get_arm_cp_reginfo(cpu
->cp_regs
, key
);
237 if (cpreg_field_is_64bit(ri
)) {
238 return gdb_get_reg64(buf
, (uint64_t)read_raw_cp_reg(env
, ri
));
240 return gdb_get_reg32(buf
, (uint32_t)read_raw_cp_reg(env
, ri
));
246 static int arm_gdb_set_sysreg(CPUState
*cs
, uint8_t *buf
, int reg
)
251 static void arm_gen_one_feature_sysreg(GDBFeatureBuilder
*builder
,
252 DynamicGDBFeatureInfo
*dyn_feature
,
253 ARMCPRegInfo
*ri
, uint32_t ri_key
,
256 gdb_feature_builder_append_reg(builder
, ri
->name
, bitsize
, n
,
259 dyn_feature
->data
.cpregs
.keys
[n
] = ri_key
;
262 static void arm_register_sysreg_for_feature(gpointer key
, gpointer value
,
265 uint32_t ri_key
= (uintptr_t)key
;
266 ARMCPRegInfo
*ri
= value
;
267 RegisterSysregFeatureParam
*param
= p
;
268 ARMCPU
*cpu
= ARM_CPU(param
->cs
);
269 CPUARMState
*env
= &cpu
->env
;
270 DynamicGDBFeatureInfo
*dyn_feature
= &cpu
->dyn_sysreg_feature
;
272 if (!(ri
->type
& (ARM_CP_NO_RAW
| ARM_CP_NO_GDB
))) {
273 if (arm_feature(env
, ARM_FEATURE_AARCH64
)) {
274 if (ri
->state
== ARM_CP_STATE_AA64
) {
275 arm_gen_one_feature_sysreg(¶m
->builder
, dyn_feature
,
276 ri
, ri_key
, 64, param
->n
++);
279 if (ri
->state
== ARM_CP_STATE_AA32
) {
280 if (!arm_feature(env
, ARM_FEATURE_EL3
) &&
281 (ri
->secure
& ARM_CP_SECSTATE_S
)) {
284 if (ri
->type
& ARM_CP_64BIT
) {
285 arm_gen_one_feature_sysreg(¶m
->builder
, dyn_feature
,
286 ri
, ri_key
, 64, param
->n
++);
288 arm_gen_one_feature_sysreg(¶m
->builder
, dyn_feature
,
289 ri
, ri_key
, 32, param
->n
++);
296 static GDBFeature
*arm_gen_dynamic_sysreg_feature(CPUState
*cs
, int base_reg
)
298 ARMCPU
*cpu
= ARM_CPU(cs
);
299 RegisterSysregFeatureParam param
= {cs
};
300 gsize num_regs
= g_hash_table_size(cpu
->cp_regs
);
302 gdb_feature_builder_init(¶m
.builder
,
303 &cpu
->dyn_sysreg_feature
.desc
,
304 "org.qemu.gdb.arm.sys.regs",
305 "system-registers.xml",
307 cpu
->dyn_sysreg_feature
.data
.cpregs
.keys
= g_new(uint32_t, num_regs
);
308 g_hash_table_foreach(cpu
->cp_regs
, arm_register_sysreg_for_feature
, ¶m
);
309 gdb_feature_builder_end(¶m
.builder
);
310 return &cpu
->dyn_sysreg_feature
.desc
;
325 static const struct {
329 [M_SYSREG_MSP
] = { "msp", ARM_FEATURE_M
},
330 [M_SYSREG_PSP
] = { "psp", ARM_FEATURE_M
},
331 [M_SYSREG_PRIMASK
] = { "primask", ARM_FEATURE_M
},
332 [M_SYSREG_CONTROL
] = { "control", ARM_FEATURE_M
},
333 [M_SYSREG_BASEPRI
] = { "basepri", ARM_FEATURE_M_MAIN
},
334 [M_SYSREG_FAULTMASK
] = { "faultmask", ARM_FEATURE_M_MAIN
},
335 [M_SYSREG_MSPLIM
] = { "msplim", ARM_FEATURE_V8
},
336 [M_SYSREG_PSPLIM
] = { "psplim", ARM_FEATURE_V8
},
339 static uint32_t *m_sysreg_ptr(CPUARMState
*env
, MProfileSysreg reg
, bool sec
)
345 ptr
= arm_v7m_get_sp_ptr(env
, sec
, false, true);
348 ptr
= arm_v7m_get_sp_ptr(env
, sec
, true, true);
350 case M_SYSREG_MSPLIM
:
351 ptr
= &env
->v7m
.msplim
[sec
];
353 case M_SYSREG_PSPLIM
:
354 ptr
= &env
->v7m
.psplim
[sec
];
356 case M_SYSREG_PRIMASK
:
357 ptr
= &env
->v7m
.primask
[sec
];
359 case M_SYSREG_BASEPRI
:
360 ptr
= &env
->v7m
.basepri
[sec
];
362 case M_SYSREG_FAULTMASK
:
363 ptr
= &env
->v7m
.faultmask
[sec
];
365 case M_SYSREG_CONTROL
:
366 ptr
= &env
->v7m
.control
[sec
];
371 return arm_feature(env
, m_sysreg_def
[reg
].feature
) ? ptr
: NULL
;
374 static int m_sysreg_get(CPUARMState
*env
, GByteArray
*buf
,
375 MProfileSysreg reg
, bool secure
)
377 uint32_t *ptr
= m_sysreg_ptr(env
, reg
, secure
);
382 return gdb_get_reg32(buf
, *ptr
);
385 static int arm_gdb_get_m_systemreg(CPUState
*cs
, GByteArray
*buf
, int reg
)
387 ARMCPU
*cpu
= ARM_CPU(cs
);
388 CPUARMState
*env
= &cpu
->env
;
391 * Here, we emulate MRS instruction, where CONTROL has a mix of
392 * banked and non-banked bits.
394 if (reg
== M_SYSREG_CONTROL
) {
395 return gdb_get_reg32(buf
, arm_v7m_mrs_control(env
, env
->v7m
.secure
));
397 return m_sysreg_get(env
, buf
, reg
, env
->v7m
.secure
);
400 static int arm_gdb_set_m_systemreg(CPUState
*cs
, uint8_t *buf
, int reg
)
405 static GDBFeature
*arm_gen_dynamic_m_systemreg_feature(CPUState
*cs
,
408 ARMCPU
*cpu
= ARM_CPU(cs
);
409 CPUARMState
*env
= &cpu
->env
;
410 GDBFeatureBuilder builder
;
414 gdb_feature_builder_init(&builder
, &cpu
->dyn_m_systemreg_feature
.desc
,
415 "org.gnu.gdb.arm.m-system", "arm-m-system.xml",
418 for (i
= 0; i
< ARRAY_SIZE(m_sysreg_def
); i
++) {
419 if (arm_feature(env
, m_sysreg_def
[i
].feature
)) {
420 gdb_feature_builder_append_reg(&builder
, m_sysreg_def
[i
].name
, 32,
425 gdb_feature_builder_end(&builder
);
427 return &cpu
->dyn_m_systemreg_feature
.desc
;
430 #ifndef CONFIG_USER_ONLY
432 * For user-only, we see the non-secure registers via m_systemreg above.
433 * For secext, encode the non-secure view as even and secure view as odd.
435 static int arm_gdb_get_m_secextreg(CPUState
*cs
, GByteArray
*buf
, int reg
)
437 ARMCPU
*cpu
= ARM_CPU(cs
);
438 CPUARMState
*env
= &cpu
->env
;
440 return m_sysreg_get(env
, buf
, reg
>> 1, reg
& 1);
443 static int arm_gdb_set_m_secextreg(CPUState
*cs
, uint8_t *buf
, int reg
)
448 static GDBFeature
*arm_gen_dynamic_m_secextreg_feature(CPUState
*cs
,
451 ARMCPU
*cpu
= ARM_CPU(cs
);
452 GDBFeatureBuilder builder
;
457 gdb_feature_builder_init(&builder
, &cpu
->dyn_m_secextreg_feature
.desc
,
458 "org.gnu.gdb.arm.secext", "arm-m-secext.xml",
461 for (i
= 0; i
< ARRAY_SIZE(m_sysreg_def
); i
++) {
462 name
= g_strconcat(m_sysreg_def
[i
].name
, "_ns", NULL
);
463 gdb_feature_builder_append_reg(&builder
, name
, 32, reg
++,
465 name
= g_strconcat(m_sysreg_def
[i
].name
, "_s", NULL
);
466 gdb_feature_builder_append_reg(&builder
, name
, 32, reg
++,
470 gdb_feature_builder_end(&builder
);
472 return &cpu
->dyn_m_secextreg_feature
.desc
;
475 #endif /* CONFIG_TCG */
477 void arm_cpu_register_gdb_regs_for_features(ARMCPU
*cpu
)
479 CPUState
*cs
= CPU(cpu
);
480 CPUARMState
*env
= &cpu
->env
;
482 if (arm_feature(env
, ARM_FEATURE_AARCH64
)) {
484 * The lower part of each SVE register aliases to the FPU
485 * registers so we don't need to include both.
487 #ifdef TARGET_AARCH64
488 if (isar_feature_aa64_sve(&cpu
->isar
)) {
489 GDBFeature
*feature
= arm_gen_dynamic_svereg_feature(cs
, cs
->gdb_num_regs
);
490 gdb_register_coprocessor(cs
, aarch64_gdb_get_sve_reg
,
491 aarch64_gdb_set_sve_reg
, feature
, 0);
493 gdb_register_coprocessor(cs
, aarch64_gdb_get_fpu_reg
,
494 aarch64_gdb_set_fpu_reg
,
495 gdb_find_static_feature("aarch64-fpu.xml"),
499 * Note that we report pauth information via the feature name
500 * org.gnu.gdb.aarch64.pauth_v2, not org.gnu.gdb.aarch64.pauth.
501 * GDB versions 9 through 12 have a bug where they will crash
502 * if they see the latter XML from QEMU.
504 if (isar_feature_aa64_pauth(&cpu
->isar
)) {
505 gdb_register_coprocessor(cs
, aarch64_gdb_get_pauth_reg
,
506 aarch64_gdb_set_pauth_reg
,
507 gdb_find_static_feature("aarch64-pauth.xml"),
512 if (arm_feature(env
, ARM_FEATURE_NEON
)) {
513 gdb_register_coprocessor(cs
, vfp_gdb_get_reg
, vfp_gdb_set_reg
,
514 gdb_find_static_feature("arm-neon.xml"),
516 } else if (cpu_isar_feature(aa32_simd_r32
, cpu
)) {
517 gdb_register_coprocessor(cs
, vfp_gdb_get_reg
, vfp_gdb_set_reg
,
518 gdb_find_static_feature("arm-vfp3.xml"),
520 } else if (cpu_isar_feature(aa32_vfp_simd
, cpu
)) {
521 gdb_register_coprocessor(cs
, vfp_gdb_get_reg
, vfp_gdb_set_reg
,
522 gdb_find_static_feature("arm-vfp.xml"), 0);
524 if (!arm_feature(env
, ARM_FEATURE_M
)) {
526 * A and R profile have FP sysregs FPEXC and FPSID that we
529 gdb_register_coprocessor(cs
, vfp_gdb_get_sysreg
, vfp_gdb_set_sysreg
,
530 gdb_find_static_feature("arm-vfp-sysregs.xml"),
534 if (cpu_isar_feature(aa32_mve
, cpu
) && tcg_enabled()) {
535 gdb_register_coprocessor(cs
, mve_gdb_get_reg
, mve_gdb_set_reg
,
536 gdb_find_static_feature("arm-m-profile-mve.xml"),
539 gdb_register_coprocessor(cs
, arm_gdb_get_sysreg
, arm_gdb_set_sysreg
,
540 arm_gen_dynamic_sysreg_feature(cs
, cs
->gdb_num_regs
),
544 if (arm_feature(env
, ARM_FEATURE_M
) && tcg_enabled()) {
545 gdb_register_coprocessor(cs
,
546 arm_gdb_get_m_systemreg
, arm_gdb_set_m_systemreg
,
547 arm_gen_dynamic_m_systemreg_feature(cs
, cs
->gdb_num_regs
), 0);
548 #ifndef CONFIG_USER_ONLY
549 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
550 gdb_register_coprocessor(cs
,
551 arm_gdb_get_m_secextreg
, arm_gdb_set_m_secextreg
,
552 arm_gen_dynamic_m_secextreg_feature(cs
, cs
->gdb_num_regs
), 0);
556 #endif /* CONFIG_TCG */