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