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