xref: /qemu/target/avr/gdbstub.c (revision f81198cefad223afc8e1ae60e9830b60e5f2d6ff)
1  /*
2   * QEMU AVR gdbstub
3   *
4   * Copyright (c) 2016-2020 Michael Rolnik
5   *
6   * This library is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU Lesser General Public
8   * License as published by the Free Software Foundation; either
9   * version 2.1 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, see
18   * <http://www.gnu.org/licenses/lgpl-2.1.html>
19   */
20  
21  #include "qemu/osdep.h"
22  #include "gdbstub/helpers.h"
23  #include "cpu.h"
24  
25  int avr_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
26  {
27      CPUAVRState *env = cpu_env(cs);
28  
29      /*  R */
30      if (n < 32) {
31          return gdb_get_reg8(mem_buf, env->r[n]);
32      }
33  
34      /*  SREG */
35      if (n == 32) {
36          uint8_t sreg = cpu_get_sreg(env);
37  
38          return gdb_get_reg8(mem_buf, sreg);
39      }
40  
41      /*  SP */
42      if (n == 33) {
43          return gdb_get_reg16(mem_buf, env->sp & 0x0000ffff);
44      }
45  
46      /*  PC */
47      if (n == 34) {
48          return gdb_get_reg32(mem_buf, env->pc_w * 2);
49      }
50  
51      return 0;
52  }
53  
54  int avr_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
55  {
56      CPUAVRState *env = cpu_env(cs);
57  
58      /*  R */
59      if (n < 32) {
60          env->r[n] = *mem_buf;
61          return 1;
62      }
63  
64      /*  SREG */
65      if (n == 32) {
66          cpu_set_sreg(env, *mem_buf);
67          return 1;
68      }
69  
70      /*  SP */
71      if (n == 33) {
72          env->sp = lduw_p(mem_buf);
73          return 2;
74      }
75  
76      /*  PC */
77      if (n == 34) {
78          env->pc_w = ldl_p(mem_buf) / 2;
79          return 4;
80      }
81  
82      return 0;
83  }
84  
85  vaddr avr_cpu_gdb_adjust_breakpoint(CPUState *cpu, vaddr addr)
86  {
87      /*
88       * This is due to some strange GDB behavior
89       * Let's assume main has address 0x100:
90       * b main   - sets breakpoint at address 0x00000100 (code)
91       * b *0x100 - sets breakpoint at address 0x00800100 (data)
92       *
93       * Force all breakpoints into code space.
94       */
95      return addr % OFFSET_DATA;
96  }
97