xref: /openbmc/qemu/target/riscv/csr.c (revision 3521f9cadc29c7d68b73b325ddb46a7acebf6212)
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 "tcg/tcg-cpu.h"
25 #include "pmu.h"
26 #include "time_helper.h"
27 #include "exec/exec-all.h"
28 #include "exec/tb-flush.h"
29 #include "system/cpu-timers.h"
30 #include "qemu/guest-random.h"
31 #include "qapi/error.h"
32 #include <stdbool.h>
33 
34 /* CSR function table public API */
35 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
36 {
37     *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
38 }
39 
40 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
41 {
42     csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
43 }
44 
45 /* Predicates */
46 #if !defined(CONFIG_USER_ONLY)
47 RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
48 {
49     bool virt = env->virt_enabled;
50 
51     if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
52         return RISCV_EXCP_NONE;
53     }
54 
55     if (!(env->mstateen[index] & bit)) {
56         return RISCV_EXCP_ILLEGAL_INST;
57     }
58 
59     if (virt) {
60         if (!(env->hstateen[index] & bit)) {
61             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
62         }
63 
64         if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
65             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
66         }
67     }
68 
69     if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
70         if (!(env->sstateen[index] & bit)) {
71             return RISCV_EXCP_ILLEGAL_INST;
72         }
73     }
74 
75     return RISCV_EXCP_NONE;
76 }
77 #endif
78 
79 static RISCVException fs(CPURISCVState *env, int csrno)
80 {
81 #if !defined(CONFIG_USER_ONLY)
82     if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
83         !riscv_cpu_cfg(env)->ext_zfinx) {
84         return RISCV_EXCP_ILLEGAL_INST;
85     }
86 
87     if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
88         return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
89     }
90 #endif
91     return RISCV_EXCP_NONE;
92 }
93 
94 static RISCVException vs(CPURISCVState *env, int csrno)
95 {
96     if (riscv_cpu_cfg(env)->ext_zve32x) {
97 #if !defined(CONFIG_USER_ONLY)
98         if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
99             return RISCV_EXCP_ILLEGAL_INST;
100         }
101 #endif
102         return RISCV_EXCP_NONE;
103     }
104     return RISCV_EXCP_ILLEGAL_INST;
105 }
106 
107 static RISCVException ctr(CPURISCVState *env, int csrno)
108 {
109 #if !defined(CONFIG_USER_ONLY)
110     RISCVCPU *cpu = env_archcpu(env);
111     int ctr_index;
112     target_ulong ctr_mask;
113     int base_csrno = CSR_CYCLE;
114     bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
115 
116     if (rv32 && csrno >= CSR_CYCLEH) {
117         /* Offset for RV32 hpmcounternh counters */
118         base_csrno += 0x80;
119     }
120     ctr_index = csrno - base_csrno;
121     ctr_mask = BIT(ctr_index);
122 
123     if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
124         (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
125         if (!riscv_cpu_cfg(env)->ext_zicntr) {
126             return RISCV_EXCP_ILLEGAL_INST;
127         }
128 
129         goto skip_ext_pmu_check;
130     }
131 
132     if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
133         /* No counter is enabled in PMU or the counter is out of range */
134         return RISCV_EXCP_ILLEGAL_INST;
135     }
136 
137 skip_ext_pmu_check:
138 
139     if (env->debugger) {
140         return RISCV_EXCP_NONE;
141     }
142 
143     if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
144         return RISCV_EXCP_ILLEGAL_INST;
145     }
146 
147     if (env->virt_enabled) {
148         if (!get_field(env->hcounteren, ctr_mask) ||
149             (env->priv == PRV_U && !get_field(env->scounteren, ctr_mask))) {
150             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
151         }
152     }
153 
154     if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
155         !get_field(env->scounteren, ctr_mask)) {
156         return RISCV_EXCP_ILLEGAL_INST;
157     }
158 
159 #endif
160     return RISCV_EXCP_NONE;
161 }
162 
163 static RISCVException ctr32(CPURISCVState *env, int csrno)
164 {
165     if (riscv_cpu_mxl(env) != MXL_RV32) {
166         return RISCV_EXCP_ILLEGAL_INST;
167     }
168 
169     return ctr(env, csrno);
170 }
171 
172 static RISCVException zcmt(CPURISCVState *env, int csrno)
173 {
174     if (!riscv_cpu_cfg(env)->ext_zcmt) {
175         return RISCV_EXCP_ILLEGAL_INST;
176     }
177 
178 #if !defined(CONFIG_USER_ONLY)
179     RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
180     if (ret != RISCV_EXCP_NONE) {
181         return ret;
182     }
183 #endif
184 
185     return RISCV_EXCP_NONE;
186 }
187 
188 static RISCVException cfi_ss(CPURISCVState *env, int csrno)
189 {
190     if (!env_archcpu(env)->cfg.ext_zicfiss) {
191         return RISCV_EXCP_ILLEGAL_INST;
192     }
193 
194     /* if bcfi not active for current env, access to csr is illegal */
195     if (!cpu_get_bcfien(env)) {
196 #if !defined(CONFIG_USER_ONLY)
197         if (env->debugger) {
198             return RISCV_EXCP_NONE;
199         }
200 #endif
201         return RISCV_EXCP_ILLEGAL_INST;
202     }
203 
204     return RISCV_EXCP_NONE;
205 }
206 
207 #if !defined(CONFIG_USER_ONLY)
208 static RISCVException mctr(CPURISCVState *env, int csrno)
209 {
210     RISCVCPU *cpu = env_archcpu(env);
211     uint32_t pmu_avail_ctrs = cpu->pmu_avail_ctrs;
212     int ctr_index;
213     int base_csrno = CSR_MHPMCOUNTER3;
214 
215     if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) {
216         /* Offset for RV32 mhpmcounternh counters */
217         csrno -= 0x80;
218     }
219 
220     g_assert(csrno >= CSR_MHPMCOUNTER3 && csrno <= CSR_MHPMCOUNTER31);
221 
222     ctr_index = csrno - base_csrno;
223     if ((BIT(ctr_index) & pmu_avail_ctrs >> 3) == 0) {
224         /* The PMU is not enabled or counter is out of range */
225         return RISCV_EXCP_ILLEGAL_INST;
226     }
227 
228     return RISCV_EXCP_NONE;
229 }
230 
231 static RISCVException mctr32(CPURISCVState *env, int csrno)
232 {
233     if (riscv_cpu_mxl(env) != MXL_RV32) {
234         return RISCV_EXCP_ILLEGAL_INST;
235     }
236 
237     return mctr(env, csrno);
238 }
239 
240 static RISCVException sscofpmf(CPURISCVState *env, int csrno)
241 {
242     if (!riscv_cpu_cfg(env)->ext_sscofpmf) {
243         return RISCV_EXCP_ILLEGAL_INST;
244     }
245 
246     return RISCV_EXCP_NONE;
247 }
248 
249 static RISCVException sscofpmf_32(CPURISCVState *env, int csrno)
250 {
251     if (riscv_cpu_mxl(env) != MXL_RV32) {
252         return RISCV_EXCP_ILLEGAL_INST;
253     }
254 
255     return sscofpmf(env, csrno);
256 }
257 
258 static RISCVException smcntrpmf(CPURISCVState *env, int csrno)
259 {
260     if (!riscv_cpu_cfg(env)->ext_smcntrpmf) {
261         return RISCV_EXCP_ILLEGAL_INST;
262     }
263 
264     return RISCV_EXCP_NONE;
265 }
266 
267 static RISCVException smcntrpmf_32(CPURISCVState *env, int csrno)
268 {
269     if (riscv_cpu_mxl(env) != MXL_RV32) {
270         return RISCV_EXCP_ILLEGAL_INST;
271     }
272 
273     return smcntrpmf(env, csrno);
274 }
275 
276 static RISCVException any(CPURISCVState *env, int csrno)
277 {
278     return RISCV_EXCP_NONE;
279 }
280 
281 static RISCVException any32(CPURISCVState *env, int csrno)
282 {
283     if (riscv_cpu_mxl(env) != MXL_RV32) {
284         return RISCV_EXCP_ILLEGAL_INST;
285     }
286 
287     return any(env, csrno);
288 
289 }
290 
291 static RISCVException aia_any(CPURISCVState *env, int csrno)
292 {
293     if (!riscv_cpu_cfg(env)->ext_smaia) {
294         return RISCV_EXCP_ILLEGAL_INST;
295     }
296 
297     return any(env, csrno);
298 }
299 
300 static RISCVException aia_any32(CPURISCVState *env, int csrno)
301 {
302     if (!riscv_cpu_cfg(env)->ext_smaia) {
303         return RISCV_EXCP_ILLEGAL_INST;
304     }
305 
306     return any32(env, csrno);
307 }
308 
309 static RISCVException csrind_any(CPURISCVState *env, int csrno)
310 {
311     if (!riscv_cpu_cfg(env)->ext_smcsrind) {
312         return RISCV_EXCP_ILLEGAL_INST;
313     }
314 
315     return RISCV_EXCP_NONE;
316 }
317 
318 static RISCVException csrind_or_aia_any(CPURISCVState *env, int csrno)
319 {
320     if (!riscv_cpu_cfg(env)->ext_smaia && !riscv_cpu_cfg(env)->ext_smcsrind) {
321         return RISCV_EXCP_ILLEGAL_INST;
322     }
323 
324     return any(env, csrno);
325 }
326 
327 static RISCVException smode(CPURISCVState *env, int csrno)
328 {
329     if (riscv_has_ext(env, RVS)) {
330         return RISCV_EXCP_NONE;
331     }
332 
333     return RISCV_EXCP_ILLEGAL_INST;
334 }
335 
336 static RISCVException smode32(CPURISCVState *env, int csrno)
337 {
338     if (riscv_cpu_mxl(env) != MXL_RV32) {
339         return RISCV_EXCP_ILLEGAL_INST;
340     }
341 
342     return smode(env, csrno);
343 }
344 
345 static RISCVException aia_smode(CPURISCVState *env, int csrno)
346 {
347     int ret;
348 
349     if (!riscv_cpu_cfg(env)->ext_ssaia) {
350         return RISCV_EXCP_ILLEGAL_INST;
351     }
352 
353     if (csrno == CSR_STOPEI) {
354         ret = smstateen_acc_ok(env, 0, SMSTATEEN0_IMSIC);
355     } else {
356         ret = smstateen_acc_ok(env, 0, SMSTATEEN0_AIA);
357     }
358 
359     if (ret != RISCV_EXCP_NONE) {
360         return ret;
361     }
362 
363     return smode(env, csrno);
364 }
365 
366 static RISCVException aia_smode32(CPURISCVState *env, int csrno)
367 {
368     int ret;
369 
370     if (!riscv_cpu_cfg(env)->ext_ssaia) {
371         return RISCV_EXCP_ILLEGAL_INST;
372     }
373 
374     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_AIA);
375     if (ret != RISCV_EXCP_NONE) {
376         return ret;
377     }
378 
379     return smode32(env, csrno);
380 }
381 
382 static RISCVException scountinhibit_pred(CPURISCVState *env, int csrno)
383 {
384     RISCVCPU *cpu = env_archcpu(env);
385 
386     if (!cpu->cfg.ext_ssccfg || !cpu->cfg.ext_smcdeleg) {
387         return RISCV_EXCP_ILLEGAL_INST;
388     }
389 
390     if (env->virt_enabled) {
391         return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
392     }
393 
394     return smode(env, csrno);
395 }
396 
397 static bool csrind_extensions_present(CPURISCVState *env)
398 {
399     return riscv_cpu_cfg(env)->ext_smcsrind || riscv_cpu_cfg(env)->ext_sscsrind;
400 }
401 
402 static bool aia_extensions_present(CPURISCVState *env)
403 {
404     return riscv_cpu_cfg(env)->ext_smaia || riscv_cpu_cfg(env)->ext_ssaia;
405 }
406 
407 static bool csrind_or_aia_extensions_present(CPURISCVState *env)
408 {
409     return csrind_extensions_present(env) || aia_extensions_present(env);
410 }
411 
412 static RISCVException csrind_smode(CPURISCVState *env, int csrno)
413 {
414     if (!csrind_extensions_present(env)) {
415         return RISCV_EXCP_ILLEGAL_INST;
416     }
417 
418     return smode(env, csrno);
419 }
420 
421 static RISCVException csrind_or_aia_smode(CPURISCVState *env, int csrno)
422 {
423     if (!csrind_or_aia_extensions_present(env)) {
424         return RISCV_EXCP_ILLEGAL_INST;
425     }
426 
427     return smode(env, csrno);
428 }
429 
430 static RISCVException hmode(CPURISCVState *env, int csrno)
431 {
432     if (riscv_has_ext(env, RVH)) {
433         return RISCV_EXCP_NONE;
434     }
435 
436     return RISCV_EXCP_ILLEGAL_INST;
437 }
438 
439 static RISCVException hmode32(CPURISCVState *env, int csrno)
440 {
441     if (riscv_cpu_mxl(env) != MXL_RV32) {
442         return RISCV_EXCP_ILLEGAL_INST;
443     }
444 
445     return hmode(env, csrno);
446 
447 }
448 
449 static RISCVException csrind_hmode(CPURISCVState *env, int csrno)
450 {
451     if (!csrind_extensions_present(env)) {
452         return RISCV_EXCP_ILLEGAL_INST;
453     }
454 
455     return hmode(env, csrno);
456 }
457 
458 static RISCVException csrind_or_aia_hmode(CPURISCVState *env, int csrno)
459 {
460     if (!csrind_or_aia_extensions_present(env)) {
461         return RISCV_EXCP_ILLEGAL_INST;
462     }
463 
464     return hmode(env, csrno);
465 }
466 
467 static RISCVException umode(CPURISCVState *env, int csrno)
468 {
469     if (riscv_has_ext(env, RVU)) {
470         return RISCV_EXCP_NONE;
471     }
472 
473     return RISCV_EXCP_ILLEGAL_INST;
474 }
475 
476 static RISCVException umode32(CPURISCVState *env, int csrno)
477 {
478     if (riscv_cpu_mxl(env) != MXL_RV32) {
479         return RISCV_EXCP_ILLEGAL_INST;
480     }
481 
482     return umode(env, csrno);
483 }
484 
485 static RISCVException mstateen(CPURISCVState *env, int csrno)
486 {
487     if (!riscv_cpu_cfg(env)->ext_smstateen) {
488         return RISCV_EXCP_ILLEGAL_INST;
489     }
490 
491     return any(env, csrno);
492 }
493 
494 static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
495 {
496     if (!riscv_cpu_cfg(env)->ext_smstateen) {
497         return RISCV_EXCP_ILLEGAL_INST;
498     }
499 
500     RISCVException ret = hmode(env, csrno);
501     if (ret != RISCV_EXCP_NONE) {
502         return ret;
503     }
504 
505     if (env->debugger) {
506         return RISCV_EXCP_NONE;
507     }
508 
509     if (env->priv < PRV_M) {
510         if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
511             return RISCV_EXCP_ILLEGAL_INST;
512         }
513     }
514 
515     return RISCV_EXCP_NONE;
516 }
517 
518 static RISCVException hstateen(CPURISCVState *env, int csrno)
519 {
520     return hstateen_pred(env, csrno, CSR_HSTATEEN0);
521 }
522 
523 static RISCVException hstateenh(CPURISCVState *env, int csrno)
524 {
525     return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
526 }
527 
528 static RISCVException sstateen(CPURISCVState *env, int csrno)
529 {
530     bool virt = env->virt_enabled;
531     int index = csrno - CSR_SSTATEEN0;
532 
533     if (!riscv_cpu_cfg(env)->ext_smstateen) {
534         return RISCV_EXCP_ILLEGAL_INST;
535     }
536 
537     RISCVException ret = smode(env, csrno);
538     if (ret != RISCV_EXCP_NONE) {
539         return ret;
540     }
541 
542     if (env->debugger) {
543         return RISCV_EXCP_NONE;
544     }
545 
546     if (env->priv < PRV_M) {
547         if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
548             return RISCV_EXCP_ILLEGAL_INST;
549         }
550 
551         if (virt) {
552             if (!(env->hstateen[index] & SMSTATEEN_STATEEN)) {
553                 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
554             }
555         }
556     }
557 
558     return RISCV_EXCP_NONE;
559 }
560 
561 static RISCVException sstc(CPURISCVState *env, int csrno)
562 {
563     bool hmode_check = false;
564 
565     if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn) {
566         return RISCV_EXCP_ILLEGAL_INST;
567     }
568 
569     if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
570         hmode_check = true;
571     }
572 
573     RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
574     if (ret != RISCV_EXCP_NONE) {
575         return ret;
576     }
577 
578     if (env->debugger) {
579         return RISCV_EXCP_NONE;
580     }
581 
582     if (env->priv == PRV_M) {
583         return RISCV_EXCP_NONE;
584     }
585 
586     /*
587      * No need of separate function for rv32 as menvcfg stores both menvcfg
588      * menvcfgh for RV32.
589      */
590     if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
591           get_field(env->menvcfg, MENVCFG_STCE))) {
592         return RISCV_EXCP_ILLEGAL_INST;
593     }
594 
595     if (env->virt_enabled) {
596         if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
597               get_field(env->henvcfg, HENVCFG_STCE))) {
598             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
599         }
600     }
601 
602     return RISCV_EXCP_NONE;
603 }
604 
605 static RISCVException sstc_32(CPURISCVState *env, int csrno)
606 {
607     if (riscv_cpu_mxl(env) != MXL_RV32) {
608         return RISCV_EXCP_ILLEGAL_INST;
609     }
610 
611     return sstc(env, csrno);
612 }
613 
614 static RISCVException satp(CPURISCVState *env, int csrno)
615 {
616     if (env->priv == PRV_S && !env->virt_enabled &&
617         get_field(env->mstatus, MSTATUS_TVM)) {
618         return RISCV_EXCP_ILLEGAL_INST;
619     }
620     if (env->priv == PRV_S && env->virt_enabled &&
621         get_field(env->hstatus, HSTATUS_VTVM)) {
622         return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
623     }
624 
625     return smode(env, csrno);
626 }
627 
628 static RISCVException hgatp(CPURISCVState *env, int csrno)
629 {
630     if (env->priv == PRV_S && !env->virt_enabled &&
631         get_field(env->mstatus, MSTATUS_TVM)) {
632         return RISCV_EXCP_ILLEGAL_INST;
633     }
634 
635     return hmode(env, csrno);
636 }
637 
638 static RISCVException aia_hmode(CPURISCVState *env, int csrno)
639 {
640     int ret;
641 
642     if (!riscv_cpu_cfg(env)->ext_ssaia) {
643         return RISCV_EXCP_ILLEGAL_INST;
644      }
645 
646     if (csrno == CSR_VSTOPEI) {
647         ret = smstateen_acc_ok(env, 0, SMSTATEEN0_IMSIC);
648     } else {
649         ret = smstateen_acc_ok(env, 0, SMSTATEEN0_AIA);
650     }
651 
652     if (ret != RISCV_EXCP_NONE) {
653         return ret;
654     }
655 
656     return hmode(env, csrno);
657 }
658 
659 static RISCVException aia_hmode32(CPURISCVState *env, int csrno)
660 {
661     int ret;
662 
663     if (!riscv_cpu_cfg(env)->ext_ssaia) {
664         return RISCV_EXCP_ILLEGAL_INST;
665      }
666 
667     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_AIA);
668     if (ret != RISCV_EXCP_NONE) {
669         return ret;
670     }
671 
672     if (!riscv_cpu_cfg(env)->ext_ssaia) {
673         return RISCV_EXCP_ILLEGAL_INST;
674     }
675 
676     return hmode32(env, csrno);
677 }
678 
679 static RISCVException dbltrp_hmode(CPURISCVState *env, int csrno)
680 {
681     if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
682         return RISCV_EXCP_NONE;
683     }
684 
685     return hmode(env, csrno);
686 }
687 
688 static RISCVException pmp(CPURISCVState *env, int csrno)
689 {
690     if (riscv_cpu_cfg(env)->pmp) {
691         if (csrno <= CSR_PMPCFG3) {
692             uint32_t reg_index = csrno - CSR_PMPCFG0;
693 
694             /* TODO: RV128 restriction check */
695             if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
696                 return RISCV_EXCP_ILLEGAL_INST;
697             }
698         }
699 
700         return RISCV_EXCP_NONE;
701     }
702 
703     return RISCV_EXCP_ILLEGAL_INST;
704 }
705 
706 static RISCVException have_mseccfg(CPURISCVState *env, int csrno)
707 {
708     if (riscv_cpu_cfg(env)->ext_smepmp) {
709         return RISCV_EXCP_NONE;
710     }
711     if (riscv_cpu_cfg(env)->ext_zkr) {
712         return RISCV_EXCP_NONE;
713     }
714     if (riscv_cpu_cfg(env)->ext_smmpm) {
715         return RISCV_EXCP_NONE;
716     }
717 
718     return RISCV_EXCP_ILLEGAL_INST;
719 }
720 
721 static RISCVException debug(CPURISCVState *env, int csrno)
722 {
723     if (riscv_cpu_cfg(env)->debug) {
724         return RISCV_EXCP_NONE;
725     }
726 
727     return RISCV_EXCP_ILLEGAL_INST;
728 }
729 
730 static RISCVException rnmi(CPURISCVState *env, int csrno)
731 {
732     RISCVCPU *cpu = env_archcpu(env);
733 
734     if (cpu->cfg.ext_smrnmi) {
735         return RISCV_EXCP_NONE;
736     }
737 
738     return RISCV_EXCP_ILLEGAL_INST;
739 }
740 #endif
741 
742 static RISCVException seed(CPURISCVState *env, int csrno)
743 {
744     if (!riscv_cpu_cfg(env)->ext_zkr) {
745         return RISCV_EXCP_ILLEGAL_INST;
746     }
747 
748 #if !defined(CONFIG_USER_ONLY)
749     if (env->debugger) {
750         return RISCV_EXCP_NONE;
751     }
752 
753     /*
754      * With a CSR read-write instruction:
755      * 1) The seed CSR is always available in machine mode as normal.
756      * 2) Attempted access to seed from virtual modes VS and VU always raises
757      * an exception(virtual instruction exception only if mseccfg.sseed=1).
758      * 3) Without the corresponding access control bit set to 1, any attempted
759      * access to seed from U, S or HS modes will raise an illegal instruction
760      * exception.
761      */
762     if (env->priv == PRV_M) {
763         return RISCV_EXCP_NONE;
764     } else if (env->virt_enabled) {
765         if (env->mseccfg & MSECCFG_SSEED) {
766             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
767         } else {
768             return RISCV_EXCP_ILLEGAL_INST;
769         }
770     } else {
771         if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) {
772             return RISCV_EXCP_NONE;
773         } else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) {
774             return RISCV_EXCP_NONE;
775         } else {
776             return RISCV_EXCP_ILLEGAL_INST;
777         }
778     }
779 #else
780     return RISCV_EXCP_NONE;
781 #endif
782 }
783 
784 /* zicfiss CSR_SSP read and write */
785 static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
786 {
787     *val = env->ssp;
788     return RISCV_EXCP_NONE;
789 }
790 
791 static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
792 {
793     env->ssp = val;
794     return RISCV_EXCP_NONE;
795 }
796 
797 /* User Floating-Point CSRs */
798 static RISCVException read_fflags(CPURISCVState *env, int csrno,
799                                   target_ulong *val)
800 {
801     *val = riscv_cpu_get_fflags(env);
802     return RISCV_EXCP_NONE;
803 }
804 
805 static RISCVException write_fflags(CPURISCVState *env, int csrno,
806                                    target_ulong val)
807 {
808 #if !defined(CONFIG_USER_ONLY)
809     if (riscv_has_ext(env, RVF)) {
810         env->mstatus |= MSTATUS_FS;
811     }
812 #endif
813     riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
814     return RISCV_EXCP_NONE;
815 }
816 
817 static RISCVException read_frm(CPURISCVState *env, int csrno,
818                                target_ulong *val)
819 {
820     *val = env->frm;
821     return RISCV_EXCP_NONE;
822 }
823 
824 static RISCVException write_frm(CPURISCVState *env, int csrno,
825                                 target_ulong val)
826 {
827 #if !defined(CONFIG_USER_ONLY)
828     if (riscv_has_ext(env, RVF)) {
829         env->mstatus |= MSTATUS_FS;
830     }
831 #endif
832     env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
833     return RISCV_EXCP_NONE;
834 }
835 
836 static RISCVException read_fcsr(CPURISCVState *env, int csrno,
837                                 target_ulong *val)
838 {
839     *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
840         | (env->frm << FSR_RD_SHIFT);
841     return RISCV_EXCP_NONE;
842 }
843 
844 static RISCVException write_fcsr(CPURISCVState *env, int csrno,
845                                  target_ulong val)
846 {
847 #if !defined(CONFIG_USER_ONLY)
848     if (riscv_has_ext(env, RVF)) {
849         env->mstatus |= MSTATUS_FS;
850     }
851 #endif
852     env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
853     riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
854     return RISCV_EXCP_NONE;
855 }
856 
857 static RISCVException read_vtype(CPURISCVState *env, int csrno,
858                                  target_ulong *val)
859 {
860     uint64_t vill;
861     switch (env->xl) {
862     case MXL_RV32:
863         vill = (uint32_t)env->vill << 31;
864         break;
865     case MXL_RV64:
866         vill = (uint64_t)env->vill << 63;
867         break;
868     default:
869         g_assert_not_reached();
870     }
871     *val = (target_ulong)vill | env->vtype;
872     return RISCV_EXCP_NONE;
873 }
874 
875 static RISCVException read_vl(CPURISCVState *env, int csrno,
876                               target_ulong *val)
877 {
878     *val = env->vl;
879     return RISCV_EXCP_NONE;
880 }
881 
882 static RISCVException read_vlenb(CPURISCVState *env, int csrno,
883                                  target_ulong *val)
884 {
885     *val = riscv_cpu_cfg(env)->vlenb;
886     return RISCV_EXCP_NONE;
887 }
888 
889 static RISCVException read_vxrm(CPURISCVState *env, int csrno,
890                                 target_ulong *val)
891 {
892     *val = env->vxrm;
893     return RISCV_EXCP_NONE;
894 }
895 
896 static RISCVException write_vxrm(CPURISCVState *env, int csrno,
897                                  target_ulong val)
898 {
899 #if !defined(CONFIG_USER_ONLY)
900     env->mstatus |= MSTATUS_VS;
901 #endif
902     env->vxrm = val;
903     return RISCV_EXCP_NONE;
904 }
905 
906 static RISCVException read_vxsat(CPURISCVState *env, int csrno,
907                                  target_ulong *val)
908 {
909     *val = env->vxsat & BIT(0);
910     return RISCV_EXCP_NONE;
911 }
912 
913 static RISCVException write_vxsat(CPURISCVState *env, int csrno,
914                                   target_ulong val)
915 {
916 #if !defined(CONFIG_USER_ONLY)
917     env->mstatus |= MSTATUS_VS;
918 #endif
919     env->vxsat = val & BIT(0);
920     return RISCV_EXCP_NONE;
921 }
922 
923 static RISCVException read_vstart(CPURISCVState *env, int csrno,
924                                   target_ulong *val)
925 {
926     *val = env->vstart;
927     return RISCV_EXCP_NONE;
928 }
929 
930 static RISCVException write_vstart(CPURISCVState *env, int csrno,
931                                    target_ulong val)
932 {
933 #if !defined(CONFIG_USER_ONLY)
934     env->mstatus |= MSTATUS_VS;
935 #endif
936     /*
937      * The vstart CSR is defined to have only enough writable bits
938      * to hold the largest element index, i.e. lg2(VLEN) bits.
939      */
940     env->vstart = val & ~(~0ULL << ctzl(riscv_cpu_cfg(env)->vlenb << 3));
941     return RISCV_EXCP_NONE;
942 }
943 
944 static RISCVException read_vcsr(CPURISCVState *env, int csrno,
945                                 target_ulong *val)
946 {
947     *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
948     return RISCV_EXCP_NONE;
949 }
950 
951 static RISCVException write_vcsr(CPURISCVState *env, int csrno,
952                                  target_ulong val)
953 {
954 #if !defined(CONFIG_USER_ONLY)
955     env->mstatus |= MSTATUS_VS;
956 #endif
957     env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
958     env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
959     return RISCV_EXCP_NONE;
960 }
961 
962 #if defined(CONFIG_USER_ONLY)
963 /* User Timers and Counters */
964 static target_ulong get_ticks(bool shift)
965 {
966     int64_t val = cpu_get_host_ticks();
967     target_ulong result = shift ? val >> 32 : val;
968 
969     return result;
970 }
971 
972 static RISCVException read_time(CPURISCVState *env, int csrno,
973                                 target_ulong *val)
974 {
975     *val = cpu_get_host_ticks();
976     return RISCV_EXCP_NONE;
977 }
978 
979 static RISCVException read_timeh(CPURISCVState *env, int csrno,
980                                  target_ulong *val)
981 {
982     *val = cpu_get_host_ticks() >> 32;
983     return RISCV_EXCP_NONE;
984 }
985 
986 static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
987                                       target_ulong *val)
988 {
989     *val = get_ticks(false);
990     return RISCV_EXCP_NONE;
991 }
992 
993 static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
994                                        target_ulong *val)
995 {
996     *val = get_ticks(true);
997     return RISCV_EXCP_NONE;
998 }
999 
1000 #else /* CONFIG_USER_ONLY */
1001 
1002 static RISCVException read_mcyclecfg(CPURISCVState *env, int csrno,
1003                                      target_ulong *val)
1004 {
1005     *val = env->mcyclecfg;
1006     return RISCV_EXCP_NONE;
1007 }
1008 
1009 static RISCVException write_mcyclecfg(CPURISCVState *env, int csrno,
1010                                       target_ulong val)
1011 {
1012     uint64_t inh_avail_mask;
1013 
1014     if (riscv_cpu_mxl(env) == MXL_RV32) {
1015         env->mcyclecfg = val;
1016     } else {
1017         /* Set xINH fields if priv mode supported */
1018         inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MCYCLECFG_BIT_MINH;
1019         inh_avail_mask |= riscv_has_ext(env, RVU) ? MCYCLECFG_BIT_UINH : 0;
1020         inh_avail_mask |= riscv_has_ext(env, RVS) ? MCYCLECFG_BIT_SINH : 0;
1021         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1022                            riscv_has_ext(env, RVU)) ? MCYCLECFG_BIT_VUINH : 0;
1023         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1024                            riscv_has_ext(env, RVS)) ? MCYCLECFG_BIT_VSINH : 0;
1025         env->mcyclecfg = val & inh_avail_mask;
1026     }
1027 
1028     return RISCV_EXCP_NONE;
1029 }
1030 
1031 static RISCVException read_mcyclecfgh(CPURISCVState *env, int csrno,
1032                                       target_ulong *val)
1033 {
1034     *val = env->mcyclecfgh;
1035     return RISCV_EXCP_NONE;
1036 }
1037 
1038 static RISCVException write_mcyclecfgh(CPURISCVState *env, int csrno,
1039                                        target_ulong val)
1040 {
1041     target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
1042                                                  MCYCLECFGH_BIT_MINH);
1043 
1044     /* Set xINH fields if priv mode supported */
1045     inh_avail_mask |= riscv_has_ext(env, RVU) ? MCYCLECFGH_BIT_UINH : 0;
1046     inh_avail_mask |= riscv_has_ext(env, RVS) ? MCYCLECFGH_BIT_SINH : 0;
1047     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1048                        riscv_has_ext(env, RVU)) ? MCYCLECFGH_BIT_VUINH : 0;
1049     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1050                        riscv_has_ext(env, RVS)) ? MCYCLECFGH_BIT_VSINH : 0;
1051 
1052     env->mcyclecfgh = val & inh_avail_mask;
1053     return RISCV_EXCP_NONE;
1054 }
1055 
1056 static RISCVException read_minstretcfg(CPURISCVState *env, int csrno,
1057                                        target_ulong *val)
1058 {
1059     *val = env->minstretcfg;
1060     return RISCV_EXCP_NONE;
1061 }
1062 
1063 static RISCVException write_minstretcfg(CPURISCVState *env, int csrno,
1064                                         target_ulong val)
1065 {
1066     uint64_t inh_avail_mask;
1067 
1068     if (riscv_cpu_mxl(env) == MXL_RV32) {
1069         env->minstretcfg = val;
1070     } else {
1071         inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MINSTRETCFG_BIT_MINH;
1072         inh_avail_mask |= riscv_has_ext(env, RVU) ? MINSTRETCFG_BIT_UINH : 0;
1073         inh_avail_mask |= riscv_has_ext(env, RVS) ? MINSTRETCFG_BIT_SINH : 0;
1074         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1075                            riscv_has_ext(env, RVU)) ? MINSTRETCFG_BIT_VUINH : 0;
1076         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1077                            riscv_has_ext(env, RVS)) ? MINSTRETCFG_BIT_VSINH : 0;
1078         env->minstretcfg = val & inh_avail_mask;
1079     }
1080     return RISCV_EXCP_NONE;
1081 }
1082 
1083 static RISCVException read_minstretcfgh(CPURISCVState *env, int csrno,
1084                                         target_ulong *val)
1085 {
1086     *val = env->minstretcfgh;
1087     return RISCV_EXCP_NONE;
1088 }
1089 
1090 static RISCVException write_minstretcfgh(CPURISCVState *env, int csrno,
1091                                          target_ulong val)
1092 {
1093     target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
1094                                                  MINSTRETCFGH_BIT_MINH);
1095 
1096     inh_avail_mask |= riscv_has_ext(env, RVU) ? MINSTRETCFGH_BIT_UINH : 0;
1097     inh_avail_mask |= riscv_has_ext(env, RVS) ? MINSTRETCFGH_BIT_SINH : 0;
1098     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1099                        riscv_has_ext(env, RVU)) ? MINSTRETCFGH_BIT_VUINH : 0;
1100     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1101                        riscv_has_ext(env, RVS)) ? MINSTRETCFGH_BIT_VSINH : 0;
1102 
1103     env->minstretcfgh = val & inh_avail_mask;
1104     return RISCV_EXCP_NONE;
1105 }
1106 
1107 static RISCVException read_mhpmevent(CPURISCVState *env, int csrno,
1108                                      target_ulong *val)
1109 {
1110     int evt_index = csrno - CSR_MCOUNTINHIBIT;
1111 
1112     *val = env->mhpmevent_val[evt_index];
1113 
1114     return RISCV_EXCP_NONE;
1115 }
1116 
1117 static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
1118                                       target_ulong val)
1119 {
1120     int evt_index = csrno - CSR_MCOUNTINHIBIT;
1121     uint64_t mhpmevt_val = val;
1122     uint64_t inh_avail_mask;
1123 
1124     if (riscv_cpu_mxl(env) == MXL_RV32) {
1125         env->mhpmevent_val[evt_index] = val;
1126         mhpmevt_val = mhpmevt_val |
1127                       ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
1128     } else {
1129         inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MHPMEVENT_BIT_MINH;
1130         inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENT_BIT_UINH : 0;
1131         inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENT_BIT_SINH : 0;
1132         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1133                            riscv_has_ext(env, RVU)) ? MHPMEVENT_BIT_VUINH : 0;
1134         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1135                            riscv_has_ext(env, RVS)) ? MHPMEVENT_BIT_VSINH : 0;
1136         mhpmevt_val = val & inh_avail_mask;
1137         env->mhpmevent_val[evt_index] = mhpmevt_val;
1138     }
1139 
1140     riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
1141 
1142     return RISCV_EXCP_NONE;
1143 }
1144 
1145 static RISCVException read_mhpmeventh(CPURISCVState *env, int csrno,
1146                                       target_ulong *val)
1147 {
1148     int evt_index = csrno - CSR_MHPMEVENT3H + 3;
1149 
1150     *val = env->mhpmeventh_val[evt_index];
1151 
1152     return RISCV_EXCP_NONE;
1153 }
1154 
1155 static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
1156                                        target_ulong val)
1157 {
1158     int evt_index = csrno - CSR_MHPMEVENT3H + 3;
1159     uint64_t mhpmevth_val;
1160     uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
1161     target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
1162                                                   MHPMEVENTH_BIT_MINH);
1163 
1164     inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENTH_BIT_UINH : 0;
1165     inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENTH_BIT_SINH : 0;
1166     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1167                        riscv_has_ext(env, RVU)) ? MHPMEVENTH_BIT_VUINH : 0;
1168     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1169                        riscv_has_ext(env, RVS)) ? MHPMEVENTH_BIT_VSINH : 0;
1170 
1171     mhpmevth_val = val & inh_avail_mask;
1172     mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
1173     env->mhpmeventh_val[evt_index] = mhpmevth_val;
1174 
1175     riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
1176 
1177     return RISCV_EXCP_NONE;
1178 }
1179 
1180 static target_ulong riscv_pmu_ctr_get_fixed_counters_val(CPURISCVState *env,
1181                                                          int counter_idx,
1182                                                          bool upper_half)
1183 {
1184     int inst = riscv_pmu_ctr_monitor_instructions(env, counter_idx);
1185     uint64_t *counter_arr_virt = env->pmu_fixed_ctrs[inst].counter_virt;
1186     uint64_t *counter_arr = env->pmu_fixed_ctrs[inst].counter;
1187     target_ulong result = 0;
1188     uint64_t curr_val = 0;
1189     uint64_t cfg_val = 0;
1190 
1191     if (counter_idx == 0) {
1192         cfg_val = upper_half ? ((uint64_t)env->mcyclecfgh << 32) :
1193                   env->mcyclecfg;
1194     } else if (counter_idx == 2) {
1195         cfg_val = upper_half ? ((uint64_t)env->minstretcfgh << 32) :
1196                   env->minstretcfg;
1197     } else {
1198         cfg_val = upper_half ?
1199                   ((uint64_t)env->mhpmeventh_val[counter_idx] << 32) :
1200                   env->mhpmevent_val[counter_idx];
1201         cfg_val &= MHPMEVENT_FILTER_MASK;
1202     }
1203 
1204     if (!cfg_val) {
1205         if (icount_enabled()) {
1206                 curr_val = inst ? icount_get_raw() : icount_get();
1207         } else {
1208             curr_val = cpu_get_host_ticks();
1209         }
1210 
1211         goto done;
1212     }
1213 
1214     /* Update counter before reading. */
1215     riscv_pmu_update_fixed_ctrs(env, env->priv, env->virt_enabled);
1216 
1217     if (!(cfg_val & MCYCLECFG_BIT_MINH)) {
1218         curr_val += counter_arr[PRV_M];
1219     }
1220 
1221     if (!(cfg_val & MCYCLECFG_BIT_SINH)) {
1222         curr_val += counter_arr[PRV_S];
1223     }
1224 
1225     if (!(cfg_val & MCYCLECFG_BIT_UINH)) {
1226         curr_val += counter_arr[PRV_U];
1227     }
1228 
1229     if (!(cfg_val & MCYCLECFG_BIT_VSINH)) {
1230         curr_val += counter_arr_virt[PRV_S];
1231     }
1232 
1233     if (!(cfg_val & MCYCLECFG_BIT_VUINH)) {
1234         curr_val += counter_arr_virt[PRV_U];
1235     }
1236 
1237 done:
1238     if (riscv_cpu_mxl(env) == MXL_RV32) {
1239         result = upper_half ? curr_val >> 32 : curr_val;
1240     } else {
1241         result = curr_val;
1242     }
1243 
1244     return result;
1245 }
1246 
1247 static RISCVException riscv_pmu_write_ctr(CPURISCVState *env, target_ulong val,
1248                                           uint32_t ctr_idx)
1249 {
1250     PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
1251     uint64_t mhpmctr_val = val;
1252 
1253     counter->mhpmcounter_val = val;
1254     if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
1255         (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
1256          riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
1257         counter->mhpmcounter_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
1258                                                                 ctr_idx, false);
1259         if (ctr_idx > 2) {
1260             if (riscv_cpu_mxl(env) == MXL_RV32) {
1261                 mhpmctr_val = mhpmctr_val |
1262                               ((uint64_t)counter->mhpmcounterh_val << 32);
1263             }
1264             riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
1265         }
1266      } else {
1267         /* Other counters can keep incrementing from the given value */
1268         counter->mhpmcounter_prev = val;
1269     }
1270 
1271     return RISCV_EXCP_NONE;
1272 }
1273 
1274 static RISCVException riscv_pmu_write_ctrh(CPURISCVState *env, target_ulong val,
1275                                           uint32_t ctr_idx)
1276 {
1277     PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
1278     uint64_t mhpmctr_val = counter->mhpmcounter_val;
1279     uint64_t mhpmctrh_val = val;
1280 
1281     counter->mhpmcounterh_val = val;
1282     mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
1283     if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
1284         (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
1285          riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
1286         counter->mhpmcounterh_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
1287                                                                  ctr_idx, true);
1288         if (ctr_idx > 2) {
1289             riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
1290         }
1291     } else {
1292         counter->mhpmcounterh_prev = val;
1293     }
1294 
1295     return RISCV_EXCP_NONE;
1296 }
1297 
1298 static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
1299 {
1300     int ctr_idx = csrno - CSR_MCYCLE;
1301 
1302     return riscv_pmu_write_ctr(env, val, ctr_idx);
1303 }
1304 
1305 static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
1306 {
1307     int ctr_idx = csrno - CSR_MCYCLEH;
1308 
1309     return riscv_pmu_write_ctrh(env, val, ctr_idx);
1310 }
1311 
1312 RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
1313                                          bool upper_half, uint32_t ctr_idx)
1314 {
1315     PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
1316     target_ulong ctr_prev = upper_half ? counter->mhpmcounterh_prev :
1317                                          counter->mhpmcounter_prev;
1318     target_ulong ctr_val = upper_half ? counter->mhpmcounterh_val :
1319                                         counter->mhpmcounter_val;
1320 
1321     if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
1322         /*
1323          * Counter should not increment if inhibit bit is set. Just return the
1324          * current counter value.
1325          */
1326          *val = ctr_val;
1327          return RISCV_EXCP_NONE;
1328     }
1329 
1330     /*
1331      * The kernel computes the perf delta by subtracting the current value from
1332      * the value it initialized previously (ctr_val).
1333      */
1334     if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
1335         riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
1336         *val = riscv_pmu_ctr_get_fixed_counters_val(env, ctr_idx, upper_half) -
1337                                                     ctr_prev + ctr_val;
1338     } else {
1339         *val = ctr_val;
1340     }
1341 
1342     return RISCV_EXCP_NONE;
1343 }
1344 
1345 static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
1346                                       target_ulong *val)
1347 {
1348     uint16_t ctr_index;
1349 
1350     if (csrno >= CSR_MCYCLE && csrno <= CSR_MHPMCOUNTER31) {
1351         ctr_index = csrno - CSR_MCYCLE;
1352     } else if (csrno >= CSR_CYCLE && csrno <= CSR_HPMCOUNTER31) {
1353         ctr_index = csrno - CSR_CYCLE;
1354     } else {
1355         return RISCV_EXCP_ILLEGAL_INST;
1356     }
1357 
1358     return riscv_pmu_read_ctr(env, val, false, ctr_index);
1359 }
1360 
1361 static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
1362                                        target_ulong *val)
1363 {
1364     uint16_t ctr_index;
1365 
1366     if (csrno >= CSR_MCYCLEH && csrno <= CSR_MHPMCOUNTER31H) {
1367         ctr_index = csrno - CSR_MCYCLEH;
1368     } else if (csrno >= CSR_CYCLEH && csrno <= CSR_HPMCOUNTER31H) {
1369         ctr_index = csrno - CSR_CYCLEH;
1370     } else {
1371         return RISCV_EXCP_ILLEGAL_INST;
1372     }
1373 
1374     return riscv_pmu_read_ctr(env, val, true, ctr_index);
1375 }
1376 
1377 static int rmw_cd_mhpmcounter(CPURISCVState *env, int ctr_idx,
1378                               target_ulong *val, target_ulong new_val,
1379                               target_ulong wr_mask)
1380 {
1381     if (wr_mask != 0 && wr_mask != -1) {
1382         return -EINVAL;
1383     }
1384 
1385     if (!wr_mask && val) {
1386         riscv_pmu_read_ctr(env, val, false, ctr_idx);
1387     } else if (wr_mask) {
1388         riscv_pmu_write_ctr(env, new_val, ctr_idx);
1389     } else {
1390         return -EINVAL;
1391     }
1392 
1393     return 0;
1394 }
1395 
1396 static int rmw_cd_mhpmcounterh(CPURISCVState *env, int ctr_idx,
1397                                target_ulong *val, target_ulong new_val,
1398                                target_ulong wr_mask)
1399 {
1400     if (wr_mask != 0 && wr_mask != -1) {
1401         return -EINVAL;
1402     }
1403 
1404     if (!wr_mask && val) {
1405         riscv_pmu_read_ctr(env, val, true, ctr_idx);
1406     } else if (wr_mask) {
1407         riscv_pmu_write_ctrh(env, new_val, ctr_idx);
1408     } else {
1409         return -EINVAL;
1410     }
1411 
1412     return 0;
1413 }
1414 
1415 static int rmw_cd_mhpmevent(CPURISCVState *env, int evt_index,
1416                             target_ulong *val, target_ulong new_val,
1417                             target_ulong wr_mask)
1418 {
1419     uint64_t mhpmevt_val = new_val;
1420 
1421     if (wr_mask != 0 && wr_mask != -1) {
1422         return -EINVAL;
1423     }
1424 
1425     if (!wr_mask && val) {
1426         *val = env->mhpmevent_val[evt_index];
1427         if (riscv_cpu_cfg(env)->ext_sscofpmf) {
1428             *val &= ~MHPMEVENT_BIT_MINH;
1429         }
1430     } else if (wr_mask) {
1431         wr_mask &= ~MHPMEVENT_BIT_MINH;
1432         mhpmevt_val = (new_val & wr_mask) |
1433                       (env->mhpmevent_val[evt_index] & ~wr_mask);
1434         if (riscv_cpu_mxl(env) == MXL_RV32) {
1435             mhpmevt_val = mhpmevt_val |
1436                           ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
1437         }
1438         env->mhpmevent_val[evt_index] = mhpmevt_val;
1439         riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
1440     } else {
1441         return -EINVAL;
1442     }
1443 
1444     return 0;
1445 }
1446 
1447 static int rmw_cd_mhpmeventh(CPURISCVState *env, int evt_index,
1448                              target_ulong *val, target_ulong new_val,
1449                              target_ulong wr_mask)
1450 {
1451     uint64_t mhpmevth_val;
1452     uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
1453 
1454     if (wr_mask != 0 && wr_mask != -1) {
1455         return -EINVAL;
1456     }
1457 
1458     if (!wr_mask && val) {
1459         *val = env->mhpmeventh_val[evt_index];
1460         if (riscv_cpu_cfg(env)->ext_sscofpmf) {
1461             *val &= ~MHPMEVENTH_BIT_MINH;
1462         }
1463     } else if (wr_mask) {
1464         wr_mask &= ~MHPMEVENTH_BIT_MINH;
1465         env->mhpmeventh_val[evt_index] =
1466             (new_val & wr_mask) | (env->mhpmeventh_val[evt_index] & ~wr_mask);
1467         mhpmevth_val = env->mhpmeventh_val[evt_index];
1468         mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
1469         riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
1470     } else {
1471         return -EINVAL;
1472     }
1473 
1474     return 0;
1475 }
1476 
1477 static int rmw_cd_ctr_cfg(CPURISCVState *env, int cfg_index, target_ulong *val,
1478                             target_ulong new_val, target_ulong wr_mask)
1479 {
1480     switch (cfg_index) {
1481     case 0:             /* CYCLECFG */
1482         if (wr_mask) {
1483             wr_mask &= ~MCYCLECFG_BIT_MINH;
1484             env->mcyclecfg = (new_val & wr_mask) | (env->mcyclecfg & ~wr_mask);
1485         } else {
1486             *val = env->mcyclecfg &= ~MHPMEVENTH_BIT_MINH;
1487         }
1488         break;
1489     case 2:             /* INSTRETCFG */
1490         if (wr_mask) {
1491             wr_mask &= ~MINSTRETCFG_BIT_MINH;
1492             env->minstretcfg = (new_val & wr_mask) |
1493                                (env->minstretcfg & ~wr_mask);
1494         } else {
1495             *val = env->minstretcfg &= ~MHPMEVENTH_BIT_MINH;
1496         }
1497         break;
1498     default:
1499         return -EINVAL;
1500     }
1501     return 0;
1502 }
1503 
1504 static int rmw_cd_ctr_cfgh(CPURISCVState *env, int cfg_index, target_ulong *val,
1505                             target_ulong new_val, target_ulong wr_mask)
1506 {
1507 
1508     if (riscv_cpu_mxl(env) != MXL_RV32) {
1509         return RISCV_EXCP_ILLEGAL_INST;
1510     }
1511 
1512     switch (cfg_index) {
1513     case 0:         /* CYCLECFGH */
1514         if (wr_mask) {
1515             wr_mask &= ~MCYCLECFGH_BIT_MINH;
1516             env->mcyclecfgh = (new_val & wr_mask) |
1517                               (env->mcyclecfgh & ~wr_mask);
1518         } else {
1519             *val = env->mcyclecfgh;
1520         }
1521         break;
1522     case 2:          /* INSTRETCFGH */
1523         if (wr_mask) {
1524             wr_mask &= ~MINSTRETCFGH_BIT_MINH;
1525             env->minstretcfgh = (new_val & wr_mask) |
1526                                 (env->minstretcfgh & ~wr_mask);
1527         } else {
1528             *val = env->minstretcfgh;
1529         }
1530         break;
1531     default:
1532         return -EINVAL;
1533     }
1534     return 0;
1535 }
1536 
1537 
1538 static RISCVException read_scountovf(CPURISCVState *env, int csrno,
1539                                      target_ulong *val)
1540 {
1541     int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
1542     int i;
1543     *val = 0;
1544     target_ulong *mhpm_evt_val;
1545     uint64_t of_bit_mask;
1546 
1547     /* Virtualize scountovf for counter delegation */
1548     if (riscv_cpu_cfg(env)->ext_sscofpmf &&
1549         riscv_cpu_cfg(env)->ext_ssccfg &&
1550         get_field(env->menvcfg, MENVCFG_CDE) &&
1551         env->virt_enabled) {
1552         return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1553     }
1554 
1555     if (riscv_cpu_mxl(env) == MXL_RV32) {
1556         mhpm_evt_val = env->mhpmeventh_val;
1557         of_bit_mask = MHPMEVENTH_BIT_OF;
1558     } else {
1559         mhpm_evt_val = env->mhpmevent_val;
1560         of_bit_mask = MHPMEVENT_BIT_OF;
1561     }
1562 
1563     for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
1564         if ((get_field(env->mcounteren, BIT(i))) &&
1565             (mhpm_evt_val[i] & of_bit_mask)) {
1566                     *val |= BIT(i);
1567             }
1568     }
1569 
1570     return RISCV_EXCP_NONE;
1571 }
1572 
1573 static RISCVException read_time(CPURISCVState *env, int csrno,
1574                                 target_ulong *val)
1575 {
1576     uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
1577 
1578     if (!env->rdtime_fn) {
1579         return RISCV_EXCP_ILLEGAL_INST;
1580     }
1581 
1582     *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
1583     return RISCV_EXCP_NONE;
1584 }
1585 
1586 static RISCVException read_timeh(CPURISCVState *env, int csrno,
1587                                  target_ulong *val)
1588 {
1589     uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
1590 
1591     if (!env->rdtime_fn) {
1592         return RISCV_EXCP_ILLEGAL_INST;
1593     }
1594 
1595     *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
1596     return RISCV_EXCP_NONE;
1597 }
1598 
1599 static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
1600                                      target_ulong *val)
1601 {
1602     *val = env->vstimecmp;
1603 
1604     return RISCV_EXCP_NONE;
1605 }
1606 
1607 static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
1608                                       target_ulong *val)
1609 {
1610     *val = env->vstimecmp >> 32;
1611 
1612     return RISCV_EXCP_NONE;
1613 }
1614 
1615 static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
1616                                       target_ulong val)
1617 {
1618     if (riscv_cpu_mxl(env) == MXL_RV32) {
1619         env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
1620     } else {
1621         env->vstimecmp = val;
1622     }
1623 
1624     riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
1625                               env->htimedelta, MIP_VSTIP);
1626 
1627     return RISCV_EXCP_NONE;
1628 }
1629 
1630 static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
1631                                        target_ulong val)
1632 {
1633     env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
1634     riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
1635                               env->htimedelta, MIP_VSTIP);
1636 
1637     return RISCV_EXCP_NONE;
1638 }
1639 
1640 static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
1641                                     target_ulong *val)
1642 {
1643     if (env->virt_enabled) {
1644         *val = env->vstimecmp;
1645     } else {
1646         *val = env->stimecmp;
1647     }
1648 
1649     return RISCV_EXCP_NONE;
1650 }
1651 
1652 static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
1653                                      target_ulong *val)
1654 {
1655     if (env->virt_enabled) {
1656         *val = env->vstimecmp >> 32;
1657     } else {
1658         *val = env->stimecmp >> 32;
1659     }
1660 
1661     return RISCV_EXCP_NONE;
1662 }
1663 
1664 static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
1665                                      target_ulong val)
1666 {
1667     if (env->virt_enabled) {
1668         if (env->hvictl & HVICTL_VTI) {
1669             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1670         }
1671         return write_vstimecmp(env, csrno, val);
1672     }
1673 
1674     if (riscv_cpu_mxl(env) == MXL_RV32) {
1675         env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
1676     } else {
1677         env->stimecmp = val;
1678     }
1679 
1680     riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
1681 
1682     return RISCV_EXCP_NONE;
1683 }
1684 
1685 static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
1686                                       target_ulong val)
1687 {
1688     if (env->virt_enabled) {
1689         if (env->hvictl & HVICTL_VTI) {
1690             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1691         }
1692         return write_vstimecmph(env, csrno, val);
1693     }
1694 
1695     env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
1696     riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
1697 
1698     return RISCV_EXCP_NONE;
1699 }
1700 
1701 #define VSTOPI_NUM_SRCS 5
1702 
1703 /*
1704  * All core local interrupts except the fixed ones 0:12. This macro is for
1705  * virtual interrupts logic so please don't change this to avoid messing up
1706  * the whole support, For reference see AIA spec: `5.3 Interrupt filtering and
1707  * virtual interrupts for supervisor level` and `6.3.2 Virtual interrupts for
1708  * VS level`.
1709  */
1710 #define LOCAL_INTERRUPTS   (~0x1FFFULL)
1711 
1712 static const uint64_t delegable_ints =
1713     S_MODE_INTERRUPTS | VS_MODE_INTERRUPTS | MIP_LCOFIP;
1714 static const uint64_t vs_delegable_ints =
1715     (VS_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & ~MIP_LCOFIP;
1716 static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
1717                                      HS_MODE_INTERRUPTS | LOCAL_INTERRUPTS;
1718 #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
1719                          (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
1720                          (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
1721                          (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
1722                          (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
1723                          (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
1724                          (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
1725                          (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
1726                          (1ULL << (RISCV_EXCP_U_ECALL)) | \
1727                          (1ULL << (RISCV_EXCP_S_ECALL)) | \
1728                          (1ULL << (RISCV_EXCP_VS_ECALL)) | \
1729                          (1ULL << (RISCV_EXCP_M_ECALL)) | \
1730                          (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
1731                          (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
1732                          (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
1733                          (1ULL << (RISCV_EXCP_SW_CHECK)) | \
1734                          (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
1735                          (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
1736                          (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
1737                          (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
1738 static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
1739     ~((1ULL << (RISCV_EXCP_S_ECALL)) |
1740       (1ULL << (RISCV_EXCP_VS_ECALL)) |
1741       (1ULL << (RISCV_EXCP_M_ECALL)) |
1742       (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
1743       (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
1744       (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
1745       (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
1746 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
1747     SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
1748     SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
1749 
1750 /*
1751  * Spec allows for bits 13:63 to be either read-only or writable.
1752  * So far we have interrupt LCOFIP in that region which is writable.
1753  *
1754  * Also, spec allows to inject virtual interrupts in this region even
1755  * without any hardware interrupts for that interrupt number.
1756  *
1757  * For now interrupt in 13:63 region are all kept writable. 13 being
1758  * LCOFIP and 14:63 being virtual only. Change this in future if we
1759  * introduce more interrupts that are not writable.
1760  */
1761 
1762 /* Bit STIP can be an alias of mip.STIP that's why it's writable in mvip. */
1763 static const uint64_t mvip_writable_mask = MIP_SSIP | MIP_STIP | MIP_SEIP |
1764                                     LOCAL_INTERRUPTS;
1765 static const uint64_t mvien_writable_mask = MIP_SSIP | MIP_SEIP |
1766                                     LOCAL_INTERRUPTS;
1767 
1768 static const uint64_t sip_writable_mask = SIP_SSIP | LOCAL_INTERRUPTS;
1769 static const uint64_t hip_writable_mask = MIP_VSSIP;
1770 static const uint64_t hvip_writable_mask = MIP_VSSIP | MIP_VSTIP |
1771                                     MIP_VSEIP | LOCAL_INTERRUPTS;
1772 static const uint64_t hvien_writable_mask = LOCAL_INTERRUPTS;
1773 
1774 static const uint64_t vsip_writable_mask = MIP_VSSIP | LOCAL_INTERRUPTS;
1775 
1776 const bool valid_vm_1_10_32[16] = {
1777     [VM_1_10_MBARE] = true,
1778     [VM_1_10_SV32] = true
1779 };
1780 
1781 const bool valid_vm_1_10_64[16] = {
1782     [VM_1_10_MBARE] = true,
1783     [VM_1_10_SV39] = true,
1784     [VM_1_10_SV48] = true,
1785     [VM_1_10_SV57] = true
1786 };
1787 
1788 /* Machine Information Registers */
1789 static RISCVException read_zero(CPURISCVState *env, int csrno,
1790                                 target_ulong *val)
1791 {
1792     *val = 0;
1793     return RISCV_EXCP_NONE;
1794 }
1795 
1796 static RISCVException write_ignore(CPURISCVState *env, int csrno,
1797                                    target_ulong val)
1798 {
1799     return RISCV_EXCP_NONE;
1800 }
1801 
1802 static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
1803                                      target_ulong *val)
1804 {
1805     *val = riscv_cpu_cfg(env)->mvendorid;
1806     return RISCV_EXCP_NONE;
1807 }
1808 
1809 static RISCVException read_marchid(CPURISCVState *env, int csrno,
1810                                    target_ulong *val)
1811 {
1812     *val = riscv_cpu_cfg(env)->marchid;
1813     return RISCV_EXCP_NONE;
1814 }
1815 
1816 static RISCVException read_mimpid(CPURISCVState *env, int csrno,
1817                                   target_ulong *val)
1818 {
1819     *val = riscv_cpu_cfg(env)->mimpid;
1820     return RISCV_EXCP_NONE;
1821 }
1822 
1823 static RISCVException read_mhartid(CPURISCVState *env, int csrno,
1824                                    target_ulong *val)
1825 {
1826     *val = env->mhartid;
1827     return RISCV_EXCP_NONE;
1828 }
1829 
1830 /* Machine Trap Setup */
1831 
1832 /* We do not store SD explicitly, only compute it on demand. */
1833 static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
1834 {
1835     if ((status & MSTATUS_FS) == MSTATUS_FS ||
1836         (status & MSTATUS_VS) == MSTATUS_VS ||
1837         (status & MSTATUS_XS) == MSTATUS_XS) {
1838         switch (xl) {
1839         case MXL_RV32:
1840             return status | MSTATUS32_SD;
1841         case MXL_RV64:
1842             return status | MSTATUS64_SD;
1843         case MXL_RV128:
1844             return MSTATUSH128_SD;
1845         default:
1846             g_assert_not_reached();
1847         }
1848     }
1849     return status;
1850 }
1851 
1852 static RISCVException read_mstatus(CPURISCVState *env, int csrno,
1853                                    target_ulong *val)
1854 {
1855     *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
1856     return RISCV_EXCP_NONE;
1857 }
1858 
1859 static bool validate_vm(CPURISCVState *env, target_ulong vm)
1860 {
1861     uint64_t mode_supported = riscv_cpu_cfg(env)->satp_mode.map;
1862     return get_field(mode_supported, (1 << vm));
1863 }
1864 
1865 static target_ulong legalize_xatp(CPURISCVState *env, target_ulong old_xatp,
1866                                   target_ulong val)
1867 {
1868     target_ulong mask;
1869     bool vm;
1870     if (riscv_cpu_mxl(env) == MXL_RV32) {
1871         vm = validate_vm(env, get_field(val, SATP32_MODE));
1872         mask = (val ^ old_xatp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
1873     } else {
1874         vm = validate_vm(env, get_field(val, SATP64_MODE));
1875         mask = (val ^ old_xatp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
1876     }
1877 
1878     if (vm && mask) {
1879         /*
1880          * The ISA defines SATP.MODE=Bare as "no translation", but we still
1881          * pass these through QEMU's TLB emulation as it improves
1882          * performance.  Flushing the TLB on SATP writes with paging
1883          * enabled avoids leaking those invalid cached mappings.
1884          */
1885         tlb_flush(env_cpu(env));
1886         return val;
1887     }
1888     return old_xatp;
1889 }
1890 
1891 static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
1892                                  target_ulong val)
1893 {
1894     bool valid = false;
1895     target_ulong new_mpp = get_field(val, MSTATUS_MPP);
1896 
1897     switch (new_mpp) {
1898     case PRV_M:
1899         valid = true;
1900         break;
1901     case PRV_S:
1902         valid = riscv_has_ext(env, RVS);
1903         break;
1904     case PRV_U:
1905         valid = riscv_has_ext(env, RVU);
1906         break;
1907     }
1908 
1909     /* Remain field unchanged if new_mpp value is invalid */
1910     if (!valid) {
1911         val = set_field(val, MSTATUS_MPP, old_mpp);
1912     }
1913 
1914     return val;
1915 }
1916 
1917 static RISCVException write_mstatus(CPURISCVState *env, int csrno,
1918                                     target_ulong val)
1919 {
1920     uint64_t mstatus = env->mstatus;
1921     uint64_t mask = 0;
1922     RISCVMXL xl = riscv_cpu_mxl(env);
1923 
1924     /*
1925      * MPP field have been made WARL since priv version 1.11. However,
1926      * legalization for it will not break any software running on 1.10.
1927      */
1928     val = legalize_mpp(env, get_field(mstatus, MSTATUS_MPP), val);
1929 
1930     /* flush tlb on mstatus fields that affect VM */
1931     if ((val ^ mstatus) & MSTATUS_MXR) {
1932         tlb_flush(env_cpu(env));
1933     }
1934     mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
1935         MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
1936         MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
1937         MSTATUS_TW;
1938 
1939     if (riscv_has_ext(env, RVF)) {
1940         mask |= MSTATUS_FS;
1941     }
1942     if (riscv_has_ext(env, RVV)) {
1943         mask |= MSTATUS_VS;
1944     }
1945 
1946     if (riscv_env_smode_dbltrp_enabled(env, env->virt_enabled)) {
1947         mask |= MSTATUS_SDT;
1948         if ((val & MSTATUS_SDT) != 0) {
1949             val &= ~MSTATUS_SIE;
1950         }
1951     }
1952 
1953     if (riscv_cpu_cfg(env)->ext_smdbltrp) {
1954         mask |= MSTATUS_MDT;
1955         if ((val & MSTATUS_MDT) != 0) {
1956             val &= ~MSTATUS_MIE;
1957         }
1958     }
1959 
1960     if (xl != MXL_RV32 || env->debugger) {
1961         if (riscv_has_ext(env, RVH)) {
1962             mask |= MSTATUS_MPV | MSTATUS_GVA;
1963         }
1964         if ((val & MSTATUS64_UXL) != 0) {
1965             mask |= MSTATUS64_UXL;
1966         }
1967     }
1968 
1969     /* If cfi lp extension is available, then apply cfi lp mask */
1970     if (env_archcpu(env)->cfg.ext_zicfilp) {
1971         mask |= (MSTATUS_MPELP | MSTATUS_SPELP);
1972     }
1973 
1974     mstatus = (mstatus & ~mask) | (val & mask);
1975 
1976     env->mstatus = mstatus;
1977 
1978     /*
1979      * Except in debug mode, UXL/SXL can only be modified by higher
1980      * privilege mode. So xl will not be changed in normal mode.
1981      */
1982     if (env->debugger) {
1983         env->xl = cpu_recompute_xl(env);
1984     }
1985 
1986     return RISCV_EXCP_NONE;
1987 }
1988 
1989 static RISCVException read_mstatush(CPURISCVState *env, int csrno,
1990                                     target_ulong *val)
1991 {
1992     *val = env->mstatus >> 32;
1993     return RISCV_EXCP_NONE;
1994 }
1995 
1996 static RISCVException write_mstatush(CPURISCVState *env, int csrno,
1997                                      target_ulong val)
1998 {
1999     uint64_t valh = (uint64_t)val << 32;
2000     uint64_t mask = riscv_has_ext(env, RVH) ? MSTATUS_MPV | MSTATUS_GVA : 0;
2001 
2002     if (riscv_cpu_cfg(env)->ext_smdbltrp) {
2003         mask |= MSTATUS_MDT;
2004         if ((valh & MSTATUS_MDT) != 0) {
2005             mask |= MSTATUS_MIE;
2006         }
2007     }
2008     env->mstatus = (env->mstatus & ~mask) | (valh & mask);
2009 
2010     return RISCV_EXCP_NONE;
2011 }
2012 
2013 static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
2014                                         Int128 *val)
2015 {
2016     *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128,
2017                                                       env->mstatus));
2018     return RISCV_EXCP_NONE;
2019 }
2020 
2021 static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
2022                                      Int128 *val)
2023 {
2024     *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
2025     return RISCV_EXCP_NONE;
2026 }
2027 
2028 static RISCVException read_misa(CPURISCVState *env, int csrno,
2029                                 target_ulong *val)
2030 {
2031     target_ulong misa;
2032 
2033     switch (env->misa_mxl) {
2034     case MXL_RV32:
2035         misa = (target_ulong)MXL_RV32 << 30;
2036         break;
2037 #ifdef TARGET_RISCV64
2038     case MXL_RV64:
2039         misa = (target_ulong)MXL_RV64 << 62;
2040         break;
2041 #endif
2042     default:
2043         g_assert_not_reached();
2044     }
2045 
2046     *val = misa | env->misa_ext;
2047     return RISCV_EXCP_NONE;
2048 }
2049 
2050 static RISCVException write_misa(CPURISCVState *env, int csrno,
2051                                  target_ulong val)
2052 {
2053     RISCVCPU *cpu = env_archcpu(env);
2054     uint32_t orig_misa_ext = env->misa_ext;
2055     Error *local_err = NULL;
2056 
2057     if (!riscv_cpu_cfg(env)->misa_w) {
2058         /* drop write to misa */
2059         return RISCV_EXCP_NONE;
2060     }
2061 
2062     /* Mask extensions that are not supported by this hart */
2063     val &= env->misa_ext_mask;
2064 
2065     /*
2066      * Suppress 'C' if next instruction is not aligned
2067      * TODO: this should check next_pc
2068      */
2069     if ((val & RVC) && (GETPC() & ~3) != 0) {
2070         val &= ~RVC;
2071     }
2072 
2073     /* Disable RVG if any of its dependencies are disabled */
2074     if (!(val & RVI && val & RVM && val & RVA &&
2075           val & RVF && val & RVD)) {
2076         val &= ~RVG;
2077     }
2078 
2079     /* If nothing changed, do nothing. */
2080     if (val == env->misa_ext) {
2081         return RISCV_EXCP_NONE;
2082     }
2083 
2084     env->misa_ext = val;
2085     riscv_cpu_validate_set_extensions(cpu, &local_err);
2086     if (local_err != NULL) {
2087         /* Rollback on validation error */
2088         qemu_log_mask(LOG_GUEST_ERROR, "Unable to write MISA ext value "
2089                       "0x%x, keeping existing MISA ext 0x%x\n",
2090                       env->misa_ext, orig_misa_ext);
2091 
2092         env->misa_ext = orig_misa_ext;
2093 
2094         return RISCV_EXCP_NONE;
2095     }
2096 
2097     if (!(env->misa_ext & RVF)) {
2098         env->mstatus &= ~MSTATUS_FS;
2099     }
2100 
2101     /* flush translation cache */
2102     tb_flush(env_cpu(env));
2103     env->xl = riscv_cpu_mxl(env);
2104     return RISCV_EXCP_NONE;
2105 }
2106 
2107 static RISCVException read_medeleg(CPURISCVState *env, int csrno,
2108                                    target_ulong *val)
2109 {
2110     *val = env->medeleg;
2111     return RISCV_EXCP_NONE;
2112 }
2113 
2114 static RISCVException write_medeleg(CPURISCVState *env, int csrno,
2115                                     target_ulong val)
2116 {
2117     env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
2118     return RISCV_EXCP_NONE;
2119 }
2120 
2121 static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
2122                                     uint64_t *ret_val,
2123                                     uint64_t new_val, uint64_t wr_mask)
2124 {
2125     uint64_t mask = wr_mask & delegable_ints;
2126 
2127     if (ret_val) {
2128         *ret_val = env->mideleg;
2129     }
2130 
2131     env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
2132 
2133     if (riscv_has_ext(env, RVH)) {
2134         env->mideleg |= HS_MODE_INTERRUPTS;
2135     }
2136 
2137     return RISCV_EXCP_NONE;
2138 }
2139 
2140 static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
2141                                   target_ulong *ret_val,
2142                                   target_ulong new_val, target_ulong wr_mask)
2143 {
2144     uint64_t rval;
2145     RISCVException ret;
2146 
2147     ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
2148     if (ret_val) {
2149         *ret_val = rval;
2150     }
2151 
2152     return ret;
2153 }
2154 
2155 static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
2156                                    target_ulong *ret_val,
2157                                    target_ulong new_val,
2158                                    target_ulong wr_mask)
2159 {
2160     uint64_t rval;
2161     RISCVException ret;
2162 
2163     ret = rmw_mideleg64(env, csrno, &rval,
2164         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2165     if (ret_val) {
2166         *ret_val = rval >> 32;
2167     }
2168 
2169     return ret;
2170 }
2171 
2172 static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
2173                                 uint64_t *ret_val,
2174                                 uint64_t new_val, uint64_t wr_mask)
2175 {
2176     uint64_t mask = wr_mask & all_ints;
2177 
2178     if (ret_val) {
2179         *ret_val = env->mie;
2180     }
2181 
2182     env->mie = (env->mie & ~mask) | (new_val & mask);
2183 
2184     if (!riscv_has_ext(env, RVH)) {
2185         env->mie &= ~((uint64_t)HS_MODE_INTERRUPTS);
2186     }
2187 
2188     return RISCV_EXCP_NONE;
2189 }
2190 
2191 static RISCVException rmw_mie(CPURISCVState *env, int csrno,
2192                               target_ulong *ret_val,
2193                               target_ulong new_val, target_ulong wr_mask)
2194 {
2195     uint64_t rval;
2196     RISCVException ret;
2197 
2198     ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
2199     if (ret_val) {
2200         *ret_val = rval;
2201     }
2202 
2203     return ret;
2204 }
2205 
2206 static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
2207                                target_ulong *ret_val,
2208                                target_ulong new_val, target_ulong wr_mask)
2209 {
2210     uint64_t rval;
2211     RISCVException ret;
2212 
2213     ret = rmw_mie64(env, csrno, &rval,
2214         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2215     if (ret_val) {
2216         *ret_val = rval >> 32;
2217     }
2218 
2219     return ret;
2220 }
2221 
2222 static RISCVException rmw_mvien64(CPURISCVState *env, int csrno,
2223                                 uint64_t *ret_val,
2224                                 uint64_t new_val, uint64_t wr_mask)
2225 {
2226     uint64_t mask = wr_mask & mvien_writable_mask;
2227 
2228     if (ret_val) {
2229         *ret_val = env->mvien;
2230     }
2231 
2232     env->mvien = (env->mvien & ~mask) | (new_val & mask);
2233 
2234     return RISCV_EXCP_NONE;
2235 }
2236 
2237 static RISCVException rmw_mvien(CPURISCVState *env, int csrno,
2238                               target_ulong *ret_val,
2239                               target_ulong new_val, target_ulong wr_mask)
2240 {
2241     uint64_t rval;
2242     RISCVException ret;
2243 
2244     ret = rmw_mvien64(env, csrno, &rval, new_val, wr_mask);
2245     if (ret_val) {
2246         *ret_val = rval;
2247     }
2248 
2249     return ret;
2250 }
2251 
2252 static RISCVException rmw_mvienh(CPURISCVState *env, int csrno,
2253                                 target_ulong *ret_val,
2254                                 target_ulong new_val, target_ulong wr_mask)
2255 {
2256     uint64_t rval;
2257     RISCVException ret;
2258 
2259     ret = rmw_mvien64(env, csrno, &rval,
2260         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2261     if (ret_val) {
2262         *ret_val = rval >> 32;
2263     }
2264 
2265     return ret;
2266 }
2267 
2268 static RISCVException read_mtopi(CPURISCVState *env, int csrno,
2269                                  target_ulong *val)
2270 {
2271     int irq;
2272     uint8_t iprio;
2273 
2274     irq = riscv_cpu_mirq_pending(env);
2275     if (irq <= 0 || irq > 63) {
2276         *val = 0;
2277     } else {
2278         iprio = env->miprio[irq];
2279         if (!iprio) {
2280             if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) {
2281                 iprio = IPRIO_MMAXIPRIO;
2282             }
2283         }
2284         *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2285         *val |= iprio;
2286     }
2287 
2288     return RISCV_EXCP_NONE;
2289 }
2290 
2291 static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
2292 {
2293     if (!env->virt_enabled) {
2294         return csrno;
2295     }
2296 
2297     switch (csrno) {
2298     case CSR_SISELECT:
2299         return CSR_VSISELECT;
2300     case CSR_SIREG:
2301         return CSR_VSIREG;
2302     case CSR_STOPEI:
2303         return CSR_VSTOPEI;
2304     default:
2305         return csrno;
2306     };
2307 }
2308 
2309 static int csrind_xlate_vs_csrno(CPURISCVState *env, int csrno)
2310 {
2311     if (!env->virt_enabled) {
2312         return csrno;
2313     }
2314 
2315     switch (csrno) {
2316     case CSR_SISELECT:
2317         return CSR_VSISELECT;
2318     case CSR_SIREG:
2319     case CSR_SIREG2:
2320     case CSR_SIREG3:
2321     case CSR_SIREG4:
2322     case CSR_SIREG5:
2323     case CSR_SIREG6:
2324         return CSR_VSIREG + (csrno - CSR_SIREG);
2325     default:
2326         return csrno;
2327     };
2328 }
2329 
2330 static RISCVException rmw_xiselect(CPURISCVState *env, int csrno,
2331                                    target_ulong *val, target_ulong new_val,
2332                                    target_ulong wr_mask)
2333 {
2334     target_ulong *iselect;
2335     int ret;
2336 
2337     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_SVSLCT);
2338     if (ret != RISCV_EXCP_NONE) {
2339         return ret;
2340     }
2341 
2342     /* Translate CSR number for VS-mode */
2343     csrno = csrind_xlate_vs_csrno(env, csrno);
2344 
2345     /* Find the iselect CSR based on CSR number */
2346     switch (csrno) {
2347     case CSR_MISELECT:
2348         iselect = &env->miselect;
2349         break;
2350     case CSR_SISELECT:
2351         iselect = &env->siselect;
2352         break;
2353     case CSR_VSISELECT:
2354         iselect = &env->vsiselect;
2355         break;
2356     default:
2357          return RISCV_EXCP_ILLEGAL_INST;
2358     };
2359 
2360     if (val) {
2361         *val = *iselect;
2362     }
2363 
2364     if (riscv_cpu_cfg(env)->ext_smcsrind || riscv_cpu_cfg(env)->ext_sscsrind) {
2365         wr_mask &= ISELECT_MASK_SXCSRIND;
2366     } else {
2367         wr_mask &= ISELECT_MASK_AIA;
2368     }
2369 
2370     if (wr_mask) {
2371         *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
2372     }
2373 
2374     return RISCV_EXCP_NONE;
2375 }
2376 
2377 static bool xiselect_aia_range(target_ulong isel)
2378 {
2379     return (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) ||
2380            (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST);
2381 }
2382 
2383 static bool xiselect_cd_range(target_ulong isel)
2384 {
2385     return (ISELECT_CD_FIRST <= isel && isel <= ISELECT_CD_LAST);
2386 }
2387 
2388 static int rmw_iprio(target_ulong xlen,
2389                      target_ulong iselect, uint8_t *iprio,
2390                      target_ulong *val, target_ulong new_val,
2391                      target_ulong wr_mask, int ext_irq_no)
2392 {
2393     int i, firq, nirqs;
2394     target_ulong old_val;
2395 
2396     if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
2397         return -EINVAL;
2398     }
2399     if (xlen != 32 && iselect & 0x1) {
2400         return -EINVAL;
2401     }
2402 
2403     nirqs = 4 * (xlen / 32);
2404     firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
2405 
2406     old_val = 0;
2407     for (i = 0; i < nirqs; i++) {
2408         old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i);
2409     }
2410 
2411     if (val) {
2412         *val = old_val;
2413     }
2414 
2415     if (wr_mask) {
2416         new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
2417         for (i = 0; i < nirqs; i++) {
2418             /*
2419              * M-level and S-level external IRQ priority always read-only
2420              * zero. This means default priority order is always preferred
2421              * for M-level and S-level external IRQs.
2422              */
2423             if ((firq + i) == ext_irq_no) {
2424                 continue;
2425             }
2426             iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
2427         }
2428     }
2429 
2430     return 0;
2431 }
2432 
2433 static RISCVException rmw_xireg_aia(CPURISCVState *env, int csrno,
2434                          target_ulong isel, target_ulong *val,
2435                          target_ulong new_val, target_ulong wr_mask)
2436 {
2437     bool virt = false, isel_reserved = false;
2438     int ret = -EINVAL;
2439     uint8_t *iprio;
2440     target_ulong priv, vgein;
2441 
2442     /* VS-mode CSR number passed in has already been translated */
2443     switch (csrno) {
2444     case CSR_MIREG:
2445         if (!riscv_cpu_cfg(env)->ext_smaia) {
2446             goto done;
2447         }
2448         iprio = env->miprio;
2449         priv = PRV_M;
2450         break;
2451     case CSR_SIREG:
2452         if (!riscv_cpu_cfg(env)->ext_ssaia ||
2453             (env->priv == PRV_S && env->mvien & MIP_SEIP &&
2454             env->siselect >= ISELECT_IMSIC_EIDELIVERY &&
2455             env->siselect <= ISELECT_IMSIC_EIE63)) {
2456             goto done;
2457         }
2458         iprio = env->siprio;
2459         priv = PRV_S;
2460         break;
2461     case CSR_VSIREG:
2462         if (!riscv_cpu_cfg(env)->ext_ssaia) {
2463             goto done;
2464         }
2465         iprio = env->hviprio;
2466         priv = PRV_S;
2467         virt = true;
2468         break;
2469     default:
2470         goto done;
2471     };
2472 
2473     /* Find the selected guest interrupt file */
2474     vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
2475 
2476     if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
2477         /* Local interrupt priority registers not available for VS-mode */
2478         if (!virt) {
2479             ret = rmw_iprio(riscv_cpu_mxl_bits(env),
2480                             isel, iprio, val, new_val, wr_mask,
2481                             (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
2482         }
2483     } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) {
2484         /* IMSIC registers only available when machine implements it. */
2485         if (env->aia_ireg_rmw_fn[priv]) {
2486             /* Selected guest interrupt file should not be zero */
2487             if (virt && (!vgein || env->geilen < vgein)) {
2488                 goto done;
2489             }
2490             /* Call machine specific IMSIC register emulation */
2491             ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
2492                                     AIA_MAKE_IREG(isel, priv, virt, vgein,
2493                                                   riscv_cpu_mxl_bits(env)),
2494                                     val, new_val, wr_mask);
2495         }
2496     } else {
2497         isel_reserved = true;
2498     }
2499 
2500 done:
2501     /*
2502      * If AIA is not enabled, illegal instruction exception is always
2503      * returned regardless of whether we are in VS-mode or not
2504      */
2505     if (ret) {
2506         return (env->virt_enabled && virt && !isel_reserved) ?
2507                RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2508     }
2509 
2510     return RISCV_EXCP_NONE;
2511 }
2512 
2513 static int rmw_xireg_cd(CPURISCVState *env, int csrno,
2514                         target_ulong isel, target_ulong *val,
2515                         target_ulong new_val, target_ulong wr_mask)
2516 {
2517     int ret = -EINVAL;
2518     int ctr_index = isel - ISELECT_CD_FIRST;
2519     int isel_hpm_start = ISELECT_CD_FIRST + 3;
2520 
2521     if (!riscv_cpu_cfg(env)->ext_smcdeleg || !riscv_cpu_cfg(env)->ext_ssccfg) {
2522         ret = RISCV_EXCP_ILLEGAL_INST;
2523         goto done;
2524     }
2525 
2526     /* Invalid siselect value for reserved */
2527     if (ctr_index == 1) {
2528         goto done;
2529     }
2530 
2531     /* sireg4 and sireg5 provides access RV32 only CSRs */
2532     if (((csrno == CSR_SIREG5) || (csrno == CSR_SIREG4)) &&
2533         (riscv_cpu_mxl(env) != MXL_RV32)) {
2534         ret = RISCV_EXCP_ILLEGAL_INST;
2535         goto done;
2536     }
2537 
2538     /* Check Sscofpmf dependancy */
2539     if (!riscv_cpu_cfg(env)->ext_sscofpmf && csrno == CSR_SIREG5 &&
2540         (isel_hpm_start <= isel && isel <= ISELECT_CD_LAST)) {
2541         goto done;
2542     }
2543 
2544     /* Check smcntrpmf dependancy */
2545     if (!riscv_cpu_cfg(env)->ext_smcntrpmf &&
2546         (csrno == CSR_SIREG2 || csrno == CSR_SIREG5) &&
2547         (ISELECT_CD_FIRST <= isel && isel < isel_hpm_start)) {
2548         goto done;
2549     }
2550 
2551     if (!get_field(env->mcounteren, BIT(ctr_index)) ||
2552         !get_field(env->menvcfg, MENVCFG_CDE)) {
2553         goto done;
2554     }
2555 
2556     switch (csrno) {
2557     case CSR_SIREG:
2558         ret = rmw_cd_mhpmcounter(env, ctr_index, val, new_val, wr_mask);
2559         break;
2560     case CSR_SIREG4:
2561         ret = rmw_cd_mhpmcounterh(env, ctr_index, val, new_val, wr_mask);
2562         break;
2563     case CSR_SIREG2:
2564         if (ctr_index <= 2) {
2565             ret = rmw_cd_ctr_cfg(env, ctr_index, val, new_val, wr_mask);
2566         } else {
2567             ret = rmw_cd_mhpmevent(env, ctr_index, val, new_val, wr_mask);
2568         }
2569         break;
2570     case CSR_SIREG5:
2571         if (ctr_index <= 2) {
2572             ret = rmw_cd_ctr_cfgh(env, ctr_index, val, new_val, wr_mask);
2573         } else {
2574             ret = rmw_cd_mhpmeventh(env, ctr_index, val, new_val, wr_mask);
2575         }
2576         break;
2577     default:
2578         goto done;
2579     }
2580 
2581 done:
2582     return ret;
2583 }
2584 
2585 /*
2586  * rmw_xireg_csrind: Perform indirect access to xireg and xireg2-xireg6
2587  *
2588  * Perform indirect access to xireg and xireg2-xireg6.
2589  * This is a generic interface for all xireg CSRs. Apart from AIA, all other
2590  * extension using csrind should be implemented here.
2591  */
2592 static int rmw_xireg_csrind(CPURISCVState *env, int csrno,
2593                               target_ulong isel, target_ulong *val,
2594                               target_ulong new_val, target_ulong wr_mask)
2595 {
2596     int ret = -EINVAL;
2597     bool virt = csrno == CSR_VSIREG ? true : false;
2598 
2599     if (xiselect_cd_range(isel)) {
2600         ret = rmw_xireg_cd(env, csrno, isel, val, new_val, wr_mask);
2601     } else {
2602         /*
2603          * As per the specification, access to unimplented region is undefined
2604          * but recommendation is to raise illegal instruction exception.
2605          */
2606         return RISCV_EXCP_ILLEGAL_INST;
2607     }
2608 
2609     if (ret) {
2610         return (env->virt_enabled && virt) ?
2611                RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2612     }
2613 
2614     return RISCV_EXCP_NONE;
2615 }
2616 
2617 static int rmw_xiregi(CPURISCVState *env, int csrno, target_ulong *val,
2618                       target_ulong new_val, target_ulong wr_mask)
2619 {
2620     int ret = -EINVAL;
2621     target_ulong isel;
2622 
2623     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_SVSLCT);
2624     if (ret != RISCV_EXCP_NONE) {
2625         return ret;
2626     }
2627 
2628     /* Translate CSR number for VS-mode */
2629     csrno = csrind_xlate_vs_csrno(env, csrno);
2630 
2631     if (CSR_MIREG <= csrno && csrno <= CSR_MIREG6 &&
2632         csrno != CSR_MIREG4 - 1) {
2633         isel = env->miselect;
2634     } else if (CSR_SIREG <= csrno && csrno <= CSR_SIREG6 &&
2635                csrno != CSR_SIREG4 - 1) {
2636         isel = env->siselect;
2637     } else if (CSR_VSIREG <= csrno && csrno <= CSR_VSIREG6 &&
2638                csrno != CSR_VSIREG4 - 1) {
2639         isel = env->vsiselect;
2640     } else {
2641         return RISCV_EXCP_ILLEGAL_INST;
2642     }
2643 
2644     return rmw_xireg_csrind(env, csrno, isel, val, new_val, wr_mask);
2645 }
2646 
2647 static RISCVException rmw_xireg(CPURISCVState *env, int csrno,
2648                                 target_ulong *val, target_ulong new_val,
2649                                 target_ulong wr_mask)
2650 {
2651     int ret = -EINVAL;
2652     target_ulong isel;
2653 
2654     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_SVSLCT);
2655     if (ret != RISCV_EXCP_NONE) {
2656         return ret;
2657     }
2658 
2659     /* Translate CSR number for VS-mode */
2660     csrno = csrind_xlate_vs_csrno(env, csrno);
2661 
2662     /* Decode register details from CSR number */
2663     switch (csrno) {
2664     case CSR_MIREG:
2665         isel = env->miselect;
2666         break;
2667     case CSR_SIREG:
2668         isel = env->siselect;
2669         break;
2670     case CSR_VSIREG:
2671         isel = env->vsiselect;
2672         break;
2673     default:
2674         goto done;
2675     };
2676 
2677     /*
2678      * Use the xiselect range to determine actual op on xireg.
2679      *
2680      * Since we only checked the existence of AIA or Indirect Access in the
2681      * predicate, we should check the existence of the exact extension when
2682      * we get to a specific range and return illegal instruction exception even
2683      * in VS-mode.
2684      */
2685     if (xiselect_aia_range(isel)) {
2686         return rmw_xireg_aia(env, csrno, isel, val, new_val, wr_mask);
2687     } else if (riscv_cpu_cfg(env)->ext_smcsrind ||
2688                riscv_cpu_cfg(env)->ext_sscsrind) {
2689         return rmw_xireg_csrind(env, csrno, isel, val, new_val, wr_mask);
2690     }
2691 
2692 done:
2693     return RISCV_EXCP_ILLEGAL_INST;
2694 }
2695 
2696 static RISCVException rmw_xtopei(CPURISCVState *env, int csrno,
2697                                  target_ulong *val, target_ulong new_val,
2698                                  target_ulong wr_mask)
2699 {
2700     bool virt;
2701     int ret = -EINVAL;
2702     target_ulong priv, vgein;
2703 
2704     /* Translate CSR number for VS-mode */
2705     csrno = aia_xlate_vs_csrno(env, csrno);
2706 
2707     /* Decode register details from CSR number */
2708     virt = false;
2709     switch (csrno) {
2710     case CSR_MTOPEI:
2711         priv = PRV_M;
2712         break;
2713     case CSR_STOPEI:
2714         if (env->mvien & MIP_SEIP && env->priv == PRV_S) {
2715             goto done;
2716         }
2717         priv = PRV_S;
2718         break;
2719     case CSR_VSTOPEI:
2720         priv = PRV_S;
2721         virt = true;
2722         break;
2723     default:
2724         goto done;
2725     };
2726 
2727     /* IMSIC CSRs only available when machine implements IMSIC. */
2728     if (!env->aia_ireg_rmw_fn[priv]) {
2729         goto done;
2730     }
2731 
2732     /* Find the selected guest interrupt file */
2733     vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
2734 
2735     /* Selected guest interrupt file should be valid */
2736     if (virt && (!vgein || env->geilen < vgein)) {
2737         goto done;
2738     }
2739 
2740     /* Call machine specific IMSIC register emulation for TOPEI */
2741     ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
2742                     AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein,
2743                                   riscv_cpu_mxl_bits(env)),
2744                     val, new_val, wr_mask);
2745 
2746 done:
2747     if (ret) {
2748         return (env->virt_enabled && virt) ?
2749                RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2750     }
2751     return RISCV_EXCP_NONE;
2752 }
2753 
2754 static RISCVException read_mtvec(CPURISCVState *env, int csrno,
2755                                  target_ulong *val)
2756 {
2757     *val = env->mtvec;
2758     return RISCV_EXCP_NONE;
2759 }
2760 
2761 static RISCVException write_mtvec(CPURISCVState *env, int csrno,
2762                                   target_ulong val)
2763 {
2764     /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
2765     if ((val & 3) < 2) {
2766         env->mtvec = val;
2767     } else {
2768         qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
2769     }
2770     return RISCV_EXCP_NONE;
2771 }
2772 
2773 static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
2774                                          target_ulong *val)
2775 {
2776     *val = env->mcountinhibit;
2777     return RISCV_EXCP_NONE;
2778 }
2779 
2780 static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
2781                                           target_ulong val)
2782 {
2783     int cidx;
2784     PMUCTRState *counter;
2785     RISCVCPU *cpu = env_archcpu(env);
2786     uint32_t present_ctrs = cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR;
2787     target_ulong updated_ctrs = (env->mcountinhibit ^ val) & present_ctrs;
2788     uint64_t mhpmctr_val, prev_count, curr_count;
2789 
2790     /* WARL register - disable unavailable counters; TM bit is always 0 */
2791     env->mcountinhibit = val & present_ctrs;
2792 
2793     /* Check if any other counter is also monitoring cycles/instructions */
2794     for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
2795         if (!(updated_ctrs & BIT(cidx)) ||
2796             (!riscv_pmu_ctr_monitor_cycles(env, cidx) &&
2797             !riscv_pmu_ctr_monitor_instructions(env, cidx))) {
2798             continue;
2799         }
2800 
2801         counter = &env->pmu_ctrs[cidx];
2802 
2803         if (!get_field(env->mcountinhibit, BIT(cidx))) {
2804             counter->mhpmcounter_prev =
2805                 riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false);
2806             if (riscv_cpu_mxl(env) == MXL_RV32) {
2807                 counter->mhpmcounterh_prev =
2808                     riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
2809             }
2810 
2811             if (cidx > 2) {
2812                 mhpmctr_val = counter->mhpmcounter_val;
2813                 if (riscv_cpu_mxl(env) == MXL_RV32) {
2814                     mhpmctr_val = mhpmctr_val |
2815                             ((uint64_t)counter->mhpmcounterh_val << 32);
2816                 }
2817                 riscv_pmu_setup_timer(env, mhpmctr_val, cidx);
2818             }
2819         } else {
2820             curr_count = riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false);
2821 
2822             mhpmctr_val = counter->mhpmcounter_val;
2823             prev_count = counter->mhpmcounter_prev;
2824             if (riscv_cpu_mxl(env) == MXL_RV32) {
2825                 uint64_t tmp =
2826                     riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
2827 
2828                 curr_count = curr_count | (tmp << 32);
2829                 mhpmctr_val = mhpmctr_val |
2830                     ((uint64_t)counter->mhpmcounterh_val << 32);
2831                 prev_count = prev_count |
2832                     ((uint64_t)counter->mhpmcounterh_prev << 32);
2833             }
2834 
2835             /* Adjust the counter for later reads. */
2836             mhpmctr_val = curr_count - prev_count + mhpmctr_val;
2837             counter->mhpmcounter_val = mhpmctr_val;
2838             if (riscv_cpu_mxl(env) == MXL_RV32) {
2839                 counter->mhpmcounterh_val = mhpmctr_val >> 32;
2840             }
2841         }
2842     }
2843 
2844     return RISCV_EXCP_NONE;
2845 }
2846 
2847 static RISCVException read_scountinhibit(CPURISCVState *env, int csrno,
2848                                          target_ulong *val)
2849 {
2850     /* S-mode can only access the bits delegated by M-mode */
2851     *val = env->mcountinhibit & env->mcounteren;
2852     return RISCV_EXCP_NONE;
2853 }
2854 
2855 static RISCVException write_scountinhibit(CPURISCVState *env, int csrno,
2856                                           target_ulong val)
2857 {
2858     write_mcountinhibit(env, csrno, val & env->mcounteren);
2859     return RISCV_EXCP_NONE;
2860 }
2861 
2862 static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
2863                                       target_ulong *val)
2864 {
2865     *val = env->mcounteren;
2866     return RISCV_EXCP_NONE;
2867 }
2868 
2869 static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
2870                                        target_ulong val)
2871 {
2872     RISCVCPU *cpu = env_archcpu(env);
2873 
2874     /* WARL register - disable unavailable counters */
2875     env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
2876                              COUNTEREN_IR);
2877     return RISCV_EXCP_NONE;
2878 }
2879 
2880 /* Machine Trap Handling */
2881 static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
2882                                          Int128 *val)
2883 {
2884     *val = int128_make128(env->mscratch, env->mscratchh);
2885     return RISCV_EXCP_NONE;
2886 }
2887 
2888 static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
2889                                           Int128 val)
2890 {
2891     env->mscratch = int128_getlo(val);
2892     env->mscratchh = int128_gethi(val);
2893     return RISCV_EXCP_NONE;
2894 }
2895 
2896 static RISCVException read_mscratch(CPURISCVState *env, int csrno,
2897                                     target_ulong *val)
2898 {
2899     *val = env->mscratch;
2900     return RISCV_EXCP_NONE;
2901 }
2902 
2903 static RISCVException write_mscratch(CPURISCVState *env, int csrno,
2904                                      target_ulong val)
2905 {
2906     env->mscratch = val;
2907     return RISCV_EXCP_NONE;
2908 }
2909 
2910 static RISCVException read_mepc(CPURISCVState *env, int csrno,
2911                                 target_ulong *val)
2912 {
2913     *val = env->mepc;
2914     return RISCV_EXCP_NONE;
2915 }
2916 
2917 static RISCVException write_mepc(CPURISCVState *env, int csrno,
2918                                  target_ulong val)
2919 {
2920     env->mepc = val;
2921     return RISCV_EXCP_NONE;
2922 }
2923 
2924 static RISCVException read_mcause(CPURISCVState *env, int csrno,
2925                                   target_ulong *val)
2926 {
2927     *val = env->mcause;
2928     return RISCV_EXCP_NONE;
2929 }
2930 
2931 static RISCVException write_mcause(CPURISCVState *env, int csrno,
2932                                    target_ulong val)
2933 {
2934     env->mcause = val;
2935     return RISCV_EXCP_NONE;
2936 }
2937 
2938 static RISCVException read_mtval(CPURISCVState *env, int csrno,
2939                                  target_ulong *val)
2940 {
2941     *val = env->mtval;
2942     return RISCV_EXCP_NONE;
2943 }
2944 
2945 static RISCVException write_mtval(CPURISCVState *env, int csrno,
2946                                   target_ulong val)
2947 {
2948     env->mtval = val;
2949     return RISCV_EXCP_NONE;
2950 }
2951 
2952 /* Execution environment configuration setup */
2953 static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
2954                                    target_ulong *val)
2955 {
2956     *val = env->menvcfg;
2957     return RISCV_EXCP_NONE;
2958 }
2959 
2960 static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
2961                                     target_ulong val);
2962 static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
2963                                     target_ulong val)
2964 {
2965     const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
2966     uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE |
2967                     MENVCFG_CBZE | MENVCFG_CDE;
2968 
2969     if (riscv_cpu_mxl(env) == MXL_RV64) {
2970         mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
2971                 (cfg->ext_sstc ? MENVCFG_STCE : 0) |
2972                 (cfg->ext_smcdeleg ? MENVCFG_CDE : 0) |
2973                 (cfg->ext_svadu ? MENVCFG_ADUE : 0) |
2974                 (cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
2975 
2976         if (env_archcpu(env)->cfg.ext_zicfilp) {
2977             mask |= MENVCFG_LPE;
2978         }
2979 
2980         if (env_archcpu(env)->cfg.ext_zicfiss) {
2981             mask |= MENVCFG_SSE;
2982         }
2983 
2984         /* Update PMM field only if the value is valid according to Zjpm v1.0 */
2985         if (env_archcpu(env)->cfg.ext_smnpm &&
2986             get_field(val, MENVCFG_PMM) != PMM_FIELD_RESERVED) {
2987             mask |= MENVCFG_PMM;
2988 	}
2989 
2990         if ((val & MENVCFG_DTE) == 0) {
2991             env->mstatus &= ~MSTATUS_SDT;
2992         }
2993     }
2994     env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
2995     write_henvcfg(env, CSR_HENVCFG, env->henvcfg);
2996 
2997     return RISCV_EXCP_NONE;
2998 }
2999 
3000 static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
3001                                     target_ulong *val)
3002 {
3003     *val = env->menvcfg >> 32;
3004     return RISCV_EXCP_NONE;
3005 }
3006 
3007 static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
3008                                     target_ulong val);
3009 static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
3010                                      target_ulong val)
3011 {
3012     const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
3013     uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
3014                     (cfg->ext_sstc ? MENVCFG_STCE : 0) |
3015                     (cfg->ext_svadu ? MENVCFG_ADUE : 0) |
3016                     (cfg->ext_smcdeleg ? MENVCFG_CDE : 0) |
3017                     (cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
3018     uint64_t valh = (uint64_t)val << 32;
3019 
3020     if ((valh & MENVCFG_DTE) == 0) {
3021         env->mstatus &= ~MSTATUS_SDT;
3022     }
3023 
3024     env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
3025     write_henvcfgh(env, CSR_HENVCFGH, env->henvcfg >> 32);
3026 
3027     return RISCV_EXCP_NONE;
3028 }
3029 
3030 static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
3031                                    target_ulong *val)
3032 {
3033     RISCVException ret;
3034 
3035     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
3036     if (ret != RISCV_EXCP_NONE) {
3037         return ret;
3038     }
3039 
3040     *val = env->senvcfg;
3041     return RISCV_EXCP_NONE;
3042 }
3043 
3044 static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
3045                                     target_ulong val)
3046 {
3047     uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
3048     RISCVException ret;
3049     /* Update PMM field only if the value is valid according to Zjpm v1.0 */
3050     if (env_archcpu(env)->cfg.ext_ssnpm &&
3051         riscv_cpu_mxl(env) == MXL_RV64 &&
3052         get_field(val, SENVCFG_PMM) != PMM_FIELD_RESERVED) {
3053         mask |= SENVCFG_PMM;
3054     }
3055 
3056     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
3057     if (ret != RISCV_EXCP_NONE) {
3058         return ret;
3059     }
3060 
3061     if (env_archcpu(env)->cfg.ext_zicfilp) {
3062         mask |= SENVCFG_LPE;
3063     }
3064 
3065     /* Higher mode SSE must be ON for next-less mode SSE to be ON */
3066     if (env_archcpu(env)->cfg.ext_zicfiss &&
3067         get_field(env->menvcfg, MENVCFG_SSE) &&
3068         (env->virt_enabled ? get_field(env->henvcfg, HENVCFG_SSE) : true)) {
3069         mask |= SENVCFG_SSE;
3070     }
3071 
3072     if (env_archcpu(env)->cfg.ext_svukte) {
3073         mask |= SENVCFG_UKTE;
3074     }
3075 
3076     env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
3077     return RISCV_EXCP_NONE;
3078 }
3079 
3080 static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
3081                                    target_ulong *val)
3082 {
3083     RISCVException ret;
3084 
3085     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
3086     if (ret != RISCV_EXCP_NONE) {
3087         return ret;
3088     }
3089 
3090     /*
3091      * henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
3092      * henvcfg.stce is read_only 0 when menvcfg.stce = 0
3093      * henvcfg.adue is read_only 0 when menvcfg.adue = 0
3094      * henvcfg.dte is read_only 0 when menvcfg.dte = 0
3095      */
3096     *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
3097                              HENVCFG_DTE) | env->menvcfg);
3098     return RISCV_EXCP_NONE;
3099 }
3100 
3101 static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
3102                                     target_ulong val)
3103 {
3104     uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
3105     RISCVException ret;
3106 
3107     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
3108     if (ret != RISCV_EXCP_NONE) {
3109         return ret;
3110     }
3111 
3112     if (riscv_cpu_mxl(env) == MXL_RV64) {
3113         mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
3114                                 HENVCFG_DTE);
3115 
3116         if (env_archcpu(env)->cfg.ext_zicfilp) {
3117             mask |= HENVCFG_LPE;
3118         }
3119 
3120         /* H can light up SSE for VS only if HS had it from menvcfg */
3121         if (env_archcpu(env)->cfg.ext_zicfiss &&
3122             get_field(env->menvcfg, MENVCFG_SSE)) {
3123             mask |= HENVCFG_SSE;
3124         }
3125 
3126         /* Update PMM field only if the value is valid according to Zjpm v1.0 */
3127         if (env_archcpu(env)->cfg.ext_ssnpm &&
3128             get_field(val, HENVCFG_PMM) != PMM_FIELD_RESERVED) {
3129             mask |= HENVCFG_PMM;
3130         }
3131     }
3132 
3133     env->henvcfg = val & mask;
3134     if ((env->henvcfg & HENVCFG_DTE) == 0) {
3135         env->vsstatus &= ~MSTATUS_SDT;
3136     }
3137 
3138     return RISCV_EXCP_NONE;
3139 }
3140 
3141 static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
3142                                     target_ulong *val)
3143 {
3144     RISCVException ret;
3145 
3146     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
3147     if (ret != RISCV_EXCP_NONE) {
3148         return ret;
3149     }
3150 
3151     *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
3152                               HENVCFG_DTE) | env->menvcfg)) >> 32;
3153     return RISCV_EXCP_NONE;
3154 }
3155 
3156 static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
3157                                      target_ulong val)
3158 {
3159     uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
3160                                     HENVCFG_ADUE | HENVCFG_DTE);
3161     uint64_t valh = (uint64_t)val << 32;
3162     RISCVException ret;
3163 
3164     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
3165     if (ret != RISCV_EXCP_NONE) {
3166         return ret;
3167     }
3168     env->henvcfg = (env->henvcfg & 0xFFFFFFFF) | (valh & mask);
3169     if ((env->henvcfg & HENVCFG_DTE) == 0) {
3170         env->vsstatus &= ~MSTATUS_SDT;
3171     }
3172     return RISCV_EXCP_NONE;
3173 }
3174 
3175 static RISCVException read_mstateen(CPURISCVState *env, int csrno,
3176                                     target_ulong *val)
3177 {
3178     *val = env->mstateen[csrno - CSR_MSTATEEN0];
3179 
3180     return RISCV_EXCP_NONE;
3181 }
3182 
3183 static RISCVException write_mstateen(CPURISCVState *env, int csrno,
3184                                      uint64_t wr_mask, target_ulong new_val)
3185 {
3186     uint64_t *reg;
3187 
3188     reg = &env->mstateen[csrno - CSR_MSTATEEN0];
3189     *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
3190 
3191     return RISCV_EXCP_NONE;
3192 }
3193 
3194 static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
3195                                       target_ulong new_val)
3196 {
3197     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
3198     if (!riscv_has_ext(env, RVF)) {
3199         wr_mask |= SMSTATEEN0_FCSR;
3200     }
3201 
3202     if (env->priv_ver >= PRIV_VERSION_1_13_0) {
3203         wr_mask |= SMSTATEEN0_P1P13;
3204     }
3205 
3206     if (riscv_cpu_cfg(env)->ext_smaia || riscv_cpu_cfg(env)->ext_smcsrind) {
3207         wr_mask |= SMSTATEEN0_SVSLCT;
3208     }
3209 
3210     /*
3211      * As per the AIA specification, SMSTATEEN0_IMSIC is valid only if IMSIC is
3212      * implemented. However, that information is with MachineState and we can't
3213      * figure that out in csr.c. Just enable if Smaia is available.
3214      */
3215     if (riscv_cpu_cfg(env)->ext_smaia) {
3216         wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
3217     }
3218 
3219     return write_mstateen(env, csrno, wr_mask, new_val);
3220 }
3221 
3222 static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
3223                                          target_ulong new_val)
3224 {
3225     return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
3226 }
3227 
3228 static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
3229                                      target_ulong *val)
3230 {
3231     *val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
3232 
3233     return RISCV_EXCP_NONE;
3234 }
3235 
3236 static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
3237                                       uint64_t wr_mask, target_ulong new_val)
3238 {
3239     uint64_t *reg, val;
3240 
3241     reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
3242     val = (uint64_t)new_val << 32;
3243     val |= *reg & 0xFFFFFFFF;
3244     *reg = (*reg & ~wr_mask) | (val & wr_mask);
3245 
3246     return RISCV_EXCP_NONE;
3247 }
3248 
3249 static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
3250                                        target_ulong new_val)
3251 {
3252     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
3253 
3254     if (env->priv_ver >= PRIV_VERSION_1_13_0) {
3255         wr_mask |= SMSTATEEN0_P1P13;
3256     }
3257 
3258     return write_mstateenh(env, csrno, wr_mask, new_val);
3259 }
3260 
3261 static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
3262                                           target_ulong new_val)
3263 {
3264     return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
3265 }
3266 
3267 static RISCVException read_hstateen(CPURISCVState *env, int csrno,
3268                                     target_ulong *val)
3269 {
3270     int index = csrno - CSR_HSTATEEN0;
3271 
3272     *val = env->hstateen[index] & env->mstateen[index];
3273 
3274     return RISCV_EXCP_NONE;
3275 }
3276 
3277 static RISCVException write_hstateen(CPURISCVState *env, int csrno,
3278                                      uint64_t mask, target_ulong new_val)
3279 {
3280     int index = csrno - CSR_HSTATEEN0;
3281     uint64_t *reg, wr_mask;
3282 
3283     reg = &env->hstateen[index];
3284     wr_mask = env->mstateen[index] & mask;
3285     *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
3286 
3287     return RISCV_EXCP_NONE;
3288 }
3289 
3290 static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
3291                                       target_ulong new_val)
3292 {
3293     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
3294 
3295     if (!riscv_has_ext(env, RVF)) {
3296         wr_mask |= SMSTATEEN0_FCSR;
3297     }
3298 
3299     if (riscv_cpu_cfg(env)->ext_ssaia || riscv_cpu_cfg(env)->ext_sscsrind) {
3300         wr_mask |= SMSTATEEN0_SVSLCT;
3301     }
3302 
3303     /*
3304      * As per the AIA specification, SMSTATEEN0_IMSIC is valid only if IMSIC is
3305      * implemented. However, that information is with MachineState and we can't
3306      * figure that out in csr.c. Just enable if Ssaia is available.
3307      */
3308     if (riscv_cpu_cfg(env)->ext_ssaia) {
3309         wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
3310     }
3311 
3312     return write_hstateen(env, csrno, wr_mask, new_val);
3313 }
3314 
3315 static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
3316                                          target_ulong new_val)
3317 {
3318     return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
3319 }
3320 
3321 static RISCVException read_hstateenh(CPURISCVState *env, int csrno,
3322                                      target_ulong *val)
3323 {
3324     int index = csrno - CSR_HSTATEEN0H;
3325 
3326     *val = (env->hstateen[index] >> 32) & (env->mstateen[index] >> 32);
3327 
3328     return RISCV_EXCP_NONE;
3329 }
3330 
3331 static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
3332                                       uint64_t mask, target_ulong new_val)
3333 {
3334     int index = csrno - CSR_HSTATEEN0H;
3335     uint64_t *reg, wr_mask, val;
3336 
3337     reg = &env->hstateen[index];
3338     val = (uint64_t)new_val << 32;
3339     val |= *reg & 0xFFFFFFFF;
3340     wr_mask = env->mstateen[index] & mask;
3341     *reg = (*reg & ~wr_mask) | (val & wr_mask);
3342 
3343     return RISCV_EXCP_NONE;
3344 }
3345 
3346 static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
3347                                        target_ulong new_val)
3348 {
3349     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
3350 
3351     return write_hstateenh(env, csrno, wr_mask, new_val);
3352 }
3353 
3354 static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
3355                                           target_ulong new_val)
3356 {
3357     return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
3358 }
3359 
3360 static RISCVException read_sstateen(CPURISCVState *env, int csrno,
3361                                     target_ulong *val)
3362 {
3363     bool virt = env->virt_enabled;
3364     int index = csrno - CSR_SSTATEEN0;
3365 
3366     *val = env->sstateen[index] & env->mstateen[index];
3367     if (virt) {
3368         *val &= env->hstateen[index];
3369     }
3370 
3371     return RISCV_EXCP_NONE;
3372 }
3373 
3374 static RISCVException write_sstateen(CPURISCVState *env, int csrno,
3375                                      uint64_t mask, target_ulong new_val)
3376 {
3377     bool virt = env->virt_enabled;
3378     int index = csrno - CSR_SSTATEEN0;
3379     uint64_t wr_mask;
3380     uint64_t *reg;
3381 
3382     wr_mask = env->mstateen[index] & mask;
3383     if (virt) {
3384         wr_mask &= env->hstateen[index];
3385     }
3386 
3387     reg = &env->sstateen[index];
3388     *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
3389 
3390     return RISCV_EXCP_NONE;
3391 }
3392 
3393 static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
3394                                       target_ulong new_val)
3395 {
3396     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
3397 
3398     if (!riscv_has_ext(env, RVF)) {
3399         wr_mask |= SMSTATEEN0_FCSR;
3400     }
3401 
3402     return write_sstateen(env, csrno, wr_mask, new_val);
3403 }
3404 
3405 static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
3406                                       target_ulong new_val)
3407 {
3408     return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
3409 }
3410 
3411 static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
3412                                 uint64_t *ret_val,
3413                                 uint64_t new_val, uint64_t wr_mask)
3414 {
3415     uint64_t old_mip, mask = wr_mask & delegable_ints;
3416     uint32_t gin;
3417 
3418     if (mask & MIP_SEIP) {
3419         env->software_seip = new_val & MIP_SEIP;
3420         new_val |= env->external_seip * MIP_SEIP;
3421     }
3422 
3423     if (riscv_cpu_cfg(env)->ext_sstc && (env->priv == PRV_M) &&
3424         get_field(env->menvcfg, MENVCFG_STCE)) {
3425         /* sstc extension forbids STIP & VSTIP to be writeable in mip */
3426         mask = mask & ~(MIP_STIP | MIP_VSTIP);
3427     }
3428 
3429     if (mask) {
3430         old_mip = riscv_cpu_update_mip(env, mask, (new_val & mask));
3431     } else {
3432         old_mip = env->mip;
3433     }
3434 
3435     if (csrno != CSR_HVIP) {
3436         gin = get_field(env->hstatus, HSTATUS_VGEIN);
3437         old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
3438         old_mip |= env->vstime_irq ? MIP_VSTIP : 0;
3439     }
3440 
3441     if (ret_val) {
3442         *ret_val = old_mip;
3443     }
3444 
3445     return RISCV_EXCP_NONE;
3446 }
3447 
3448 static RISCVException rmw_mip(CPURISCVState *env, int csrno,
3449                               target_ulong *ret_val,
3450                               target_ulong new_val, target_ulong wr_mask)
3451 {
3452     uint64_t rval;
3453     RISCVException ret;
3454 
3455     ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
3456     if (ret_val) {
3457         *ret_val = rval;
3458     }
3459 
3460     return ret;
3461 }
3462 
3463 static RISCVException rmw_miph(CPURISCVState *env, int csrno,
3464                                target_ulong *ret_val,
3465                                target_ulong new_val, target_ulong wr_mask)
3466 {
3467     uint64_t rval;
3468     RISCVException ret;
3469 
3470     ret = rmw_mip64(env, csrno, &rval,
3471         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3472     if (ret_val) {
3473         *ret_val = rval >> 32;
3474     }
3475 
3476     return ret;
3477 }
3478 
3479 /*
3480  * The function is written for two use-cases:
3481  * 1- To access mvip csr as is for m-mode access.
3482  * 2- To access sip as a combination of mip and mvip for s-mode.
3483  *
3484  * Both report bits 1, 5, 9 and 13:63 but with the exception of
3485  * STIP being read-only zero in case of mvip when sstc extension
3486  * is present.
3487  * Also, sip needs to be read-only zero when both mideleg[i] and
3488  * mvien[i] are zero but mvip needs to be an alias of mip.
3489  */
3490 static RISCVException rmw_mvip64(CPURISCVState *env, int csrno,
3491                                 uint64_t *ret_val,
3492                                 uint64_t new_val, uint64_t wr_mask)
3493 {
3494     RISCVCPU *cpu = env_archcpu(env);
3495     target_ulong ret_mip = 0;
3496     RISCVException ret;
3497     uint64_t old_mvip;
3498 
3499     /*
3500      * mideleg[i]  mvien[i]
3501      *   0           0      No delegation. mvip[i] is alias of mip[i].
3502      *   0           1      mvip[i] becomes source of interrupt, mip bypassed.
3503      *   1           X      mip[i] is source of interrupt and mvip[i] aliases
3504      *                      mip[i].
3505      *
3506      *   So alias condition would be for bits:
3507      *      ((S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & (mideleg | ~mvien)) |
3508      *          (!sstc & MIP_STIP)
3509      *
3510      *   Non-alias condition will be for bits:
3511      *      (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & (~mideleg & mvien)
3512      *
3513      *  alias_mask denotes the bits that come from mip nalias_mask denotes bits
3514      *  that come from hvip.
3515      */
3516     uint64_t alias_mask = ((S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) &
3517         (env->mideleg | ~env->mvien)) | MIP_STIP;
3518     uint64_t nalias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) &
3519         (~env->mideleg & env->mvien);
3520     uint64_t wr_mask_mvip;
3521     uint64_t wr_mask_mip;
3522 
3523     /*
3524      * mideleg[i]  mvien[i]
3525      *   0           0      sip[i] read-only zero.
3526      *   0           1      sip[i] alias of mvip[i].
3527      *   1           X      sip[i] alias of mip[i].
3528      *
3529      *  Both alias and non-alias mask remain same for sip except for bits
3530      *  which are zero in both mideleg and mvien.
3531      */
3532     if (csrno == CSR_SIP) {
3533         /* Remove bits that are zero in both mideleg and mvien. */
3534         alias_mask &= (env->mideleg | env->mvien);
3535         nalias_mask &= (env->mideleg | env->mvien);
3536     }
3537 
3538     /*
3539      * If sstc is present, mvip.STIP is not an alias of mip.STIP so clear
3540      * that our in mip returned value.
3541      */
3542     if (cpu->cfg.ext_sstc && (env->priv == PRV_M) &&
3543         get_field(env->menvcfg, MENVCFG_STCE)) {
3544         alias_mask &= ~MIP_STIP;
3545     }
3546 
3547     wr_mask_mip = wr_mask & alias_mask & mvip_writable_mask;
3548     wr_mask_mvip = wr_mask & nalias_mask & mvip_writable_mask;
3549 
3550     /*
3551      * For bits set in alias_mask, mvip needs to be alias of mip, so forward
3552      * this to rmw_mip.
3553      */
3554     ret = rmw_mip(env, CSR_MIP, &ret_mip, new_val, wr_mask_mip);
3555     if (ret != RISCV_EXCP_NONE) {
3556         return ret;
3557     }
3558 
3559     old_mvip = env->mvip;
3560 
3561     /*
3562      * Write to mvip. Update only non-alias bits. Alias bits were updated
3563      * in mip in rmw_mip above.
3564      */
3565     if (wr_mask_mvip) {
3566         env->mvip = (env->mvip & ~wr_mask_mvip) | (new_val & wr_mask_mvip);
3567 
3568         /*
3569          * Given mvip is separate source from mip, we need to trigger interrupt
3570          * from here separately. Normally this happen from riscv_cpu_update_mip.
3571          */
3572         riscv_cpu_interrupt(env);
3573     }
3574 
3575     if (ret_val) {
3576         ret_mip &= alias_mask;
3577         old_mvip &= nalias_mask;
3578 
3579         *ret_val = old_mvip | ret_mip;
3580     }
3581 
3582     return RISCV_EXCP_NONE;
3583 }
3584 
3585 static RISCVException rmw_mvip(CPURISCVState *env, int csrno,
3586                               target_ulong *ret_val,
3587                               target_ulong new_val, target_ulong wr_mask)
3588 {
3589     uint64_t rval;
3590     RISCVException ret;
3591 
3592     ret = rmw_mvip64(env, csrno, &rval, new_val, wr_mask);
3593     if (ret_val) {
3594         *ret_val = rval;
3595     }
3596 
3597     return ret;
3598 }
3599 
3600 static RISCVException rmw_mviph(CPURISCVState *env, int csrno,
3601                                target_ulong *ret_val,
3602                                target_ulong new_val, target_ulong wr_mask)
3603 {
3604     uint64_t rval;
3605     RISCVException ret;
3606 
3607     ret = rmw_mvip64(env, csrno, &rval,
3608         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3609     if (ret_val) {
3610         *ret_val = rval >> 32;
3611     }
3612 
3613     return ret;
3614 }
3615 
3616 /* Supervisor Trap Setup */
3617 static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
3618                                         Int128 *val)
3619 {
3620     uint64_t mask = sstatus_v1_10_mask;
3621     uint64_t sstatus = env->mstatus & mask;
3622     if (env->xl != MXL_RV32 || env->debugger) {
3623         mask |= SSTATUS64_UXL;
3624     }
3625     if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
3626         mask |= SSTATUS_SDT;
3627     }
3628 
3629     if (env_archcpu(env)->cfg.ext_zicfilp) {
3630         mask |= SSTATUS_SPELP;
3631     }
3632 
3633     *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
3634     return RISCV_EXCP_NONE;
3635 }
3636 
3637 static RISCVException read_sstatus(CPURISCVState *env, int csrno,
3638                                    target_ulong *val)
3639 {
3640     target_ulong mask = (sstatus_v1_10_mask);
3641     if (env->xl != MXL_RV32 || env->debugger) {
3642         mask |= SSTATUS64_UXL;
3643     }
3644 
3645     if (env_archcpu(env)->cfg.ext_zicfilp) {
3646         mask |= SSTATUS_SPELP;
3647     }
3648     if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
3649         mask |= SSTATUS_SDT;
3650     }
3651     /* TODO: Use SXL not MXL. */
3652     *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
3653     return RISCV_EXCP_NONE;
3654 }
3655 
3656 static RISCVException write_sstatus(CPURISCVState *env, int csrno,
3657                                     target_ulong val)
3658 {
3659     target_ulong mask = (sstatus_v1_10_mask);
3660 
3661     if (env->xl != MXL_RV32 || env->debugger) {
3662         if ((val & SSTATUS64_UXL) != 0) {
3663             mask |= SSTATUS64_UXL;
3664         }
3665     }
3666 
3667     if (env_archcpu(env)->cfg.ext_zicfilp) {
3668         mask |= SSTATUS_SPELP;
3669     }
3670     if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
3671         mask |= SSTATUS_SDT;
3672     }
3673     target_ulong newval = (env->mstatus & ~mask) | (val & mask);
3674     return write_mstatus(env, CSR_MSTATUS, newval);
3675 }
3676 
3677 static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
3678                                  uint64_t *ret_val,
3679                                  uint64_t new_val, uint64_t wr_mask)
3680 {
3681     uint64_t alias_mask = (LOCAL_INTERRUPTS | VS_MODE_INTERRUPTS) &
3682                             env->hideleg;
3683     uint64_t nalias_mask = LOCAL_INTERRUPTS & (~env->hideleg & env->hvien);
3684     uint64_t rval, rval_vs, vsbits;
3685     uint64_t wr_mask_vsie;
3686     uint64_t wr_mask_mie;
3687     RISCVException ret;
3688 
3689     /* Bring VS-level bits to correct position */
3690     vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
3691     new_val &= ~(VS_MODE_INTERRUPTS >> 1);
3692     new_val |= vsbits << 1;
3693 
3694     vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
3695     wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
3696     wr_mask |= vsbits << 1;
3697 
3698     wr_mask_mie = wr_mask & alias_mask;
3699     wr_mask_vsie = wr_mask & nalias_mask;
3700 
3701     ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask_mie);
3702 
3703     rval_vs = env->vsie & nalias_mask;
3704     env->vsie = (env->vsie & ~wr_mask_vsie) | (new_val & wr_mask_vsie);
3705 
3706     if (ret_val) {
3707         rval &= alias_mask;
3708         vsbits = rval & VS_MODE_INTERRUPTS;
3709         rval &= ~VS_MODE_INTERRUPTS;
3710         *ret_val = rval | (vsbits >> 1) | rval_vs;
3711     }
3712 
3713     return ret;
3714 }
3715 
3716 static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
3717                                target_ulong *ret_val,
3718                                target_ulong new_val, target_ulong wr_mask)
3719 {
3720     uint64_t rval;
3721     RISCVException ret;
3722 
3723     ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
3724     if (ret_val) {
3725         *ret_val = rval;
3726     }
3727 
3728     return ret;
3729 }
3730 
3731 static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
3732                                 target_ulong *ret_val,
3733                                 target_ulong new_val, target_ulong wr_mask)
3734 {
3735     uint64_t rval;
3736     RISCVException ret;
3737 
3738     ret = rmw_vsie64(env, csrno, &rval,
3739         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3740     if (ret_val) {
3741         *ret_val = rval >> 32;
3742     }
3743 
3744     return ret;
3745 }
3746 
3747 static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
3748                                 uint64_t *ret_val,
3749                                 uint64_t new_val, uint64_t wr_mask)
3750 {
3751     uint64_t nalias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) &
3752         (~env->mideleg & env->mvien);
3753     uint64_t alias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & env->mideleg;
3754     uint64_t sie_mask = wr_mask & nalias_mask;
3755     RISCVException ret;
3756 
3757     /*
3758      * mideleg[i]  mvien[i]
3759      *   0           0      sie[i] read-only zero.
3760      *   0           1      sie[i] is a separate writable bit.
3761      *   1           X      sie[i] alias of mie[i].
3762      *
3763      *  Both alias and non-alias mask remain same for sip except for bits
3764      *  which are zero in both mideleg and mvien.
3765      */
3766     if (env->virt_enabled) {
3767         if (env->hvictl & HVICTL_VTI) {
3768             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
3769         }
3770         ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
3771         if (ret_val) {
3772             *ret_val &= alias_mask;
3773         }
3774     } else {
3775         ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & alias_mask);
3776         if (ret_val) {
3777             *ret_val &= alias_mask;
3778             *ret_val |= env->sie & nalias_mask;
3779         }
3780 
3781         env->sie = (env->sie & ~sie_mask) | (new_val & sie_mask);
3782     }
3783 
3784     return ret;
3785 }
3786 
3787 static RISCVException rmw_sie(CPURISCVState *env, int csrno,
3788                               target_ulong *ret_val,
3789                               target_ulong new_val, target_ulong wr_mask)
3790 {
3791     uint64_t rval;
3792     RISCVException ret;
3793 
3794     ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
3795     if (ret == RISCV_EXCP_NONE && ret_val) {
3796         *ret_val = rval;
3797     }
3798 
3799     return ret;
3800 }
3801 
3802 static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
3803                                target_ulong *ret_val,
3804                                target_ulong new_val, target_ulong wr_mask)
3805 {
3806     uint64_t rval;
3807     RISCVException ret;
3808 
3809     ret = rmw_sie64(env, csrno, &rval,
3810         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3811     if (ret_val) {
3812         *ret_val = rval >> 32;
3813     }
3814 
3815     return ret;
3816 }
3817 
3818 static RISCVException read_stvec(CPURISCVState *env, int csrno,
3819                                  target_ulong *val)
3820 {
3821     *val = env->stvec;
3822     return RISCV_EXCP_NONE;
3823 }
3824 
3825 static RISCVException write_stvec(CPURISCVState *env, int csrno,
3826                                   target_ulong val)
3827 {
3828     /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
3829     if ((val & 3) < 2) {
3830         env->stvec = val;
3831     } else {
3832         qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
3833     }
3834     return RISCV_EXCP_NONE;
3835 }
3836 
3837 static RISCVException read_scounteren(CPURISCVState *env, int csrno,
3838                                       target_ulong *val)
3839 {
3840     *val = env->scounteren;
3841     return RISCV_EXCP_NONE;
3842 }
3843 
3844 static RISCVException write_scounteren(CPURISCVState *env, int csrno,
3845                                        target_ulong val)
3846 {
3847     RISCVCPU *cpu = env_archcpu(env);
3848 
3849     /* WARL register - disable unavailable counters */
3850     env->scounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
3851                              COUNTEREN_IR);
3852     return RISCV_EXCP_NONE;
3853 }
3854 
3855 /* Supervisor Trap Handling */
3856 static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
3857                                          Int128 *val)
3858 {
3859     *val = int128_make128(env->sscratch, env->sscratchh);
3860     return RISCV_EXCP_NONE;
3861 }
3862 
3863 static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
3864                                           Int128 val)
3865 {
3866     env->sscratch = int128_getlo(val);
3867     env->sscratchh = int128_gethi(val);
3868     return RISCV_EXCP_NONE;
3869 }
3870 
3871 static RISCVException read_sscratch(CPURISCVState *env, int csrno,
3872                                     target_ulong *val)
3873 {
3874     *val = env->sscratch;
3875     return RISCV_EXCP_NONE;
3876 }
3877 
3878 static RISCVException write_sscratch(CPURISCVState *env, int csrno,
3879                                      target_ulong val)
3880 {
3881     env->sscratch = val;
3882     return RISCV_EXCP_NONE;
3883 }
3884 
3885 static RISCVException read_sepc(CPURISCVState *env, int csrno,
3886                                 target_ulong *val)
3887 {
3888     *val = env->sepc;
3889     return RISCV_EXCP_NONE;
3890 }
3891 
3892 static RISCVException write_sepc(CPURISCVState *env, int csrno,
3893                                  target_ulong val)
3894 {
3895     env->sepc = val;
3896     return RISCV_EXCP_NONE;
3897 }
3898 
3899 static RISCVException read_scause(CPURISCVState *env, int csrno,
3900                                   target_ulong *val)
3901 {
3902     *val = env->scause;
3903     return RISCV_EXCP_NONE;
3904 }
3905 
3906 static RISCVException write_scause(CPURISCVState *env, int csrno,
3907                                    target_ulong val)
3908 {
3909     env->scause = val;
3910     return RISCV_EXCP_NONE;
3911 }
3912 
3913 static RISCVException read_stval(CPURISCVState *env, int csrno,
3914                                  target_ulong *val)
3915 {
3916     *val = env->stval;
3917     return RISCV_EXCP_NONE;
3918 }
3919 
3920 static RISCVException write_stval(CPURISCVState *env, int csrno,
3921                                   target_ulong val)
3922 {
3923     env->stval = val;
3924     return RISCV_EXCP_NONE;
3925 }
3926 
3927 static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
3928                                  uint64_t *ret_val,
3929                                  uint64_t new_val, uint64_t wr_mask);
3930 
3931 static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
3932                                  uint64_t *ret_val,
3933                                  uint64_t new_val, uint64_t wr_mask)
3934 {
3935     RISCVException ret;
3936     uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
3937     uint64_t vsbits;
3938 
3939     /* Add virtualized bits into vsip mask. */
3940     mask |= env->hvien & ~env->hideleg;
3941 
3942     /* Bring VS-level bits to correct position */
3943     vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
3944     new_val &= ~(VS_MODE_INTERRUPTS >> 1);
3945     new_val |= vsbits << 1;
3946     vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
3947     wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
3948     wr_mask |= vsbits << 1;
3949 
3950     ret = rmw_hvip64(env, csrno, &rval, new_val,
3951                      wr_mask & mask & vsip_writable_mask);
3952     if (ret_val) {
3953         rval &= mask;
3954         vsbits = rval & VS_MODE_INTERRUPTS;
3955         rval &= ~VS_MODE_INTERRUPTS;
3956         *ret_val = rval | (vsbits >> 1);
3957     }
3958 
3959     return ret;
3960 }
3961 
3962 static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
3963                                target_ulong *ret_val,
3964                                target_ulong new_val, target_ulong wr_mask)
3965 {
3966     uint64_t rval;
3967     RISCVException ret;
3968 
3969     ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
3970     if (ret_val) {
3971         *ret_val = rval;
3972     }
3973 
3974     return ret;
3975 }
3976 
3977 static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
3978                                 target_ulong *ret_val,
3979                                 target_ulong new_val, target_ulong wr_mask)
3980 {
3981     uint64_t rval;
3982     RISCVException ret;
3983 
3984     ret = rmw_vsip64(env, csrno, &rval,
3985         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3986     if (ret_val) {
3987         *ret_val = rval >> 32;
3988     }
3989 
3990     return ret;
3991 }
3992 
3993 static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
3994                                 uint64_t *ret_val,
3995                                 uint64_t new_val, uint64_t wr_mask)
3996 {
3997     RISCVException ret;
3998     uint64_t mask = (env->mideleg | env->mvien) & sip_writable_mask;
3999 
4000     if (env->virt_enabled) {
4001         if (env->hvictl & HVICTL_VTI) {
4002             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
4003         }
4004         ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
4005     } else {
4006         ret = rmw_mvip64(env, csrno, ret_val, new_val, wr_mask & mask);
4007     }
4008 
4009     if (ret_val) {
4010         *ret_val &= (env->mideleg | env->mvien) &
4011             (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS);
4012     }
4013 
4014     return ret;
4015 }
4016 
4017 static RISCVException rmw_sip(CPURISCVState *env, int csrno,
4018                               target_ulong *ret_val,
4019                               target_ulong new_val, target_ulong wr_mask)
4020 {
4021     uint64_t rval;
4022     RISCVException ret;
4023 
4024     ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
4025     if (ret_val) {
4026         *ret_val = rval;
4027     }
4028 
4029     return ret;
4030 }
4031 
4032 static RISCVException rmw_siph(CPURISCVState *env, int csrno,
4033                                target_ulong *ret_val,
4034                                target_ulong new_val, target_ulong wr_mask)
4035 {
4036     uint64_t rval;
4037     RISCVException ret;
4038 
4039     ret = rmw_sip64(env, csrno, &rval,
4040         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
4041     if (ret_val) {
4042         *ret_val = rval >> 32;
4043     }
4044 
4045     return ret;
4046 }
4047 
4048 /* Supervisor Protection and Translation */
4049 static RISCVException read_satp(CPURISCVState *env, int csrno,
4050                                 target_ulong *val)
4051 {
4052     if (!riscv_cpu_cfg(env)->mmu) {
4053         *val = 0;
4054         return RISCV_EXCP_NONE;
4055     }
4056     *val = env->satp;
4057     return RISCV_EXCP_NONE;
4058 }
4059 
4060 static RISCVException write_satp(CPURISCVState *env, int csrno,
4061                                  target_ulong val)
4062 {
4063     if (!riscv_cpu_cfg(env)->mmu) {
4064         return RISCV_EXCP_NONE;
4065     }
4066 
4067     env->satp = legalize_xatp(env, env->satp, val);
4068     return RISCV_EXCP_NONE;
4069 }
4070 
4071 static RISCVException read_vstopi(CPURISCVState *env, int csrno,
4072                                   target_ulong *val)
4073 {
4074     int irq, ret;
4075     target_ulong topei;
4076     uint64_t vseip, vsgein;
4077     uint32_t iid, iprio, hviid, hviprio, gein;
4078     uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS];
4079 
4080     gein = get_field(env->hstatus, HSTATUS_VGEIN);
4081     hviid = get_field(env->hvictl, HVICTL_IID);
4082     hviprio = get_field(env->hvictl, HVICTL_IPRIO);
4083 
4084     if (gein) {
4085         vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
4086         vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP;
4087         if (gein <= env->geilen && vseip) {
4088             siid[scount] = IRQ_S_EXT;
4089             siprio[scount] = IPRIO_MMAXIPRIO + 1;
4090             if (env->aia_ireg_rmw_fn[PRV_S]) {
4091                 /*
4092                  * Call machine specific IMSIC register emulation for
4093                  * reading TOPEI.
4094                  */
4095                 ret = env->aia_ireg_rmw_fn[PRV_S](
4096                         env->aia_ireg_rmw_fn_arg[PRV_S],
4097                         AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein,
4098                                       riscv_cpu_mxl_bits(env)),
4099                         &topei, 0, 0);
4100                 if (!ret && topei) {
4101                     siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK;
4102                 }
4103             }
4104             scount++;
4105         }
4106     } else {
4107         if (hviid == IRQ_S_EXT && hviprio) {
4108             siid[scount] = IRQ_S_EXT;
4109             siprio[scount] = hviprio;
4110             scount++;
4111         }
4112     }
4113 
4114     if (env->hvictl & HVICTL_VTI) {
4115         if (hviid != IRQ_S_EXT) {
4116             siid[scount] = hviid;
4117             siprio[scount] = hviprio;
4118             scount++;
4119         }
4120     } else {
4121         irq = riscv_cpu_vsirq_pending(env);
4122         if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) {
4123             siid[scount] = irq;
4124             siprio[scount] = env->hviprio[irq];
4125             scount++;
4126         }
4127     }
4128 
4129     iid = 0;
4130     iprio = UINT_MAX;
4131     for (s = 0; s < scount; s++) {
4132         if (siprio[s] < iprio) {
4133             iid = siid[s];
4134             iprio = siprio[s];
4135         }
4136     }
4137 
4138     if (iid) {
4139         if (env->hvictl & HVICTL_IPRIOM) {
4140             if (iprio > IPRIO_MMAXIPRIO) {
4141                 iprio = IPRIO_MMAXIPRIO;
4142             }
4143             if (!iprio) {
4144                 if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) {
4145                     iprio = IPRIO_MMAXIPRIO;
4146                 }
4147             }
4148         } else {
4149             iprio = 1;
4150         }
4151     } else {
4152         iprio = 0;
4153     }
4154 
4155     *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT;
4156     *val |= iprio;
4157 
4158     return RISCV_EXCP_NONE;
4159 }
4160 
4161 static RISCVException read_stopi(CPURISCVState *env, int csrno,
4162                                  target_ulong *val)
4163 {
4164     int irq;
4165     uint8_t iprio;
4166 
4167     if (env->virt_enabled) {
4168         return read_vstopi(env, CSR_VSTOPI, val);
4169     }
4170 
4171     irq = riscv_cpu_sirq_pending(env);
4172     if (irq <= 0 || irq > 63) {
4173         *val = 0;
4174     } else {
4175         iprio = env->siprio[irq];
4176         if (!iprio) {
4177             if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) {
4178                 iprio = IPRIO_MMAXIPRIO;
4179            }
4180         }
4181         *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
4182         *val |= iprio;
4183     }
4184 
4185     return RISCV_EXCP_NONE;
4186 }
4187 
4188 /* Hypervisor Extensions */
4189 static RISCVException read_hstatus(CPURISCVState *env, int csrno,
4190                                    target_ulong *val)
4191 {
4192     *val = env->hstatus;
4193     if (riscv_cpu_mxl(env) != MXL_RV32) {
4194         /* We only support 64-bit VSXL */
4195         *val = set_field(*val, HSTATUS_VSXL, 2);
4196     }
4197     /* We only support little endian */
4198     *val = set_field(*val, HSTATUS_VSBE, 0);
4199     return RISCV_EXCP_NONE;
4200 }
4201 
4202 static RISCVException write_hstatus(CPURISCVState *env, int csrno,
4203                                     target_ulong val)
4204 {
4205     uint64_t mask = (target_ulong)-1;
4206     if (!env_archcpu(env)->cfg.ext_svukte) {
4207         mask &= ~HSTATUS_HUKTE;
4208     }
4209     /* Update PMM field only if the value is valid according to Zjpm v1.0 */
4210     if (!env_archcpu(env)->cfg.ext_ssnpm ||
4211         riscv_cpu_mxl(env) != MXL_RV64 ||
4212         get_field(val, HSTATUS_HUPMM) == PMM_FIELD_RESERVED) {
4213         mask &= ~HSTATUS_HUPMM;
4214     }
4215     env->hstatus = (env->hstatus & ~mask) | (val & mask);
4216 
4217     if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
4218         qemu_log_mask(LOG_UNIMP,
4219                       "QEMU does not support mixed HSXLEN options.");
4220     }
4221     if (get_field(val, HSTATUS_VSBE) != 0) {
4222         qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
4223     }
4224     return RISCV_EXCP_NONE;
4225 }
4226 
4227 static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
4228                                    target_ulong *val)
4229 {
4230     *val = env->hedeleg;
4231     return RISCV_EXCP_NONE;
4232 }
4233 
4234 static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
4235                                     target_ulong val)
4236 {
4237     env->hedeleg = val & vs_delegable_excps;
4238     return RISCV_EXCP_NONE;
4239 }
4240 
4241 static RISCVException read_hedelegh(CPURISCVState *env, int csrno,
4242                                    target_ulong *val)
4243 {
4244     RISCVException ret;
4245     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_P1P13);
4246     if (ret != RISCV_EXCP_NONE) {
4247         return ret;
4248     }
4249 
4250     /* Reserved, now read zero */
4251     *val = 0;
4252     return RISCV_EXCP_NONE;
4253 }
4254 
4255 static RISCVException write_hedelegh(CPURISCVState *env, int csrno,
4256                                     target_ulong val)
4257 {
4258     RISCVException ret;
4259     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_P1P13);
4260     if (ret != RISCV_EXCP_NONE) {
4261         return ret;
4262     }
4263 
4264     /* Reserved, now write ignore */
4265     return RISCV_EXCP_NONE;
4266 }
4267 
4268 static RISCVException rmw_hvien64(CPURISCVState *env, int csrno,
4269                                     uint64_t *ret_val,
4270                                     uint64_t new_val, uint64_t wr_mask)
4271 {
4272     uint64_t mask = wr_mask & hvien_writable_mask;
4273 
4274     if (ret_val) {
4275         *ret_val = env->hvien;
4276     }
4277 
4278     env->hvien = (env->hvien & ~mask) | (new_val & mask);
4279 
4280     return RISCV_EXCP_NONE;
4281 }
4282 
4283 static RISCVException rmw_hvien(CPURISCVState *env, int csrno,
4284                                target_ulong *ret_val,
4285                                target_ulong new_val, target_ulong wr_mask)
4286 {
4287     uint64_t rval;
4288     RISCVException ret;
4289 
4290     ret = rmw_hvien64(env, csrno, &rval, new_val, wr_mask);
4291     if (ret_val) {
4292         *ret_val = rval;
4293     }
4294 
4295     return ret;
4296 }
4297 
4298 static RISCVException rmw_hvienh(CPURISCVState *env, int csrno,
4299                                    target_ulong *ret_val,
4300                                    target_ulong new_val, target_ulong wr_mask)
4301 {
4302     uint64_t rval;
4303     RISCVException ret;
4304 
4305     ret = rmw_hvien64(env, csrno, &rval,
4306         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
4307     if (ret_val) {
4308         *ret_val = rval >> 32;
4309     }
4310 
4311     return ret;
4312 }
4313 
4314 static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
4315                                     uint64_t *ret_val,
4316                                     uint64_t new_val, uint64_t wr_mask)
4317 {
4318     uint64_t mask = wr_mask & vs_delegable_ints;
4319 
4320     if (ret_val) {
4321         *ret_val = env->hideleg & vs_delegable_ints;
4322     }
4323 
4324     env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
4325     return RISCV_EXCP_NONE;
4326 }
4327 
4328 static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
4329                                   target_ulong *ret_val,
4330                                   target_ulong new_val, target_ulong wr_mask)
4331 {
4332     uint64_t rval;
4333     RISCVException ret;
4334 
4335     ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
4336     if (ret_val) {
4337         *ret_val = rval;
4338     }
4339 
4340     return ret;
4341 }
4342 
4343 static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
4344                                    target_ulong *ret_val,
4345                                    target_ulong new_val, target_ulong wr_mask)
4346 {
4347     uint64_t rval;
4348     RISCVException ret;
4349 
4350     ret = rmw_hideleg64(env, csrno, &rval,
4351         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
4352     if (ret_val) {
4353         *ret_val = rval >> 32;
4354     }
4355 
4356     return ret;
4357 }
4358 
4359 /*
4360  * The function is written for two use-cases:
4361  * 1- To access hvip csr as is for HS-mode access.
4362  * 2- To access vsip as a combination of hvip, and mip for vs-mode.
4363  *
4364  * Both report bits 2, 6, 10 and 13:63.
4365  * vsip needs to be read-only zero when both hideleg[i] and
4366  * hvien[i] are zero.
4367  */
4368 static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
4369                                  uint64_t *ret_val,
4370                                  uint64_t new_val, uint64_t wr_mask)
4371 {
4372     RISCVException ret;
4373     uint64_t old_hvip;
4374     uint64_t ret_mip;
4375 
4376     /*
4377      * For bits 10, 6 and 2, vsip[i] is an alias of hip[i]. These bits are
4378      * present in hip, hvip and mip. Where mip[i] is alias of hip[i] and hvip[i]
4379      * is OR'ed in hip[i] to inject virtual interrupts from hypervisor. These
4380      * bits are actually being maintained in mip so we read them from there.
4381      * This way we have a single source of truth and allows for easier
4382      * implementation.
4383      *
4384      * For bits 13:63 we have:
4385      *
4386      * hideleg[i]  hvien[i]
4387      *   0           0      No delegation. vsip[i] readonly zero.
4388      *   0           1      vsip[i] is alias of hvip[i], sip bypassed.
4389      *   1           X      vsip[i] is alias of sip[i], hvip bypassed.
4390      *
4391      *  alias_mask denotes the bits that come from sip (mip here given we
4392      *  maintain all bits there). nalias_mask denotes bits that come from
4393      *  hvip.
4394      */
4395     uint64_t alias_mask = (env->hideleg | ~env->hvien) | VS_MODE_INTERRUPTS;
4396     uint64_t nalias_mask = (~env->hideleg & env->hvien);
4397     uint64_t wr_mask_hvip;
4398     uint64_t wr_mask_mip;
4399 
4400     /*
4401      * Both alias and non-alias mask remain same for vsip except:
4402      *  1- For VS* bits if they are zero in hideleg.
4403      *  2- For 13:63 bits if they are zero in both hideleg and hvien.
4404      */
4405     if (csrno == CSR_VSIP) {
4406         /* zero-out VS* bits that are not delegated to VS mode. */
4407         alias_mask &= (env->hideleg | ~VS_MODE_INTERRUPTS);
4408 
4409         /*
4410          * zero-out 13:63 bits that are zero in both hideleg and hvien.
4411          * nalias_mask mask can not contain any VS* bits so only second
4412          * condition applies on it.
4413          */
4414         nalias_mask &= (env->hideleg | env->hvien);
4415         alias_mask &= (env->hideleg | env->hvien);
4416     }
4417 
4418     wr_mask_hvip = wr_mask & nalias_mask & hvip_writable_mask;
4419     wr_mask_mip = wr_mask & alias_mask & hvip_writable_mask;
4420 
4421     /* Aliased bits, bits 10, 6, 2 need to come from mip. */
4422     ret = rmw_mip64(env, csrno, &ret_mip, new_val, wr_mask_mip);
4423     if (ret != RISCV_EXCP_NONE) {
4424         return ret;
4425     }
4426 
4427     old_hvip = env->hvip;
4428 
4429     if (wr_mask_hvip) {
4430         env->hvip = (env->hvip & ~wr_mask_hvip) | (new_val & wr_mask_hvip);
4431 
4432         /*
4433          * Given hvip is separate source from mip, we need to trigger interrupt
4434          * from here separately. Normally this happen from riscv_cpu_update_mip.
4435          */
4436         riscv_cpu_interrupt(env);
4437     }
4438 
4439     if (ret_val) {
4440         /* Only take VS* bits from mip. */
4441         ret_mip &= alias_mask;
4442 
4443         /* Take in non-delegated 13:63 bits from hvip. */
4444         old_hvip &= nalias_mask;
4445 
4446         *ret_val = ret_mip | old_hvip;
4447     }
4448 
4449     return ret;
4450 }
4451 
4452 static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
4453                                target_ulong *ret_val,
4454                                target_ulong new_val, target_ulong wr_mask)
4455 {
4456     uint64_t rval;
4457     RISCVException ret;
4458 
4459     ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
4460     if (ret_val) {
4461         *ret_val = rval;
4462     }
4463 
4464     return ret;
4465 }
4466 
4467 static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
4468                                 target_ulong *ret_val,
4469                                 target_ulong new_val, target_ulong wr_mask)
4470 {
4471     uint64_t rval;
4472     RISCVException ret;
4473 
4474     ret = rmw_hvip64(env, csrno, &rval,
4475         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
4476     if (ret_val) {
4477         *ret_val = rval >> 32;
4478     }
4479 
4480     return ret;
4481 }
4482 
4483 static RISCVException rmw_hip(CPURISCVState *env, int csrno,
4484                               target_ulong *ret_value,
4485                               target_ulong new_value, target_ulong write_mask)
4486 {
4487     int ret = rmw_mip(env, csrno, ret_value, new_value,
4488                       write_mask & hip_writable_mask);
4489 
4490     if (ret_value) {
4491         *ret_value &= HS_MODE_INTERRUPTS;
4492     }
4493     return ret;
4494 }
4495 
4496 static RISCVException rmw_hie(CPURISCVState *env, int csrno,
4497                               target_ulong *ret_val,
4498                               target_ulong new_val, target_ulong wr_mask)
4499 {
4500     uint64_t rval;
4501     RISCVException ret;
4502 
4503     ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
4504     if (ret_val) {
4505         *ret_val = rval & HS_MODE_INTERRUPTS;
4506     }
4507 
4508     return ret;
4509 }
4510 
4511 static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
4512                                       target_ulong *val)
4513 {
4514     *val = env->hcounteren;
4515     return RISCV_EXCP_NONE;
4516 }
4517 
4518 static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
4519                                        target_ulong val)
4520 {
4521     RISCVCPU *cpu = env_archcpu(env);
4522 
4523     /* WARL register - disable unavailable counters */
4524     env->hcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
4525                              COUNTEREN_IR);
4526     return RISCV_EXCP_NONE;
4527 }
4528 
4529 static RISCVException read_hgeie(CPURISCVState *env, int csrno,
4530                                  target_ulong *val)
4531 {
4532     if (val) {
4533         *val = env->hgeie;
4534     }
4535     return RISCV_EXCP_NONE;
4536 }
4537 
4538 static RISCVException write_hgeie(CPURISCVState *env, int csrno,
4539                                   target_ulong val)
4540 {
4541     /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
4542     val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
4543     env->hgeie = val;
4544     /* Update mip.SGEIP bit */
4545     riscv_cpu_update_mip(env, MIP_SGEIP,
4546                          BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
4547     return RISCV_EXCP_NONE;
4548 }
4549 
4550 static RISCVException read_htval(CPURISCVState *env, int csrno,
4551                                  target_ulong *val)
4552 {
4553     *val = env->htval;
4554     return RISCV_EXCP_NONE;
4555 }
4556 
4557 static RISCVException write_htval(CPURISCVState *env, int csrno,
4558                                   target_ulong val)
4559 {
4560     env->htval = val;
4561     return RISCV_EXCP_NONE;
4562 }
4563 
4564 static RISCVException read_htinst(CPURISCVState *env, int csrno,
4565                                   target_ulong *val)
4566 {
4567     *val = env->htinst;
4568     return RISCV_EXCP_NONE;
4569 }
4570 
4571 static RISCVException write_htinst(CPURISCVState *env, int csrno,
4572                                    target_ulong val)
4573 {
4574     return RISCV_EXCP_NONE;
4575 }
4576 
4577 static RISCVException read_hgeip(CPURISCVState *env, int csrno,
4578                                  target_ulong *val)
4579 {
4580     if (val) {
4581         *val = env->hgeip;
4582     }
4583     return RISCV_EXCP_NONE;
4584 }
4585 
4586 static RISCVException read_hgatp(CPURISCVState *env, int csrno,
4587                                  target_ulong *val)
4588 {
4589     *val = env->hgatp;
4590     return RISCV_EXCP_NONE;
4591 }
4592 
4593 static RISCVException write_hgatp(CPURISCVState *env, int csrno,
4594                                   target_ulong val)
4595 {
4596     env->hgatp = legalize_xatp(env, env->hgatp, val);
4597     return RISCV_EXCP_NONE;
4598 }
4599 
4600 static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
4601                                       target_ulong *val)
4602 {
4603     if (!env->rdtime_fn) {
4604         return RISCV_EXCP_ILLEGAL_INST;
4605     }
4606 
4607     *val = env->htimedelta;
4608     return RISCV_EXCP_NONE;
4609 }
4610 
4611 static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
4612                                        target_ulong val)
4613 {
4614     if (!env->rdtime_fn) {
4615         return RISCV_EXCP_ILLEGAL_INST;
4616     }
4617 
4618     if (riscv_cpu_mxl(env) == MXL_RV32) {
4619         env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
4620     } else {
4621         env->htimedelta = val;
4622     }
4623 
4624     if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
4625         riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
4626                                   env->htimedelta, MIP_VSTIP);
4627     }
4628 
4629     return RISCV_EXCP_NONE;
4630 }
4631 
4632 static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
4633                                        target_ulong *val)
4634 {
4635     if (!env->rdtime_fn) {
4636         return RISCV_EXCP_ILLEGAL_INST;
4637     }
4638 
4639     *val = env->htimedelta >> 32;
4640     return RISCV_EXCP_NONE;
4641 }
4642 
4643 static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
4644                                         target_ulong val)
4645 {
4646     if (!env->rdtime_fn) {
4647         return RISCV_EXCP_ILLEGAL_INST;
4648     }
4649 
4650     env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
4651 
4652     if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
4653         riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
4654                                   env->htimedelta, MIP_VSTIP);
4655     }
4656 
4657     return RISCV_EXCP_NONE;
4658 }
4659 
4660 static RISCVException read_hvictl(CPURISCVState *env, int csrno,
4661                                   target_ulong *val)
4662 {
4663     *val = env->hvictl;
4664     return RISCV_EXCP_NONE;
4665 }
4666 
4667 static RISCVException write_hvictl(CPURISCVState *env, int csrno,
4668                                    target_ulong val)
4669 {
4670     env->hvictl = val & HVICTL_VALID_MASK;
4671     return RISCV_EXCP_NONE;
4672 }
4673 
4674 static RISCVException read_hvipriox(CPURISCVState *env, int first_index,
4675                          uint8_t *iprio, target_ulong *val)
4676 {
4677     int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
4678 
4679     /* First index has to be a multiple of number of irqs per register */
4680     if (first_index % num_irqs) {
4681         return (env->virt_enabled) ?
4682                RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
4683     }
4684 
4685     /* Fill-up return value */
4686     *val = 0;
4687     for (i = 0; i < num_irqs; i++) {
4688         if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
4689             continue;
4690         }
4691         if (rdzero) {
4692             continue;
4693         }
4694         *val |= ((target_ulong)iprio[irq]) << (i * 8);
4695     }
4696 
4697     return RISCV_EXCP_NONE;
4698 }
4699 
4700 static RISCVException write_hvipriox(CPURISCVState *env, int first_index,
4701                           uint8_t *iprio, target_ulong val)
4702 {
4703     int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
4704 
4705     /* First index has to be a multiple of number of irqs per register */
4706     if (first_index % num_irqs) {
4707         return (env->virt_enabled) ?
4708                RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
4709     }
4710 
4711     /* Fill-up priority array */
4712     for (i = 0; i < num_irqs; i++) {
4713         if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
4714             continue;
4715         }
4716         if (rdzero) {
4717             iprio[irq] = 0;
4718         } else {
4719             iprio[irq] = (val >> (i * 8)) & 0xff;
4720         }
4721     }
4722 
4723     return RISCV_EXCP_NONE;
4724 }
4725 
4726 static RISCVException read_hviprio1(CPURISCVState *env, int csrno,
4727                                     target_ulong *val)
4728 {
4729     return read_hvipriox(env, 0, env->hviprio, val);
4730 }
4731 
4732 static RISCVException write_hviprio1(CPURISCVState *env, int csrno,
4733                                      target_ulong val)
4734 {
4735     return write_hvipriox(env, 0, env->hviprio, val);
4736 }
4737 
4738 static RISCVException read_hviprio1h(CPURISCVState *env, int csrno,
4739                                      target_ulong *val)
4740 {
4741     return read_hvipriox(env, 4, env->hviprio, val);
4742 }
4743 
4744 static RISCVException write_hviprio1h(CPURISCVState *env, int csrno,
4745                                       target_ulong val)
4746 {
4747     return write_hvipriox(env, 4, env->hviprio, val);
4748 }
4749 
4750 static RISCVException read_hviprio2(CPURISCVState *env, int csrno,
4751                                     target_ulong *val)
4752 {
4753     return read_hvipriox(env, 8, env->hviprio, val);
4754 }
4755 
4756 static RISCVException write_hviprio2(CPURISCVState *env, int csrno,
4757                                      target_ulong val)
4758 {
4759     return write_hvipriox(env, 8, env->hviprio, val);
4760 }
4761 
4762 static RISCVException read_hviprio2h(CPURISCVState *env, int csrno,
4763                                      target_ulong *val)
4764 {
4765     return read_hvipriox(env, 12, env->hviprio, val);
4766 }
4767 
4768 static RISCVException write_hviprio2h(CPURISCVState *env, int csrno,
4769                                       target_ulong val)
4770 {
4771     return write_hvipriox(env, 12, env->hviprio, val);
4772 }
4773 
4774 /* Virtual CSR Registers */
4775 static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
4776                                     target_ulong *val)
4777 {
4778     *val = env->vsstatus;
4779     return RISCV_EXCP_NONE;
4780 }
4781 
4782 static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
4783                                      target_ulong val)
4784 {
4785     uint64_t mask = (target_ulong)-1;
4786     if ((val & VSSTATUS64_UXL) == 0) {
4787         mask &= ~VSSTATUS64_UXL;
4788     }
4789     if ((env->henvcfg & HENVCFG_DTE)) {
4790         if ((val & SSTATUS_SDT) != 0) {
4791             val &= ~SSTATUS_SIE;
4792         }
4793     } else {
4794         val &= ~SSTATUS_SDT;
4795     }
4796     env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
4797     return RISCV_EXCP_NONE;
4798 }
4799 
4800 static RISCVException read_vstvec(CPURISCVState *env, int csrno,
4801                                   target_ulong *val)
4802 {
4803     *val = env->vstvec;
4804     return RISCV_EXCP_NONE;
4805 }
4806 
4807 static RISCVException write_vstvec(CPURISCVState *env, int csrno,
4808                                    target_ulong val)
4809 {
4810     /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
4811     if ((val & 3) < 2) {
4812         env->vstvec = val;
4813     } else {
4814         qemu_log_mask(LOG_UNIMP, "CSR_VSTVEC: reserved mode not supported\n");
4815     }
4816     return RISCV_EXCP_NONE;
4817 }
4818 
4819 static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
4820                                      target_ulong *val)
4821 {
4822     *val = env->vsscratch;
4823     return RISCV_EXCP_NONE;
4824 }
4825 
4826 static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
4827                                       target_ulong val)
4828 {
4829     env->vsscratch = val;
4830     return RISCV_EXCP_NONE;
4831 }
4832 
4833 static RISCVException read_vsepc(CPURISCVState *env, int csrno,
4834                                  target_ulong *val)
4835 {
4836     *val = env->vsepc;
4837     return RISCV_EXCP_NONE;
4838 }
4839 
4840 static RISCVException write_vsepc(CPURISCVState *env, int csrno,
4841                                   target_ulong val)
4842 {
4843     env->vsepc = val;
4844     return RISCV_EXCP_NONE;
4845 }
4846 
4847 static RISCVException read_vscause(CPURISCVState *env, int csrno,
4848                                    target_ulong *val)
4849 {
4850     *val = env->vscause;
4851     return RISCV_EXCP_NONE;
4852 }
4853 
4854 static RISCVException write_vscause(CPURISCVState *env, int csrno,
4855                                     target_ulong val)
4856 {
4857     env->vscause = val;
4858     return RISCV_EXCP_NONE;
4859 }
4860 
4861 static RISCVException read_vstval(CPURISCVState *env, int csrno,
4862                                   target_ulong *val)
4863 {
4864     *val = env->vstval;
4865     return RISCV_EXCP_NONE;
4866 }
4867 
4868 static RISCVException write_vstval(CPURISCVState *env, int csrno,
4869                                    target_ulong val)
4870 {
4871     env->vstval = val;
4872     return RISCV_EXCP_NONE;
4873 }
4874 
4875 static RISCVException read_vsatp(CPURISCVState *env, int csrno,
4876                                  target_ulong *val)
4877 {
4878     *val = env->vsatp;
4879     return RISCV_EXCP_NONE;
4880 }
4881 
4882 static RISCVException write_vsatp(CPURISCVState *env, int csrno,
4883                                   target_ulong val)
4884 {
4885     env->vsatp = legalize_xatp(env, env->vsatp, val);
4886     return RISCV_EXCP_NONE;
4887 }
4888 
4889 static RISCVException read_mtval2(CPURISCVState *env, int csrno,
4890                                   target_ulong *val)
4891 {
4892     *val = env->mtval2;
4893     return RISCV_EXCP_NONE;
4894 }
4895 
4896 static RISCVException write_mtval2(CPURISCVState *env, int csrno,
4897                                    target_ulong val)
4898 {
4899     env->mtval2 = val;
4900     return RISCV_EXCP_NONE;
4901 }
4902 
4903 static RISCVException read_mtinst(CPURISCVState *env, int csrno,
4904                                   target_ulong *val)
4905 {
4906     *val = env->mtinst;
4907     return RISCV_EXCP_NONE;
4908 }
4909 
4910 static RISCVException write_mtinst(CPURISCVState *env, int csrno,
4911                                    target_ulong val)
4912 {
4913     env->mtinst = val;
4914     return RISCV_EXCP_NONE;
4915 }
4916 
4917 /* Physical Memory Protection */
4918 static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
4919                                    target_ulong *val)
4920 {
4921     *val = mseccfg_csr_read(env);
4922     return RISCV_EXCP_NONE;
4923 }
4924 
4925 static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
4926                                     target_ulong val)
4927 {
4928     mseccfg_csr_write(env, val);
4929     return RISCV_EXCP_NONE;
4930 }
4931 
4932 static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
4933                                   target_ulong *val)
4934 {
4935     uint32_t reg_index = csrno - CSR_PMPCFG0;
4936 
4937     *val = pmpcfg_csr_read(env, reg_index);
4938     return RISCV_EXCP_NONE;
4939 }
4940 
4941 static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
4942                                    target_ulong val)
4943 {
4944     uint32_t reg_index = csrno - CSR_PMPCFG0;
4945 
4946     pmpcfg_csr_write(env, reg_index, val);
4947     return RISCV_EXCP_NONE;
4948 }
4949 
4950 static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
4951                                    target_ulong *val)
4952 {
4953     *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
4954     return RISCV_EXCP_NONE;
4955 }
4956 
4957 static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
4958                                     target_ulong val)
4959 {
4960     pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
4961     return RISCV_EXCP_NONE;
4962 }
4963 
4964 static RISCVException read_tselect(CPURISCVState *env, int csrno,
4965                                    target_ulong *val)
4966 {
4967     *val = tselect_csr_read(env);
4968     return RISCV_EXCP_NONE;
4969 }
4970 
4971 static RISCVException write_tselect(CPURISCVState *env, int csrno,
4972                                     target_ulong val)
4973 {
4974     tselect_csr_write(env, val);
4975     return RISCV_EXCP_NONE;
4976 }
4977 
4978 static RISCVException read_tdata(CPURISCVState *env, int csrno,
4979                                  target_ulong *val)
4980 {
4981     /* return 0 in tdata1 to end the trigger enumeration */
4982     if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
4983         *val = 0;
4984         return RISCV_EXCP_NONE;
4985     }
4986 
4987     if (!tdata_available(env, csrno - CSR_TDATA1)) {
4988         return RISCV_EXCP_ILLEGAL_INST;
4989     }
4990 
4991     *val = tdata_csr_read(env, csrno - CSR_TDATA1);
4992     return RISCV_EXCP_NONE;
4993 }
4994 
4995 static RISCVException write_tdata(CPURISCVState *env, int csrno,
4996                                   target_ulong val)
4997 {
4998     if (!tdata_available(env, csrno - CSR_TDATA1)) {
4999         return RISCV_EXCP_ILLEGAL_INST;
5000     }
5001 
5002     tdata_csr_write(env, csrno - CSR_TDATA1, val);
5003     return RISCV_EXCP_NONE;
5004 }
5005 
5006 static RISCVException read_tinfo(CPURISCVState *env, int csrno,
5007                                  target_ulong *val)
5008 {
5009     *val = tinfo_csr_read(env);
5010     return RISCV_EXCP_NONE;
5011 }
5012 
5013 static RISCVException read_mcontext(CPURISCVState *env, int csrno,
5014                                     target_ulong *val)
5015 {
5016     *val = env->mcontext;
5017     return RISCV_EXCP_NONE;
5018 }
5019 
5020 static RISCVException write_mcontext(CPURISCVState *env, int csrno,
5021                                      target_ulong val)
5022 {
5023     bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
5024     int32_t mask;
5025 
5026     if (riscv_has_ext(env, RVH)) {
5027         /* Spec suggest 7-bit for RV32 and 14-bit for RV64 w/ H extension */
5028         mask = rv32 ? MCONTEXT32_HCONTEXT : MCONTEXT64_HCONTEXT;
5029     } else {
5030         /* Spec suggest 6-bit for RV32 and 13-bit for RV64 w/o H extension */
5031         mask = rv32 ? MCONTEXT32 : MCONTEXT64;
5032     }
5033 
5034     env->mcontext = val & mask;
5035     return RISCV_EXCP_NONE;
5036 }
5037 
5038 static RISCVException read_mnscratch(CPURISCVState *env, int csrno,
5039                                      target_ulong *val)
5040 {
5041     *val = env->mnscratch;
5042     return RISCV_EXCP_NONE;
5043 }
5044 
5045 static int write_mnscratch(CPURISCVState *env, int csrno, target_ulong val)
5046 {
5047     env->mnscratch = val;
5048     return RISCV_EXCP_NONE;
5049 }
5050 
5051 static int read_mnepc(CPURISCVState *env, int csrno, target_ulong *val)
5052 {
5053     *val = env->mnepc;
5054     return RISCV_EXCP_NONE;
5055 }
5056 
5057 static int write_mnepc(CPURISCVState *env, int csrno, target_ulong val)
5058 {
5059     env->mnepc = val;
5060     return RISCV_EXCP_NONE;
5061 }
5062 
5063 static int read_mncause(CPURISCVState *env, int csrno, target_ulong *val)
5064 {
5065     *val = env->mncause;
5066     return RISCV_EXCP_NONE;
5067 }
5068 
5069 static int write_mncause(CPURISCVState *env, int csrno, target_ulong val)
5070 {
5071     env->mncause = val;
5072     return RISCV_EXCP_NONE;
5073 }
5074 
5075 static int read_mnstatus(CPURISCVState *env, int csrno, target_ulong *val)
5076 {
5077     *val = env->mnstatus;
5078     return RISCV_EXCP_NONE;
5079 }
5080 
5081 static int write_mnstatus(CPURISCVState *env, int csrno, target_ulong val)
5082 {
5083     target_ulong mask = (MNSTATUS_NMIE | MNSTATUS_MNPP);
5084 
5085     if (riscv_has_ext(env, RVH)) {
5086         /* Flush tlb on mnstatus fields that affect VM. */
5087         if ((val ^ env->mnstatus) & MNSTATUS_MNPV) {
5088             tlb_flush(env_cpu(env));
5089         }
5090 
5091         mask |= MNSTATUS_MNPV;
5092     }
5093 
5094     /* mnstatus.mnie can only be cleared by hardware. */
5095     env->mnstatus = (env->mnstatus & MNSTATUS_NMIE) | (val & mask);
5096     return RISCV_EXCP_NONE;
5097 }
5098 
5099 #endif
5100 
5101 /* Crypto Extension */
5102 target_ulong riscv_new_csr_seed(target_ulong new_value,
5103                                 target_ulong write_mask)
5104 {
5105     uint16_t random_v;
5106     Error *random_e = NULL;
5107     int random_r;
5108     target_ulong rval;
5109 
5110     random_r = qemu_guest_getrandom(&random_v, 2, &random_e);
5111     if (unlikely(random_r < 0)) {
5112         /*
5113          * Failed, for unknown reasons in the crypto subsystem.
5114          * The best we can do is log the reason and return a
5115          * failure indication to the guest.  There is no reason
5116          * we know to expect the failure to be transitory, so
5117          * indicate DEAD to avoid having the guest spin on WAIT.
5118          */
5119         qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
5120                       __func__, error_get_pretty(random_e));
5121         error_free(random_e);
5122         rval = SEED_OPST_DEAD;
5123     } else {
5124         rval = random_v | SEED_OPST_ES16;
5125     }
5126 
5127     return rval;
5128 }
5129 
5130 static RISCVException rmw_seed(CPURISCVState *env, int csrno,
5131                                target_ulong *ret_value,
5132                                target_ulong new_value,
5133                                target_ulong write_mask)
5134 {
5135     target_ulong rval;
5136 
5137     rval = riscv_new_csr_seed(new_value, write_mask);
5138 
5139     if (ret_value) {
5140         *ret_value = rval;
5141     }
5142 
5143     return RISCV_EXCP_NONE;
5144 }
5145 
5146 /*
5147  * riscv_csrrw - read and/or update control and status register
5148  *
5149  * csrr   <->  riscv_csrrw(env, csrno, ret_value, 0, 0);
5150  * csrrw  <->  riscv_csrrw(env, csrno, ret_value, value, -1);
5151  * csrrs  <->  riscv_csrrw(env, csrno, ret_value, -1, value);
5152  * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
5153  */
5154 
5155 static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
5156                                                int csrno,
5157                                                bool write)
5158 {
5159     /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
5160     bool read_only = get_field(csrno, 0xC00) == 3;
5161     int csr_min_priv = csr_ops[csrno].min_priv_ver;
5162 
5163     /* ensure the CSR extension is enabled */
5164     if (!riscv_cpu_cfg(env)->ext_zicsr) {
5165         return RISCV_EXCP_ILLEGAL_INST;
5166     }
5167 
5168     /* ensure CSR is implemented by checking predicate */
5169     if (!csr_ops[csrno].predicate) {
5170         return RISCV_EXCP_ILLEGAL_INST;
5171     }
5172 
5173     /* privileged spec version check */
5174     if (env->priv_ver < csr_min_priv) {
5175         return RISCV_EXCP_ILLEGAL_INST;
5176     }
5177 
5178     /* read / write check */
5179     if (write && read_only) {
5180         return RISCV_EXCP_ILLEGAL_INST;
5181     }
5182 
5183     /*
5184      * The predicate() not only does existence check but also does some
5185      * access control check which triggers for example virtual instruction
5186      * exception in some cases. When writing read-only CSRs in those cases
5187      * illegal instruction exception should be triggered instead of virtual
5188      * instruction exception. Hence this comes after the read / write check.
5189      */
5190     RISCVException ret = csr_ops[csrno].predicate(env, csrno);
5191     if (ret != RISCV_EXCP_NONE) {
5192         return ret;
5193     }
5194 
5195 #if !defined(CONFIG_USER_ONLY)
5196     int csr_priv, effective_priv = env->priv;
5197 
5198     if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
5199         !env->virt_enabled) {
5200         /*
5201          * We are in HS mode. Add 1 to the effective privilege level to
5202          * allow us to access the Hypervisor CSRs.
5203          */
5204         effective_priv++;
5205     }
5206 
5207     csr_priv = get_field(csrno, 0x300);
5208     if (!env->debugger && (effective_priv < csr_priv)) {
5209         if (csr_priv == (PRV_S + 1) && env->virt_enabled) {
5210             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
5211         }
5212         return RISCV_EXCP_ILLEGAL_INST;
5213     }
5214 #endif
5215     return RISCV_EXCP_NONE;
5216 }
5217 
5218 static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
5219                                        target_ulong *ret_value,
5220                                        target_ulong new_value,
5221                                        target_ulong write_mask)
5222 {
5223     RISCVException ret;
5224     target_ulong old_value = 0;
5225 
5226     /* execute combined read/write operation if it exists */
5227     if (csr_ops[csrno].op) {
5228         return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
5229     }
5230 
5231     /*
5232      * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
5233      * and we can't throw side effects caused by CSR reads.
5234      */
5235     if (ret_value) {
5236         /* if no accessor exists then return failure */
5237         if (!csr_ops[csrno].read) {
5238             return RISCV_EXCP_ILLEGAL_INST;
5239         }
5240         /* read old value */
5241         ret = csr_ops[csrno].read(env, csrno, &old_value);
5242         if (ret != RISCV_EXCP_NONE) {
5243             return ret;
5244         }
5245     }
5246 
5247     /* write value if writable and write mask set, otherwise drop writes */
5248     if (write_mask) {
5249         new_value = (old_value & ~write_mask) | (new_value & write_mask);
5250         if (csr_ops[csrno].write) {
5251             ret = csr_ops[csrno].write(env, csrno, new_value);
5252             if (ret != RISCV_EXCP_NONE) {
5253                 return ret;
5254             }
5255         }
5256     }
5257 
5258     /* return old value */
5259     if (ret_value) {
5260         *ret_value = old_value;
5261     }
5262 
5263     return RISCV_EXCP_NONE;
5264 }
5265 
5266 RISCVException riscv_csrr(CPURISCVState *env, int csrno,
5267                            target_ulong *ret_value)
5268 {
5269     RISCVException ret = riscv_csrrw_check(env, csrno, false);
5270     if (ret != RISCV_EXCP_NONE) {
5271         return ret;
5272     }
5273 
5274     return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
5275 }
5276 
5277 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
5278                            target_ulong *ret_value,
5279                            target_ulong new_value, target_ulong write_mask)
5280 {
5281     RISCVException ret = riscv_csrrw_check(env, csrno, true);
5282     if (ret != RISCV_EXCP_NONE) {
5283         return ret;
5284     }
5285 
5286     return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
5287 }
5288 
5289 static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
5290                                         Int128 *ret_value,
5291                                         Int128 new_value,
5292                                         Int128 write_mask)
5293 {
5294     RISCVException ret;
5295     Int128 old_value;
5296 
5297     /* read old value */
5298     ret = csr_ops[csrno].read128(env, csrno, &old_value);
5299     if (ret != RISCV_EXCP_NONE) {
5300         return ret;
5301     }
5302 
5303     /* write value if writable and write mask set, otherwise drop writes */
5304     if (int128_nz(write_mask)) {
5305         new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
5306                               int128_and(new_value, write_mask));
5307         if (csr_ops[csrno].write128) {
5308             ret = csr_ops[csrno].write128(env, csrno, new_value);
5309             if (ret != RISCV_EXCP_NONE) {
5310                 return ret;
5311             }
5312         } else if (csr_ops[csrno].write) {
5313             /* avoids having to write wrappers for all registers */
5314             ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
5315             if (ret != RISCV_EXCP_NONE) {
5316                 return ret;
5317             }
5318         }
5319     }
5320 
5321     /* return old value */
5322     if (ret_value) {
5323         *ret_value = old_value;
5324     }
5325 
5326     return RISCV_EXCP_NONE;
5327 }
5328 
5329 RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
5330                                Int128 *ret_value)
5331 {
5332     RISCVException ret;
5333 
5334     ret = riscv_csrrw_check(env, csrno, false);
5335     if (ret != RISCV_EXCP_NONE) {
5336         return ret;
5337     }
5338 
5339     if (csr_ops[csrno].read128) {
5340         return riscv_csrrw_do128(env, csrno, ret_value,
5341                                  int128_zero(), int128_zero());
5342     }
5343 
5344     /*
5345      * Fall back to 64-bit version for now, if the 128-bit alternative isn't
5346      * at all defined.
5347      * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
5348      * significant), for those, this fallback is correctly handling the
5349      * accesses
5350      */
5351     target_ulong old_value;
5352     ret = riscv_csrrw_do64(env, csrno, &old_value,
5353                            (target_ulong)0,
5354                            (target_ulong)0);
5355     if (ret == RISCV_EXCP_NONE && ret_value) {
5356         *ret_value = int128_make64(old_value);
5357     }
5358     return ret;
5359 }
5360 
5361 RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
5362                                 Int128 *ret_value,
5363                                 Int128 new_value, Int128 write_mask)
5364 {
5365     RISCVException ret;
5366 
5367     ret = riscv_csrrw_check(env, csrno, true);
5368     if (ret != RISCV_EXCP_NONE) {
5369         return ret;
5370     }
5371 
5372     if (csr_ops[csrno].read128) {
5373         return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
5374     }
5375 
5376     /*
5377      * Fall back to 64-bit version for now, if the 128-bit alternative isn't
5378      * at all defined.
5379      * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
5380      * significant), for those, this fallback is correctly handling the
5381      * accesses
5382      */
5383     target_ulong old_value;
5384     ret = riscv_csrrw_do64(env, csrno, &old_value,
5385                            int128_getlo(new_value),
5386                            int128_getlo(write_mask));
5387     if (ret == RISCV_EXCP_NONE && ret_value) {
5388         *ret_value = int128_make64(old_value);
5389     }
5390     return ret;
5391 }
5392 
5393 /*
5394  * Debugger support.  If not in user mode, set env->debugger before the
5395  * riscv_csrrw call and clear it after the call.
5396  */
5397 RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
5398                                  target_ulong *ret_value,
5399                                  target_ulong new_value,
5400                                  target_ulong write_mask)
5401 {
5402     RISCVException ret;
5403 #if !defined(CONFIG_USER_ONLY)
5404     env->debugger = true;
5405 #endif
5406     if (!write_mask) {
5407         ret = riscv_csrr(env, csrno, ret_value);
5408     } else {
5409         ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
5410     }
5411 #if !defined(CONFIG_USER_ONLY)
5412     env->debugger = false;
5413 #endif
5414     return ret;
5415 }
5416 
5417 static RISCVException read_jvt(CPURISCVState *env, int csrno,
5418                                target_ulong *val)
5419 {
5420     *val = env->jvt;
5421     return RISCV_EXCP_NONE;
5422 }
5423 
5424 static RISCVException write_jvt(CPURISCVState *env, int csrno,
5425                                 target_ulong val)
5426 {
5427     env->jvt = val;
5428     return RISCV_EXCP_NONE;
5429 }
5430 
5431 /*
5432  * Control and Status Register function table
5433  * riscv_csr_operations::predicate() must be provided for an implemented CSR
5434  */
5435 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
5436     /* User Floating-Point CSRs */
5437     [CSR_FFLAGS]   = { "fflags",   fs,     read_fflags,  write_fflags },
5438     [CSR_FRM]      = { "frm",      fs,     read_frm,     write_frm    },
5439     [CSR_FCSR]     = { "fcsr",     fs,     read_fcsr,    write_fcsr   },
5440     /* Vector CSRs */
5441     [CSR_VSTART]   = { "vstart",   vs,     read_vstart,  write_vstart },
5442     [CSR_VXSAT]    = { "vxsat",    vs,     read_vxsat,   write_vxsat  },
5443     [CSR_VXRM]     = { "vxrm",     vs,     read_vxrm,    write_vxrm   },
5444     [CSR_VCSR]     = { "vcsr",     vs,     read_vcsr,    write_vcsr   },
5445     [CSR_VL]       = { "vl",       vs,     read_vl                    },
5446     [CSR_VTYPE]    = { "vtype",    vs,     read_vtype                 },
5447     [CSR_VLENB]    = { "vlenb",    vs,     read_vlenb                 },
5448     /* User Timers and Counters */
5449     [CSR_CYCLE]    = { "cycle",    ctr,    read_hpmcounter  },
5450     [CSR_INSTRET]  = { "instret",  ctr,    read_hpmcounter  },
5451     [CSR_CYCLEH]   = { "cycleh",   ctr32,  read_hpmcounterh },
5452     [CSR_INSTRETH] = { "instreth", ctr32,  read_hpmcounterh },
5453 
5454     /*
5455      * In privileged mode, the monitor will have to emulate TIME CSRs only if
5456      * rdtime callback is not provided by machine/platform emulation.
5457      */
5458     [CSR_TIME]  = { "time",  ctr,   read_time  },
5459     [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
5460 
5461     /* Crypto Extension */
5462     [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
5463 
5464     /* Zcmt Extension */
5465     [CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
5466 
5467     /* zicfiss Extension, shadow stack register */
5468     [CSR_SSP]  = { "ssp", cfi_ss, read_ssp, write_ssp },
5469 
5470 #if !defined(CONFIG_USER_ONLY)
5471     /* Machine Timers and Counters */
5472     [CSR_MCYCLE]    = { "mcycle",    any,   read_hpmcounter,
5473                         write_mhpmcounter                    },
5474     [CSR_MINSTRET]  = { "minstret",  any,   read_hpmcounter,
5475                         write_mhpmcounter                    },
5476     [CSR_MCYCLEH]   = { "mcycleh",   any32, read_hpmcounterh,
5477                         write_mhpmcounterh                   },
5478     [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh,
5479                         write_mhpmcounterh                   },
5480 
5481     /* Machine Information Registers */
5482     [CSR_MVENDORID] = { "mvendorid", any,   read_mvendorid },
5483     [CSR_MARCHID]   = { "marchid",   any,   read_marchid   },
5484     [CSR_MIMPID]    = { "mimpid",    any,   read_mimpid    },
5485     [CSR_MHARTID]   = { "mhartid",   any,   read_mhartid   },
5486 
5487     [CSR_MCONFIGPTR]  = { "mconfigptr", any,   read_zero,
5488                           .min_priv_ver = PRIV_VERSION_1_12_0 },
5489     /* Machine Trap Setup */
5490     [CSR_MSTATUS]     = { "mstatus",    any,   read_mstatus, write_mstatus,
5491                           NULL,                read_mstatus_i128           },
5492     [CSR_MISA]        = { "misa",       any,   read_misa,    write_misa,
5493                           NULL,                read_misa_i128              },
5494     [CSR_MIDELEG]     = { "mideleg",    any,   NULL, NULL,   rmw_mideleg   },
5495     [CSR_MEDELEG]     = { "medeleg",    any,   read_medeleg, write_medeleg },
5496     [CSR_MIE]         = { "mie",        any,   NULL, NULL,   rmw_mie       },
5497     [CSR_MTVEC]       = { "mtvec",      any,   read_mtvec,   write_mtvec   },
5498     [CSR_MCOUNTEREN]  = { "mcounteren", umode, read_mcounteren,
5499                           write_mcounteren                                 },
5500 
5501     [CSR_MSTATUSH]    = { "mstatush",   any32, read_mstatush,
5502                           write_mstatush                                   },
5503     [CSR_MEDELEGH]    = { "medelegh",   any32, read_zero, write_ignore,
5504                           .min_priv_ver = PRIV_VERSION_1_13_0              },
5505     [CSR_HEDELEGH]    = { "hedelegh",   hmode32, read_hedelegh, write_hedelegh,
5506                           .min_priv_ver = PRIV_VERSION_1_13_0              },
5507 
5508     /* Machine Trap Handling */
5509     [CSR_MSCRATCH] = { "mscratch", any,  read_mscratch, write_mscratch,
5510                        NULL, read_mscratch_i128, write_mscratch_i128   },
5511     [CSR_MEPC]     = { "mepc",     any,  read_mepc,     write_mepc     },
5512     [CSR_MCAUSE]   = { "mcause",   any,  read_mcause,   write_mcause   },
5513     [CSR_MTVAL]    = { "mtval",    any,  read_mtval,    write_mtval    },
5514     [CSR_MIP]      = { "mip",      any,  NULL,    NULL, rmw_mip        },
5515 
5516     /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
5517     [CSR_MISELECT] = { "miselect", csrind_or_aia_any,   NULL, NULL,
5518                        rmw_xiselect                                    },
5519     [CSR_MIREG]    = { "mireg",    csrind_or_aia_any,   NULL, NULL,
5520                        rmw_xireg                                       },
5521 
5522     /* Machine Indirect Register Alias */
5523     [CSR_MIREG2]   = { "mireg2", csrind_any, NULL, NULL, rmw_xiregi,
5524                        .min_priv_ver = PRIV_VERSION_1_12_0          },
5525     [CSR_MIREG3]   = { "mireg3", csrind_any, NULL, NULL, rmw_xiregi,
5526                        .min_priv_ver = PRIV_VERSION_1_12_0          },
5527     [CSR_MIREG4]   = { "mireg4", csrind_any, NULL, NULL, rmw_xiregi,
5528                        .min_priv_ver = PRIV_VERSION_1_12_0          },
5529     [CSR_MIREG5]   = { "mireg5", csrind_any, NULL, NULL, rmw_xiregi,
5530                        .min_priv_ver = PRIV_VERSION_1_12_0          },
5531     [CSR_MIREG6]   = { "mireg6", csrind_any, NULL, NULL, rmw_xiregi,
5532                        .min_priv_ver = PRIV_VERSION_1_12_0          },
5533 
5534     /* Machine-Level Interrupts (AIA) */
5535     [CSR_MTOPEI]   = { "mtopei",   aia_any, NULL, NULL, rmw_xtopei },
5536     [CSR_MTOPI]    = { "mtopi",    aia_any, read_mtopi },
5537 
5538     /* Virtual Interrupts for Supervisor Level (AIA) */
5539     [CSR_MVIEN]    = { "mvien",    aia_any, NULL, NULL, rmw_mvien   },
5540     [CSR_MVIP]     = { "mvip",     aia_any, NULL, NULL, rmw_mvip    },
5541 
5542     /* Machine-Level High-Half CSRs (AIA) */
5543     [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
5544     [CSR_MIEH]     = { "mieh",     aia_any32, NULL, NULL, rmw_mieh     },
5545     [CSR_MVIENH]   = { "mvienh",   aia_any32, NULL, NULL, rmw_mvienh   },
5546     [CSR_MVIPH]    = { "mviph",    aia_any32, NULL, NULL, rmw_mviph    },
5547     [CSR_MIPH]     = { "miph",     aia_any32, NULL, NULL, rmw_miph     },
5548 
5549     /* Execution environment configuration */
5550     [CSR_MENVCFG]  = { "menvcfg",  umode, read_menvcfg,  write_menvcfg,
5551                        .min_priv_ver = PRIV_VERSION_1_12_0              },
5552     [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh,
5553                        .min_priv_ver = PRIV_VERSION_1_12_0              },
5554     [CSR_SENVCFG]  = { "senvcfg",  smode, read_senvcfg,  write_senvcfg,
5555                        .min_priv_ver = PRIV_VERSION_1_12_0              },
5556     [CSR_HENVCFG]  = { "henvcfg",  hmode, read_henvcfg, write_henvcfg,
5557                        .min_priv_ver = PRIV_VERSION_1_12_0              },
5558     [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
5559                        .min_priv_ver = PRIV_VERSION_1_12_0              },
5560 
5561     /* Smstateen extension CSRs */
5562     [CSR_MSTATEEN0] = { "mstateen0", mstateen, read_mstateen, write_mstateen0,
5563                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5564     [CSR_MSTATEEN0H] = { "mstateen0h", mstateen, read_mstateenh,
5565                           write_mstateen0h,
5566                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5567     [CSR_MSTATEEN1] = { "mstateen1", mstateen, read_mstateen,
5568                         write_mstateen_1_3,
5569                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5570     [CSR_MSTATEEN1H] = { "mstateen1h", mstateen, read_mstateenh,
5571                          write_mstateenh_1_3,
5572                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5573     [CSR_MSTATEEN2] = { "mstateen2", mstateen, read_mstateen,
5574                         write_mstateen_1_3,
5575                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5576     [CSR_MSTATEEN2H] = { "mstateen2h", mstateen, read_mstateenh,
5577                          write_mstateenh_1_3,
5578                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5579     [CSR_MSTATEEN3] = { "mstateen3", mstateen, read_mstateen,
5580                         write_mstateen_1_3,
5581                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5582     [CSR_MSTATEEN3H] = { "mstateen3h", mstateen, read_mstateenh,
5583                          write_mstateenh_1_3,
5584                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5585     [CSR_HSTATEEN0] = { "hstateen0", hstateen, read_hstateen, write_hstateen0,
5586                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5587     [CSR_HSTATEEN0H] = { "hstateen0h", hstateenh, read_hstateenh,
5588                          write_hstateen0h,
5589                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5590     [CSR_HSTATEEN1] = { "hstateen1", hstateen, read_hstateen,
5591                         write_hstateen_1_3,
5592                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5593     [CSR_HSTATEEN1H] = { "hstateen1h", hstateenh, read_hstateenh,
5594                          write_hstateenh_1_3,
5595                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5596     [CSR_HSTATEEN2] = { "hstateen2", hstateen, read_hstateen,
5597                         write_hstateen_1_3,
5598                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5599     [CSR_HSTATEEN2H] = { "hstateen2h", hstateenh, read_hstateenh,
5600                          write_hstateenh_1_3,
5601                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5602     [CSR_HSTATEEN3] = { "hstateen3", hstateen, read_hstateen,
5603                         write_hstateen_1_3,
5604                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5605     [CSR_HSTATEEN3H] = { "hstateen3h", hstateenh, read_hstateenh,
5606                          write_hstateenh_1_3,
5607                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5608     [CSR_SSTATEEN0] = { "sstateen0", sstateen, read_sstateen, write_sstateen0,
5609                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5610     [CSR_SSTATEEN1] = { "sstateen1", sstateen, read_sstateen,
5611                         write_sstateen_1_3,
5612                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5613     [CSR_SSTATEEN2] = { "sstateen2", sstateen, read_sstateen,
5614                         write_sstateen_1_3,
5615                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5616     [CSR_SSTATEEN3] = { "sstateen3", sstateen, read_sstateen,
5617                         write_sstateen_1_3,
5618                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5619 
5620     /* RNMI */
5621     [CSR_MNSCRATCH] = { "mnscratch", rnmi, read_mnscratch, write_mnscratch,
5622                         .min_priv_ver = PRIV_VERSION_1_12_0               },
5623     [CSR_MNEPC]     = { "mnepc",     rnmi, read_mnepc,     write_mnepc,
5624                         .min_priv_ver = PRIV_VERSION_1_12_0               },
5625     [CSR_MNCAUSE]   = { "mncause",   rnmi, read_mncause,   write_mncause,
5626                         .min_priv_ver = PRIV_VERSION_1_12_0               },
5627     [CSR_MNSTATUS]  = { "mnstatus",  rnmi, read_mnstatus,  write_mnstatus,
5628                         .min_priv_ver = PRIV_VERSION_1_12_0               },
5629 
5630     /* Supervisor Counter Delegation */
5631     [CSR_SCOUNTINHIBIT] = {"scountinhibit", scountinhibit_pred,
5632                             read_scountinhibit, write_scountinhibit,
5633                            .min_priv_ver = PRIV_VERSION_1_12_0 },
5634 
5635     /* Supervisor Trap Setup */
5636     [CSR_SSTATUS]    = { "sstatus",    smode, read_sstatus,    write_sstatus,
5637                          NULL,                read_sstatus_i128              },
5638     [CSR_SIE]        = { "sie",        smode, NULL,   NULL,    rmw_sie       },
5639     [CSR_STVEC]      = { "stvec",      smode, read_stvec,      write_stvec   },
5640     [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren,
5641                          write_scounteren                                    },
5642 
5643     /* Supervisor Trap Handling */
5644     [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch,
5645                        NULL, read_sscratch_i128, write_sscratch_i128    },
5646     [CSR_SEPC]     = { "sepc",     smode, read_sepc,     write_sepc     },
5647     [CSR_SCAUSE]   = { "scause",   smode, read_scause,   write_scause   },
5648     [CSR_STVAL]    = { "stval",    smode, read_stval,    write_stval    },
5649     [CSR_SIP]      = { "sip",      smode, NULL,    NULL, rmw_sip        },
5650     [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp,
5651                        .min_priv_ver = PRIV_VERSION_1_12_0 },
5652     [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
5653                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5654     [CSR_VSTIMECMP] = { "vstimecmp", sstc, read_vstimecmp,
5655                         write_vstimecmp,
5656                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5657     [CSR_VSTIMECMPH] = { "vstimecmph", sstc_32, read_vstimecmph,
5658                          write_vstimecmph,
5659                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5660 
5661     /* Supervisor Protection and Translation */
5662     [CSR_SATP]     = { "satp",     satp, read_satp,     write_satp     },
5663 
5664     /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
5665     [CSR_SISELECT]   = { "siselect",   csrind_or_aia_smode, NULL, NULL,
5666                          rmw_xiselect                                       },
5667     [CSR_SIREG]      = { "sireg",      csrind_or_aia_smode, NULL, NULL,
5668                          rmw_xireg                                          },
5669 
5670     /* Supervisor Indirect Register Alias */
5671     [CSR_SIREG2]      = { "sireg2", csrind_smode, NULL, NULL, rmw_xiregi,
5672                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5673     [CSR_SIREG3]      = { "sireg3", csrind_smode, NULL, NULL, rmw_xiregi,
5674                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5675     [CSR_SIREG4]      = { "sireg4", csrind_smode, NULL, NULL, rmw_xiregi,
5676                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5677     [CSR_SIREG5]      = { "sireg5", csrind_smode, NULL, NULL, rmw_xiregi,
5678                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5679     [CSR_SIREG6]      = { "sireg6", csrind_smode, NULL, NULL, rmw_xiregi,
5680                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5681 
5682     /* Supervisor-Level Interrupts (AIA) */
5683     [CSR_STOPEI]     = { "stopei",     aia_smode, NULL, NULL, rmw_xtopei },
5684     [CSR_STOPI]      = { "stopi",      aia_smode, read_stopi },
5685 
5686     /* Supervisor-Level High-Half CSRs (AIA) */
5687     [CSR_SIEH]       = { "sieh",   aia_smode32, NULL, NULL, rmw_sieh },
5688     [CSR_SIPH]       = { "siph",   aia_smode32, NULL, NULL, rmw_siph },
5689 
5690     [CSR_HSTATUS]     = { "hstatus",     hmode,   read_hstatus, write_hstatus,
5691                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5692     [CSR_HEDELEG]     = { "hedeleg",     hmode,   read_hedeleg, write_hedeleg,
5693                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5694     [CSR_HIDELEG]     = { "hideleg",     hmode,   NULL,   NULL, rmw_hideleg,
5695                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5696     [CSR_HVIP]        = { "hvip",        hmode,   NULL,   NULL, rmw_hvip,
5697                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5698     [CSR_HIP]         = { "hip",         hmode,   NULL,   NULL, rmw_hip,
5699                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5700     [CSR_HIE]         = { "hie",         hmode,   NULL,   NULL, rmw_hie,
5701                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5702     [CSR_HCOUNTEREN]  = { "hcounteren",  hmode,   read_hcounteren,
5703                           write_hcounteren,
5704                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5705     [CSR_HGEIE]       = { "hgeie",       hmode,   read_hgeie,   write_hgeie,
5706                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5707     [CSR_HTVAL]       = { "htval",       hmode,   read_htval,   write_htval,
5708                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5709     [CSR_HTINST]      = { "htinst",      hmode,   read_htinst,  write_htinst,
5710                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5711     [CSR_HGEIP]       = { "hgeip",       hmode,   read_hgeip,
5712                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5713     [CSR_HGATP]       = { "hgatp",       hgatp,   read_hgatp,   write_hgatp,
5714                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5715     [CSR_HTIMEDELTA]  = { "htimedelta",  hmode,   read_htimedelta,
5716                           write_htimedelta,
5717                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5718     [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah,
5719                           write_htimedeltah,
5720                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5721 
5722     [CSR_VSSTATUS]    = { "vsstatus",    hmode,   read_vsstatus,
5723                           write_vsstatus,
5724                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5725     [CSR_VSIP]        = { "vsip",        hmode,   NULL,    NULL, rmw_vsip,
5726                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5727     [CSR_VSIE]        = { "vsie",        hmode,   NULL,    NULL, rmw_vsie ,
5728                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5729     [CSR_VSTVEC]      = { "vstvec",      hmode,   read_vstvec,   write_vstvec,
5730                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5731     [CSR_VSSCRATCH]   = { "vsscratch",   hmode,   read_vsscratch,
5732                           write_vsscratch,
5733                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5734     [CSR_VSEPC]       = { "vsepc",       hmode,   read_vsepc,    write_vsepc,
5735                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5736     [CSR_VSCAUSE]     = { "vscause",     hmode,   read_vscause,  write_vscause,
5737                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5738     [CSR_VSTVAL]      = { "vstval",      hmode,   read_vstval,   write_vstval,
5739                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5740     [CSR_VSATP]       = { "vsatp",       hmode,   read_vsatp,    write_vsatp,
5741                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5742 
5743     [CSR_MTVAL2]      = { "mtval2", dbltrp_hmode, read_mtval2, write_mtval2,
5744                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5745     [CSR_MTINST]      = { "mtinst",      hmode,   read_mtinst,   write_mtinst,
5746                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5747 
5748     /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
5749     [CSR_HVIEN]       = { "hvien",       aia_hmode, NULL, NULL, rmw_hvien },
5750     [CSR_HVICTL]      = { "hvictl",      aia_hmode, read_hvictl,
5751                           write_hvictl                                      },
5752     [CSR_HVIPRIO1]    = { "hviprio1",    aia_hmode, read_hviprio1,
5753                           write_hviprio1                                    },
5754     [CSR_HVIPRIO2]    = { "hviprio2",    aia_hmode, read_hviprio2,
5755                           write_hviprio2                                    },
5756     /*
5757      * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
5758      */
5759     [CSR_VSISELECT]   = { "vsiselect",   csrind_or_aia_hmode, NULL, NULL,
5760                           rmw_xiselect                                      },
5761     [CSR_VSIREG]      = { "vsireg",      csrind_or_aia_hmode, NULL, NULL,
5762                           rmw_xireg                                         },
5763 
5764     /* Virtual Supervisor Indirect Alias */
5765     [CSR_VSIREG2]     = { "vsireg2", csrind_hmode, NULL, NULL, rmw_xiregi,
5766                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5767     [CSR_VSIREG3]     = { "vsireg3", csrind_hmode, NULL, NULL, rmw_xiregi,
5768                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5769     [CSR_VSIREG4]     = { "vsireg4", csrind_hmode, NULL, NULL, rmw_xiregi,
5770                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5771     [CSR_VSIREG5]     = { "vsireg5", csrind_hmode, NULL, NULL, rmw_xiregi,
5772                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5773     [CSR_VSIREG6]     = { "vsireg6", csrind_hmode, NULL, NULL, rmw_xiregi,
5774                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5775 
5776     /* VS-Level Interrupts (H-extension with AIA) */
5777     [CSR_VSTOPEI]     = { "vstopei",     aia_hmode, NULL, NULL, rmw_xtopei },
5778     [CSR_VSTOPI]      = { "vstopi",      aia_hmode, read_vstopi },
5779 
5780     /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
5781     [CSR_HIDELEGH]    = { "hidelegh",    aia_hmode32, NULL, NULL,
5782                           rmw_hidelegh                                      },
5783     [CSR_HVIENH]      = { "hvienh",      aia_hmode32, NULL, NULL, rmw_hvienh },
5784     [CSR_HVIPH]       = { "hviph",       aia_hmode32, NULL, NULL, rmw_hviph },
5785     [CSR_HVIPRIO1H]   = { "hviprio1h",   aia_hmode32, read_hviprio1h,
5786                           write_hviprio1h                                   },
5787     [CSR_HVIPRIO2H]   = { "hviprio2h",   aia_hmode32, read_hviprio2h,
5788                           write_hviprio2h                                   },
5789     [CSR_VSIEH]       = { "vsieh",       aia_hmode32, NULL, NULL, rmw_vsieh },
5790     [CSR_VSIPH]       = { "vsiph",       aia_hmode32, NULL, NULL, rmw_vsiph },
5791 
5792     /* Physical Memory Protection */
5793     [CSR_MSECCFG]    = { "mseccfg",   have_mseccfg, read_mseccfg, write_mseccfg,
5794                          .min_priv_ver = PRIV_VERSION_1_11_0           },
5795     [CSR_PMPCFG0]    = { "pmpcfg0",   pmp, read_pmpcfg,  write_pmpcfg  },
5796     [CSR_PMPCFG1]    = { "pmpcfg1",   pmp, read_pmpcfg,  write_pmpcfg  },
5797     [CSR_PMPCFG2]    = { "pmpcfg2",   pmp, read_pmpcfg,  write_pmpcfg  },
5798     [CSR_PMPCFG3]    = { "pmpcfg3",   pmp, read_pmpcfg,  write_pmpcfg  },
5799     [CSR_PMPADDR0]   = { "pmpaddr0",  pmp, read_pmpaddr, write_pmpaddr },
5800     [CSR_PMPADDR1]   = { "pmpaddr1",  pmp, read_pmpaddr, write_pmpaddr },
5801     [CSR_PMPADDR2]   = { "pmpaddr2",  pmp, read_pmpaddr, write_pmpaddr },
5802     [CSR_PMPADDR3]   = { "pmpaddr3",  pmp, read_pmpaddr, write_pmpaddr },
5803     [CSR_PMPADDR4]   = { "pmpaddr4",  pmp, read_pmpaddr, write_pmpaddr },
5804     [CSR_PMPADDR5]   = { "pmpaddr5",  pmp, read_pmpaddr, write_pmpaddr },
5805     [CSR_PMPADDR6]   = { "pmpaddr6",  pmp, read_pmpaddr, write_pmpaddr },
5806     [CSR_PMPADDR7]   = { "pmpaddr7",  pmp, read_pmpaddr, write_pmpaddr },
5807     [CSR_PMPADDR8]   = { "pmpaddr8",  pmp, read_pmpaddr, write_pmpaddr },
5808     [CSR_PMPADDR9]   = { "pmpaddr9",  pmp, read_pmpaddr, write_pmpaddr },
5809     [CSR_PMPADDR10]  = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
5810     [CSR_PMPADDR11]  = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
5811     [CSR_PMPADDR12]  = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
5812     [CSR_PMPADDR13]  = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
5813     [CSR_PMPADDR14] =  { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
5814     [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
5815 
5816     /* Debug CSRs */
5817     [CSR_TSELECT]   =  { "tselect",  debug, read_tselect,  write_tselect  },
5818     [CSR_TDATA1]    =  { "tdata1",   debug, read_tdata,    write_tdata    },
5819     [CSR_TDATA2]    =  { "tdata2",   debug, read_tdata,    write_tdata    },
5820     [CSR_TDATA3]    =  { "tdata3",   debug, read_tdata,    write_tdata    },
5821     [CSR_TINFO]     =  { "tinfo",    debug, read_tinfo,    write_ignore   },
5822     [CSR_MCONTEXT]  =  { "mcontext", debug, read_mcontext, write_mcontext },
5823 
5824     /* Performance Counters */
5825     [CSR_HPMCOUNTER3]    = { "hpmcounter3",    ctr,    read_hpmcounter },
5826     [CSR_HPMCOUNTER4]    = { "hpmcounter4",    ctr,    read_hpmcounter },
5827     [CSR_HPMCOUNTER5]    = { "hpmcounter5",    ctr,    read_hpmcounter },
5828     [CSR_HPMCOUNTER6]    = { "hpmcounter6",    ctr,    read_hpmcounter },
5829     [CSR_HPMCOUNTER7]    = { "hpmcounter7",    ctr,    read_hpmcounter },
5830     [CSR_HPMCOUNTER8]    = { "hpmcounter8",    ctr,    read_hpmcounter },
5831     [CSR_HPMCOUNTER9]    = { "hpmcounter9",    ctr,    read_hpmcounter },
5832     [CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,    read_hpmcounter },
5833     [CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,    read_hpmcounter },
5834     [CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,    read_hpmcounter },
5835     [CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,    read_hpmcounter },
5836     [CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,    read_hpmcounter },
5837     [CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,    read_hpmcounter },
5838     [CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,    read_hpmcounter },
5839     [CSR_HPMCOUNTER17]   = { "hpmcounter17",   ctr,    read_hpmcounter },
5840     [CSR_HPMCOUNTER18]   = { "hpmcounter18",   ctr,    read_hpmcounter },
5841     [CSR_HPMCOUNTER19]   = { "hpmcounter19",   ctr,    read_hpmcounter },
5842     [CSR_HPMCOUNTER20]   = { "hpmcounter20",   ctr,    read_hpmcounter },
5843     [CSR_HPMCOUNTER21]   = { "hpmcounter21",   ctr,    read_hpmcounter },
5844     [CSR_HPMCOUNTER22]   = { "hpmcounter22",   ctr,    read_hpmcounter },
5845     [CSR_HPMCOUNTER23]   = { "hpmcounter23",   ctr,    read_hpmcounter },
5846     [CSR_HPMCOUNTER24]   = { "hpmcounter24",   ctr,    read_hpmcounter },
5847     [CSR_HPMCOUNTER25]   = { "hpmcounter25",   ctr,    read_hpmcounter },
5848     [CSR_HPMCOUNTER26]   = { "hpmcounter26",   ctr,    read_hpmcounter },
5849     [CSR_HPMCOUNTER27]   = { "hpmcounter27",   ctr,    read_hpmcounter },
5850     [CSR_HPMCOUNTER28]   = { "hpmcounter28",   ctr,    read_hpmcounter },
5851     [CSR_HPMCOUNTER29]   = { "hpmcounter29",   ctr,    read_hpmcounter },
5852     [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,    read_hpmcounter },
5853     [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,    read_hpmcounter },
5854 
5855     [CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   mctr,    read_hpmcounter,
5856                              write_mhpmcounter                         },
5857     [CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   mctr,    read_hpmcounter,
5858                              write_mhpmcounter                         },
5859     [CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   mctr,    read_hpmcounter,
5860                              write_mhpmcounter                         },
5861     [CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   mctr,    read_hpmcounter,
5862                              write_mhpmcounter                         },
5863     [CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   mctr,    read_hpmcounter,
5864                              write_mhpmcounter                         },
5865     [CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   mctr,    read_hpmcounter,
5866                              write_mhpmcounter                         },
5867     [CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   mctr,    read_hpmcounter,
5868                              write_mhpmcounter                         },
5869     [CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  mctr,    read_hpmcounter,
5870                              write_mhpmcounter                         },
5871     [CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  mctr,    read_hpmcounter,
5872                              write_mhpmcounter                         },
5873     [CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  mctr,    read_hpmcounter,
5874                              write_mhpmcounter                         },
5875     [CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  mctr,    read_hpmcounter,
5876                              write_mhpmcounter                         },
5877     [CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  mctr,    read_hpmcounter,
5878                              write_mhpmcounter                         },
5879     [CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  mctr,    read_hpmcounter,
5880                              write_mhpmcounter                         },
5881     [CSR_MHPMCOUNTER16]  = { "mhpmcounter16",  mctr,    read_hpmcounter,
5882                              write_mhpmcounter                         },
5883     [CSR_MHPMCOUNTER17]  = { "mhpmcounter17",  mctr,    read_hpmcounter,
5884                              write_mhpmcounter                         },
5885     [CSR_MHPMCOUNTER18]  = { "mhpmcounter18",  mctr,    read_hpmcounter,
5886                              write_mhpmcounter                         },
5887     [CSR_MHPMCOUNTER19]  = { "mhpmcounter19",  mctr,    read_hpmcounter,
5888                              write_mhpmcounter                         },
5889     [CSR_MHPMCOUNTER20]  = { "mhpmcounter20",  mctr,    read_hpmcounter,
5890                              write_mhpmcounter                         },
5891     [CSR_MHPMCOUNTER21]  = { "mhpmcounter21",  mctr,    read_hpmcounter,
5892                              write_mhpmcounter                         },
5893     [CSR_MHPMCOUNTER22]  = { "mhpmcounter22",  mctr,    read_hpmcounter,
5894                              write_mhpmcounter                         },
5895     [CSR_MHPMCOUNTER23]  = { "mhpmcounter23",  mctr,    read_hpmcounter,
5896                              write_mhpmcounter                         },
5897     [CSR_MHPMCOUNTER24]  = { "mhpmcounter24",  mctr,    read_hpmcounter,
5898                              write_mhpmcounter                         },
5899     [CSR_MHPMCOUNTER25]  = { "mhpmcounter25",  mctr,    read_hpmcounter,
5900                              write_mhpmcounter                         },
5901     [CSR_MHPMCOUNTER26]  = { "mhpmcounter26",  mctr,    read_hpmcounter,
5902                              write_mhpmcounter                         },
5903     [CSR_MHPMCOUNTER27]  = { "mhpmcounter27",  mctr,    read_hpmcounter,
5904                              write_mhpmcounter                         },
5905     [CSR_MHPMCOUNTER28]  = { "mhpmcounter28",  mctr,    read_hpmcounter,
5906                              write_mhpmcounter                         },
5907     [CSR_MHPMCOUNTER29]  = { "mhpmcounter29",  mctr,    read_hpmcounter,
5908                              write_mhpmcounter                         },
5909     [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  mctr,    read_hpmcounter,
5910                              write_mhpmcounter                         },
5911     [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  mctr,    read_hpmcounter,
5912                              write_mhpmcounter                         },
5913 
5914     [CSR_MCOUNTINHIBIT]  = { "mcountinhibit",  any, read_mcountinhibit,
5915                              write_mcountinhibit,
5916                              .min_priv_ver = PRIV_VERSION_1_11_0       },
5917 
5918     [CSR_MCYCLECFG]      = { "mcyclecfg",   smcntrpmf, read_mcyclecfg,
5919                              write_mcyclecfg,
5920                              .min_priv_ver = PRIV_VERSION_1_12_0       },
5921     [CSR_MINSTRETCFG]    = { "minstretcfg", smcntrpmf, read_minstretcfg,
5922                              write_minstretcfg,
5923                              .min_priv_ver = PRIV_VERSION_1_12_0       },
5924 
5925     [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_mhpmevent,
5926                              write_mhpmevent                           },
5927     [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_mhpmevent,
5928                              write_mhpmevent                           },
5929     [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_mhpmevent,
5930                              write_mhpmevent                           },
5931     [CSR_MHPMEVENT6]     = { "mhpmevent6",     any,    read_mhpmevent,
5932                              write_mhpmevent                           },
5933     [CSR_MHPMEVENT7]     = { "mhpmevent7",     any,    read_mhpmevent,
5934                              write_mhpmevent                           },
5935     [CSR_MHPMEVENT8]     = { "mhpmevent8",     any,    read_mhpmevent,
5936                              write_mhpmevent                           },
5937     [CSR_MHPMEVENT9]     = { "mhpmevent9",     any,    read_mhpmevent,
5938                              write_mhpmevent                           },
5939     [CSR_MHPMEVENT10]    = { "mhpmevent10",    any,    read_mhpmevent,
5940                              write_mhpmevent                           },
5941     [CSR_MHPMEVENT11]    = { "mhpmevent11",    any,    read_mhpmevent,
5942                              write_mhpmevent                           },
5943     [CSR_MHPMEVENT12]    = { "mhpmevent12",    any,    read_mhpmevent,
5944                              write_mhpmevent                           },
5945     [CSR_MHPMEVENT13]    = { "mhpmevent13",    any,    read_mhpmevent,
5946                              write_mhpmevent                           },
5947     [CSR_MHPMEVENT14]    = { "mhpmevent14",    any,    read_mhpmevent,
5948                              write_mhpmevent                           },
5949     [CSR_MHPMEVENT15]    = { "mhpmevent15",    any,    read_mhpmevent,
5950                              write_mhpmevent                           },
5951     [CSR_MHPMEVENT16]    = { "mhpmevent16",    any,    read_mhpmevent,
5952                              write_mhpmevent                           },
5953     [CSR_MHPMEVENT17]    = { "mhpmevent17",    any,    read_mhpmevent,
5954                              write_mhpmevent                           },
5955     [CSR_MHPMEVENT18]    = { "mhpmevent18",    any,    read_mhpmevent,
5956                              write_mhpmevent                           },
5957     [CSR_MHPMEVENT19]    = { "mhpmevent19",    any,    read_mhpmevent,
5958                              write_mhpmevent                           },
5959     [CSR_MHPMEVENT20]    = { "mhpmevent20",    any,    read_mhpmevent,
5960                              write_mhpmevent                           },
5961     [CSR_MHPMEVENT21]    = { "mhpmevent21",    any,    read_mhpmevent,
5962                              write_mhpmevent                           },
5963     [CSR_MHPMEVENT22]    = { "mhpmevent22",    any,    read_mhpmevent,
5964                              write_mhpmevent                           },
5965     [CSR_MHPMEVENT23]    = { "mhpmevent23",    any,    read_mhpmevent,
5966                              write_mhpmevent                           },
5967     [CSR_MHPMEVENT24]    = { "mhpmevent24",    any,    read_mhpmevent,
5968                              write_mhpmevent                           },
5969     [CSR_MHPMEVENT25]    = { "mhpmevent25",    any,    read_mhpmevent,
5970                              write_mhpmevent                           },
5971     [CSR_MHPMEVENT26]    = { "mhpmevent26",    any,    read_mhpmevent,
5972                              write_mhpmevent                           },
5973     [CSR_MHPMEVENT27]    = { "mhpmevent27",    any,    read_mhpmevent,
5974                              write_mhpmevent                           },
5975     [CSR_MHPMEVENT28]    = { "mhpmevent28",    any,    read_mhpmevent,
5976                              write_mhpmevent                           },
5977     [CSR_MHPMEVENT29]    = { "mhpmevent29",    any,    read_mhpmevent,
5978                              write_mhpmevent                           },
5979     [CSR_MHPMEVENT30]    = { "mhpmevent30",    any,    read_mhpmevent,
5980                              write_mhpmevent                           },
5981     [CSR_MHPMEVENT31]    = { "mhpmevent31",    any,    read_mhpmevent,
5982                              write_mhpmevent                           },
5983 
5984     [CSR_MCYCLECFGH]     = { "mcyclecfgh",   smcntrpmf_32, read_mcyclecfgh,
5985                              write_mcyclecfgh,
5986                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5987     [CSR_MINSTRETCFGH]   = { "minstretcfgh", smcntrpmf_32, read_minstretcfgh,
5988                              write_minstretcfgh,
5989                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5990 
5991     [CSR_MHPMEVENT3H]    = { "mhpmevent3h",    sscofpmf_32,  read_mhpmeventh,
5992                              write_mhpmeventh,
5993                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5994     [CSR_MHPMEVENT4H]    = { "mhpmevent4h",    sscofpmf_32,  read_mhpmeventh,
5995                              write_mhpmeventh,
5996                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5997     [CSR_MHPMEVENT5H]    = { "mhpmevent5h",    sscofpmf_32,  read_mhpmeventh,
5998                              write_mhpmeventh,
5999                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6000     [CSR_MHPMEVENT6H]    = { "mhpmevent6h",    sscofpmf_32,  read_mhpmeventh,
6001                              write_mhpmeventh,
6002                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6003     [CSR_MHPMEVENT7H]    = { "mhpmevent7h",    sscofpmf_32,  read_mhpmeventh,
6004                              write_mhpmeventh,
6005                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6006     [CSR_MHPMEVENT8H]    = { "mhpmevent8h",    sscofpmf_32,  read_mhpmeventh,
6007                              write_mhpmeventh,
6008                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6009     [CSR_MHPMEVENT9H]    = { "mhpmevent9h",    sscofpmf_32,  read_mhpmeventh,
6010                              write_mhpmeventh,
6011                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6012     [CSR_MHPMEVENT10H]   = { "mhpmevent10h",    sscofpmf_32,  read_mhpmeventh,
6013                              write_mhpmeventh,
6014                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6015     [CSR_MHPMEVENT11H]   = { "mhpmevent11h",    sscofpmf_32,  read_mhpmeventh,
6016                              write_mhpmeventh,
6017                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6018     [CSR_MHPMEVENT12H]   = { "mhpmevent12h",    sscofpmf_32,  read_mhpmeventh,
6019                              write_mhpmeventh,
6020                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6021     [CSR_MHPMEVENT13H]   = { "mhpmevent13h",    sscofpmf_32,  read_mhpmeventh,
6022                              write_mhpmeventh,
6023                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6024     [CSR_MHPMEVENT14H]   = { "mhpmevent14h",    sscofpmf_32,  read_mhpmeventh,
6025                              write_mhpmeventh,
6026                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6027     [CSR_MHPMEVENT15H]   = { "mhpmevent15h",    sscofpmf_32,  read_mhpmeventh,
6028                              write_mhpmeventh,
6029                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6030     [CSR_MHPMEVENT16H]   = { "mhpmevent16h",    sscofpmf_32,  read_mhpmeventh,
6031                              write_mhpmeventh,
6032                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6033     [CSR_MHPMEVENT17H]   = { "mhpmevent17h",    sscofpmf_32,  read_mhpmeventh,
6034                              write_mhpmeventh,
6035                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6036     [CSR_MHPMEVENT18H]   = { "mhpmevent18h",    sscofpmf_32,  read_mhpmeventh,
6037                              write_mhpmeventh,
6038                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6039     [CSR_MHPMEVENT19H]   = { "mhpmevent19h",    sscofpmf_32,  read_mhpmeventh,
6040                              write_mhpmeventh,
6041                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6042     [CSR_MHPMEVENT20H]   = { "mhpmevent20h",    sscofpmf_32,  read_mhpmeventh,
6043                              write_mhpmeventh,
6044                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6045     [CSR_MHPMEVENT21H]   = { "mhpmevent21h",    sscofpmf_32,  read_mhpmeventh,
6046                              write_mhpmeventh,
6047                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6048     [CSR_MHPMEVENT22H]   = { "mhpmevent22h",    sscofpmf_32,  read_mhpmeventh,
6049                              write_mhpmeventh,
6050                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6051     [CSR_MHPMEVENT23H]   = { "mhpmevent23h",    sscofpmf_32,  read_mhpmeventh,
6052                              write_mhpmeventh,
6053                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6054     [CSR_MHPMEVENT24H]   = { "mhpmevent24h",    sscofpmf_32,  read_mhpmeventh,
6055                              write_mhpmeventh,
6056                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6057     [CSR_MHPMEVENT25H]   = { "mhpmevent25h",    sscofpmf_32,  read_mhpmeventh,
6058                              write_mhpmeventh,
6059                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6060     [CSR_MHPMEVENT26H]   = { "mhpmevent26h",    sscofpmf_32,  read_mhpmeventh,
6061                              write_mhpmeventh,
6062                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6063     [CSR_MHPMEVENT27H]   = { "mhpmevent27h",    sscofpmf_32,  read_mhpmeventh,
6064                              write_mhpmeventh,
6065                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6066     [CSR_MHPMEVENT28H]   = { "mhpmevent28h",    sscofpmf_32,  read_mhpmeventh,
6067                              write_mhpmeventh,
6068                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6069     [CSR_MHPMEVENT29H]   = { "mhpmevent29h",    sscofpmf_32,  read_mhpmeventh,
6070                              write_mhpmeventh,
6071                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6072     [CSR_MHPMEVENT30H]   = { "mhpmevent30h",    sscofpmf_32,  read_mhpmeventh,
6073                              write_mhpmeventh,
6074                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6075     [CSR_MHPMEVENT31H]   = { "mhpmevent31h",    sscofpmf_32,  read_mhpmeventh,
6076                              write_mhpmeventh,
6077                              .min_priv_ver = PRIV_VERSION_1_12_0        },
6078 
6079     [CSR_HPMCOUNTER3H]   = { "hpmcounter3h",   ctr32,  read_hpmcounterh },
6080     [CSR_HPMCOUNTER4H]   = { "hpmcounter4h",   ctr32,  read_hpmcounterh },
6081     [CSR_HPMCOUNTER5H]   = { "hpmcounter5h",   ctr32,  read_hpmcounterh },
6082     [CSR_HPMCOUNTER6H]   = { "hpmcounter6h",   ctr32,  read_hpmcounterh },
6083     [CSR_HPMCOUNTER7H]   = { "hpmcounter7h",   ctr32,  read_hpmcounterh },
6084     [CSR_HPMCOUNTER8H]   = { "hpmcounter8h",   ctr32,  read_hpmcounterh },
6085     [CSR_HPMCOUNTER9H]   = { "hpmcounter9h",   ctr32,  read_hpmcounterh },
6086     [CSR_HPMCOUNTER10H]  = { "hpmcounter10h",  ctr32,  read_hpmcounterh },
6087     [CSR_HPMCOUNTER11H]  = { "hpmcounter11h",  ctr32,  read_hpmcounterh },
6088     [CSR_HPMCOUNTER12H]  = { "hpmcounter12h",  ctr32,  read_hpmcounterh },
6089     [CSR_HPMCOUNTER13H]  = { "hpmcounter13h",  ctr32,  read_hpmcounterh },
6090     [CSR_HPMCOUNTER14H]  = { "hpmcounter14h",  ctr32,  read_hpmcounterh },
6091     [CSR_HPMCOUNTER15H]  = { "hpmcounter15h",  ctr32,  read_hpmcounterh },
6092     [CSR_HPMCOUNTER16H]  = { "hpmcounter16h",  ctr32,  read_hpmcounterh },
6093     [CSR_HPMCOUNTER17H]  = { "hpmcounter17h",  ctr32,  read_hpmcounterh },
6094     [CSR_HPMCOUNTER18H]  = { "hpmcounter18h",  ctr32,  read_hpmcounterh },
6095     [CSR_HPMCOUNTER19H]  = { "hpmcounter19h",  ctr32,  read_hpmcounterh },
6096     [CSR_HPMCOUNTER20H]  = { "hpmcounter20h",  ctr32,  read_hpmcounterh },
6097     [CSR_HPMCOUNTER21H]  = { "hpmcounter21h",  ctr32,  read_hpmcounterh },
6098     [CSR_HPMCOUNTER22H]  = { "hpmcounter22h",  ctr32,  read_hpmcounterh },
6099     [CSR_HPMCOUNTER23H]  = { "hpmcounter23h",  ctr32,  read_hpmcounterh },
6100     [CSR_HPMCOUNTER24H]  = { "hpmcounter24h",  ctr32,  read_hpmcounterh },
6101     [CSR_HPMCOUNTER25H]  = { "hpmcounter25h",  ctr32,  read_hpmcounterh },
6102     [CSR_HPMCOUNTER26H]  = { "hpmcounter26h",  ctr32,  read_hpmcounterh },
6103     [CSR_HPMCOUNTER27H]  = { "hpmcounter27h",  ctr32,  read_hpmcounterh },
6104     [CSR_HPMCOUNTER28H]  = { "hpmcounter28h",  ctr32,  read_hpmcounterh },
6105     [CSR_HPMCOUNTER29H]  = { "hpmcounter29h",  ctr32,  read_hpmcounterh },
6106     [CSR_HPMCOUNTER30H]  = { "hpmcounter30h",  ctr32,  read_hpmcounterh },
6107     [CSR_HPMCOUNTER31H]  = { "hpmcounter31h",  ctr32,  read_hpmcounterh },
6108 
6109     [CSR_MHPMCOUNTER3H]  = { "mhpmcounter3h",  mctr32,  read_hpmcounterh,
6110                              write_mhpmcounterh                         },
6111     [CSR_MHPMCOUNTER4H]  = { "mhpmcounter4h",  mctr32,  read_hpmcounterh,
6112                              write_mhpmcounterh                         },
6113     [CSR_MHPMCOUNTER5H]  = { "mhpmcounter5h",  mctr32,  read_hpmcounterh,
6114                              write_mhpmcounterh                         },
6115     [CSR_MHPMCOUNTER6H]  = { "mhpmcounter6h",  mctr32,  read_hpmcounterh,
6116                              write_mhpmcounterh                         },
6117     [CSR_MHPMCOUNTER7H]  = { "mhpmcounter7h",  mctr32,  read_hpmcounterh,
6118                              write_mhpmcounterh                         },
6119     [CSR_MHPMCOUNTER8H]  = { "mhpmcounter8h",  mctr32,  read_hpmcounterh,
6120                              write_mhpmcounterh                         },
6121     [CSR_MHPMCOUNTER9H]  = { "mhpmcounter9h",  mctr32,  read_hpmcounterh,
6122                              write_mhpmcounterh                         },
6123     [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32,  read_hpmcounterh,
6124                              write_mhpmcounterh                         },
6125     [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32,  read_hpmcounterh,
6126                              write_mhpmcounterh                         },
6127     [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32,  read_hpmcounterh,
6128                              write_mhpmcounterh                         },
6129     [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32,  read_hpmcounterh,
6130                              write_mhpmcounterh                         },
6131     [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32,  read_hpmcounterh,
6132                              write_mhpmcounterh                         },
6133     [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32,  read_hpmcounterh,
6134                              write_mhpmcounterh                         },
6135     [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32,  read_hpmcounterh,
6136                              write_mhpmcounterh                         },
6137     [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32,  read_hpmcounterh,
6138                              write_mhpmcounterh                         },
6139     [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32,  read_hpmcounterh,
6140                              write_mhpmcounterh                         },
6141     [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32,  read_hpmcounterh,
6142                              write_mhpmcounterh                         },
6143     [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32,  read_hpmcounterh,
6144                              write_mhpmcounterh                         },
6145     [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32,  read_hpmcounterh,
6146                              write_mhpmcounterh                         },
6147     [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32,  read_hpmcounterh,
6148                              write_mhpmcounterh                         },
6149     [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32,  read_hpmcounterh,
6150                              write_mhpmcounterh                         },
6151     [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32,  read_hpmcounterh,
6152                              write_mhpmcounterh                         },
6153     [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32,  read_hpmcounterh,
6154                              write_mhpmcounterh                         },
6155     [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32,  read_hpmcounterh,
6156                              write_mhpmcounterh                         },
6157     [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32,  read_hpmcounterh,
6158                              write_mhpmcounterh                         },
6159     [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32,  read_hpmcounterh,
6160                              write_mhpmcounterh                         },
6161     [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32,  read_hpmcounterh,
6162                              write_mhpmcounterh                         },
6163     [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32,  read_hpmcounterh,
6164                              write_mhpmcounterh                         },
6165     [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32,  read_hpmcounterh,
6166                              write_mhpmcounterh                         },
6167     [CSR_SCOUNTOVF]      = { "scountovf", sscofpmf,  read_scountovf,
6168                              .min_priv_ver = PRIV_VERSION_1_12_0 },
6169 
6170 #endif /* !CONFIG_USER_ONLY */
6171 };
6172