xref: /openbmc/qemu/target/avr/gdbstub.c (revision 0654c794)
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 
avr_cpu_gdb_read_register(CPUState * cs,GByteArray * mem_buf,int n)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 
avr_cpu_gdb_write_register(CPUState * cs,uint8_t * mem_buf,int n)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 
avr_cpu_gdb_adjust_breakpoint(CPUState * cpu,vaddr addr)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