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