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 "sysemu/tcg.h" 25 #include "internals.h" 26 #include "cpu-features.h" 27 #include "cpregs.h" 28 29 typedef struct RegisterSysregFeatureParam { 30 CPUState *cs; 31 GDBFeatureBuilder builder; 32 int n; 33 } RegisterSysregFeatureParam; 34 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 39 newer gdb. */ 40 41 int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 42 { 43 ARMCPU *cpu = ARM_CPU(cs); 44 CPUARMState *env = &cpu->env; 45 46 if (n < 16) { 47 /* Core integer register. */ 48 return gdb_get_reg32(mem_buf, env->regs[n]); 49 } 50 if (n == 25) { 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)); 54 } else { 55 return gdb_get_reg32(mem_buf, cpsr_read(env)); 56 } 57 } 58 /* Unknown register. */ 59 return 0; 60 } 61 62 int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 63 { 64 ARMCPU *cpu = ARM_CPU(cs); 65 CPUARMState *env = &cpu->env; 66 uint32_t tmp; 67 68 tmp = ldl_p(mem_buf); 69 70 /* 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. 76 */ 77 if (n == 15) { 78 tmp &= ~1; 79 } 80 81 if (n < 16) { 82 /* Core integer register. */ 83 if (n == 13 && arm_feature(env, ARM_FEATURE_M)) { 84 /* M profile SP low bits are always 0 */ 85 tmp &= ~3; 86 } 87 env->regs[n] = tmp; 88 return 4; 89 } 90 if (n == 25) { 91 /* CPSR, or XPSR for M-profile */ 92 if (arm_feature(env, ARM_FEATURE_M)) { 93 /* 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. 98 */ 99 xpsr_write(env, tmp, ~XPSR_EXCP); 100 } else { 101 cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub); 102 } 103 return 4; 104 } 105 /* Unknown register. */ 106 return 0; 107 } 108 109 static int vfp_gdb_get_reg(CPUState *cs, GByteArray *buf, int reg) 110 { 111 ARMCPU *cpu = ARM_CPU(cs); 112 CPUARMState *env = &cpu->env; 113 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16; 114 115 /* VFP data registers are always little-endian. */ 116 if (reg < nregs) { 117 return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg)); 118 } 119 if (arm_feature(env, ARM_FEATURE_NEON)) { 120 /* Aliases for Q regs. */ 121 nregs += 16; 122 if (reg < nregs) { 123 uint64_t *q = aa32_vfp_qreg(env, reg - 32); 124 return gdb_get_reg128(buf, q[0], q[1]); 125 } 126 } 127 switch (reg - nregs) { 128 case 0: 129 return gdb_get_reg32(buf, vfp_get_fpscr(env)); 130 } 131 return 0; 132 } 133 134 static int vfp_gdb_set_reg(CPUState *cs, uint8_t *buf, int reg) 135 { 136 ARMCPU *cpu = ARM_CPU(cs); 137 CPUARMState *env = &cpu->env; 138 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16; 139 140 if (reg < nregs) { 141 *aa32_vfp_dreg(env, reg) = ldq_le_p(buf); 142 return 8; 143 } 144 if (arm_feature(env, ARM_FEATURE_NEON)) { 145 nregs += 16; 146 if (reg < nregs) { 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); 150 return 16; 151 } 152 } 153 switch (reg - nregs) { 154 case 0: 155 vfp_set_fpscr(env, ldl_p(buf)); 156 return 4; 157 } 158 return 0; 159 } 160 161 static int vfp_gdb_get_sysreg(CPUState *cs, GByteArray *buf, int reg) 162 { 163 ARMCPU *cpu = ARM_CPU(cs); 164 CPUARMState *env = &cpu->env; 165 166 switch (reg) { 167 case 0: 168 return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]); 169 case 1: 170 return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]); 171 } 172 return 0; 173 } 174 175 static int vfp_gdb_set_sysreg(CPUState *cs, uint8_t *buf, int reg) 176 { 177 ARMCPU *cpu = ARM_CPU(cs); 178 CPUARMState *env = &cpu->env; 179 180 switch (reg) { 181 case 0: 182 env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); 183 return 4; 184 case 1: 185 env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); 186 return 4; 187 } 188 return 0; 189 } 190 191 static int mve_gdb_get_reg(CPUState *cs, GByteArray *buf, int reg) 192 { 193 ARMCPU *cpu = ARM_CPU(cs); 194 CPUARMState *env = &cpu->env; 195 196 switch (reg) { 197 case 0: 198 return gdb_get_reg32(buf, env->v7m.vpr); 199 default: 200 return 0; 201 } 202 } 203 204 static int mve_gdb_set_reg(CPUState *cs, uint8_t *buf, int reg) 205 { 206 ARMCPU *cpu = ARM_CPU(cs); 207 CPUARMState *env = &cpu->env; 208 209 switch (reg) { 210 case 0: 211 env->v7m.vpr = ldl_p(buf); 212 return 4; 213 default: 214 return 0; 215 } 216 } 217 218 /** 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) 223 * 224 * We return the number of bytes copied 225 */ 226 227 static int arm_gdb_get_sysreg(CPUState *cs, GByteArray *buf, int reg) 228 { 229 ARMCPU *cpu = ARM_CPU(cs); 230 CPUARMState *env = &cpu->env; 231 const ARMCPRegInfo *ri; 232 uint32_t key; 233 234 key = cpu->dyn_sysreg_feature.data.cpregs.keys[reg]; 235 ri = get_arm_cp_reginfo(cpu->cp_regs, key); 236 if (ri) { 237 if (cpreg_field_is_64bit(ri)) { 238 return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri)); 239 } else { 240 return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri)); 241 } 242 } 243 return 0; 244 } 245 246 static int arm_gdb_set_sysreg(CPUState *cs, uint8_t *buf, int reg) 247 { 248 return 0; 249 } 250 251 static void arm_gen_one_feature_sysreg(GDBFeatureBuilder *builder, 252 DynamicGDBFeatureInfo *dyn_feature, 253 ARMCPRegInfo *ri, uint32_t ri_key, 254 int bitsize, int n) 255 { 256 gdb_feature_builder_append_reg(builder, ri->name, bitsize, n, 257 "int", "cp_regs"); 258 259 dyn_feature->data.cpregs.keys[n] = ri_key; 260 } 261 262 static void arm_register_sysreg_for_feature(gpointer key, gpointer value, 263 gpointer p) 264 { 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; 271 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++); 277 } 278 } else { 279 if (ri->state == ARM_CP_STATE_AA32) { 280 if (!arm_feature(env, ARM_FEATURE_EL3) && 281 (ri->secure & ARM_CP_SECSTATE_S)) { 282 return; 283 } 284 if (ri->type & ARM_CP_64BIT) { 285 arm_gen_one_feature_sysreg(¶m->builder, dyn_feature, 286 ri, ri_key, 64, param->n++); 287 } else { 288 arm_gen_one_feature_sysreg(¶m->builder, dyn_feature, 289 ri, ri_key, 32, param->n++); 290 } 291 } 292 } 293 } 294 } 295 296 static GDBFeature *arm_gen_dynamic_sysreg_feature(CPUState *cs, int base_reg) 297 { 298 ARMCPU *cpu = ARM_CPU(cs); 299 RegisterSysregFeatureParam param = {cs}; 300 gsize num_regs = g_hash_table_size(cpu->cp_regs); 301 302 gdb_feature_builder_init(¶m.builder, 303 &cpu->dyn_sysreg_feature.desc, 304 "org.qemu.gdb.arm.sys.regs", 305 "system-registers.xml", 306 base_reg); 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; 311 } 312 313 #ifdef CONFIG_TCG 314 typedef enum { 315 M_SYSREG_MSP, 316 M_SYSREG_PSP, 317 M_SYSREG_PRIMASK, 318 M_SYSREG_CONTROL, 319 M_SYSREG_BASEPRI, 320 M_SYSREG_FAULTMASK, 321 M_SYSREG_MSPLIM, 322 M_SYSREG_PSPLIM, 323 } MProfileSysreg; 324 325 static const struct { 326 const char *name; 327 int feature; 328 } m_sysreg_def[] = { 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 }, 337 }; 338 339 static uint32_t *m_sysreg_ptr(CPUARMState *env, MProfileSysreg reg, bool sec) 340 { 341 uint32_t *ptr; 342 343 switch (reg) { 344 case M_SYSREG_MSP: 345 ptr = arm_v7m_get_sp_ptr(env, sec, false, true); 346 break; 347 case M_SYSREG_PSP: 348 ptr = arm_v7m_get_sp_ptr(env, sec, true, true); 349 break; 350 case M_SYSREG_MSPLIM: 351 ptr = &env->v7m.msplim[sec]; 352 break; 353 case M_SYSREG_PSPLIM: 354 ptr = &env->v7m.psplim[sec]; 355 break; 356 case M_SYSREG_PRIMASK: 357 ptr = &env->v7m.primask[sec]; 358 break; 359 case M_SYSREG_BASEPRI: 360 ptr = &env->v7m.basepri[sec]; 361 break; 362 case M_SYSREG_FAULTMASK: 363 ptr = &env->v7m.faultmask[sec]; 364 break; 365 case M_SYSREG_CONTROL: 366 ptr = &env->v7m.control[sec]; 367 break; 368 default: 369 return NULL; 370 } 371 return arm_feature(env, m_sysreg_def[reg].feature) ? ptr : NULL; 372 } 373 374 static int m_sysreg_get(CPUARMState *env, GByteArray *buf, 375 MProfileSysreg reg, bool secure) 376 { 377 uint32_t *ptr = m_sysreg_ptr(env, reg, secure); 378 379 if (ptr == NULL) { 380 return 0; 381 } 382 return gdb_get_reg32(buf, *ptr); 383 } 384 385 static int arm_gdb_get_m_systemreg(CPUState *cs, GByteArray *buf, int reg) 386 { 387 ARMCPU *cpu = ARM_CPU(cs); 388 CPUARMState *env = &cpu->env; 389 390 /* 391 * Here, we emulate MRS instruction, where CONTROL has a mix of 392 * banked and non-banked bits. 393 */ 394 if (reg == M_SYSREG_CONTROL) { 395 return gdb_get_reg32(buf, arm_v7m_mrs_control(env, env->v7m.secure)); 396 } 397 return m_sysreg_get(env, buf, reg, env->v7m.secure); 398 } 399 400 static int arm_gdb_set_m_systemreg(CPUState *cs, uint8_t *buf, int reg) 401 { 402 return 0; /* TODO */ 403 } 404 405 static GDBFeature *arm_gen_dynamic_m_systemreg_feature(CPUState *cs, 406 int base_reg) 407 { 408 ARMCPU *cpu = ARM_CPU(cs); 409 CPUARMState *env = &cpu->env; 410 GDBFeatureBuilder builder; 411 int reg = 0; 412 int i; 413 414 gdb_feature_builder_init(&builder, &cpu->dyn_m_systemreg_feature.desc, 415 "org.gnu.gdb.arm.m-system", "arm-m-system.xml", 416 base_reg); 417 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, 421 reg++, "int", NULL); 422 } 423 } 424 425 gdb_feature_builder_end(&builder); 426 427 return &cpu->dyn_m_systemreg_feature.desc; 428 } 429 430 #ifndef CONFIG_USER_ONLY 431 /* 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. 434 */ 435 static int arm_gdb_get_m_secextreg(CPUState *cs, GByteArray *buf, int reg) 436 { 437 ARMCPU *cpu = ARM_CPU(cs); 438 CPUARMState *env = &cpu->env; 439 440 return m_sysreg_get(env, buf, reg >> 1, reg & 1); 441 } 442 443 static int arm_gdb_set_m_secextreg(CPUState *cs, uint8_t *buf, int reg) 444 { 445 return 0; /* TODO */ 446 } 447 448 static GDBFeature *arm_gen_dynamic_m_secextreg_feature(CPUState *cs, 449 int base_reg) 450 { 451 ARMCPU *cpu = ARM_CPU(cs); 452 GDBFeatureBuilder builder; 453 char *name; 454 int reg = 0; 455 int i; 456 457 gdb_feature_builder_init(&builder, &cpu->dyn_m_secextreg_feature.desc, 458 "org.gnu.gdb.arm.secext", "arm-m-secext.xml", 459 base_reg); 460 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++, 464 "int", NULL); 465 name = g_strconcat(m_sysreg_def[i].name, "_s", NULL); 466 gdb_feature_builder_append_reg(&builder, name, 32, reg++, 467 "int", NULL); 468 } 469 470 gdb_feature_builder_end(&builder); 471 472 return &cpu->dyn_m_secextreg_feature.desc; 473 } 474 #endif 475 #endif /* CONFIG_TCG */ 476 477 void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) 478 { 479 CPUState *cs = CPU(cpu); 480 CPUARMState *env = &cpu->env; 481 482 if (arm_feature(env, ARM_FEATURE_AARCH64)) { 483 /* 484 * The lower part of each SVE register aliases to the FPU 485 * registers so we don't need to include both. 486 */ 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); 492 } else { 493 gdb_register_coprocessor(cs, aarch64_gdb_get_fpu_reg, 494 aarch64_gdb_set_fpu_reg, 495 gdb_find_static_feature("aarch64-fpu.xml"), 496 0); 497 } 498 /* 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. 503 */ 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"), 508 0); 509 } 510 #endif 511 } else { 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"), 515 0); 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"), 519 0); 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); 523 } 524 if (!arm_feature(env, ARM_FEATURE_M)) { 525 /* 526 * A and R profile have FP sysregs FPEXC and FPSID that we 527 * expose to gdb. 528 */ 529 gdb_register_coprocessor(cs, vfp_gdb_get_sysreg, vfp_gdb_set_sysreg, 530 gdb_find_static_feature("arm-vfp-sysregs.xml"), 531 0); 532 } 533 } 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"), 537 0); 538 } 539 gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg, 540 arm_gen_dynamic_sysreg_feature(cs, cs->gdb_num_regs), 541 0); 542 543 #ifdef CONFIG_TCG 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); 553 } 554 #endif 555 } 556 #endif /* CONFIG_TCG */ 557 } 558