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