1 /* 2 * QEMU AVR gdbstub 3 * 4 * Copyright (c) 2016-2020 Michael Rolnik 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 18 * <http://www.gnu.org/licenses/lgpl-2.1.html> 19 */ 20 21 #include "qemu/osdep.h" 22 #include "gdbstub/helpers.h" 23 24 int avr_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 25 { 26 AVRCPU *cpu = AVR_CPU(cs); 27 CPUAVRState *env = &cpu->env; 28 29 /* R */ 30 if (n < 32) { 31 return gdb_get_reg8(mem_buf, env->r[n]); 32 } 33 34 /* SREG */ 35 if (n == 32) { 36 uint8_t sreg = cpu_get_sreg(env); 37 38 return gdb_get_reg8(mem_buf, sreg); 39 } 40 41 /* SP */ 42 if (n == 33) { 43 return gdb_get_reg16(mem_buf, env->sp & 0x0000ffff); 44 } 45 46 /* PC */ 47 if (n == 34) { 48 return gdb_get_reg32(mem_buf, env->pc_w * 2); 49 } 50 51 return 0; 52 } 53 54 int avr_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 55 { 56 AVRCPU *cpu = AVR_CPU(cs); 57 CPUAVRState *env = &cpu->env; 58 59 /* R */ 60 if (n < 32) { 61 env->r[n] = *mem_buf; 62 return 1; 63 } 64 65 /* SREG */ 66 if (n == 32) { 67 cpu_set_sreg(env, *mem_buf); 68 return 1; 69 } 70 71 /* SP */ 72 if (n == 33) { 73 env->sp = lduw_p(mem_buf); 74 return 2; 75 } 76 77 /* PC */ 78 if (n == 34) { 79 env->pc_w = ldl_p(mem_buf) / 2; 80 return 4; 81 } 82 83 return 0; 84 } 85 86 vaddr avr_cpu_gdb_adjust_breakpoint(CPUState *cpu, vaddr addr) 87 { 88 /* 89 * This is due to some strange GDB behavior 90 * Let's assume main has address 0x100: 91 * b main - sets breakpoint at address 0x00000100 (code) 92 * b *0x100 - sets breakpoint at address 0x00800100 (data) 93 * 94 * Force all breakpoints into code space. 95 */ 96 return addr % OFFSET_DATA; 97 } 98