qemu/target/arm/gdbstub64.c
<<
>>
Prefs
   1/*
   2 * ARM gdb server stub: AArch64 specific functions.
   3 *
   4 * Copyright (c) 2013 SUSE LINUX Products GmbH
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19#include "qemu/osdep.h"
  20#include "qemu/log.h"
  21#include "cpu.h"
  22#include "internals.h"
  23#include "exec/gdbstub.h"
  24
  25int aarch64_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
  26{
  27    ARMCPU *cpu = ARM_CPU(cs);
  28    CPUARMState *env = &cpu->env;
  29
  30    if (n < 31) {
  31        /* Core integer register.  */
  32        return gdb_get_reg64(mem_buf, env->xregs[n]);
  33    }
  34    switch (n) {
  35    case 31:
  36        return gdb_get_reg64(mem_buf, env->xregs[31]);
  37    case 32:
  38        return gdb_get_reg64(mem_buf, env->pc);
  39    case 33:
  40        return gdb_get_reg32(mem_buf, pstate_read(env));
  41    }
  42    /* Unknown register.  */
  43    return 0;
  44}
  45
  46int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
  47{
  48    ARMCPU *cpu = ARM_CPU(cs);
  49    CPUARMState *env = &cpu->env;
  50    uint64_t tmp;
  51
  52    tmp = ldq_p(mem_buf);
  53
  54    if (n < 31) {
  55        /* Core integer register.  */
  56        env->xregs[n] = tmp;
  57        return 8;
  58    }
  59    switch (n) {
  60    case 31:
  61        env->xregs[31] = tmp;
  62        return 8;
  63    case 32:
  64        env->pc = tmp;
  65        return 8;
  66    case 33:
  67        /* CPSR */
  68        pstate_write(env, tmp);
  69        return 4;
  70    }
  71    /* Unknown register.  */
  72    return 0;
  73}
  74
  75int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
  76{
  77    switch (reg) {
  78    case 0 ... 31:
  79    {
  80        /* 128 bit FP register - quads are in LE order */
  81        uint64_t *q = aa64_vfp_qreg(env, reg);
  82        return gdb_get_reg128(buf, q[1], q[0]);
  83    }
  84    case 32:
  85        /* FPSR */
  86        return gdb_get_reg32(buf, vfp_get_fpsr(env));
  87    case 33:
  88        /* FPCR */
  89        return gdb_get_reg32(buf, vfp_get_fpcr(env));
  90    default:
  91        return 0;
  92    }
  93}
  94
  95int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
  96{
  97    switch (reg) {
  98    case 0 ... 31:
  99        /* 128 bit FP register */
 100        {
 101            uint64_t *q = aa64_vfp_qreg(env, reg);
 102            q[0] = ldq_le_p(buf);
 103            q[1] = ldq_le_p(buf + 8);
 104            return 16;
 105        }
 106    case 32:
 107        /* FPSR */
 108        vfp_set_fpsr(env, ldl_p(buf));
 109        return 4;
 110    case 33:
 111        /* FPCR */
 112        vfp_set_fpcr(env, ldl_p(buf));
 113        return 4;
 114    default:
 115        return 0;
 116    }
 117}
 118
 119int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg)
 120{
 121    ARMCPU *cpu = env_archcpu(env);
 122
 123    switch (reg) {
 124    /* The first 32 registers are the zregs */
 125    case 0 ... 31:
 126    {
 127        int vq, len = 0;
 128        for (vq = 0; vq < cpu->sve_max_vq; vq++) {
 129            len += gdb_get_reg128(buf,
 130                                  env->vfp.zregs[reg].d[vq * 2 + 1],
 131                                  env->vfp.zregs[reg].d[vq * 2]);
 132        }
 133        return len;
 134    }
 135    case 32:
 136        return gdb_get_reg32(buf, vfp_get_fpsr(env));
 137    case 33:
 138        return gdb_get_reg32(buf, vfp_get_fpcr(env));
 139    /* then 16 predicates and the ffr */
 140    case 34 ... 50:
 141    {
 142        int preg = reg - 34;
 143        int vq, len = 0;
 144        for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
 145            len += gdb_get_reg64(buf, env->vfp.pregs[preg].p[vq / 4]);
 146        }
 147        return len;
 148    }
 149    case 51:
 150    {
 151        /*
 152         * We report in Vector Granules (VG) which is 64bit in a Z reg
 153         * while the ZCR works in Vector Quads (VQ) which is 128bit chunks.
 154         */
 155        int vq = sve_zcr_len_for_el(env, arm_current_el(env)) + 1;
 156        return gdb_get_reg64(buf, vq * 2);
 157    }
 158    default:
 159        /* gdbstub asked for something out our range */
 160        qemu_log_mask(LOG_UNIMP, "%s: out of range register %d", __func__, reg);
 161        break;
 162    }
 163
 164    return 0;
 165}
 166
 167int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg)
 168{
 169    ARMCPU *cpu = env_archcpu(env);
 170
 171    /* The first 32 registers are the zregs */
 172    switch (reg) {
 173    /* The first 32 registers are the zregs */
 174    case 0 ... 31:
 175    {
 176        int vq, len = 0;
 177        uint64_t *p = (uint64_t *) buf;
 178        for (vq = 0; vq < cpu->sve_max_vq; vq++) {
 179            env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
 180            env->vfp.zregs[reg].d[vq * 2] = *p++;
 181            len += 16;
 182        }
 183        return len;
 184    }
 185    case 32:
 186        vfp_set_fpsr(env, *(uint32_t *)buf);
 187        return 4;
 188    case 33:
 189        vfp_set_fpcr(env, *(uint32_t *)buf);
 190        return 4;
 191    case 34 ... 50:
 192    {
 193        int preg = reg - 34;
 194        int vq, len = 0;
 195        uint64_t *p = (uint64_t *) buf;
 196        for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
 197            env->vfp.pregs[preg].p[vq / 4] = *p++;
 198            len += 8;
 199        }
 200        return len;
 201    }
 202    case 51:
 203        /* cannot set vg via gdbstub */
 204        return 0;
 205    default:
 206        /* gdbstub asked for something out our range */
 207        break;
 208    }
 209
 210    return 0;
 211}
 212