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" 22*4ea5fe99SAlex 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 { 2612b35405SMichael Rolnik AVRCPU *cpu = AVR_CPU(cs); 2712b35405SMichael Rolnik CPUAVRState *env = &cpu->env; 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 { 5612b35405SMichael Rolnik AVRCPU *cpu = AVR_CPU(cs); 5712b35405SMichael Rolnik CPUAVRState *env = &cpu->env; 5812b35405SMichael Rolnik 5912b35405SMichael Rolnik /* R */ 6012b35405SMichael Rolnik if (n < 32) { 6112b35405SMichael Rolnik env->r[n] = *mem_buf; 6212b35405SMichael Rolnik return 1; 6312b35405SMichael Rolnik } 6412b35405SMichael Rolnik 6512b35405SMichael Rolnik /* SREG */ 6612b35405SMichael Rolnik if (n == 32) { 6712b35405SMichael Rolnik cpu_set_sreg(env, *mem_buf); 6812b35405SMichael Rolnik return 1; 6912b35405SMichael Rolnik } 7012b35405SMichael Rolnik 7112b35405SMichael Rolnik /* SP */ 7212b35405SMichael Rolnik if (n == 33) { 7312b35405SMichael Rolnik env->sp = lduw_p(mem_buf); 7412b35405SMichael Rolnik return 2; 7512b35405SMichael Rolnik } 7612b35405SMichael Rolnik 7712b35405SMichael Rolnik /* PC */ 7812b35405SMichael Rolnik if (n == 34) { 7912b35405SMichael Rolnik env->pc_w = ldl_p(mem_buf) / 2; 8012b35405SMichael Rolnik return 4; 8112b35405SMichael Rolnik } 8212b35405SMichael Rolnik 8312b35405SMichael Rolnik return 0; 8412b35405SMichael Rolnik } 85e64cb6c2SRichard Henderson 86e64cb6c2SRichard Henderson vaddr avr_cpu_gdb_adjust_breakpoint(CPUState *cpu, vaddr addr) 87e64cb6c2SRichard Henderson { 88e64cb6c2SRichard Henderson /* 89e64cb6c2SRichard Henderson * This is due to some strange GDB behavior 90e64cb6c2SRichard Henderson * Let's assume main has address 0x100: 91e64cb6c2SRichard Henderson * b main - sets breakpoint at address 0x00000100 (code) 92e64cb6c2SRichard Henderson * b *0x100 - sets breakpoint at address 0x00800100 (data) 93e64cb6c2SRichard Henderson * 94e64cb6c2SRichard Henderson * Force all breakpoints into code space. 95e64cb6c2SRichard Henderson */ 96e64cb6c2SRichard Henderson return addr % OFFSET_DATA; 97e64cb6c2SRichard Henderson } 98