112b35405SMichael Rolnik /* 212b35405SMichael Rolnik * QEMU AVR gdbstub 312b35405SMichael Rolnik * 412b35405SMichael Rolnik * Copyright (c) 2016-2020 Michael Rolnik 512b35405SMichael Rolnik * 612b35405SMichael Rolnik * This library is free software; you can redistribute it and/or 712b35405SMichael Rolnik * modify it under the terms of the GNU Lesser General Public 812b35405SMichael Rolnik * License as published by the Free Software Foundation; either 912b35405SMichael Rolnik * version 2.1 of the License, or (at your option) any later version. 1012b35405SMichael Rolnik * 1112b35405SMichael Rolnik * This library is distributed in the hope that it will be useful, 1212b35405SMichael Rolnik * but WITHOUT ANY WARRANTY; without even the implied warranty of 1312b35405SMichael Rolnik * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1412b35405SMichael Rolnik * Lesser General Public License for more details. 1512b35405SMichael Rolnik * 1612b35405SMichael Rolnik * You should have received a copy of the GNU Lesser General Public 1712b35405SMichael Rolnik * License along with this library; if not, see 1812b35405SMichael Rolnik * <http://www.gnu.org/licenses/lgpl-2.1.html> 1912b35405SMichael Rolnik */ 2012b35405SMichael Rolnik 2112b35405SMichael Rolnik #include "qemu/osdep.h" 224ea5fe99SAlex Bennée #include "gdbstub/helpers.h" 2312b35405SMichael Rolnik 2412b35405SMichael Rolnik int avr_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 2512b35405SMichael Rolnik { 26*2db5b94dSPhilippe Mathieu-Daudé CPUAVRState *env = cpu_env(cs); 2712b35405SMichael Rolnik 2812b35405SMichael Rolnik /* R */ 2912b35405SMichael Rolnik if (n < 32) { 3012b35405SMichael Rolnik return gdb_get_reg8(mem_buf, env->r[n]); 3112b35405SMichael Rolnik } 3212b35405SMichael Rolnik 3312b35405SMichael Rolnik /* SREG */ 3412b35405SMichael Rolnik if (n == 32) { 3512b35405SMichael Rolnik uint8_t sreg = cpu_get_sreg(env); 3612b35405SMichael Rolnik 3712b35405SMichael Rolnik return gdb_get_reg8(mem_buf, sreg); 3812b35405SMichael Rolnik } 3912b35405SMichael Rolnik 4012b35405SMichael Rolnik /* SP */ 4112b35405SMichael Rolnik if (n == 33) { 4212b35405SMichael Rolnik return gdb_get_reg16(mem_buf, env->sp & 0x0000ffff); 4312b35405SMichael Rolnik } 4412b35405SMichael Rolnik 4512b35405SMichael Rolnik /* PC */ 4612b35405SMichael Rolnik if (n == 34) { 4712b35405SMichael Rolnik return gdb_get_reg32(mem_buf, env->pc_w * 2); 4812b35405SMichael Rolnik } 4912b35405SMichael Rolnik 5012b35405SMichael Rolnik return 0; 5112b35405SMichael Rolnik } 5212b35405SMichael Rolnik 5312b35405SMichael Rolnik int avr_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 5412b35405SMichael Rolnik { 55*2db5b94dSPhilippe Mathieu-Daudé CPUAVRState *env = cpu_env(cs); 5612b35405SMichael Rolnik 5712b35405SMichael Rolnik /* R */ 5812b35405SMichael Rolnik if (n < 32) { 5912b35405SMichael Rolnik env->r[n] = *mem_buf; 6012b35405SMichael Rolnik return 1; 6112b35405SMichael Rolnik } 6212b35405SMichael Rolnik 6312b35405SMichael Rolnik /* SREG */ 6412b35405SMichael Rolnik if (n == 32) { 6512b35405SMichael Rolnik cpu_set_sreg(env, *mem_buf); 6612b35405SMichael Rolnik return 1; 6712b35405SMichael Rolnik } 6812b35405SMichael Rolnik 6912b35405SMichael Rolnik /* SP */ 7012b35405SMichael Rolnik if (n == 33) { 7112b35405SMichael Rolnik env->sp = lduw_p(mem_buf); 7212b35405SMichael Rolnik return 2; 7312b35405SMichael Rolnik } 7412b35405SMichael Rolnik 7512b35405SMichael Rolnik /* PC */ 7612b35405SMichael Rolnik if (n == 34) { 7712b35405SMichael Rolnik env->pc_w = ldl_p(mem_buf) / 2; 7812b35405SMichael Rolnik return 4; 7912b35405SMichael Rolnik } 8012b35405SMichael Rolnik 8112b35405SMichael Rolnik return 0; 8212b35405SMichael Rolnik } 83e64cb6c2SRichard Henderson 84e64cb6c2SRichard Henderson vaddr avr_cpu_gdb_adjust_breakpoint(CPUState *cpu, vaddr addr) 85e64cb6c2SRichard Henderson { 86e64cb6c2SRichard Henderson /* 87e64cb6c2SRichard Henderson * This is due to some strange GDB behavior 88e64cb6c2SRichard Henderson * Let's assume main has address 0x100: 89e64cb6c2SRichard Henderson * b main - sets breakpoint at address 0x00000100 (code) 90e64cb6c2SRichard Henderson * b *0x100 - sets breakpoint at address 0x00800100 (data) 91e64cb6c2SRichard Henderson * 92e64cb6c2SRichard Henderson * Force all breakpoints into code space. 93e64cb6c2SRichard Henderson */ 94e64cb6c2SRichard Henderson return addr % OFFSET_DATA; 95e64cb6c2SRichard Henderson } 96