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