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