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