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