qemu/target/arm/gdbstub.c
<<
>>
Prefs
   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
  25typedef 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
  37int 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
  72int 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
 133static 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
 157static 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
 183static 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
 194static 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
 207static 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
 217static 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
 237static 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
 255static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
 256{
 257    return 0;
 258}
 259
 260static 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
 272static 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
 307int 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, &param);
 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
 324struct TypeSize {
 325    const char *gdb_type;
 326    int  size;
 327    const char sz, suffix;
 328};
 329
 330static 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
 352int 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
 444const 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
 456void 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