xref: /openbmc/qemu/target/riscv/gdbstub.c (revision f0dbe427ec7c0dd81fc95c1d0d7174b79b6e6587)
1  /*
2   * RISC-V GDB Server Stub
3   *
4   * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5   *
6   * This program is free software; you can redistribute it and/or modify it
7   * under the terms and conditions of the GNU General Public License,
8   * version 2 or later, as published by the Free Software Foundation.
9   *
10   * This program is distributed in the hope it will be useful, but WITHOUT
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13   * more details.
14   *
15   * You should have received a copy of the GNU General Public License along with
16   * this program.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  #include "qemu/osdep.h"
20  #include "exec/gdbstub.h"
21  #include "gdbstub/helpers.h"
22  #include "cpu.h"
23  
24  struct TypeSize {
25      const char *gdb_type;
26      const char *id;
27      int size;
28      const char suffix;
29  };
30  
31  static const struct TypeSize vec_lanes[] = {
32      /* quads */
33      { "uint128", "quads", 128, 'q' },
34      /* 64 bit */
35      { "uint64", "longs", 64, 'l' },
36      /* 32 bit */
37      { "uint32", "words", 32, 'w' },
38      /* 16 bit */
39      { "uint16", "shorts", 16, 's' },
40      /*
41       * TODO: currently there is no reliable way of telling
42       * if the remote gdb actually understands ieee_half so
43       * we don't expose it in the target description for now.
44       * { "ieee_half", 16, 'h', 'f' },
45       */
46      /* bytes */
47      { "uint8", "bytes", 8, 'b' },
48  };
49  
50  int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
51  {
52      RISCVCPU *cpu = RISCV_CPU(cs);
53      CPURISCVState *env = &cpu->env;
54      target_ulong tmp;
55  
56      if (n < 32) {
57          tmp = env->gpr[n];
58      } else if (n == 32) {
59          tmp = env->pc;
60      } else {
61          return 0;
62      }
63  
64      switch (env->misa_mxl_max) {
65      case MXL_RV32:
66          return gdb_get_reg32(mem_buf, tmp);
67      case MXL_RV64:
68      case MXL_RV128:
69          return gdb_get_reg64(mem_buf, tmp);
70      default:
71          g_assert_not_reached();
72      }
73      return 0;
74  }
75  
76  int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
77  {
78      RISCVCPU *cpu = RISCV_CPU(cs);
79      CPURISCVState *env = &cpu->env;
80      int length = 0;
81      target_ulong tmp;
82  
83      switch (env->misa_mxl_max) {
84      case MXL_RV32:
85          tmp = (int32_t)ldl_p(mem_buf);
86          length = 4;
87          break;
88      case MXL_RV64:
89      case MXL_RV128:
90          if (env->xl < MXL_RV64) {
91              tmp = (int32_t)ldq_p(mem_buf);
92          } else {
93              tmp = ldq_p(mem_buf);
94          }
95          length = 8;
96          break;
97      default:
98          g_assert_not_reached();
99      }
100      if (n > 0 && n < 32) {
101          env->gpr[n] = tmp;
102      } else if (n == 32) {
103          env->pc = tmp;
104      }
105  
106      return length;
107  }
108  
109  static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
110  {
111      if (n < 32) {
112          if (env->misa_ext & RVD) {
113              return gdb_get_reg64(buf, env->fpr[n]);
114          }
115          if (env->misa_ext & RVF) {
116              return gdb_get_reg32(buf, env->fpr[n]);
117          }
118      }
119      return 0;
120  }
121  
122  static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
123  {
124      if (n < 32) {
125          env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
126          return sizeof(uint64_t);
127      }
128      return 0;
129  }
130  
131  static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
132  {
133      uint16_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
134      if (n < 32) {
135          int i;
136          int cnt = 0;
137          for (i = 0; i < vlenb; i += 8) {
138              cnt += gdb_get_reg64(buf,
139                                   env->vreg[(n * vlenb + i) / 8]);
140          }
141          return cnt;
142      }
143  
144      return 0;
145  }
146  
147  static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
148  {
149      uint16_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
150      if (n < 32) {
151          int i;
152          for (i = 0; i < vlenb; i += 8) {
153              env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
154          }
155          return vlenb;
156      }
157  
158      return 0;
159  }
160  
161  static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
162  {
163      if (n < CSR_TABLE_SIZE) {
164          target_ulong val = 0;
165          int result;
166  
167          result = riscv_csrrw_debug(env, n, &val, 0, 0);
168          if (result == RISCV_EXCP_NONE) {
169              return gdb_get_regl(buf, val);
170          }
171      }
172      return 0;
173  }
174  
175  static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
176  {
177      if (n < CSR_TABLE_SIZE) {
178          target_ulong val = ldtul_p(mem_buf);
179          int result;
180  
181          result = riscv_csrrw_debug(env, n, NULL, val, -1);
182          if (result == RISCV_EXCP_NONE) {
183              return sizeof(target_ulong);
184          }
185      }
186      return 0;
187  }
188  
189  static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n)
190  {
191      if (n == 0) {
192  #ifdef CONFIG_USER_ONLY
193          return gdb_get_regl(buf, 0);
194  #else
195          return gdb_get_regl(buf, cs->priv);
196  #endif
197      }
198      return 0;
199  }
200  
201  static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
202  {
203      if (n == 0) {
204  #ifndef CONFIG_USER_ONLY
205          cs->priv = ldtul_p(mem_buf) & 0x3;
206          if (cs->priv == PRV_RESERVED) {
207              cs->priv = PRV_S;
208          }
209  #endif
210          return sizeof(target_ulong);
211      }
212      return 0;
213  }
214  
215  static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
216  {
217      RISCVCPU *cpu = RISCV_CPU(cs);
218      CPURISCVState *env = &cpu->env;
219      GString *s = g_string_new(NULL);
220      riscv_csr_predicate_fn predicate;
221      int bitsize = 16 << env->misa_mxl_max;
222      int i;
223  
224  #if !defined(CONFIG_USER_ONLY)
225      env->debugger = true;
226  #endif
227  
228      /* Until gdb knows about 128-bit registers */
229      if (bitsize > 64) {
230          bitsize = 64;
231      }
232  
233      g_string_printf(s, "<?xml version=\"1.0\"?>");
234      g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
235      g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
236  
237      for (i = 0; i < CSR_TABLE_SIZE; i++) {
238          if (env->priv_ver < csr_ops[i].min_priv_ver) {
239              continue;
240          }
241          predicate = csr_ops[i].predicate;
242          if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
243              if (csr_ops[i].name) {
244                  g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
245              } else {
246                  g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
247              }
248              g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
249              g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
250          }
251      }
252  
253      g_string_append_printf(s, "</feature>");
254  
255      cpu->dyn_csr_xml = g_string_free(s, false);
256  
257  #if !defined(CONFIG_USER_ONLY)
258      env->debugger = false;
259  #endif
260  
261      return CSR_TABLE_SIZE;
262  }
263  
264  static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
265  {
266      RISCVCPU *cpu = RISCV_CPU(cs);
267      GString *s = g_string_new(NULL);
268      g_autoptr(GString) ts = g_string_new("");
269      int reg_width = cpu->cfg.vlen;
270      int num_regs = 0;
271      int i;
272  
273      g_string_printf(s, "<?xml version=\"1.0\"?>");
274      g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
275      g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.vector\">");
276  
277      /* First define types and totals in a whole VL */
278      for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
279          int count = reg_width / vec_lanes[i].size;
280          g_string_printf(ts, "%s", vec_lanes[i].id);
281          g_string_append_printf(s,
282                                 "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
283                                 ts->str, vec_lanes[i].gdb_type, count);
284      }
285  
286      /* Define unions */
287      g_string_append_printf(s, "<union id=\"riscv_vector\">");
288      for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
289          g_string_append_printf(s, "<field name=\"%c\" type=\"%s\"/>",
290                                 vec_lanes[i].suffix,
291                                 vec_lanes[i].id);
292      }
293      g_string_append(s, "</union>");
294  
295      /* Define vector registers */
296      for (i = 0; i < 32; i++) {
297          g_string_append_printf(s,
298                                 "<reg name=\"v%d\" bitsize=\"%d\""
299                                 " regnum=\"%d\" group=\"vector\""
300                                 " type=\"riscv_vector\"/>",
301                                 i, reg_width, base_reg++);
302          num_regs++;
303      }
304  
305      g_string_append_printf(s, "</feature>");
306  
307      cpu->dyn_vreg_xml = g_string_free(s, false);
308      return num_regs;
309  }
310  
311  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
312  {
313      RISCVCPU *cpu = RISCV_CPU(cs);
314      CPURISCVState *env = &cpu->env;
315      if (env->misa_ext & RVD) {
316          gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
317                                   32, "riscv-64bit-fpu.xml", 0);
318      } else if (env->misa_ext & RVF) {
319          gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
320                                   32, "riscv-32bit-fpu.xml", 0);
321      }
322      if (env->misa_ext & RVV) {
323          int base_reg = cs->gdb_num_regs;
324          gdb_register_coprocessor(cs, riscv_gdb_get_vector,
325                                   riscv_gdb_set_vector,
326                                   ricsv_gen_dynamic_vector_xml(cs, base_reg),
327                                   "riscv-vector.xml", 0);
328      }
329      switch (env->misa_mxl_max) {
330      case MXL_RV32:
331          gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
332                                   riscv_gdb_set_virtual,
333                                   1, "riscv-32bit-virtual.xml", 0);
334          break;
335      case MXL_RV64:
336      case MXL_RV128:
337          gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
338                                   riscv_gdb_set_virtual,
339                                   1, "riscv-64bit-virtual.xml", 0);
340          break;
341      default:
342          g_assert_not_reached();
343      }
344  
345      if (cpu->cfg.ext_zicsr) {
346          int base_reg = cs->gdb_num_regs;
347          gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
348                                   riscv_gen_dynamic_csr_xml(cs, base_reg),
349                                   "riscv-csr.xml", 0);
350      }
351  }
352