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 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-common.h"
  21#include "cpu.h"
  22#include "exec/gdbstub.h"
  23#include "internals.h"
  24
  25#ifndef CONFIG_USER_ONLY
  26
  27/* FIXME: This should be generalized and moved into helper.c */
  28static void map_a32_to_a64_regs(CPUARMState *env)
  29{
  30    unsigned int i;
  31
  32    for (i = 0; i < 8; i++) {
  33        env->xregs[i] = env->regs[i];
  34    }
  35    for (i = 0; i < ARRAY_SIZE(env->usr_regs); i++) {
  36        env->xregs[i + 8] = env->usr_regs[i];
  37    }
  38    env->xregs[13] = env->banked_r13[bank_number(ARM_CPU_MODE_USR)];
  39    env->xregs[14] = env->banked_r14[bank_number(ARM_CPU_MODE_USR)];
  40
  41    for (i = 0; i < ARRAY_SIZE(env->fiq_regs); i++) {
  42        env->xregs[i + 24] = env->fiq_regs[i];
  43    }
  44    env->xregs[29] = env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)];
  45    env->xregs[30] = env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)];
  46
  47    /* HAX!  */
  48    env->xregs[31] = env->regs[13];
  49
  50    env->pc = env->regs[15];
  51    pstate_write(env, env->spsr | (1 << 4));
  52}
  53
  54static void map_a64_to_a32_regs(CPUARMState *env)
  55{
  56    unsigned int i = 0;
  57
  58    for (i = 0; i < 8; i++) {
  59        env->regs[i] = env->xregs[i];
  60    }
  61    for (i = 0; i < ARRAY_SIZE(env->usr_regs); i++) {
  62        env->usr_regs[i] = env->xregs[i + 8];
  63    }
  64    env->banked_r13[bank_number(ARM_CPU_MODE_USR)] = env->xregs[13];
  65    env->banked_r14[bank_number(ARM_CPU_MODE_USR)] = env->xregs[14];
  66
  67    for (i = 0; i < ARRAY_SIZE(env->usr_regs); i++) {
  68        env->fiq_regs[i] = env->xregs[i + 24];
  69    }
  70    env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[29];
  71    env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30];
  72
  73    env->regs[15] = env->pc;
  74}
  75
  76#endif
  77
  78int aarch64_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
  79{
  80    ARMCPU *cpu = ARM_CPU(cs);
  81    CPUARMState *env = &cpu->env;
  82
  83#ifndef CONFIG_USER_ONLY
  84    if (!is_a64(env)) {
  85        map_a32_to_a64_regs(env);
  86    }
  87#endif
  88
  89    if (n < 31) {
  90        /* Core integer register.  */
  91        return gdb_get_reg64(mem_buf, env->xregs[n]);
  92    }
  93    switch (n) {
  94    case 31:
  95    {
  96        unsigned int cur_el = arm_current_el(env);
  97        uint64_t sp;
  98
  99        aarch64_save_sp(env, cur_el);
 100        switch (env->debug_ctx) {
 101            case DEBUG_EL0:
 102                sp = env->sp_el[0];
 103                break;
 104            case DEBUG_EL1:
 105                sp = env->sp_el[1];
 106                break;
 107            case DEBUG_EL2:
 108                sp = env->sp_el[2];
 109                break;
 110            case DEBUG_EL3:
 111                sp = env->sp_el[3];
 112                break;
 113            default:
 114                sp = env->xregs[31];
 115                break;
 116        }
 117        return gdb_get_reg64(mem_buf, sp);
 118    }
 119    case 32:
 120        return gdb_get_reg64(mem_buf, env->pc);
 121    case 33:
 122        return gdb_get_reg32(mem_buf, pstate_read(env));
 123    }
 124    /* Unknown register.  */
 125    return 0;
 126}
 127
 128int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 129{
 130    ARMCPU *cpu = ARM_CPU(cs);
 131    CPUARMState *env = &cpu->env;
 132    uint64_t tmp;
 133    int rlen = 0;
 134
 135#ifndef CONFIG_USER_ONLY
 136    if (!is_a64(env)) {
 137        map_a32_to_a64_regs(env);
 138    }
 139#endif
 140
 141    tmp = ldq_p(mem_buf);
 142
 143    if (n < 31) {
 144        /* Core integer register.  */
 145        env->xregs[n] = tmp;
 146        rlen = 8;
 147    }
 148    switch (n) {
 149    case 31: {
 150        unsigned int cur_el = arm_current_el(env);
 151
 152        aarch64_save_sp(env, cur_el);
 153        switch (env->debug_ctx) {
 154            case DEBUG_EL0:
 155                env->sp_el[0] = tmp;
 156                break;
 157            case DEBUG_EL1:
 158                env->sp_el[1] = tmp;
 159                break;
 160            case DEBUG_EL2:
 161                env->sp_el[2] = tmp;
 162                break;
 163            case DEBUG_EL3:
 164                env->sp_el[3] = tmp;
 165                break;
 166            default:
 167                env->xregs[31] = tmp;
 168                break;
 169        }
 170        aarch64_restore_sp(env, cur_el);
 171        rlen = 8;
 172        break;
 173    }
 174    case 32:
 175        env->pc = tmp;
 176        rlen = 8;
 177        break;
 178    case 33:
 179        /* CPSR */
 180        pstate_write(env, tmp);
 181        rlen = 4;
 182        break;
 183    }
 184
 185#ifndef CONFIG_USER_ONLY
 186    if (!is_a64(env)) {
 187        map_a64_to_a32_regs(env);
 188    }
 189#endif
 190
 191    /* Unknown register.  */
 192    return rlen;
 193}
 194