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