qemu/target/ppc/gdbstub.c
<<
>>
Prefs
   1/*
   2 * PowerPC 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 "internal.h"
  24
  25static int ppc_gdb_register_len_apple(int n)
  26{
  27    switch (n) {
  28    case 0 ... 31:
  29        /* gprs */
  30        return 8;
  31    case 32 ... 63:
  32        /* fprs */
  33        return 8;
  34    case 64 ... 95:
  35        return 16;
  36    case 64 + 32: /* nip */
  37    case 65 + 32: /* msr */
  38    case 67 + 32: /* lr */
  39    case 68 + 32: /* ctr */
  40    case 70 + 32: /* fpscr */
  41        return 8;
  42    case 66 + 32: /* cr */
  43    case 69 + 32: /* xer */
  44        return 4;
  45    default:
  46        return 0;
  47    }
  48}
  49
  50static int ppc_gdb_register_len(int n)
  51{
  52    switch (n) {
  53    case 0 ... 31:
  54        /* gprs */
  55        return sizeof(target_ulong);
  56    case 32 ... 63:
  57        /* fprs */
  58        if (gdb_has_xml) {
  59            return 0;
  60        }
  61        return 8;
  62    case 66:
  63        /* cr */
  64    case 69:
  65        /* xer */
  66        return 4;
  67    case 64:
  68        /* nip */
  69    case 65:
  70        /* msr */
  71    case 67:
  72        /* lr */
  73    case 68:
  74        /* ctr */
  75        return sizeof(target_ulong);
  76    case 70:
  77        /* fpscr */
  78        if (gdb_has_xml) {
  79            return 0;
  80        }
  81        return sizeof(target_ulong);
  82    default:
  83        return 0;
  84    }
  85}
  86
  87/*
  88 * We need to present the registers to gdb in the "current" memory
  89 * ordering.  For user-only mode we get this for free;
  90 * TARGET_WORDS_BIGENDIAN is set to the proper ordering for the
  91 * binary, and cannot be changed.  For system mode,
  92 * TARGET_WORDS_BIGENDIAN is always set, and we must check the current
  93 * mode of the chip to see if we're running in little-endian.
  94 */
  95void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
  96{
  97#ifndef CONFIG_USER_ONLY
  98    if (!msr_le) {
  99        /* do nothing */
 100    } else if (len == 4) {
 101        bswap32s((uint32_t *)mem_buf);
 102    } else if (len == 8) {
 103        bswap64s((uint64_t *)mem_buf);
 104    } else if (len == 16) {
 105        bswap128s((Int128 *)mem_buf);
 106    } else {
 107        g_assert_not_reached();
 108    }
 109#endif
 110}
 111
 112/*
 113 * Old gdb always expects FP registers.  Newer (xml-aware) gdb only
 114 * expects whatever the target description contains.  Due to a
 115 * historical mishap the FP registers appear in between core integer
 116 * regs and PC, MSR, CR, and so forth.  We hack round this by giving
 117 * the FP regs zero size when talking to a newer gdb.
 118 */
 119
 120int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
 121{
 122    PowerPCCPU *cpu = POWERPC_CPU(cs);
 123    CPUPPCState *env = &cpu->env;
 124    uint8_t *mem_buf;
 125    int r = ppc_gdb_register_len(n);
 126
 127    if (!r) {
 128        return r;
 129    }
 130
 131    if (n < 32) {
 132        /* gprs */
 133        gdb_get_regl(buf, env->gpr[n]);
 134    } else if (n < 64) {
 135        /* fprs */
 136        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
 137    } else {
 138        switch (n) {
 139        case 64:
 140            gdb_get_regl(buf, env->nip);
 141            break;
 142        case 65:
 143            gdb_get_regl(buf, env->msr);
 144            break;
 145        case 66:
 146            {
 147                uint32_t cr = 0;
 148                int i;
 149                for (i = 0; i < 8; i++) {
 150                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
 151                }
 152                gdb_get_reg32(buf, cr);
 153                break;
 154            }
 155        case 67:
 156            gdb_get_regl(buf, env->lr);
 157            break;
 158        case 68:
 159            gdb_get_regl(buf, env->ctr);
 160            break;
 161        case 69:
 162            gdb_get_reg32(buf, cpu_read_xer(env));
 163            break;
 164        case 70:
 165            gdb_get_reg32(buf, env->fpscr);
 166            break;
 167        }
 168    }
 169    mem_buf = buf->data + buf->len - r;
 170    ppc_maybe_bswap_register(env, mem_buf, r);
 171    return r;
 172}
 173
 174int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n)
 175{
 176    PowerPCCPU *cpu = POWERPC_CPU(cs);
 177    CPUPPCState *env = &cpu->env;
 178    uint8_t *mem_buf;
 179    int r = ppc_gdb_register_len_apple(n);
 180
 181    if (!r) {
 182        return r;
 183    }
 184
 185    if (n < 32) {
 186        /* gprs */
 187        gdb_get_reg64(buf, env->gpr[n]);
 188    } else if (n < 64) {
 189        /* fprs */
 190        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
 191    } else if (n < 96) {
 192        /* Altivec */
 193        gdb_get_reg64(buf, n - 64);
 194        gdb_get_reg64(buf, 0);
 195    } else {
 196        switch (n) {
 197        case 64 + 32:
 198            gdb_get_reg64(buf, env->nip);
 199            break;
 200        case 65 + 32:
 201            gdb_get_reg64(buf, env->msr);
 202            break;
 203        case 66 + 32:
 204            {
 205                uint32_t cr = 0;
 206                int i;
 207                for (i = 0; i < 8; i++) {
 208                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
 209                }
 210                gdb_get_reg32(buf, cr);
 211                break;
 212            }
 213        case 67 + 32:
 214            gdb_get_reg64(buf, env->lr);
 215            break;
 216        case 68 + 32:
 217            gdb_get_reg64(buf, env->ctr);
 218            break;
 219        case 69 + 32:
 220            gdb_get_reg32(buf, cpu_read_xer(env));
 221            break;
 222        case 70 + 32:
 223            gdb_get_reg64(buf, env->fpscr);
 224            break;
 225        }
 226    }
 227    mem_buf = buf->data + buf->len - r;
 228    ppc_maybe_bswap_register(env, mem_buf, r);
 229    return r;
 230}
 231
 232int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 233{
 234    PowerPCCPU *cpu = POWERPC_CPU(cs);
 235    CPUPPCState *env = &cpu->env;
 236    int r = ppc_gdb_register_len(n);
 237
 238    if (!r) {
 239        return r;
 240    }
 241    ppc_maybe_bswap_register(env, mem_buf, r);
 242    if (n < 32) {
 243        /* gprs */
 244        env->gpr[n] = ldtul_p(mem_buf);
 245    } else if (n < 64) {
 246        /* fprs */
 247        *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
 248    } else {
 249        switch (n) {
 250        case 64:
 251            env->nip = ldtul_p(mem_buf);
 252            break;
 253        case 65:
 254            ppc_store_msr(env, ldtul_p(mem_buf));
 255            break;
 256        case 66:
 257            {
 258                uint32_t cr = ldl_p(mem_buf);
 259                int i;
 260                for (i = 0; i < 8; i++) {
 261                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
 262                }
 263                break;
 264            }
 265        case 67:
 266            env->lr = ldtul_p(mem_buf);
 267            break;
 268        case 68:
 269            env->ctr = ldtul_p(mem_buf);
 270            break;
 271        case 69:
 272            cpu_write_xer(env, ldl_p(mem_buf));
 273            break;
 274        case 70:
 275            /* fpscr */
 276            ppc_store_fpscr(env, ldtul_p(mem_buf));
 277            break;
 278        }
 279    }
 280    return r;
 281}
 282int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
 283{
 284    PowerPCCPU *cpu = POWERPC_CPU(cs);
 285    CPUPPCState *env = &cpu->env;
 286    int r = ppc_gdb_register_len_apple(n);
 287
 288    if (!r) {
 289        return r;
 290    }
 291    ppc_maybe_bswap_register(env, mem_buf, r);
 292    if (n < 32) {
 293        /* gprs */
 294        env->gpr[n] = ldq_p(mem_buf);
 295    } else if (n < 64) {
 296        /* fprs */
 297        *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
 298    } else {
 299        switch (n) {
 300        case 64 + 32:
 301            env->nip = ldq_p(mem_buf);
 302            break;
 303        case 65 + 32:
 304            ppc_store_msr(env, ldq_p(mem_buf));
 305            break;
 306        case 66 + 32:
 307            {
 308                uint32_t cr = ldl_p(mem_buf);
 309                int i;
 310                for (i = 0; i < 8; i++) {
 311                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
 312                }
 313                break;
 314            }
 315        case 67 + 32:
 316            env->lr = ldq_p(mem_buf);
 317            break;
 318        case 68 + 32:
 319            env->ctr = ldq_p(mem_buf);
 320            break;
 321        case 69 + 32:
 322            cpu_write_xer(env, ldl_p(mem_buf));
 323            break;
 324        case 70 + 32:
 325            /* fpscr */
 326            ppc_store_fpscr(env, ldq_p(mem_buf));
 327            break;
 328        }
 329    }
 330    return r;
 331}
 332
 333#ifndef CONFIG_USER_ONLY
 334void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu)
 335{
 336    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
 337    CPUPPCState *env = &cpu->env;
 338    GString *xml;
 339    char *spr_name;
 340    unsigned int num_regs = 0;
 341    int i;
 342
 343    if (pcc->gdb_spr_xml) {
 344        return;
 345    }
 346
 347    xml = g_string_new("<?xml version=\"1.0\"?>");
 348    g_string_append(xml, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
 349    g_string_append(xml, "<feature name=\"org.qemu.power.spr\">");
 350
 351    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
 352        ppc_spr_t *spr = &env->spr_cb[i];
 353
 354        if (!spr->name) {
 355            continue;
 356        }
 357
 358        spr_name = g_ascii_strdown(spr->name, -1);
 359        g_string_append_printf(xml, "<reg name=\"%s\"", spr_name);
 360        g_free(spr_name);
 361
 362        g_string_append_printf(xml, " bitsize=\"%d\"", TARGET_LONG_BITS);
 363        g_string_append(xml, " group=\"spr\"/>");
 364
 365        /*
 366         * GDB identifies registers based on the order they are
 367         * presented in the XML. These ids will not match QEMU's
 368         * representation (which follows the PowerISA).
 369         *
 370         * Store the position of the current register description so
 371         * we can make the correspondence later.
 372         */
 373        spr->gdb_id = num_regs;
 374        num_regs++;
 375    }
 376
 377    g_string_append(xml, "</feature>");
 378
 379    pcc->gdb_num_sprs = num_regs;
 380    pcc->gdb_spr_xml = g_string_free(xml, false);
 381}
 382
 383const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name)
 384{
 385    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
 386
 387    if (strcmp(xml_name, "power-spr.xml") == 0) {
 388        return pcc->gdb_spr_xml;
 389    }
 390    return NULL;
 391}
 392#endif
 393
 394#if !defined(CONFIG_USER_ONLY)
 395static int gdb_find_spr_idx(CPUPPCState *env, int n)
 396{
 397    int i;
 398
 399    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
 400        ppc_spr_t *spr = &env->spr_cb[i];
 401
 402        if (spr->name && spr->gdb_id == n) {
 403            return i;
 404        }
 405    }
 406    return -1;
 407}
 408
 409static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
 410{
 411    int reg;
 412    int len;
 413
 414    reg = gdb_find_spr_idx(env, n);
 415    if (reg < 0) {
 416        return 0;
 417    }
 418
 419    len = TARGET_LONG_SIZE;
 420    gdb_get_regl(buf, env->spr[reg]);
 421    ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
 422    return len;
 423}
 424
 425static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 426{
 427    int reg;
 428    int len;
 429
 430    reg = gdb_find_spr_idx(env, n);
 431    if (reg < 0) {
 432        return 0;
 433    }
 434
 435    len = TARGET_LONG_SIZE;
 436    ppc_maybe_bswap_register(env, mem_buf, len);
 437    env->spr[reg] = ldn_p(mem_buf, len);
 438
 439    return len;
 440}
 441#endif
 442
 443static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
 444{
 445    uint8_t *mem_buf;
 446    if (n < 32) {
 447        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
 448        mem_buf = gdb_get_reg_ptr(buf, 8);
 449        ppc_maybe_bswap_register(env, mem_buf, 8);
 450        return 8;
 451    }
 452    if (n == 32) {
 453        gdb_get_reg32(buf, env->fpscr);
 454        mem_buf = gdb_get_reg_ptr(buf, 4);
 455        ppc_maybe_bswap_register(env, mem_buf, 4);
 456        return 4;
 457    }
 458    return 0;
 459}
 460
 461static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 462{
 463    if (n < 32) {
 464        ppc_maybe_bswap_register(env, mem_buf, 8);
 465        *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
 466        return 8;
 467    }
 468    if (n == 32) {
 469        ppc_maybe_bswap_register(env, mem_buf, 4);
 470        ppc_store_fpscr(env, ldl_p(mem_buf));
 471        return 4;
 472    }
 473    return 0;
 474}
 475
 476static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
 477{
 478    uint8_t *mem_buf;
 479
 480    if (n < 32) {
 481        ppc_avr_t *avr = cpu_avr_ptr(env, n);
 482        gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1));
 483        mem_buf = gdb_get_reg_ptr(buf, 16);
 484        ppc_maybe_bswap_register(env, mem_buf, 16);
 485        return 16;
 486    }
 487    if (n == 32) {
 488        gdb_get_reg32(buf, ppc_get_vscr(env));
 489        mem_buf = gdb_get_reg_ptr(buf, 4);
 490        ppc_maybe_bswap_register(env, mem_buf, 4);
 491        return 4;
 492    }
 493    if (n == 33) {
 494        gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
 495        mem_buf = gdb_get_reg_ptr(buf, 4);
 496        ppc_maybe_bswap_register(env, mem_buf, 4);
 497        return 4;
 498    }
 499    return 0;
 500}
 501
 502static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 503{
 504    if (n < 32) {
 505        ppc_avr_t *avr = cpu_avr_ptr(env, n);
 506        ppc_maybe_bswap_register(env, mem_buf, 16);
 507        avr->VsrD(0) = ldq_p(mem_buf);
 508        avr->VsrD(1) = ldq_p(mem_buf + 8);
 509        return 16;
 510    }
 511    if (n == 32) {
 512        ppc_maybe_bswap_register(env, mem_buf, 4);
 513        ppc_store_vscr(env, ldl_p(mem_buf));
 514        return 4;
 515    }
 516    if (n == 33) {
 517        ppc_maybe_bswap_register(env, mem_buf, 4);
 518        env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
 519        return 4;
 520    }
 521    return 0;
 522}
 523
 524static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
 525{
 526    if (n < 32) {
 527#if defined(TARGET_PPC64)
 528        gdb_get_reg32(buf, env->gpr[n] >> 32);
 529        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
 530#else
 531        gdb_get_reg32(buf, env->gprh[n]);
 532#endif
 533        return 4;
 534    }
 535    if (n == 32) {
 536        gdb_get_reg64(buf, env->spe_acc);
 537        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
 538        return 8;
 539    }
 540    if (n == 33) {
 541        gdb_get_reg32(buf, env->spe_fscr);
 542        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
 543        return 4;
 544    }
 545    return 0;
 546}
 547
 548static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 549{
 550    if (n < 32) {
 551#if defined(TARGET_PPC64)
 552        target_ulong lo = (uint32_t)env->gpr[n];
 553        target_ulong hi;
 554
 555        ppc_maybe_bswap_register(env, mem_buf, 4);
 556
 557        hi = (target_ulong)ldl_p(mem_buf) << 32;
 558        env->gpr[n] = lo | hi;
 559#else
 560        env->gprh[n] = ldl_p(mem_buf);
 561#endif
 562        return 4;
 563    }
 564    if (n == 32) {
 565        ppc_maybe_bswap_register(env, mem_buf, 8);
 566        env->spe_acc = ldq_p(mem_buf);
 567        return 8;
 568    }
 569    if (n == 33) {
 570        ppc_maybe_bswap_register(env, mem_buf, 4);
 571        env->spe_fscr = ldl_p(mem_buf);
 572        return 4;
 573    }
 574    return 0;
 575}
 576
 577static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
 578{
 579    if (n < 32) {
 580        gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
 581        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
 582        return 8;
 583    }
 584    return 0;
 585}
 586
 587static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 588{
 589    if (n < 32) {
 590        ppc_maybe_bswap_register(env, mem_buf, 8);
 591        *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
 592        return 8;
 593    }
 594    return 0;
 595}
 596
 597gchar *ppc_gdb_arch_name(CPUState *cs)
 598{
 599#if defined(TARGET_PPC64)
 600    return g_strdup("powerpc:common64");
 601#else
 602    return g_strdup("powerpc:common");
 603#endif
 604}
 605
 606void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
 607{
 608    if (pcc->insns_flags & PPC_FLOAT) {
 609        gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
 610                                 33, "power-fpu.xml", 0);
 611    }
 612    if (pcc->insns_flags & PPC_ALTIVEC) {
 613        gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
 614                                 34, "power-altivec.xml", 0);
 615    }
 616    if (pcc->insns_flags & PPC_SPE) {
 617        gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
 618                                 34, "power-spe.xml", 0);
 619    }
 620    if (pcc->insns_flags2 & PPC2_VSX) {
 621        gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
 622                                 32, "power-vsx.xml", 0);
 623    }
 624#ifndef CONFIG_USER_ONLY
 625    gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
 626                             pcc->gdb_num_sprs, "power-spr.xml", 0);
 627#endif
 628}
 629