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