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