1*fcf5ef2aSThomas Huth /* 2*fcf5ef2aSThomas Huth * ARM gdb server stub 3*fcf5ef2aSThomas Huth * 4*fcf5ef2aSThomas Huth * Copyright (c) 2003-2005 Fabrice Bellard 5*fcf5ef2aSThomas Huth * Copyright (c) 2013 SUSE LINUX Products GmbH 6*fcf5ef2aSThomas Huth * 7*fcf5ef2aSThomas Huth * This library is free software; you can redistribute it and/or 8*fcf5ef2aSThomas Huth * modify it under the terms of the GNU Lesser General Public 9*fcf5ef2aSThomas Huth * License as published by the Free Software Foundation; either 10*fcf5ef2aSThomas Huth * version 2 of the License, or (at your option) any later version. 11*fcf5ef2aSThomas Huth * 12*fcf5ef2aSThomas Huth * This library is distributed in the hope that it will be useful, 13*fcf5ef2aSThomas Huth * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*fcf5ef2aSThomas Huth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*fcf5ef2aSThomas Huth * Lesser General Public License for more details. 16*fcf5ef2aSThomas Huth * 17*fcf5ef2aSThomas Huth * You should have received a copy of the GNU Lesser General Public 18*fcf5ef2aSThomas Huth * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19*fcf5ef2aSThomas Huth */ 20*fcf5ef2aSThomas Huth #include "qemu/osdep.h" 21*fcf5ef2aSThomas Huth #include "qemu-common.h" 22*fcf5ef2aSThomas Huth #include "cpu.h" 23*fcf5ef2aSThomas Huth #include "exec/gdbstub.h" 24*fcf5ef2aSThomas Huth 25*fcf5ef2aSThomas Huth /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect 26*fcf5ef2aSThomas Huth whatever the target description contains. Due to a historical mishap 27*fcf5ef2aSThomas Huth the FPA registers appear in between core integer regs and the CPSR. 28*fcf5ef2aSThomas Huth We hack round this by giving the FPA regs zero size when talking to a 29*fcf5ef2aSThomas Huth newer gdb. */ 30*fcf5ef2aSThomas Huth 31*fcf5ef2aSThomas Huth int arm_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) 32*fcf5ef2aSThomas Huth { 33*fcf5ef2aSThomas Huth ARMCPU *cpu = ARM_CPU(cs); 34*fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 35*fcf5ef2aSThomas Huth 36*fcf5ef2aSThomas Huth if (n < 16) { 37*fcf5ef2aSThomas Huth /* Core integer register. */ 38*fcf5ef2aSThomas Huth return gdb_get_reg32(mem_buf, env->regs[n]); 39*fcf5ef2aSThomas Huth } 40*fcf5ef2aSThomas Huth if (n < 24) { 41*fcf5ef2aSThomas Huth /* FPA registers. */ 42*fcf5ef2aSThomas Huth if (gdb_has_xml) { 43*fcf5ef2aSThomas Huth return 0; 44*fcf5ef2aSThomas Huth } 45*fcf5ef2aSThomas Huth memset(mem_buf, 0, 12); 46*fcf5ef2aSThomas Huth return 12; 47*fcf5ef2aSThomas Huth } 48*fcf5ef2aSThomas Huth switch (n) { 49*fcf5ef2aSThomas Huth case 24: 50*fcf5ef2aSThomas Huth /* FPA status register. */ 51*fcf5ef2aSThomas Huth if (gdb_has_xml) { 52*fcf5ef2aSThomas Huth return 0; 53*fcf5ef2aSThomas Huth } 54*fcf5ef2aSThomas Huth return gdb_get_reg32(mem_buf, 0); 55*fcf5ef2aSThomas Huth case 25: 56*fcf5ef2aSThomas Huth /* CPSR */ 57*fcf5ef2aSThomas Huth return gdb_get_reg32(mem_buf, cpsr_read(env)); 58*fcf5ef2aSThomas Huth } 59*fcf5ef2aSThomas Huth /* Unknown register. */ 60*fcf5ef2aSThomas Huth return 0; 61*fcf5ef2aSThomas Huth } 62*fcf5ef2aSThomas Huth 63*fcf5ef2aSThomas Huth int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 64*fcf5ef2aSThomas Huth { 65*fcf5ef2aSThomas Huth ARMCPU *cpu = ARM_CPU(cs); 66*fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 67*fcf5ef2aSThomas Huth uint32_t tmp; 68*fcf5ef2aSThomas Huth 69*fcf5ef2aSThomas Huth tmp = ldl_p(mem_buf); 70*fcf5ef2aSThomas Huth 71*fcf5ef2aSThomas Huth /* Mask out low bit of PC to workaround gdb bugs. This will probably 72*fcf5ef2aSThomas Huth cause problems if we ever implement the Jazelle DBX extensions. */ 73*fcf5ef2aSThomas Huth if (n == 15) { 74*fcf5ef2aSThomas Huth tmp &= ~1; 75*fcf5ef2aSThomas Huth } 76*fcf5ef2aSThomas Huth 77*fcf5ef2aSThomas Huth if (n < 16) { 78*fcf5ef2aSThomas Huth /* Core integer register. */ 79*fcf5ef2aSThomas Huth env->regs[n] = tmp; 80*fcf5ef2aSThomas Huth return 4; 81*fcf5ef2aSThomas Huth } 82*fcf5ef2aSThomas Huth if (n < 24) { /* 16-23 */ 83*fcf5ef2aSThomas Huth /* FPA registers (ignored). */ 84*fcf5ef2aSThomas Huth if (gdb_has_xml) { 85*fcf5ef2aSThomas Huth return 0; 86*fcf5ef2aSThomas Huth } 87*fcf5ef2aSThomas Huth return 12; 88*fcf5ef2aSThomas Huth } 89*fcf5ef2aSThomas Huth switch (n) { 90*fcf5ef2aSThomas Huth case 24: 91*fcf5ef2aSThomas Huth /* FPA status register (ignored). */ 92*fcf5ef2aSThomas Huth if (gdb_has_xml) { 93*fcf5ef2aSThomas Huth return 0; 94*fcf5ef2aSThomas Huth } 95*fcf5ef2aSThomas Huth return 4; 96*fcf5ef2aSThomas Huth case 25: 97*fcf5ef2aSThomas Huth /* CPSR */ 98*fcf5ef2aSThomas Huth cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub); 99*fcf5ef2aSThomas Huth return 4; 100*fcf5ef2aSThomas Huth } 101*fcf5ef2aSThomas Huth /* Unknown register. */ 102*fcf5ef2aSThomas Huth return 0; 103*fcf5ef2aSThomas Huth } 104