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