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