xref: /qemu/target/sparc/gdbstub.c (revision 46627f41b6b781885c64a2b12814060a7ca8da36)
1  /*
2   * SPARC gdb server stub
3   *
4   * Copyright (c) 2003-2005 Fabrice Bellard
5   * Copyright (c) 2013 SUSE LINUX Products GmbH
6   *
7   * This library is free software; you can redistribute it and/or
8   * modify it under the terms of the GNU Lesser General Public
9   * License as published by the Free Software Foundation; either
10   * version 2.1 of the License, or (at your option) any later version.
11   *
12   * This library is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19   */
20  #include "qemu/osdep.h"
21  #include "cpu.h"
22  #include "exec/gdbstub.h"
23  
24  #ifdef TARGET_ABI32
25  #define gdb_get_rega(buf, val) gdb_get_reg32(buf, val)
26  #else
27  #define gdb_get_rega(buf, val) gdb_get_regl(buf, val)
28  #endif
29  
30  int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
31  {
32      SPARCCPU *cpu = SPARC_CPU(cs);
33      CPUSPARCState *env = &cpu->env;
34  
35      if (n < 8) {
36          /* g0..g7 */
37          return gdb_get_rega(mem_buf, env->gregs[n]);
38      }
39      if (n < 32) {
40          /* register window */
41          return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
42      }
43  #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
44      if (n < 64) {
45          /* fprs */
46          if (n & 1) {
47              return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
48          } else {
49              return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
50          }
51      }
52      /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
53      switch (n) {
54      case 64:
55          return gdb_get_rega(mem_buf, env->y);
56      case 65:
57          return gdb_get_rega(mem_buf, cpu_get_psr(env));
58      case 66:
59          return gdb_get_rega(mem_buf, env->wim);
60      case 67:
61          return gdb_get_rega(mem_buf, env->tbr);
62      case 68:
63          return gdb_get_rega(mem_buf, env->pc);
64      case 69:
65          return gdb_get_rega(mem_buf, env->npc);
66      case 70:
67          return gdb_get_rega(mem_buf, env->fsr);
68      case 71:
69          return gdb_get_rega(mem_buf, 0); /* csr */
70      default:
71          return gdb_get_rega(mem_buf, 0);
72      }
73  #else
74      if (n < 64) {
75          /* f0-f31 */
76          if (n & 1) {
77              return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
78          } else {
79              return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
80          }
81      }
82      if (n < 80) {
83          /* f32-f62 (double width, even numbers only) */
84          return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
85      }
86      switch (n) {
87      case 80:
88          return gdb_get_regl(mem_buf, env->pc);
89      case 81:
90          return gdb_get_regl(mem_buf, env->npc);
91      case 82:
92          return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
93                                       ((env->asi & 0xff) << 24) |
94                                       ((env->pstate & 0xfff) << 8) |
95                                       cpu_get_cwp64(env));
96      case 83:
97          return gdb_get_regl(mem_buf, env->fsr);
98      case 84:
99          return gdb_get_regl(mem_buf, env->fprs);
100      case 85:
101          return gdb_get_regl(mem_buf, env->y);
102      }
103  #endif
104      return 0;
105  }
106  
107  int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
108  {
109      SPARCCPU *cpu = SPARC_CPU(cs);
110      CPUSPARCState *env = &cpu->env;
111  #if defined(TARGET_ABI32)
112      abi_ulong tmp;
113  
114      tmp = ldl_p(mem_buf);
115  #else
116      target_ulong tmp;
117  
118      tmp = ldtul_p(mem_buf);
119  #endif
120  
121      if (n < 8) {
122          /* g0..g7 */
123          env->gregs[n] = tmp;
124      } else if (n < 32) {
125          /* register window */
126          env->regwptr[n - 8] = tmp;
127      }
128  #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
129      else if (n < 64) {
130          /* fprs */
131          /* f0-f31 */
132          if (n & 1) {
133              env->fpr[(n - 32) / 2].l.lower = tmp;
134          } else {
135              env->fpr[(n - 32) / 2].l.upper = tmp;
136          }
137      } else {
138          /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
139          switch (n) {
140          case 64:
141              env->y = tmp;
142              break;
143          case 65:
144              cpu_put_psr(env, tmp);
145              break;
146          case 66:
147              env->wim = tmp;
148              break;
149          case 67:
150              env->tbr = tmp;
151              break;
152          case 68:
153              env->pc = tmp;
154              break;
155          case 69:
156              env->npc = tmp;
157              break;
158          case 70:
159              env->fsr = tmp;
160              break;
161          default:
162              return 0;
163          }
164      }
165      return 4;
166  #else
167      else if (n < 64) {
168          /* f0-f31 */
169          tmp = ldl_p(mem_buf);
170          if (n & 1) {
171              env->fpr[(n - 32) / 2].l.lower = tmp;
172          } else {
173              env->fpr[(n - 32) / 2].l.upper = tmp;
174          }
175          return 4;
176      } else if (n < 80) {
177          /* f32-f62 (double width, even numbers only) */
178          env->fpr[(n - 32) / 2].ll = tmp;
179      } else {
180          switch (n) {
181          case 80:
182              env->pc = tmp;
183              break;
184          case 81:
185              env->npc = tmp;
186              break;
187          case 82:
188              cpu_put_ccr(env, tmp >> 32);
189              env->asi = (tmp >> 24) & 0xff;
190              env->pstate = (tmp >> 8) & 0xfff;
191              cpu_put_cwp64(env, tmp & 0xff);
192              break;
193          case 83:
194              env->fsr = tmp;
195              break;
196          case 84:
197              env->fprs = tmp;
198              break;
199          case 85:
200              env->y = tmp;
201              break;
202          default:
203              return 0;
204          }
205      }
206      return 8;
207  #endif
208  }
209