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 CPUAVRState *env = cpu_env(cs); 27 28 /* R */ 29 if (n < 32) { 30 return gdb_get_reg8(mem_buf, env->r[n]); 31 } 32 33 /* SREG */ 34 if (n == 32) { 35 uint8_t sreg = cpu_get_sreg(env); 36 37 return gdb_get_reg8(mem_buf, sreg); 38 } 39 40 /* SP */ 41 if (n == 33) { 42 return gdb_get_reg16(mem_buf, env->sp & 0x0000ffff); 43 } 44 45 /* PC */ 46 if (n == 34) { 47 return gdb_get_reg32(mem_buf, env->pc_w * 2); 48 } 49 50 return 0; 51 } 52 53 int avr_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 54 { 55 CPUAVRState *env = cpu_env(cs); 56 57 /* R */ 58 if (n < 32) { 59 env->r[n] = *mem_buf; 60 return 1; 61 } 62 63 /* SREG */ 64 if (n == 32) { 65 cpu_set_sreg(env, *mem_buf); 66 return 1; 67 } 68 69 /* SP */ 70 if (n == 33) { 71 env->sp = lduw_p(mem_buf); 72 return 2; 73 } 74 75 /* PC */ 76 if (n == 34) { 77 env->pc_w = ldl_p(mem_buf) / 2; 78 return 4; 79 } 80 81 return 0; 82 } 83 84 vaddr avr_cpu_gdb_adjust_breakpoint(CPUState *cpu, vaddr addr) 85 { 86 /* 87 * This is due to some strange GDB behavior 88 * Let's assume main has address 0x100: 89 * b main - sets breakpoint at address 0x00000100 (code) 90 * b *0x100 - sets breakpoint at address 0x00800100 (data) 91 * 92 * Force all breakpoints into code space. 93 */ 94 return addr % OFFSET_DATA; 95 } 96