qemu/target-arm/gdbstub.c
<<
>>
Prefs
   1/*
   2 * ARM 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 "cpu.h"
  23#include "exec/gdbstub.h"
  24
  25/* Old gdb always expect FPA registers.  Newer (xml-aware) gdb only expect
  26   whatever the target description contains.  Due to a historical mishap
  27   the FPA registers appear in between core integer regs and the CPSR.
  28   We hack round this by giving the FPA regs zero size when talking to a
  29   newer gdb.  */
  30
  31int arm_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
  32{
  33    ARMCPU *cpu = ARM_CPU(cs);
  34    CPUARMState *env = &cpu->env;
  35
  36    if (n < 16) {
  37        /* Core integer register.  */
  38        return gdb_get_reg32(mem_buf, env->regs[n]);
  39    }
  40    if (n < 24) {
  41        /* FPA registers.  */
  42        if (gdb_has_xml) {
  43            return 0;
  44        }
  45        memset(mem_buf, 0, 12);
  46        return 12;
  47    }
  48    switch (n) {
  49    case 24:
  50        /* FPA status register.  */
  51        if (gdb_has_xml) {
  52            return 0;
  53        }
  54        return gdb_get_reg32(mem_buf, 0);
  55    case 25:
  56        /* CPSR */
  57        return gdb_get_reg32(mem_buf, cpsr_read(env));
  58    case 26:
  59        return gdb_get_reg32(mem_buf, env->cp15.c0_cpuid);
  60    case 27:
  61        return gdb_get_reg32(mem_buf, env->cp15.c2_data);
  62    case 28:
  63        return gdb_get_reg32(mem_buf, env->cp15.c2_insn);
  64    case 29:
  65        return gdb_get_reg32(mem_buf, env->cp15.esr_el[1]);
  66    case 30:
  67        return gdb_get_reg32(mem_buf, mpidr_read_val(env));
  68    case 31:
  69        return gdb_get_reg32(mem_buf, env->elr_el[1]);
  70    }
  71    /* Unknown register.  */
  72    return 0;
  73}
  74
  75int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
  76{
  77    ARMCPU *cpu = ARM_CPU(cs);
  78    CPUARMState *env = &cpu->env;
  79    uint32_t tmp;
  80
  81    tmp = ldl_p(mem_buf);
  82
  83    /* Mask out low bit of PC to workaround gdb bugs.  This will probably
  84       cause problems if we ever implement the Jazelle DBX extensions.  */
  85    if (n == 15) {
  86        tmp &= ~1;
  87    }
  88
  89    if (n < 16) {
  90        /* Core integer register.  */
  91        env->regs[n] = tmp;
  92        return 4;
  93    }
  94    if (n < 24) { /* 16-23 */
  95        /* FPA registers (ignored).  */
  96        if (gdb_has_xml) {
  97            return 0;
  98        }
  99        return 12;
 100    }
 101    switch (n) {
 102    case 24:
 103        /* FPA status register (ignored).  */
 104        if (gdb_has_xml) {
 105            return 0;
 106        }
 107        return 4;
 108    case 25:
 109        /* CPSR */
 110        cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub);
 111        return 4;
 112    case 26:
 113        env->cp15.c0_cpuid = tmp;
 114        return 4;
 115    case 27:
 116        env->cp15.c2_data = tmp;
 117        return 4;
 118    case 28:
 119        env->cp15.c2_insn = tmp;
 120        return 4;
 121    case 29:
 122        env->cp15.esr_el[1] = tmp;
 123        return 4;
 124    case 30:
 125        /* Writing to the MPIDR is not supported */
 126        return 0;
 127    case 31:
 128        env->elr_el[1] = tmp;
 129        return 4;
 130    }
 131    /* Unknown register.  */
 132    return 0;
 133}
 134