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