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