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 "internals.h" 23 #include "exec/gdbstub.h" 24 25 typedef struct RegisterSysregXmlParam { 26 CPUState *cs; 27 GString *s; 28 int n; 29 } RegisterSysregXmlParam; 30 31 /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect 32 whatever the target description contains. Due to a historical mishap 33 the FPA registers appear in between core integer regs and the CPSR. 34 We hack round this by giving the FPA regs zero size when talking to a 35 newer gdb. */ 36 37 int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 38 { 39 ARMCPU *cpu = ARM_CPU(cs); 40 CPUARMState *env = &cpu->env; 41 42 if (n < 16) { 43 /* Core integer register. */ 44 return gdb_get_reg32(mem_buf, env->regs[n]); 45 } 46 if (n < 24) { 47 /* FPA registers. */ 48 if (gdb_has_xml) { 49 return 0; 50 } 51 return gdb_get_zeroes(mem_buf, 12); 52 } 53 switch (n) { 54 case 24: 55 /* FPA status register. */ 56 if (gdb_has_xml) { 57 return 0; 58 } 59 return gdb_get_reg32(mem_buf, 0); 60 case 25: 61 /* CPSR, or XPSR for M-profile */ 62 if (arm_feature(env, ARM_FEATURE_M)) { 63 return gdb_get_reg32(mem_buf, xpsr_read(env)); 64 } else { 65 return gdb_get_reg32(mem_buf, cpsr_read(env)); 66 } 67 } 68 /* Unknown register. */ 69 return 0; 70 } 71 72 int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 73 { 74 ARMCPU *cpu = ARM_CPU(cs); 75 CPUARMState *env = &cpu->env; 76 uint32_t tmp; 77 78 tmp = ldl_p(mem_buf); 79 80 /* 81 * Mask out low bits of PC to workaround gdb bugs. 82 * This avoids an assert in thumb_tr_translate_insn, because it is 83 * architecturally impossible to misalign the pc. 84 * This will probably cause problems if we ever implement the 85 * Jazelle DBX extensions. 86 */ 87 if (n == 15) { 88 tmp &= ~1; 89 } 90 91 if (n < 16) { 92 /* Core integer register. */ 93 if (n == 13 && arm_feature(env, ARM_FEATURE_M)) { 94 /* M profile SP low bits are always 0 */ 95 tmp &= ~3; 96 } 97 env->regs[n] = tmp; 98 return 4; 99 } 100 if (n < 24) { /* 16-23 */ 101 /* FPA registers (ignored). */ 102 if (gdb_has_xml) { 103 return 0; 104 } 105 return 12; 106 } 107 switch (n) { 108 case 24: 109 /* FPA status register (ignored). */ 110 if (gdb_has_xml) { 111 return 0; 112 } 113 return 4; 114 case 25: 115 /* CPSR, or XPSR for M-profile */ 116 if (arm_feature(env, ARM_FEATURE_M)) { 117 /* 118 * Don't allow writing to XPSR.Exception as it can cause 119 * a transition into or out of handler mode (it's not 120 * writeable via the MSR insn so this is a reasonable 121 * restriction). Other fields are safe to update. 122 */ 123 xpsr_write(env, tmp, ~XPSR_EXCP); 124 } else { 125 cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub); 126 } 127 return 4; 128 } 129 /* Unknown register. */ 130 return 0; 131 } 132 133 static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg) 134 { 135 ARMCPU *cpu = env_archcpu(env); 136 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16; 137 138 /* VFP data registers are always little-endian. */ 139 if (reg < nregs) { 140 return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg)); 141 } 142 if (arm_feature(env, ARM_FEATURE_NEON)) { 143 /* Aliases for Q regs. */ 144 nregs += 16; 145 if (reg < nregs) { 146 uint64_t *q = aa32_vfp_qreg(env, reg - 32); 147 return gdb_get_reg128(buf, q[0], q[1]); 148 } 149 } 150 switch (reg - nregs) { 151 case 0: 152 return gdb_get_reg32(buf, vfp_get_fpscr(env)); 153 } 154 return 0; 155 } 156 157 static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg) 158 { 159 ARMCPU *cpu = env_archcpu(env); 160 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16; 161 162 if (reg < nregs) { 163 *aa32_vfp_dreg(env, reg) = ldq_le_p(buf); 164 return 8; 165 } 166 if (arm_feature(env, ARM_FEATURE_NEON)) { 167 nregs += 16; 168 if (reg < nregs) { 169 uint64_t *q = aa32_vfp_qreg(env, reg - 32); 170 q[0] = ldq_le_p(buf); 171 q[1] = ldq_le_p(buf + 8); 172 return 16; 173 } 174 } 175 switch (reg - nregs) { 176 case 0: 177 vfp_set_fpscr(env, ldl_p(buf)); 178 return 4; 179 } 180 return 0; 181 } 182 183 static int vfp_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg) 184 { 185 switch (reg) { 186 case 0: 187 return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]); 188 case 1: 189 return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]); 190 } 191 return 0; 192 } 193 194 static int vfp_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg) 195 { 196 switch (reg) { 197 case 0: 198 env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); 199 return 4; 200 case 1: 201 env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); 202 return 4; 203 } 204 return 0; 205 } 206 207 static int mve_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg) 208 { 209 switch (reg) { 210 case 0: 211 return gdb_get_reg32(buf, env->v7m.vpr); 212 default: 213 return 0; 214 } 215 } 216 217 static int mve_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg) 218 { 219 switch (reg) { 220 case 0: 221 env->v7m.vpr = ldl_p(buf); 222 return 4; 223 default: 224 return 0; 225 } 226 } 227 228 /** 229 * arm_get/set_gdb_*: get/set a gdb register 230 * @env: the CPU state 231 * @buf: a buffer to copy to/from 232 * @reg: register number (offset from start of group) 233 * 234 * We return the number of bytes copied 235 */ 236 237 static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg) 238 { 239 ARMCPU *cpu = env_archcpu(env); 240 const ARMCPRegInfo *ri; 241 uint32_t key; 242 243 key = cpu->dyn_sysreg_xml.data.cpregs.keys[reg]; 244 ri = get_arm_cp_reginfo(cpu->cp_regs, key); 245 if (ri) { 246 if (cpreg_field_is_64bit(ri)) { 247 return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri)); 248 } else { 249 return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri)); 250 } 251 } 252 return 0; 253 } 254 255 static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg) 256 { 257 return 0; 258 } 259 260 static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml, 261 ARMCPRegInfo *ri, uint32_t ri_key, 262 int bitsize, int regnum) 263 { 264 g_string_append_printf(s, "<reg name=\"%s\"", ri->name); 265 g_string_append_printf(s, " bitsize=\"%d\"", bitsize); 266 g_string_append_printf(s, " regnum=\"%d\"", regnum); 267 g_string_append_printf(s, " group=\"cp_regs\"/>"); 268 dyn_xml->data.cpregs.keys[dyn_xml->num] = ri_key; 269 dyn_xml->num++; 270 } 271 272 static void arm_register_sysreg_for_xml(gpointer key, gpointer value, 273 gpointer p) 274 { 275 uint32_t ri_key = *(uint32_t *)key; 276 ARMCPRegInfo *ri = value; 277 RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p; 278 GString *s = param->s; 279 ARMCPU *cpu = ARM_CPU(param->cs); 280 CPUARMState *env = &cpu->env; 281 DynamicGDBXMLInfo *dyn_xml = &cpu->dyn_sysreg_xml; 282 283 if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_NO_GDB))) { 284 if (arm_feature(env, ARM_FEATURE_AARCH64)) { 285 if (ri->state == ARM_CP_STATE_AA64) { 286 arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, 287 param->n++); 288 } 289 } else { 290 if (ri->state == ARM_CP_STATE_AA32) { 291 if (!arm_feature(env, ARM_FEATURE_EL3) && 292 (ri->secure & ARM_CP_SECSTATE_S)) { 293 return; 294 } 295 if (ri->type & ARM_CP_64BIT) { 296 arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, 297 param->n++); 298 } else { 299 arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 32, 300 param->n++); 301 } 302 } 303 } 304 } 305 } 306 307 int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg) 308 { 309 ARMCPU *cpu = ARM_CPU(cs); 310 GString *s = g_string_new(NULL); 311 RegisterSysregXmlParam param = {cs, s, base_reg}; 312 313 cpu->dyn_sysreg_xml.num = 0; 314 cpu->dyn_sysreg_xml.data.cpregs.keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs)); 315 g_string_printf(s, "<?xml version=\"1.0\"?>"); 316 g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); 317 g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">"); 318 g_hash_table_foreach(cpu->cp_regs, arm_register_sysreg_for_xml, ¶m); 319 g_string_append_printf(s, "</feature>"); 320 cpu->dyn_sysreg_xml.desc = g_string_free(s, false); 321 return cpu->dyn_sysreg_xml.num; 322 } 323 324 struct TypeSize { 325 const char *gdb_type; 326 int size; 327 const char sz, suffix; 328 }; 329 330 static const struct TypeSize vec_lanes[] = { 331 /* quads */ 332 { "uint128", 128, 'q', 'u' }, 333 { "int128", 128, 'q', 's' }, 334 /* 64 bit */ 335 { "ieee_double", 64, 'd', 'f' }, 336 { "uint64", 64, 'd', 'u' }, 337 { "int64", 64, 'd', 's' }, 338 /* 32 bit */ 339 { "ieee_single", 32, 's', 'f' }, 340 { "uint32", 32, 's', 'u' }, 341 { "int32", 32, 's', 's' }, 342 /* 16 bit */ 343 { "ieee_half", 16, 'h', 'f' }, 344 { "uint16", 16, 'h', 'u' }, 345 { "int16", 16, 'h', 's' }, 346 /* bytes */ 347 { "uint8", 8, 'b', 'u' }, 348 { "int8", 8, 'b', 's' }, 349 }; 350 351 352 int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg) 353 { 354 ARMCPU *cpu = ARM_CPU(cs); 355 GString *s = g_string_new(NULL); 356 DynamicGDBXMLInfo *info = &cpu->dyn_svereg_xml; 357 g_autoptr(GString) ts = g_string_new(""); 358 int i, j, bits, reg_width = (cpu->sve_max_vq * 128); 359 info->num = 0; 360 g_string_printf(s, "<?xml version=\"1.0\"?>"); 361 g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); 362 g_string_append_printf(s, "<feature name=\"org.gnu.gdb.aarch64.sve\">"); 363 364 /* First define types and totals in a whole VL */ 365 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { 366 int count = reg_width / vec_lanes[i].size; 367 g_string_printf(ts, "svev%c%c", vec_lanes[i].sz, vec_lanes[i].suffix); 368 g_string_append_printf(s, 369 "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>", 370 ts->str, vec_lanes[i].gdb_type, count); 371 } 372 /* 373 * Now define a union for each size group containing unsigned and 374 * signed and potentially float versions of each size from 128 to 375 * 8 bits. 376 */ 377 for (bits = 128, i = 0; bits >= 8; bits /= 2, i++) { 378 const char suf[] = { 'q', 'd', 's', 'h', 'b' }; 379 g_string_append_printf(s, "<union id=\"svevn%c\">", suf[i]); 380 for (j = 0; j < ARRAY_SIZE(vec_lanes); j++) { 381 if (vec_lanes[j].size == bits) { 382 g_string_append_printf(s, "<field name=\"%c\" type=\"svev%c%c\"/>", 383 vec_lanes[j].suffix, 384 vec_lanes[j].sz, vec_lanes[j].suffix); 385 } 386 } 387 g_string_append(s, "</union>"); 388 } 389 /* And now the final union of unions */ 390 g_string_append(s, "<union id=\"svev\">"); 391 for (bits = 128, i = 0; bits >= 8; bits /= 2, i++) { 392 const char suf[] = { 'q', 'd', 's', 'h', 'b' }; 393 g_string_append_printf(s, "<field name=\"%c\" type=\"svevn%c\"/>", 394 suf[i], suf[i]); 395 } 396 g_string_append(s, "</union>"); 397 398 /* Finally the sve prefix type */ 399 g_string_append_printf(s, 400 "<vector id=\"svep\" type=\"uint8\" count=\"%d\"/>", 401 reg_width / 8); 402 403 /* Then define each register in parts for each vq */ 404 for (i = 0; i < 32; i++) { 405 g_string_append_printf(s, 406 "<reg name=\"z%d\" bitsize=\"%d\"" 407 " regnum=\"%d\" type=\"svev\"/>", 408 i, reg_width, base_reg++); 409 info->num++; 410 } 411 /* fpscr & status registers */ 412 g_string_append_printf(s, "<reg name=\"fpsr\" bitsize=\"32\"" 413 " regnum=\"%d\" group=\"float\"" 414 " type=\"int\"/>", base_reg++); 415 g_string_append_printf(s, "<reg name=\"fpcr\" bitsize=\"32\"" 416 " regnum=\"%d\" group=\"float\"" 417 " type=\"int\"/>", base_reg++); 418 info->num += 2; 419 420 for (i = 0; i < 16; i++) { 421 g_string_append_printf(s, 422 "<reg name=\"p%d\" bitsize=\"%d\"" 423 " regnum=\"%d\" type=\"svep\"/>", 424 i, cpu->sve_max_vq * 16, base_reg++); 425 info->num++; 426 } 427 g_string_append_printf(s, 428 "<reg name=\"ffr\" bitsize=\"%d\"" 429 " regnum=\"%d\" group=\"vector\"" 430 " type=\"svep\"/>", 431 cpu->sve_max_vq * 16, base_reg++); 432 g_string_append_printf(s, 433 "<reg name=\"vg\" bitsize=\"64\"" 434 " regnum=\"%d\" type=\"int\"/>", 435 base_reg++); 436 info->num += 2; 437 g_string_append_printf(s, "</feature>"); 438 cpu->dyn_svereg_xml.desc = g_string_free(s, false); 439 440 return cpu->dyn_svereg_xml.num; 441 } 442 443 444 const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) 445 { 446 ARMCPU *cpu = ARM_CPU(cs); 447 448 if (strcmp(xmlname, "system-registers.xml") == 0) { 449 return cpu->dyn_sysreg_xml.desc; 450 } else if (strcmp(xmlname, "sve-registers.xml") == 0) { 451 return cpu->dyn_svereg_xml.desc; 452 } 453 return NULL; 454 } 455 456 void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) 457 { 458 CPUState *cs = CPU(cpu); 459 CPUARMState *env = &cpu->env; 460 461 if (arm_feature(env, ARM_FEATURE_AARCH64)) { 462 /* 463 * The lower part of each SVE register aliases to the FPU 464 * registers so we don't need to include both. 465 */ 466 #ifdef TARGET_AARCH64 467 if (isar_feature_aa64_sve(&cpu->isar)) { 468 gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg, 469 arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs), 470 "sve-registers.xml", 0); 471 } else { 472 gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg, 473 aarch64_fpu_gdb_set_reg, 474 34, "aarch64-fpu.xml", 0); 475 } 476 #endif 477 } else { 478 if (arm_feature(env, ARM_FEATURE_NEON)) { 479 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 480 49, "arm-neon.xml", 0); 481 } else if (cpu_isar_feature(aa32_simd_r32, cpu)) { 482 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 483 33, "arm-vfp3.xml", 0); 484 } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) { 485 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 486 17, "arm-vfp.xml", 0); 487 } 488 if (!arm_feature(env, ARM_FEATURE_M)) { 489 /* 490 * A and R profile have FP sysregs FPEXC and FPSID that we 491 * expose to gdb. 492 */ 493 gdb_register_coprocessor(cs, vfp_gdb_get_sysreg, vfp_gdb_set_sysreg, 494 2, "arm-vfp-sysregs.xml", 0); 495 } 496 } 497 if (cpu_isar_feature(aa32_mve, cpu)) { 498 gdb_register_coprocessor(cs, mve_gdb_get_reg, mve_gdb_set_reg, 499 1, "arm-m-profile-mve.xml", 0); 500 } 501 gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg, 502 arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs), 503 "system-registers.xml", 0); 504 505 } 506