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 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 "qemu-common.h"
  22#include "cpu.h"
  23#include "exec/gdbstub.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 69+32: /* xer */
  41    case 70+32: /* fpscr */
  42        return 8;
  43    case 66+32: /* cr */
  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        return 4;
  65    case 64:
  66        /* nip */
  67    case 65:
  68        /* msr */
  69    case 67:
  70        /* lr */
  71    case 68:
  72        /* ctr */
  73    case 69:
  74        /* xer */
  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/* We need to present the registers to gdb in the "current" memory ordering.
  88   For user-only mode we get this for free; TARGET_WORDS_BIGENDIAN is set to
  89   the proper ordering for the binary, and cannot be changed.
  90   For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check
  91   the current mode of the chip to see if we're running in little-endian.  */
  92void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
  93{
  94#ifndef CONFIG_USER_ONLY
  95    if (!msr_le) {
  96        /* do nothing */
  97    } else if (len == 4) {
  98        bswap32s((uint32_t *)mem_buf);
  99    } else if (len == 8) {
 100        bswap64s((uint64_t *)mem_buf);
 101    } else {
 102        g_assert_not_reached();
 103    }
 104#endif
 105}
 106
 107/* Old gdb always expects FP registers.  Newer (xml-aware) gdb only
 108 * expects whatever the target description contains.  Due to a
 109 * historical mishap the FP registers appear in between core integer
 110 * regs and PC, MSR, CR, and so forth.  We hack round this by giving the
 111 * FP regs zero size when talking to a newer gdb.
 112 */
 113
 114int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
 115{
 116    PowerPCCPU *cpu = POWERPC_CPU(cs);
 117    CPUPPCState *env = &cpu->env;
 118    int r = ppc_gdb_register_len(n);
 119
 120    if (!r) {
 121        return r;
 122    }
 123
 124    if (n < 32) {
 125        /* gprs */
 126        gdb_get_regl(mem_buf, env->gpr[n]);
 127    } else if (n < 64) {
 128        /* fprs */
 129        stfq_p(mem_buf, env->fpr[n-32]);
 130    } else {
 131        switch (n) {
 132        case 64:
 133            gdb_get_regl(mem_buf, env->nip);
 134            break;
 135        case 65:
 136            gdb_get_regl(mem_buf, env->msr);
 137            break;
 138        case 66:
 139            {
 140                uint32_t cr = 0;
 141                int i;
 142                for (i = 0; i < 8; i++) {
 143                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
 144                }
 145                gdb_get_reg32(mem_buf, cr);
 146                break;
 147            }
 148        case 67:
 149            gdb_get_regl(mem_buf, env->lr);
 150            break;
 151        case 68:
 152            gdb_get_regl(mem_buf, env->ctr);
 153            break;
 154        case 69:
 155            gdb_get_regl(mem_buf, env->xer);
 156            break;
 157        case 70:
 158            gdb_get_reg32(mem_buf, env->fpscr);
 159            break;
 160        }
 161    }
 162    ppc_maybe_bswap_register(env, mem_buf, r);
 163    return r;
 164}
 165
 166int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
 167{
 168    PowerPCCPU *cpu = POWERPC_CPU(cs);
 169    CPUPPCState *env = &cpu->env;
 170    int r = ppc_gdb_register_len_apple(n);
 171
 172    if (!r) {
 173        return r;
 174    }
 175
 176    if (n < 32) {
 177        /* gprs */
 178        gdb_get_reg64(mem_buf, env->gpr[n]);
 179    } else if (n < 64) {
 180        /* fprs */
 181        stfq_p(mem_buf, env->fpr[n-32]);
 182    } else if (n < 96) {
 183        /* Altivec */
 184        stq_p(mem_buf, n - 64);
 185        stq_p(mem_buf + 8, 0);
 186    } else {
 187        switch (n) {
 188        case 64 + 32:
 189            gdb_get_reg64(mem_buf, env->nip);
 190            break;
 191        case 65 + 32:
 192            gdb_get_reg64(mem_buf, env->msr);
 193            break;
 194        case 66 + 32:
 195            {
 196                uint32_t cr = 0;
 197                int i;
 198                for (i = 0; i < 8; i++) {
 199                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
 200                }
 201                gdb_get_reg32(mem_buf, cr);
 202                break;
 203            }
 204        case 67 + 32:
 205            gdb_get_reg64(mem_buf, env->lr);
 206            break;
 207        case 68 + 32:
 208            gdb_get_reg64(mem_buf, env->ctr);
 209            break;
 210        case 69 + 32:
 211            gdb_get_reg64(mem_buf, env->xer);
 212            break;
 213        case 70 + 32:
 214            gdb_get_reg64(mem_buf, env->fpscr);
 215            break;
 216        }
 217    }
 218    ppc_maybe_bswap_register(env, mem_buf, r);
 219    return r;
 220}
 221
 222int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 223{
 224    PowerPCCPU *cpu = POWERPC_CPU(cs);
 225    CPUPPCState *env = &cpu->env;
 226    int r = ppc_gdb_register_len(n);
 227
 228    if (!r) {
 229        return r;
 230    }
 231    ppc_maybe_bswap_register(env, mem_buf, r);
 232    if (n < 32) {
 233        /* gprs */
 234        env->gpr[n] = ldtul_p(mem_buf);
 235    } else if (n < 64) {
 236        /* fprs */
 237        env->fpr[n-32] = ldfq_p(mem_buf);
 238    } else {
 239        switch (n) {
 240        case 64:
 241            env->nip = ldtul_p(mem_buf);
 242            break;
 243        case 65:
 244            ppc_store_msr(env, ldtul_p(mem_buf));
 245            break;
 246        case 66:
 247            {
 248                uint32_t cr = ldl_p(mem_buf);
 249                int i;
 250                for (i = 0; i < 8; i++) {
 251                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
 252                }
 253                break;
 254            }
 255        case 67:
 256            env->lr = ldtul_p(mem_buf);
 257            break;
 258        case 68:
 259            env->ctr = ldtul_p(mem_buf);
 260            break;
 261        case 69:
 262            env->xer = ldtul_p(mem_buf);
 263            break;
 264        case 70:
 265            /* fpscr */
 266            store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
 267            break;
 268        }
 269    }
 270    return r;
 271}
 272int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
 273{
 274    PowerPCCPU *cpu = POWERPC_CPU(cs);
 275    CPUPPCState *env = &cpu->env;
 276    int r = ppc_gdb_register_len_apple(n);
 277
 278    if (!r) {
 279        return r;
 280    }
 281    ppc_maybe_bswap_register(env, mem_buf, r);
 282    if (n < 32) {
 283        /* gprs */
 284        env->gpr[n] = ldq_p(mem_buf);
 285    } else if (n < 64) {
 286        /* fprs */
 287        env->fpr[n-32] = ldfq_p(mem_buf);
 288    } else {
 289        switch (n) {
 290        case 64 + 32:
 291            env->nip = ldq_p(mem_buf);
 292            break;
 293        case 65 + 32:
 294            ppc_store_msr(env, ldq_p(mem_buf));
 295            break;
 296        case 66 + 32:
 297            {
 298                uint32_t cr = ldl_p(mem_buf);
 299                int i;
 300                for (i = 0; i < 8; i++) {
 301                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
 302                }
 303                break;
 304            }
 305        case 67 + 32:
 306            env->lr = ldq_p(mem_buf);
 307            break;
 308        case 68 + 32:
 309            env->ctr = ldq_p(mem_buf);
 310            break;
 311        case 69 + 32:
 312            env->xer = ldq_p(mem_buf);
 313            break;
 314        case 70 + 32:
 315            /* fpscr */
 316            store_fpscr(env, ldq_p(mem_buf), 0xffffffff);
 317            break;
 318        }
 319    }
 320    return r;
 321}
 322