cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

gdbstub64.c (5533B)


      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}