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