OpenOCD
riscv-013_reg.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 
7 #include "riscv-013_reg.h"
8 #include "field_helpers.h"
9 
10 #include "riscv_reg.h"
11 #include "riscv_reg_impl.h"
12 #include "riscv-013.h"
13 #include "debug_defines.h"
14 #include <helper/time_support.h>
15 
16 static int riscv013_reg_get(struct reg *reg)
17 {
19 
20  /* TODO: Hack to deal with gdb that thinks these registers still exist. */
23  buf_set_u64(reg->value, 0, reg->size, 0);
24  return ERROR_OK;
25  }
26 
27  if (reg->number >= GDB_REGNO_V0 && reg->number <= GDB_REGNO_V31) {
29  return ERROR_FAIL;
30 
31  reg->valid = riscv_reg_impl_gdb_regno_cacheable(reg->number, /* is write? */ false);
32  } else {
33  uint64_t value;
34  int result = riscv_reg_get(target, &value, reg->number);
35  if (result != ERROR_OK)
36  return result;
37  buf_set_u64(reg->value, 0, reg->size, value);
38  }
39  char *str = buf_to_hex_str(reg->value, reg->size);
40  LOG_TARGET_DEBUG(target, "Read 0x%s from %s (valid=%d).", str, reg->name,
41  reg->valid);
42  free(str);
43  return ERROR_OK;
44 }
45 
46 static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
47 {
49 
50  char *str = buf_to_hex_str(buf, reg->size);
51  LOG_TARGET_DEBUG(target, "Write 0x%s to %s (valid=%d).", str, reg->name,
52  reg->valid);
53  free(str);
54 
55  /* TODO: Hack to deal with gdb that thinks these registers still exist. */
58  buf_get_u64(buf, 0, reg->size) == 0)
59  return ERROR_OK;
60 
61  if (reg->number >= GDB_REGNO_V0 && reg->number <= GDB_REGNO_V31) {
63  return ERROR_FAIL;
64 
65  memcpy(reg->value, buf, DIV_ROUND_UP(reg->size, 8));
66  reg->valid = riscv_reg_impl_gdb_regno_cacheable(reg->number, /* is write? */ true);
67  } else {
68  const riscv_reg_t value = buf_get_u64(buf, 0, reg->size);
69  if (riscv_reg_set(target, reg->number, value) != ERROR_OK)
70  return ERROR_FAIL;
71  }
72 
73  return ERROR_OK;
74 }
75 
76 static const struct reg_arch_type *riscv013_gdb_regno_reg_type(uint32_t regno)
77 {
78  static const struct reg_arch_type riscv013_reg_type = {
80  .set = riscv013_reg_set
81  };
82  return &riscv013_reg_type;
83 }
84 
85 static int init_cache_entry(struct target *target, uint32_t regno)
86 {
87  struct reg * const reg = riscv_reg_impl_cache_entry(target, regno);
89  return ERROR_OK;
93 }
94 
101 static int assume_reg_exist(struct target *target, uint32_t regno)
102 {
104  /* exist */ true, riscv013_gdb_regno_reg_type(regno));
105 }
106 
107 static int examine_xlen(struct target *target)
108 {
109  RISCV_INFO(r);
110  unsigned int cmderr;
111 
113  GDB_REGNO_S0, /* size */ 64, AC_ACCESS_REGISTER_TRANSFER);
114  int res = riscv013_execute_abstract_command(target, command, &cmderr);
115  if (res == ERROR_OK) {
116  r->xlen = 64;
117  return ERROR_OK;
118  }
119  if (res == ERROR_TIMEOUT_REACHED)
120  return ERROR_FAIL;
121  r->xlen = 32;
122 
123  return ERROR_OK;
124 }
125 
126 static int examine_vlenb(struct target *target)
127 {
128  RISCV_INFO(r);
129 
130  /* Reading "vlenb" requires "mstatus.vs" to be set, so "mstatus" should
131  * be accessible.*/
133  if (res != ERROR_OK)
134  return res;
135 
137  if (res != ERROR_OK)
138  return res;
139 
140  riscv_reg_t vlenb_val;
141  if (riscv_reg_get(target, &vlenb_val, GDB_REGNO_VLENB) != ERROR_OK) {
143  LOG_TARGET_WARNING(target, "Couldn't read vlenb; vector register access won't work.");
144  r->vlenb = 0;
146  }
147  /* As defined by RISC-V V extension specification:
148  * https://github.com/riscv/riscv-v-spec/blob/2f68ef7256d6ec53e4d2bd7cb12862f406d64e34/v-spec.adoc?plain=1#L67-L72 */
149  const unsigned int vlen_max = 65536;
150  const unsigned int vlenb_max = vlen_max / 8;
151  if (vlenb_val > vlenb_max) {
152  LOG_TARGET_WARNING(target, "'vlenb == %" PRIu64
153  "' is greater than maximum allowed by specification (%u); vector register access won't work.",
154  vlenb_val, vlenb_max);
155  r->vlenb = 0;
156  return ERROR_OK;
157  }
158  assert(vlenb_max <= UINT_MAX);
159  r->vlenb = (unsigned int)vlenb_val;
160 
161  LOG_TARGET_INFO(target, "Vector support with vlenb=%u", r->vlenb);
162  return ERROR_OK;
163 }
164 
165 enum misa_mxl {
169  MISA_MXL_128 = 3
170 };
171 
172 unsigned int mxl_to_xlen(enum misa_mxl mxl)
173 {
174  switch (mxl) {
175  case MISA_MXL_32:
176  return 32;
177  case MISA_MXL_64:
178  return 64;
179  case MISA_MXL_128:
180  return 128;
181  case MISA_MXL_INVALID:
182  assert(0);
183  }
184  return 0;
185 }
186 
187 static int check_misa_mxl(const struct target *target, riscv_reg_t misa)
188 {
189  if (misa == 0) {
190  LOG_TARGET_WARNING(target, "'misa' register is read as zero."
191  "OpenOCD will not be able to determine some hart's capabilities.");
192  return ERROR_OK;
193  }
194  const unsigned int dxlen = riscv_xlen(target);
195  assert(dxlen <= sizeof(riscv_reg_t) * CHAR_BIT);
196  assert(dxlen >= 2);
197  const riscv_reg_t misa_mxl_mask = (riscv_reg_t)0x3 << (dxlen - 2);
198  const unsigned int mxl = get_field(misa, misa_mxl_mask);
199  if (mxl == MISA_MXL_INVALID) {
200  /* This is not an error!
201  * Imagine the platform that:
202  * - Has no abstract access to CSRs, so that CSRs are read
203  * through Program Buffer via "csrr" instruction.
204  * - Complies to v1.10 of the Priveleged Spec, so that misa.mxl
205  * is WARL and MXLEN may be chainged.
206  * https://github.com/riscv/riscv-isa-manual/commit/9a7dd2fe29011587954560b5dcf1875477b27ad8
207  * - DXLEN == MXLEN on reset == 64.
208  * In a following scenario:
209  * - misa.mxl was written, so that MXLEN is 32.
210  * - Debugger connects to the target.
211  * - Debugger observes DXLEN == 64.
212  * - Debugger reads misa:
213  * - Abstract access fails with "cmderr == not supported".
214  * - Access via Program Buffer involves reading "misa" to an
215  * "xreg" via "csrr", so that the "xreg" is filled with
216  * zero-extended value of "misa" (since "misa" is
217  * MXLEN-wide).
218  * - Debugger derives "misa.mxl" assumig "misa" is DXLEN-bit
219  * wide (64) while MXLEN is 32 and therefore erroneously
220  * assumes "misa.mxl" to be zero (invalid).
221  */
222  LOG_TARGET_WARNING(target, "Detected DXLEN (%u) does not match "
223  "MXLEN: misa.mxl == 0, misa == 0x%" PRIx64 ".",
224  dxlen, misa);
225  return ERROR_OK;
226  }
227  const unsigned int mxlen = mxl_to_xlen(mxl);
228  if (dxlen < mxlen) {
230  "MXLEN (%u) reported in misa.mxl field exceeds "
231  "the detected DXLEN (%u)",
232  mxlen, dxlen);
233  return ERROR_FAIL;
234  }
235  /* NOTE:
236  * The value of "misa.mxl" may stil not coincide with "xlen".
237  * "misa[26:XLEN-3]" bits are marked as WIRI in at least version 1.10
238  * of RISC-V Priveleged Spec. Therefore, if "xlen" is erroneously
239  * assumed to be 32 when it actually is 64, "mxl" will be read from
240  * this WIRI field and may be equal to "MISA_MXL_32" by coincidence.
241  * This is not an issue though from the version 1.11 onward, since
242  * "misa[26:XLEN-3]" became WARL and equal to 0.
243  */
244 
245  /* Display this as early as possible to help people who are using
246  * really slow simulators. */
247  LOG_TARGET_DEBUG(target, " XLEN=%d, misa=0x%" PRIx64, riscv_xlen(target), misa);
248 
249  return ERROR_OK;
250 }
251 
253 {
254  riscv_reg_t misa_extensions_mask = (riscv_reg_t)GENMASK(24, 0);
255  riscv_reg_t misa_enabled = set_field(*misa, misa_extensions_mask, misa_extensions_mask);
256  int retval = riscv_reg_set(target, GDB_REGNO_MISA, misa_enabled);
257  if (retval != ERROR_OK)
258  return retval;
259 
260  retval = riscv_reg_get(target, &misa_enabled, GDB_REGNO_MISA);
261  if (retval != ERROR_OK)
262  return retval;
263 
264  if (*misa != misa_enabled) {
265  LOG_TARGET_DEBUG(target, "Detected misa=0x%" PRIx64 "does not equal to "
266  "origin misa=0x%" PRIx64, misa_enabled, *misa);
267  retval = riscv_reg_set(target, GDB_REGNO_MISA, *misa);
268  if (retval != ERROR_OK)
269  return retval;
270  *misa = misa_enabled;
271  }
272  return ERROR_OK;
273 }
274 
275 static int examine_misa(struct target *target)
276 {
277  RISCV_INFO(r);
278 
280  if (res != ERROR_OK)
281  return res;
282 
283  riscv_reg_t misa;
284  res = riscv_reg_get(target, &misa, GDB_REGNO_MISA);
285  if (res != ERROR_OK)
286  return res;
287 
288  res = check_misa_mxl(target, misa);
289  if (res != ERROR_OK)
290  return res;
291 
293  if (config->detect_misa) {
294  res = misa_detect_extensions(target, &misa);
295  if (res != ERROR_OK)
296  return res;
297  }
298 
299  r->misa = misa;
300 
301  return ERROR_OK;
302 }
303 
304 static int examine_mtopi(struct target *target)
305 {
306  /* Assume the registers exist */
308  if (res != ERROR_OK)
309  return res;
311  if (res != ERROR_OK)
312  return res;
313 
314  riscv_reg_t value;
315  if (riscv_reg_get(target, &value, GDB_REGNO_MTOPI) != ERROR_OK) {
317  if (res != ERROR_OK)
318  return res;
320  }
321  if (riscv_reg_get(target, &value, GDB_REGNO_MTOPEI) != ERROR_OK) {
322  LOG_TARGET_INFO(target, "S?aia detected without IMSIC");
324  }
325  LOG_TARGET_INFO(target, "S?aia detected with IMSIC");
326  return ERROR_OK;
327 }
328 
334 {
336  if (res != ERROR_OK)
337  return res;
338 
340 
341  assert(target->state == TARGET_HALTED);
342 
343  res = examine_xlen(target);
344  if (res != ERROR_OK)
345  return res;
346 
347  /* Reading CSRs may clobber "s0", "s1", so it should be possible to
348  * save them in cache. */
350  if (res != ERROR_OK)
351  return res;
353  if (res != ERROR_OK)
354  return res;
355 
356  res = examine_misa(target);
357  if (res != ERROR_OK)
358  return res;
359 
360  res = examine_vlenb(target);
361  if (res != ERROR_OK)
362  return res;
363 
365 
366  res = examine_mtopi(target);
367  if (res != ERROR_OK)
368  return res;
369 
370  for (uint32_t regno = 0; regno < target->reg_cache->num_regs; ++regno) {
371  res = init_cache_entry(target, regno);
372  if (res != ERROR_OK)
373  return res;
374  }
375 
377  if (res != ERROR_OK)
378  return res;
379 
381 
382  return ERROR_OK;
383 }
384 
389 int riscv013_reg_save(struct target *target, enum gdb_regno regid)
390 {
391  if (target->state != TARGET_HALTED) {
392  LOG_TARGET_ERROR(target, "Can't save register %s on a hart that is not halted.",
394  return ERROR_FAIL;
395  }
396  assert(riscv_reg_impl_gdb_regno_cacheable(regid, /* is write? */ false) &&
397  "Only cacheable registers can be saved.");
398 
399  RISCV_INFO(r);
400  riscv_reg_t value;
401  if (!target->reg_cache) {
402  assert(!target_was_examined(target));
403  /* To create register cache it is needed to examine the target first,
404  * therefore during examine, any changed register needs to be saved
405  * and restored manually.
406  */
407  return ERROR_OK;
408  }
409 
410  struct reg *reg = riscv_reg_impl_cache_entry(target, regid);
411 
412  LOG_TARGET_DEBUG(target, "Saving %s", reg->name);
413  if (riscv_reg_get(target, &value, regid) != ERROR_OK)
414  return ERROR_FAIL;
415 
416  assert(reg->valid &&
417  "The register is cacheable, so the cache entry must be valid now.");
418  /* Mark the register dirty. We assume that this function is called
419  * because the caller is about to mess with the underlying value of the
420  * register. */
421  reg->dirty = true;
422 
423  r->last_activity = timeval_ms();
424 
425  return ERROR_OK;
426 }
char * buf_to_hex_str(const void *_buf, unsigned int buf_len)
Definition: binarybuffer.c:178
static uint64_t buf_get_u64(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 64-bit word.
Definition: binarybuffer.h:134
static void buf_set_u64(uint8_t *_buffer, unsigned int first, unsigned int num, uint64_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:65
#define GENMASK(h, l)
Definition: bits.h:24
#define AC_ACCESS_REGISTER_TRANSFER
static uint64_t set_field(uint64_t reg, uint64_t mask, uint64_t val)
Definition: field_helpers.h:21
static uint64_t get_field(uint64_t reg, uint64_t mask)
Definition: field_helpers.h:9
gdb_regno
Definition: gdb_regs.h:10
@ GDB_REGNO_MTOPI
Definition: gdb_regs.h:111
@ GDB_REGNO_MSTATUS
Definition: gdb_regs.h:103
@ GDB_REGNO_MTOPEI
Definition: gdb_regs.h:112
@ GDB_REGNO_S1
Definition: gdb_regs.h:21
@ GDB_REGNO_XPR15
Definition: gdb_regs.h:28
@ GDB_REGNO_V0
Definition: gdb_regs.h:119
@ GDB_REGNO_XPR31
Definition: gdb_regs.h:45
@ GDB_REGNO_S0
Definition: gdb_regs.h:19
@ GDB_REGNO_VLENB
Definition: gdb_regs.h:90
@ GDB_REGNO_V31
Definition: gdb_regs.h:126
@ GDB_REGNO_MISA
Definition: gdb_regs.h:98
#define LOG_TARGET_INFO(target, fmt_str,...)
Definition: log.h:167
#define LOG_TARGET_WARNING(target, fmt_str,...)
Definition: log.h:173
#define ERROR_FAIL
Definition: log.h:188
#define LOG_TARGET_ERROR(target, fmt_str,...)
Definition: log.h:176
#define LOG_TARGET_DEBUG(target, fmt_str,...)
Definition: log.h:164
#define ERROR_TIMEOUT_REACHED
Definition: log.h:191
#define ERROR_OK
Definition: log.h:182
int riscv013_set_register_buf(struct target *target, enum gdb_regno regno, const uint8_t *value)
Definition: riscv-013.c:2481
uint32_t riscv013_access_register_command(struct target *target, uint32_t number, unsigned int size, uint32_t flags)
Definition: riscv-013.c:905
int riscv013_get_register_buf(struct target *target, uint8_t *value, enum gdb_regno regno)
Definition: riscv-013.c:2426
int riscv013_execute_abstract_command(struct target *target, uint32_t command, uint32_t *cmderr)
Definition: riscv-013.c:766
static int assume_reg_exist(struct target *target, uint32_t regno)
Some registers are optional (e.g.
unsigned int mxl_to_xlen(enum misa_mxl mxl)
int riscv013_reg_examine_all(struct target *target)
This function assumes target's DM to be initialized (target is able to access DMs registers,...
static int examine_xlen(struct target *target)
static int riscv013_reg_get(struct reg *reg)
Definition: riscv-013_reg.c:16
static int check_misa_mxl(const struct target *target, riscv_reg_t misa)
int riscv013_reg_save(struct target *target, enum gdb_regno regid)
This function is used to save the value of a register in cache.
static int examine_vlenb(struct target *target)
static int examine_mtopi(struct target *target)
static int examine_misa(struct target *target)
static int init_cache_entry(struct target *target, uint32_t regno)
Definition: riscv-013_reg.c:85
misa_mxl
@ MISA_MXL_INVALID
@ MISA_MXL_128
@ MISA_MXL_32
@ MISA_MXL_64
static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
Definition: riscv-013_reg.c:46
static const struct reg_arch_type * riscv013_gdb_regno_reg_type(uint32_t regno)
Definition: riscv-013_reg.c:76
static int misa_detect_extensions(struct target *target, riscv_reg_t *misa)
unsigned int riscv_xlen(const struct target *target)
Definition: riscv.c:6378
bool riscv_supports_extension(const struct target *target, char letter)
Definition: riscv.c:6371
#define RISCV_INFO(R)
Definition: riscv.h:442
uint64_t riscv_reg_t
Definition: riscv.h:44
int riscv_reg_impl_set_exist(const struct target *target, uint32_t regno, bool exist)
Mark register as existing or not.
Definition: riscv_reg.c:581
void riscv_reg_impl_hide_csrs(const struct target *target)
Hide additional CSRs, as specified by riscv_info_t::hide_csr list.
Definition: riscv_reg.c:718
bool riscv_reg_impl_gdb_regno_exist(const struct target *target, uint32_t regno)
For most registers, returns whether they exist or not.
Definition: riscv_reg.c:348
struct target * riscv_reg_impl_get_target(const struct reg *reg)
Return the target that owns the cache entry.
Definition: riscv_reg.c:187
int riscv_reg_set(struct target *target, enum gdb_regno regid, riscv_reg_t value)
This function is used to change the value of a register.
Definition: riscv_reg.c:900
const char * riscv_reg_gdb_regno_name(const struct target *target, enum gdb_regno regno)
This file describes the register cache interface available to the RISC-V target.
Definition: riscv_reg.c:145
int riscv_reg_impl_expose_csrs(const struct target *target)
Expose additional CSRs, as specified by riscv_info_t::expose_csr list.
Definition: riscv_reg.c:691
int riscv_reg_impl_init_cache_entry(struct target *target, uint32_t regno, bool exist, const struct reg_arch_type *reg_type)
Initialize register.
Definition: riscv_reg.c:588
int riscv_reg_impl_init_cache(struct target *target)
Initialize register cache.
Definition: riscv_reg.c:660
int riscv_reg_get(struct target *target, riscv_reg_t *value, enum gdb_regno regid)
This function is used to get the value of a register.
Definition: riscv_reg.c:934
struct reg * riscv_reg_impl_cache_entry(const struct target *target, uint32_t number)
Return the entry in the register cache of the target.
Definition: riscv_reg.c:551
static bool riscv_reg_impl_is_initialized(const struct reg *reg)
This file describes the helpers to use during register cache initialization of a RISC-V target.
static void init_shared_reg_info(struct target *target)
static void riscv_reg_impl_init_vector_reg_type(const struct target *target)
TODO: vector register type description can be moved into riscv013_info_t, since 0....
static bool riscv_reg_impl_gdb_regno_cacheable(enum gdb_regno regno, bool is_write)
If write is true: return true iff we are guaranteed that the register will contain exactly the value ...
int(* get)(struct reg *reg)
Definition: register.h:152
unsigned int num_regs
Definition: register.h:148
Definition: register.h:111
bool valid
Definition: register.h:126
uint32_t size
Definition: register.h:132
uint8_t * value
Definition: register.h:122
uint32_t number
Definition: register.h:115
bool dirty
Definition: register.h:124
const char * name
Definition: register.h:113
Definition: target.h:119
enum target_state state
Definition: target.h:167
void * private_config
Definition: target.h:175
struct reg_cache * reg_cache
Definition: target.h:168
static bool target_was_examined(const struct target *target)
Definition: target.h:444
@ TARGET_HALTED
Definition: target.h:58
int64_t timeval_ms(void)
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.
Definition: types.h:79