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