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