xref: /openbmc/qemu/target/avr/gdbstub.c (revision 2db5b94d)
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