qemu/target-s390x/gdbstub.c
<<
>>
Prefs
   1/*
   2 * s390x 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 "exec/gdbstub.h"
  23#include "qemu/bitops.h"
  24
  25int s390_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
  26{
  27    S390CPU *cpu = S390_CPU(cs);
  28    CPUS390XState *env = &cpu->env;
  29    uint64_t val;
  30    int cc_op;
  31
  32    switch (n) {
  33    case S390_PSWM_REGNUM:
  34        if (tcg_enabled()) {
  35            cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst,
  36                            env->cc_vr);
  37            val = deposit64(env->psw.mask, 44, 2, cc_op);
  38            return gdb_get_regl(mem_buf, val);
  39        }
  40        return gdb_get_regl(mem_buf, env->psw.mask);
  41    case S390_PSWA_REGNUM:
  42        return gdb_get_regl(mem_buf, env->psw.addr);
  43    case S390_R0_REGNUM ... S390_R15_REGNUM:
  44        return gdb_get_regl(mem_buf, env->regs[n - S390_R0_REGNUM]);
  45    }
  46    return 0;
  47}
  48
  49int s390_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
  50{
  51    S390CPU *cpu = S390_CPU(cs);
  52    CPUS390XState *env = &cpu->env;
  53    target_ulong tmpl = ldtul_p(mem_buf);
  54
  55    switch (n) {
  56    case S390_PSWM_REGNUM:
  57        env->psw.mask = tmpl;
  58        if (tcg_enabled()) {
  59            env->cc_op = extract64(tmpl, 44, 2);
  60        }
  61        break;
  62    case S390_PSWA_REGNUM:
  63        env->psw.addr = tmpl;
  64        break;
  65    case S390_R0_REGNUM ... S390_R15_REGNUM:
  66        env->regs[n - S390_R0_REGNUM] = tmpl;
  67        break;
  68    default:
  69        return 0;
  70    }
  71    return 8;
  72}
  73
  74/* the values represent the positions in s390-acr.xml */
  75#define S390_A0_REGNUM 0
  76#define S390_A15_REGNUM 15
  77/* total number of registers in s390-acr.xml */
  78#define S390_NUM_AC_REGS 16
  79
  80static int cpu_read_ac_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
  81{
  82    switch (n) {
  83    case S390_A0_REGNUM ... S390_A15_REGNUM:
  84        return gdb_get_reg32(mem_buf, env->aregs[n]);
  85    default:
  86        return 0;
  87    }
  88}
  89
  90static int cpu_write_ac_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
  91{
  92    switch (n) {
  93    case S390_A0_REGNUM ... S390_A15_REGNUM:
  94        env->aregs[n] = ldl_p(mem_buf);
  95        cpu_synchronize_post_init(ENV_GET_CPU(env));
  96        return 4;
  97    default:
  98        return 0;
  99    }
 100}
 101
 102/* the values represent the positions in s390-fpr.xml */
 103#define S390_FPC_REGNUM 0
 104#define S390_F0_REGNUM 1
 105#define S390_F15_REGNUM 16
 106/* total number of registers in s390-fpr.xml */
 107#define S390_NUM_FP_REGS 17
 108
 109static int cpu_read_fp_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
 110{
 111    switch (n) {
 112    case S390_FPC_REGNUM:
 113        return gdb_get_reg32(mem_buf, env->fpc);
 114    case S390_F0_REGNUM ... S390_F15_REGNUM:
 115        return gdb_get_reg64(mem_buf, get_freg(env, n - S390_F0_REGNUM)->ll);
 116    default:
 117        return 0;
 118    }
 119}
 120
 121static int cpu_write_fp_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
 122{
 123    switch (n) {
 124    case S390_FPC_REGNUM:
 125        env->fpc = ldl_p(mem_buf);
 126        return 4;
 127    case S390_F0_REGNUM ... S390_F15_REGNUM:
 128        get_freg(env, n - S390_F0_REGNUM)->ll = ldtul_p(mem_buf);
 129        return 8;
 130    default:
 131        return 0;
 132    }
 133}
 134
 135/* the values represent the positions in s390-vx.xml */
 136#define S390_V0L_REGNUM 0
 137#define S390_V15L_REGNUM 15
 138#define S390_V16_REGNUM 16
 139#define S390_V31_REGNUM 31
 140/* total number of registers in s390-vx.xml */
 141#define S390_NUM_VREGS 32
 142
 143static int cpu_read_vreg(CPUS390XState *env, uint8_t *mem_buf, int n)
 144{
 145    int ret;
 146
 147    switch (n) {
 148    case S390_V0L_REGNUM ... S390_V15L_REGNUM:
 149        ret = gdb_get_reg64(mem_buf, env->vregs[n][1].ll);
 150        break;
 151    case S390_V16_REGNUM ... S390_V31_REGNUM:
 152        ret = gdb_get_reg64(mem_buf, env->vregs[n][0].ll);
 153        ret += gdb_get_reg64(mem_buf + 8, env->vregs[n][1].ll);
 154        break;
 155    default:
 156        ret = 0;
 157    }
 158
 159    return ret;
 160}
 161
 162static int cpu_write_vreg(CPUS390XState *env, uint8_t *mem_buf, int n)
 163{
 164    switch (n) {
 165    case S390_V0L_REGNUM ... S390_V15L_REGNUM:
 166        env->vregs[n][1].ll = ldtul_p(mem_buf + 8);
 167        return 8;
 168    case S390_V16_REGNUM ... S390_V31_REGNUM:
 169        env->vregs[n][0].ll = ldtul_p(mem_buf);
 170        env->vregs[n][1].ll = ldtul_p(mem_buf + 8);
 171        return 16;
 172    default:
 173        return 0;
 174    }
 175}
 176
 177/* the values represent the positions in s390-cr.xml */
 178#define S390_C0_REGNUM 0
 179#define S390_C15_REGNUM 15
 180/* total number of registers in s390-cr.xml */
 181#define S390_NUM_C_REGS 16
 182
 183#ifndef CONFIG_USER_ONLY
 184static int cpu_read_c_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
 185{
 186    switch (n) {
 187    case S390_C0_REGNUM ... S390_C15_REGNUM:
 188        return gdb_get_regl(mem_buf, env->cregs[n]);
 189    default:
 190        return 0;
 191    }
 192}
 193
 194static int cpu_write_c_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
 195{
 196    switch (n) {
 197    case S390_C0_REGNUM ... S390_C15_REGNUM:
 198        env->cregs[n] = ldtul_p(mem_buf);
 199        if (tcg_enabled()) {
 200            tlb_flush(ENV_GET_CPU(env), 1);
 201        }
 202        cpu_synchronize_post_init(ENV_GET_CPU(env));
 203        return 8;
 204    default:
 205        return 0;
 206    }
 207}
 208
 209/* the values represent the positions in s390-virt.xml */
 210#define S390_VIRT_CKC_REGNUM    0
 211#define S390_VIRT_CPUTM_REGNUM  1
 212#define S390_VIRT_BEA_REGNUM    2
 213#define S390_VIRT_PREFIX_REGNUM 3
 214#define S390_VIRT_PP_REGNUM     4
 215#define S390_VIRT_PFT_REGNUM    5
 216#define S390_VIRT_PFS_REGNUM    6
 217#define S390_VIRT_PFC_REGNUM    7
 218/* total number of registers in s390-virt.xml */
 219#define S390_NUM_VIRT_REGS 8
 220
 221static int cpu_read_virt_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
 222{
 223    switch (n) {
 224    case S390_VIRT_CKC_REGNUM:
 225        return gdb_get_regl(mem_buf, env->ckc);
 226    case S390_VIRT_CPUTM_REGNUM:
 227        return gdb_get_regl(mem_buf, env->cputm);
 228    case S390_VIRT_BEA_REGNUM:
 229        return gdb_get_regl(mem_buf, env->gbea);
 230    case S390_VIRT_PREFIX_REGNUM:
 231        return gdb_get_regl(mem_buf, env->psa);
 232    case S390_VIRT_PP_REGNUM:
 233        return gdb_get_regl(mem_buf, env->pp);
 234    case S390_VIRT_PFT_REGNUM:
 235        return gdb_get_regl(mem_buf, env->pfault_token);
 236    case S390_VIRT_PFS_REGNUM:
 237        return gdb_get_regl(mem_buf, env->pfault_select);
 238    case S390_VIRT_PFC_REGNUM:
 239        return gdb_get_regl(mem_buf, env->pfault_compare);
 240    default:
 241        return 0;
 242    }
 243}
 244
 245static int cpu_write_virt_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
 246{
 247    switch (n) {
 248    case S390_VIRT_CKC_REGNUM:
 249        env->ckc = ldtul_p(mem_buf);
 250        cpu_synchronize_post_init(ENV_GET_CPU(env));
 251        return 8;
 252    case S390_VIRT_CPUTM_REGNUM:
 253        env->cputm = ldtul_p(mem_buf);
 254        cpu_synchronize_post_init(ENV_GET_CPU(env));
 255        return 8;
 256    case S390_VIRT_BEA_REGNUM:
 257        env->gbea = ldtul_p(mem_buf);
 258        cpu_synchronize_post_init(ENV_GET_CPU(env));
 259        return 8;
 260    case S390_VIRT_PREFIX_REGNUM:
 261        env->psa = ldtul_p(mem_buf);
 262        cpu_synchronize_post_init(ENV_GET_CPU(env));
 263        return 8;
 264    case S390_VIRT_PP_REGNUM:
 265        env->pp = ldtul_p(mem_buf);
 266        cpu_synchronize_post_init(ENV_GET_CPU(env));
 267        return 8;
 268    case S390_VIRT_PFT_REGNUM:
 269        env->pfault_token = ldtul_p(mem_buf);
 270        cpu_synchronize_post_init(ENV_GET_CPU(env));
 271        return 8;
 272    case S390_VIRT_PFS_REGNUM:
 273        env->pfault_select = ldtul_p(mem_buf);
 274        cpu_synchronize_post_init(ENV_GET_CPU(env));
 275        return 8;
 276    case S390_VIRT_PFC_REGNUM:
 277        env->pfault_compare = ldtul_p(mem_buf);
 278        cpu_synchronize_post_init(ENV_GET_CPU(env));
 279        return 8;
 280    default:
 281        return 0;
 282    }
 283}
 284#endif
 285
 286void s390_cpu_gdb_init(CPUState *cs)
 287{
 288    gdb_register_coprocessor(cs, cpu_read_ac_reg,
 289                             cpu_write_ac_reg,
 290                             S390_NUM_AC_REGS, "s390-acr.xml", 0);
 291
 292    gdb_register_coprocessor(cs, cpu_read_fp_reg,
 293                             cpu_write_fp_reg,
 294                             S390_NUM_FP_REGS, "s390-fpr.xml", 0);
 295
 296    gdb_register_coprocessor(cs, cpu_read_vreg,
 297                             cpu_write_vreg,
 298                             S390_NUM_VREGS, "s390-vx.xml", 0);
 299
 300#ifndef CONFIG_USER_ONLY
 301    gdb_register_coprocessor(cs, cpu_read_c_reg,
 302                             cpu_write_c_reg,
 303                             S390_NUM_C_REGS, "s390-cr.xml", 0);
 304
 305    if (kvm_enabled()) {
 306        gdb_register_coprocessor(cs, cpu_read_virt_reg,
 307                                 cpu_write_virt_reg,
 308                                 S390_NUM_VIRT_REGS, "s390-virt.xml", 0);
 309    }
 310#endif
 311}
 312