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