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 "system/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 arm_cpu_gdb_read_register(CPUState * cs,GByteArray * mem_buf,int n)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 #ifdef TARGET_AARCH64 48 if (arm_gdbstub_is_aarch64(cpu)) { 49 return aarch64_cpu_gdb_read_register(cs, mem_buf, n); 50 } 51 #endif 52 53 if (n < 16) { 54 /* Core integer register. */ 55 return gdb_get_reg32(mem_buf, env->regs[n]); 56 } 57 if (n == 25) { 58 /* CPSR, or XPSR for M-profile */ 59 if (arm_feature(env, ARM_FEATURE_M)) { 60 return gdb_get_reg32(mem_buf, xpsr_read(env)); 61 } else { 62 return gdb_get_reg32(mem_buf, cpsr_read(env)); 63 } 64 } 65 /* Unknown register. */ 66 return 0; 67 } 68 arm_cpu_gdb_write_register(CPUState * cs,uint8_t * mem_buf,int n)69 int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 70 { 71 ARMCPU *cpu = ARM_CPU(cs); 72 CPUARMState *env = &cpu->env; 73 uint32_t tmp; 74 75 #ifdef TARGET_AARCH64 76 if (arm_gdbstub_is_aarch64(cpu)) { 77 return aarch64_cpu_gdb_write_register(cs, mem_buf, n); 78 } 79 #endif 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 == 25) { 104 /* CPSR, or XPSR for M-profile */ 105 if (arm_feature(env, ARM_FEATURE_M)) { 106 /* 107 * Don't allow writing to XPSR.Exception as it can cause 108 * a transition into or out of handler mode (it's not 109 * writable via the MSR insn so this is a reasonable 110 * restriction). Other fields are safe to update. 111 */ 112 xpsr_write(env, tmp, ~XPSR_EXCP); 113 } else { 114 cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub); 115 } 116 return 4; 117 } 118 /* Unknown register. */ 119 return 0; 120 } 121 vfp_gdb_get_reg(CPUState * cs,GByteArray * buf,int reg)122 static int vfp_gdb_get_reg(CPUState *cs, GByteArray *buf, int reg) 123 { 124 ARMCPU *cpu = ARM_CPU(cs); 125 CPUARMState *env = &cpu->env; 126 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16; 127 128 /* VFP data registers are always little-endian. */ 129 if (reg < nregs) { 130 return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg)); 131 } 132 if (arm_feature(env, ARM_FEATURE_NEON)) { 133 /* Aliases for Q regs. */ 134 nregs += 16; 135 if (reg < nregs) { 136 uint64_t *q = aa32_vfp_qreg(env, reg - 32); 137 return gdb_get_reg128(buf, q[0], q[1]); 138 } 139 } 140 switch (reg - nregs) { 141 case 0: 142 return gdb_get_reg32(buf, vfp_get_fpscr(env)); 143 } 144 return 0; 145 } 146 vfp_gdb_set_reg(CPUState * cs,uint8_t * buf,int reg)147 static int vfp_gdb_set_reg(CPUState *cs, uint8_t *buf, int reg) 148 { 149 ARMCPU *cpu = ARM_CPU(cs); 150 CPUARMState *env = &cpu->env; 151 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16; 152 153 if (reg < nregs) { 154 *aa32_vfp_dreg(env, reg) = ldq_le_p(buf); 155 return 8; 156 } 157 if (arm_feature(env, ARM_FEATURE_NEON)) { 158 nregs += 16; 159 if (reg < nregs) { 160 uint64_t *q = aa32_vfp_qreg(env, reg - 32); 161 q[0] = ldq_le_p(buf); 162 q[1] = ldq_le_p(buf + 8); 163 return 16; 164 } 165 } 166 switch (reg - nregs) { 167 case 0: 168 vfp_set_fpscr(env, ldl_p(buf)); 169 return 4; 170 } 171 return 0; 172 } 173 vfp_gdb_get_sysreg(CPUState * cs,GByteArray * buf,int reg)174 static int vfp_gdb_get_sysreg(CPUState *cs, GByteArray *buf, int reg) 175 { 176 ARMCPU *cpu = ARM_CPU(cs); 177 CPUARMState *env = &cpu->env; 178 179 switch (reg) { 180 case 0: 181 return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]); 182 case 1: 183 return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]); 184 } 185 return 0; 186 } 187 vfp_gdb_set_sysreg(CPUState * cs,uint8_t * buf,int reg)188 static int vfp_gdb_set_sysreg(CPUState *cs, uint8_t *buf, int reg) 189 { 190 ARMCPU *cpu = ARM_CPU(cs); 191 CPUARMState *env = &cpu->env; 192 193 switch (reg) { 194 case 0: 195 env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); 196 return 4; 197 case 1: 198 env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); 199 return 4; 200 } 201 return 0; 202 } 203 mve_gdb_get_reg(CPUState * cs,GByteArray * buf,int reg)204 static int mve_gdb_get_reg(CPUState *cs, GByteArray *buf, int reg) 205 { 206 ARMCPU *cpu = ARM_CPU(cs); 207 CPUARMState *env = &cpu->env; 208 209 switch (reg) { 210 case 0: 211 return gdb_get_reg32(buf, env->v7m.vpr); 212 default: 213 return 0; 214 } 215 } 216 mve_gdb_set_reg(CPUState * cs,uint8_t * buf,int reg)217 static int mve_gdb_set_reg(CPUState *cs, uint8_t *buf, int reg) 218 { 219 ARMCPU *cpu = ARM_CPU(cs); 220 CPUARMState *env = &cpu->env; 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 arm_gdb_get_sysreg(CPUState * cs,GByteArray * buf,int reg)240 static int arm_gdb_get_sysreg(CPUState *cs, GByteArray *buf, int reg) 241 { 242 ARMCPU *cpu = ARM_CPU(cs); 243 CPUARMState *env = &cpu->env; 244 const ARMCPRegInfo *ri; 245 uint32_t key; 246 247 key = cpu->dyn_sysreg_feature.data.cpregs.keys[reg]; 248 ri = get_arm_cp_reginfo(cpu->cp_regs, key); 249 if (ri) { 250 if (cpreg_field_is_64bit(ri)) { 251 return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri)); 252 } else { 253 return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri)); 254 } 255 } 256 return 0; 257 } 258 arm_gdb_set_sysreg(CPUState * cs,uint8_t * buf,int reg)259 static int arm_gdb_set_sysreg(CPUState *cs, uint8_t *buf, int reg) 260 { 261 return 0; 262 } 263 arm_gen_one_feature_sysreg(GDBFeatureBuilder * builder,DynamicGDBFeatureInfo * dyn_feature,ARMCPRegInfo * ri,uint32_t ri_key,int bitsize,int n)264 static void arm_gen_one_feature_sysreg(GDBFeatureBuilder *builder, 265 DynamicGDBFeatureInfo *dyn_feature, 266 ARMCPRegInfo *ri, uint32_t ri_key, 267 int bitsize, int n) 268 { 269 gdb_feature_builder_append_reg(builder, ri->name, bitsize, n, 270 "int", "cp_regs"); 271 272 dyn_feature->data.cpregs.keys[n] = ri_key; 273 } 274 arm_register_sysreg_for_feature(gpointer key,gpointer value,gpointer p)275 static void arm_register_sysreg_for_feature(gpointer key, gpointer value, 276 gpointer p) 277 { 278 uint32_t ri_key = (uintptr_t)key; 279 ARMCPRegInfo *ri = value; 280 RegisterSysregFeatureParam *param = p; 281 ARMCPU *cpu = ARM_CPU(param->cs); 282 CPUARMState *env = &cpu->env; 283 DynamicGDBFeatureInfo *dyn_feature = &cpu->dyn_sysreg_feature; 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_feature_sysreg(¶m->builder, dyn_feature, 289 ri, ri_key, 64, 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_feature_sysreg(¶m->builder, dyn_feature, 299 ri, ri_key, 64, param->n++); 300 } else { 301 arm_gen_one_feature_sysreg(¶m->builder, dyn_feature, 302 ri, ri_key, 32, param->n++); 303 } 304 } 305 } 306 } 307 } 308 arm_gen_dynamic_sysreg_feature(CPUState * cs,int base_reg)309 static GDBFeature *arm_gen_dynamic_sysreg_feature(CPUState *cs, int base_reg) 310 { 311 ARMCPU *cpu = ARM_CPU(cs); 312 RegisterSysregFeatureParam param = {cs}; 313 gsize num_regs = g_hash_table_size(cpu->cp_regs); 314 315 gdb_feature_builder_init(¶m.builder, 316 &cpu->dyn_sysreg_feature.desc, 317 "org.qemu.gdb.arm.sys.regs", 318 "system-registers.xml", 319 base_reg); 320 cpu->dyn_sysreg_feature.data.cpregs.keys = g_new(uint32_t, num_regs); 321 g_hash_table_foreach(cpu->cp_regs, arm_register_sysreg_for_feature, ¶m); 322 gdb_feature_builder_end(¶m.builder); 323 return &cpu->dyn_sysreg_feature.desc; 324 } 325 326 #ifdef CONFIG_TCG 327 typedef enum { 328 M_SYSREG_MSP, 329 M_SYSREG_PSP, 330 M_SYSREG_PRIMASK, 331 M_SYSREG_CONTROL, 332 M_SYSREG_BASEPRI, 333 M_SYSREG_FAULTMASK, 334 M_SYSREG_MSPLIM, 335 M_SYSREG_PSPLIM, 336 } MProfileSysreg; 337 338 static const struct { 339 const char *name; 340 int feature; 341 } m_sysreg_def[] = { 342 [M_SYSREG_MSP] = { "msp", ARM_FEATURE_M }, 343 [M_SYSREG_PSP] = { "psp", ARM_FEATURE_M }, 344 [M_SYSREG_PRIMASK] = { "primask", ARM_FEATURE_M }, 345 [M_SYSREG_CONTROL] = { "control", ARM_FEATURE_M }, 346 [M_SYSREG_BASEPRI] = { "basepri", ARM_FEATURE_M_MAIN }, 347 [M_SYSREG_FAULTMASK] = { "faultmask", ARM_FEATURE_M_MAIN }, 348 [M_SYSREG_MSPLIM] = { "msplim", ARM_FEATURE_V8 }, 349 [M_SYSREG_PSPLIM] = { "psplim", ARM_FEATURE_V8 }, 350 }; 351 m_sysreg_ptr(CPUARMState * env,MProfileSysreg reg,bool sec)352 static uint32_t *m_sysreg_ptr(CPUARMState *env, MProfileSysreg reg, bool sec) 353 { 354 uint32_t *ptr; 355 356 switch (reg) { 357 case M_SYSREG_MSP: 358 ptr = arm_v7m_get_sp_ptr(env, sec, false, true); 359 break; 360 case M_SYSREG_PSP: 361 ptr = arm_v7m_get_sp_ptr(env, sec, true, true); 362 break; 363 case M_SYSREG_MSPLIM: 364 ptr = &env->v7m.msplim[sec]; 365 break; 366 case M_SYSREG_PSPLIM: 367 ptr = &env->v7m.psplim[sec]; 368 break; 369 case M_SYSREG_PRIMASK: 370 ptr = &env->v7m.primask[sec]; 371 break; 372 case M_SYSREG_BASEPRI: 373 ptr = &env->v7m.basepri[sec]; 374 break; 375 case M_SYSREG_FAULTMASK: 376 ptr = &env->v7m.faultmask[sec]; 377 break; 378 case M_SYSREG_CONTROL: 379 ptr = &env->v7m.control[sec]; 380 break; 381 default: 382 return NULL; 383 } 384 return arm_feature(env, m_sysreg_def[reg].feature) ? ptr : NULL; 385 } 386 m_sysreg_get(CPUARMState * env,GByteArray * buf,MProfileSysreg reg,bool secure)387 static int m_sysreg_get(CPUARMState *env, GByteArray *buf, 388 MProfileSysreg reg, bool secure) 389 { 390 uint32_t *ptr = m_sysreg_ptr(env, reg, secure); 391 392 if (ptr == NULL) { 393 return 0; 394 } 395 return gdb_get_reg32(buf, *ptr); 396 } 397 arm_gdb_get_m_systemreg(CPUState * cs,GByteArray * buf,int reg)398 static int arm_gdb_get_m_systemreg(CPUState *cs, GByteArray *buf, int reg) 399 { 400 ARMCPU *cpu = ARM_CPU(cs); 401 CPUARMState *env = &cpu->env; 402 403 /* 404 * Here, we emulate MRS instruction, where CONTROL has a mix of 405 * banked and non-banked bits. 406 */ 407 if (reg == M_SYSREG_CONTROL) { 408 return gdb_get_reg32(buf, arm_v7m_mrs_control(env, env->v7m.secure)); 409 } 410 return m_sysreg_get(env, buf, reg, env->v7m.secure); 411 } 412 arm_gdb_set_m_systemreg(CPUState * cs,uint8_t * buf,int reg)413 static int arm_gdb_set_m_systemreg(CPUState *cs, uint8_t *buf, int reg) 414 { 415 return 0; /* TODO */ 416 } 417 arm_gen_dynamic_m_systemreg_feature(CPUState * cs,int base_reg)418 static GDBFeature *arm_gen_dynamic_m_systemreg_feature(CPUState *cs, 419 int base_reg) 420 { 421 ARMCPU *cpu = ARM_CPU(cs); 422 CPUARMState *env = &cpu->env; 423 GDBFeatureBuilder builder; 424 int reg = 0; 425 int i; 426 427 gdb_feature_builder_init(&builder, &cpu->dyn_m_systemreg_feature.desc, 428 "org.gnu.gdb.arm.m-system", "arm-m-system.xml", 429 base_reg); 430 431 for (i = 0; i < ARRAY_SIZE(m_sysreg_def); i++) { 432 if (arm_feature(env, m_sysreg_def[i].feature)) { 433 gdb_feature_builder_append_reg(&builder, m_sysreg_def[i].name, 32, 434 reg++, "int", NULL); 435 } 436 } 437 438 gdb_feature_builder_end(&builder); 439 440 return &cpu->dyn_m_systemreg_feature.desc; 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 */ arm_gdb_get_m_secextreg(CPUState * cs,GByteArray * buf,int reg)448 static int arm_gdb_get_m_secextreg(CPUState *cs, GByteArray *buf, int reg) 449 { 450 ARMCPU *cpu = ARM_CPU(cs); 451 CPUARMState *env = &cpu->env; 452 453 return m_sysreg_get(env, buf, reg >> 1, reg & 1); 454 } 455 arm_gdb_set_m_secextreg(CPUState * cs,uint8_t * buf,int reg)456 static int arm_gdb_set_m_secextreg(CPUState *cs, uint8_t *buf, int reg) 457 { 458 return 0; /* TODO */ 459 } 460 arm_gen_dynamic_m_secextreg_feature(CPUState * cs,int base_reg)461 static GDBFeature *arm_gen_dynamic_m_secextreg_feature(CPUState *cs, 462 int base_reg) 463 { 464 ARMCPU *cpu = ARM_CPU(cs); 465 GDBFeatureBuilder builder; 466 char *name; 467 int reg = 0; 468 int i; 469 470 gdb_feature_builder_init(&builder, &cpu->dyn_m_secextreg_feature.desc, 471 "org.gnu.gdb.arm.secext", "arm-m-secext.xml", 472 base_reg); 473 474 for (i = 0; i < ARRAY_SIZE(m_sysreg_def); i++) { 475 name = g_strconcat(m_sysreg_def[i].name, "_ns", NULL); 476 gdb_feature_builder_append_reg(&builder, name, 32, reg++, 477 "int", NULL); 478 name = g_strconcat(m_sysreg_def[i].name, "_s", NULL); 479 gdb_feature_builder_append_reg(&builder, name, 32, reg++, 480 "int", NULL); 481 } 482 483 gdb_feature_builder_end(&builder); 484 485 return &cpu->dyn_m_secextreg_feature.desc; 486 } 487 #endif 488 #endif /* CONFIG_TCG */ 489 arm_cpu_register_gdb_commands(ARMCPU * cpu)490 void arm_cpu_register_gdb_commands(ARMCPU *cpu) 491 { 492 g_autoptr(GPtrArray) query_table = g_ptr_array_new(); 493 g_autoptr(GPtrArray) set_table = g_ptr_array_new(); 494 g_autoptr(GString) qsupported_features = g_string_new(NULL); 495 496 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { 497 #ifdef TARGET_AARCH64 498 aarch64_cpu_register_gdb_commands(cpu, qsupported_features, query_table, 499 set_table); 500 #endif 501 } 502 503 /* Set arch-specific handlers for 'q' commands. */ 504 if (query_table->len) { 505 gdb_extend_query_table(query_table); 506 } 507 508 /* Set arch-specific handlers for 'Q' commands. */ 509 if (set_table->len) { 510 gdb_extend_set_table(set_table); 511 } 512 513 /* Set arch-specific qSupported feature. */ 514 if (qsupported_features->len) { 515 gdb_extend_qsupported_features(qsupported_features->str); 516 } 517 } 518 arm_cpu_register_gdb_regs_for_features(ARMCPU * cpu)519 void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) 520 { 521 CPUState *cs = CPU(cpu); 522 CPUARMState *env = &cpu->env; 523 524 if (arm_feature(env, ARM_FEATURE_AARCH64)) { 525 /* 526 * The lower part of each SVE register aliases to the FPU 527 * registers so we don't need to include both. 528 */ 529 #ifdef TARGET_AARCH64 530 if (isar_feature_aa64_sve(&cpu->isar)) { 531 GDBFeature *feature = arm_gen_dynamic_svereg_feature(cs, cs->gdb_num_regs); 532 gdb_register_coprocessor(cs, aarch64_gdb_get_sve_reg, 533 aarch64_gdb_set_sve_reg, feature, 0); 534 } else { 535 gdb_register_coprocessor(cs, aarch64_gdb_get_fpu_reg, 536 aarch64_gdb_set_fpu_reg, 537 gdb_find_static_feature("aarch64-fpu.xml"), 538 0); 539 } 540 /* 541 * Note that we report pauth information via the feature name 542 * org.gnu.gdb.aarch64.pauth_v2, not org.gnu.gdb.aarch64.pauth. 543 * GDB versions 9 through 12 have a bug where they will crash 544 * if they see the latter XML from QEMU. 545 */ 546 if (isar_feature_aa64_pauth(&cpu->isar)) { 547 gdb_register_coprocessor(cs, aarch64_gdb_get_pauth_reg, 548 aarch64_gdb_set_pauth_reg, 549 gdb_find_static_feature("aarch64-pauth.xml"), 550 0); 551 } 552 553 #ifdef CONFIG_USER_ONLY 554 /* Memory Tagging Extension (MTE) 'tag_ctl' pseudo-register. */ 555 if (cpu_isar_feature(aa64_mte, cpu)) { 556 gdb_register_coprocessor(cs, aarch64_gdb_get_tag_ctl_reg, 557 aarch64_gdb_set_tag_ctl_reg, 558 gdb_find_static_feature("aarch64-mte.xml"), 559 0); 560 } 561 #endif 562 #endif 563 } else { 564 if (arm_feature(env, ARM_FEATURE_NEON)) { 565 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 566 gdb_find_static_feature("arm-neon.xml"), 567 0); 568 } else if (cpu_isar_feature(aa32_simd_r32, cpu)) { 569 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 570 gdb_find_static_feature("arm-vfp3.xml"), 571 0); 572 } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) { 573 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 574 gdb_find_static_feature("arm-vfp.xml"), 0); 575 } 576 if (!arm_feature(env, ARM_FEATURE_M)) { 577 /* 578 * A and R profile have FP sysregs FPEXC and FPSID that we 579 * expose to gdb. 580 */ 581 gdb_register_coprocessor(cs, vfp_gdb_get_sysreg, vfp_gdb_set_sysreg, 582 gdb_find_static_feature("arm-vfp-sysregs.xml"), 583 0); 584 } 585 } 586 if (cpu_isar_feature(aa32_mve, cpu) && tcg_enabled()) { 587 gdb_register_coprocessor(cs, mve_gdb_get_reg, mve_gdb_set_reg, 588 gdb_find_static_feature("arm-m-profile-mve.xml"), 589 0); 590 } 591 gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg, 592 arm_gen_dynamic_sysreg_feature(cs, cs->gdb_num_regs), 593 0); 594 595 #ifdef CONFIG_TCG 596 if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) { 597 gdb_register_coprocessor(cs, 598 arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg, 599 arm_gen_dynamic_m_systemreg_feature(cs, cs->gdb_num_regs), 0); 600 #ifndef CONFIG_USER_ONLY 601 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { 602 gdb_register_coprocessor(cs, 603 arm_gdb_get_m_secextreg, arm_gdb_set_m_secextreg, 604 arm_gen_dynamic_m_secextreg_feature(cs, cs->gdb_num_regs), 0); 605 } 606 #endif 607 } 608 #endif /* CONFIG_TCG */ 609 } 610