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