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" 23*0654c794SPhilippe Mathieu-Daudé #include "cpu.h" 2412b35405SMichael Rolnik 2512b35405SMichael Rolnik int avr_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 2612b35405SMichael Rolnik { 272db5b94dSPhilippe Mathieu-Daudé CPUAVRState *env = cpu_env(cs); 2812b35405SMichael Rolnik 2912b35405SMichael Rolnik /* R */ 3012b35405SMichael Rolnik if (n < 32) { 3112b35405SMichael Rolnik return gdb_get_reg8(mem_buf, env->r[n]); 3212b35405SMichael Rolnik } 3312b35405SMichael Rolnik 3412b35405SMichael Rolnik /* SREG */ 3512b35405SMichael Rolnik if (n == 32) { 3612b35405SMichael Rolnik uint8_t sreg = cpu_get_sreg(env); 3712b35405SMichael Rolnik 3812b35405SMichael Rolnik return gdb_get_reg8(mem_buf, sreg); 3912b35405SMichael Rolnik } 4012b35405SMichael Rolnik 4112b35405SMichael Rolnik /* SP */ 4212b35405SMichael Rolnik if (n == 33) { 4312b35405SMichael Rolnik return gdb_get_reg16(mem_buf, env->sp & 0x0000ffff); 4412b35405SMichael Rolnik } 4512b35405SMichael Rolnik 4612b35405SMichael Rolnik /* PC */ 4712b35405SMichael Rolnik if (n == 34) { 4812b35405SMichael Rolnik return gdb_get_reg32(mem_buf, env->pc_w * 2); 4912b35405SMichael Rolnik } 5012b35405SMichael Rolnik 5112b35405SMichael Rolnik return 0; 5212b35405SMichael Rolnik } 5312b35405SMichael Rolnik 5412b35405SMichael Rolnik int avr_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 5512b35405SMichael Rolnik { 562db5b94dSPhilippe Mathieu-Daudé CPUAVRState *env = cpu_env(cs); 5712b35405SMichael Rolnik 5812b35405SMichael Rolnik /* R */ 5912b35405SMichael Rolnik if (n < 32) { 6012b35405SMichael Rolnik env->r[n] = *mem_buf; 6112b35405SMichael Rolnik return 1; 6212b35405SMichael Rolnik } 6312b35405SMichael Rolnik 6412b35405SMichael Rolnik /* SREG */ 6512b35405SMichael Rolnik if (n == 32) { 6612b35405SMichael Rolnik cpu_set_sreg(env, *mem_buf); 6712b35405SMichael Rolnik return 1; 6812b35405SMichael Rolnik } 6912b35405SMichael Rolnik 7012b35405SMichael Rolnik /* SP */ 7112b35405SMichael Rolnik if (n == 33) { 7212b35405SMichael Rolnik env->sp = lduw_p(mem_buf); 7312b35405SMichael Rolnik return 2; 7412b35405SMichael Rolnik } 7512b35405SMichael Rolnik 7612b35405SMichael Rolnik /* PC */ 7712b35405SMichael Rolnik if (n == 34) { 7812b35405SMichael Rolnik env->pc_w = ldl_p(mem_buf) / 2; 7912b35405SMichael Rolnik return 4; 8012b35405SMichael Rolnik } 8112b35405SMichael Rolnik 8212b35405SMichael Rolnik return 0; 8312b35405SMichael Rolnik } 84e64cb6c2SRichard Henderson 85e64cb6c2SRichard Henderson vaddr avr_cpu_gdb_adjust_breakpoint(CPUState *cpu, vaddr addr) 86e64cb6c2SRichard Henderson { 87e64cb6c2SRichard Henderson /* 88e64cb6c2SRichard Henderson * This is due to some strange GDB behavior 89e64cb6c2SRichard Henderson * Let's assume main has address 0x100: 90e64cb6c2SRichard Henderson * b main - sets breakpoint at address 0x00000100 (code) 91e64cb6c2SRichard Henderson * b *0x100 - sets breakpoint at address 0x00800100 (data) 92e64cb6c2SRichard Henderson * 93e64cb6c2SRichard Henderson * Force all breakpoints into code space. 94e64cb6c2SRichard Henderson */ 95e64cb6c2SRichard Henderson return addr % OFFSET_DATA; 96e64cb6c2SRichard Henderson } 97