xref: /openbmc/qemu/target/sparc/gdbstub.c (revision ef929281f1ddb1ce74f5fe39377a88e6cc8237aa)
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 "gdbstub/helpers.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      CPUSPARCState *env = cpu_env(cs);
33  
34      if (n < 8) {
35          /* g0..g7 */
36          return gdb_get_rega(mem_buf, env->gregs[n]);
37      }
38      if (n < 32) {
39          /* register window */
40          return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
41      }
42  #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
43      if (n < 64) {
44          /* fprs */
45          if (n & 1) {
46              return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
47          } else {
48              return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
49          }
50      }
51      /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
52      switch (n) {
53      case 64:
54          return gdb_get_rega(mem_buf, env->y);
55      case 65:
56          return gdb_get_rega(mem_buf, cpu_get_psr(env));
57      case 66:
58          return gdb_get_rega(mem_buf, env->wim);
59      case 67:
60          return gdb_get_rega(mem_buf, env->tbr);
61      case 68:
62          return gdb_get_rega(mem_buf, env->pc);
63      case 69:
64          return gdb_get_rega(mem_buf, env->npc);
65      case 70:
66          return gdb_get_rega(mem_buf, cpu_get_fsr(env));
67      case 71:
68          return gdb_get_rega(mem_buf, 0); /* csr */
69      default:
70          return gdb_get_rega(mem_buf, 0);
71      }
72  #else
73      if (n < 64) {
74          /* f0-f31 */
75          if (n & 1) {
76              return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
77          } else {
78              return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
79          }
80      }
81      if (n < 80) {
82          /* f32-f62 (double width, even numbers only) */
83          return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
84      }
85      switch (n) {
86      case 80:
87          return gdb_get_regl(mem_buf, env->pc);
88      case 81:
89          return gdb_get_regl(mem_buf, env->npc);
90      case 82:
91          return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
92                                       ((env->asi & 0xff) << 24) |
93                                       ((env->pstate & 0xfff) << 8) |
94                                       cpu_get_cwp64(env));
95      case 83:
96          return gdb_get_regl(mem_buf, cpu_get_fsr(env));
97      case 84:
98          return gdb_get_regl(mem_buf, env->fprs);
99      case 85:
100          return gdb_get_regl(mem_buf, env->y);
101      }
102  #endif
103      return 0;
104  }
105  
106  int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
107  {
108      SPARCCPU *cpu = SPARC_CPU(cs);
109      CPUSPARCState *env = &cpu->env;
110  #if defined(TARGET_ABI32)
111      abi_ulong tmp;
112  
113      tmp = ldl_p(mem_buf);
114  #else
115      target_ulong tmp;
116  
117      tmp = ldtul_p(mem_buf);
118  #endif
119  
120      if (n < 8) {
121          /* g0..g7 */
122          env->gregs[n] = tmp;
123      } else if (n < 32) {
124          /* register window */
125          env->regwptr[n - 8] = tmp;
126      }
127  #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
128      else if (n < 64) {
129          /* fprs */
130          /* f0-f31 */
131          if (n & 1) {
132              env->fpr[(n - 32) / 2].l.lower = tmp;
133          } else {
134              env->fpr[(n - 32) / 2].l.upper = tmp;
135          }
136      } else {
137          /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
138          switch (n) {
139          case 64:
140              env->y = tmp;
141              break;
142          case 65:
143              cpu_put_psr(env, tmp);
144              break;
145          case 66:
146              env->wim = tmp;
147              break;
148          case 67:
149              env->tbr = tmp;
150              break;
151          case 68:
152              env->pc = tmp;
153              break;
154          case 69:
155              env->npc = tmp;
156              break;
157          case 70:
158              cpu_put_fsr(env, tmp);
159              break;
160          default:
161              return 0;
162          }
163      }
164      return 4;
165  #else
166      else if (n < 64) {
167          /* f0-f31 */
168          tmp = ldl_p(mem_buf);
169          if (n & 1) {
170              env->fpr[(n - 32) / 2].l.lower = tmp;
171          } else {
172              env->fpr[(n - 32) / 2].l.upper = tmp;
173          }
174          return 4;
175      } else if (n < 80) {
176          /* f32-f62 (double width, even numbers only) */
177          env->fpr[(n - 32) / 2].ll = tmp;
178      } else {
179          switch (n) {
180          case 80:
181              env->pc = tmp;
182              break;
183          case 81:
184              env->npc = tmp;
185              break;
186          case 82:
187              cpu_put_ccr(env, tmp >> 32);
188              env->asi = (tmp >> 24) & 0xff;
189              env->pstate = (tmp >> 8) & 0xfff;
190              cpu_put_cwp64(env, tmp & 0xff);
191              break;
192          case 83:
193              cpu_put_fsr(env, tmp);
194              break;
195          case 84:
196              env->fprs = tmp;
197              break;
198          case 85:
199              env->y = tmp;
200              break;
201          default:
202              return 0;
203          }
204      }
205      return 8;
206  #endif
207  }
208