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