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