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 #include "cpu.h" 24 25 int avr_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 26 { 27 CPUAVRState *env = cpu_env(cs); 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 CPUAVRState *env = cpu_env(cs); 57 58 /* R */ 59 if (n < 32) { 60 env->r[n] = *mem_buf; 61 return 1; 62 } 63 64 /* SREG */ 65 if (n == 32) { 66 cpu_set_sreg(env, *mem_buf); 67 return 1; 68 } 69 70 /* SP */ 71 if (n == 33) { 72 env->sp = lduw_le_p(mem_buf); 73 return 2; 74 } 75 76 /* PC */ 77 if (n == 34) { 78 env->pc_w = ldl_le_p(mem_buf) / 2; 79 return 4; 80 } 81 82 return 0; 83 } 84 85 vaddr avr_cpu_gdb_adjust_breakpoint(CPUState *cpu, vaddr addr) 86 { 87 /* 88 * This is due to some strange GDB behavior 89 * Let's assume main has address 0x100: 90 * b main - sets breakpoint at address 0x00000100 (code) 91 * b *0x100 - sets breakpoint at address 0x00800100 (data) 92 * 93 * Force all breakpoints into code space. 94 */ 95 return addr % OFFSET_DATA; 96 } 97