xref: /openbmc/qemu/target/avr/gdbstub.c (revision e64cb6c2)
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"
2212b35405SMichael Rolnik #include "exec/gdbstub.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 }
85*e64cb6c2SRichard Henderson 
86*e64cb6c2SRichard Henderson vaddr avr_cpu_gdb_adjust_breakpoint(CPUState *cpu, vaddr addr)
87*e64cb6c2SRichard Henderson {
88*e64cb6c2SRichard Henderson     /*
89*e64cb6c2SRichard Henderson      * This is due to some strange GDB behavior
90*e64cb6c2SRichard Henderson      * Let's assume main has address 0x100:
91*e64cb6c2SRichard Henderson      * b main   - sets breakpoint at address 0x00000100 (code)
92*e64cb6c2SRichard Henderson      * b *0x100 - sets breakpoint at address 0x00800100 (data)
93*e64cb6c2SRichard Henderson      *
94*e64cb6c2SRichard Henderson      * Force all breakpoints into code space.
95*e64cb6c2SRichard Henderson      */
96*e64cb6c2SRichard Henderson     return addr % OFFSET_DATA;
97*e64cb6c2SRichard Henderson }
98