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