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