xref: /openbmc/qemu/target/riscv/csr.c (revision 68a90134c0310a1e4e707906b766c893af3cec85)
1  /*
2   * RISC-V Control and Status Registers.
3   *
4   * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5   * Copyright (c) 2017-2018 SiFive, Inc.
6   *
7   * This program is free software; you can redistribute it and/or modify it
8   * under the terms and conditions of the GNU General Public License,
9   * version 2 or later, as published by the Free Software Foundation.
10   *
11   * This program is distributed in the hope it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14   * more details.
15   *
16   * You should have received a copy of the GNU General Public License along with
17   * this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  #include "qemu/osdep.h"
21  #include "qemu/log.h"
22  #include "qemu/timer.h"
23  #include "cpu.h"
24  #include "tcg/tcg-cpu.h"
25  #include "pmu.h"
26  #include "time_helper.h"
27  #include "exec/exec-all.h"
28  #include "exec/tb-flush.h"
29  #include "sysemu/cpu-timers.h"
30  #include "qemu/guest-random.h"
31  #include "qapi/error.h"
32  
33  /* CSR function table public API */
riscv_get_csr_ops(int csrno,riscv_csr_operations * ops)34  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
35  {
36      *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
37  }
38  
riscv_set_csr_ops(int csrno,riscv_csr_operations * ops)39  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
40  {
41      csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
42  }
43  
44  /* Predicates */
45  #if !defined(CONFIG_USER_ONLY)
smstateen_acc_ok(CPURISCVState * env,int index,uint64_t bit)46  RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
47  {
48      bool virt = env->virt_enabled;
49  
50      if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
51          return RISCV_EXCP_NONE;
52      }
53  
54      if (!(env->mstateen[index] & bit)) {
55          return RISCV_EXCP_ILLEGAL_INST;
56      }
57  
58      if (virt) {
59          if (!(env->hstateen[index] & bit)) {
60              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
61          }
62  
63          if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
64              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
65          }
66      }
67  
68      if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
69          if (!(env->sstateen[index] & bit)) {
70              return RISCV_EXCP_ILLEGAL_INST;
71          }
72      }
73  
74      return RISCV_EXCP_NONE;
75  }
76  #endif
77  
fs(CPURISCVState * env,int csrno)78  static RISCVException fs(CPURISCVState *env, int csrno)
79  {
80  #if !defined(CONFIG_USER_ONLY)
81      if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
82          !riscv_cpu_cfg(env)->ext_zfinx) {
83          return RISCV_EXCP_ILLEGAL_INST;
84      }
85  
86      if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
87          return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
88      }
89  #endif
90      return RISCV_EXCP_NONE;
91  }
92  
vs(CPURISCVState * env,int csrno)93  static RISCVException vs(CPURISCVState *env, int csrno)
94  {
95      if (riscv_cpu_cfg(env)->ext_zve32x) {
96  #if !defined(CONFIG_USER_ONLY)
97          if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
98              return RISCV_EXCP_ILLEGAL_INST;
99          }
100  #endif
101          return RISCV_EXCP_NONE;
102      }
103      return RISCV_EXCP_ILLEGAL_INST;
104  }
105  
ctr(CPURISCVState * env,int csrno)106  static RISCVException ctr(CPURISCVState *env, int csrno)
107  {
108  #if !defined(CONFIG_USER_ONLY)
109      RISCVCPU *cpu = env_archcpu(env);
110      int ctr_index;
111      target_ulong ctr_mask;
112      int base_csrno = CSR_CYCLE;
113      bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
114  
115      if (rv32 && csrno >= CSR_CYCLEH) {
116          /* Offset for RV32 hpmcounternh counters */
117          base_csrno += 0x80;
118      }
119      ctr_index = csrno - base_csrno;
120      ctr_mask = BIT(ctr_index);
121  
122      if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
123          (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
124          if (!riscv_cpu_cfg(env)->ext_zicntr) {
125              return RISCV_EXCP_ILLEGAL_INST;
126          }
127  
128          goto skip_ext_pmu_check;
129      }
130  
131      if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
132          /* No counter is enabled in PMU or the counter is out of range */
133          return RISCV_EXCP_ILLEGAL_INST;
134      }
135  
136  skip_ext_pmu_check:
137  
138      if (env->debugger) {
139          return RISCV_EXCP_NONE;
140      }
141  
142      if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
143          return RISCV_EXCP_ILLEGAL_INST;
144      }
145  
146      if (env->virt_enabled) {
147          if (!get_field(env->hcounteren, ctr_mask) ||
148              (env->priv == PRV_U && !get_field(env->scounteren, ctr_mask))) {
149              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
150          }
151      }
152  
153      if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
154          !get_field(env->scounteren, ctr_mask)) {
155          return RISCV_EXCP_ILLEGAL_INST;
156      }
157  
158  #endif
159      return RISCV_EXCP_NONE;
160  }
161  
ctr32(CPURISCVState * env,int csrno)162  static RISCVException ctr32(CPURISCVState *env, int csrno)
163  {
164      if (riscv_cpu_mxl(env) != MXL_RV32) {
165          return RISCV_EXCP_ILLEGAL_INST;
166      }
167  
168      return ctr(env, csrno);
169  }
170  
zcmt(CPURISCVState * env,int csrno)171  static RISCVException zcmt(CPURISCVState *env, int csrno)
172  {
173      if (!riscv_cpu_cfg(env)->ext_zcmt) {
174          return RISCV_EXCP_ILLEGAL_INST;
175      }
176  
177  #if !defined(CONFIG_USER_ONLY)
178      RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
179      if (ret != RISCV_EXCP_NONE) {
180          return ret;
181      }
182  #endif
183  
184      return RISCV_EXCP_NONE;
185  }
186  
cfi_ss(CPURISCVState * env,int csrno)187  static RISCVException cfi_ss(CPURISCVState *env, int csrno)
188  {
189      if (!env_archcpu(env)->cfg.ext_zicfiss) {
190          return RISCV_EXCP_ILLEGAL_INST;
191      }
192  
193      /* If ext implemented, M-mode always have access to SSP CSR */
194      if (env->priv == PRV_M) {
195          return RISCV_EXCP_NONE;
196      }
197  
198      /* if bcfi not active for current env, access to csr is illegal */
199      if (!cpu_get_bcfien(env)) {
200  #if !defined(CONFIG_USER_ONLY)
201          if (env->debugger) {
202              return RISCV_EXCP_NONE;
203          }
204  #endif
205          return RISCV_EXCP_ILLEGAL_INST;
206      }
207  
208      return RISCV_EXCP_NONE;
209  }
210  
211  #if !defined(CONFIG_USER_ONLY)
mctr(CPURISCVState * env,int csrno)212  static RISCVException mctr(CPURISCVState *env, int csrno)
213  {
214      RISCVCPU *cpu = env_archcpu(env);
215      uint32_t pmu_avail_ctrs = cpu->pmu_avail_ctrs;
216      int ctr_index;
217      int base_csrno = CSR_MHPMCOUNTER3;
218  
219      if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) {
220          /* Offset for RV32 mhpmcounternh counters */
221          csrno -= 0x80;
222      }
223  
224      g_assert(csrno >= CSR_MHPMCOUNTER3 && csrno <= CSR_MHPMCOUNTER31);
225  
226      ctr_index = csrno - base_csrno;
227      if ((BIT(ctr_index) & pmu_avail_ctrs >> 3) == 0) {
228          /* The PMU is not enabled or counter is out of range */
229          return RISCV_EXCP_ILLEGAL_INST;
230      }
231  
232      return RISCV_EXCP_NONE;
233  }
234  
mctr32(CPURISCVState * env,int csrno)235  static RISCVException mctr32(CPURISCVState *env, int csrno)
236  {
237      if (riscv_cpu_mxl(env) != MXL_RV32) {
238          return RISCV_EXCP_ILLEGAL_INST;
239      }
240  
241      return mctr(env, csrno);
242  }
243  
sscofpmf(CPURISCVState * env,int csrno)244  static RISCVException sscofpmf(CPURISCVState *env, int csrno)
245  {
246      if (!riscv_cpu_cfg(env)->ext_sscofpmf) {
247          return RISCV_EXCP_ILLEGAL_INST;
248      }
249  
250      return RISCV_EXCP_NONE;
251  }
252  
sscofpmf_32(CPURISCVState * env,int csrno)253  static RISCVException sscofpmf_32(CPURISCVState *env, int csrno)
254  {
255      if (riscv_cpu_mxl(env) != MXL_RV32) {
256          return RISCV_EXCP_ILLEGAL_INST;
257      }
258  
259      return sscofpmf(env, csrno);
260  }
261  
smcntrpmf(CPURISCVState * env,int csrno)262  static RISCVException smcntrpmf(CPURISCVState *env, int csrno)
263  {
264      if (!riscv_cpu_cfg(env)->ext_smcntrpmf) {
265          return RISCV_EXCP_ILLEGAL_INST;
266      }
267  
268      return RISCV_EXCP_NONE;
269  }
270  
smcntrpmf_32(CPURISCVState * env,int csrno)271  static RISCVException smcntrpmf_32(CPURISCVState *env, int csrno)
272  {
273      if (riscv_cpu_mxl(env) != MXL_RV32) {
274          return RISCV_EXCP_ILLEGAL_INST;
275      }
276  
277      return smcntrpmf(env, csrno);
278  }
279  
any(CPURISCVState * env,int csrno)280  static RISCVException any(CPURISCVState *env, int csrno)
281  {
282      return RISCV_EXCP_NONE;
283  }
284  
any32(CPURISCVState * env,int csrno)285  static RISCVException any32(CPURISCVState *env, int csrno)
286  {
287      if (riscv_cpu_mxl(env) != MXL_RV32) {
288          return RISCV_EXCP_ILLEGAL_INST;
289      }
290  
291      return any(env, csrno);
292  
293  }
294  
aia_any(CPURISCVState * env,int csrno)295  static RISCVException aia_any(CPURISCVState *env, int csrno)
296  {
297      if (!riscv_cpu_cfg(env)->ext_smaia) {
298          return RISCV_EXCP_ILLEGAL_INST;
299      }
300  
301      return any(env, csrno);
302  }
303  
aia_any32(CPURISCVState * env,int csrno)304  static RISCVException aia_any32(CPURISCVState *env, int csrno)
305  {
306      if (!riscv_cpu_cfg(env)->ext_smaia) {
307          return RISCV_EXCP_ILLEGAL_INST;
308      }
309  
310      return any32(env, csrno);
311  }
312  
smode(CPURISCVState * env,int csrno)313  static RISCVException smode(CPURISCVState *env, int csrno)
314  {
315      if (riscv_has_ext(env, RVS)) {
316          return RISCV_EXCP_NONE;
317      }
318  
319      return RISCV_EXCP_ILLEGAL_INST;
320  }
321  
smode32(CPURISCVState * env,int csrno)322  static RISCVException smode32(CPURISCVState *env, int csrno)
323  {
324      if (riscv_cpu_mxl(env) != MXL_RV32) {
325          return RISCV_EXCP_ILLEGAL_INST;
326      }
327  
328      return smode(env, csrno);
329  }
330  
aia_smode(CPURISCVState * env,int csrno)331  static RISCVException aia_smode(CPURISCVState *env, int csrno)
332  {
333      if (!riscv_cpu_cfg(env)->ext_ssaia) {
334          return RISCV_EXCP_ILLEGAL_INST;
335      }
336  
337      return smode(env, csrno);
338  }
339  
aia_smode32(CPURISCVState * env,int csrno)340  static RISCVException aia_smode32(CPURISCVState *env, int csrno)
341  {
342      if (!riscv_cpu_cfg(env)->ext_ssaia) {
343          return RISCV_EXCP_ILLEGAL_INST;
344      }
345  
346      return smode32(env, csrno);
347  }
348  
hmode(CPURISCVState * env,int csrno)349  static RISCVException hmode(CPURISCVState *env, int csrno)
350  {
351      if (riscv_has_ext(env, RVH)) {
352          return RISCV_EXCP_NONE;
353      }
354  
355      return RISCV_EXCP_ILLEGAL_INST;
356  }
357  
hmode32(CPURISCVState * env,int csrno)358  static RISCVException hmode32(CPURISCVState *env, int csrno)
359  {
360      if (riscv_cpu_mxl(env) != MXL_RV32) {
361          return RISCV_EXCP_ILLEGAL_INST;
362      }
363  
364      return hmode(env, csrno);
365  
366  }
367  
umode(CPURISCVState * env,int csrno)368  static RISCVException umode(CPURISCVState *env, int csrno)
369  {
370      if (riscv_has_ext(env, RVU)) {
371          return RISCV_EXCP_NONE;
372      }
373  
374      return RISCV_EXCP_ILLEGAL_INST;
375  }
376  
umode32(CPURISCVState * env,int csrno)377  static RISCVException umode32(CPURISCVState *env, int csrno)
378  {
379      if (riscv_cpu_mxl(env) != MXL_RV32) {
380          return RISCV_EXCP_ILLEGAL_INST;
381      }
382  
383      return umode(env, csrno);
384  }
385  
mstateen(CPURISCVState * env,int csrno)386  static RISCVException mstateen(CPURISCVState *env, int csrno)
387  {
388      if (!riscv_cpu_cfg(env)->ext_smstateen) {
389          return RISCV_EXCP_ILLEGAL_INST;
390      }
391  
392      return any(env, csrno);
393  }
394  
hstateen_pred(CPURISCVState * env,int csrno,int base)395  static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
396  {
397      if (!riscv_cpu_cfg(env)->ext_smstateen) {
398          return RISCV_EXCP_ILLEGAL_INST;
399      }
400  
401      RISCVException ret = hmode(env, csrno);
402      if (ret != RISCV_EXCP_NONE) {
403          return ret;
404      }
405  
406      if (env->debugger) {
407          return RISCV_EXCP_NONE;
408      }
409  
410      if (env->priv < PRV_M) {
411          if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
412              return RISCV_EXCP_ILLEGAL_INST;
413          }
414      }
415  
416      return RISCV_EXCP_NONE;
417  }
418  
hstateen(CPURISCVState * env,int csrno)419  static RISCVException hstateen(CPURISCVState *env, int csrno)
420  {
421      return hstateen_pred(env, csrno, CSR_HSTATEEN0);
422  }
423  
hstateenh(CPURISCVState * env,int csrno)424  static RISCVException hstateenh(CPURISCVState *env, int csrno)
425  {
426      return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
427  }
428  
sstateen(CPURISCVState * env,int csrno)429  static RISCVException sstateen(CPURISCVState *env, int csrno)
430  {
431      bool virt = env->virt_enabled;
432      int index = csrno - CSR_SSTATEEN0;
433  
434      if (!riscv_cpu_cfg(env)->ext_smstateen) {
435          return RISCV_EXCP_ILLEGAL_INST;
436      }
437  
438      RISCVException ret = smode(env, csrno);
439      if (ret != RISCV_EXCP_NONE) {
440          return ret;
441      }
442  
443      if (env->debugger) {
444          return RISCV_EXCP_NONE;
445      }
446  
447      if (env->priv < PRV_M) {
448          if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
449              return RISCV_EXCP_ILLEGAL_INST;
450          }
451  
452          if (virt) {
453              if (!(env->hstateen[index] & SMSTATEEN_STATEEN)) {
454                  return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
455              }
456          }
457      }
458  
459      return RISCV_EXCP_NONE;
460  }
461  
sstc(CPURISCVState * env,int csrno)462  static RISCVException sstc(CPURISCVState *env, int csrno)
463  {
464      bool hmode_check = false;
465  
466      if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn) {
467          return RISCV_EXCP_ILLEGAL_INST;
468      }
469  
470      if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
471          hmode_check = true;
472      }
473  
474      RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
475      if (ret != RISCV_EXCP_NONE) {
476          return ret;
477      }
478  
479      if (env->debugger) {
480          return RISCV_EXCP_NONE;
481      }
482  
483      if (env->priv == PRV_M) {
484          return RISCV_EXCP_NONE;
485      }
486  
487      /*
488       * No need of separate function for rv32 as menvcfg stores both menvcfg
489       * menvcfgh for RV32.
490       */
491      if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
492            get_field(env->menvcfg, MENVCFG_STCE))) {
493          return RISCV_EXCP_ILLEGAL_INST;
494      }
495  
496      if (env->virt_enabled) {
497          if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
498                get_field(env->henvcfg, HENVCFG_STCE))) {
499              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
500          }
501      }
502  
503      return RISCV_EXCP_NONE;
504  }
505  
sstc_32(CPURISCVState * env,int csrno)506  static RISCVException sstc_32(CPURISCVState *env, int csrno)
507  {
508      if (riscv_cpu_mxl(env) != MXL_RV32) {
509          return RISCV_EXCP_ILLEGAL_INST;
510      }
511  
512      return sstc(env, csrno);
513  }
514  
satp(CPURISCVState * env,int csrno)515  static RISCVException satp(CPURISCVState *env, int csrno)
516  {
517      if (env->priv == PRV_S && !env->virt_enabled &&
518          get_field(env->mstatus, MSTATUS_TVM)) {
519          return RISCV_EXCP_ILLEGAL_INST;
520      }
521      if (env->priv == PRV_S && env->virt_enabled &&
522          get_field(env->hstatus, HSTATUS_VTVM)) {
523          return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
524      }
525  
526      return smode(env, csrno);
527  }
528  
hgatp(CPURISCVState * env,int csrno)529  static RISCVException hgatp(CPURISCVState *env, int csrno)
530  {
531      if (env->priv == PRV_S && !env->virt_enabled &&
532          get_field(env->mstatus, MSTATUS_TVM)) {
533          return RISCV_EXCP_ILLEGAL_INST;
534      }
535  
536      return hmode(env, csrno);
537  }
538  
539  /* Checks if PointerMasking registers could be accessed */
pointer_masking(CPURISCVState * env,int csrno)540  static RISCVException pointer_masking(CPURISCVState *env, int csrno)
541  {
542      /* Check if j-ext is present */
543      if (riscv_has_ext(env, RVJ)) {
544          return RISCV_EXCP_NONE;
545      }
546      return RISCV_EXCP_ILLEGAL_INST;
547  }
548  
aia_hmode(CPURISCVState * env,int csrno)549  static RISCVException aia_hmode(CPURISCVState *env, int csrno)
550  {
551      if (!riscv_cpu_cfg(env)->ext_ssaia) {
552          return RISCV_EXCP_ILLEGAL_INST;
553       }
554  
555       return hmode(env, csrno);
556  }
557  
aia_hmode32(CPURISCVState * env,int csrno)558  static RISCVException aia_hmode32(CPURISCVState *env, int csrno)
559  {
560      if (!riscv_cpu_cfg(env)->ext_ssaia) {
561          return RISCV_EXCP_ILLEGAL_INST;
562      }
563  
564      return hmode32(env, csrno);
565  }
566  
pmp(CPURISCVState * env,int csrno)567  static RISCVException pmp(CPURISCVState *env, int csrno)
568  {
569      if (riscv_cpu_cfg(env)->pmp) {
570          if (csrno <= CSR_PMPCFG3) {
571              uint32_t reg_index = csrno - CSR_PMPCFG0;
572  
573              /* TODO: RV128 restriction check */
574              if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
575                  return RISCV_EXCP_ILLEGAL_INST;
576              }
577          }
578  
579          return RISCV_EXCP_NONE;
580      }
581  
582      return RISCV_EXCP_ILLEGAL_INST;
583  }
584  
have_mseccfg(CPURISCVState * env,int csrno)585  static RISCVException have_mseccfg(CPURISCVState *env, int csrno)
586  {
587      if (riscv_cpu_cfg(env)->ext_smepmp) {
588          return RISCV_EXCP_NONE;
589      }
590      if (riscv_cpu_cfg(env)->ext_zkr) {
591          return RISCV_EXCP_NONE;
592      }
593  
594      return RISCV_EXCP_ILLEGAL_INST;
595  }
596  
debug(CPURISCVState * env,int csrno)597  static RISCVException debug(CPURISCVState *env, int csrno)
598  {
599      if (riscv_cpu_cfg(env)->debug) {
600          return RISCV_EXCP_NONE;
601      }
602  
603      return RISCV_EXCP_ILLEGAL_INST;
604  }
605  #endif
606  
seed(CPURISCVState * env,int csrno)607  static RISCVException seed(CPURISCVState *env, int csrno)
608  {
609      if (!riscv_cpu_cfg(env)->ext_zkr) {
610          return RISCV_EXCP_ILLEGAL_INST;
611      }
612  
613  #if !defined(CONFIG_USER_ONLY)
614      if (env->debugger) {
615          return RISCV_EXCP_NONE;
616      }
617  
618      /*
619       * With a CSR read-write instruction:
620       * 1) The seed CSR is always available in machine mode as normal.
621       * 2) Attempted access to seed from virtual modes VS and VU always raises
622       * an exception(virtual instruction exception only if mseccfg.sseed=1).
623       * 3) Without the corresponding access control bit set to 1, any attempted
624       * access to seed from U, S or HS modes will raise an illegal instruction
625       * exception.
626       */
627      if (env->priv == PRV_M) {
628          return RISCV_EXCP_NONE;
629      } else if (env->virt_enabled) {
630          if (env->mseccfg & MSECCFG_SSEED) {
631              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
632          } else {
633              return RISCV_EXCP_ILLEGAL_INST;
634          }
635      } else {
636          if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) {
637              return RISCV_EXCP_NONE;
638          } else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) {
639              return RISCV_EXCP_NONE;
640          } else {
641              return RISCV_EXCP_ILLEGAL_INST;
642          }
643      }
644  #else
645      return RISCV_EXCP_NONE;
646  #endif
647  }
648  
649  /* zicfiss CSR_SSP read and write */
read_ssp(CPURISCVState * env,int csrno,target_ulong * val)650  static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
651  {
652      *val = env->ssp;
653      return RISCV_EXCP_NONE;
654  }
655  
write_ssp(CPURISCVState * env,int csrno,target_ulong val)656  static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
657  {
658      env->ssp = val;
659      return RISCV_EXCP_NONE;
660  }
661  
662  /* User Floating-Point CSRs */
read_fflags(CPURISCVState * env,int csrno,target_ulong * val)663  static RISCVException read_fflags(CPURISCVState *env, int csrno,
664                                    target_ulong *val)
665  {
666      *val = riscv_cpu_get_fflags(env);
667      return RISCV_EXCP_NONE;
668  }
669  
write_fflags(CPURISCVState * env,int csrno,target_ulong val)670  static RISCVException write_fflags(CPURISCVState *env, int csrno,
671                                     target_ulong val)
672  {
673  #if !defined(CONFIG_USER_ONLY)
674      if (riscv_has_ext(env, RVF)) {
675          env->mstatus |= MSTATUS_FS;
676      }
677  #endif
678      riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
679      return RISCV_EXCP_NONE;
680  }
681  
read_frm(CPURISCVState * env,int csrno,target_ulong * val)682  static RISCVException read_frm(CPURISCVState *env, int csrno,
683                                 target_ulong *val)
684  {
685      *val = env->frm;
686      return RISCV_EXCP_NONE;
687  }
688  
write_frm(CPURISCVState * env,int csrno,target_ulong val)689  static RISCVException write_frm(CPURISCVState *env, int csrno,
690                                  target_ulong val)
691  {
692  #if !defined(CONFIG_USER_ONLY)
693      if (riscv_has_ext(env, RVF)) {
694          env->mstatus |= MSTATUS_FS;
695      }
696  #endif
697      env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
698      return RISCV_EXCP_NONE;
699  }
700  
read_fcsr(CPURISCVState * env,int csrno,target_ulong * val)701  static RISCVException read_fcsr(CPURISCVState *env, int csrno,
702                                  target_ulong *val)
703  {
704      *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
705          | (env->frm << FSR_RD_SHIFT);
706      return RISCV_EXCP_NONE;
707  }
708  
write_fcsr(CPURISCVState * env,int csrno,target_ulong val)709  static RISCVException write_fcsr(CPURISCVState *env, int csrno,
710                                   target_ulong val)
711  {
712  #if !defined(CONFIG_USER_ONLY)
713      if (riscv_has_ext(env, RVF)) {
714          env->mstatus |= MSTATUS_FS;
715      }
716  #endif
717      env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
718      riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
719      return RISCV_EXCP_NONE;
720  }
721  
read_vtype(CPURISCVState * env,int csrno,target_ulong * val)722  static RISCVException read_vtype(CPURISCVState *env, int csrno,
723                                   target_ulong *val)
724  {
725      uint64_t vill;
726      switch (env->xl) {
727      case MXL_RV32:
728          vill = (uint32_t)env->vill << 31;
729          break;
730      case MXL_RV64:
731          vill = (uint64_t)env->vill << 63;
732          break;
733      default:
734          g_assert_not_reached();
735      }
736      *val = (target_ulong)vill | env->vtype;
737      return RISCV_EXCP_NONE;
738  }
739  
read_vl(CPURISCVState * env,int csrno,target_ulong * val)740  static RISCVException read_vl(CPURISCVState *env, int csrno,
741                                target_ulong *val)
742  {
743      *val = env->vl;
744      return RISCV_EXCP_NONE;
745  }
746  
read_vlenb(CPURISCVState * env,int csrno,target_ulong * val)747  static RISCVException read_vlenb(CPURISCVState *env, int csrno,
748                                   target_ulong *val)
749  {
750      *val = riscv_cpu_cfg(env)->vlenb;
751      return RISCV_EXCP_NONE;
752  }
753  
read_vxrm(CPURISCVState * env,int csrno,target_ulong * val)754  static RISCVException read_vxrm(CPURISCVState *env, int csrno,
755                                  target_ulong *val)
756  {
757      *val = env->vxrm;
758      return RISCV_EXCP_NONE;
759  }
760  
write_vxrm(CPURISCVState * env,int csrno,target_ulong val)761  static RISCVException write_vxrm(CPURISCVState *env, int csrno,
762                                   target_ulong val)
763  {
764  #if !defined(CONFIG_USER_ONLY)
765      env->mstatus |= MSTATUS_VS;
766  #endif
767      env->vxrm = val;
768      return RISCV_EXCP_NONE;
769  }
770  
read_vxsat(CPURISCVState * env,int csrno,target_ulong * val)771  static RISCVException read_vxsat(CPURISCVState *env, int csrno,
772                                   target_ulong *val)
773  {
774      *val = env->vxsat & BIT(0);
775      return RISCV_EXCP_NONE;
776  }
777  
write_vxsat(CPURISCVState * env,int csrno,target_ulong val)778  static RISCVException write_vxsat(CPURISCVState *env, int csrno,
779                                    target_ulong val)
780  {
781  #if !defined(CONFIG_USER_ONLY)
782      env->mstatus |= MSTATUS_VS;
783  #endif
784      env->vxsat = val & BIT(0);
785      return RISCV_EXCP_NONE;
786  }
787  
read_vstart(CPURISCVState * env,int csrno,target_ulong * val)788  static RISCVException read_vstart(CPURISCVState *env, int csrno,
789                                    target_ulong *val)
790  {
791      *val = env->vstart;
792      return RISCV_EXCP_NONE;
793  }
794  
write_vstart(CPURISCVState * env,int csrno,target_ulong val)795  static RISCVException write_vstart(CPURISCVState *env, int csrno,
796                                     target_ulong val)
797  {
798  #if !defined(CONFIG_USER_ONLY)
799      env->mstatus |= MSTATUS_VS;
800  #endif
801      /*
802       * The vstart CSR is defined to have only enough writable bits
803       * to hold the largest element index, i.e. lg2(VLEN) bits.
804       */
805      env->vstart = val & ~(~0ULL << ctzl(riscv_cpu_cfg(env)->vlenb << 3));
806      return RISCV_EXCP_NONE;
807  }
808  
read_vcsr(CPURISCVState * env,int csrno,target_ulong * val)809  static RISCVException read_vcsr(CPURISCVState *env, int csrno,
810                                  target_ulong *val)
811  {
812      *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
813      return RISCV_EXCP_NONE;
814  }
815  
write_vcsr(CPURISCVState * env,int csrno,target_ulong val)816  static RISCVException write_vcsr(CPURISCVState *env, int csrno,
817                                   target_ulong val)
818  {
819  #if !defined(CONFIG_USER_ONLY)
820      env->mstatus |= MSTATUS_VS;
821  #endif
822      env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
823      env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
824      return RISCV_EXCP_NONE;
825  }
826  
827  #if defined(CONFIG_USER_ONLY)
828  /* User Timers and Counters */
get_ticks(bool shift)829  static target_ulong get_ticks(bool shift)
830  {
831      int64_t val = cpu_get_host_ticks();
832      target_ulong result = shift ? val >> 32 : val;
833  
834      return result;
835  }
836  
read_time(CPURISCVState * env,int csrno,target_ulong * val)837  static RISCVException read_time(CPURISCVState *env, int csrno,
838                                  target_ulong *val)
839  {
840      *val = cpu_get_host_ticks();
841      return RISCV_EXCP_NONE;
842  }
843  
read_timeh(CPURISCVState * env,int csrno,target_ulong * val)844  static RISCVException read_timeh(CPURISCVState *env, int csrno,
845                                   target_ulong *val)
846  {
847      *val = cpu_get_host_ticks() >> 32;
848      return RISCV_EXCP_NONE;
849  }
850  
read_hpmcounter(CPURISCVState * env,int csrno,target_ulong * val)851  static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
852                                        target_ulong *val)
853  {
854      *val = get_ticks(false);
855      return RISCV_EXCP_NONE;
856  }
857  
read_hpmcounterh(CPURISCVState * env,int csrno,target_ulong * val)858  static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
859                                         target_ulong *val)
860  {
861      *val = get_ticks(true);
862      return RISCV_EXCP_NONE;
863  }
864  
865  #else /* CONFIG_USER_ONLY */
866  
read_mcyclecfg(CPURISCVState * env,int csrno,target_ulong * val)867  static RISCVException read_mcyclecfg(CPURISCVState *env, int csrno,
868                                       target_ulong *val)
869  {
870      *val = env->mcyclecfg;
871      return RISCV_EXCP_NONE;
872  }
873  
write_mcyclecfg(CPURISCVState * env,int csrno,target_ulong val)874  static RISCVException write_mcyclecfg(CPURISCVState *env, int csrno,
875                                        target_ulong val)
876  {
877      uint64_t inh_avail_mask;
878  
879      if (riscv_cpu_mxl(env) == MXL_RV32) {
880          env->mcyclecfg = val;
881      } else {
882          /* Set xINH fields if priv mode supported */
883          inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MCYCLECFG_BIT_MINH;
884          inh_avail_mask |= riscv_has_ext(env, RVU) ? MCYCLECFG_BIT_UINH : 0;
885          inh_avail_mask |= riscv_has_ext(env, RVS) ? MCYCLECFG_BIT_SINH : 0;
886          inh_avail_mask |= (riscv_has_ext(env, RVH) &&
887                             riscv_has_ext(env, RVU)) ? MCYCLECFG_BIT_VUINH : 0;
888          inh_avail_mask |= (riscv_has_ext(env, RVH) &&
889                             riscv_has_ext(env, RVS)) ? MCYCLECFG_BIT_VSINH : 0;
890          env->mcyclecfg = val & inh_avail_mask;
891      }
892  
893      return RISCV_EXCP_NONE;
894  }
895  
read_mcyclecfgh(CPURISCVState * env,int csrno,target_ulong * val)896  static RISCVException read_mcyclecfgh(CPURISCVState *env, int csrno,
897                                        target_ulong *val)
898  {
899      *val = env->mcyclecfgh;
900      return RISCV_EXCP_NONE;
901  }
902  
write_mcyclecfgh(CPURISCVState * env,int csrno,target_ulong val)903  static RISCVException write_mcyclecfgh(CPURISCVState *env, int csrno,
904                                         target_ulong val)
905  {
906      target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
907                                                   MCYCLECFGH_BIT_MINH);
908  
909      /* Set xINH fields if priv mode supported */
910      inh_avail_mask |= riscv_has_ext(env, RVU) ? MCYCLECFGH_BIT_UINH : 0;
911      inh_avail_mask |= riscv_has_ext(env, RVS) ? MCYCLECFGH_BIT_SINH : 0;
912      inh_avail_mask |= (riscv_has_ext(env, RVH) &&
913                         riscv_has_ext(env, RVU)) ? MCYCLECFGH_BIT_VUINH : 0;
914      inh_avail_mask |= (riscv_has_ext(env, RVH) &&
915                         riscv_has_ext(env, RVS)) ? MCYCLECFGH_BIT_VSINH : 0;
916  
917      env->mcyclecfgh = val & inh_avail_mask;
918      return RISCV_EXCP_NONE;
919  }
920  
read_minstretcfg(CPURISCVState * env,int csrno,target_ulong * val)921  static RISCVException read_minstretcfg(CPURISCVState *env, int csrno,
922                                         target_ulong *val)
923  {
924      *val = env->minstretcfg;
925      return RISCV_EXCP_NONE;
926  }
927  
write_minstretcfg(CPURISCVState * env,int csrno,target_ulong val)928  static RISCVException write_minstretcfg(CPURISCVState *env, int csrno,
929                                          target_ulong val)
930  {
931      uint64_t inh_avail_mask;
932  
933      if (riscv_cpu_mxl(env) == MXL_RV32) {
934          env->minstretcfg = val;
935      } else {
936          inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MINSTRETCFG_BIT_MINH;
937          inh_avail_mask |= riscv_has_ext(env, RVU) ? MINSTRETCFG_BIT_UINH : 0;
938          inh_avail_mask |= riscv_has_ext(env, RVS) ? MINSTRETCFG_BIT_SINH : 0;
939          inh_avail_mask |= (riscv_has_ext(env, RVH) &&
940                             riscv_has_ext(env, RVU)) ? MINSTRETCFG_BIT_VUINH : 0;
941          inh_avail_mask |= (riscv_has_ext(env, RVH) &&
942                             riscv_has_ext(env, RVS)) ? MINSTRETCFG_BIT_VSINH : 0;
943          env->minstretcfg = val & inh_avail_mask;
944      }
945      return RISCV_EXCP_NONE;
946  }
947  
read_minstretcfgh(CPURISCVState * env,int csrno,target_ulong * val)948  static RISCVException read_minstretcfgh(CPURISCVState *env, int csrno,
949                                          target_ulong *val)
950  {
951      *val = env->minstretcfgh;
952      return RISCV_EXCP_NONE;
953  }
954  
write_minstretcfgh(CPURISCVState * env,int csrno,target_ulong val)955  static RISCVException write_minstretcfgh(CPURISCVState *env, int csrno,
956                                           target_ulong val)
957  {
958      target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
959                                                   MINSTRETCFGH_BIT_MINH);
960  
961      inh_avail_mask |= riscv_has_ext(env, RVU) ? MINSTRETCFGH_BIT_UINH : 0;
962      inh_avail_mask |= riscv_has_ext(env, RVS) ? MINSTRETCFGH_BIT_SINH : 0;
963      inh_avail_mask |= (riscv_has_ext(env, RVH) &&
964                         riscv_has_ext(env, RVU)) ? MINSTRETCFGH_BIT_VUINH : 0;
965      inh_avail_mask |= (riscv_has_ext(env, RVH) &&
966                         riscv_has_ext(env, RVS)) ? MINSTRETCFGH_BIT_VSINH : 0;
967  
968      env->minstretcfgh = val & inh_avail_mask;
969      return RISCV_EXCP_NONE;
970  }
971  
read_mhpmevent(CPURISCVState * env,int csrno,target_ulong * val)972  static RISCVException read_mhpmevent(CPURISCVState *env, int csrno,
973                                       target_ulong *val)
974  {
975      int evt_index = csrno - CSR_MCOUNTINHIBIT;
976  
977      *val = env->mhpmevent_val[evt_index];
978  
979      return RISCV_EXCP_NONE;
980  }
981  
write_mhpmevent(CPURISCVState * env,int csrno,target_ulong val)982  static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
983                                        target_ulong val)
984  {
985      int evt_index = csrno - CSR_MCOUNTINHIBIT;
986      uint64_t mhpmevt_val = val;
987      uint64_t inh_avail_mask;
988  
989      if (riscv_cpu_mxl(env) == MXL_RV32) {
990          env->mhpmevent_val[evt_index] = val;
991          mhpmevt_val = mhpmevt_val |
992                        ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
993      } else {
994          inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MHPMEVENT_BIT_MINH;
995          inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENT_BIT_UINH : 0;
996          inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENT_BIT_SINH : 0;
997          inh_avail_mask |= (riscv_has_ext(env, RVH) &&
998                             riscv_has_ext(env, RVU)) ? MHPMEVENT_BIT_VUINH : 0;
999          inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1000                             riscv_has_ext(env, RVS)) ? MHPMEVENT_BIT_VSINH : 0;
1001          mhpmevt_val = val & inh_avail_mask;
1002          env->mhpmevent_val[evt_index] = mhpmevt_val;
1003      }
1004  
1005      riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
1006  
1007      return RISCV_EXCP_NONE;
1008  }
1009  
read_mhpmeventh(CPURISCVState * env,int csrno,target_ulong * val)1010  static RISCVException read_mhpmeventh(CPURISCVState *env, int csrno,
1011                                        target_ulong *val)
1012  {
1013      int evt_index = csrno - CSR_MHPMEVENT3H + 3;
1014  
1015      *val = env->mhpmeventh_val[evt_index];
1016  
1017      return RISCV_EXCP_NONE;
1018  }
1019  
write_mhpmeventh(CPURISCVState * env,int csrno,target_ulong val)1020  static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
1021                                         target_ulong val)
1022  {
1023      int evt_index = csrno - CSR_MHPMEVENT3H + 3;
1024      uint64_t mhpmevth_val;
1025      uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
1026      target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
1027                                                    MHPMEVENTH_BIT_MINH);
1028  
1029      inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENTH_BIT_UINH : 0;
1030      inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENTH_BIT_SINH : 0;
1031      inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1032                         riscv_has_ext(env, RVU)) ? MHPMEVENTH_BIT_VUINH : 0;
1033      inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1034                         riscv_has_ext(env, RVS)) ? MHPMEVENTH_BIT_VSINH : 0;
1035  
1036      mhpmevth_val = val & inh_avail_mask;
1037      mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
1038      env->mhpmeventh_val[evt_index] = mhpmevth_val;
1039  
1040      riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
1041  
1042      return RISCV_EXCP_NONE;
1043  }
1044  
riscv_pmu_ctr_get_fixed_counters_val(CPURISCVState * env,int counter_idx,bool upper_half)1045  static target_ulong riscv_pmu_ctr_get_fixed_counters_val(CPURISCVState *env,
1046                                                           int counter_idx,
1047                                                           bool upper_half)
1048  {
1049      int inst = riscv_pmu_ctr_monitor_instructions(env, counter_idx);
1050      uint64_t *counter_arr_virt = env->pmu_fixed_ctrs[inst].counter_virt;
1051      uint64_t *counter_arr = env->pmu_fixed_ctrs[inst].counter;
1052      target_ulong result = 0;
1053      uint64_t curr_val = 0;
1054      uint64_t cfg_val = 0;
1055  
1056      if (counter_idx == 0) {
1057          cfg_val = upper_half ? ((uint64_t)env->mcyclecfgh << 32) :
1058                    env->mcyclecfg;
1059      } else if (counter_idx == 2) {
1060          cfg_val = upper_half ? ((uint64_t)env->minstretcfgh << 32) :
1061                    env->minstretcfg;
1062      } else {
1063          cfg_val = upper_half ?
1064                    ((uint64_t)env->mhpmeventh_val[counter_idx] << 32) :
1065                    env->mhpmevent_val[counter_idx];
1066          cfg_val &= MHPMEVENT_FILTER_MASK;
1067      }
1068  
1069      if (!cfg_val) {
1070          if (icount_enabled()) {
1071                  curr_val = inst ? icount_get_raw() : icount_get();
1072          } else {
1073              curr_val = cpu_get_host_ticks();
1074          }
1075  
1076          goto done;
1077      }
1078  
1079      /* Update counter before reading. */
1080      riscv_pmu_update_fixed_ctrs(env, env->priv, env->virt_enabled);
1081  
1082      if (!(cfg_val & MCYCLECFG_BIT_MINH)) {
1083          curr_val += counter_arr[PRV_M];
1084      }
1085  
1086      if (!(cfg_val & MCYCLECFG_BIT_SINH)) {
1087          curr_val += counter_arr[PRV_S];
1088      }
1089  
1090      if (!(cfg_val & MCYCLECFG_BIT_UINH)) {
1091          curr_val += counter_arr[PRV_U];
1092      }
1093  
1094      if (!(cfg_val & MCYCLECFG_BIT_VSINH)) {
1095          curr_val += counter_arr_virt[PRV_S];
1096      }
1097  
1098      if (!(cfg_val & MCYCLECFG_BIT_VUINH)) {
1099          curr_val += counter_arr_virt[PRV_U];
1100      }
1101  
1102  done:
1103      if (riscv_cpu_mxl(env) == MXL_RV32) {
1104          result = upper_half ? curr_val >> 32 : curr_val;
1105      } else {
1106          result = curr_val;
1107      }
1108  
1109      return result;
1110  }
1111  
write_mhpmcounter(CPURISCVState * env,int csrno,target_ulong val)1112  static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
1113                                          target_ulong val)
1114  {
1115      int ctr_idx = csrno - CSR_MCYCLE;
1116      PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
1117      uint64_t mhpmctr_val = val;
1118  
1119      counter->mhpmcounter_val = val;
1120      if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
1121          (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
1122           riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
1123          counter->mhpmcounter_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
1124                                                                  ctr_idx, false);
1125          if (ctr_idx > 2) {
1126              if (riscv_cpu_mxl(env) == MXL_RV32) {
1127                  mhpmctr_val = mhpmctr_val |
1128                                ((uint64_t)counter->mhpmcounterh_val << 32);
1129              }
1130              riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
1131          }
1132       } else {
1133          /* Other counters can keep incrementing from the given value */
1134          counter->mhpmcounter_prev = val;
1135      }
1136  
1137      return RISCV_EXCP_NONE;
1138  }
1139  
write_mhpmcounterh(CPURISCVState * env,int csrno,target_ulong val)1140  static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
1141                                           target_ulong val)
1142  {
1143      int ctr_idx = csrno - CSR_MCYCLEH;
1144      PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
1145      uint64_t mhpmctr_val = counter->mhpmcounter_val;
1146      uint64_t mhpmctrh_val = val;
1147  
1148      counter->mhpmcounterh_val = val;
1149      mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
1150      if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
1151          (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
1152           riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
1153          counter->mhpmcounterh_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
1154                                                                   ctr_idx, true);
1155          if (ctr_idx > 2) {
1156              riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
1157          }
1158      } else {
1159          counter->mhpmcounterh_prev = val;
1160      }
1161  
1162      return RISCV_EXCP_NONE;
1163  }
1164  
riscv_pmu_read_ctr(CPURISCVState * env,target_ulong * val,bool upper_half,uint32_t ctr_idx)1165  RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
1166                                           bool upper_half, uint32_t ctr_idx)
1167  {
1168      PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
1169      target_ulong ctr_prev = upper_half ? counter->mhpmcounterh_prev :
1170                                           counter->mhpmcounter_prev;
1171      target_ulong ctr_val = upper_half ? counter->mhpmcounterh_val :
1172                                          counter->mhpmcounter_val;
1173  
1174      if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
1175          /*
1176           * Counter should not increment if inhibit bit is set. Just return the
1177           * current counter value.
1178           */
1179           *val = ctr_val;
1180           return RISCV_EXCP_NONE;
1181      }
1182  
1183      /*
1184       * The kernel computes the perf delta by subtracting the current value from
1185       * the value it initialized previously (ctr_val).
1186       */
1187      if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
1188          riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
1189          *val = riscv_pmu_ctr_get_fixed_counters_val(env, ctr_idx, upper_half) -
1190                                                      ctr_prev + ctr_val;
1191      } else {
1192          *val = ctr_val;
1193      }
1194  
1195      return RISCV_EXCP_NONE;
1196  }
1197  
read_hpmcounter(CPURISCVState * env,int csrno,target_ulong * val)1198  static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
1199                                        target_ulong *val)
1200  {
1201      uint16_t ctr_index;
1202  
1203      if (csrno >= CSR_MCYCLE && csrno <= CSR_MHPMCOUNTER31) {
1204          ctr_index = csrno - CSR_MCYCLE;
1205      } else if (csrno >= CSR_CYCLE && csrno <= CSR_HPMCOUNTER31) {
1206          ctr_index = csrno - CSR_CYCLE;
1207      } else {
1208          return RISCV_EXCP_ILLEGAL_INST;
1209      }
1210  
1211      return riscv_pmu_read_ctr(env, val, false, ctr_index);
1212  }
1213  
read_hpmcounterh(CPURISCVState * env,int csrno,target_ulong * val)1214  static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
1215                                         target_ulong *val)
1216  {
1217      uint16_t ctr_index;
1218  
1219      if (csrno >= CSR_MCYCLEH && csrno <= CSR_MHPMCOUNTER31H) {
1220          ctr_index = csrno - CSR_MCYCLEH;
1221      } else if (csrno >= CSR_CYCLEH && csrno <= CSR_HPMCOUNTER31H) {
1222          ctr_index = csrno - CSR_CYCLEH;
1223      } else {
1224          return RISCV_EXCP_ILLEGAL_INST;
1225      }
1226  
1227      return riscv_pmu_read_ctr(env, val, true, ctr_index);
1228  }
1229  
read_scountovf(CPURISCVState * env,int csrno,target_ulong * val)1230  static RISCVException read_scountovf(CPURISCVState *env, int csrno,
1231                                       target_ulong *val)
1232  {
1233      int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
1234      int i;
1235      *val = 0;
1236      target_ulong *mhpm_evt_val;
1237      uint64_t of_bit_mask;
1238  
1239      if (riscv_cpu_mxl(env) == MXL_RV32) {
1240          mhpm_evt_val = env->mhpmeventh_val;
1241          of_bit_mask = MHPMEVENTH_BIT_OF;
1242      } else {
1243          mhpm_evt_val = env->mhpmevent_val;
1244          of_bit_mask = MHPMEVENT_BIT_OF;
1245      }
1246  
1247      for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
1248          if ((get_field(env->mcounteren, BIT(i))) &&
1249              (mhpm_evt_val[i] & of_bit_mask)) {
1250                      *val |= BIT(i);
1251              }
1252      }
1253  
1254      return RISCV_EXCP_NONE;
1255  }
1256  
read_time(CPURISCVState * env,int csrno,target_ulong * val)1257  static RISCVException read_time(CPURISCVState *env, int csrno,
1258                                  target_ulong *val)
1259  {
1260      uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
1261  
1262      if (!env->rdtime_fn) {
1263          return RISCV_EXCP_ILLEGAL_INST;
1264      }
1265  
1266      *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
1267      return RISCV_EXCP_NONE;
1268  }
1269  
read_timeh(CPURISCVState * env,int csrno,target_ulong * val)1270  static RISCVException read_timeh(CPURISCVState *env, int csrno,
1271                                   target_ulong *val)
1272  {
1273      uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
1274  
1275      if (!env->rdtime_fn) {
1276          return RISCV_EXCP_ILLEGAL_INST;
1277      }
1278  
1279      *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
1280      return RISCV_EXCP_NONE;
1281  }
1282  
read_vstimecmp(CPURISCVState * env,int csrno,target_ulong * val)1283  static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
1284                                       target_ulong *val)
1285  {
1286      *val = env->vstimecmp;
1287  
1288      return RISCV_EXCP_NONE;
1289  }
1290  
read_vstimecmph(CPURISCVState * env,int csrno,target_ulong * val)1291  static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
1292                                        target_ulong *val)
1293  {
1294      *val = env->vstimecmp >> 32;
1295  
1296      return RISCV_EXCP_NONE;
1297  }
1298  
write_vstimecmp(CPURISCVState * env,int csrno,target_ulong val)1299  static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
1300                                        target_ulong val)
1301  {
1302      if (riscv_cpu_mxl(env) == MXL_RV32) {
1303          env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
1304      } else {
1305          env->vstimecmp = val;
1306      }
1307  
1308      riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
1309                                env->htimedelta, MIP_VSTIP);
1310  
1311      return RISCV_EXCP_NONE;
1312  }
1313  
write_vstimecmph(CPURISCVState * env,int csrno,target_ulong val)1314  static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
1315                                         target_ulong val)
1316  {
1317      env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
1318      riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
1319                                env->htimedelta, MIP_VSTIP);
1320  
1321      return RISCV_EXCP_NONE;
1322  }
1323  
read_stimecmp(CPURISCVState * env,int csrno,target_ulong * val)1324  static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
1325                                      target_ulong *val)
1326  {
1327      if (env->virt_enabled) {
1328          *val = env->vstimecmp;
1329      } else {
1330          *val = env->stimecmp;
1331      }
1332  
1333      return RISCV_EXCP_NONE;
1334  }
1335  
read_stimecmph(CPURISCVState * env,int csrno,target_ulong * val)1336  static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
1337                                       target_ulong *val)
1338  {
1339      if (env->virt_enabled) {
1340          *val = env->vstimecmp >> 32;
1341      } else {
1342          *val = env->stimecmp >> 32;
1343      }
1344  
1345      return RISCV_EXCP_NONE;
1346  }
1347  
write_stimecmp(CPURISCVState * env,int csrno,target_ulong val)1348  static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
1349                                       target_ulong val)
1350  {
1351      if (env->virt_enabled) {
1352          if (env->hvictl & HVICTL_VTI) {
1353              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1354          }
1355          return write_vstimecmp(env, csrno, val);
1356      }
1357  
1358      if (riscv_cpu_mxl(env) == MXL_RV32) {
1359          env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
1360      } else {
1361          env->stimecmp = val;
1362      }
1363  
1364      riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
1365  
1366      return RISCV_EXCP_NONE;
1367  }
1368  
write_stimecmph(CPURISCVState * env,int csrno,target_ulong val)1369  static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
1370                                        target_ulong val)
1371  {
1372      if (env->virt_enabled) {
1373          if (env->hvictl & HVICTL_VTI) {
1374              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1375          }
1376          return write_vstimecmph(env, csrno, val);
1377      }
1378  
1379      env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
1380      riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
1381  
1382      return RISCV_EXCP_NONE;
1383  }
1384  
1385  #define VSTOPI_NUM_SRCS 5
1386  
1387  /*
1388   * All core local interrupts except the fixed ones 0:12. This macro is for
1389   * virtual interrupts logic so please don't change this to avoid messing up
1390   * the whole support, For reference see AIA spec: `5.3 Interrupt filtering and
1391   * virtual interrupts for supervisor level` and `6.3.2 Virtual interrupts for
1392   * VS level`.
1393   */
1394  #define LOCAL_INTERRUPTS   (~0x1FFFULL)
1395  
1396  static const uint64_t delegable_ints =
1397      S_MODE_INTERRUPTS | VS_MODE_INTERRUPTS | MIP_LCOFIP;
1398  static const uint64_t vs_delegable_ints =
1399      (VS_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & ~MIP_LCOFIP;
1400  static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
1401                                       HS_MODE_INTERRUPTS | LOCAL_INTERRUPTS;
1402  #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
1403                           (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
1404                           (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
1405                           (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
1406                           (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
1407                           (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
1408                           (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
1409                           (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
1410                           (1ULL << (RISCV_EXCP_U_ECALL)) | \
1411                           (1ULL << (RISCV_EXCP_S_ECALL)) | \
1412                           (1ULL << (RISCV_EXCP_VS_ECALL)) | \
1413                           (1ULL << (RISCV_EXCP_M_ECALL)) | \
1414                           (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
1415                           (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
1416                           (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
1417                           (1ULL << (RISCV_EXCP_SW_CHECK)) | \
1418                           (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
1419                           (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
1420                           (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
1421                           (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
1422  static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
1423      ~((1ULL << (RISCV_EXCP_S_ECALL)) |
1424        (1ULL << (RISCV_EXCP_VS_ECALL)) |
1425        (1ULL << (RISCV_EXCP_M_ECALL)) |
1426        (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
1427        (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
1428        (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
1429        (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
1430  static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
1431      SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
1432      SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
1433  
1434  /*
1435   * Spec allows for bits 13:63 to be either read-only or writable.
1436   * So far we have interrupt LCOFIP in that region which is writable.
1437   *
1438   * Also, spec allows to inject virtual interrupts in this region even
1439   * without any hardware interrupts for that interrupt number.
1440   *
1441   * For now interrupt in 13:63 region are all kept writable. 13 being
1442   * LCOFIP and 14:63 being virtual only. Change this in future if we
1443   * introduce more interrupts that are not writable.
1444   */
1445  
1446  /* Bit STIP can be an alias of mip.STIP that's why it's writable in mvip. */
1447  static const uint64_t mvip_writable_mask = MIP_SSIP | MIP_STIP | MIP_SEIP |
1448                                      LOCAL_INTERRUPTS;
1449  static const uint64_t mvien_writable_mask = MIP_SSIP | MIP_SEIP |
1450                                      LOCAL_INTERRUPTS;
1451  
1452  static const uint64_t sip_writable_mask = SIP_SSIP | LOCAL_INTERRUPTS;
1453  static const uint64_t hip_writable_mask = MIP_VSSIP;
1454  static const uint64_t hvip_writable_mask = MIP_VSSIP | MIP_VSTIP |
1455                                      MIP_VSEIP | LOCAL_INTERRUPTS;
1456  static const uint64_t hvien_writable_mask = LOCAL_INTERRUPTS;
1457  
1458  static const uint64_t vsip_writable_mask = MIP_VSSIP | LOCAL_INTERRUPTS;
1459  
1460  const bool valid_vm_1_10_32[16] = {
1461      [VM_1_10_MBARE] = true,
1462      [VM_1_10_SV32] = true
1463  };
1464  
1465  const bool valid_vm_1_10_64[16] = {
1466      [VM_1_10_MBARE] = true,
1467      [VM_1_10_SV39] = true,
1468      [VM_1_10_SV48] = true,
1469      [VM_1_10_SV57] = true
1470  };
1471  
1472  /* Machine Information Registers */
read_zero(CPURISCVState * env,int csrno,target_ulong * val)1473  static RISCVException read_zero(CPURISCVState *env, int csrno,
1474                                  target_ulong *val)
1475  {
1476      *val = 0;
1477      return RISCV_EXCP_NONE;
1478  }
1479  
write_ignore(CPURISCVState * env,int csrno,target_ulong val)1480  static RISCVException write_ignore(CPURISCVState *env, int csrno,
1481                                     target_ulong val)
1482  {
1483      return RISCV_EXCP_NONE;
1484  }
1485  
read_mvendorid(CPURISCVState * env,int csrno,target_ulong * val)1486  static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
1487                                       target_ulong *val)
1488  {
1489      *val = riscv_cpu_cfg(env)->mvendorid;
1490      return RISCV_EXCP_NONE;
1491  }
1492  
read_marchid(CPURISCVState * env,int csrno,target_ulong * val)1493  static RISCVException read_marchid(CPURISCVState *env, int csrno,
1494                                     target_ulong *val)
1495  {
1496      *val = riscv_cpu_cfg(env)->marchid;
1497      return RISCV_EXCP_NONE;
1498  }
1499  
read_mimpid(CPURISCVState * env,int csrno,target_ulong * val)1500  static RISCVException read_mimpid(CPURISCVState *env, int csrno,
1501                                    target_ulong *val)
1502  {
1503      *val = riscv_cpu_cfg(env)->mimpid;
1504      return RISCV_EXCP_NONE;
1505  }
1506  
read_mhartid(CPURISCVState * env,int csrno,target_ulong * val)1507  static RISCVException read_mhartid(CPURISCVState *env, int csrno,
1508                                     target_ulong *val)
1509  {
1510      *val = env->mhartid;
1511      return RISCV_EXCP_NONE;
1512  }
1513  
1514  /* Machine Trap Setup */
1515  
1516  /* We do not store SD explicitly, only compute it on demand. */
add_status_sd(RISCVMXL xl,uint64_t status)1517  static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
1518  {
1519      if ((status & MSTATUS_FS) == MSTATUS_FS ||
1520          (status & MSTATUS_VS) == MSTATUS_VS ||
1521          (status & MSTATUS_XS) == MSTATUS_XS) {
1522          switch (xl) {
1523          case MXL_RV32:
1524              return status | MSTATUS32_SD;
1525          case MXL_RV64:
1526              return status | MSTATUS64_SD;
1527          case MXL_RV128:
1528              return MSTATUSH128_SD;
1529          default:
1530              g_assert_not_reached();
1531          }
1532      }
1533      return status;
1534  }
1535  
read_mstatus(CPURISCVState * env,int csrno,target_ulong * val)1536  static RISCVException read_mstatus(CPURISCVState *env, int csrno,
1537                                     target_ulong *val)
1538  {
1539      *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
1540      return RISCV_EXCP_NONE;
1541  }
1542  
validate_vm(CPURISCVState * env,target_ulong vm)1543  static bool validate_vm(CPURISCVState *env, target_ulong vm)
1544  {
1545      uint64_t mode_supported = riscv_cpu_cfg(env)->satp_mode.map;
1546      return get_field(mode_supported, (1 << vm));
1547  }
1548  
legalize_xatp(CPURISCVState * env,target_ulong old_xatp,target_ulong val)1549  static target_ulong legalize_xatp(CPURISCVState *env, target_ulong old_xatp,
1550                                    target_ulong val)
1551  {
1552      target_ulong mask;
1553      bool vm;
1554      if (riscv_cpu_mxl(env) == MXL_RV32) {
1555          vm = validate_vm(env, get_field(val, SATP32_MODE));
1556          mask = (val ^ old_xatp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
1557      } else {
1558          vm = validate_vm(env, get_field(val, SATP64_MODE));
1559          mask = (val ^ old_xatp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
1560      }
1561  
1562      if (vm && mask) {
1563          /*
1564           * The ISA defines SATP.MODE=Bare as "no translation", but we still
1565           * pass these through QEMU's TLB emulation as it improves
1566           * performance.  Flushing the TLB on SATP writes with paging
1567           * enabled avoids leaking those invalid cached mappings.
1568           */
1569          tlb_flush(env_cpu(env));
1570          return val;
1571      }
1572      return old_xatp;
1573  }
1574  
legalize_mpp(CPURISCVState * env,target_ulong old_mpp,target_ulong val)1575  static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
1576                                   target_ulong val)
1577  {
1578      bool valid = false;
1579      target_ulong new_mpp = get_field(val, MSTATUS_MPP);
1580  
1581      switch (new_mpp) {
1582      case PRV_M:
1583          valid = true;
1584          break;
1585      case PRV_S:
1586          valid = riscv_has_ext(env, RVS);
1587          break;
1588      case PRV_U:
1589          valid = riscv_has_ext(env, RVU);
1590          break;
1591      }
1592  
1593      /* Remain field unchanged if new_mpp value is invalid */
1594      if (!valid) {
1595          val = set_field(val, MSTATUS_MPP, old_mpp);
1596      }
1597  
1598      return val;
1599  }
1600  
write_mstatus(CPURISCVState * env,int csrno,target_ulong val)1601  static RISCVException write_mstatus(CPURISCVState *env, int csrno,
1602                                      target_ulong val)
1603  {
1604      uint64_t mstatus = env->mstatus;
1605      uint64_t mask = 0;
1606      RISCVMXL xl = riscv_cpu_mxl(env);
1607  
1608      /*
1609       * MPP field have been made WARL since priv version 1.11. However,
1610       * legalization for it will not break any software running on 1.10.
1611       */
1612      val = legalize_mpp(env, get_field(mstatus, MSTATUS_MPP), val);
1613  
1614      /* flush tlb on mstatus fields that affect VM */
1615      if ((val ^ mstatus) & MSTATUS_MXR) {
1616          tlb_flush(env_cpu(env));
1617      }
1618      mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
1619          MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
1620          MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
1621          MSTATUS_TW;
1622  
1623      if (riscv_has_ext(env, RVF)) {
1624          mask |= MSTATUS_FS;
1625      }
1626      if (riscv_has_ext(env, RVV)) {
1627          mask |= MSTATUS_VS;
1628      }
1629  
1630      if (xl != MXL_RV32 || env->debugger) {
1631          if (riscv_has_ext(env, RVH)) {
1632              mask |= MSTATUS_MPV | MSTATUS_GVA;
1633          }
1634          if ((val & MSTATUS64_UXL) != 0) {
1635              mask |= MSTATUS64_UXL;
1636          }
1637      }
1638  
1639      /* If cfi lp extension is available, then apply cfi lp mask */
1640      if (env_archcpu(env)->cfg.ext_zicfilp) {
1641          mask |= (MSTATUS_MPELP | MSTATUS_SPELP);
1642      }
1643  
1644      mstatus = (mstatus & ~mask) | (val & mask);
1645  
1646      env->mstatus = mstatus;
1647  
1648      /*
1649       * Except in debug mode, UXL/SXL can only be modified by higher
1650       * privilege mode. So xl will not be changed in normal mode.
1651       */
1652      if (env->debugger) {
1653          env->xl = cpu_recompute_xl(env);
1654      }
1655  
1656      riscv_cpu_update_mask(env);
1657      return RISCV_EXCP_NONE;
1658  }
1659  
read_mstatush(CPURISCVState * env,int csrno,target_ulong * val)1660  static RISCVException read_mstatush(CPURISCVState *env, int csrno,
1661                                      target_ulong *val)
1662  {
1663      *val = env->mstatus >> 32;
1664      return RISCV_EXCP_NONE;
1665  }
1666  
write_mstatush(CPURISCVState * env,int csrno,target_ulong val)1667  static RISCVException write_mstatush(CPURISCVState *env, int csrno,
1668                                       target_ulong val)
1669  {
1670      uint64_t valh = (uint64_t)val << 32;
1671      uint64_t mask = riscv_has_ext(env, RVH) ? MSTATUS_MPV | MSTATUS_GVA : 0;
1672  
1673      env->mstatus = (env->mstatus & ~mask) | (valh & mask);
1674  
1675      return RISCV_EXCP_NONE;
1676  }
1677  
read_mstatus_i128(CPURISCVState * env,int csrno,Int128 * val)1678  static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
1679                                          Int128 *val)
1680  {
1681      *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128,
1682                                                        env->mstatus));
1683      return RISCV_EXCP_NONE;
1684  }
1685  
read_misa_i128(CPURISCVState * env,int csrno,Int128 * val)1686  static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
1687                                       Int128 *val)
1688  {
1689      *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
1690      return RISCV_EXCP_NONE;
1691  }
1692  
read_misa(CPURISCVState * env,int csrno,target_ulong * val)1693  static RISCVException read_misa(CPURISCVState *env, int csrno,
1694                                  target_ulong *val)
1695  {
1696      target_ulong misa;
1697  
1698      switch (env->misa_mxl) {
1699      case MXL_RV32:
1700          misa = (target_ulong)MXL_RV32 << 30;
1701          break;
1702  #ifdef TARGET_RISCV64
1703      case MXL_RV64:
1704          misa = (target_ulong)MXL_RV64 << 62;
1705          break;
1706  #endif
1707      default:
1708          g_assert_not_reached();
1709      }
1710  
1711      *val = misa | env->misa_ext;
1712      return RISCV_EXCP_NONE;
1713  }
1714  
write_misa(CPURISCVState * env,int csrno,target_ulong val)1715  static RISCVException write_misa(CPURISCVState *env, int csrno,
1716                                   target_ulong val)
1717  {
1718      RISCVCPU *cpu = env_archcpu(env);
1719      uint32_t orig_misa_ext = env->misa_ext;
1720      Error *local_err = NULL;
1721  
1722      if (!riscv_cpu_cfg(env)->misa_w) {
1723          /* drop write to misa */
1724          return RISCV_EXCP_NONE;
1725      }
1726  
1727      /* Mask extensions that are not supported by this hart */
1728      val &= env->misa_ext_mask;
1729  
1730      /*
1731       * Suppress 'C' if next instruction is not aligned
1732       * TODO: this should check next_pc
1733       */
1734      if ((val & RVC) && (GETPC() & ~3) != 0) {
1735          val &= ~RVC;
1736      }
1737  
1738      /* Disable RVG if any of its dependencies are disabled */
1739      if (!(val & RVI && val & RVM && val & RVA &&
1740            val & RVF && val & RVD)) {
1741          val &= ~RVG;
1742      }
1743  
1744      /* If nothing changed, do nothing. */
1745      if (val == env->misa_ext) {
1746          return RISCV_EXCP_NONE;
1747      }
1748  
1749      env->misa_ext = val;
1750      riscv_cpu_validate_set_extensions(cpu, &local_err);
1751      if (local_err != NULL) {
1752          /* Rollback on validation error */
1753          qemu_log_mask(LOG_GUEST_ERROR, "Unable to write MISA ext value "
1754                        "0x%x, keeping existing MISA ext 0x%x\n",
1755                        env->misa_ext, orig_misa_ext);
1756  
1757          env->misa_ext = orig_misa_ext;
1758  
1759          return RISCV_EXCP_NONE;
1760      }
1761  
1762      if (!(env->misa_ext & RVF)) {
1763          env->mstatus &= ~MSTATUS_FS;
1764      }
1765  
1766      /* flush translation cache */
1767      tb_flush(env_cpu(env));
1768      env->xl = riscv_cpu_mxl(env);
1769      return RISCV_EXCP_NONE;
1770  }
1771  
read_medeleg(CPURISCVState * env,int csrno,target_ulong * val)1772  static RISCVException read_medeleg(CPURISCVState *env, int csrno,
1773                                     target_ulong *val)
1774  {
1775      *val = env->medeleg;
1776      return RISCV_EXCP_NONE;
1777  }
1778  
write_medeleg(CPURISCVState * env,int csrno,target_ulong val)1779  static RISCVException write_medeleg(CPURISCVState *env, int csrno,
1780                                      target_ulong val)
1781  {
1782      env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
1783      return RISCV_EXCP_NONE;
1784  }
1785  
rmw_mideleg64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)1786  static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
1787                                      uint64_t *ret_val,
1788                                      uint64_t new_val, uint64_t wr_mask)
1789  {
1790      uint64_t mask = wr_mask & delegable_ints;
1791  
1792      if (ret_val) {
1793          *ret_val = env->mideleg;
1794      }
1795  
1796      env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
1797  
1798      if (riscv_has_ext(env, RVH)) {
1799          env->mideleg |= HS_MODE_INTERRUPTS;
1800      }
1801  
1802      return RISCV_EXCP_NONE;
1803  }
1804  
rmw_mideleg(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1805  static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
1806                                    target_ulong *ret_val,
1807                                    target_ulong new_val, target_ulong wr_mask)
1808  {
1809      uint64_t rval;
1810      RISCVException ret;
1811  
1812      ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
1813      if (ret_val) {
1814          *ret_val = rval;
1815      }
1816  
1817      return ret;
1818  }
1819  
rmw_midelegh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1820  static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
1821                                     target_ulong *ret_val,
1822                                     target_ulong new_val,
1823                                     target_ulong wr_mask)
1824  {
1825      uint64_t rval;
1826      RISCVException ret;
1827  
1828      ret = rmw_mideleg64(env, csrno, &rval,
1829          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1830      if (ret_val) {
1831          *ret_val = rval >> 32;
1832      }
1833  
1834      return ret;
1835  }
1836  
rmw_mie64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)1837  static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
1838                                  uint64_t *ret_val,
1839                                  uint64_t new_val, uint64_t wr_mask)
1840  {
1841      uint64_t mask = wr_mask & all_ints;
1842  
1843      if (ret_val) {
1844          *ret_val = env->mie;
1845      }
1846  
1847      env->mie = (env->mie & ~mask) | (new_val & mask);
1848  
1849      if (!riscv_has_ext(env, RVH)) {
1850          env->mie &= ~((uint64_t)HS_MODE_INTERRUPTS);
1851      }
1852  
1853      return RISCV_EXCP_NONE;
1854  }
1855  
rmw_mie(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1856  static RISCVException rmw_mie(CPURISCVState *env, int csrno,
1857                                target_ulong *ret_val,
1858                                target_ulong new_val, target_ulong wr_mask)
1859  {
1860      uint64_t rval;
1861      RISCVException ret;
1862  
1863      ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
1864      if (ret_val) {
1865          *ret_val = rval;
1866      }
1867  
1868      return ret;
1869  }
1870  
rmw_mieh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1871  static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
1872                                 target_ulong *ret_val,
1873                                 target_ulong new_val, target_ulong wr_mask)
1874  {
1875      uint64_t rval;
1876      RISCVException ret;
1877  
1878      ret = rmw_mie64(env, csrno, &rval,
1879          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1880      if (ret_val) {
1881          *ret_val = rval >> 32;
1882      }
1883  
1884      return ret;
1885  }
1886  
rmw_mvien64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)1887  static RISCVException rmw_mvien64(CPURISCVState *env, int csrno,
1888                                  uint64_t *ret_val,
1889                                  uint64_t new_val, uint64_t wr_mask)
1890  {
1891      uint64_t mask = wr_mask & mvien_writable_mask;
1892  
1893      if (ret_val) {
1894          *ret_val = env->mvien;
1895      }
1896  
1897      env->mvien = (env->mvien & ~mask) | (new_val & mask);
1898  
1899      return RISCV_EXCP_NONE;
1900  }
1901  
rmw_mvien(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1902  static RISCVException rmw_mvien(CPURISCVState *env, int csrno,
1903                                target_ulong *ret_val,
1904                                target_ulong new_val, target_ulong wr_mask)
1905  {
1906      uint64_t rval;
1907      RISCVException ret;
1908  
1909      ret = rmw_mvien64(env, csrno, &rval, new_val, wr_mask);
1910      if (ret_val) {
1911          *ret_val = rval;
1912      }
1913  
1914      return ret;
1915  }
1916  
rmw_mvienh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1917  static RISCVException rmw_mvienh(CPURISCVState *env, int csrno,
1918                                  target_ulong *ret_val,
1919                                  target_ulong new_val, target_ulong wr_mask)
1920  {
1921      uint64_t rval;
1922      RISCVException ret;
1923  
1924      ret = rmw_mvien64(env, csrno, &rval,
1925          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1926      if (ret_val) {
1927          *ret_val = rval >> 32;
1928      }
1929  
1930      return ret;
1931  }
1932  
read_mtopi(CPURISCVState * env,int csrno,target_ulong * val)1933  static RISCVException read_mtopi(CPURISCVState *env, int csrno,
1934                                   target_ulong *val)
1935  {
1936      int irq;
1937      uint8_t iprio;
1938  
1939      irq = riscv_cpu_mirq_pending(env);
1940      if (irq <= 0 || irq > 63) {
1941          *val = 0;
1942      } else {
1943          iprio = env->miprio[irq];
1944          if (!iprio) {
1945              if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) {
1946                  iprio = IPRIO_MMAXIPRIO;
1947              }
1948          }
1949          *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
1950          *val |= iprio;
1951      }
1952  
1953      return RISCV_EXCP_NONE;
1954  }
1955  
aia_xlate_vs_csrno(CPURISCVState * env,int csrno)1956  static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
1957  {
1958      if (!env->virt_enabled) {
1959          return csrno;
1960      }
1961  
1962      switch (csrno) {
1963      case CSR_SISELECT:
1964          return CSR_VSISELECT;
1965      case CSR_SIREG:
1966          return CSR_VSIREG;
1967      case CSR_STOPEI:
1968          return CSR_VSTOPEI;
1969      default:
1970          return csrno;
1971      };
1972  }
1973  
rmw_xiselect(CPURISCVState * env,int csrno,target_ulong * val,target_ulong new_val,target_ulong wr_mask)1974  static RISCVException rmw_xiselect(CPURISCVState *env, int csrno,
1975                                     target_ulong *val, target_ulong new_val,
1976                                     target_ulong wr_mask)
1977  {
1978      target_ulong *iselect;
1979  
1980      /* Translate CSR number for VS-mode */
1981      csrno = aia_xlate_vs_csrno(env, csrno);
1982  
1983      /* Find the iselect CSR based on CSR number */
1984      switch (csrno) {
1985      case CSR_MISELECT:
1986          iselect = &env->miselect;
1987          break;
1988      case CSR_SISELECT:
1989          iselect = &env->siselect;
1990          break;
1991      case CSR_VSISELECT:
1992          iselect = &env->vsiselect;
1993          break;
1994      default:
1995           return RISCV_EXCP_ILLEGAL_INST;
1996      };
1997  
1998      if (val) {
1999          *val = *iselect;
2000      }
2001  
2002      wr_mask &= ISELECT_MASK;
2003      if (wr_mask) {
2004          *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
2005      }
2006  
2007      return RISCV_EXCP_NONE;
2008  }
2009  
rmw_iprio(target_ulong xlen,target_ulong iselect,uint8_t * iprio,target_ulong * val,target_ulong new_val,target_ulong wr_mask,int ext_irq_no)2010  static int rmw_iprio(target_ulong xlen,
2011                       target_ulong iselect, uint8_t *iprio,
2012                       target_ulong *val, target_ulong new_val,
2013                       target_ulong wr_mask, int ext_irq_no)
2014  {
2015      int i, firq, nirqs;
2016      target_ulong old_val;
2017  
2018      if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
2019          return -EINVAL;
2020      }
2021      if (xlen != 32 && iselect & 0x1) {
2022          return -EINVAL;
2023      }
2024  
2025      nirqs = 4 * (xlen / 32);
2026      firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
2027  
2028      old_val = 0;
2029      for (i = 0; i < nirqs; i++) {
2030          old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i);
2031      }
2032  
2033      if (val) {
2034          *val = old_val;
2035      }
2036  
2037      if (wr_mask) {
2038          new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
2039          for (i = 0; i < nirqs; i++) {
2040              /*
2041               * M-level and S-level external IRQ priority always read-only
2042               * zero. This means default priority order is always preferred
2043               * for M-level and S-level external IRQs.
2044               */
2045              if ((firq + i) == ext_irq_no) {
2046                  continue;
2047              }
2048              iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
2049          }
2050      }
2051  
2052      return 0;
2053  }
2054  
rmw_xireg(CPURISCVState * env,int csrno,target_ulong * val,target_ulong new_val,target_ulong wr_mask)2055  static RISCVException rmw_xireg(CPURISCVState *env, int csrno,
2056                                  target_ulong *val, target_ulong new_val,
2057                                  target_ulong wr_mask)
2058  {
2059      bool virt, isel_reserved;
2060      uint8_t *iprio;
2061      int ret = -EINVAL;
2062      target_ulong priv, isel, vgein;
2063  
2064      /* Translate CSR number for VS-mode */
2065      csrno = aia_xlate_vs_csrno(env, csrno);
2066  
2067      /* Decode register details from CSR number */
2068      virt = false;
2069      isel_reserved = false;
2070      switch (csrno) {
2071      case CSR_MIREG:
2072          iprio = env->miprio;
2073          isel = env->miselect;
2074          priv = PRV_M;
2075          break;
2076      case CSR_SIREG:
2077          if (env->priv == PRV_S && env->mvien & MIP_SEIP &&
2078              env->siselect >= ISELECT_IMSIC_EIDELIVERY &&
2079              env->siselect <= ISELECT_IMSIC_EIE63) {
2080              goto done;
2081          }
2082          iprio = env->siprio;
2083          isel = env->siselect;
2084          priv = PRV_S;
2085          break;
2086      case CSR_VSIREG:
2087          iprio = env->hviprio;
2088          isel = env->vsiselect;
2089          priv = PRV_S;
2090          virt = true;
2091          break;
2092      default:
2093           goto done;
2094      };
2095  
2096      /* Find the selected guest interrupt file */
2097      vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
2098  
2099      if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
2100          /* Local interrupt priority registers not available for VS-mode */
2101          if (!virt) {
2102              ret = rmw_iprio(riscv_cpu_mxl_bits(env),
2103                              isel, iprio, val, new_val, wr_mask,
2104                              (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
2105          }
2106      } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) {
2107          /* IMSIC registers only available when machine implements it. */
2108          if (env->aia_ireg_rmw_fn[priv]) {
2109              /* Selected guest interrupt file should not be zero */
2110              if (virt && (!vgein || env->geilen < vgein)) {
2111                  goto done;
2112              }
2113              /* Call machine specific IMSIC register emulation */
2114              ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
2115                                      AIA_MAKE_IREG(isel, priv, virt, vgein,
2116                                                    riscv_cpu_mxl_bits(env)),
2117                                      val, new_val, wr_mask);
2118          }
2119      } else {
2120          isel_reserved = true;
2121      }
2122  
2123  done:
2124      if (ret) {
2125          return (env->virt_enabled && virt && !isel_reserved) ?
2126                 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2127      }
2128      return RISCV_EXCP_NONE;
2129  }
2130  
rmw_xtopei(CPURISCVState * env,int csrno,target_ulong * val,target_ulong new_val,target_ulong wr_mask)2131  static RISCVException rmw_xtopei(CPURISCVState *env, int csrno,
2132                                   target_ulong *val, target_ulong new_val,
2133                                   target_ulong wr_mask)
2134  {
2135      bool virt;
2136      int ret = -EINVAL;
2137      target_ulong priv, vgein;
2138  
2139      /* Translate CSR number for VS-mode */
2140      csrno = aia_xlate_vs_csrno(env, csrno);
2141  
2142      /* Decode register details from CSR number */
2143      virt = false;
2144      switch (csrno) {
2145      case CSR_MTOPEI:
2146          priv = PRV_M;
2147          break;
2148      case CSR_STOPEI:
2149          if (env->mvien & MIP_SEIP && env->priv == PRV_S) {
2150              goto done;
2151          }
2152          priv = PRV_S;
2153          break;
2154      case CSR_VSTOPEI:
2155          priv = PRV_S;
2156          virt = true;
2157          break;
2158      default:
2159          goto done;
2160      };
2161  
2162      /* IMSIC CSRs only available when machine implements IMSIC. */
2163      if (!env->aia_ireg_rmw_fn[priv]) {
2164          goto done;
2165      }
2166  
2167      /* Find the selected guest interrupt file */
2168      vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
2169  
2170      /* Selected guest interrupt file should be valid */
2171      if (virt && (!vgein || env->geilen < vgein)) {
2172          goto done;
2173      }
2174  
2175      /* Call machine specific IMSIC register emulation for TOPEI */
2176      ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
2177                      AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein,
2178                                    riscv_cpu_mxl_bits(env)),
2179                      val, new_val, wr_mask);
2180  
2181  done:
2182      if (ret) {
2183          return (env->virt_enabled && virt) ?
2184                 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2185      }
2186      return RISCV_EXCP_NONE;
2187  }
2188  
read_mtvec(CPURISCVState * env,int csrno,target_ulong * val)2189  static RISCVException read_mtvec(CPURISCVState *env, int csrno,
2190                                   target_ulong *val)
2191  {
2192      *val = env->mtvec;
2193      return RISCV_EXCP_NONE;
2194  }
2195  
write_mtvec(CPURISCVState * env,int csrno,target_ulong val)2196  static RISCVException write_mtvec(CPURISCVState *env, int csrno,
2197                                    target_ulong val)
2198  {
2199      /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
2200      if ((val & 3) < 2) {
2201          env->mtvec = val;
2202      } else {
2203          qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
2204      }
2205      return RISCV_EXCP_NONE;
2206  }
2207  
read_mcountinhibit(CPURISCVState * env,int csrno,target_ulong * val)2208  static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
2209                                           target_ulong *val)
2210  {
2211      *val = env->mcountinhibit;
2212      return RISCV_EXCP_NONE;
2213  }
2214  
write_mcountinhibit(CPURISCVState * env,int csrno,target_ulong val)2215  static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
2216                                            target_ulong val)
2217  {
2218      int cidx;
2219      PMUCTRState *counter;
2220      RISCVCPU *cpu = env_archcpu(env);
2221      uint32_t present_ctrs = cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR;
2222      target_ulong updated_ctrs = (env->mcountinhibit ^ val) & present_ctrs;
2223      uint64_t mhpmctr_val, prev_count, curr_count;
2224  
2225      /* WARL register - disable unavailable counters; TM bit is always 0 */
2226      env->mcountinhibit = val & present_ctrs;
2227  
2228      /* Check if any other counter is also monitoring cycles/instructions */
2229      for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
2230          if (!(updated_ctrs & BIT(cidx)) ||
2231              (!riscv_pmu_ctr_monitor_cycles(env, cidx) &&
2232              !riscv_pmu_ctr_monitor_instructions(env, cidx))) {
2233              continue;
2234          }
2235  
2236          counter = &env->pmu_ctrs[cidx];
2237  
2238          if (!get_field(env->mcountinhibit, BIT(cidx))) {
2239              counter->mhpmcounter_prev =
2240                  riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false);
2241              if (riscv_cpu_mxl(env) == MXL_RV32) {
2242                  counter->mhpmcounterh_prev =
2243                      riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
2244              }
2245  
2246              if (cidx > 2) {
2247                  mhpmctr_val = counter->mhpmcounter_val;
2248                  if (riscv_cpu_mxl(env) == MXL_RV32) {
2249                      mhpmctr_val = mhpmctr_val |
2250                              ((uint64_t)counter->mhpmcounterh_val << 32);
2251                  }
2252                  riscv_pmu_setup_timer(env, mhpmctr_val, cidx);
2253              }
2254          } else {
2255              curr_count = riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false);
2256  
2257              mhpmctr_val = counter->mhpmcounter_val;
2258              prev_count = counter->mhpmcounter_prev;
2259              if (riscv_cpu_mxl(env) == MXL_RV32) {
2260                  uint64_t tmp =
2261                      riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
2262  
2263                  curr_count = curr_count | (tmp << 32);
2264                  mhpmctr_val = mhpmctr_val |
2265                      ((uint64_t)counter->mhpmcounterh_val << 32);
2266                  prev_count = prev_count |
2267                      ((uint64_t)counter->mhpmcounterh_prev << 32);
2268              }
2269  
2270              /* Adjust the counter for later reads. */
2271              mhpmctr_val = curr_count - prev_count + mhpmctr_val;
2272              counter->mhpmcounter_val = mhpmctr_val;
2273              if (riscv_cpu_mxl(env) == MXL_RV32) {
2274                  counter->mhpmcounterh_val = mhpmctr_val >> 32;
2275              }
2276          }
2277      }
2278  
2279      return RISCV_EXCP_NONE;
2280  }
2281  
read_mcounteren(CPURISCVState * env,int csrno,target_ulong * val)2282  static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
2283                                        target_ulong *val)
2284  {
2285      *val = env->mcounteren;
2286      return RISCV_EXCP_NONE;
2287  }
2288  
write_mcounteren(CPURISCVState * env,int csrno,target_ulong val)2289  static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
2290                                         target_ulong val)
2291  {
2292      RISCVCPU *cpu = env_archcpu(env);
2293  
2294      /* WARL register - disable unavailable counters */
2295      env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
2296                               COUNTEREN_IR);
2297      return RISCV_EXCP_NONE;
2298  }
2299  
2300  /* Machine Trap Handling */
read_mscratch_i128(CPURISCVState * env,int csrno,Int128 * val)2301  static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
2302                                           Int128 *val)
2303  {
2304      *val = int128_make128(env->mscratch, env->mscratchh);
2305      return RISCV_EXCP_NONE;
2306  }
2307  
write_mscratch_i128(CPURISCVState * env,int csrno,Int128 val)2308  static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
2309                                            Int128 val)
2310  {
2311      env->mscratch = int128_getlo(val);
2312      env->mscratchh = int128_gethi(val);
2313      return RISCV_EXCP_NONE;
2314  }
2315  
read_mscratch(CPURISCVState * env,int csrno,target_ulong * val)2316  static RISCVException read_mscratch(CPURISCVState *env, int csrno,
2317                                      target_ulong *val)
2318  {
2319      *val = env->mscratch;
2320      return RISCV_EXCP_NONE;
2321  }
2322  
write_mscratch(CPURISCVState * env,int csrno,target_ulong val)2323  static RISCVException write_mscratch(CPURISCVState *env, int csrno,
2324                                       target_ulong val)
2325  {
2326      env->mscratch = val;
2327      return RISCV_EXCP_NONE;
2328  }
2329  
read_mepc(CPURISCVState * env,int csrno,target_ulong * val)2330  static RISCVException read_mepc(CPURISCVState *env, int csrno,
2331                                  target_ulong *val)
2332  {
2333      *val = env->mepc;
2334      return RISCV_EXCP_NONE;
2335  }
2336  
write_mepc(CPURISCVState * env,int csrno,target_ulong val)2337  static RISCVException write_mepc(CPURISCVState *env, int csrno,
2338                                   target_ulong val)
2339  {
2340      env->mepc = val;
2341      return RISCV_EXCP_NONE;
2342  }
2343  
read_mcause(CPURISCVState * env,int csrno,target_ulong * val)2344  static RISCVException read_mcause(CPURISCVState *env, int csrno,
2345                                    target_ulong *val)
2346  {
2347      *val = env->mcause;
2348      return RISCV_EXCP_NONE;
2349  }
2350  
write_mcause(CPURISCVState * env,int csrno,target_ulong val)2351  static RISCVException write_mcause(CPURISCVState *env, int csrno,
2352                                     target_ulong val)
2353  {
2354      env->mcause = val;
2355      return RISCV_EXCP_NONE;
2356  }
2357  
read_mtval(CPURISCVState * env,int csrno,target_ulong * val)2358  static RISCVException read_mtval(CPURISCVState *env, int csrno,
2359                                   target_ulong *val)
2360  {
2361      *val = env->mtval;
2362      return RISCV_EXCP_NONE;
2363  }
2364  
write_mtval(CPURISCVState * env,int csrno,target_ulong val)2365  static RISCVException write_mtval(CPURISCVState *env, int csrno,
2366                                    target_ulong val)
2367  {
2368      env->mtval = val;
2369      return RISCV_EXCP_NONE;
2370  }
2371  
2372  /* Execution environment configuration setup */
read_menvcfg(CPURISCVState * env,int csrno,target_ulong * val)2373  static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
2374                                     target_ulong *val)
2375  {
2376      *val = env->menvcfg;
2377      return RISCV_EXCP_NONE;
2378  }
2379  
write_menvcfg(CPURISCVState * env,int csrno,target_ulong val)2380  static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
2381                                      target_ulong val)
2382  {
2383      const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
2384      uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
2385  
2386      if (riscv_cpu_mxl(env) == MXL_RV64) {
2387          mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
2388                  (cfg->ext_sstc ? MENVCFG_STCE : 0) |
2389                  (cfg->ext_svadu ? MENVCFG_ADUE : 0);
2390  
2391          if (env_archcpu(env)->cfg.ext_zicfilp) {
2392              mask |= MENVCFG_LPE;
2393          }
2394  
2395          if (env_archcpu(env)->cfg.ext_zicfiss) {
2396              mask |= MENVCFG_SSE;
2397          }
2398      }
2399      env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
2400  
2401      return RISCV_EXCP_NONE;
2402  }
2403  
read_menvcfgh(CPURISCVState * env,int csrno,target_ulong * val)2404  static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
2405                                      target_ulong *val)
2406  {
2407      *val = env->menvcfg >> 32;
2408      return RISCV_EXCP_NONE;
2409  }
2410  
write_menvcfgh(CPURISCVState * env,int csrno,target_ulong val)2411  static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
2412                                       target_ulong val)
2413  {
2414      const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
2415      uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
2416                      (cfg->ext_sstc ? MENVCFG_STCE : 0) |
2417                      (cfg->ext_svadu ? MENVCFG_ADUE : 0);
2418      uint64_t valh = (uint64_t)val << 32;
2419  
2420      env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
2421  
2422      return RISCV_EXCP_NONE;
2423  }
2424  
read_senvcfg(CPURISCVState * env,int csrno,target_ulong * val)2425  static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
2426                                     target_ulong *val)
2427  {
2428      RISCVException ret;
2429  
2430      ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2431      if (ret != RISCV_EXCP_NONE) {
2432          return ret;
2433      }
2434  
2435      *val = env->senvcfg;
2436      return RISCV_EXCP_NONE;
2437  }
2438  
write_senvcfg(CPURISCVState * env,int csrno,target_ulong val)2439  static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
2440                                      target_ulong val)
2441  {
2442      uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
2443      RISCVException ret;
2444  
2445      ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2446      if (ret != RISCV_EXCP_NONE) {
2447          return ret;
2448      }
2449  
2450      if (env_archcpu(env)->cfg.ext_zicfilp) {
2451          mask |= SENVCFG_LPE;
2452      }
2453  
2454      /* Higher mode SSE must be ON for next-less mode SSE to be ON */
2455      if (env_archcpu(env)->cfg.ext_zicfiss &&
2456          get_field(env->menvcfg, MENVCFG_SSE) &&
2457          (env->virt_enabled ? get_field(env->henvcfg, HENVCFG_SSE) : true)) {
2458          mask |= SENVCFG_SSE;
2459      }
2460  
2461      env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
2462      return RISCV_EXCP_NONE;
2463  }
2464  
read_henvcfg(CPURISCVState * env,int csrno,target_ulong * val)2465  static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
2466                                     target_ulong *val)
2467  {
2468      RISCVException ret;
2469  
2470      ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2471      if (ret != RISCV_EXCP_NONE) {
2472          return ret;
2473      }
2474  
2475      /*
2476       * henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
2477       * henvcfg.stce is read_only 0 when menvcfg.stce = 0
2478       * henvcfg.adue is read_only 0 when menvcfg.adue = 0
2479       */
2480      *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
2481                             env->menvcfg);
2482      return RISCV_EXCP_NONE;
2483  }
2484  
write_henvcfg(CPURISCVState * env,int csrno,target_ulong val)2485  static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
2486                                      target_ulong val)
2487  {
2488      uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
2489      RISCVException ret;
2490  
2491      ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2492      if (ret != RISCV_EXCP_NONE) {
2493          return ret;
2494      }
2495  
2496      if (riscv_cpu_mxl(env) == MXL_RV64) {
2497          mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
2498  
2499          if (env_archcpu(env)->cfg.ext_zicfilp) {
2500              mask |= HENVCFG_LPE;
2501          }
2502  
2503          /* H can light up SSE for VS only if HS had it from menvcfg */
2504          if (env_archcpu(env)->cfg.ext_zicfiss &&
2505              get_field(env->menvcfg, MENVCFG_SSE)) {
2506              mask |= HENVCFG_SSE;
2507          }
2508      }
2509  
2510      env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
2511  
2512      return RISCV_EXCP_NONE;
2513  }
2514  
read_henvcfgh(CPURISCVState * env,int csrno,target_ulong * val)2515  static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
2516                                      target_ulong *val)
2517  {
2518      RISCVException ret;
2519  
2520      ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2521      if (ret != RISCV_EXCP_NONE) {
2522          return ret;
2523      }
2524  
2525      *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
2526                              env->menvcfg)) >> 32;
2527      return RISCV_EXCP_NONE;
2528  }
2529  
write_henvcfgh(CPURISCVState * env,int csrno,target_ulong val)2530  static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
2531                                       target_ulong val)
2532  {
2533      uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
2534                                      HENVCFG_ADUE);
2535      uint64_t valh = (uint64_t)val << 32;
2536      RISCVException ret;
2537  
2538      ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2539      if (ret != RISCV_EXCP_NONE) {
2540          return ret;
2541      }
2542  
2543      env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
2544      return RISCV_EXCP_NONE;
2545  }
2546  
read_mstateen(CPURISCVState * env,int csrno,target_ulong * val)2547  static RISCVException read_mstateen(CPURISCVState *env, int csrno,
2548                                      target_ulong *val)
2549  {
2550      *val = env->mstateen[csrno - CSR_MSTATEEN0];
2551  
2552      return RISCV_EXCP_NONE;
2553  }
2554  
write_mstateen(CPURISCVState * env,int csrno,uint64_t wr_mask,target_ulong new_val)2555  static RISCVException write_mstateen(CPURISCVState *env, int csrno,
2556                                       uint64_t wr_mask, target_ulong new_val)
2557  {
2558      uint64_t *reg;
2559  
2560      reg = &env->mstateen[csrno - CSR_MSTATEEN0];
2561      *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2562  
2563      return RISCV_EXCP_NONE;
2564  }
2565  
write_mstateen0(CPURISCVState * env,int csrno,target_ulong new_val)2566  static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
2567                                        target_ulong new_val)
2568  {
2569      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2570      if (!riscv_has_ext(env, RVF)) {
2571          wr_mask |= SMSTATEEN0_FCSR;
2572      }
2573  
2574      if (env->priv_ver >= PRIV_VERSION_1_13_0) {
2575          wr_mask |= SMSTATEEN0_P1P13;
2576      }
2577  
2578      return write_mstateen(env, csrno, wr_mask, new_val);
2579  }
2580  
write_mstateen_1_3(CPURISCVState * env,int csrno,target_ulong new_val)2581  static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
2582                                           target_ulong new_val)
2583  {
2584      return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2585  }
2586  
read_mstateenh(CPURISCVState * env,int csrno,target_ulong * val)2587  static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
2588                                       target_ulong *val)
2589  {
2590      *val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
2591  
2592      return RISCV_EXCP_NONE;
2593  }
2594  
write_mstateenh(CPURISCVState * env,int csrno,uint64_t wr_mask,target_ulong new_val)2595  static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
2596                                        uint64_t wr_mask, target_ulong new_val)
2597  {
2598      uint64_t *reg, val;
2599  
2600      reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
2601      val = (uint64_t)new_val << 32;
2602      val |= *reg & 0xFFFFFFFF;
2603      *reg = (*reg & ~wr_mask) | (val & wr_mask);
2604  
2605      return RISCV_EXCP_NONE;
2606  }
2607  
write_mstateen0h(CPURISCVState * env,int csrno,target_ulong new_val)2608  static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
2609                                         target_ulong new_val)
2610  {
2611      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2612  
2613      if (env->priv_ver >= PRIV_VERSION_1_13_0) {
2614          wr_mask |= SMSTATEEN0_P1P13;
2615      }
2616  
2617      return write_mstateenh(env, csrno, wr_mask, new_val);
2618  }
2619  
write_mstateenh_1_3(CPURISCVState * env,int csrno,target_ulong new_val)2620  static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
2621                                            target_ulong new_val)
2622  {
2623      return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
2624  }
2625  
read_hstateen(CPURISCVState * env,int csrno,target_ulong * val)2626  static RISCVException read_hstateen(CPURISCVState *env, int csrno,
2627                                      target_ulong *val)
2628  {
2629      int index = csrno - CSR_HSTATEEN0;
2630  
2631      *val = env->hstateen[index] & env->mstateen[index];
2632  
2633      return RISCV_EXCP_NONE;
2634  }
2635  
write_hstateen(CPURISCVState * env,int csrno,uint64_t mask,target_ulong new_val)2636  static RISCVException write_hstateen(CPURISCVState *env, int csrno,
2637                                       uint64_t mask, target_ulong new_val)
2638  {
2639      int index = csrno - CSR_HSTATEEN0;
2640      uint64_t *reg, wr_mask;
2641  
2642      reg = &env->hstateen[index];
2643      wr_mask = env->mstateen[index] & mask;
2644      *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2645  
2646      return RISCV_EXCP_NONE;
2647  }
2648  
write_hstateen0(CPURISCVState * env,int csrno,target_ulong new_val)2649  static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
2650                                        target_ulong new_val)
2651  {
2652      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2653  
2654      if (!riscv_has_ext(env, RVF)) {
2655          wr_mask |= SMSTATEEN0_FCSR;
2656      }
2657  
2658      return write_hstateen(env, csrno, wr_mask, new_val);
2659  }
2660  
write_hstateen_1_3(CPURISCVState * env,int csrno,target_ulong new_val)2661  static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
2662                                           target_ulong new_val)
2663  {
2664      return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2665  }
2666  
read_hstateenh(CPURISCVState * env,int csrno,target_ulong * val)2667  static RISCVException read_hstateenh(CPURISCVState *env, int csrno,
2668                                       target_ulong *val)
2669  {
2670      int index = csrno - CSR_HSTATEEN0H;
2671  
2672      *val = (env->hstateen[index] >> 32) & (env->mstateen[index] >> 32);
2673  
2674      return RISCV_EXCP_NONE;
2675  }
2676  
write_hstateenh(CPURISCVState * env,int csrno,uint64_t mask,target_ulong new_val)2677  static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
2678                                        uint64_t mask, target_ulong new_val)
2679  {
2680      int index = csrno - CSR_HSTATEEN0H;
2681      uint64_t *reg, wr_mask, val;
2682  
2683      reg = &env->hstateen[index];
2684      val = (uint64_t)new_val << 32;
2685      val |= *reg & 0xFFFFFFFF;
2686      wr_mask = env->mstateen[index] & mask;
2687      *reg = (*reg & ~wr_mask) | (val & wr_mask);
2688  
2689      return RISCV_EXCP_NONE;
2690  }
2691  
write_hstateen0h(CPURISCVState * env,int csrno,target_ulong new_val)2692  static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
2693                                         target_ulong new_val)
2694  {
2695      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2696  
2697      return write_hstateenh(env, csrno, wr_mask, new_val);
2698  }
2699  
write_hstateenh_1_3(CPURISCVState * env,int csrno,target_ulong new_val)2700  static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
2701                                            target_ulong new_val)
2702  {
2703      return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
2704  }
2705  
read_sstateen(CPURISCVState * env,int csrno,target_ulong * val)2706  static RISCVException read_sstateen(CPURISCVState *env, int csrno,
2707                                      target_ulong *val)
2708  {
2709      bool virt = env->virt_enabled;
2710      int index = csrno - CSR_SSTATEEN0;
2711  
2712      *val = env->sstateen[index] & env->mstateen[index];
2713      if (virt) {
2714          *val &= env->hstateen[index];
2715      }
2716  
2717      return RISCV_EXCP_NONE;
2718  }
2719  
write_sstateen(CPURISCVState * env,int csrno,uint64_t mask,target_ulong new_val)2720  static RISCVException write_sstateen(CPURISCVState *env, int csrno,
2721                                       uint64_t mask, target_ulong new_val)
2722  {
2723      bool virt = env->virt_enabled;
2724      int index = csrno - CSR_SSTATEEN0;
2725      uint64_t wr_mask;
2726      uint64_t *reg;
2727  
2728      wr_mask = env->mstateen[index] & mask;
2729      if (virt) {
2730          wr_mask &= env->hstateen[index];
2731      }
2732  
2733      reg = &env->sstateen[index];
2734      *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2735  
2736      return RISCV_EXCP_NONE;
2737  }
2738  
write_sstateen0(CPURISCVState * env,int csrno,target_ulong new_val)2739  static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
2740                                        target_ulong new_val)
2741  {
2742      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2743  
2744      if (!riscv_has_ext(env, RVF)) {
2745          wr_mask |= SMSTATEEN0_FCSR;
2746      }
2747  
2748      return write_sstateen(env, csrno, wr_mask, new_val);
2749  }
2750  
write_sstateen_1_3(CPURISCVState * env,int csrno,target_ulong new_val)2751  static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
2752                                        target_ulong new_val)
2753  {
2754      return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2755  }
2756  
rmw_mip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)2757  static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
2758                                  uint64_t *ret_val,
2759                                  uint64_t new_val, uint64_t wr_mask)
2760  {
2761      uint64_t old_mip, mask = wr_mask & delegable_ints;
2762      uint32_t gin;
2763  
2764      if (mask & MIP_SEIP) {
2765          env->software_seip = new_val & MIP_SEIP;
2766          new_val |= env->external_seip * MIP_SEIP;
2767      }
2768  
2769      if (riscv_cpu_cfg(env)->ext_sstc && (env->priv == PRV_M) &&
2770          get_field(env->menvcfg, MENVCFG_STCE)) {
2771          /* sstc extension forbids STIP & VSTIP to be writeable in mip */
2772          mask = mask & ~(MIP_STIP | MIP_VSTIP);
2773      }
2774  
2775      if (mask) {
2776          old_mip = riscv_cpu_update_mip(env, mask, (new_val & mask));
2777      } else {
2778          old_mip = env->mip;
2779      }
2780  
2781      if (csrno != CSR_HVIP) {
2782          gin = get_field(env->hstatus, HSTATUS_VGEIN);
2783          old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
2784          old_mip |= env->vstime_irq ? MIP_VSTIP : 0;
2785      }
2786  
2787      if (ret_val) {
2788          *ret_val = old_mip;
2789      }
2790  
2791      return RISCV_EXCP_NONE;
2792  }
2793  
rmw_mip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)2794  static RISCVException rmw_mip(CPURISCVState *env, int csrno,
2795                                target_ulong *ret_val,
2796                                target_ulong new_val, target_ulong wr_mask)
2797  {
2798      uint64_t rval;
2799      RISCVException ret;
2800  
2801      ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
2802      if (ret_val) {
2803          *ret_val = rval;
2804      }
2805  
2806      return ret;
2807  }
2808  
rmw_miph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)2809  static RISCVException rmw_miph(CPURISCVState *env, int csrno,
2810                                 target_ulong *ret_val,
2811                                 target_ulong new_val, target_ulong wr_mask)
2812  {
2813      uint64_t rval;
2814      RISCVException ret;
2815  
2816      ret = rmw_mip64(env, csrno, &rval,
2817          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2818      if (ret_val) {
2819          *ret_val = rval >> 32;
2820      }
2821  
2822      return ret;
2823  }
2824  
2825  /*
2826   * The function is written for two use-cases:
2827   * 1- To access mvip csr as is for m-mode access.
2828   * 2- To access sip as a combination of mip and mvip for s-mode.
2829   *
2830   * Both report bits 1, 5, 9 and 13:63 but with the exception of
2831   * STIP being read-only zero in case of mvip when sstc extension
2832   * is present.
2833   * Also, sip needs to be read-only zero when both mideleg[i] and
2834   * mvien[i] are zero but mvip needs to be an alias of mip.
2835   */
rmw_mvip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)2836  static RISCVException rmw_mvip64(CPURISCVState *env, int csrno,
2837                                  uint64_t *ret_val,
2838                                  uint64_t new_val, uint64_t wr_mask)
2839  {
2840      RISCVCPU *cpu = env_archcpu(env);
2841      target_ulong ret_mip = 0;
2842      RISCVException ret;
2843      uint64_t old_mvip;
2844  
2845      /*
2846       * mideleg[i]  mvien[i]
2847       *   0           0      No delegation. mvip[i] is alias of mip[i].
2848       *   0           1      mvip[i] becomes source of interrupt, mip bypassed.
2849       *   1           X      mip[i] is source of interrupt and mvip[i] aliases
2850       *                      mip[i].
2851       *
2852       *   So alias condition would be for bits:
2853       *      ((S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & (mideleg | ~mvien)) |
2854       *          (!sstc & MIP_STIP)
2855       *
2856       *   Non-alias condition will be for bits:
2857       *      (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & (~mideleg & mvien)
2858       *
2859       *  alias_mask denotes the bits that come from mip nalias_mask denotes bits
2860       *  that come from hvip.
2861       */
2862      uint64_t alias_mask = ((S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) &
2863          (env->mideleg | ~env->mvien)) | MIP_STIP;
2864      uint64_t nalias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) &
2865          (~env->mideleg & env->mvien);
2866      uint64_t wr_mask_mvip;
2867      uint64_t wr_mask_mip;
2868  
2869      /*
2870       * mideleg[i]  mvien[i]
2871       *   0           0      sip[i] read-only zero.
2872       *   0           1      sip[i] alias of mvip[i].
2873       *   1           X      sip[i] alias of mip[i].
2874       *
2875       *  Both alias and non-alias mask remain same for sip except for bits
2876       *  which are zero in both mideleg and mvien.
2877       */
2878      if (csrno == CSR_SIP) {
2879          /* Remove bits that are zero in both mideleg and mvien. */
2880          alias_mask &= (env->mideleg | env->mvien);
2881          nalias_mask &= (env->mideleg | env->mvien);
2882      }
2883  
2884      /*
2885       * If sstc is present, mvip.STIP is not an alias of mip.STIP so clear
2886       * that our in mip returned value.
2887       */
2888      if (cpu->cfg.ext_sstc && (env->priv == PRV_M) &&
2889          get_field(env->menvcfg, MENVCFG_STCE)) {
2890          alias_mask &= ~MIP_STIP;
2891      }
2892  
2893      wr_mask_mip = wr_mask & alias_mask & mvip_writable_mask;
2894      wr_mask_mvip = wr_mask & nalias_mask & mvip_writable_mask;
2895  
2896      /*
2897       * For bits set in alias_mask, mvip needs to be alias of mip, so forward
2898       * this to rmw_mip.
2899       */
2900      ret = rmw_mip(env, CSR_MIP, &ret_mip, new_val, wr_mask_mip);
2901      if (ret != RISCV_EXCP_NONE) {
2902          return ret;
2903      }
2904  
2905      old_mvip = env->mvip;
2906  
2907      /*
2908       * Write to mvip. Update only non-alias bits. Alias bits were updated
2909       * in mip in rmw_mip above.
2910       */
2911      if (wr_mask_mvip) {
2912          env->mvip = (env->mvip & ~wr_mask_mvip) | (new_val & wr_mask_mvip);
2913  
2914          /*
2915           * Given mvip is separate source from mip, we need to trigger interrupt
2916           * from here separately. Normally this happen from riscv_cpu_update_mip.
2917           */
2918          riscv_cpu_interrupt(env);
2919      }
2920  
2921      if (ret_val) {
2922          ret_mip &= alias_mask;
2923          old_mvip &= nalias_mask;
2924  
2925          *ret_val = old_mvip | ret_mip;
2926      }
2927  
2928      return RISCV_EXCP_NONE;
2929  }
2930  
rmw_mvip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)2931  static RISCVException rmw_mvip(CPURISCVState *env, int csrno,
2932                                target_ulong *ret_val,
2933                                target_ulong new_val, target_ulong wr_mask)
2934  {
2935      uint64_t rval;
2936      RISCVException ret;
2937  
2938      ret = rmw_mvip64(env, csrno, &rval, new_val, wr_mask);
2939      if (ret_val) {
2940          *ret_val = rval;
2941      }
2942  
2943      return ret;
2944  }
2945  
rmw_mviph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)2946  static RISCVException rmw_mviph(CPURISCVState *env, int csrno,
2947                                 target_ulong *ret_val,
2948                                 target_ulong new_val, target_ulong wr_mask)
2949  {
2950      uint64_t rval;
2951      RISCVException ret;
2952  
2953      ret = rmw_mvip64(env, csrno, &rval,
2954          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2955      if (ret_val) {
2956          *ret_val = rval >> 32;
2957      }
2958  
2959      return ret;
2960  }
2961  
2962  /* Supervisor Trap Setup */
read_sstatus_i128(CPURISCVState * env,int csrno,Int128 * val)2963  static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
2964                                          Int128 *val)
2965  {
2966      uint64_t mask = sstatus_v1_10_mask;
2967      uint64_t sstatus = env->mstatus & mask;
2968      if (env->xl != MXL_RV32 || env->debugger) {
2969          mask |= SSTATUS64_UXL;
2970      }
2971  
2972      if (env_archcpu(env)->cfg.ext_zicfilp) {
2973          mask |= SSTATUS_SPELP;
2974      }
2975  
2976      *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
2977      return RISCV_EXCP_NONE;
2978  }
2979  
read_sstatus(CPURISCVState * env,int csrno,target_ulong * val)2980  static RISCVException read_sstatus(CPURISCVState *env, int csrno,
2981                                     target_ulong *val)
2982  {
2983      target_ulong mask = (sstatus_v1_10_mask);
2984      if (env->xl != MXL_RV32 || env->debugger) {
2985          mask |= SSTATUS64_UXL;
2986      }
2987  
2988      if (env_archcpu(env)->cfg.ext_zicfilp) {
2989          mask |= SSTATUS_SPELP;
2990      }
2991  
2992      /* TODO: Use SXL not MXL. */
2993      *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
2994      return RISCV_EXCP_NONE;
2995  }
2996  
write_sstatus(CPURISCVState * env,int csrno,target_ulong val)2997  static RISCVException write_sstatus(CPURISCVState *env, int csrno,
2998                                      target_ulong val)
2999  {
3000      target_ulong mask = (sstatus_v1_10_mask);
3001  
3002      if (env->xl != MXL_RV32 || env->debugger) {
3003          if ((val & SSTATUS64_UXL) != 0) {
3004              mask |= SSTATUS64_UXL;
3005          }
3006      }
3007  
3008      if (env_archcpu(env)->cfg.ext_zicfilp) {
3009          mask |= SSTATUS_SPELP;
3010      }
3011  
3012      target_ulong newval = (env->mstatus & ~mask) | (val & mask);
3013      return write_mstatus(env, CSR_MSTATUS, newval);
3014  }
3015  
rmw_vsie64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3016  static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
3017                                   uint64_t *ret_val,
3018                                   uint64_t new_val, uint64_t wr_mask)
3019  {
3020      uint64_t alias_mask = (LOCAL_INTERRUPTS | VS_MODE_INTERRUPTS) &
3021                              env->hideleg;
3022      uint64_t nalias_mask = LOCAL_INTERRUPTS & (~env->hideleg & env->hvien);
3023      uint64_t rval, rval_vs, vsbits;
3024      uint64_t wr_mask_vsie;
3025      uint64_t wr_mask_mie;
3026      RISCVException ret;
3027  
3028      /* Bring VS-level bits to correct position */
3029      vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
3030      new_val &= ~(VS_MODE_INTERRUPTS >> 1);
3031      new_val |= vsbits << 1;
3032  
3033      vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
3034      wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
3035      wr_mask |= vsbits << 1;
3036  
3037      wr_mask_mie = wr_mask & alias_mask;
3038      wr_mask_vsie = wr_mask & nalias_mask;
3039  
3040      ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask_mie);
3041  
3042      rval_vs = env->vsie & nalias_mask;
3043      env->vsie = (env->vsie & ~wr_mask_vsie) | (new_val & wr_mask_vsie);
3044  
3045      if (ret_val) {
3046          rval &= alias_mask;
3047          vsbits = rval & VS_MODE_INTERRUPTS;
3048          rval &= ~VS_MODE_INTERRUPTS;
3049          *ret_val = rval | (vsbits >> 1) | rval_vs;
3050      }
3051  
3052      return ret;
3053  }
3054  
rmw_vsie(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3055  static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
3056                                 target_ulong *ret_val,
3057                                 target_ulong new_val, target_ulong wr_mask)
3058  {
3059      uint64_t rval;
3060      RISCVException ret;
3061  
3062      ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
3063      if (ret_val) {
3064          *ret_val = rval;
3065      }
3066  
3067      return ret;
3068  }
3069  
rmw_vsieh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3070  static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
3071                                  target_ulong *ret_val,
3072                                  target_ulong new_val, target_ulong wr_mask)
3073  {
3074      uint64_t rval;
3075      RISCVException ret;
3076  
3077      ret = rmw_vsie64(env, csrno, &rval,
3078          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3079      if (ret_val) {
3080          *ret_val = rval >> 32;
3081      }
3082  
3083      return ret;
3084  }
3085  
rmw_sie64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3086  static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
3087                                  uint64_t *ret_val,
3088                                  uint64_t new_val, uint64_t wr_mask)
3089  {
3090      uint64_t nalias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) &
3091          (~env->mideleg & env->mvien);
3092      uint64_t alias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & env->mideleg;
3093      uint64_t sie_mask = wr_mask & nalias_mask;
3094      RISCVException ret;
3095  
3096      /*
3097       * mideleg[i]  mvien[i]
3098       *   0           0      sie[i] read-only zero.
3099       *   0           1      sie[i] is a separate writable bit.
3100       *   1           X      sie[i] alias of mie[i].
3101       *
3102       *  Both alias and non-alias mask remain same for sip except for bits
3103       *  which are zero in both mideleg and mvien.
3104       */
3105      if (env->virt_enabled) {
3106          if (env->hvictl & HVICTL_VTI) {
3107              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
3108          }
3109          ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
3110          if (ret_val) {
3111              *ret_val &= alias_mask;
3112          }
3113      } else {
3114          ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & alias_mask);
3115          if (ret_val) {
3116              *ret_val &= alias_mask;
3117              *ret_val |= env->sie & nalias_mask;
3118          }
3119  
3120          env->sie = (env->sie & ~sie_mask) | (new_val & sie_mask);
3121      }
3122  
3123      return ret;
3124  }
3125  
rmw_sie(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3126  static RISCVException rmw_sie(CPURISCVState *env, int csrno,
3127                                target_ulong *ret_val,
3128                                target_ulong new_val, target_ulong wr_mask)
3129  {
3130      uint64_t rval;
3131      RISCVException ret;
3132  
3133      ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
3134      if (ret == RISCV_EXCP_NONE && ret_val) {
3135          *ret_val = rval;
3136      }
3137  
3138      return ret;
3139  }
3140  
rmw_sieh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3141  static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
3142                                 target_ulong *ret_val,
3143                                 target_ulong new_val, target_ulong wr_mask)
3144  {
3145      uint64_t rval;
3146      RISCVException ret;
3147  
3148      ret = rmw_sie64(env, csrno, &rval,
3149          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3150      if (ret_val) {
3151          *ret_val = rval >> 32;
3152      }
3153  
3154      return ret;
3155  }
3156  
read_stvec(CPURISCVState * env,int csrno,target_ulong * val)3157  static RISCVException read_stvec(CPURISCVState *env, int csrno,
3158                                   target_ulong *val)
3159  {
3160      *val = env->stvec;
3161      return RISCV_EXCP_NONE;
3162  }
3163  
write_stvec(CPURISCVState * env,int csrno,target_ulong val)3164  static RISCVException write_stvec(CPURISCVState *env, int csrno,
3165                                    target_ulong val)
3166  {
3167      /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
3168      if ((val & 3) < 2) {
3169          env->stvec = val;
3170      } else {
3171          qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
3172      }
3173      return RISCV_EXCP_NONE;
3174  }
3175  
read_scounteren(CPURISCVState * env,int csrno,target_ulong * val)3176  static RISCVException read_scounteren(CPURISCVState *env, int csrno,
3177                                        target_ulong *val)
3178  {
3179      *val = env->scounteren;
3180      return RISCV_EXCP_NONE;
3181  }
3182  
write_scounteren(CPURISCVState * env,int csrno,target_ulong val)3183  static RISCVException write_scounteren(CPURISCVState *env, int csrno,
3184                                         target_ulong val)
3185  {
3186      RISCVCPU *cpu = env_archcpu(env);
3187  
3188      /* WARL register - disable unavailable counters */
3189      env->scounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
3190                               COUNTEREN_IR);
3191      return RISCV_EXCP_NONE;
3192  }
3193  
3194  /* Supervisor Trap Handling */
read_sscratch_i128(CPURISCVState * env,int csrno,Int128 * val)3195  static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
3196                                           Int128 *val)
3197  {
3198      *val = int128_make128(env->sscratch, env->sscratchh);
3199      return RISCV_EXCP_NONE;
3200  }
3201  
write_sscratch_i128(CPURISCVState * env,int csrno,Int128 val)3202  static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
3203                                            Int128 val)
3204  {
3205      env->sscratch = int128_getlo(val);
3206      env->sscratchh = int128_gethi(val);
3207      return RISCV_EXCP_NONE;
3208  }
3209  
read_sscratch(CPURISCVState * env,int csrno,target_ulong * val)3210  static RISCVException read_sscratch(CPURISCVState *env, int csrno,
3211                                      target_ulong *val)
3212  {
3213      *val = env->sscratch;
3214      return RISCV_EXCP_NONE;
3215  }
3216  
write_sscratch(CPURISCVState * env,int csrno,target_ulong val)3217  static RISCVException write_sscratch(CPURISCVState *env, int csrno,
3218                                       target_ulong val)
3219  {
3220      env->sscratch = val;
3221      return RISCV_EXCP_NONE;
3222  }
3223  
read_sepc(CPURISCVState * env,int csrno,target_ulong * val)3224  static RISCVException read_sepc(CPURISCVState *env, int csrno,
3225                                  target_ulong *val)
3226  {
3227      *val = env->sepc;
3228      return RISCV_EXCP_NONE;
3229  }
3230  
write_sepc(CPURISCVState * env,int csrno,target_ulong val)3231  static RISCVException write_sepc(CPURISCVState *env, int csrno,
3232                                   target_ulong val)
3233  {
3234      env->sepc = val;
3235      return RISCV_EXCP_NONE;
3236  }
3237  
read_scause(CPURISCVState * env,int csrno,target_ulong * val)3238  static RISCVException read_scause(CPURISCVState *env, int csrno,
3239                                    target_ulong *val)
3240  {
3241      *val = env->scause;
3242      return RISCV_EXCP_NONE;
3243  }
3244  
write_scause(CPURISCVState * env,int csrno,target_ulong val)3245  static RISCVException write_scause(CPURISCVState *env, int csrno,
3246                                     target_ulong val)
3247  {
3248      env->scause = val;
3249      return RISCV_EXCP_NONE;
3250  }
3251  
read_stval(CPURISCVState * env,int csrno,target_ulong * val)3252  static RISCVException read_stval(CPURISCVState *env, int csrno,
3253                                   target_ulong *val)
3254  {
3255      *val = env->stval;
3256      return RISCV_EXCP_NONE;
3257  }
3258  
write_stval(CPURISCVState * env,int csrno,target_ulong val)3259  static RISCVException write_stval(CPURISCVState *env, int csrno,
3260                                    target_ulong val)
3261  {
3262      env->stval = val;
3263      return RISCV_EXCP_NONE;
3264  }
3265  
3266  static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
3267                                   uint64_t *ret_val,
3268                                   uint64_t new_val, uint64_t wr_mask);
3269  
rmw_vsip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3270  static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
3271                                   uint64_t *ret_val,
3272                                   uint64_t new_val, uint64_t wr_mask)
3273  {
3274      RISCVException ret;
3275      uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
3276      uint64_t vsbits;
3277  
3278      /* Add virtualized bits into vsip mask. */
3279      mask |= env->hvien & ~env->hideleg;
3280  
3281      /* Bring VS-level bits to correct position */
3282      vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
3283      new_val &= ~(VS_MODE_INTERRUPTS >> 1);
3284      new_val |= vsbits << 1;
3285      vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
3286      wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
3287      wr_mask |= vsbits << 1;
3288  
3289      ret = rmw_hvip64(env, csrno, &rval, new_val,
3290                       wr_mask & mask & vsip_writable_mask);
3291      if (ret_val) {
3292          rval &= mask;
3293          vsbits = rval & VS_MODE_INTERRUPTS;
3294          rval &= ~VS_MODE_INTERRUPTS;
3295          *ret_val = rval | (vsbits >> 1);
3296      }
3297  
3298      return ret;
3299  }
3300  
rmw_vsip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3301  static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
3302                                 target_ulong *ret_val,
3303                                 target_ulong new_val, target_ulong wr_mask)
3304  {
3305      uint64_t rval;
3306      RISCVException ret;
3307  
3308      ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
3309      if (ret_val) {
3310          *ret_val = rval;
3311      }
3312  
3313      return ret;
3314  }
3315  
rmw_vsiph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3316  static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
3317                                  target_ulong *ret_val,
3318                                  target_ulong new_val, target_ulong wr_mask)
3319  {
3320      uint64_t rval;
3321      RISCVException ret;
3322  
3323      ret = rmw_vsip64(env, csrno, &rval,
3324          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3325      if (ret_val) {
3326          *ret_val = rval >> 32;
3327      }
3328  
3329      return ret;
3330  }
3331  
rmw_sip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3332  static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
3333                                  uint64_t *ret_val,
3334                                  uint64_t new_val, uint64_t wr_mask)
3335  {
3336      RISCVException ret;
3337      uint64_t mask = (env->mideleg | env->mvien) & sip_writable_mask;
3338  
3339      if (env->virt_enabled) {
3340          if (env->hvictl & HVICTL_VTI) {
3341              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
3342          }
3343          ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
3344      } else {
3345          ret = rmw_mvip64(env, csrno, ret_val, new_val, wr_mask & mask);
3346      }
3347  
3348      if (ret_val) {
3349          *ret_val &= (env->mideleg | env->mvien) &
3350              (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS);
3351      }
3352  
3353      return ret;
3354  }
3355  
rmw_sip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3356  static RISCVException rmw_sip(CPURISCVState *env, int csrno,
3357                                target_ulong *ret_val,
3358                                target_ulong new_val, target_ulong wr_mask)
3359  {
3360      uint64_t rval;
3361      RISCVException ret;
3362  
3363      ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
3364      if (ret_val) {
3365          *ret_val = rval;
3366      }
3367  
3368      return ret;
3369  }
3370  
rmw_siph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3371  static RISCVException rmw_siph(CPURISCVState *env, int csrno,
3372                                 target_ulong *ret_val,
3373                                 target_ulong new_val, target_ulong wr_mask)
3374  {
3375      uint64_t rval;
3376      RISCVException ret;
3377  
3378      ret = rmw_sip64(env, csrno, &rval,
3379          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3380      if (ret_val) {
3381          *ret_val = rval >> 32;
3382      }
3383  
3384      return ret;
3385  }
3386  
3387  /* Supervisor Protection and Translation */
read_satp(CPURISCVState * env,int csrno,target_ulong * val)3388  static RISCVException read_satp(CPURISCVState *env, int csrno,
3389                                  target_ulong *val)
3390  {
3391      if (!riscv_cpu_cfg(env)->mmu) {
3392          *val = 0;
3393          return RISCV_EXCP_NONE;
3394      }
3395      *val = env->satp;
3396      return RISCV_EXCP_NONE;
3397  }
3398  
write_satp(CPURISCVState * env,int csrno,target_ulong val)3399  static RISCVException write_satp(CPURISCVState *env, int csrno,
3400                                   target_ulong val)
3401  {
3402      if (!riscv_cpu_cfg(env)->mmu) {
3403          return RISCV_EXCP_NONE;
3404      }
3405  
3406      env->satp = legalize_xatp(env, env->satp, val);
3407      return RISCV_EXCP_NONE;
3408  }
3409  
read_vstopi(CPURISCVState * env,int csrno,target_ulong * val)3410  static RISCVException read_vstopi(CPURISCVState *env, int csrno,
3411                                    target_ulong *val)
3412  {
3413      int irq, ret;
3414      target_ulong topei;
3415      uint64_t vseip, vsgein;
3416      uint32_t iid, iprio, hviid, hviprio, gein;
3417      uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS];
3418  
3419      gein = get_field(env->hstatus, HSTATUS_VGEIN);
3420      hviid = get_field(env->hvictl, HVICTL_IID);
3421      hviprio = get_field(env->hvictl, HVICTL_IPRIO);
3422  
3423      if (gein) {
3424          vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
3425          vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP;
3426          if (gein <= env->geilen && vseip) {
3427              siid[scount] = IRQ_S_EXT;
3428              siprio[scount] = IPRIO_MMAXIPRIO + 1;
3429              if (env->aia_ireg_rmw_fn[PRV_S]) {
3430                  /*
3431                   * Call machine specific IMSIC register emulation for
3432                   * reading TOPEI.
3433                   */
3434                  ret = env->aia_ireg_rmw_fn[PRV_S](
3435                          env->aia_ireg_rmw_fn_arg[PRV_S],
3436                          AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein,
3437                                        riscv_cpu_mxl_bits(env)),
3438                          &topei, 0, 0);
3439                  if (!ret && topei) {
3440                      siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK;
3441                  }
3442              }
3443              scount++;
3444          }
3445      } else {
3446          if (hviid == IRQ_S_EXT && hviprio) {
3447              siid[scount] = IRQ_S_EXT;
3448              siprio[scount] = hviprio;
3449              scount++;
3450          }
3451      }
3452  
3453      if (env->hvictl & HVICTL_VTI) {
3454          if (hviid != IRQ_S_EXT) {
3455              siid[scount] = hviid;
3456              siprio[scount] = hviprio;
3457              scount++;
3458          }
3459      } else {
3460          irq = riscv_cpu_vsirq_pending(env);
3461          if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) {
3462              siid[scount] = irq;
3463              siprio[scount] = env->hviprio[irq];
3464              scount++;
3465          }
3466      }
3467  
3468      iid = 0;
3469      iprio = UINT_MAX;
3470      for (s = 0; s < scount; s++) {
3471          if (siprio[s] < iprio) {
3472              iid = siid[s];
3473              iprio = siprio[s];
3474          }
3475      }
3476  
3477      if (iid) {
3478          if (env->hvictl & HVICTL_IPRIOM) {
3479              if (iprio > IPRIO_MMAXIPRIO) {
3480                  iprio = IPRIO_MMAXIPRIO;
3481              }
3482              if (!iprio) {
3483                  if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) {
3484                      iprio = IPRIO_MMAXIPRIO;
3485                  }
3486              }
3487          } else {
3488              iprio = 1;
3489          }
3490      } else {
3491          iprio = 0;
3492      }
3493  
3494      *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT;
3495      *val |= iprio;
3496  
3497      return RISCV_EXCP_NONE;
3498  }
3499  
read_stopi(CPURISCVState * env,int csrno,target_ulong * val)3500  static RISCVException read_stopi(CPURISCVState *env, int csrno,
3501                                   target_ulong *val)
3502  {
3503      int irq;
3504      uint8_t iprio;
3505  
3506      if (env->virt_enabled) {
3507          return read_vstopi(env, CSR_VSTOPI, val);
3508      }
3509  
3510      irq = riscv_cpu_sirq_pending(env);
3511      if (irq <= 0 || irq > 63) {
3512          *val = 0;
3513      } else {
3514          iprio = env->siprio[irq];
3515          if (!iprio) {
3516              if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) {
3517                  iprio = IPRIO_MMAXIPRIO;
3518             }
3519          }
3520          *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
3521          *val |= iprio;
3522      }
3523  
3524      return RISCV_EXCP_NONE;
3525  }
3526  
3527  /* Hypervisor Extensions */
read_hstatus(CPURISCVState * env,int csrno,target_ulong * val)3528  static RISCVException read_hstatus(CPURISCVState *env, int csrno,
3529                                     target_ulong *val)
3530  {
3531      *val = env->hstatus;
3532      if (riscv_cpu_mxl(env) != MXL_RV32) {
3533          /* We only support 64-bit VSXL */
3534          *val = set_field(*val, HSTATUS_VSXL, 2);
3535      }
3536      /* We only support little endian */
3537      *val = set_field(*val, HSTATUS_VSBE, 0);
3538      return RISCV_EXCP_NONE;
3539  }
3540  
write_hstatus(CPURISCVState * env,int csrno,target_ulong val)3541  static RISCVException write_hstatus(CPURISCVState *env, int csrno,
3542                                      target_ulong val)
3543  {
3544      env->hstatus = val;
3545      if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
3546          qemu_log_mask(LOG_UNIMP,
3547                        "QEMU does not support mixed HSXLEN options.");
3548      }
3549      if (get_field(val, HSTATUS_VSBE) != 0) {
3550          qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
3551      }
3552      return RISCV_EXCP_NONE;
3553  }
3554  
read_hedeleg(CPURISCVState * env,int csrno,target_ulong * val)3555  static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
3556                                     target_ulong *val)
3557  {
3558      *val = env->hedeleg;
3559      return RISCV_EXCP_NONE;
3560  }
3561  
write_hedeleg(CPURISCVState * env,int csrno,target_ulong val)3562  static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
3563                                      target_ulong val)
3564  {
3565      env->hedeleg = val & vs_delegable_excps;
3566      return RISCV_EXCP_NONE;
3567  }
3568  
read_hedelegh(CPURISCVState * env,int csrno,target_ulong * val)3569  static RISCVException read_hedelegh(CPURISCVState *env, int csrno,
3570                                     target_ulong *val)
3571  {
3572      RISCVException ret;
3573      ret = smstateen_acc_ok(env, 0, SMSTATEEN0_P1P13);
3574      if (ret != RISCV_EXCP_NONE) {
3575          return ret;
3576      }
3577  
3578      /* Reserved, now read zero */
3579      *val = 0;
3580      return RISCV_EXCP_NONE;
3581  }
3582  
write_hedelegh(CPURISCVState * env,int csrno,target_ulong val)3583  static RISCVException write_hedelegh(CPURISCVState *env, int csrno,
3584                                      target_ulong val)
3585  {
3586      RISCVException ret;
3587      ret = smstateen_acc_ok(env, 0, SMSTATEEN0_P1P13);
3588      if (ret != RISCV_EXCP_NONE) {
3589          return ret;
3590      }
3591  
3592      /* Reserved, now write ignore */
3593      return RISCV_EXCP_NONE;
3594  }
3595  
rmw_hvien64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3596  static RISCVException rmw_hvien64(CPURISCVState *env, int csrno,
3597                                      uint64_t *ret_val,
3598                                      uint64_t new_val, uint64_t wr_mask)
3599  {
3600      uint64_t mask = wr_mask & hvien_writable_mask;
3601  
3602      if (ret_val) {
3603          *ret_val = env->hvien;
3604      }
3605  
3606      env->hvien = (env->hvien & ~mask) | (new_val & mask);
3607  
3608      return RISCV_EXCP_NONE;
3609  }
3610  
rmw_hvien(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3611  static RISCVException rmw_hvien(CPURISCVState *env, int csrno,
3612                                 target_ulong *ret_val,
3613                                 target_ulong new_val, target_ulong wr_mask)
3614  {
3615      uint64_t rval;
3616      RISCVException ret;
3617  
3618      ret = rmw_hvien64(env, csrno, &rval, new_val, wr_mask);
3619      if (ret_val) {
3620          *ret_val = rval;
3621      }
3622  
3623      return ret;
3624  }
3625  
rmw_hvienh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3626  static RISCVException rmw_hvienh(CPURISCVState *env, int csrno,
3627                                     target_ulong *ret_val,
3628                                     target_ulong new_val, target_ulong wr_mask)
3629  {
3630      uint64_t rval;
3631      RISCVException ret;
3632  
3633      ret = rmw_hvien64(env, csrno, &rval,
3634          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3635      if (ret_val) {
3636          *ret_val = rval >> 32;
3637      }
3638  
3639      return ret;
3640  }
3641  
rmw_hideleg64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3642  static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
3643                                      uint64_t *ret_val,
3644                                      uint64_t new_val, uint64_t wr_mask)
3645  {
3646      uint64_t mask = wr_mask & vs_delegable_ints;
3647  
3648      if (ret_val) {
3649          *ret_val = env->hideleg & vs_delegable_ints;
3650      }
3651  
3652      env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
3653      return RISCV_EXCP_NONE;
3654  }
3655  
rmw_hideleg(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3656  static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
3657                                    target_ulong *ret_val,
3658                                    target_ulong new_val, target_ulong wr_mask)
3659  {
3660      uint64_t rval;
3661      RISCVException ret;
3662  
3663      ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
3664      if (ret_val) {
3665          *ret_val = rval;
3666      }
3667  
3668      return ret;
3669  }
3670  
rmw_hidelegh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3671  static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
3672                                     target_ulong *ret_val,
3673                                     target_ulong new_val, target_ulong wr_mask)
3674  {
3675      uint64_t rval;
3676      RISCVException ret;
3677  
3678      ret = rmw_hideleg64(env, csrno, &rval,
3679          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3680      if (ret_val) {
3681          *ret_val = rval >> 32;
3682      }
3683  
3684      return ret;
3685  }
3686  
3687  /*
3688   * The function is written for two use-cases:
3689   * 1- To access hvip csr as is for HS-mode access.
3690   * 2- To access vsip as a combination of hvip, and mip for vs-mode.
3691   *
3692   * Both report bits 2, 6, 10 and 13:63.
3693   * vsip needs to be read-only zero when both hideleg[i] and
3694   * hvien[i] are zero.
3695   */
rmw_hvip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3696  static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
3697                                   uint64_t *ret_val,
3698                                   uint64_t new_val, uint64_t wr_mask)
3699  {
3700      RISCVException ret;
3701      uint64_t old_hvip;
3702      uint64_t ret_mip;
3703  
3704      /*
3705       * For bits 10, 6 and 2, vsip[i] is an alias of hip[i]. These bits are
3706       * present in hip, hvip and mip. Where mip[i] is alias of hip[i] and hvip[i]
3707       * is OR'ed in hip[i] to inject virtual interrupts from hypervisor. These
3708       * bits are actually being maintained in mip so we read them from there.
3709       * This way we have a single source of truth and allows for easier
3710       * implementation.
3711       *
3712       * For bits 13:63 we have:
3713       *
3714       * hideleg[i]  hvien[i]
3715       *   0           0      No delegation. vsip[i] readonly zero.
3716       *   0           1      vsip[i] is alias of hvip[i], sip bypassed.
3717       *   1           X      vsip[i] is alias of sip[i], hvip bypassed.
3718       *
3719       *  alias_mask denotes the bits that come from sip (mip here given we
3720       *  maintain all bits there). nalias_mask denotes bits that come from
3721       *  hvip.
3722       */
3723      uint64_t alias_mask = (env->hideleg | ~env->hvien) | VS_MODE_INTERRUPTS;
3724      uint64_t nalias_mask = (~env->hideleg & env->hvien);
3725      uint64_t wr_mask_hvip;
3726      uint64_t wr_mask_mip;
3727  
3728      /*
3729       * Both alias and non-alias mask remain same for vsip except:
3730       *  1- For VS* bits if they are zero in hideleg.
3731       *  2- For 13:63 bits if they are zero in both hideleg and hvien.
3732       */
3733      if (csrno == CSR_VSIP) {
3734          /* zero-out VS* bits that are not delegated to VS mode. */
3735          alias_mask &= (env->hideleg | ~VS_MODE_INTERRUPTS);
3736  
3737          /*
3738           * zero-out 13:63 bits that are zero in both hideleg and hvien.
3739           * nalias_mask mask can not contain any VS* bits so only second
3740           * condition applies on it.
3741           */
3742          nalias_mask &= (env->hideleg | env->hvien);
3743          alias_mask &= (env->hideleg | env->hvien);
3744      }
3745  
3746      wr_mask_hvip = wr_mask & nalias_mask & hvip_writable_mask;
3747      wr_mask_mip = wr_mask & alias_mask & hvip_writable_mask;
3748  
3749      /* Aliased bits, bits 10, 6, 2 need to come from mip. */
3750      ret = rmw_mip64(env, csrno, &ret_mip, new_val, wr_mask_mip);
3751      if (ret != RISCV_EXCP_NONE) {
3752          return ret;
3753      }
3754  
3755      old_hvip = env->hvip;
3756  
3757      if (wr_mask_hvip) {
3758          env->hvip = (env->hvip & ~wr_mask_hvip) | (new_val & wr_mask_hvip);
3759  
3760          /*
3761           * Given hvip is separate source from mip, we need to trigger interrupt
3762           * from here separately. Normally this happen from riscv_cpu_update_mip.
3763           */
3764          riscv_cpu_interrupt(env);
3765      }
3766  
3767      if (ret_val) {
3768          /* Only take VS* bits from mip. */
3769          ret_mip &= alias_mask;
3770  
3771          /* Take in non-delegated 13:63 bits from hvip. */
3772          old_hvip &= nalias_mask;
3773  
3774          *ret_val = ret_mip | old_hvip;
3775      }
3776  
3777      return ret;
3778  }
3779  
rmw_hvip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3780  static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
3781                                 target_ulong *ret_val,
3782                                 target_ulong new_val, target_ulong wr_mask)
3783  {
3784      uint64_t rval;
3785      RISCVException ret;
3786  
3787      ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
3788      if (ret_val) {
3789          *ret_val = rval;
3790      }
3791  
3792      return ret;
3793  }
3794  
rmw_hviph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3795  static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
3796                                  target_ulong *ret_val,
3797                                  target_ulong new_val, target_ulong wr_mask)
3798  {
3799      uint64_t rval;
3800      RISCVException ret;
3801  
3802      ret = rmw_hvip64(env, csrno, &rval,
3803          ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3804      if (ret_val) {
3805          *ret_val = rval >> 32;
3806      }
3807  
3808      return ret;
3809  }
3810  
rmw_hip(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)3811  static RISCVException rmw_hip(CPURISCVState *env, int csrno,
3812                                target_ulong *ret_value,
3813                                target_ulong new_value, target_ulong write_mask)
3814  {
3815      int ret = rmw_mip(env, csrno, ret_value, new_value,
3816                        write_mask & hip_writable_mask);
3817  
3818      if (ret_value) {
3819          *ret_value &= HS_MODE_INTERRUPTS;
3820      }
3821      return ret;
3822  }
3823  
rmw_hie(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3824  static RISCVException rmw_hie(CPURISCVState *env, int csrno,
3825                                target_ulong *ret_val,
3826                                target_ulong new_val, target_ulong wr_mask)
3827  {
3828      uint64_t rval;
3829      RISCVException ret;
3830  
3831      ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
3832      if (ret_val) {
3833          *ret_val = rval & HS_MODE_INTERRUPTS;
3834      }
3835  
3836      return ret;
3837  }
3838  
read_hcounteren(CPURISCVState * env,int csrno,target_ulong * val)3839  static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
3840                                        target_ulong *val)
3841  {
3842      *val = env->hcounteren;
3843      return RISCV_EXCP_NONE;
3844  }
3845  
write_hcounteren(CPURISCVState * env,int csrno,target_ulong val)3846  static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
3847                                         target_ulong val)
3848  {
3849      RISCVCPU *cpu = env_archcpu(env);
3850  
3851      /* WARL register - disable unavailable counters */
3852      env->hcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
3853                               COUNTEREN_IR);
3854      return RISCV_EXCP_NONE;
3855  }
3856  
read_hgeie(CPURISCVState * env,int csrno,target_ulong * val)3857  static RISCVException read_hgeie(CPURISCVState *env, int csrno,
3858                                   target_ulong *val)
3859  {
3860      if (val) {
3861          *val = env->hgeie;
3862      }
3863      return RISCV_EXCP_NONE;
3864  }
3865  
write_hgeie(CPURISCVState * env,int csrno,target_ulong val)3866  static RISCVException write_hgeie(CPURISCVState *env, int csrno,
3867                                    target_ulong val)
3868  {
3869      /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
3870      val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
3871      env->hgeie = val;
3872      /* Update mip.SGEIP bit */
3873      riscv_cpu_update_mip(env, MIP_SGEIP,
3874                           BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
3875      return RISCV_EXCP_NONE;
3876  }
3877  
read_htval(CPURISCVState * env,int csrno,target_ulong * val)3878  static RISCVException read_htval(CPURISCVState *env, int csrno,
3879                                   target_ulong *val)
3880  {
3881      *val = env->htval;
3882      return RISCV_EXCP_NONE;
3883  }
3884  
write_htval(CPURISCVState * env,int csrno,target_ulong val)3885  static RISCVException write_htval(CPURISCVState *env, int csrno,
3886                                    target_ulong val)
3887  {
3888      env->htval = val;
3889      return RISCV_EXCP_NONE;
3890  }
3891  
read_htinst(CPURISCVState * env,int csrno,target_ulong * val)3892  static RISCVException read_htinst(CPURISCVState *env, int csrno,
3893                                    target_ulong *val)
3894  {
3895      *val = env->htinst;
3896      return RISCV_EXCP_NONE;
3897  }
3898  
write_htinst(CPURISCVState * env,int csrno,target_ulong val)3899  static RISCVException write_htinst(CPURISCVState *env, int csrno,
3900                                     target_ulong val)
3901  {
3902      return RISCV_EXCP_NONE;
3903  }
3904  
read_hgeip(CPURISCVState * env,int csrno,target_ulong * val)3905  static RISCVException read_hgeip(CPURISCVState *env, int csrno,
3906                                   target_ulong *val)
3907  {
3908      if (val) {
3909          *val = env->hgeip;
3910      }
3911      return RISCV_EXCP_NONE;
3912  }
3913  
read_hgatp(CPURISCVState * env,int csrno,target_ulong * val)3914  static RISCVException read_hgatp(CPURISCVState *env, int csrno,
3915                                   target_ulong *val)
3916  {
3917      *val = env->hgatp;
3918      return RISCV_EXCP_NONE;
3919  }
3920  
write_hgatp(CPURISCVState * env,int csrno,target_ulong val)3921  static RISCVException write_hgatp(CPURISCVState *env, int csrno,
3922                                    target_ulong val)
3923  {
3924      env->hgatp = legalize_xatp(env, env->hgatp, val);
3925      return RISCV_EXCP_NONE;
3926  }
3927  
read_htimedelta(CPURISCVState * env,int csrno,target_ulong * val)3928  static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
3929                                        target_ulong *val)
3930  {
3931      if (!env->rdtime_fn) {
3932          return RISCV_EXCP_ILLEGAL_INST;
3933      }
3934  
3935      *val = env->htimedelta;
3936      return RISCV_EXCP_NONE;
3937  }
3938  
write_htimedelta(CPURISCVState * env,int csrno,target_ulong val)3939  static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
3940                                         target_ulong val)
3941  {
3942      if (!env->rdtime_fn) {
3943          return RISCV_EXCP_ILLEGAL_INST;
3944      }
3945  
3946      if (riscv_cpu_mxl(env) == MXL_RV32) {
3947          env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
3948      } else {
3949          env->htimedelta = val;
3950      }
3951  
3952      if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
3953          riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
3954                                    env->htimedelta, MIP_VSTIP);
3955      }
3956  
3957      return RISCV_EXCP_NONE;
3958  }
3959  
read_htimedeltah(CPURISCVState * env,int csrno,target_ulong * val)3960  static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
3961                                         target_ulong *val)
3962  {
3963      if (!env->rdtime_fn) {
3964          return RISCV_EXCP_ILLEGAL_INST;
3965      }
3966  
3967      *val = env->htimedelta >> 32;
3968      return RISCV_EXCP_NONE;
3969  }
3970  
write_htimedeltah(CPURISCVState * env,int csrno,target_ulong val)3971  static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
3972                                          target_ulong val)
3973  {
3974      if (!env->rdtime_fn) {
3975          return RISCV_EXCP_ILLEGAL_INST;
3976      }
3977  
3978      env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
3979  
3980      if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
3981          riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
3982                                    env->htimedelta, MIP_VSTIP);
3983      }
3984  
3985      return RISCV_EXCP_NONE;
3986  }
3987  
read_hvictl(CPURISCVState * env,int csrno,target_ulong * val)3988  static RISCVException read_hvictl(CPURISCVState *env, int csrno,
3989                                    target_ulong *val)
3990  {
3991      *val = env->hvictl;
3992      return RISCV_EXCP_NONE;
3993  }
3994  
write_hvictl(CPURISCVState * env,int csrno,target_ulong val)3995  static RISCVException write_hvictl(CPURISCVState *env, int csrno,
3996                                     target_ulong val)
3997  {
3998      env->hvictl = val & HVICTL_VALID_MASK;
3999      return RISCV_EXCP_NONE;
4000  }
4001  
read_hvipriox(CPURISCVState * env,int first_index,uint8_t * iprio,target_ulong * val)4002  static RISCVException read_hvipriox(CPURISCVState *env, int first_index,
4003                           uint8_t *iprio, target_ulong *val)
4004  {
4005      int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
4006  
4007      /* First index has to be a multiple of number of irqs per register */
4008      if (first_index % num_irqs) {
4009          return (env->virt_enabled) ?
4010                 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
4011      }
4012  
4013      /* Fill-up return value */
4014      *val = 0;
4015      for (i = 0; i < num_irqs; i++) {
4016          if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
4017              continue;
4018          }
4019          if (rdzero) {
4020              continue;
4021          }
4022          *val |= ((target_ulong)iprio[irq]) << (i * 8);
4023      }
4024  
4025      return RISCV_EXCP_NONE;
4026  }
4027  
write_hvipriox(CPURISCVState * env,int first_index,uint8_t * iprio,target_ulong val)4028  static RISCVException write_hvipriox(CPURISCVState *env, int first_index,
4029                            uint8_t *iprio, target_ulong val)
4030  {
4031      int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
4032  
4033      /* First index has to be a multiple of number of irqs per register */
4034      if (first_index % num_irqs) {
4035          return (env->virt_enabled) ?
4036                 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
4037      }
4038  
4039      /* Fill-up priority array */
4040      for (i = 0; i < num_irqs; i++) {
4041          if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
4042              continue;
4043          }
4044          if (rdzero) {
4045              iprio[irq] = 0;
4046          } else {
4047              iprio[irq] = (val >> (i * 8)) & 0xff;
4048          }
4049      }
4050  
4051      return RISCV_EXCP_NONE;
4052  }
4053  
read_hviprio1(CPURISCVState * env,int csrno,target_ulong * val)4054  static RISCVException read_hviprio1(CPURISCVState *env, int csrno,
4055                                      target_ulong *val)
4056  {
4057      return read_hvipriox(env, 0, env->hviprio, val);
4058  }
4059  
write_hviprio1(CPURISCVState * env,int csrno,target_ulong val)4060  static RISCVException write_hviprio1(CPURISCVState *env, int csrno,
4061                                       target_ulong val)
4062  {
4063      return write_hvipriox(env, 0, env->hviprio, val);
4064  }
4065  
read_hviprio1h(CPURISCVState * env,int csrno,target_ulong * val)4066  static RISCVException read_hviprio1h(CPURISCVState *env, int csrno,
4067                                       target_ulong *val)
4068  {
4069      return read_hvipriox(env, 4, env->hviprio, val);
4070  }
4071  
write_hviprio1h(CPURISCVState * env,int csrno,target_ulong val)4072  static RISCVException write_hviprio1h(CPURISCVState *env, int csrno,
4073                                        target_ulong val)
4074  {
4075      return write_hvipriox(env, 4, env->hviprio, val);
4076  }
4077  
read_hviprio2(CPURISCVState * env,int csrno,target_ulong * val)4078  static RISCVException read_hviprio2(CPURISCVState *env, int csrno,
4079                                      target_ulong *val)
4080  {
4081      return read_hvipriox(env, 8, env->hviprio, val);
4082  }
4083  
write_hviprio2(CPURISCVState * env,int csrno,target_ulong val)4084  static RISCVException write_hviprio2(CPURISCVState *env, int csrno,
4085                                       target_ulong val)
4086  {
4087      return write_hvipriox(env, 8, env->hviprio, val);
4088  }
4089  
read_hviprio2h(CPURISCVState * env,int csrno,target_ulong * val)4090  static RISCVException read_hviprio2h(CPURISCVState *env, int csrno,
4091                                       target_ulong *val)
4092  {
4093      return read_hvipriox(env, 12, env->hviprio, val);
4094  }
4095  
write_hviprio2h(CPURISCVState * env,int csrno,target_ulong val)4096  static RISCVException write_hviprio2h(CPURISCVState *env, int csrno,
4097                                        target_ulong val)
4098  {
4099      return write_hvipriox(env, 12, env->hviprio, val);
4100  }
4101  
4102  /* Virtual CSR Registers */
read_vsstatus(CPURISCVState * env,int csrno,target_ulong * val)4103  static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
4104                                      target_ulong *val)
4105  {
4106      *val = env->vsstatus;
4107      return RISCV_EXCP_NONE;
4108  }
4109  
write_vsstatus(CPURISCVState * env,int csrno,target_ulong val)4110  static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
4111                                       target_ulong val)
4112  {
4113      uint64_t mask = (target_ulong)-1;
4114      if ((val & VSSTATUS64_UXL) == 0) {
4115          mask &= ~VSSTATUS64_UXL;
4116      }
4117      env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
4118      return RISCV_EXCP_NONE;
4119  }
4120  
read_vstvec(CPURISCVState * env,int csrno,target_ulong * val)4121  static RISCVException read_vstvec(CPURISCVState *env, int csrno,
4122                                    target_ulong *val)
4123  {
4124      *val = env->vstvec;
4125      return RISCV_EXCP_NONE;
4126  }
4127  
write_vstvec(CPURISCVState * env,int csrno,target_ulong val)4128  static RISCVException write_vstvec(CPURISCVState *env, int csrno,
4129                                     target_ulong val)
4130  {
4131      /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
4132      if ((val & 3) < 2) {
4133          env->vstvec = val;
4134      } else {
4135          qemu_log_mask(LOG_UNIMP, "CSR_VSTVEC: reserved mode not supported\n");
4136      }
4137      return RISCV_EXCP_NONE;
4138  }
4139  
read_vsscratch(CPURISCVState * env,int csrno,target_ulong * val)4140  static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
4141                                       target_ulong *val)
4142  {
4143      *val = env->vsscratch;
4144      return RISCV_EXCP_NONE;
4145  }
4146  
write_vsscratch(CPURISCVState * env,int csrno,target_ulong val)4147  static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
4148                                        target_ulong val)
4149  {
4150      env->vsscratch = val;
4151      return RISCV_EXCP_NONE;
4152  }
4153  
read_vsepc(CPURISCVState * env,int csrno,target_ulong * val)4154  static RISCVException read_vsepc(CPURISCVState *env, int csrno,
4155                                   target_ulong *val)
4156  {
4157      *val = env->vsepc;
4158      return RISCV_EXCP_NONE;
4159  }
4160  
write_vsepc(CPURISCVState * env,int csrno,target_ulong val)4161  static RISCVException write_vsepc(CPURISCVState *env, int csrno,
4162                                    target_ulong val)
4163  {
4164      env->vsepc = val;
4165      return RISCV_EXCP_NONE;
4166  }
4167  
read_vscause(CPURISCVState * env,int csrno,target_ulong * val)4168  static RISCVException read_vscause(CPURISCVState *env, int csrno,
4169                                     target_ulong *val)
4170  {
4171      *val = env->vscause;
4172      return RISCV_EXCP_NONE;
4173  }
4174  
write_vscause(CPURISCVState * env,int csrno,target_ulong val)4175  static RISCVException write_vscause(CPURISCVState *env, int csrno,
4176                                      target_ulong val)
4177  {
4178      env->vscause = val;
4179      return RISCV_EXCP_NONE;
4180  }
4181  
read_vstval(CPURISCVState * env,int csrno,target_ulong * val)4182  static RISCVException read_vstval(CPURISCVState *env, int csrno,
4183                                    target_ulong *val)
4184  {
4185      *val = env->vstval;
4186      return RISCV_EXCP_NONE;
4187  }
4188  
write_vstval(CPURISCVState * env,int csrno,target_ulong val)4189  static RISCVException write_vstval(CPURISCVState *env, int csrno,
4190                                     target_ulong val)
4191  {
4192      env->vstval = val;
4193      return RISCV_EXCP_NONE;
4194  }
4195  
read_vsatp(CPURISCVState * env,int csrno,target_ulong * val)4196  static RISCVException read_vsatp(CPURISCVState *env, int csrno,
4197                                   target_ulong *val)
4198  {
4199      *val = env->vsatp;
4200      return RISCV_EXCP_NONE;
4201  }
4202  
write_vsatp(CPURISCVState * env,int csrno,target_ulong val)4203  static RISCVException write_vsatp(CPURISCVState *env, int csrno,
4204                                    target_ulong val)
4205  {
4206      env->vsatp = legalize_xatp(env, env->vsatp, val);
4207      return RISCV_EXCP_NONE;
4208  }
4209  
read_mtval2(CPURISCVState * env,int csrno,target_ulong * val)4210  static RISCVException read_mtval2(CPURISCVState *env, int csrno,
4211                                    target_ulong *val)
4212  {
4213      *val = env->mtval2;
4214      return RISCV_EXCP_NONE;
4215  }
4216  
write_mtval2(CPURISCVState * env,int csrno,target_ulong val)4217  static RISCVException write_mtval2(CPURISCVState *env, int csrno,
4218                                     target_ulong val)
4219  {
4220      env->mtval2 = val;
4221      return RISCV_EXCP_NONE;
4222  }
4223  
read_mtinst(CPURISCVState * env,int csrno,target_ulong * val)4224  static RISCVException read_mtinst(CPURISCVState *env, int csrno,
4225                                    target_ulong *val)
4226  {
4227      *val = env->mtinst;
4228      return RISCV_EXCP_NONE;
4229  }
4230  
write_mtinst(CPURISCVState * env,int csrno,target_ulong val)4231  static RISCVException write_mtinst(CPURISCVState *env, int csrno,
4232                                     target_ulong val)
4233  {
4234      env->mtinst = val;
4235      return RISCV_EXCP_NONE;
4236  }
4237  
4238  /* Physical Memory Protection */
read_mseccfg(CPURISCVState * env,int csrno,target_ulong * val)4239  static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
4240                                     target_ulong *val)
4241  {
4242      *val = mseccfg_csr_read(env);
4243      return RISCV_EXCP_NONE;
4244  }
4245  
write_mseccfg(CPURISCVState * env,int csrno,target_ulong val)4246  static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
4247                                      target_ulong val)
4248  {
4249      mseccfg_csr_write(env, val);
4250      return RISCV_EXCP_NONE;
4251  }
4252  
read_pmpcfg(CPURISCVState * env,int csrno,target_ulong * val)4253  static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
4254                                    target_ulong *val)
4255  {
4256      uint32_t reg_index = csrno - CSR_PMPCFG0;
4257  
4258      *val = pmpcfg_csr_read(env, reg_index);
4259      return RISCV_EXCP_NONE;
4260  }
4261  
write_pmpcfg(CPURISCVState * env,int csrno,target_ulong val)4262  static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
4263                                     target_ulong val)
4264  {
4265      uint32_t reg_index = csrno - CSR_PMPCFG0;
4266  
4267      pmpcfg_csr_write(env, reg_index, val);
4268      return RISCV_EXCP_NONE;
4269  }
4270  
read_pmpaddr(CPURISCVState * env,int csrno,target_ulong * val)4271  static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
4272                                     target_ulong *val)
4273  {
4274      *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
4275      return RISCV_EXCP_NONE;
4276  }
4277  
write_pmpaddr(CPURISCVState * env,int csrno,target_ulong val)4278  static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
4279                                      target_ulong val)
4280  {
4281      pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
4282      return RISCV_EXCP_NONE;
4283  }
4284  
read_tselect(CPURISCVState * env,int csrno,target_ulong * val)4285  static RISCVException read_tselect(CPURISCVState *env, int csrno,
4286                                     target_ulong *val)
4287  {
4288      *val = tselect_csr_read(env);
4289      return RISCV_EXCP_NONE;
4290  }
4291  
write_tselect(CPURISCVState * env,int csrno,target_ulong val)4292  static RISCVException write_tselect(CPURISCVState *env, int csrno,
4293                                      target_ulong val)
4294  {
4295      tselect_csr_write(env, val);
4296      return RISCV_EXCP_NONE;
4297  }
4298  
read_tdata(CPURISCVState * env,int csrno,target_ulong * val)4299  static RISCVException read_tdata(CPURISCVState *env, int csrno,
4300                                   target_ulong *val)
4301  {
4302      /* return 0 in tdata1 to end the trigger enumeration */
4303      if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
4304          *val = 0;
4305          return RISCV_EXCP_NONE;
4306      }
4307  
4308      if (!tdata_available(env, csrno - CSR_TDATA1)) {
4309          return RISCV_EXCP_ILLEGAL_INST;
4310      }
4311  
4312      *val = tdata_csr_read(env, csrno - CSR_TDATA1);
4313      return RISCV_EXCP_NONE;
4314  }
4315  
write_tdata(CPURISCVState * env,int csrno,target_ulong val)4316  static RISCVException write_tdata(CPURISCVState *env, int csrno,
4317                                    target_ulong val)
4318  {
4319      if (!tdata_available(env, csrno - CSR_TDATA1)) {
4320          return RISCV_EXCP_ILLEGAL_INST;
4321      }
4322  
4323      tdata_csr_write(env, csrno - CSR_TDATA1, val);
4324      return RISCV_EXCP_NONE;
4325  }
4326  
read_tinfo(CPURISCVState * env,int csrno,target_ulong * val)4327  static RISCVException read_tinfo(CPURISCVState *env, int csrno,
4328                                   target_ulong *val)
4329  {
4330      *val = tinfo_csr_read(env);
4331      return RISCV_EXCP_NONE;
4332  }
4333  
read_mcontext(CPURISCVState * env,int csrno,target_ulong * val)4334  static RISCVException read_mcontext(CPURISCVState *env, int csrno,
4335                                      target_ulong *val)
4336  {
4337      *val = env->mcontext;
4338      return RISCV_EXCP_NONE;
4339  }
4340  
write_mcontext(CPURISCVState * env,int csrno,target_ulong val)4341  static RISCVException write_mcontext(CPURISCVState *env, int csrno,
4342                                       target_ulong val)
4343  {
4344      bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
4345      int32_t mask;
4346  
4347      if (riscv_has_ext(env, RVH)) {
4348          /* Spec suggest 7-bit for RV32 and 14-bit for RV64 w/ H extension */
4349          mask = rv32 ? MCONTEXT32_HCONTEXT : MCONTEXT64_HCONTEXT;
4350      } else {
4351          /* Spec suggest 6-bit for RV32 and 13-bit for RV64 w/o H extension */
4352          mask = rv32 ? MCONTEXT32 : MCONTEXT64;
4353      }
4354  
4355      env->mcontext = val & mask;
4356      return RISCV_EXCP_NONE;
4357  }
4358  
4359  /*
4360   * Functions to access Pointer Masking feature registers
4361   * We have to check if current priv lvl could modify
4362   * csr in given mode
4363   */
check_pm_current_disabled(CPURISCVState * env,int csrno)4364  static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
4365  {
4366      int csr_priv = get_field(csrno, 0x300);
4367      int pm_current;
4368  
4369      if (env->debugger) {
4370          return false;
4371      }
4372      /*
4373       * If priv lvls differ that means we're accessing csr from higher priv lvl,
4374       * so allow the access
4375       */
4376      if (env->priv != csr_priv) {
4377          return false;
4378      }
4379      switch (env->priv) {
4380      case PRV_M:
4381          pm_current = get_field(env->mmte, M_PM_CURRENT);
4382          break;
4383      case PRV_S:
4384          pm_current = get_field(env->mmte, S_PM_CURRENT);
4385          break;
4386      case PRV_U:
4387          pm_current = get_field(env->mmte, U_PM_CURRENT);
4388          break;
4389      default:
4390          g_assert_not_reached();
4391      }
4392      /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
4393      return !pm_current;
4394  }
4395  
read_mmte(CPURISCVState * env,int csrno,target_ulong * val)4396  static RISCVException read_mmte(CPURISCVState *env, int csrno,
4397                                  target_ulong *val)
4398  {
4399      *val = env->mmte & MMTE_MASK;
4400      return RISCV_EXCP_NONE;
4401  }
4402  
write_mmte(CPURISCVState * env,int csrno,target_ulong val)4403  static RISCVException write_mmte(CPURISCVState *env, int csrno,
4404                                   target_ulong val)
4405  {
4406      uint64_t mstatus;
4407      target_ulong wpri_val = val & MMTE_MASK;
4408  
4409      if (val != wpri_val) {
4410          qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
4411                        TARGET_FMT_lx "\n", "MMTE: WPRI violation written 0x",
4412                        val, "vs expected 0x", wpri_val);
4413      }
4414      /* for machine mode pm.current is hardwired to 1 */
4415      wpri_val |= MMTE_M_PM_CURRENT;
4416  
4417      /* hardwiring pm.instruction bit to 0, since it's not supported yet */
4418      wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
4419      env->mmte = wpri_val | EXT_STATUS_DIRTY;
4420      riscv_cpu_update_mask(env);
4421  
4422      /* Set XS and SD bits, since PM CSRs are dirty */
4423      mstatus = env->mstatus | MSTATUS_XS;
4424      write_mstatus(env, csrno, mstatus);
4425      return RISCV_EXCP_NONE;
4426  }
4427  
read_smte(CPURISCVState * env,int csrno,target_ulong * val)4428  static RISCVException read_smte(CPURISCVState *env, int csrno,
4429                                  target_ulong *val)
4430  {
4431      *val = env->mmte & SMTE_MASK;
4432      return RISCV_EXCP_NONE;
4433  }
4434  
write_smte(CPURISCVState * env,int csrno,target_ulong val)4435  static RISCVException write_smte(CPURISCVState *env, int csrno,
4436                                   target_ulong val)
4437  {
4438      target_ulong wpri_val = val & SMTE_MASK;
4439  
4440      if (val != wpri_val) {
4441          qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
4442                        TARGET_FMT_lx "\n", "SMTE: WPRI violation written 0x",
4443                        val, "vs expected 0x", wpri_val);
4444      }
4445  
4446      /* if pm.current==0 we can't modify current PM CSRs */
4447      if (check_pm_current_disabled(env, csrno)) {
4448          return RISCV_EXCP_NONE;
4449      }
4450  
4451      wpri_val |= (env->mmte & ~SMTE_MASK);
4452      write_mmte(env, csrno, wpri_val);
4453      return RISCV_EXCP_NONE;
4454  }
4455  
read_umte(CPURISCVState * env,int csrno,target_ulong * val)4456  static RISCVException read_umte(CPURISCVState *env, int csrno,
4457                                  target_ulong *val)
4458  {
4459      *val = env->mmte & UMTE_MASK;
4460      return RISCV_EXCP_NONE;
4461  }
4462  
write_umte(CPURISCVState * env,int csrno,target_ulong val)4463  static RISCVException write_umte(CPURISCVState *env, int csrno,
4464                                   target_ulong val)
4465  {
4466      target_ulong wpri_val = val & UMTE_MASK;
4467  
4468      if (val != wpri_val) {
4469          qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
4470                        TARGET_FMT_lx "\n", "UMTE: WPRI violation written 0x",
4471                        val, "vs expected 0x", wpri_val);
4472      }
4473  
4474      if (check_pm_current_disabled(env, csrno)) {
4475          return RISCV_EXCP_NONE;
4476      }
4477  
4478      wpri_val |= (env->mmte & ~UMTE_MASK);
4479      write_mmte(env, csrno, wpri_val);
4480      return RISCV_EXCP_NONE;
4481  }
4482  
read_mpmmask(CPURISCVState * env,int csrno,target_ulong * val)4483  static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
4484                                     target_ulong *val)
4485  {
4486      *val = env->mpmmask;
4487      return RISCV_EXCP_NONE;
4488  }
4489  
write_mpmmask(CPURISCVState * env,int csrno,target_ulong val)4490  static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
4491                                      target_ulong val)
4492  {
4493      uint64_t mstatus;
4494  
4495      env->mpmmask = val;
4496      if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
4497          env->cur_pmmask = val;
4498      }
4499      env->mmte |= EXT_STATUS_DIRTY;
4500  
4501      /* Set XS and SD bits, since PM CSRs are dirty */
4502      mstatus = env->mstatus | MSTATUS_XS;
4503      write_mstatus(env, csrno, mstatus);
4504      return RISCV_EXCP_NONE;
4505  }
4506  
read_spmmask(CPURISCVState * env,int csrno,target_ulong * val)4507  static RISCVException read_spmmask(CPURISCVState *env, int csrno,
4508                                     target_ulong *val)
4509  {
4510      *val = env->spmmask;
4511      return RISCV_EXCP_NONE;
4512  }
4513  
write_spmmask(CPURISCVState * env,int csrno,target_ulong val)4514  static RISCVException write_spmmask(CPURISCVState *env, int csrno,
4515                                      target_ulong val)
4516  {
4517      uint64_t mstatus;
4518  
4519      /* if pm.current==0 we can't modify current PM CSRs */
4520      if (check_pm_current_disabled(env, csrno)) {
4521          return RISCV_EXCP_NONE;
4522      }
4523      env->spmmask = val;
4524      if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
4525          env->cur_pmmask = val;
4526          if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
4527              env->cur_pmmask &= UINT32_MAX;
4528          }
4529      }
4530      env->mmte |= EXT_STATUS_DIRTY;
4531  
4532      /* Set XS and SD bits, since PM CSRs are dirty */
4533      mstatus = env->mstatus | MSTATUS_XS;
4534      write_mstatus(env, csrno, mstatus);
4535      return RISCV_EXCP_NONE;
4536  }
4537  
read_upmmask(CPURISCVState * env,int csrno,target_ulong * val)4538  static RISCVException read_upmmask(CPURISCVState *env, int csrno,
4539                                     target_ulong *val)
4540  {
4541      *val = env->upmmask;
4542      return RISCV_EXCP_NONE;
4543  }
4544  
write_upmmask(CPURISCVState * env,int csrno,target_ulong val)4545  static RISCVException write_upmmask(CPURISCVState *env, int csrno,
4546                                      target_ulong val)
4547  {
4548      uint64_t mstatus;
4549  
4550      /* if pm.current==0 we can't modify current PM CSRs */
4551      if (check_pm_current_disabled(env, csrno)) {
4552          return RISCV_EXCP_NONE;
4553      }
4554      env->upmmask = val;
4555      if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
4556          env->cur_pmmask = val;
4557          if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
4558              env->cur_pmmask &= UINT32_MAX;
4559          }
4560      }
4561      env->mmte |= EXT_STATUS_DIRTY;
4562  
4563      /* Set XS and SD bits, since PM CSRs are dirty */
4564      mstatus = env->mstatus | MSTATUS_XS;
4565      write_mstatus(env, csrno, mstatus);
4566      return RISCV_EXCP_NONE;
4567  }
4568  
read_mpmbase(CPURISCVState * env,int csrno,target_ulong * val)4569  static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
4570                                     target_ulong *val)
4571  {
4572      *val = env->mpmbase;
4573      return RISCV_EXCP_NONE;
4574  }
4575  
write_mpmbase(CPURISCVState * env,int csrno,target_ulong val)4576  static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
4577                                      target_ulong val)
4578  {
4579      uint64_t mstatus;
4580  
4581      env->mpmbase = val;
4582      if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
4583          env->cur_pmbase = val;
4584      }
4585      env->mmte |= EXT_STATUS_DIRTY;
4586  
4587      /* Set XS and SD bits, since PM CSRs are dirty */
4588      mstatus = env->mstatus | MSTATUS_XS;
4589      write_mstatus(env, csrno, mstatus);
4590      return RISCV_EXCP_NONE;
4591  }
4592  
read_spmbase(CPURISCVState * env,int csrno,target_ulong * val)4593  static RISCVException read_spmbase(CPURISCVState *env, int csrno,
4594                                     target_ulong *val)
4595  {
4596      *val = env->spmbase;
4597      return RISCV_EXCP_NONE;
4598  }
4599  
write_spmbase(CPURISCVState * env,int csrno,target_ulong val)4600  static RISCVException write_spmbase(CPURISCVState *env, int csrno,
4601                                      target_ulong val)
4602  {
4603      uint64_t mstatus;
4604  
4605      /* if pm.current==0 we can't modify current PM CSRs */
4606      if (check_pm_current_disabled(env, csrno)) {
4607          return RISCV_EXCP_NONE;
4608      }
4609      env->spmbase = val;
4610      if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
4611          env->cur_pmbase = val;
4612          if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
4613              env->cur_pmbase &= UINT32_MAX;
4614          }
4615      }
4616      env->mmte |= EXT_STATUS_DIRTY;
4617  
4618      /* Set XS and SD bits, since PM CSRs are dirty */
4619      mstatus = env->mstatus | MSTATUS_XS;
4620      write_mstatus(env, csrno, mstatus);
4621      return RISCV_EXCP_NONE;
4622  }
4623  
read_upmbase(CPURISCVState * env,int csrno,target_ulong * val)4624  static RISCVException read_upmbase(CPURISCVState *env, int csrno,
4625                                     target_ulong *val)
4626  {
4627      *val = env->upmbase;
4628      return RISCV_EXCP_NONE;
4629  }
4630  
write_upmbase(CPURISCVState * env,int csrno,target_ulong val)4631  static RISCVException write_upmbase(CPURISCVState *env, int csrno,
4632                                      target_ulong val)
4633  {
4634      uint64_t mstatus;
4635  
4636      /* if pm.current==0 we can't modify current PM CSRs */
4637      if (check_pm_current_disabled(env, csrno)) {
4638          return RISCV_EXCP_NONE;
4639      }
4640      env->upmbase = val;
4641      if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
4642          env->cur_pmbase = val;
4643          if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
4644              env->cur_pmbase &= UINT32_MAX;
4645          }
4646      }
4647      env->mmte |= EXT_STATUS_DIRTY;
4648  
4649      /* Set XS and SD bits, since PM CSRs are dirty */
4650      mstatus = env->mstatus | MSTATUS_XS;
4651      write_mstatus(env, csrno, mstatus);
4652      return RISCV_EXCP_NONE;
4653  }
4654  
4655  #endif
4656  
4657  /* Crypto Extension */
riscv_new_csr_seed(target_ulong new_value,target_ulong write_mask)4658  target_ulong riscv_new_csr_seed(target_ulong new_value,
4659                                  target_ulong write_mask)
4660  {
4661      uint16_t random_v;
4662      Error *random_e = NULL;
4663      int random_r;
4664      target_ulong rval;
4665  
4666      random_r = qemu_guest_getrandom(&random_v, 2, &random_e);
4667      if (unlikely(random_r < 0)) {
4668          /*
4669           * Failed, for unknown reasons in the crypto subsystem.
4670           * The best we can do is log the reason and return a
4671           * failure indication to the guest.  There is no reason
4672           * we know to expect the failure to be transitory, so
4673           * indicate DEAD to avoid having the guest spin on WAIT.
4674           */
4675          qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
4676                        __func__, error_get_pretty(random_e));
4677          error_free(random_e);
4678          rval = SEED_OPST_DEAD;
4679      } else {
4680          rval = random_v | SEED_OPST_ES16;
4681      }
4682  
4683      return rval;
4684  }
4685  
rmw_seed(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)4686  static RISCVException rmw_seed(CPURISCVState *env, int csrno,
4687                                 target_ulong *ret_value,
4688                                 target_ulong new_value,
4689                                 target_ulong write_mask)
4690  {
4691      target_ulong rval;
4692  
4693      rval = riscv_new_csr_seed(new_value, write_mask);
4694  
4695      if (ret_value) {
4696          *ret_value = rval;
4697      }
4698  
4699      return RISCV_EXCP_NONE;
4700  }
4701  
4702  /*
4703   * riscv_csrrw - read and/or update control and status register
4704   *
4705   * csrr   <->  riscv_csrrw(env, csrno, ret_value, 0, 0);
4706   * csrrw  <->  riscv_csrrw(env, csrno, ret_value, value, -1);
4707   * csrrs  <->  riscv_csrrw(env, csrno, ret_value, -1, value);
4708   * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
4709   */
4710  
riscv_csrrw_check(CPURISCVState * env,int csrno,bool write)4711  static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
4712                                                 int csrno,
4713                                                 bool write)
4714  {
4715      /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
4716      bool read_only = get_field(csrno, 0xC00) == 3;
4717      int csr_min_priv = csr_ops[csrno].min_priv_ver;
4718  
4719      /* ensure the CSR extension is enabled */
4720      if (!riscv_cpu_cfg(env)->ext_zicsr) {
4721          return RISCV_EXCP_ILLEGAL_INST;
4722      }
4723  
4724      /* ensure CSR is implemented by checking predicate */
4725      if (!csr_ops[csrno].predicate) {
4726          return RISCV_EXCP_ILLEGAL_INST;
4727      }
4728  
4729      /* privileged spec version check */
4730      if (env->priv_ver < csr_min_priv) {
4731          return RISCV_EXCP_ILLEGAL_INST;
4732      }
4733  
4734      /* read / write check */
4735      if (write && read_only) {
4736          return RISCV_EXCP_ILLEGAL_INST;
4737      }
4738  
4739      /*
4740       * The predicate() not only does existence check but also does some
4741       * access control check which triggers for example virtual instruction
4742       * exception in some cases. When writing read-only CSRs in those cases
4743       * illegal instruction exception should be triggered instead of virtual
4744       * instruction exception. Hence this comes after the read / write check.
4745       */
4746      RISCVException ret = csr_ops[csrno].predicate(env, csrno);
4747      if (ret != RISCV_EXCP_NONE) {
4748          return ret;
4749      }
4750  
4751  #if !defined(CONFIG_USER_ONLY)
4752      int csr_priv, effective_priv = env->priv;
4753  
4754      if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
4755          !env->virt_enabled) {
4756          /*
4757           * We are in HS mode. Add 1 to the effective privilege level to
4758           * allow us to access the Hypervisor CSRs.
4759           */
4760          effective_priv++;
4761      }
4762  
4763      csr_priv = get_field(csrno, 0x300);
4764      if (!env->debugger && (effective_priv < csr_priv)) {
4765          if (csr_priv == (PRV_S + 1) && env->virt_enabled) {
4766              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
4767          }
4768          return RISCV_EXCP_ILLEGAL_INST;
4769      }
4770  #endif
4771      return RISCV_EXCP_NONE;
4772  }
4773  
riscv_csrrw_do64(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)4774  static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
4775                                         target_ulong *ret_value,
4776                                         target_ulong new_value,
4777                                         target_ulong write_mask)
4778  {
4779      RISCVException ret;
4780      target_ulong old_value = 0;
4781  
4782      /* execute combined read/write operation if it exists */
4783      if (csr_ops[csrno].op) {
4784          return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
4785      }
4786  
4787      /*
4788       * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
4789       * and we can't throw side effects caused by CSR reads.
4790       */
4791      if (ret_value) {
4792          /* if no accessor exists then return failure */
4793          if (!csr_ops[csrno].read) {
4794              return RISCV_EXCP_ILLEGAL_INST;
4795          }
4796          /* read old value */
4797          ret = csr_ops[csrno].read(env, csrno, &old_value);
4798          if (ret != RISCV_EXCP_NONE) {
4799              return ret;
4800          }
4801      }
4802  
4803      /* write value if writable and write mask set, otherwise drop writes */
4804      if (write_mask) {
4805          new_value = (old_value & ~write_mask) | (new_value & write_mask);
4806          if (csr_ops[csrno].write) {
4807              ret = csr_ops[csrno].write(env, csrno, new_value);
4808              if (ret != RISCV_EXCP_NONE) {
4809                  return ret;
4810              }
4811          }
4812      }
4813  
4814      /* return old value */
4815      if (ret_value) {
4816          *ret_value = old_value;
4817      }
4818  
4819      return RISCV_EXCP_NONE;
4820  }
4821  
riscv_csrr(CPURISCVState * env,int csrno,target_ulong * ret_value)4822  RISCVException riscv_csrr(CPURISCVState *env, int csrno,
4823                             target_ulong *ret_value)
4824  {
4825      RISCVException ret = riscv_csrrw_check(env, csrno, false);
4826      if (ret != RISCV_EXCP_NONE) {
4827          return ret;
4828      }
4829  
4830      return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
4831  }
4832  
riscv_csrrw(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)4833  RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
4834                             target_ulong *ret_value,
4835                             target_ulong new_value, target_ulong write_mask)
4836  {
4837      RISCVException ret = riscv_csrrw_check(env, csrno, true);
4838      if (ret != RISCV_EXCP_NONE) {
4839          return ret;
4840      }
4841  
4842      return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
4843  }
4844  
riscv_csrrw_do128(CPURISCVState * env,int csrno,Int128 * ret_value,Int128 new_value,Int128 write_mask)4845  static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
4846                                          Int128 *ret_value,
4847                                          Int128 new_value,
4848                                          Int128 write_mask)
4849  {
4850      RISCVException ret;
4851      Int128 old_value;
4852  
4853      /* read old value */
4854      ret = csr_ops[csrno].read128(env, csrno, &old_value);
4855      if (ret != RISCV_EXCP_NONE) {
4856          return ret;
4857      }
4858  
4859      /* write value if writable and write mask set, otherwise drop writes */
4860      if (int128_nz(write_mask)) {
4861          new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
4862                                int128_and(new_value, write_mask));
4863          if (csr_ops[csrno].write128) {
4864              ret = csr_ops[csrno].write128(env, csrno, new_value);
4865              if (ret != RISCV_EXCP_NONE) {
4866                  return ret;
4867              }
4868          } else if (csr_ops[csrno].write) {
4869              /* avoids having to write wrappers for all registers */
4870              ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
4871              if (ret != RISCV_EXCP_NONE) {
4872                  return ret;
4873              }
4874          }
4875      }
4876  
4877      /* return old value */
4878      if (ret_value) {
4879          *ret_value = old_value;
4880      }
4881  
4882      return RISCV_EXCP_NONE;
4883  }
4884  
riscv_csrr_i128(CPURISCVState * env,int csrno,Int128 * ret_value)4885  RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
4886                                 Int128 *ret_value)
4887  {
4888      RISCVException ret;
4889  
4890      ret = riscv_csrrw_check(env, csrno, false);
4891      if (ret != RISCV_EXCP_NONE) {
4892          return ret;
4893      }
4894  
4895      if (csr_ops[csrno].read128) {
4896          return riscv_csrrw_do128(env, csrno, ret_value,
4897                                   int128_zero(), int128_zero());
4898      }
4899  
4900      /*
4901       * Fall back to 64-bit version for now, if the 128-bit alternative isn't
4902       * at all defined.
4903       * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
4904       * significant), for those, this fallback is correctly handling the
4905       * accesses
4906       */
4907      target_ulong old_value;
4908      ret = riscv_csrrw_do64(env, csrno, &old_value,
4909                             (target_ulong)0,
4910                             (target_ulong)0);
4911      if (ret == RISCV_EXCP_NONE && ret_value) {
4912          *ret_value = int128_make64(old_value);
4913      }
4914      return ret;
4915  }
4916  
riscv_csrrw_i128(CPURISCVState * env,int csrno,Int128 * ret_value,Int128 new_value,Int128 write_mask)4917  RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
4918                                  Int128 *ret_value,
4919                                  Int128 new_value, Int128 write_mask)
4920  {
4921      RISCVException ret;
4922  
4923      ret = riscv_csrrw_check(env, csrno, true);
4924      if (ret != RISCV_EXCP_NONE) {
4925          return ret;
4926      }
4927  
4928      if (csr_ops[csrno].read128) {
4929          return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
4930      }
4931  
4932      /*
4933       * Fall back to 64-bit version for now, if the 128-bit alternative isn't
4934       * at all defined.
4935       * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
4936       * significant), for those, this fallback is correctly handling the
4937       * accesses
4938       */
4939      target_ulong old_value;
4940      ret = riscv_csrrw_do64(env, csrno, &old_value,
4941                             int128_getlo(new_value),
4942                             int128_getlo(write_mask));
4943      if (ret == RISCV_EXCP_NONE && ret_value) {
4944          *ret_value = int128_make64(old_value);
4945      }
4946      return ret;
4947  }
4948  
4949  /*
4950   * Debugger support.  If not in user mode, set env->debugger before the
4951   * riscv_csrrw call and clear it after the call.
4952   */
riscv_csrrw_debug(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)4953  RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
4954                                   target_ulong *ret_value,
4955                                   target_ulong new_value,
4956                                   target_ulong write_mask)
4957  {
4958      RISCVException ret;
4959  #if !defined(CONFIG_USER_ONLY)
4960      env->debugger = true;
4961  #endif
4962      if (!write_mask) {
4963          ret = riscv_csrr(env, csrno, ret_value);
4964      } else {
4965          ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
4966      }
4967  #if !defined(CONFIG_USER_ONLY)
4968      env->debugger = false;
4969  #endif
4970      return ret;
4971  }
4972  
read_jvt(CPURISCVState * env,int csrno,target_ulong * val)4973  static RISCVException read_jvt(CPURISCVState *env, int csrno,
4974                                 target_ulong *val)
4975  {
4976      *val = env->jvt;
4977      return RISCV_EXCP_NONE;
4978  }
4979  
write_jvt(CPURISCVState * env,int csrno,target_ulong val)4980  static RISCVException write_jvt(CPURISCVState *env, int csrno,
4981                                  target_ulong val)
4982  {
4983      env->jvt = val;
4984      return RISCV_EXCP_NONE;
4985  }
4986  
4987  /*
4988   * Control and Status Register function table
4989   * riscv_csr_operations::predicate() must be provided for an implemented CSR
4990   */
4991  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
4992      /* User Floating-Point CSRs */
4993      [CSR_FFLAGS]   = { "fflags",   fs,     read_fflags,  write_fflags },
4994      [CSR_FRM]      = { "frm",      fs,     read_frm,     write_frm    },
4995      [CSR_FCSR]     = { "fcsr",     fs,     read_fcsr,    write_fcsr   },
4996      /* Vector CSRs */
4997      [CSR_VSTART]   = { "vstart",   vs,     read_vstart,  write_vstart },
4998      [CSR_VXSAT]    = { "vxsat",    vs,     read_vxsat,   write_vxsat  },
4999      [CSR_VXRM]     = { "vxrm",     vs,     read_vxrm,    write_vxrm   },
5000      [CSR_VCSR]     = { "vcsr",     vs,     read_vcsr,    write_vcsr   },
5001      [CSR_VL]       = { "vl",       vs,     read_vl                    },
5002      [CSR_VTYPE]    = { "vtype",    vs,     read_vtype                 },
5003      [CSR_VLENB]    = { "vlenb",    vs,     read_vlenb                 },
5004      /* User Timers and Counters */
5005      [CSR_CYCLE]    = { "cycle",    ctr,    read_hpmcounter  },
5006      [CSR_INSTRET]  = { "instret",  ctr,    read_hpmcounter  },
5007      [CSR_CYCLEH]   = { "cycleh",   ctr32,  read_hpmcounterh },
5008      [CSR_INSTRETH] = { "instreth", ctr32,  read_hpmcounterh },
5009  
5010      /*
5011       * In privileged mode, the monitor will have to emulate TIME CSRs only if
5012       * rdtime callback is not provided by machine/platform emulation.
5013       */
5014      [CSR_TIME]  = { "time",  ctr,   read_time  },
5015      [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
5016  
5017      /* Crypto Extension */
5018      [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
5019  
5020      /* Zcmt Extension */
5021      [CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
5022  
5023      /* zicfiss Extension, shadow stack register */
5024      [CSR_SSP]  = { "ssp", cfi_ss, read_ssp, write_ssp },
5025  
5026  #if !defined(CONFIG_USER_ONLY)
5027      /* Machine Timers and Counters */
5028      [CSR_MCYCLE]    = { "mcycle",    any,   read_hpmcounter,
5029                          write_mhpmcounter                    },
5030      [CSR_MINSTRET]  = { "minstret",  any,   read_hpmcounter,
5031                          write_mhpmcounter                    },
5032      [CSR_MCYCLEH]   = { "mcycleh",   any32, read_hpmcounterh,
5033                          write_mhpmcounterh                   },
5034      [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh,
5035                          write_mhpmcounterh                   },
5036  
5037      /* Machine Information Registers */
5038      [CSR_MVENDORID] = { "mvendorid", any,   read_mvendorid },
5039      [CSR_MARCHID]   = { "marchid",   any,   read_marchid   },
5040      [CSR_MIMPID]    = { "mimpid",    any,   read_mimpid    },
5041      [CSR_MHARTID]   = { "mhartid",   any,   read_mhartid   },
5042  
5043      [CSR_MCONFIGPTR]  = { "mconfigptr", any,   read_zero,
5044                            .min_priv_ver = PRIV_VERSION_1_12_0 },
5045      /* Machine Trap Setup */
5046      [CSR_MSTATUS]     = { "mstatus",    any,   read_mstatus, write_mstatus,
5047                            NULL,                read_mstatus_i128           },
5048      [CSR_MISA]        = { "misa",       any,   read_misa,    write_misa,
5049                            NULL,                read_misa_i128              },
5050      [CSR_MIDELEG]     = { "mideleg",    any,   NULL, NULL,   rmw_mideleg   },
5051      [CSR_MEDELEG]     = { "medeleg",    any,   read_medeleg, write_medeleg },
5052      [CSR_MIE]         = { "mie",        any,   NULL, NULL,   rmw_mie       },
5053      [CSR_MTVEC]       = { "mtvec",      any,   read_mtvec,   write_mtvec   },
5054      [CSR_MCOUNTEREN]  = { "mcounteren", umode, read_mcounteren,
5055                            write_mcounteren                                 },
5056  
5057      [CSR_MSTATUSH]    = { "mstatush",   any32, read_mstatush,
5058                            write_mstatush                                   },
5059      [CSR_MEDELEGH]    = { "medelegh",   any32, read_zero, write_ignore,
5060                            .min_priv_ver = PRIV_VERSION_1_13_0              },
5061      [CSR_HEDELEGH]    = { "hedelegh",   hmode32, read_hedelegh, write_hedelegh,
5062                            .min_priv_ver = PRIV_VERSION_1_13_0              },
5063  
5064      /* Machine Trap Handling */
5065      [CSR_MSCRATCH] = { "mscratch", any,  read_mscratch, write_mscratch,
5066                         NULL, read_mscratch_i128, write_mscratch_i128   },
5067      [CSR_MEPC]     = { "mepc",     any,  read_mepc,     write_mepc     },
5068      [CSR_MCAUSE]   = { "mcause",   any,  read_mcause,   write_mcause   },
5069      [CSR_MTVAL]    = { "mtval",    any,  read_mtval,    write_mtval    },
5070      [CSR_MIP]      = { "mip",      any,  NULL,    NULL, rmw_mip        },
5071  
5072      /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
5073      [CSR_MISELECT] = { "miselect", aia_any,   NULL, NULL,    rmw_xiselect },
5074      [CSR_MIREG]    = { "mireg",    aia_any,   NULL, NULL,    rmw_xireg },
5075  
5076      /* Machine-Level Interrupts (AIA) */
5077      [CSR_MTOPEI]   = { "mtopei",   aia_any, NULL, NULL, rmw_xtopei },
5078      [CSR_MTOPI]    = { "mtopi",    aia_any, read_mtopi },
5079  
5080      /* Virtual Interrupts for Supervisor Level (AIA) */
5081      [CSR_MVIEN]    = { "mvien",    aia_any, NULL, NULL, rmw_mvien   },
5082      [CSR_MVIP]     = { "mvip",     aia_any, NULL, NULL, rmw_mvip    },
5083  
5084      /* Machine-Level High-Half CSRs (AIA) */
5085      [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
5086      [CSR_MIEH]     = { "mieh",     aia_any32, NULL, NULL, rmw_mieh     },
5087      [CSR_MVIENH]   = { "mvienh",   aia_any32, NULL, NULL, rmw_mvienh   },
5088      [CSR_MVIPH]    = { "mviph",    aia_any32, NULL, NULL, rmw_mviph    },
5089      [CSR_MIPH]     = { "miph",     aia_any32, NULL, NULL, rmw_miph     },
5090  
5091      /* Execution environment configuration */
5092      [CSR_MENVCFG]  = { "menvcfg",  umode, read_menvcfg,  write_menvcfg,
5093                         .min_priv_ver = PRIV_VERSION_1_12_0              },
5094      [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh,
5095                         .min_priv_ver = PRIV_VERSION_1_12_0              },
5096      [CSR_SENVCFG]  = { "senvcfg",  smode, read_senvcfg,  write_senvcfg,
5097                         .min_priv_ver = PRIV_VERSION_1_12_0              },
5098      [CSR_HENVCFG]  = { "henvcfg",  hmode, read_henvcfg, write_henvcfg,
5099                         .min_priv_ver = PRIV_VERSION_1_12_0              },
5100      [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
5101                         .min_priv_ver = PRIV_VERSION_1_12_0              },
5102  
5103      /* Smstateen extension CSRs */
5104      [CSR_MSTATEEN0] = { "mstateen0", mstateen, read_mstateen, write_mstateen0,
5105                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5106      [CSR_MSTATEEN0H] = { "mstateen0h", mstateen, read_mstateenh,
5107                            write_mstateen0h,
5108                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5109      [CSR_MSTATEEN1] = { "mstateen1", mstateen, read_mstateen,
5110                          write_mstateen_1_3,
5111                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5112      [CSR_MSTATEEN1H] = { "mstateen1h", mstateen, read_mstateenh,
5113                           write_mstateenh_1_3,
5114                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5115      [CSR_MSTATEEN2] = { "mstateen2", mstateen, read_mstateen,
5116                          write_mstateen_1_3,
5117                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5118      [CSR_MSTATEEN2H] = { "mstateen2h", mstateen, read_mstateenh,
5119                           write_mstateenh_1_3,
5120                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5121      [CSR_MSTATEEN3] = { "mstateen3", mstateen, read_mstateen,
5122                          write_mstateen_1_3,
5123                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5124      [CSR_MSTATEEN3H] = { "mstateen3h", mstateen, read_mstateenh,
5125                           write_mstateenh_1_3,
5126                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5127      [CSR_HSTATEEN0] = { "hstateen0", hstateen, read_hstateen, write_hstateen0,
5128                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5129      [CSR_HSTATEEN0H] = { "hstateen0h", hstateenh, read_hstateenh,
5130                           write_hstateen0h,
5131                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5132      [CSR_HSTATEEN1] = { "hstateen1", hstateen, read_hstateen,
5133                          write_hstateen_1_3,
5134                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5135      [CSR_HSTATEEN1H] = { "hstateen1h", hstateenh, read_hstateenh,
5136                           write_hstateenh_1_3,
5137                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5138      [CSR_HSTATEEN2] = { "hstateen2", hstateen, read_hstateen,
5139                          write_hstateen_1_3,
5140                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5141      [CSR_HSTATEEN2H] = { "hstateen2h", hstateenh, read_hstateenh,
5142                           write_hstateenh_1_3,
5143                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5144      [CSR_HSTATEEN3] = { "hstateen3", hstateen, read_hstateen,
5145                          write_hstateen_1_3,
5146                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5147      [CSR_HSTATEEN3H] = { "hstateen3h", hstateenh, read_hstateenh,
5148                           write_hstateenh_1_3,
5149                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5150      [CSR_SSTATEEN0] = { "sstateen0", sstateen, read_sstateen, write_sstateen0,
5151                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5152      [CSR_SSTATEEN1] = { "sstateen1", sstateen, read_sstateen,
5153                          write_sstateen_1_3,
5154                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5155      [CSR_SSTATEEN2] = { "sstateen2", sstateen, read_sstateen,
5156                          write_sstateen_1_3,
5157                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5158      [CSR_SSTATEEN3] = { "sstateen3", sstateen, read_sstateen,
5159                          write_sstateen_1_3,
5160                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5161  
5162      /* Supervisor Trap Setup */
5163      [CSR_SSTATUS]    = { "sstatus",    smode, read_sstatus,    write_sstatus,
5164                           NULL,                read_sstatus_i128              },
5165      [CSR_SIE]        = { "sie",        smode, NULL,   NULL,    rmw_sie       },
5166      [CSR_STVEC]      = { "stvec",      smode, read_stvec,      write_stvec   },
5167      [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren,
5168                           write_scounteren                                    },
5169  
5170      /* Supervisor Trap Handling */
5171      [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch,
5172                         NULL, read_sscratch_i128, write_sscratch_i128    },
5173      [CSR_SEPC]     = { "sepc",     smode, read_sepc,     write_sepc     },
5174      [CSR_SCAUSE]   = { "scause",   smode, read_scause,   write_scause   },
5175      [CSR_STVAL]    = { "stval",    smode, read_stval,    write_stval    },
5176      [CSR_SIP]      = { "sip",      smode, NULL,    NULL, rmw_sip        },
5177      [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp,
5178                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5179      [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
5180                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5181      [CSR_VSTIMECMP] = { "vstimecmp", sstc, read_vstimecmp,
5182                          write_vstimecmp,
5183                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5184      [CSR_VSTIMECMPH] = { "vstimecmph", sstc_32, read_vstimecmph,
5185                           write_vstimecmph,
5186                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5187  
5188      /* Supervisor Protection and Translation */
5189      [CSR_SATP]     = { "satp",     satp, read_satp,     write_satp     },
5190  
5191      /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
5192      [CSR_SISELECT]   = { "siselect",   aia_smode, NULL, NULL, rmw_xiselect },
5193      [CSR_SIREG]      = { "sireg",      aia_smode, NULL, NULL, rmw_xireg },
5194  
5195      /* Supervisor-Level Interrupts (AIA) */
5196      [CSR_STOPEI]     = { "stopei",     aia_smode, NULL, NULL, rmw_xtopei },
5197      [CSR_STOPI]      = { "stopi",      aia_smode, read_stopi },
5198  
5199      /* Supervisor-Level High-Half CSRs (AIA) */
5200      [CSR_SIEH]       = { "sieh",   aia_smode32, NULL, NULL, rmw_sieh },
5201      [CSR_SIPH]       = { "siph",   aia_smode32, NULL, NULL, rmw_siph },
5202  
5203      [CSR_HSTATUS]     = { "hstatus",     hmode,   read_hstatus, write_hstatus,
5204                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5205      [CSR_HEDELEG]     = { "hedeleg",     hmode,   read_hedeleg, write_hedeleg,
5206                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5207      [CSR_HIDELEG]     = { "hideleg",     hmode,   NULL,   NULL, rmw_hideleg,
5208                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5209      [CSR_HVIP]        = { "hvip",        hmode,   NULL,   NULL, rmw_hvip,
5210                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5211      [CSR_HIP]         = { "hip",         hmode,   NULL,   NULL, rmw_hip,
5212                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5213      [CSR_HIE]         = { "hie",         hmode,   NULL,   NULL, rmw_hie,
5214                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5215      [CSR_HCOUNTEREN]  = { "hcounteren",  hmode,   read_hcounteren,
5216                            write_hcounteren,
5217                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5218      [CSR_HGEIE]       = { "hgeie",       hmode,   read_hgeie,   write_hgeie,
5219                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5220      [CSR_HTVAL]       = { "htval",       hmode,   read_htval,   write_htval,
5221                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5222      [CSR_HTINST]      = { "htinst",      hmode,   read_htinst,  write_htinst,
5223                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5224      [CSR_HGEIP]       = { "hgeip",       hmode,   read_hgeip,
5225                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5226      [CSR_HGATP]       = { "hgatp",       hgatp,   read_hgatp,   write_hgatp,
5227                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5228      [CSR_HTIMEDELTA]  = { "htimedelta",  hmode,   read_htimedelta,
5229                            write_htimedelta,
5230                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5231      [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah,
5232                            write_htimedeltah,
5233                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5234  
5235      [CSR_VSSTATUS]    = { "vsstatus",    hmode,   read_vsstatus,
5236                            write_vsstatus,
5237                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5238      [CSR_VSIP]        = { "vsip",        hmode,   NULL,    NULL, rmw_vsip,
5239                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5240      [CSR_VSIE]        = { "vsie",        hmode,   NULL,    NULL, rmw_vsie ,
5241                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5242      [CSR_VSTVEC]      = { "vstvec",      hmode,   read_vstvec,   write_vstvec,
5243                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5244      [CSR_VSSCRATCH]   = { "vsscratch",   hmode,   read_vsscratch,
5245                            write_vsscratch,
5246                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5247      [CSR_VSEPC]       = { "vsepc",       hmode,   read_vsepc,    write_vsepc,
5248                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5249      [CSR_VSCAUSE]     = { "vscause",     hmode,   read_vscause,  write_vscause,
5250                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5251      [CSR_VSTVAL]      = { "vstval",      hmode,   read_vstval,   write_vstval,
5252                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5253      [CSR_VSATP]       = { "vsatp",       hmode,   read_vsatp,    write_vsatp,
5254                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5255  
5256      [CSR_MTVAL2]      = { "mtval2",      hmode,   read_mtval2,   write_mtval2,
5257                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5258      [CSR_MTINST]      = { "mtinst",      hmode,   read_mtinst,   write_mtinst,
5259                            .min_priv_ver = PRIV_VERSION_1_12_0                },
5260  
5261      /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
5262      [CSR_HVIEN]       = { "hvien",       aia_hmode, NULL, NULL, rmw_hvien },
5263      [CSR_HVICTL]      = { "hvictl",      aia_hmode, read_hvictl,
5264                            write_hvictl                                      },
5265      [CSR_HVIPRIO1]    = { "hviprio1",    aia_hmode, read_hviprio1,
5266                            write_hviprio1                                    },
5267      [CSR_HVIPRIO2]    = { "hviprio2",    aia_hmode, read_hviprio2,
5268                            write_hviprio2                                    },
5269      /*
5270       * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
5271       */
5272      [CSR_VSISELECT]   = { "vsiselect",   aia_hmode, NULL, NULL,
5273                            rmw_xiselect                                     },
5274      [CSR_VSIREG]      = { "vsireg",      aia_hmode, NULL, NULL, rmw_xireg  },
5275  
5276      /* VS-Level Interrupts (H-extension with AIA) */
5277      [CSR_VSTOPEI]     = { "vstopei",     aia_hmode, NULL, NULL, rmw_xtopei },
5278      [CSR_VSTOPI]      = { "vstopi",      aia_hmode, read_vstopi },
5279  
5280      /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
5281      [CSR_HIDELEGH]    = { "hidelegh",    aia_hmode32, NULL, NULL,
5282                            rmw_hidelegh                                      },
5283      [CSR_HVIENH]      = { "hvienh",      aia_hmode32, NULL, NULL, rmw_hvienh },
5284      [CSR_HVIPH]       = { "hviph",       aia_hmode32, NULL, NULL, rmw_hviph },
5285      [CSR_HVIPRIO1H]   = { "hviprio1h",   aia_hmode32, read_hviprio1h,
5286                            write_hviprio1h                                   },
5287      [CSR_HVIPRIO2H]   = { "hviprio2h",   aia_hmode32, read_hviprio2h,
5288                            write_hviprio2h                                   },
5289      [CSR_VSIEH]       = { "vsieh",       aia_hmode32, NULL, NULL, rmw_vsieh },
5290      [CSR_VSIPH]       = { "vsiph",       aia_hmode32, NULL, NULL, rmw_vsiph },
5291  
5292      /* Physical Memory Protection */
5293      [CSR_MSECCFG]    = { "mseccfg",   have_mseccfg, read_mseccfg, write_mseccfg,
5294                           .min_priv_ver = PRIV_VERSION_1_11_0           },
5295      [CSR_PMPCFG0]    = { "pmpcfg0",   pmp, read_pmpcfg,  write_pmpcfg  },
5296      [CSR_PMPCFG1]    = { "pmpcfg1",   pmp, read_pmpcfg,  write_pmpcfg  },
5297      [CSR_PMPCFG2]    = { "pmpcfg2",   pmp, read_pmpcfg,  write_pmpcfg  },
5298      [CSR_PMPCFG3]    = { "pmpcfg3",   pmp, read_pmpcfg,  write_pmpcfg  },
5299      [CSR_PMPADDR0]   = { "pmpaddr0",  pmp, read_pmpaddr, write_pmpaddr },
5300      [CSR_PMPADDR1]   = { "pmpaddr1",  pmp, read_pmpaddr, write_pmpaddr },
5301      [CSR_PMPADDR2]   = { "pmpaddr2",  pmp, read_pmpaddr, write_pmpaddr },
5302      [CSR_PMPADDR3]   = { "pmpaddr3",  pmp, read_pmpaddr, write_pmpaddr },
5303      [CSR_PMPADDR4]   = { "pmpaddr4",  pmp, read_pmpaddr, write_pmpaddr },
5304      [CSR_PMPADDR5]   = { "pmpaddr5",  pmp, read_pmpaddr, write_pmpaddr },
5305      [CSR_PMPADDR6]   = { "pmpaddr6",  pmp, read_pmpaddr, write_pmpaddr },
5306      [CSR_PMPADDR7]   = { "pmpaddr7",  pmp, read_pmpaddr, write_pmpaddr },
5307      [CSR_PMPADDR8]   = { "pmpaddr8",  pmp, read_pmpaddr, write_pmpaddr },
5308      [CSR_PMPADDR9]   = { "pmpaddr9",  pmp, read_pmpaddr, write_pmpaddr },
5309      [CSR_PMPADDR10]  = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
5310      [CSR_PMPADDR11]  = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
5311      [CSR_PMPADDR12]  = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
5312      [CSR_PMPADDR13]  = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
5313      [CSR_PMPADDR14] =  { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
5314      [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
5315  
5316      /* Debug CSRs */
5317      [CSR_TSELECT]   =  { "tselect",  debug, read_tselect,  write_tselect  },
5318      [CSR_TDATA1]    =  { "tdata1",   debug, read_tdata,    write_tdata    },
5319      [CSR_TDATA2]    =  { "tdata2",   debug, read_tdata,    write_tdata    },
5320      [CSR_TDATA3]    =  { "tdata3",   debug, read_tdata,    write_tdata    },
5321      [CSR_TINFO]     =  { "tinfo",    debug, read_tinfo,    write_ignore   },
5322      [CSR_MCONTEXT]  =  { "mcontext", debug, read_mcontext, write_mcontext },
5323  
5324      /* User Pointer Masking */
5325      [CSR_UMTE]    =    { "umte",    pointer_masking, read_umte,  write_umte },
5326      [CSR_UPMMASK] =    { "upmmask", pointer_masking, read_upmmask,
5327                           write_upmmask                                      },
5328      [CSR_UPMBASE] =    { "upmbase", pointer_masking, read_upmbase,
5329                           write_upmbase                                      },
5330      /* Machine Pointer Masking */
5331      [CSR_MMTE]    =    { "mmte",    pointer_masking, read_mmte,  write_mmte },
5332      [CSR_MPMMASK] =    { "mpmmask", pointer_masking, read_mpmmask,
5333                           write_mpmmask                                      },
5334      [CSR_MPMBASE] =    { "mpmbase", pointer_masking, read_mpmbase,
5335                           write_mpmbase                                      },
5336      /* Supervisor Pointer Masking */
5337      [CSR_SMTE]    =    { "smte",    pointer_masking, read_smte,  write_smte },
5338      [CSR_SPMMASK] =    { "spmmask", pointer_masking, read_spmmask,
5339                           write_spmmask                                      },
5340      [CSR_SPMBASE] =    { "spmbase", pointer_masking, read_spmbase,
5341                           write_spmbase                                      },
5342  
5343      /* Performance Counters */
5344      [CSR_HPMCOUNTER3]    = { "hpmcounter3",    ctr,    read_hpmcounter },
5345      [CSR_HPMCOUNTER4]    = { "hpmcounter4",    ctr,    read_hpmcounter },
5346      [CSR_HPMCOUNTER5]    = { "hpmcounter5",    ctr,    read_hpmcounter },
5347      [CSR_HPMCOUNTER6]    = { "hpmcounter6",    ctr,    read_hpmcounter },
5348      [CSR_HPMCOUNTER7]    = { "hpmcounter7",    ctr,    read_hpmcounter },
5349      [CSR_HPMCOUNTER8]    = { "hpmcounter8",    ctr,    read_hpmcounter },
5350      [CSR_HPMCOUNTER9]    = { "hpmcounter9",    ctr,    read_hpmcounter },
5351      [CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,    read_hpmcounter },
5352      [CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,    read_hpmcounter },
5353      [CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,    read_hpmcounter },
5354      [CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,    read_hpmcounter },
5355      [CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,    read_hpmcounter },
5356      [CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,    read_hpmcounter },
5357      [CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,    read_hpmcounter },
5358      [CSR_HPMCOUNTER17]   = { "hpmcounter17",   ctr,    read_hpmcounter },
5359      [CSR_HPMCOUNTER18]   = { "hpmcounter18",   ctr,    read_hpmcounter },
5360      [CSR_HPMCOUNTER19]   = { "hpmcounter19",   ctr,    read_hpmcounter },
5361      [CSR_HPMCOUNTER20]   = { "hpmcounter20",   ctr,    read_hpmcounter },
5362      [CSR_HPMCOUNTER21]   = { "hpmcounter21",   ctr,    read_hpmcounter },
5363      [CSR_HPMCOUNTER22]   = { "hpmcounter22",   ctr,    read_hpmcounter },
5364      [CSR_HPMCOUNTER23]   = { "hpmcounter23",   ctr,    read_hpmcounter },
5365      [CSR_HPMCOUNTER24]   = { "hpmcounter24",   ctr,    read_hpmcounter },
5366      [CSR_HPMCOUNTER25]   = { "hpmcounter25",   ctr,    read_hpmcounter },
5367      [CSR_HPMCOUNTER26]   = { "hpmcounter26",   ctr,    read_hpmcounter },
5368      [CSR_HPMCOUNTER27]   = { "hpmcounter27",   ctr,    read_hpmcounter },
5369      [CSR_HPMCOUNTER28]   = { "hpmcounter28",   ctr,    read_hpmcounter },
5370      [CSR_HPMCOUNTER29]   = { "hpmcounter29",   ctr,    read_hpmcounter },
5371      [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,    read_hpmcounter },
5372      [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,    read_hpmcounter },
5373  
5374      [CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   mctr,    read_hpmcounter,
5375                               write_mhpmcounter                         },
5376      [CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   mctr,    read_hpmcounter,
5377                               write_mhpmcounter                         },
5378      [CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   mctr,    read_hpmcounter,
5379                               write_mhpmcounter                         },
5380      [CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   mctr,    read_hpmcounter,
5381                               write_mhpmcounter                         },
5382      [CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   mctr,    read_hpmcounter,
5383                               write_mhpmcounter                         },
5384      [CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   mctr,    read_hpmcounter,
5385                               write_mhpmcounter                         },
5386      [CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   mctr,    read_hpmcounter,
5387                               write_mhpmcounter                         },
5388      [CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  mctr,    read_hpmcounter,
5389                               write_mhpmcounter                         },
5390      [CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  mctr,    read_hpmcounter,
5391                               write_mhpmcounter                         },
5392      [CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  mctr,    read_hpmcounter,
5393                               write_mhpmcounter                         },
5394      [CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  mctr,    read_hpmcounter,
5395                               write_mhpmcounter                         },
5396      [CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  mctr,    read_hpmcounter,
5397                               write_mhpmcounter                         },
5398      [CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  mctr,    read_hpmcounter,
5399                               write_mhpmcounter                         },
5400      [CSR_MHPMCOUNTER16]  = { "mhpmcounter16",  mctr,    read_hpmcounter,
5401                               write_mhpmcounter                         },
5402      [CSR_MHPMCOUNTER17]  = { "mhpmcounter17",  mctr,    read_hpmcounter,
5403                               write_mhpmcounter                         },
5404      [CSR_MHPMCOUNTER18]  = { "mhpmcounter18",  mctr,    read_hpmcounter,
5405                               write_mhpmcounter                         },
5406      [CSR_MHPMCOUNTER19]  = { "mhpmcounter19",  mctr,    read_hpmcounter,
5407                               write_mhpmcounter                         },
5408      [CSR_MHPMCOUNTER20]  = { "mhpmcounter20",  mctr,    read_hpmcounter,
5409                               write_mhpmcounter                         },
5410      [CSR_MHPMCOUNTER21]  = { "mhpmcounter21",  mctr,    read_hpmcounter,
5411                               write_mhpmcounter                         },
5412      [CSR_MHPMCOUNTER22]  = { "mhpmcounter22",  mctr,    read_hpmcounter,
5413                               write_mhpmcounter                         },
5414      [CSR_MHPMCOUNTER23]  = { "mhpmcounter23",  mctr,    read_hpmcounter,
5415                               write_mhpmcounter                         },
5416      [CSR_MHPMCOUNTER24]  = { "mhpmcounter24",  mctr,    read_hpmcounter,
5417                               write_mhpmcounter                         },
5418      [CSR_MHPMCOUNTER25]  = { "mhpmcounter25",  mctr,    read_hpmcounter,
5419                               write_mhpmcounter                         },
5420      [CSR_MHPMCOUNTER26]  = { "mhpmcounter26",  mctr,    read_hpmcounter,
5421                               write_mhpmcounter                         },
5422      [CSR_MHPMCOUNTER27]  = { "mhpmcounter27",  mctr,    read_hpmcounter,
5423                               write_mhpmcounter                         },
5424      [CSR_MHPMCOUNTER28]  = { "mhpmcounter28",  mctr,    read_hpmcounter,
5425                               write_mhpmcounter                         },
5426      [CSR_MHPMCOUNTER29]  = { "mhpmcounter29",  mctr,    read_hpmcounter,
5427                               write_mhpmcounter                         },
5428      [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  mctr,    read_hpmcounter,
5429                               write_mhpmcounter                         },
5430      [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  mctr,    read_hpmcounter,
5431                               write_mhpmcounter                         },
5432  
5433      [CSR_MCOUNTINHIBIT]  = { "mcountinhibit",  any, read_mcountinhibit,
5434                               write_mcountinhibit,
5435                               .min_priv_ver = PRIV_VERSION_1_11_0       },
5436  
5437      [CSR_MCYCLECFG]      = { "mcyclecfg",   smcntrpmf, read_mcyclecfg,
5438                               write_mcyclecfg,
5439                               .min_priv_ver = PRIV_VERSION_1_12_0       },
5440      [CSR_MINSTRETCFG]    = { "minstretcfg", smcntrpmf, read_minstretcfg,
5441                               write_minstretcfg,
5442                               .min_priv_ver = PRIV_VERSION_1_12_0       },
5443  
5444      [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_mhpmevent,
5445                               write_mhpmevent                           },
5446      [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_mhpmevent,
5447                               write_mhpmevent                           },
5448      [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_mhpmevent,
5449                               write_mhpmevent                           },
5450      [CSR_MHPMEVENT6]     = { "mhpmevent6",     any,    read_mhpmevent,
5451                               write_mhpmevent                           },
5452      [CSR_MHPMEVENT7]     = { "mhpmevent7",     any,    read_mhpmevent,
5453                               write_mhpmevent                           },
5454      [CSR_MHPMEVENT8]     = { "mhpmevent8",     any,    read_mhpmevent,
5455                               write_mhpmevent                           },
5456      [CSR_MHPMEVENT9]     = { "mhpmevent9",     any,    read_mhpmevent,
5457                               write_mhpmevent                           },
5458      [CSR_MHPMEVENT10]    = { "mhpmevent10",    any,    read_mhpmevent,
5459                               write_mhpmevent                           },
5460      [CSR_MHPMEVENT11]    = { "mhpmevent11",    any,    read_mhpmevent,
5461                               write_mhpmevent                           },
5462      [CSR_MHPMEVENT12]    = { "mhpmevent12",    any,    read_mhpmevent,
5463                               write_mhpmevent                           },
5464      [CSR_MHPMEVENT13]    = { "mhpmevent13",    any,    read_mhpmevent,
5465                               write_mhpmevent                           },
5466      [CSR_MHPMEVENT14]    = { "mhpmevent14",    any,    read_mhpmevent,
5467                               write_mhpmevent                           },
5468      [CSR_MHPMEVENT15]    = { "mhpmevent15",    any,    read_mhpmevent,
5469                               write_mhpmevent                           },
5470      [CSR_MHPMEVENT16]    = { "mhpmevent16",    any,    read_mhpmevent,
5471                               write_mhpmevent                           },
5472      [CSR_MHPMEVENT17]    = { "mhpmevent17",    any,    read_mhpmevent,
5473                               write_mhpmevent                           },
5474      [CSR_MHPMEVENT18]    = { "mhpmevent18",    any,    read_mhpmevent,
5475                               write_mhpmevent                           },
5476      [CSR_MHPMEVENT19]    = { "mhpmevent19",    any,    read_mhpmevent,
5477                               write_mhpmevent                           },
5478      [CSR_MHPMEVENT20]    = { "mhpmevent20",    any,    read_mhpmevent,
5479                               write_mhpmevent                           },
5480      [CSR_MHPMEVENT21]    = { "mhpmevent21",    any,    read_mhpmevent,
5481                               write_mhpmevent                           },
5482      [CSR_MHPMEVENT22]    = { "mhpmevent22",    any,    read_mhpmevent,
5483                               write_mhpmevent                           },
5484      [CSR_MHPMEVENT23]    = { "mhpmevent23",    any,    read_mhpmevent,
5485                               write_mhpmevent                           },
5486      [CSR_MHPMEVENT24]    = { "mhpmevent24",    any,    read_mhpmevent,
5487                               write_mhpmevent                           },
5488      [CSR_MHPMEVENT25]    = { "mhpmevent25",    any,    read_mhpmevent,
5489                               write_mhpmevent                           },
5490      [CSR_MHPMEVENT26]    = { "mhpmevent26",    any,    read_mhpmevent,
5491                               write_mhpmevent                           },
5492      [CSR_MHPMEVENT27]    = { "mhpmevent27",    any,    read_mhpmevent,
5493                               write_mhpmevent                           },
5494      [CSR_MHPMEVENT28]    = { "mhpmevent28",    any,    read_mhpmevent,
5495                               write_mhpmevent                           },
5496      [CSR_MHPMEVENT29]    = { "mhpmevent29",    any,    read_mhpmevent,
5497                               write_mhpmevent                           },
5498      [CSR_MHPMEVENT30]    = { "mhpmevent30",    any,    read_mhpmevent,
5499                               write_mhpmevent                           },
5500      [CSR_MHPMEVENT31]    = { "mhpmevent31",    any,    read_mhpmevent,
5501                               write_mhpmevent                           },
5502  
5503      [CSR_MCYCLECFGH]     = { "mcyclecfgh",   smcntrpmf_32, read_mcyclecfgh,
5504                               write_mcyclecfgh,
5505                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5506      [CSR_MINSTRETCFGH]   = { "minstretcfgh", smcntrpmf_32, read_minstretcfgh,
5507                               write_minstretcfgh,
5508                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5509  
5510      [CSR_MHPMEVENT3H]    = { "mhpmevent3h",    sscofpmf_32,  read_mhpmeventh,
5511                               write_mhpmeventh,
5512                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5513      [CSR_MHPMEVENT4H]    = { "mhpmevent4h",    sscofpmf_32,  read_mhpmeventh,
5514                               write_mhpmeventh,
5515                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5516      [CSR_MHPMEVENT5H]    = { "mhpmevent5h",    sscofpmf_32,  read_mhpmeventh,
5517                               write_mhpmeventh,
5518                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5519      [CSR_MHPMEVENT6H]    = { "mhpmevent6h",    sscofpmf_32,  read_mhpmeventh,
5520                               write_mhpmeventh,
5521                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5522      [CSR_MHPMEVENT7H]    = { "mhpmevent7h",    sscofpmf_32,  read_mhpmeventh,
5523                               write_mhpmeventh,
5524                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5525      [CSR_MHPMEVENT8H]    = { "mhpmevent8h",    sscofpmf_32,  read_mhpmeventh,
5526                               write_mhpmeventh,
5527                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5528      [CSR_MHPMEVENT9H]    = { "mhpmevent9h",    sscofpmf_32,  read_mhpmeventh,
5529                               write_mhpmeventh,
5530                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5531      [CSR_MHPMEVENT10H]   = { "mhpmevent10h",    sscofpmf_32,  read_mhpmeventh,
5532                               write_mhpmeventh,
5533                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5534      [CSR_MHPMEVENT11H]   = { "mhpmevent11h",    sscofpmf_32,  read_mhpmeventh,
5535                               write_mhpmeventh,
5536                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5537      [CSR_MHPMEVENT12H]   = { "mhpmevent12h",    sscofpmf_32,  read_mhpmeventh,
5538                               write_mhpmeventh,
5539                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5540      [CSR_MHPMEVENT13H]   = { "mhpmevent13h",    sscofpmf_32,  read_mhpmeventh,
5541                               write_mhpmeventh,
5542                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5543      [CSR_MHPMEVENT14H]   = { "mhpmevent14h",    sscofpmf_32,  read_mhpmeventh,
5544                               write_mhpmeventh,
5545                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5546      [CSR_MHPMEVENT15H]   = { "mhpmevent15h",    sscofpmf_32,  read_mhpmeventh,
5547                               write_mhpmeventh,
5548                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5549      [CSR_MHPMEVENT16H]   = { "mhpmevent16h",    sscofpmf_32,  read_mhpmeventh,
5550                               write_mhpmeventh,
5551                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5552      [CSR_MHPMEVENT17H]   = { "mhpmevent17h",    sscofpmf_32,  read_mhpmeventh,
5553                               write_mhpmeventh,
5554                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5555      [CSR_MHPMEVENT18H]   = { "mhpmevent18h",    sscofpmf_32,  read_mhpmeventh,
5556                               write_mhpmeventh,
5557                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5558      [CSR_MHPMEVENT19H]   = { "mhpmevent19h",    sscofpmf_32,  read_mhpmeventh,
5559                               write_mhpmeventh,
5560                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5561      [CSR_MHPMEVENT20H]   = { "mhpmevent20h",    sscofpmf_32,  read_mhpmeventh,
5562                               write_mhpmeventh,
5563                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5564      [CSR_MHPMEVENT21H]   = { "mhpmevent21h",    sscofpmf_32,  read_mhpmeventh,
5565                               write_mhpmeventh,
5566                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5567      [CSR_MHPMEVENT22H]   = { "mhpmevent22h",    sscofpmf_32,  read_mhpmeventh,
5568                               write_mhpmeventh,
5569                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5570      [CSR_MHPMEVENT23H]   = { "mhpmevent23h",    sscofpmf_32,  read_mhpmeventh,
5571                               write_mhpmeventh,
5572                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5573      [CSR_MHPMEVENT24H]   = { "mhpmevent24h",    sscofpmf_32,  read_mhpmeventh,
5574                               write_mhpmeventh,
5575                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5576      [CSR_MHPMEVENT25H]   = { "mhpmevent25h",    sscofpmf_32,  read_mhpmeventh,
5577                               write_mhpmeventh,
5578                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5579      [CSR_MHPMEVENT26H]   = { "mhpmevent26h",    sscofpmf_32,  read_mhpmeventh,
5580                               write_mhpmeventh,
5581                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5582      [CSR_MHPMEVENT27H]   = { "mhpmevent27h",    sscofpmf_32,  read_mhpmeventh,
5583                               write_mhpmeventh,
5584                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5585      [CSR_MHPMEVENT28H]   = { "mhpmevent28h",    sscofpmf_32,  read_mhpmeventh,
5586                               write_mhpmeventh,
5587                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5588      [CSR_MHPMEVENT29H]   = { "mhpmevent29h",    sscofpmf_32,  read_mhpmeventh,
5589                               write_mhpmeventh,
5590                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5591      [CSR_MHPMEVENT30H]   = { "mhpmevent30h",    sscofpmf_32,  read_mhpmeventh,
5592                               write_mhpmeventh,
5593                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5594      [CSR_MHPMEVENT31H]   = { "mhpmevent31h",    sscofpmf_32,  read_mhpmeventh,
5595                               write_mhpmeventh,
5596                               .min_priv_ver = PRIV_VERSION_1_12_0        },
5597  
5598      [CSR_HPMCOUNTER3H]   = { "hpmcounter3h",   ctr32,  read_hpmcounterh },
5599      [CSR_HPMCOUNTER4H]   = { "hpmcounter4h",   ctr32,  read_hpmcounterh },
5600      [CSR_HPMCOUNTER5H]   = { "hpmcounter5h",   ctr32,  read_hpmcounterh },
5601      [CSR_HPMCOUNTER6H]   = { "hpmcounter6h",   ctr32,  read_hpmcounterh },
5602      [CSR_HPMCOUNTER7H]   = { "hpmcounter7h",   ctr32,  read_hpmcounterh },
5603      [CSR_HPMCOUNTER8H]   = { "hpmcounter8h",   ctr32,  read_hpmcounterh },
5604      [CSR_HPMCOUNTER9H]   = { "hpmcounter9h",   ctr32,  read_hpmcounterh },
5605      [CSR_HPMCOUNTER10H]  = { "hpmcounter10h",  ctr32,  read_hpmcounterh },
5606      [CSR_HPMCOUNTER11H]  = { "hpmcounter11h",  ctr32,  read_hpmcounterh },
5607      [CSR_HPMCOUNTER12H]  = { "hpmcounter12h",  ctr32,  read_hpmcounterh },
5608      [CSR_HPMCOUNTER13H]  = { "hpmcounter13h",  ctr32,  read_hpmcounterh },
5609      [CSR_HPMCOUNTER14H]  = { "hpmcounter14h",  ctr32,  read_hpmcounterh },
5610      [CSR_HPMCOUNTER15H]  = { "hpmcounter15h",  ctr32,  read_hpmcounterh },
5611      [CSR_HPMCOUNTER16H]  = { "hpmcounter16h",  ctr32,  read_hpmcounterh },
5612      [CSR_HPMCOUNTER17H]  = { "hpmcounter17h",  ctr32,  read_hpmcounterh },
5613      [CSR_HPMCOUNTER18H]  = { "hpmcounter18h",  ctr32,  read_hpmcounterh },
5614      [CSR_HPMCOUNTER19H]  = { "hpmcounter19h",  ctr32,  read_hpmcounterh },
5615      [CSR_HPMCOUNTER20H]  = { "hpmcounter20h",  ctr32,  read_hpmcounterh },
5616      [CSR_HPMCOUNTER21H]  = { "hpmcounter21h",  ctr32,  read_hpmcounterh },
5617      [CSR_HPMCOUNTER22H]  = { "hpmcounter22h",  ctr32,  read_hpmcounterh },
5618      [CSR_HPMCOUNTER23H]  = { "hpmcounter23h",  ctr32,  read_hpmcounterh },
5619      [CSR_HPMCOUNTER24H]  = { "hpmcounter24h",  ctr32,  read_hpmcounterh },
5620      [CSR_HPMCOUNTER25H]  = { "hpmcounter25h",  ctr32,  read_hpmcounterh },
5621      [CSR_HPMCOUNTER26H]  = { "hpmcounter26h",  ctr32,  read_hpmcounterh },
5622      [CSR_HPMCOUNTER27H]  = { "hpmcounter27h",  ctr32,  read_hpmcounterh },
5623      [CSR_HPMCOUNTER28H]  = { "hpmcounter28h",  ctr32,  read_hpmcounterh },
5624      [CSR_HPMCOUNTER29H]  = { "hpmcounter29h",  ctr32,  read_hpmcounterh },
5625      [CSR_HPMCOUNTER30H]  = { "hpmcounter30h",  ctr32,  read_hpmcounterh },
5626      [CSR_HPMCOUNTER31H]  = { "hpmcounter31h",  ctr32,  read_hpmcounterh },
5627  
5628      [CSR_MHPMCOUNTER3H]  = { "mhpmcounter3h",  mctr32,  read_hpmcounterh,
5629                               write_mhpmcounterh                         },
5630      [CSR_MHPMCOUNTER4H]  = { "mhpmcounter4h",  mctr32,  read_hpmcounterh,
5631                               write_mhpmcounterh                         },
5632      [CSR_MHPMCOUNTER5H]  = { "mhpmcounter5h",  mctr32,  read_hpmcounterh,
5633                               write_mhpmcounterh                         },
5634      [CSR_MHPMCOUNTER6H]  = { "mhpmcounter6h",  mctr32,  read_hpmcounterh,
5635                               write_mhpmcounterh                         },
5636      [CSR_MHPMCOUNTER7H]  = { "mhpmcounter7h",  mctr32,  read_hpmcounterh,
5637                               write_mhpmcounterh                         },
5638      [CSR_MHPMCOUNTER8H]  = { "mhpmcounter8h",  mctr32,  read_hpmcounterh,
5639                               write_mhpmcounterh                         },
5640      [CSR_MHPMCOUNTER9H]  = { "mhpmcounter9h",  mctr32,  read_hpmcounterh,
5641                               write_mhpmcounterh                         },
5642      [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32,  read_hpmcounterh,
5643                               write_mhpmcounterh                         },
5644      [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32,  read_hpmcounterh,
5645                               write_mhpmcounterh                         },
5646      [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32,  read_hpmcounterh,
5647                               write_mhpmcounterh                         },
5648      [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32,  read_hpmcounterh,
5649                               write_mhpmcounterh                         },
5650      [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32,  read_hpmcounterh,
5651                               write_mhpmcounterh                         },
5652      [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32,  read_hpmcounterh,
5653                               write_mhpmcounterh                         },
5654      [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32,  read_hpmcounterh,
5655                               write_mhpmcounterh                         },
5656      [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32,  read_hpmcounterh,
5657                               write_mhpmcounterh                         },
5658      [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32,  read_hpmcounterh,
5659                               write_mhpmcounterh                         },
5660      [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32,  read_hpmcounterh,
5661                               write_mhpmcounterh                         },
5662      [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32,  read_hpmcounterh,
5663                               write_mhpmcounterh                         },
5664      [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32,  read_hpmcounterh,
5665                               write_mhpmcounterh                         },
5666      [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32,  read_hpmcounterh,
5667                               write_mhpmcounterh                         },
5668      [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32,  read_hpmcounterh,
5669                               write_mhpmcounterh                         },
5670      [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32,  read_hpmcounterh,
5671                               write_mhpmcounterh                         },
5672      [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32,  read_hpmcounterh,
5673                               write_mhpmcounterh                         },
5674      [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32,  read_hpmcounterh,
5675                               write_mhpmcounterh                         },
5676      [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32,  read_hpmcounterh,
5677                               write_mhpmcounterh                         },
5678      [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32,  read_hpmcounterh,
5679                               write_mhpmcounterh                         },
5680      [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32,  read_hpmcounterh,
5681                               write_mhpmcounterh                         },
5682      [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32,  read_hpmcounterh,
5683                               write_mhpmcounterh                         },
5684      [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32,  read_hpmcounterh,
5685                               write_mhpmcounterh                         },
5686      [CSR_SCOUNTOVF]      = { "scountovf", sscofpmf,  read_scountovf,
5687                               .min_priv_ver = PRIV_VERSION_1_12_0 },
5688  
5689  #endif /* !CONFIG_USER_ONLY */
5690  };
5691