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