nbd/server: Add FLAG_PAYLOAD support to CMD_BLOCK_STATUS
[qemu/ericb.git] / target / riscv / csr.c
blobea7585329e91470a50c431eb76efde43d4933d56
1 /*
2 * RISC-V Control and Status Registers.
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2017-2018 SiFive, Inc.
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.
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.
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/>.
20 #include "qemu/osdep.h"
21 #include "qemu/log.h"
22 #include "qemu/timer.h"
23 #include "cpu.h"
24 #include "pmu.h"
25 #include "time_helper.h"
26 #include "qemu/main-loop.h"
27 #include "exec/exec-all.h"
28 #include "exec/tb-flush.h"
29 #include "sysemu/cpu-timers.h"
30 #include "qemu/guest-random.h"
31 #include "qapi/error.h"
33 /* CSR function table public API */
34 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
36 *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
39 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
41 csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
44 /* Predicates */
45 #if !defined(CONFIG_USER_ONLY)
46 RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
48 bool virt = env->virt_enabled;
50 if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
51 return RISCV_EXCP_NONE;
54 if (!(env->mstateen[index] & bit)) {
55 return RISCV_EXCP_ILLEGAL_INST;
58 if (virt) {
59 if (!(env->hstateen[index] & bit)) {
60 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
63 if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
64 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
68 if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
69 if (!(env->sstateen[index] & bit)) {
70 return RISCV_EXCP_ILLEGAL_INST;
74 return RISCV_EXCP_NONE;
76 #endif
78 static RISCVException fs(CPURISCVState *env, int csrno)
80 #if !defined(CONFIG_USER_ONLY)
81 if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
82 !riscv_cpu_cfg(env)->ext_zfinx) {
83 return RISCV_EXCP_ILLEGAL_INST;
86 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
87 return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
89 #endif
90 return RISCV_EXCP_NONE;
93 static RISCVException vs(CPURISCVState *env, int csrno)
95 if (riscv_cpu_cfg(env)->ext_zve32f) {
96 #if !defined(CONFIG_USER_ONLY)
97 if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
98 return RISCV_EXCP_ILLEGAL_INST;
100 #endif
101 return RISCV_EXCP_NONE;
103 return RISCV_EXCP_ILLEGAL_INST;
106 static RISCVException ctr(CPURISCVState *env, int csrno)
108 #if !defined(CONFIG_USER_ONLY)
109 RISCVCPU *cpu = env_archcpu(env);
110 int ctr_index;
111 target_ulong ctr_mask;
112 int base_csrno = CSR_CYCLE;
113 bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
115 if (rv32 && csrno >= CSR_CYCLEH) {
116 /* Offset for RV32 hpmcounternh counters */
117 base_csrno += 0x80;
119 ctr_index = csrno - base_csrno;
120 ctr_mask = BIT(ctr_index);
122 if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
123 (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
124 goto skip_ext_pmu_check;
127 if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
128 /* No counter is enabled in PMU or the counter is out of range */
129 return RISCV_EXCP_ILLEGAL_INST;
132 skip_ext_pmu_check:
134 if (env->debugger) {
135 return RISCV_EXCP_NONE;
138 if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
139 return RISCV_EXCP_ILLEGAL_INST;
142 if (env->virt_enabled) {
143 if (!get_field(env->hcounteren, ctr_mask) ||
144 (env->priv == PRV_U && !get_field(env->scounteren, ctr_mask))) {
145 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
149 if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
150 !get_field(env->scounteren, ctr_mask)) {
151 return RISCV_EXCP_ILLEGAL_INST;
154 #endif
155 return RISCV_EXCP_NONE;
158 static RISCVException ctr32(CPURISCVState *env, int csrno)
160 if (riscv_cpu_mxl(env) != MXL_RV32) {
161 return RISCV_EXCP_ILLEGAL_INST;
164 return ctr(env, csrno);
167 static RISCVException zcmt(CPURISCVState *env, int csrno)
169 if (!riscv_cpu_cfg(env)->ext_zcmt) {
170 return RISCV_EXCP_ILLEGAL_INST;
173 #if !defined(CONFIG_USER_ONLY)
174 RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
175 if (ret != RISCV_EXCP_NONE) {
176 return ret;
178 #endif
180 return RISCV_EXCP_NONE;
183 #if !defined(CONFIG_USER_ONLY)
184 static RISCVException mctr(CPURISCVState *env, int csrno)
186 int pmu_num = riscv_cpu_cfg(env)->pmu_num;
187 int ctr_index;
188 int base_csrno = CSR_MHPMCOUNTER3;
190 if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) {
191 /* Offset for RV32 mhpmcounternh counters */
192 base_csrno += 0x80;
194 ctr_index = csrno - base_csrno;
195 if (!pmu_num || ctr_index >= pmu_num) {
196 /* The PMU is not enabled or counter is out of range */
197 return RISCV_EXCP_ILLEGAL_INST;
200 return RISCV_EXCP_NONE;
203 static RISCVException mctr32(CPURISCVState *env, int csrno)
205 if (riscv_cpu_mxl(env) != MXL_RV32) {
206 return RISCV_EXCP_ILLEGAL_INST;
209 return mctr(env, csrno);
212 static RISCVException sscofpmf(CPURISCVState *env, int csrno)
214 if (!riscv_cpu_cfg(env)->ext_sscofpmf) {
215 return RISCV_EXCP_ILLEGAL_INST;
218 return RISCV_EXCP_NONE;
221 static RISCVException any(CPURISCVState *env, int csrno)
223 return RISCV_EXCP_NONE;
226 static RISCVException any32(CPURISCVState *env, int csrno)
228 if (riscv_cpu_mxl(env) != MXL_RV32) {
229 return RISCV_EXCP_ILLEGAL_INST;
232 return any(env, csrno);
236 static int aia_any(CPURISCVState *env, int csrno)
238 if (!riscv_cpu_cfg(env)->ext_smaia) {
239 return RISCV_EXCP_ILLEGAL_INST;
242 return any(env, csrno);
245 static int aia_any32(CPURISCVState *env, int csrno)
247 if (!riscv_cpu_cfg(env)->ext_smaia) {
248 return RISCV_EXCP_ILLEGAL_INST;
251 return any32(env, csrno);
254 static RISCVException smode(CPURISCVState *env, int csrno)
256 if (riscv_has_ext(env, RVS)) {
257 return RISCV_EXCP_NONE;
260 return RISCV_EXCP_ILLEGAL_INST;
263 static int smode32(CPURISCVState *env, int csrno)
265 if (riscv_cpu_mxl(env) != MXL_RV32) {
266 return RISCV_EXCP_ILLEGAL_INST;
269 return smode(env, csrno);
272 static int aia_smode(CPURISCVState *env, int csrno)
274 if (!riscv_cpu_cfg(env)->ext_ssaia) {
275 return RISCV_EXCP_ILLEGAL_INST;
278 return smode(env, csrno);
281 static int aia_smode32(CPURISCVState *env, int csrno)
283 if (!riscv_cpu_cfg(env)->ext_ssaia) {
284 return RISCV_EXCP_ILLEGAL_INST;
287 return smode32(env, csrno);
290 static RISCVException hmode(CPURISCVState *env, int csrno)
292 if (riscv_has_ext(env, RVH)) {
293 return RISCV_EXCP_NONE;
296 return RISCV_EXCP_ILLEGAL_INST;
299 static RISCVException hmode32(CPURISCVState *env, int csrno)
301 if (riscv_cpu_mxl(env) != MXL_RV32) {
302 return RISCV_EXCP_ILLEGAL_INST;
305 return hmode(env, csrno);
309 static RISCVException umode(CPURISCVState *env, int csrno)
311 if (riscv_has_ext(env, RVU)) {
312 return RISCV_EXCP_NONE;
315 return RISCV_EXCP_ILLEGAL_INST;
318 static RISCVException umode32(CPURISCVState *env, int csrno)
320 if (riscv_cpu_mxl(env) != MXL_RV32) {
321 return RISCV_EXCP_ILLEGAL_INST;
324 return umode(env, csrno);
327 static RISCVException mstateen(CPURISCVState *env, int csrno)
329 if (!riscv_cpu_cfg(env)->ext_smstateen) {
330 return RISCV_EXCP_ILLEGAL_INST;
333 return any(env, csrno);
336 static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
338 if (!riscv_cpu_cfg(env)->ext_smstateen) {
339 return RISCV_EXCP_ILLEGAL_INST;
342 RISCVException ret = hmode(env, csrno);
343 if (ret != RISCV_EXCP_NONE) {
344 return ret;
347 if (env->debugger) {
348 return RISCV_EXCP_NONE;
351 if (env->priv < PRV_M) {
352 if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
353 return RISCV_EXCP_ILLEGAL_INST;
357 return RISCV_EXCP_NONE;
360 static RISCVException hstateen(CPURISCVState *env, int csrno)
362 return hstateen_pred(env, csrno, CSR_HSTATEEN0);
365 static RISCVException hstateenh(CPURISCVState *env, int csrno)
367 return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
370 static RISCVException sstateen(CPURISCVState *env, int csrno)
372 bool virt = env->virt_enabled;
373 int index = csrno - CSR_SSTATEEN0;
375 if (!riscv_cpu_cfg(env)->ext_smstateen) {
376 return RISCV_EXCP_ILLEGAL_INST;
379 RISCVException ret = smode(env, csrno);
380 if (ret != RISCV_EXCP_NONE) {
381 return ret;
384 if (env->debugger) {
385 return RISCV_EXCP_NONE;
388 if (env->priv < PRV_M) {
389 if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
390 return RISCV_EXCP_ILLEGAL_INST;
393 if (virt) {
394 if (!(env->hstateen[index] & SMSTATEEN_STATEEN)) {
395 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
400 return RISCV_EXCP_NONE;
403 static RISCVException sstc(CPURISCVState *env, int csrno)
405 bool hmode_check = false;
407 if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn) {
408 return RISCV_EXCP_ILLEGAL_INST;
411 if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
412 hmode_check = true;
415 RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
416 if (ret != RISCV_EXCP_NONE) {
417 return ret;
420 if (env->debugger) {
421 return RISCV_EXCP_NONE;
424 if (env->priv == PRV_M) {
425 return RISCV_EXCP_NONE;
429 * No need of separate function for rv32 as menvcfg stores both menvcfg
430 * menvcfgh for RV32.
432 if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
433 get_field(env->menvcfg, MENVCFG_STCE))) {
434 return RISCV_EXCP_ILLEGAL_INST;
437 if (env->virt_enabled) {
438 if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
439 get_field(env->henvcfg, HENVCFG_STCE))) {
440 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
444 return RISCV_EXCP_NONE;
447 static RISCVException sstc_32(CPURISCVState *env, int csrno)
449 if (riscv_cpu_mxl(env) != MXL_RV32) {
450 return RISCV_EXCP_ILLEGAL_INST;
453 return sstc(env, csrno);
456 static RISCVException satp(CPURISCVState *env, int csrno)
458 if (env->priv == PRV_S && !env->virt_enabled &&
459 get_field(env->mstatus, MSTATUS_TVM)) {
460 return RISCV_EXCP_ILLEGAL_INST;
462 if (env->priv == PRV_S && env->virt_enabled &&
463 get_field(env->hstatus, HSTATUS_VTVM)) {
464 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
467 return smode(env, csrno);
470 static RISCVException hgatp(CPURISCVState *env, int csrno)
472 if (env->priv == PRV_S && !env->virt_enabled &&
473 get_field(env->mstatus, MSTATUS_TVM)) {
474 return RISCV_EXCP_ILLEGAL_INST;
477 return hmode(env, csrno);
480 /* Checks if PointerMasking registers could be accessed */
481 static RISCVException pointer_masking(CPURISCVState *env, int csrno)
483 /* Check if j-ext is present */
484 if (riscv_has_ext(env, RVJ)) {
485 return RISCV_EXCP_NONE;
487 return RISCV_EXCP_ILLEGAL_INST;
490 static int aia_hmode(CPURISCVState *env, int csrno)
492 if (!riscv_cpu_cfg(env)->ext_ssaia) {
493 return RISCV_EXCP_ILLEGAL_INST;
496 return hmode(env, csrno);
499 static int aia_hmode32(CPURISCVState *env, int csrno)
501 if (!riscv_cpu_cfg(env)->ext_ssaia) {
502 return RISCV_EXCP_ILLEGAL_INST;
505 return hmode32(env, csrno);
508 static RISCVException pmp(CPURISCVState *env, int csrno)
510 if (riscv_cpu_cfg(env)->pmp) {
511 if (csrno <= CSR_PMPCFG3) {
512 uint32_t reg_index = csrno - CSR_PMPCFG0;
514 /* TODO: RV128 restriction check */
515 if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
516 return RISCV_EXCP_ILLEGAL_INST;
520 return RISCV_EXCP_NONE;
523 return RISCV_EXCP_ILLEGAL_INST;
526 static RISCVException epmp(CPURISCVState *env, int csrno)
528 if (riscv_cpu_cfg(env)->epmp) {
529 return RISCV_EXCP_NONE;
532 return RISCV_EXCP_ILLEGAL_INST;
535 static RISCVException debug(CPURISCVState *env, int csrno)
537 if (riscv_cpu_cfg(env)->debug) {
538 return RISCV_EXCP_NONE;
541 return RISCV_EXCP_ILLEGAL_INST;
543 #endif
545 static RISCVException seed(CPURISCVState *env, int csrno)
547 if (!riscv_cpu_cfg(env)->ext_zkr) {
548 return RISCV_EXCP_ILLEGAL_INST;
551 #if !defined(CONFIG_USER_ONLY)
552 if (env->debugger) {
553 return RISCV_EXCP_NONE;
557 * With a CSR read-write instruction:
558 * 1) The seed CSR is always available in machine mode as normal.
559 * 2) Attempted access to seed from virtual modes VS and VU always raises
560 * an exception(virtual instruction exception only if mseccfg.sseed=1).
561 * 3) Without the corresponding access control bit set to 1, any attempted
562 * access to seed from U, S or HS modes will raise an illegal instruction
563 * exception.
565 if (env->priv == PRV_M) {
566 return RISCV_EXCP_NONE;
567 } else if (env->virt_enabled) {
568 if (env->mseccfg & MSECCFG_SSEED) {
569 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
570 } else {
571 return RISCV_EXCP_ILLEGAL_INST;
573 } else {
574 if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) {
575 return RISCV_EXCP_NONE;
576 } else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) {
577 return RISCV_EXCP_NONE;
578 } else {
579 return RISCV_EXCP_ILLEGAL_INST;
582 #else
583 return RISCV_EXCP_NONE;
584 #endif
587 /* User Floating-Point CSRs */
588 static RISCVException read_fflags(CPURISCVState *env, int csrno,
589 target_ulong *val)
591 *val = riscv_cpu_get_fflags(env);
592 return RISCV_EXCP_NONE;
595 static RISCVException write_fflags(CPURISCVState *env, int csrno,
596 target_ulong val)
598 #if !defined(CONFIG_USER_ONLY)
599 if (riscv_has_ext(env, RVF)) {
600 env->mstatus |= MSTATUS_FS;
602 #endif
603 riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
604 return RISCV_EXCP_NONE;
607 static RISCVException read_frm(CPURISCVState *env, int csrno,
608 target_ulong *val)
610 *val = env->frm;
611 return RISCV_EXCP_NONE;
614 static RISCVException write_frm(CPURISCVState *env, int csrno,
615 target_ulong val)
617 #if !defined(CONFIG_USER_ONLY)
618 if (riscv_has_ext(env, RVF)) {
619 env->mstatus |= MSTATUS_FS;
621 #endif
622 env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
623 return RISCV_EXCP_NONE;
626 static RISCVException read_fcsr(CPURISCVState *env, int csrno,
627 target_ulong *val)
629 *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
630 | (env->frm << FSR_RD_SHIFT);
631 return RISCV_EXCP_NONE;
634 static RISCVException write_fcsr(CPURISCVState *env, int csrno,
635 target_ulong val)
637 #if !defined(CONFIG_USER_ONLY)
638 if (riscv_has_ext(env, RVF)) {
639 env->mstatus |= MSTATUS_FS;
641 #endif
642 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
643 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
644 return RISCV_EXCP_NONE;
647 static RISCVException read_vtype(CPURISCVState *env, int csrno,
648 target_ulong *val)
650 uint64_t vill;
651 switch (env->xl) {
652 case MXL_RV32:
653 vill = (uint32_t)env->vill << 31;
654 break;
655 case MXL_RV64:
656 vill = (uint64_t)env->vill << 63;
657 break;
658 default:
659 g_assert_not_reached();
661 *val = (target_ulong)vill | env->vtype;
662 return RISCV_EXCP_NONE;
665 static RISCVException read_vl(CPURISCVState *env, int csrno,
666 target_ulong *val)
668 *val = env->vl;
669 return RISCV_EXCP_NONE;
672 static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
674 *val = riscv_cpu_cfg(env)->vlen >> 3;
675 return RISCV_EXCP_NONE;
678 static RISCVException read_vxrm(CPURISCVState *env, int csrno,
679 target_ulong *val)
681 *val = env->vxrm;
682 return RISCV_EXCP_NONE;
685 static RISCVException write_vxrm(CPURISCVState *env, int csrno,
686 target_ulong val)
688 #if !defined(CONFIG_USER_ONLY)
689 env->mstatus |= MSTATUS_VS;
690 #endif
691 env->vxrm = val;
692 return RISCV_EXCP_NONE;
695 static RISCVException read_vxsat(CPURISCVState *env, int csrno,
696 target_ulong *val)
698 *val = env->vxsat;
699 return RISCV_EXCP_NONE;
702 static RISCVException write_vxsat(CPURISCVState *env, int csrno,
703 target_ulong val)
705 #if !defined(CONFIG_USER_ONLY)
706 env->mstatus |= MSTATUS_VS;
707 #endif
708 env->vxsat = val;
709 return RISCV_EXCP_NONE;
712 static RISCVException read_vstart(CPURISCVState *env, int csrno,
713 target_ulong *val)
715 *val = env->vstart;
716 return RISCV_EXCP_NONE;
719 static RISCVException write_vstart(CPURISCVState *env, int csrno,
720 target_ulong val)
722 #if !defined(CONFIG_USER_ONLY)
723 env->mstatus |= MSTATUS_VS;
724 #endif
726 * The vstart CSR is defined to have only enough writable bits
727 * to hold the largest element index, i.e. lg2(VLEN) bits.
729 env->vstart = val & ~(~0ULL << ctzl(riscv_cpu_cfg(env)->vlen));
730 return RISCV_EXCP_NONE;
733 static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
735 *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
736 return RISCV_EXCP_NONE;
739 static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
741 #if !defined(CONFIG_USER_ONLY)
742 env->mstatus |= MSTATUS_VS;
743 #endif
744 env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
745 env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
746 return RISCV_EXCP_NONE;
749 /* User Timers and Counters */
750 static target_ulong get_ticks(bool shift)
752 int64_t val;
753 target_ulong result;
755 #if !defined(CONFIG_USER_ONLY)
756 if (icount_enabled()) {
757 val = icount_get();
758 } else {
759 val = cpu_get_host_ticks();
761 #else
762 val = cpu_get_host_ticks();
763 #endif
765 if (shift) {
766 result = val >> 32;
767 } else {
768 result = val;
771 return result;
774 #if defined(CONFIG_USER_ONLY)
775 static RISCVException read_time(CPURISCVState *env, int csrno,
776 target_ulong *val)
778 *val = cpu_get_host_ticks();
779 return RISCV_EXCP_NONE;
782 static RISCVException read_timeh(CPURISCVState *env, int csrno,
783 target_ulong *val)
785 *val = cpu_get_host_ticks() >> 32;
786 return RISCV_EXCP_NONE;
789 static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
791 *val = get_ticks(false);
792 return RISCV_EXCP_NONE;
795 static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
797 *val = get_ticks(true);
798 return RISCV_EXCP_NONE;
801 #else /* CONFIG_USER_ONLY */
803 static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
805 int evt_index = csrno - CSR_MCOUNTINHIBIT;
807 *val = env->mhpmevent_val[evt_index];
809 return RISCV_EXCP_NONE;
812 static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
814 int evt_index = csrno - CSR_MCOUNTINHIBIT;
815 uint64_t mhpmevt_val = val;
817 env->mhpmevent_val[evt_index] = val;
819 if (riscv_cpu_mxl(env) == MXL_RV32) {
820 mhpmevt_val = mhpmevt_val |
821 ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
823 riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
825 return RISCV_EXCP_NONE;
828 static int read_mhpmeventh(CPURISCVState *env, int csrno, target_ulong *val)
830 int evt_index = csrno - CSR_MHPMEVENT3H + 3;
832 *val = env->mhpmeventh_val[evt_index];
834 return RISCV_EXCP_NONE;
837 static int write_mhpmeventh(CPURISCVState *env, int csrno, target_ulong val)
839 int evt_index = csrno - CSR_MHPMEVENT3H + 3;
840 uint64_t mhpmevth_val = val;
841 uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
843 mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
844 env->mhpmeventh_val[evt_index] = val;
846 riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
848 return RISCV_EXCP_NONE;
851 static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
853 int ctr_idx = csrno - CSR_MCYCLE;
854 PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
855 uint64_t mhpmctr_val = val;
857 counter->mhpmcounter_val = val;
858 if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
859 riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
860 counter->mhpmcounter_prev = get_ticks(false);
861 if (ctr_idx > 2) {
862 if (riscv_cpu_mxl(env) == MXL_RV32) {
863 mhpmctr_val = mhpmctr_val |
864 ((uint64_t)counter->mhpmcounterh_val << 32);
866 riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
868 } else {
869 /* Other counters can keep incrementing from the given value */
870 counter->mhpmcounter_prev = val;
873 return RISCV_EXCP_NONE;
876 static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
878 int ctr_idx = csrno - CSR_MCYCLEH;
879 PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
880 uint64_t mhpmctr_val = counter->mhpmcounter_val;
881 uint64_t mhpmctrh_val = val;
883 counter->mhpmcounterh_val = val;
884 mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
885 if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
886 riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
887 counter->mhpmcounterh_prev = get_ticks(true);
888 if (ctr_idx > 2) {
889 riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
891 } else {
892 counter->mhpmcounterh_prev = val;
895 return RISCV_EXCP_NONE;
898 static RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
899 bool upper_half, uint32_t ctr_idx)
901 PMUCTRState counter = env->pmu_ctrs[ctr_idx];
902 target_ulong ctr_prev = upper_half ? counter.mhpmcounterh_prev :
903 counter.mhpmcounter_prev;
904 target_ulong ctr_val = upper_half ? counter.mhpmcounterh_val :
905 counter.mhpmcounter_val;
907 if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
909 * Counter should not increment if inhibit bit is set. We can't really
910 * stop the icount counting. Just return the counter value written by
911 * the supervisor to indicate that counter was not incremented.
913 if (!counter.started) {
914 *val = ctr_val;
915 return RISCV_EXCP_NONE;
916 } else {
917 /* Mark that the counter has been stopped */
918 counter.started = false;
923 * The kernel computes the perf delta by subtracting the current value from
924 * the value it initialized previously (ctr_val).
926 if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
927 riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
928 *val = get_ticks(upper_half) - ctr_prev + ctr_val;
929 } else {
930 *val = ctr_val;
933 return RISCV_EXCP_NONE;
936 static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
938 uint16_t ctr_index;
940 if (csrno >= CSR_MCYCLE && csrno <= CSR_MHPMCOUNTER31) {
941 ctr_index = csrno - CSR_MCYCLE;
942 } else if (csrno >= CSR_CYCLE && csrno <= CSR_HPMCOUNTER31) {
943 ctr_index = csrno - CSR_CYCLE;
944 } else {
945 return RISCV_EXCP_ILLEGAL_INST;
948 return riscv_pmu_read_ctr(env, val, false, ctr_index);
951 static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
953 uint16_t ctr_index;
955 if (csrno >= CSR_MCYCLEH && csrno <= CSR_MHPMCOUNTER31H) {
956 ctr_index = csrno - CSR_MCYCLEH;
957 } else if (csrno >= CSR_CYCLEH && csrno <= CSR_HPMCOUNTER31H) {
958 ctr_index = csrno - CSR_CYCLEH;
959 } else {
960 return RISCV_EXCP_ILLEGAL_INST;
963 return riscv_pmu_read_ctr(env, val, true, ctr_index);
966 static int read_scountovf(CPURISCVState *env, int csrno, target_ulong *val)
968 int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
969 int i;
970 *val = 0;
971 target_ulong *mhpm_evt_val;
972 uint64_t of_bit_mask;
974 if (riscv_cpu_mxl(env) == MXL_RV32) {
975 mhpm_evt_val = env->mhpmeventh_val;
976 of_bit_mask = MHPMEVENTH_BIT_OF;
977 } else {
978 mhpm_evt_val = env->mhpmevent_val;
979 of_bit_mask = MHPMEVENT_BIT_OF;
982 for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
983 if ((get_field(env->mcounteren, BIT(i))) &&
984 (mhpm_evt_val[i] & of_bit_mask)) {
985 *val |= BIT(i);
989 return RISCV_EXCP_NONE;
992 static RISCVException read_time(CPURISCVState *env, int csrno,
993 target_ulong *val)
995 uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
997 if (!env->rdtime_fn) {
998 return RISCV_EXCP_ILLEGAL_INST;
1001 *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
1002 return RISCV_EXCP_NONE;
1005 static RISCVException read_timeh(CPURISCVState *env, int csrno,
1006 target_ulong *val)
1008 uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
1010 if (!env->rdtime_fn) {
1011 return RISCV_EXCP_ILLEGAL_INST;
1014 *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
1015 return RISCV_EXCP_NONE;
1018 static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
1019 target_ulong *val)
1021 *val = env->vstimecmp;
1023 return RISCV_EXCP_NONE;
1026 static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
1027 target_ulong *val)
1029 *val = env->vstimecmp >> 32;
1031 return RISCV_EXCP_NONE;
1034 static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
1035 target_ulong val)
1037 if (riscv_cpu_mxl(env) == MXL_RV32) {
1038 env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
1039 } else {
1040 env->vstimecmp = val;
1043 riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
1044 env->htimedelta, MIP_VSTIP);
1046 return RISCV_EXCP_NONE;
1049 static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
1050 target_ulong val)
1052 env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
1053 riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
1054 env->htimedelta, MIP_VSTIP);
1056 return RISCV_EXCP_NONE;
1059 static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
1060 target_ulong *val)
1062 if (env->virt_enabled) {
1063 *val = env->vstimecmp;
1064 } else {
1065 *val = env->stimecmp;
1068 return RISCV_EXCP_NONE;
1071 static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
1072 target_ulong *val)
1074 if (env->virt_enabled) {
1075 *val = env->vstimecmp >> 32;
1076 } else {
1077 *val = env->stimecmp >> 32;
1080 return RISCV_EXCP_NONE;
1083 static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
1084 target_ulong val)
1086 if (env->virt_enabled) {
1087 if (env->hvictl & HVICTL_VTI) {
1088 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1090 return write_vstimecmp(env, csrno, val);
1093 if (riscv_cpu_mxl(env) == MXL_RV32) {
1094 env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
1095 } else {
1096 env->stimecmp = val;
1099 riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
1101 return RISCV_EXCP_NONE;
1104 static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
1105 target_ulong val)
1107 if (env->virt_enabled) {
1108 if (env->hvictl & HVICTL_VTI) {
1109 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1111 return write_vstimecmph(env, csrno, val);
1114 env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
1115 riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
1117 return RISCV_EXCP_NONE;
1120 /* Machine constants */
1122 #define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
1123 #define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP | \
1124 MIP_LCOFIP))
1125 #define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
1126 #define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
1128 #define VSTOPI_NUM_SRCS 5
1130 static const uint64_t delegable_ints = S_MODE_INTERRUPTS |
1131 VS_MODE_INTERRUPTS;
1132 static const uint64_t vs_delegable_ints = VS_MODE_INTERRUPTS;
1133 static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
1134 HS_MODE_INTERRUPTS;
1135 #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
1136 (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
1137 (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
1138 (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
1139 (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
1140 (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
1141 (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
1142 (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
1143 (1ULL << (RISCV_EXCP_U_ECALL)) | \
1144 (1ULL << (RISCV_EXCP_S_ECALL)) | \
1145 (1ULL << (RISCV_EXCP_VS_ECALL)) | \
1146 (1ULL << (RISCV_EXCP_M_ECALL)) | \
1147 (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
1148 (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
1149 (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
1150 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
1151 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
1152 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
1153 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
1154 static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
1155 ~((1ULL << (RISCV_EXCP_S_ECALL)) |
1156 (1ULL << (RISCV_EXCP_VS_ECALL)) |
1157 (1ULL << (RISCV_EXCP_M_ECALL)) |
1158 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
1159 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
1160 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
1161 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
1162 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
1163 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
1164 SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
1165 static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP |
1166 SIP_LCOFIP;
1167 static const target_ulong hip_writable_mask = MIP_VSSIP;
1168 static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP |
1169 MIP_VSEIP;
1170 static const target_ulong vsip_writable_mask = MIP_VSSIP;
1172 const bool valid_vm_1_10_32[16] = {
1173 [VM_1_10_MBARE] = true,
1174 [VM_1_10_SV32] = true
1177 const bool valid_vm_1_10_64[16] = {
1178 [VM_1_10_MBARE] = true,
1179 [VM_1_10_SV39] = true,
1180 [VM_1_10_SV48] = true,
1181 [VM_1_10_SV57] = true
1184 /* Machine Information Registers */
1185 static RISCVException read_zero(CPURISCVState *env, int csrno,
1186 target_ulong *val)
1188 *val = 0;
1189 return RISCV_EXCP_NONE;
1192 static RISCVException write_ignore(CPURISCVState *env, int csrno,
1193 target_ulong val)
1195 return RISCV_EXCP_NONE;
1198 static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
1199 target_ulong *val)
1201 *val = riscv_cpu_cfg(env)->mvendorid;
1202 return RISCV_EXCP_NONE;
1205 static RISCVException read_marchid(CPURISCVState *env, int csrno,
1206 target_ulong *val)
1208 *val = riscv_cpu_cfg(env)->marchid;
1209 return RISCV_EXCP_NONE;
1212 static RISCVException read_mimpid(CPURISCVState *env, int csrno,
1213 target_ulong *val)
1215 *val = riscv_cpu_cfg(env)->mimpid;
1216 return RISCV_EXCP_NONE;
1219 static RISCVException read_mhartid(CPURISCVState *env, int csrno,
1220 target_ulong *val)
1222 *val = env->mhartid;
1223 return RISCV_EXCP_NONE;
1226 /* Machine Trap Setup */
1228 /* We do not store SD explicitly, only compute it on demand. */
1229 static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
1231 if ((status & MSTATUS_FS) == MSTATUS_FS ||
1232 (status & MSTATUS_VS) == MSTATUS_VS ||
1233 (status & MSTATUS_XS) == MSTATUS_XS) {
1234 switch (xl) {
1235 case MXL_RV32:
1236 return status | MSTATUS32_SD;
1237 case MXL_RV64:
1238 return status | MSTATUS64_SD;
1239 case MXL_RV128:
1240 return MSTATUSH128_SD;
1241 default:
1242 g_assert_not_reached();
1245 return status;
1248 static RISCVException read_mstatus(CPURISCVState *env, int csrno,
1249 target_ulong *val)
1251 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
1252 return RISCV_EXCP_NONE;
1255 static bool validate_vm(CPURISCVState *env, target_ulong vm)
1257 return (vm & 0xf) <=
1258 satp_mode_max_from_map(riscv_cpu_cfg(env)->satp_mode.map);
1261 static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
1262 target_ulong val)
1264 bool valid = false;
1265 target_ulong new_mpp = get_field(val, MSTATUS_MPP);
1267 switch (new_mpp) {
1268 case PRV_M:
1269 valid = true;
1270 break;
1271 case PRV_S:
1272 valid = riscv_has_ext(env, RVS);
1273 break;
1274 case PRV_U:
1275 valid = riscv_has_ext(env, RVU);
1276 break;
1279 /* Remain field unchanged if new_mpp value is invalid */
1280 if (!valid) {
1281 val = set_field(val, MSTATUS_MPP, old_mpp);
1284 return val;
1287 static RISCVException write_mstatus(CPURISCVState *env, int csrno,
1288 target_ulong val)
1290 uint64_t mstatus = env->mstatus;
1291 uint64_t mask = 0;
1292 RISCVMXL xl = riscv_cpu_mxl(env);
1295 * MPP field have been made WARL since priv version 1.11. However,
1296 * legalization for it will not break any software running on 1.10.
1298 val = legalize_mpp(env, get_field(mstatus, MSTATUS_MPP), val);
1300 /* flush tlb on mstatus fields that affect VM */
1301 if ((val ^ mstatus) & MSTATUS_MXR) {
1302 tlb_flush(env_cpu(env));
1304 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
1305 MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
1306 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
1307 MSTATUS_TW | MSTATUS_VS;
1309 if (riscv_has_ext(env, RVF)) {
1310 mask |= MSTATUS_FS;
1313 if (xl != MXL_RV32 || env->debugger) {
1314 if (riscv_has_ext(env, RVH)) {
1315 mask |= MSTATUS_MPV | MSTATUS_GVA;
1317 if ((val & MSTATUS64_UXL) != 0) {
1318 mask |= MSTATUS64_UXL;
1322 mstatus = (mstatus & ~mask) | (val & mask);
1324 env->mstatus = mstatus;
1327 * Except in debug mode, UXL/SXL can only be modified by higher
1328 * privilege mode. So xl will not be changed in normal mode.
1330 if (env->debugger) {
1331 env->xl = cpu_recompute_xl(env);
1334 riscv_cpu_update_mask(env);
1335 return RISCV_EXCP_NONE;
1338 static RISCVException read_mstatush(CPURISCVState *env, int csrno,
1339 target_ulong *val)
1341 *val = env->mstatus >> 32;
1342 return RISCV_EXCP_NONE;
1345 static RISCVException write_mstatush(CPURISCVState *env, int csrno,
1346 target_ulong val)
1348 uint64_t valh = (uint64_t)val << 32;
1349 uint64_t mask = riscv_has_ext(env, RVH) ? MSTATUS_MPV | MSTATUS_GVA : 0;
1351 env->mstatus = (env->mstatus & ~mask) | (valh & mask);
1353 return RISCV_EXCP_NONE;
1356 static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
1357 Int128 *val)
1359 *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128,
1360 env->mstatus));
1361 return RISCV_EXCP_NONE;
1364 static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
1365 Int128 *val)
1367 *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
1368 return RISCV_EXCP_NONE;
1371 static RISCVException read_misa(CPURISCVState *env, int csrno,
1372 target_ulong *val)
1374 target_ulong misa;
1376 switch (env->misa_mxl) {
1377 case MXL_RV32:
1378 misa = (target_ulong)MXL_RV32 << 30;
1379 break;
1380 #ifdef TARGET_RISCV64
1381 case MXL_RV64:
1382 misa = (target_ulong)MXL_RV64 << 62;
1383 break;
1384 #endif
1385 default:
1386 g_assert_not_reached();
1389 *val = misa | env->misa_ext;
1390 return RISCV_EXCP_NONE;
1393 static RISCVException write_misa(CPURISCVState *env, int csrno,
1394 target_ulong val)
1396 RISCVCPU *cpu = env_archcpu(env);
1397 uint32_t orig_misa_ext = env->misa_ext;
1398 Error *local_err = NULL;
1400 if (!riscv_cpu_cfg(env)->misa_w) {
1401 /* drop write to misa */
1402 return RISCV_EXCP_NONE;
1405 /* Mask extensions that are not supported by this hart */
1406 val &= env->misa_ext_mask;
1409 * Suppress 'C' if next instruction is not aligned
1410 * TODO: this should check next_pc
1412 if ((val & RVC) && (GETPC() & ~3) != 0) {
1413 val &= ~RVC;
1416 /* Disable RVG if any of its dependencies are disabled */
1417 if (!(val & RVI && val & RVM && val & RVA &&
1418 val & RVF && val & RVD)) {
1419 val &= ~RVG;
1422 /* If nothing changed, do nothing. */
1423 if (val == env->misa_ext) {
1424 return RISCV_EXCP_NONE;
1427 env->misa_ext = val;
1428 riscv_cpu_validate_set_extensions(cpu, &local_err);
1429 if (local_err != NULL) {
1430 /* Rollback on validation error */
1431 qemu_log_mask(LOG_GUEST_ERROR, "Unable to write MISA ext value "
1432 "0x%x, keeping existing MISA ext 0x%x\n",
1433 env->misa_ext, orig_misa_ext);
1435 env->misa_ext = orig_misa_ext;
1437 return RISCV_EXCP_NONE;
1440 if (!(env->misa_ext & RVF)) {
1441 env->mstatus &= ~MSTATUS_FS;
1444 /* flush translation cache */
1445 tb_flush(env_cpu(env));
1446 env->xl = riscv_cpu_mxl(env);
1447 return RISCV_EXCP_NONE;
1450 static RISCVException read_medeleg(CPURISCVState *env, int csrno,
1451 target_ulong *val)
1453 *val = env->medeleg;
1454 return RISCV_EXCP_NONE;
1457 static RISCVException write_medeleg(CPURISCVState *env, int csrno,
1458 target_ulong val)
1460 env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
1461 return RISCV_EXCP_NONE;
1464 static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
1465 uint64_t *ret_val,
1466 uint64_t new_val, uint64_t wr_mask)
1468 uint64_t mask = wr_mask & delegable_ints;
1470 if (ret_val) {
1471 *ret_val = env->mideleg;
1474 env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
1476 if (riscv_has_ext(env, RVH)) {
1477 env->mideleg |= HS_MODE_INTERRUPTS;
1480 return RISCV_EXCP_NONE;
1483 static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
1484 target_ulong *ret_val,
1485 target_ulong new_val, target_ulong wr_mask)
1487 uint64_t rval;
1488 RISCVException ret;
1490 ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
1491 if (ret_val) {
1492 *ret_val = rval;
1495 return ret;
1498 static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
1499 target_ulong *ret_val,
1500 target_ulong new_val,
1501 target_ulong wr_mask)
1503 uint64_t rval;
1504 RISCVException ret;
1506 ret = rmw_mideleg64(env, csrno, &rval,
1507 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1508 if (ret_val) {
1509 *ret_val = rval >> 32;
1512 return ret;
1515 static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
1516 uint64_t *ret_val,
1517 uint64_t new_val, uint64_t wr_mask)
1519 uint64_t mask = wr_mask & all_ints;
1521 if (ret_val) {
1522 *ret_val = env->mie;
1525 env->mie = (env->mie & ~mask) | (new_val & mask);
1527 if (!riscv_has_ext(env, RVH)) {
1528 env->mie &= ~((uint64_t)MIP_SGEIP);
1531 return RISCV_EXCP_NONE;
1534 static RISCVException rmw_mie(CPURISCVState *env, int csrno,
1535 target_ulong *ret_val,
1536 target_ulong new_val, target_ulong wr_mask)
1538 uint64_t rval;
1539 RISCVException ret;
1541 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
1542 if (ret_val) {
1543 *ret_val = rval;
1546 return ret;
1549 static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
1550 target_ulong *ret_val,
1551 target_ulong new_val, target_ulong wr_mask)
1553 uint64_t rval;
1554 RISCVException ret;
1556 ret = rmw_mie64(env, csrno, &rval,
1557 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1558 if (ret_val) {
1559 *ret_val = rval >> 32;
1562 return ret;
1565 static int read_mtopi(CPURISCVState *env, int csrno, target_ulong *val)
1567 int irq;
1568 uint8_t iprio;
1570 irq = riscv_cpu_mirq_pending(env);
1571 if (irq <= 0 || irq > 63) {
1572 *val = 0;
1573 } else {
1574 iprio = env->miprio[irq];
1575 if (!iprio) {
1576 if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) {
1577 iprio = IPRIO_MMAXIPRIO;
1580 *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
1581 *val |= iprio;
1584 return RISCV_EXCP_NONE;
1587 static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
1589 if (!env->virt_enabled) {
1590 return csrno;
1593 switch (csrno) {
1594 case CSR_SISELECT:
1595 return CSR_VSISELECT;
1596 case CSR_SIREG:
1597 return CSR_VSIREG;
1598 case CSR_STOPEI:
1599 return CSR_VSTOPEI;
1600 default:
1601 return csrno;
1605 static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
1606 target_ulong new_val, target_ulong wr_mask)
1608 target_ulong *iselect;
1610 /* Translate CSR number for VS-mode */
1611 csrno = aia_xlate_vs_csrno(env, csrno);
1613 /* Find the iselect CSR based on CSR number */
1614 switch (csrno) {
1615 case CSR_MISELECT:
1616 iselect = &env->miselect;
1617 break;
1618 case CSR_SISELECT:
1619 iselect = &env->siselect;
1620 break;
1621 case CSR_VSISELECT:
1622 iselect = &env->vsiselect;
1623 break;
1624 default:
1625 return RISCV_EXCP_ILLEGAL_INST;
1628 if (val) {
1629 *val = *iselect;
1632 wr_mask &= ISELECT_MASK;
1633 if (wr_mask) {
1634 *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
1637 return RISCV_EXCP_NONE;
1640 static int rmw_iprio(target_ulong xlen,
1641 target_ulong iselect, uint8_t *iprio,
1642 target_ulong *val, target_ulong new_val,
1643 target_ulong wr_mask, int ext_irq_no)
1645 int i, firq, nirqs;
1646 target_ulong old_val;
1648 if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
1649 return -EINVAL;
1651 if (xlen != 32 && iselect & 0x1) {
1652 return -EINVAL;
1655 nirqs = 4 * (xlen / 32);
1656 firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
1658 old_val = 0;
1659 for (i = 0; i < nirqs; i++) {
1660 old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i);
1663 if (val) {
1664 *val = old_val;
1667 if (wr_mask) {
1668 new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
1669 for (i = 0; i < nirqs; i++) {
1671 * M-level and S-level external IRQ priority always read-only
1672 * zero. This means default priority order is always preferred
1673 * for M-level and S-level external IRQs.
1675 if ((firq + i) == ext_irq_no) {
1676 continue;
1678 iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
1682 return 0;
1685 static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
1686 target_ulong new_val, target_ulong wr_mask)
1688 bool virt;
1689 uint8_t *iprio;
1690 int ret = -EINVAL;
1691 target_ulong priv, isel, vgein;
1693 /* Translate CSR number for VS-mode */
1694 csrno = aia_xlate_vs_csrno(env, csrno);
1696 /* Decode register details from CSR number */
1697 virt = false;
1698 switch (csrno) {
1699 case CSR_MIREG:
1700 iprio = env->miprio;
1701 isel = env->miselect;
1702 priv = PRV_M;
1703 break;
1704 case CSR_SIREG:
1705 iprio = env->siprio;
1706 isel = env->siselect;
1707 priv = PRV_S;
1708 break;
1709 case CSR_VSIREG:
1710 iprio = env->hviprio;
1711 isel = env->vsiselect;
1712 priv = PRV_S;
1713 virt = true;
1714 break;
1715 default:
1716 goto done;
1719 /* Find the selected guest interrupt file */
1720 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1722 if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
1723 /* Local interrupt priority registers not available for VS-mode */
1724 if (!virt) {
1725 ret = rmw_iprio(riscv_cpu_mxl_bits(env),
1726 isel, iprio, val, new_val, wr_mask,
1727 (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
1729 } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) {
1730 /* IMSIC registers only available when machine implements it. */
1731 if (env->aia_ireg_rmw_fn[priv]) {
1732 /* Selected guest interrupt file should not be zero */
1733 if (virt && (!vgein || env->geilen < vgein)) {
1734 goto done;
1736 /* Call machine specific IMSIC register emulation */
1737 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1738 AIA_MAKE_IREG(isel, priv, virt, vgein,
1739 riscv_cpu_mxl_bits(env)),
1740 val, new_val, wr_mask);
1744 done:
1745 if (ret) {
1746 return (env->virt_enabled && virt) ?
1747 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1749 return RISCV_EXCP_NONE;
1752 static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
1753 target_ulong new_val, target_ulong wr_mask)
1755 bool virt;
1756 int ret = -EINVAL;
1757 target_ulong priv, vgein;
1759 /* Translate CSR number for VS-mode */
1760 csrno = aia_xlate_vs_csrno(env, csrno);
1762 /* Decode register details from CSR number */
1763 virt = false;
1764 switch (csrno) {
1765 case CSR_MTOPEI:
1766 priv = PRV_M;
1767 break;
1768 case CSR_STOPEI:
1769 priv = PRV_S;
1770 break;
1771 case CSR_VSTOPEI:
1772 priv = PRV_S;
1773 virt = true;
1774 break;
1775 default:
1776 goto done;
1779 /* IMSIC CSRs only available when machine implements IMSIC. */
1780 if (!env->aia_ireg_rmw_fn[priv]) {
1781 goto done;
1784 /* Find the selected guest interrupt file */
1785 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1787 /* Selected guest interrupt file should be valid */
1788 if (virt && (!vgein || env->geilen < vgein)) {
1789 goto done;
1792 /* Call machine specific IMSIC register emulation for TOPEI */
1793 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1794 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein,
1795 riscv_cpu_mxl_bits(env)),
1796 val, new_val, wr_mask);
1798 done:
1799 if (ret) {
1800 return (env->virt_enabled && virt) ?
1801 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1803 return RISCV_EXCP_NONE;
1806 static RISCVException read_mtvec(CPURISCVState *env, int csrno,
1807 target_ulong *val)
1809 *val = env->mtvec;
1810 return RISCV_EXCP_NONE;
1813 static RISCVException write_mtvec(CPURISCVState *env, int csrno,
1814 target_ulong val)
1816 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
1817 if ((val & 3) < 2) {
1818 env->mtvec = val;
1819 } else {
1820 qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
1822 return RISCV_EXCP_NONE;
1825 static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
1826 target_ulong *val)
1828 *val = env->mcountinhibit;
1829 return RISCV_EXCP_NONE;
1832 static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
1833 target_ulong val)
1835 int cidx;
1836 PMUCTRState *counter;
1838 env->mcountinhibit = val;
1840 /* Check if any other counter is also monitoring cycles/instructions */
1841 for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
1842 if (!get_field(env->mcountinhibit, BIT(cidx))) {
1843 counter = &env->pmu_ctrs[cidx];
1844 counter->started = true;
1848 return RISCV_EXCP_NONE;
1851 static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
1852 target_ulong *val)
1854 *val = env->mcounteren;
1855 return RISCV_EXCP_NONE;
1858 static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
1859 target_ulong val)
1861 env->mcounteren = val;
1862 return RISCV_EXCP_NONE;
1865 /* Machine Trap Handling */
1866 static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
1867 Int128 *val)
1869 *val = int128_make128(env->mscratch, env->mscratchh);
1870 return RISCV_EXCP_NONE;
1873 static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
1874 Int128 val)
1876 env->mscratch = int128_getlo(val);
1877 env->mscratchh = int128_gethi(val);
1878 return RISCV_EXCP_NONE;
1881 static RISCVException read_mscratch(CPURISCVState *env, int csrno,
1882 target_ulong *val)
1884 *val = env->mscratch;
1885 return RISCV_EXCP_NONE;
1888 static RISCVException write_mscratch(CPURISCVState *env, int csrno,
1889 target_ulong val)
1891 env->mscratch = val;
1892 return RISCV_EXCP_NONE;
1895 static RISCVException read_mepc(CPURISCVState *env, int csrno,
1896 target_ulong *val)
1898 *val = env->mepc;
1899 return RISCV_EXCP_NONE;
1902 static RISCVException write_mepc(CPURISCVState *env, int csrno,
1903 target_ulong val)
1905 env->mepc = val;
1906 return RISCV_EXCP_NONE;
1909 static RISCVException read_mcause(CPURISCVState *env, int csrno,
1910 target_ulong *val)
1912 *val = env->mcause;
1913 return RISCV_EXCP_NONE;
1916 static RISCVException write_mcause(CPURISCVState *env, int csrno,
1917 target_ulong val)
1919 env->mcause = val;
1920 return RISCV_EXCP_NONE;
1923 static RISCVException read_mtval(CPURISCVState *env, int csrno,
1924 target_ulong *val)
1926 *val = env->mtval;
1927 return RISCV_EXCP_NONE;
1930 static RISCVException write_mtval(CPURISCVState *env, int csrno,
1931 target_ulong val)
1933 env->mtval = val;
1934 return RISCV_EXCP_NONE;
1937 /* Execution environment configuration setup */
1938 static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
1939 target_ulong *val)
1941 *val = env->menvcfg;
1942 return RISCV_EXCP_NONE;
1945 static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
1946 target_ulong val)
1948 const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
1949 uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
1951 if (riscv_cpu_mxl(env) == MXL_RV64) {
1952 mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
1953 (cfg->ext_sstc ? MENVCFG_STCE : 0) |
1954 (cfg->ext_svadu ? MENVCFG_HADE : 0);
1956 env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
1958 return RISCV_EXCP_NONE;
1961 static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
1962 target_ulong *val)
1964 *val = env->menvcfg >> 32;
1965 return RISCV_EXCP_NONE;
1968 static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
1969 target_ulong val)
1971 const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
1972 uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
1973 (cfg->ext_sstc ? MENVCFG_STCE : 0) |
1974 (cfg->ext_svadu ? MENVCFG_HADE : 0);
1975 uint64_t valh = (uint64_t)val << 32;
1977 env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
1979 return RISCV_EXCP_NONE;
1982 static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
1983 target_ulong *val)
1985 RISCVException ret;
1987 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
1988 if (ret != RISCV_EXCP_NONE) {
1989 return ret;
1992 *val = env->senvcfg;
1993 return RISCV_EXCP_NONE;
1996 static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
1997 target_ulong val)
1999 uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
2000 RISCVException ret;
2002 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2003 if (ret != RISCV_EXCP_NONE) {
2004 return ret;
2007 env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
2008 return RISCV_EXCP_NONE;
2011 static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
2012 target_ulong *val)
2014 RISCVException ret;
2016 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2017 if (ret != RISCV_EXCP_NONE) {
2018 return ret;
2022 * henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
2023 * henvcfg.stce is read_only 0 when menvcfg.stce = 0
2024 * henvcfg.hade is read_only 0 when menvcfg.hade = 0
2026 *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
2027 env->menvcfg);
2028 return RISCV_EXCP_NONE;
2031 static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
2032 target_ulong val)
2034 uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
2035 RISCVException ret;
2037 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2038 if (ret != RISCV_EXCP_NONE) {
2039 return ret;
2042 if (riscv_cpu_mxl(env) == MXL_RV64) {
2043 mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE);
2046 env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
2048 return RISCV_EXCP_NONE;
2051 static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
2052 target_ulong *val)
2054 RISCVException ret;
2056 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2057 if (ret != RISCV_EXCP_NONE) {
2058 return ret;
2061 *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
2062 env->menvcfg)) >> 32;
2063 return RISCV_EXCP_NONE;
2066 static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
2067 target_ulong val)
2069 uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
2070 HENVCFG_HADE);
2071 uint64_t valh = (uint64_t)val << 32;
2072 RISCVException ret;
2074 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2075 if (ret != RISCV_EXCP_NONE) {
2076 return ret;
2079 env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
2080 return RISCV_EXCP_NONE;
2083 static RISCVException read_mstateen(CPURISCVState *env, int csrno,
2084 target_ulong *val)
2086 *val = env->mstateen[csrno - CSR_MSTATEEN0];
2088 return RISCV_EXCP_NONE;
2091 static RISCVException write_mstateen(CPURISCVState *env, int csrno,
2092 uint64_t wr_mask, target_ulong new_val)
2094 uint64_t *reg;
2096 reg = &env->mstateen[csrno - CSR_MSTATEEN0];
2097 *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2099 return RISCV_EXCP_NONE;
2102 static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
2103 target_ulong new_val)
2105 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2106 if (!riscv_has_ext(env, RVF)) {
2107 wr_mask |= SMSTATEEN0_FCSR;
2110 return write_mstateen(env, csrno, wr_mask, new_val);
2113 static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
2114 target_ulong new_val)
2116 return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2119 static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
2120 target_ulong *val)
2122 *val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
2124 return RISCV_EXCP_NONE;
2127 static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
2128 uint64_t wr_mask, target_ulong new_val)
2130 uint64_t *reg, val;
2132 reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
2133 val = (uint64_t)new_val << 32;
2134 val |= *reg & 0xFFFFFFFF;
2135 *reg = (*reg & ~wr_mask) | (val & wr_mask);
2137 return RISCV_EXCP_NONE;
2140 static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
2141 target_ulong new_val)
2143 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2145 return write_mstateenh(env, csrno, wr_mask, new_val);
2148 static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
2149 target_ulong new_val)
2151 return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
2154 static RISCVException read_hstateen(CPURISCVState *env, int csrno,
2155 target_ulong *val)
2157 int index = csrno - CSR_HSTATEEN0;
2159 *val = env->hstateen[index] & env->mstateen[index];
2161 return RISCV_EXCP_NONE;
2164 static RISCVException write_hstateen(CPURISCVState *env, int csrno,
2165 uint64_t mask, target_ulong new_val)
2167 int index = csrno - CSR_HSTATEEN0;
2168 uint64_t *reg, wr_mask;
2170 reg = &env->hstateen[index];
2171 wr_mask = env->mstateen[index] & mask;
2172 *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2174 return RISCV_EXCP_NONE;
2177 static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
2178 target_ulong new_val)
2180 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2182 if (!riscv_has_ext(env, RVF)) {
2183 wr_mask |= SMSTATEEN0_FCSR;
2186 return write_hstateen(env, csrno, wr_mask, new_val);
2189 static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
2190 target_ulong new_val)
2192 return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2195 static RISCVException read_hstateenh(CPURISCVState *env, int csrno,
2196 target_ulong *val)
2198 int index = csrno - CSR_HSTATEEN0H;
2200 *val = (env->hstateen[index] >> 32) & (env->mstateen[index] >> 32);
2202 return RISCV_EXCP_NONE;
2205 static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
2206 uint64_t mask, target_ulong new_val)
2208 int index = csrno - CSR_HSTATEEN0H;
2209 uint64_t *reg, wr_mask, val;
2211 reg = &env->hstateen[index];
2212 val = (uint64_t)new_val << 32;
2213 val |= *reg & 0xFFFFFFFF;
2214 wr_mask = env->mstateen[index] & mask;
2215 *reg = (*reg & ~wr_mask) | (val & wr_mask);
2217 return RISCV_EXCP_NONE;
2220 static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
2221 target_ulong new_val)
2223 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2225 return write_hstateenh(env, csrno, wr_mask, new_val);
2228 static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
2229 target_ulong new_val)
2231 return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
2234 static RISCVException read_sstateen(CPURISCVState *env, int csrno,
2235 target_ulong *val)
2237 bool virt = env->virt_enabled;
2238 int index = csrno - CSR_SSTATEEN0;
2240 *val = env->sstateen[index] & env->mstateen[index];
2241 if (virt) {
2242 *val &= env->hstateen[index];
2245 return RISCV_EXCP_NONE;
2248 static RISCVException write_sstateen(CPURISCVState *env, int csrno,
2249 uint64_t mask, target_ulong new_val)
2251 bool virt = env->virt_enabled;
2252 int index = csrno - CSR_SSTATEEN0;
2253 uint64_t wr_mask;
2254 uint64_t *reg;
2256 wr_mask = env->mstateen[index] & mask;
2257 if (virt) {
2258 wr_mask &= env->hstateen[index];
2261 reg = &env->sstateen[index];
2262 *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2264 return RISCV_EXCP_NONE;
2267 static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
2268 target_ulong new_val)
2270 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2272 if (!riscv_has_ext(env, RVF)) {
2273 wr_mask |= SMSTATEEN0_FCSR;
2276 return write_sstateen(env, csrno, wr_mask, new_val);
2279 static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
2280 target_ulong new_val)
2282 return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2285 static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
2286 uint64_t *ret_val,
2287 uint64_t new_val, uint64_t wr_mask)
2289 uint64_t old_mip, mask = wr_mask & delegable_ints;
2290 uint32_t gin;
2292 if (mask & MIP_SEIP) {
2293 env->software_seip = new_val & MIP_SEIP;
2294 new_val |= env->external_seip * MIP_SEIP;
2297 if (riscv_cpu_cfg(env)->ext_sstc && (env->priv == PRV_M) &&
2298 get_field(env->menvcfg, MENVCFG_STCE)) {
2299 /* sstc extension forbids STIP & VSTIP to be writeable in mip */
2300 mask = mask & ~(MIP_STIP | MIP_VSTIP);
2303 if (mask) {
2304 old_mip = riscv_cpu_update_mip(env, mask, (new_val & mask));
2305 } else {
2306 old_mip = env->mip;
2309 if (csrno != CSR_HVIP) {
2310 gin = get_field(env->hstatus, HSTATUS_VGEIN);
2311 old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
2312 old_mip |= env->vstime_irq ? MIP_VSTIP : 0;
2315 if (ret_val) {
2316 *ret_val = old_mip;
2319 return RISCV_EXCP_NONE;
2322 static RISCVException rmw_mip(CPURISCVState *env, int csrno,
2323 target_ulong *ret_val,
2324 target_ulong new_val, target_ulong wr_mask)
2326 uint64_t rval;
2327 RISCVException ret;
2329 ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
2330 if (ret_val) {
2331 *ret_val = rval;
2334 return ret;
2337 static RISCVException rmw_miph(CPURISCVState *env, int csrno,
2338 target_ulong *ret_val,
2339 target_ulong new_val, target_ulong wr_mask)
2341 uint64_t rval;
2342 RISCVException ret;
2344 ret = rmw_mip64(env, csrno, &rval,
2345 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2346 if (ret_val) {
2347 *ret_val = rval >> 32;
2350 return ret;
2353 /* Supervisor Trap Setup */
2354 static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
2355 Int128 *val)
2357 uint64_t mask = sstatus_v1_10_mask;
2358 uint64_t sstatus = env->mstatus & mask;
2359 if (env->xl != MXL_RV32 || env->debugger) {
2360 mask |= SSTATUS64_UXL;
2363 *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
2364 return RISCV_EXCP_NONE;
2367 static RISCVException read_sstatus(CPURISCVState *env, int csrno,
2368 target_ulong *val)
2370 target_ulong mask = (sstatus_v1_10_mask);
2371 if (env->xl != MXL_RV32 || env->debugger) {
2372 mask |= SSTATUS64_UXL;
2374 /* TODO: Use SXL not MXL. */
2375 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
2376 return RISCV_EXCP_NONE;
2379 static RISCVException write_sstatus(CPURISCVState *env, int csrno,
2380 target_ulong val)
2382 target_ulong mask = (sstatus_v1_10_mask);
2384 if (env->xl != MXL_RV32 || env->debugger) {
2385 if ((val & SSTATUS64_UXL) != 0) {
2386 mask |= SSTATUS64_UXL;
2389 target_ulong newval = (env->mstatus & ~mask) | (val & mask);
2390 return write_mstatus(env, CSR_MSTATUS, newval);
2393 static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
2394 uint64_t *ret_val,
2395 uint64_t new_val, uint64_t wr_mask)
2397 RISCVException ret;
2398 uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
2400 /* Bring VS-level bits to correct position */
2401 new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1;
2402 wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1;
2404 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask);
2405 if (ret_val) {
2406 *ret_val = (rval & mask) >> 1;
2409 return ret;
2412 static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
2413 target_ulong *ret_val,
2414 target_ulong new_val, target_ulong wr_mask)
2416 uint64_t rval;
2417 RISCVException ret;
2419 ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
2420 if (ret_val) {
2421 *ret_val = rval;
2424 return ret;
2427 static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
2428 target_ulong *ret_val,
2429 target_ulong new_val, target_ulong wr_mask)
2431 uint64_t rval;
2432 RISCVException ret;
2434 ret = rmw_vsie64(env, csrno, &rval,
2435 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2436 if (ret_val) {
2437 *ret_val = rval >> 32;
2440 return ret;
2443 static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
2444 uint64_t *ret_val,
2445 uint64_t new_val, uint64_t wr_mask)
2447 RISCVException ret;
2448 uint64_t mask = env->mideleg & S_MODE_INTERRUPTS;
2450 if (env->virt_enabled) {
2451 if (env->hvictl & HVICTL_VTI) {
2452 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
2454 ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
2455 } else {
2456 ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask);
2459 if (ret_val) {
2460 *ret_val &= mask;
2463 return ret;
2466 static RISCVException rmw_sie(CPURISCVState *env, int csrno,
2467 target_ulong *ret_val,
2468 target_ulong new_val, target_ulong wr_mask)
2470 uint64_t rval;
2471 RISCVException ret;
2473 ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
2474 if (ret == RISCV_EXCP_NONE && ret_val) {
2475 *ret_val = rval;
2478 return ret;
2481 static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
2482 target_ulong *ret_val,
2483 target_ulong new_val, target_ulong wr_mask)
2485 uint64_t rval;
2486 RISCVException ret;
2488 ret = rmw_sie64(env, csrno, &rval,
2489 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2490 if (ret_val) {
2491 *ret_val = rval >> 32;
2494 return ret;
2497 static RISCVException read_stvec(CPURISCVState *env, int csrno,
2498 target_ulong *val)
2500 *val = env->stvec;
2501 return RISCV_EXCP_NONE;
2504 static RISCVException write_stvec(CPURISCVState *env, int csrno,
2505 target_ulong val)
2507 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
2508 if ((val & 3) < 2) {
2509 env->stvec = val;
2510 } else {
2511 qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
2513 return RISCV_EXCP_NONE;
2516 static RISCVException read_scounteren(CPURISCVState *env, int csrno,
2517 target_ulong *val)
2519 *val = env->scounteren;
2520 return RISCV_EXCP_NONE;
2523 static RISCVException write_scounteren(CPURISCVState *env, int csrno,
2524 target_ulong val)
2526 env->scounteren = val;
2527 return RISCV_EXCP_NONE;
2530 /* Supervisor Trap Handling */
2531 static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
2532 Int128 *val)
2534 *val = int128_make128(env->sscratch, env->sscratchh);
2535 return RISCV_EXCP_NONE;
2538 static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
2539 Int128 val)
2541 env->sscratch = int128_getlo(val);
2542 env->sscratchh = int128_gethi(val);
2543 return RISCV_EXCP_NONE;
2546 static RISCVException read_sscratch(CPURISCVState *env, int csrno,
2547 target_ulong *val)
2549 *val = env->sscratch;
2550 return RISCV_EXCP_NONE;
2553 static RISCVException write_sscratch(CPURISCVState *env, int csrno,
2554 target_ulong val)
2556 env->sscratch = val;
2557 return RISCV_EXCP_NONE;
2560 static RISCVException read_sepc(CPURISCVState *env, int csrno,
2561 target_ulong *val)
2563 *val = env->sepc;
2564 return RISCV_EXCP_NONE;
2567 static RISCVException write_sepc(CPURISCVState *env, int csrno,
2568 target_ulong val)
2570 env->sepc = val;
2571 return RISCV_EXCP_NONE;
2574 static RISCVException read_scause(CPURISCVState *env, int csrno,
2575 target_ulong *val)
2577 *val = env->scause;
2578 return RISCV_EXCP_NONE;
2581 static RISCVException write_scause(CPURISCVState *env, int csrno,
2582 target_ulong val)
2584 env->scause = val;
2585 return RISCV_EXCP_NONE;
2588 static RISCVException read_stval(CPURISCVState *env, int csrno,
2589 target_ulong *val)
2591 *val = env->stval;
2592 return RISCV_EXCP_NONE;
2595 static RISCVException write_stval(CPURISCVState *env, int csrno,
2596 target_ulong val)
2598 env->stval = val;
2599 return RISCV_EXCP_NONE;
2602 static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
2603 uint64_t *ret_val,
2604 uint64_t new_val, uint64_t wr_mask)
2606 RISCVException ret;
2607 uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
2609 /* Bring VS-level bits to correct position */
2610 new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1;
2611 wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1;
2613 ret = rmw_mip64(env, csrno, &rval, new_val,
2614 wr_mask & mask & vsip_writable_mask);
2615 if (ret_val) {
2616 *ret_val = (rval & mask) >> 1;
2619 return ret;
2622 static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
2623 target_ulong *ret_val,
2624 target_ulong new_val, target_ulong wr_mask)
2626 uint64_t rval;
2627 RISCVException ret;
2629 ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
2630 if (ret_val) {
2631 *ret_val = rval;
2634 return ret;
2637 static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
2638 target_ulong *ret_val,
2639 target_ulong new_val, target_ulong wr_mask)
2641 uint64_t rval;
2642 RISCVException ret;
2644 ret = rmw_vsip64(env, csrno, &rval,
2645 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2646 if (ret_val) {
2647 *ret_val = rval >> 32;
2650 return ret;
2653 static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
2654 uint64_t *ret_val,
2655 uint64_t new_val, uint64_t wr_mask)
2657 RISCVException ret;
2658 uint64_t mask = env->mideleg & sip_writable_mask;
2660 if (env->virt_enabled) {
2661 if (env->hvictl & HVICTL_VTI) {
2662 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
2664 ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
2665 } else {
2666 ret = rmw_mip64(env, csrno, ret_val, new_val, wr_mask & mask);
2669 if (ret_val) {
2670 *ret_val &= env->mideleg & S_MODE_INTERRUPTS;
2673 return ret;
2676 static RISCVException rmw_sip(CPURISCVState *env, int csrno,
2677 target_ulong *ret_val,
2678 target_ulong new_val, target_ulong wr_mask)
2680 uint64_t rval;
2681 RISCVException ret;
2683 ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
2684 if (ret_val) {
2685 *ret_val = rval;
2688 return ret;
2691 static RISCVException rmw_siph(CPURISCVState *env, int csrno,
2692 target_ulong *ret_val,
2693 target_ulong new_val, target_ulong wr_mask)
2695 uint64_t rval;
2696 RISCVException ret;
2698 ret = rmw_sip64(env, csrno, &rval,
2699 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2700 if (ret_val) {
2701 *ret_val = rval >> 32;
2704 return ret;
2707 /* Supervisor Protection and Translation */
2708 static RISCVException read_satp(CPURISCVState *env, int csrno,
2709 target_ulong *val)
2711 if (!riscv_cpu_cfg(env)->mmu) {
2712 *val = 0;
2713 return RISCV_EXCP_NONE;
2715 *val = env->satp;
2716 return RISCV_EXCP_NONE;
2719 static RISCVException write_satp(CPURISCVState *env, int csrno,
2720 target_ulong val)
2722 target_ulong mask;
2723 bool vm;
2725 if (!riscv_cpu_cfg(env)->mmu) {
2726 return RISCV_EXCP_NONE;
2729 if (riscv_cpu_mxl(env) == MXL_RV32) {
2730 vm = validate_vm(env, get_field(val, SATP32_MODE));
2731 mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
2732 } else {
2733 vm = validate_vm(env, get_field(val, SATP64_MODE));
2734 mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
2737 if (vm && mask) {
2739 * The ISA defines SATP.MODE=Bare as "no translation", but we still
2740 * pass these through QEMU's TLB emulation as it improves
2741 * performance. Flushing the TLB on SATP writes with paging
2742 * enabled avoids leaking those invalid cached mappings.
2744 tlb_flush(env_cpu(env));
2745 env->satp = val;
2747 return RISCV_EXCP_NONE;
2750 static int read_vstopi(CPURISCVState *env, int csrno, target_ulong *val)
2752 int irq, ret;
2753 target_ulong topei;
2754 uint64_t vseip, vsgein;
2755 uint32_t iid, iprio, hviid, hviprio, gein;
2756 uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS];
2758 gein = get_field(env->hstatus, HSTATUS_VGEIN);
2759 hviid = get_field(env->hvictl, HVICTL_IID);
2760 hviprio = get_field(env->hvictl, HVICTL_IPRIO);
2762 if (gein) {
2763 vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
2764 vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP;
2765 if (gein <= env->geilen && vseip) {
2766 siid[scount] = IRQ_S_EXT;
2767 siprio[scount] = IPRIO_MMAXIPRIO + 1;
2768 if (env->aia_ireg_rmw_fn[PRV_S]) {
2770 * Call machine specific IMSIC register emulation for
2771 * reading TOPEI.
2773 ret = env->aia_ireg_rmw_fn[PRV_S](
2774 env->aia_ireg_rmw_fn_arg[PRV_S],
2775 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein,
2776 riscv_cpu_mxl_bits(env)),
2777 &topei, 0, 0);
2778 if (!ret && topei) {
2779 siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK;
2782 scount++;
2784 } else {
2785 if (hviid == IRQ_S_EXT && hviprio) {
2786 siid[scount] = IRQ_S_EXT;
2787 siprio[scount] = hviprio;
2788 scount++;
2792 if (env->hvictl & HVICTL_VTI) {
2793 if (hviid != IRQ_S_EXT) {
2794 siid[scount] = hviid;
2795 siprio[scount] = hviprio;
2796 scount++;
2798 } else {
2799 irq = riscv_cpu_vsirq_pending(env);
2800 if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) {
2801 siid[scount] = irq;
2802 siprio[scount] = env->hviprio[irq];
2803 scount++;
2807 iid = 0;
2808 iprio = UINT_MAX;
2809 for (s = 0; s < scount; s++) {
2810 if (siprio[s] < iprio) {
2811 iid = siid[s];
2812 iprio = siprio[s];
2816 if (iid) {
2817 if (env->hvictl & HVICTL_IPRIOM) {
2818 if (iprio > IPRIO_MMAXIPRIO) {
2819 iprio = IPRIO_MMAXIPRIO;
2821 if (!iprio) {
2822 if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) {
2823 iprio = IPRIO_MMAXIPRIO;
2826 } else {
2827 iprio = 1;
2829 } else {
2830 iprio = 0;
2833 *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2834 *val |= iprio;
2835 return RISCV_EXCP_NONE;
2838 static int read_stopi(CPURISCVState *env, int csrno, target_ulong *val)
2840 int irq;
2841 uint8_t iprio;
2843 if (env->virt_enabled) {
2844 return read_vstopi(env, CSR_VSTOPI, val);
2847 irq = riscv_cpu_sirq_pending(env);
2848 if (irq <= 0 || irq > 63) {
2849 *val = 0;
2850 } else {
2851 iprio = env->siprio[irq];
2852 if (!iprio) {
2853 if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) {
2854 iprio = IPRIO_MMAXIPRIO;
2857 *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2858 *val |= iprio;
2861 return RISCV_EXCP_NONE;
2864 /* Hypervisor Extensions */
2865 static RISCVException read_hstatus(CPURISCVState *env, int csrno,
2866 target_ulong *val)
2868 *val = env->hstatus;
2869 if (riscv_cpu_mxl(env) != MXL_RV32) {
2870 /* We only support 64-bit VSXL */
2871 *val = set_field(*val, HSTATUS_VSXL, 2);
2873 /* We only support little endian */
2874 *val = set_field(*val, HSTATUS_VSBE, 0);
2875 return RISCV_EXCP_NONE;
2878 static RISCVException write_hstatus(CPURISCVState *env, int csrno,
2879 target_ulong val)
2881 env->hstatus = val;
2882 if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
2883 qemu_log_mask(LOG_UNIMP,
2884 "QEMU does not support mixed HSXLEN options.");
2886 if (get_field(val, HSTATUS_VSBE) != 0) {
2887 qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
2889 return RISCV_EXCP_NONE;
2892 static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
2893 target_ulong *val)
2895 *val = env->hedeleg;
2896 return RISCV_EXCP_NONE;
2899 static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
2900 target_ulong val)
2902 env->hedeleg = val & vs_delegable_excps;
2903 return RISCV_EXCP_NONE;
2906 static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
2907 uint64_t *ret_val,
2908 uint64_t new_val, uint64_t wr_mask)
2910 uint64_t mask = wr_mask & vs_delegable_ints;
2912 if (ret_val) {
2913 *ret_val = env->hideleg & vs_delegable_ints;
2916 env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
2917 return RISCV_EXCP_NONE;
2920 static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
2921 target_ulong *ret_val,
2922 target_ulong new_val, target_ulong wr_mask)
2924 uint64_t rval;
2925 RISCVException ret;
2927 ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
2928 if (ret_val) {
2929 *ret_val = rval;
2932 return ret;
2935 static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
2936 target_ulong *ret_val,
2937 target_ulong new_val, target_ulong wr_mask)
2939 uint64_t rval;
2940 RISCVException ret;
2942 ret = rmw_hideleg64(env, csrno, &rval,
2943 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2944 if (ret_val) {
2945 *ret_val = rval >> 32;
2948 return ret;
2951 static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
2952 uint64_t *ret_val,
2953 uint64_t new_val, uint64_t wr_mask)
2955 RISCVException ret;
2957 ret = rmw_mip64(env, csrno, ret_val, new_val,
2958 wr_mask & hvip_writable_mask);
2959 if (ret_val) {
2960 *ret_val &= VS_MODE_INTERRUPTS;
2963 return ret;
2966 static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
2967 target_ulong *ret_val,
2968 target_ulong new_val, target_ulong wr_mask)
2970 uint64_t rval;
2971 RISCVException ret;
2973 ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
2974 if (ret_val) {
2975 *ret_val = rval;
2978 return ret;
2981 static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
2982 target_ulong *ret_val,
2983 target_ulong new_val, target_ulong wr_mask)
2985 uint64_t rval;
2986 RISCVException ret;
2988 ret = rmw_hvip64(env, csrno, &rval,
2989 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2990 if (ret_val) {
2991 *ret_val = rval >> 32;
2994 return ret;
2997 static RISCVException rmw_hip(CPURISCVState *env, int csrno,
2998 target_ulong *ret_value,
2999 target_ulong new_value, target_ulong write_mask)
3001 int ret = rmw_mip(env, csrno, ret_value, new_value,
3002 write_mask & hip_writable_mask);
3004 if (ret_value) {
3005 *ret_value &= HS_MODE_INTERRUPTS;
3007 return ret;
3010 static RISCVException rmw_hie(CPURISCVState *env, int csrno,
3011 target_ulong *ret_val,
3012 target_ulong new_val, target_ulong wr_mask)
3014 uint64_t rval;
3015 RISCVException ret;
3017 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
3018 if (ret_val) {
3019 *ret_val = rval & HS_MODE_INTERRUPTS;
3022 return ret;
3025 static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
3026 target_ulong *val)
3028 *val = env->hcounteren;
3029 return RISCV_EXCP_NONE;
3032 static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
3033 target_ulong val)
3035 env->hcounteren = val;
3036 return RISCV_EXCP_NONE;
3039 static RISCVException read_hgeie(CPURISCVState *env, int csrno,
3040 target_ulong *val)
3042 if (val) {
3043 *val = env->hgeie;
3045 return RISCV_EXCP_NONE;
3048 static RISCVException write_hgeie(CPURISCVState *env, int csrno,
3049 target_ulong val)
3051 /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
3052 val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
3053 env->hgeie = val;
3054 /* Update mip.SGEIP bit */
3055 riscv_cpu_update_mip(env, MIP_SGEIP,
3056 BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
3057 return RISCV_EXCP_NONE;
3060 static RISCVException read_htval(CPURISCVState *env, int csrno,
3061 target_ulong *val)
3063 *val = env->htval;
3064 return RISCV_EXCP_NONE;
3067 static RISCVException write_htval(CPURISCVState *env, int csrno,
3068 target_ulong val)
3070 env->htval = val;
3071 return RISCV_EXCP_NONE;
3074 static RISCVException read_htinst(CPURISCVState *env, int csrno,
3075 target_ulong *val)
3077 *val = env->htinst;
3078 return RISCV_EXCP_NONE;
3081 static RISCVException write_htinst(CPURISCVState *env, int csrno,
3082 target_ulong val)
3084 return RISCV_EXCP_NONE;
3087 static RISCVException read_hgeip(CPURISCVState *env, int csrno,
3088 target_ulong *val)
3090 if (val) {
3091 *val = env->hgeip;
3093 return RISCV_EXCP_NONE;
3096 static RISCVException read_hgatp(CPURISCVState *env, int csrno,
3097 target_ulong *val)
3099 *val = env->hgatp;
3100 return RISCV_EXCP_NONE;
3103 static RISCVException write_hgatp(CPURISCVState *env, int csrno,
3104 target_ulong val)
3106 env->hgatp = val;
3107 return RISCV_EXCP_NONE;
3110 static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
3111 target_ulong *val)
3113 if (!env->rdtime_fn) {
3114 return RISCV_EXCP_ILLEGAL_INST;
3117 *val = env->htimedelta;
3118 return RISCV_EXCP_NONE;
3121 static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
3122 target_ulong val)
3124 if (!env->rdtime_fn) {
3125 return RISCV_EXCP_ILLEGAL_INST;
3128 if (riscv_cpu_mxl(env) == MXL_RV32) {
3129 env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
3130 } else {
3131 env->htimedelta = val;
3134 if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
3135 riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
3136 env->htimedelta, MIP_VSTIP);
3139 return RISCV_EXCP_NONE;
3142 static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
3143 target_ulong *val)
3145 if (!env->rdtime_fn) {
3146 return RISCV_EXCP_ILLEGAL_INST;
3149 *val = env->htimedelta >> 32;
3150 return RISCV_EXCP_NONE;
3153 static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
3154 target_ulong val)
3156 if (!env->rdtime_fn) {
3157 return RISCV_EXCP_ILLEGAL_INST;
3160 env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
3162 if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
3163 riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
3164 env->htimedelta, MIP_VSTIP);
3167 return RISCV_EXCP_NONE;
3170 static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val)
3172 *val = env->hvictl;
3173 return RISCV_EXCP_NONE;
3176 static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val)
3178 env->hvictl = val & HVICTL_VALID_MASK;
3179 return RISCV_EXCP_NONE;
3182 static int read_hvipriox(CPURISCVState *env, int first_index,
3183 uint8_t *iprio, target_ulong *val)
3185 int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
3187 /* First index has to be a multiple of number of irqs per register */
3188 if (first_index % num_irqs) {
3189 return (env->virt_enabled) ?
3190 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
3193 /* Fill-up return value */
3194 *val = 0;
3195 for (i = 0; i < num_irqs; i++) {
3196 if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
3197 continue;
3199 if (rdzero) {
3200 continue;
3202 *val |= ((target_ulong)iprio[irq]) << (i * 8);
3205 return RISCV_EXCP_NONE;
3208 static int write_hvipriox(CPURISCVState *env, int first_index,
3209 uint8_t *iprio, target_ulong val)
3211 int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
3213 /* First index has to be a multiple of number of irqs per register */
3214 if (first_index % num_irqs) {
3215 return (env->virt_enabled) ?
3216 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
3219 /* Fill-up priority arrary */
3220 for (i = 0; i < num_irqs; i++) {
3221 if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
3222 continue;
3224 if (rdzero) {
3225 iprio[irq] = 0;
3226 } else {
3227 iprio[irq] = (val >> (i * 8)) & 0xff;
3231 return RISCV_EXCP_NONE;
3234 static int read_hviprio1(CPURISCVState *env, int csrno, target_ulong *val)
3236 return read_hvipriox(env, 0, env->hviprio, val);
3239 static int write_hviprio1(CPURISCVState *env, int csrno, target_ulong val)
3241 return write_hvipriox(env, 0, env->hviprio, val);
3244 static int read_hviprio1h(CPURISCVState *env, int csrno, target_ulong *val)
3246 return read_hvipriox(env, 4, env->hviprio, val);
3249 static int write_hviprio1h(CPURISCVState *env, int csrno, target_ulong val)
3251 return write_hvipriox(env, 4, env->hviprio, val);
3254 static int read_hviprio2(CPURISCVState *env, int csrno, target_ulong *val)
3256 return read_hvipriox(env, 8, env->hviprio, val);
3259 static int write_hviprio2(CPURISCVState *env, int csrno, target_ulong val)
3261 return write_hvipriox(env, 8, env->hviprio, val);
3264 static int read_hviprio2h(CPURISCVState *env, int csrno, target_ulong *val)
3266 return read_hvipriox(env, 12, env->hviprio, val);
3269 static int write_hviprio2h(CPURISCVState *env, int csrno, target_ulong val)
3271 return write_hvipriox(env, 12, env->hviprio, val);
3274 /* Virtual CSR Registers */
3275 static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
3276 target_ulong *val)
3278 *val = env->vsstatus;
3279 return RISCV_EXCP_NONE;
3282 static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
3283 target_ulong val)
3285 uint64_t mask = (target_ulong)-1;
3286 if ((val & VSSTATUS64_UXL) == 0) {
3287 mask &= ~VSSTATUS64_UXL;
3289 env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
3290 return RISCV_EXCP_NONE;
3293 static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
3295 *val = env->vstvec;
3296 return RISCV_EXCP_NONE;
3299 static RISCVException write_vstvec(CPURISCVState *env, int csrno,
3300 target_ulong val)
3302 env->vstvec = val;
3303 return RISCV_EXCP_NONE;
3306 static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
3307 target_ulong *val)
3309 *val = env->vsscratch;
3310 return RISCV_EXCP_NONE;
3313 static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
3314 target_ulong val)
3316 env->vsscratch = val;
3317 return RISCV_EXCP_NONE;
3320 static RISCVException read_vsepc(CPURISCVState *env, int csrno,
3321 target_ulong *val)
3323 *val = env->vsepc;
3324 return RISCV_EXCP_NONE;
3327 static RISCVException write_vsepc(CPURISCVState *env, int csrno,
3328 target_ulong val)
3330 env->vsepc = val;
3331 return RISCV_EXCP_NONE;
3334 static RISCVException read_vscause(CPURISCVState *env, int csrno,
3335 target_ulong *val)
3337 *val = env->vscause;
3338 return RISCV_EXCP_NONE;
3341 static RISCVException write_vscause(CPURISCVState *env, int csrno,
3342 target_ulong val)
3344 env->vscause = val;
3345 return RISCV_EXCP_NONE;
3348 static RISCVException read_vstval(CPURISCVState *env, int csrno,
3349 target_ulong *val)
3351 *val = env->vstval;
3352 return RISCV_EXCP_NONE;
3355 static RISCVException write_vstval(CPURISCVState *env, int csrno,
3356 target_ulong val)
3358 env->vstval = val;
3359 return RISCV_EXCP_NONE;
3362 static RISCVException read_vsatp(CPURISCVState *env, int csrno,
3363 target_ulong *val)
3365 *val = env->vsatp;
3366 return RISCV_EXCP_NONE;
3369 static RISCVException write_vsatp(CPURISCVState *env, int csrno,
3370 target_ulong val)
3372 env->vsatp = val;
3373 return RISCV_EXCP_NONE;
3376 static RISCVException read_mtval2(CPURISCVState *env, int csrno,
3377 target_ulong *val)
3379 *val = env->mtval2;
3380 return RISCV_EXCP_NONE;
3383 static RISCVException write_mtval2(CPURISCVState *env, int csrno,
3384 target_ulong val)
3386 env->mtval2 = val;
3387 return RISCV_EXCP_NONE;
3390 static RISCVException read_mtinst(CPURISCVState *env, int csrno,
3391 target_ulong *val)
3393 *val = env->mtinst;
3394 return RISCV_EXCP_NONE;
3397 static RISCVException write_mtinst(CPURISCVState *env, int csrno,
3398 target_ulong val)
3400 env->mtinst = val;
3401 return RISCV_EXCP_NONE;
3404 /* Physical Memory Protection */
3405 static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
3406 target_ulong *val)
3408 *val = mseccfg_csr_read(env);
3409 return RISCV_EXCP_NONE;
3412 static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
3413 target_ulong val)
3415 mseccfg_csr_write(env, val);
3416 return RISCV_EXCP_NONE;
3419 static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
3420 target_ulong *val)
3422 uint32_t reg_index = csrno - CSR_PMPCFG0;
3424 *val = pmpcfg_csr_read(env, reg_index);
3425 return RISCV_EXCP_NONE;
3428 static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
3429 target_ulong val)
3431 uint32_t reg_index = csrno - CSR_PMPCFG0;
3433 pmpcfg_csr_write(env, reg_index, val);
3434 return RISCV_EXCP_NONE;
3437 static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
3438 target_ulong *val)
3440 *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
3441 return RISCV_EXCP_NONE;
3444 static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
3445 target_ulong val)
3447 pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
3448 return RISCV_EXCP_NONE;
3451 static RISCVException read_tselect(CPURISCVState *env, int csrno,
3452 target_ulong *val)
3454 *val = tselect_csr_read(env);
3455 return RISCV_EXCP_NONE;
3458 static RISCVException write_tselect(CPURISCVState *env, int csrno,
3459 target_ulong val)
3461 tselect_csr_write(env, val);
3462 return RISCV_EXCP_NONE;
3465 static RISCVException read_tdata(CPURISCVState *env, int csrno,
3466 target_ulong *val)
3468 /* return 0 in tdata1 to end the trigger enumeration */
3469 if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
3470 *val = 0;
3471 return RISCV_EXCP_NONE;
3474 if (!tdata_available(env, csrno - CSR_TDATA1)) {
3475 return RISCV_EXCP_ILLEGAL_INST;
3478 *val = tdata_csr_read(env, csrno - CSR_TDATA1);
3479 return RISCV_EXCP_NONE;
3482 static RISCVException write_tdata(CPURISCVState *env, int csrno,
3483 target_ulong val)
3485 if (!tdata_available(env, csrno - CSR_TDATA1)) {
3486 return RISCV_EXCP_ILLEGAL_INST;
3489 tdata_csr_write(env, csrno - CSR_TDATA1, val);
3490 return RISCV_EXCP_NONE;
3493 static RISCVException read_tinfo(CPURISCVState *env, int csrno,
3494 target_ulong *val)
3496 *val = tinfo_csr_read(env);
3497 return RISCV_EXCP_NONE;
3501 * Functions to access Pointer Masking feature registers
3502 * We have to check if current priv lvl could modify
3503 * csr in given mode
3505 static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
3507 int csr_priv = get_field(csrno, 0x300);
3508 int pm_current;
3510 if (env->debugger) {
3511 return false;
3514 * If priv lvls differ that means we're accessing csr from higher priv lvl,
3515 * so allow the access
3517 if (env->priv != csr_priv) {
3518 return false;
3520 switch (env->priv) {
3521 case PRV_M:
3522 pm_current = get_field(env->mmte, M_PM_CURRENT);
3523 break;
3524 case PRV_S:
3525 pm_current = get_field(env->mmte, S_PM_CURRENT);
3526 break;
3527 case PRV_U:
3528 pm_current = get_field(env->mmte, U_PM_CURRENT);
3529 break;
3530 default:
3531 g_assert_not_reached();
3533 /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
3534 return !pm_current;
3537 static RISCVException read_mmte(CPURISCVState *env, int csrno,
3538 target_ulong *val)
3540 *val = env->mmte & MMTE_MASK;
3541 return RISCV_EXCP_NONE;
3544 static RISCVException write_mmte(CPURISCVState *env, int csrno,
3545 target_ulong val)
3547 uint64_t mstatus;
3548 target_ulong wpri_val = val & MMTE_MASK;
3550 if (val != wpri_val) {
3551 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
3552 TARGET_FMT_lx "\n", "MMTE: WPRI violation written 0x",
3553 val, "vs expected 0x", wpri_val);
3555 /* for machine mode pm.current is hardwired to 1 */
3556 wpri_val |= MMTE_M_PM_CURRENT;
3558 /* hardwiring pm.instruction bit to 0, since it's not supported yet */
3559 wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
3560 env->mmte = wpri_val | EXT_STATUS_DIRTY;
3561 riscv_cpu_update_mask(env);
3563 /* Set XS and SD bits, since PM CSRs are dirty */
3564 mstatus = env->mstatus | MSTATUS_XS;
3565 write_mstatus(env, csrno, mstatus);
3566 return RISCV_EXCP_NONE;
3569 static RISCVException read_smte(CPURISCVState *env, int csrno,
3570 target_ulong *val)
3572 *val = env->mmte & SMTE_MASK;
3573 return RISCV_EXCP_NONE;
3576 static RISCVException write_smte(CPURISCVState *env, int csrno,
3577 target_ulong val)
3579 target_ulong wpri_val = val & SMTE_MASK;
3581 if (val != wpri_val) {
3582 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
3583 TARGET_FMT_lx "\n", "SMTE: WPRI violation written 0x",
3584 val, "vs expected 0x", wpri_val);
3587 /* if pm.current==0 we can't modify current PM CSRs */
3588 if (check_pm_current_disabled(env, csrno)) {
3589 return RISCV_EXCP_NONE;
3592 wpri_val |= (env->mmte & ~SMTE_MASK);
3593 write_mmte(env, csrno, wpri_val);
3594 return RISCV_EXCP_NONE;
3597 static RISCVException read_umte(CPURISCVState *env, int csrno,
3598 target_ulong *val)
3600 *val = env->mmte & UMTE_MASK;
3601 return RISCV_EXCP_NONE;
3604 static RISCVException write_umte(CPURISCVState *env, int csrno,
3605 target_ulong val)
3607 target_ulong wpri_val = val & UMTE_MASK;
3609 if (val != wpri_val) {
3610 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
3611 TARGET_FMT_lx "\n", "UMTE: WPRI violation written 0x",
3612 val, "vs expected 0x", wpri_val);
3615 if (check_pm_current_disabled(env, csrno)) {
3616 return RISCV_EXCP_NONE;
3619 wpri_val |= (env->mmte & ~UMTE_MASK);
3620 write_mmte(env, csrno, wpri_val);
3621 return RISCV_EXCP_NONE;
3624 static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
3625 target_ulong *val)
3627 *val = env->mpmmask;
3628 return RISCV_EXCP_NONE;
3631 static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
3632 target_ulong val)
3634 uint64_t mstatus;
3636 env->mpmmask = val;
3637 if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
3638 env->cur_pmmask = val;
3640 env->mmte |= EXT_STATUS_DIRTY;
3642 /* Set XS and SD bits, since PM CSRs are dirty */
3643 mstatus = env->mstatus | MSTATUS_XS;
3644 write_mstatus(env, csrno, mstatus);
3645 return RISCV_EXCP_NONE;
3648 static RISCVException read_spmmask(CPURISCVState *env, int csrno,
3649 target_ulong *val)
3651 *val = env->spmmask;
3652 return RISCV_EXCP_NONE;
3655 static RISCVException write_spmmask(CPURISCVState *env, int csrno,
3656 target_ulong val)
3658 uint64_t mstatus;
3660 /* if pm.current==0 we can't modify current PM CSRs */
3661 if (check_pm_current_disabled(env, csrno)) {
3662 return RISCV_EXCP_NONE;
3664 env->spmmask = val;
3665 if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
3666 env->cur_pmmask = val;
3667 if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
3668 env->cur_pmmask &= UINT32_MAX;
3671 env->mmte |= EXT_STATUS_DIRTY;
3673 /* Set XS and SD bits, since PM CSRs are dirty */
3674 mstatus = env->mstatus | MSTATUS_XS;
3675 write_mstatus(env, csrno, mstatus);
3676 return RISCV_EXCP_NONE;
3679 static RISCVException read_upmmask(CPURISCVState *env, int csrno,
3680 target_ulong *val)
3682 *val = env->upmmask;
3683 return RISCV_EXCP_NONE;
3686 static RISCVException write_upmmask(CPURISCVState *env, int csrno,
3687 target_ulong val)
3689 uint64_t mstatus;
3691 /* if pm.current==0 we can't modify current PM CSRs */
3692 if (check_pm_current_disabled(env, csrno)) {
3693 return RISCV_EXCP_NONE;
3695 env->upmmask = val;
3696 if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
3697 env->cur_pmmask = val;
3698 if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
3699 env->cur_pmmask &= UINT32_MAX;
3702 env->mmte |= EXT_STATUS_DIRTY;
3704 /* Set XS and SD bits, since PM CSRs are dirty */
3705 mstatus = env->mstatus | MSTATUS_XS;
3706 write_mstatus(env, csrno, mstatus);
3707 return RISCV_EXCP_NONE;
3710 static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
3711 target_ulong *val)
3713 *val = env->mpmbase;
3714 return RISCV_EXCP_NONE;
3717 static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
3718 target_ulong val)
3720 uint64_t mstatus;
3722 env->mpmbase = val;
3723 if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
3724 env->cur_pmbase = val;
3726 env->mmte |= EXT_STATUS_DIRTY;
3728 /* Set XS and SD bits, since PM CSRs are dirty */
3729 mstatus = env->mstatus | MSTATUS_XS;
3730 write_mstatus(env, csrno, mstatus);
3731 return RISCV_EXCP_NONE;
3734 static RISCVException read_spmbase(CPURISCVState *env, int csrno,
3735 target_ulong *val)
3737 *val = env->spmbase;
3738 return RISCV_EXCP_NONE;
3741 static RISCVException write_spmbase(CPURISCVState *env, int csrno,
3742 target_ulong val)
3744 uint64_t mstatus;
3746 /* if pm.current==0 we can't modify current PM CSRs */
3747 if (check_pm_current_disabled(env, csrno)) {
3748 return RISCV_EXCP_NONE;
3750 env->spmbase = val;
3751 if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
3752 env->cur_pmbase = val;
3753 if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
3754 env->cur_pmbase &= UINT32_MAX;
3757 env->mmte |= EXT_STATUS_DIRTY;
3759 /* Set XS and SD bits, since PM CSRs are dirty */
3760 mstatus = env->mstatus | MSTATUS_XS;
3761 write_mstatus(env, csrno, mstatus);
3762 return RISCV_EXCP_NONE;
3765 static RISCVException read_upmbase(CPURISCVState *env, int csrno,
3766 target_ulong *val)
3768 *val = env->upmbase;
3769 return RISCV_EXCP_NONE;
3772 static RISCVException write_upmbase(CPURISCVState *env, int csrno,
3773 target_ulong val)
3775 uint64_t mstatus;
3777 /* if pm.current==0 we can't modify current PM CSRs */
3778 if (check_pm_current_disabled(env, csrno)) {
3779 return RISCV_EXCP_NONE;
3781 env->upmbase = val;
3782 if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
3783 env->cur_pmbase = val;
3784 if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
3785 env->cur_pmbase &= UINT32_MAX;
3788 env->mmte |= EXT_STATUS_DIRTY;
3790 /* Set XS and SD bits, since PM CSRs are dirty */
3791 mstatus = env->mstatus | MSTATUS_XS;
3792 write_mstatus(env, csrno, mstatus);
3793 return RISCV_EXCP_NONE;
3796 #endif
3798 /* Crypto Extension */
3799 static RISCVException rmw_seed(CPURISCVState *env, int csrno,
3800 target_ulong *ret_value,
3801 target_ulong new_value,
3802 target_ulong write_mask)
3804 uint16_t random_v;
3805 Error *random_e = NULL;
3806 int random_r;
3807 target_ulong rval;
3809 random_r = qemu_guest_getrandom(&random_v, 2, &random_e);
3810 if (unlikely(random_r < 0)) {
3812 * Failed, for unknown reasons in the crypto subsystem.
3813 * The best we can do is log the reason and return a
3814 * failure indication to the guest. There is no reason
3815 * we know to expect the failure to be transitory, so
3816 * indicate DEAD to avoid having the guest spin on WAIT.
3818 qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
3819 __func__, error_get_pretty(random_e));
3820 error_free(random_e);
3821 rval = SEED_OPST_DEAD;
3822 } else {
3823 rval = random_v | SEED_OPST_ES16;
3826 if (ret_value) {
3827 *ret_value = rval;
3830 return RISCV_EXCP_NONE;
3834 * riscv_csrrw - read and/or update control and status register
3836 * csrr <-> riscv_csrrw(env, csrno, ret_value, 0, 0);
3837 * csrrw <-> riscv_csrrw(env, csrno, ret_value, value, -1);
3838 * csrrs <-> riscv_csrrw(env, csrno, ret_value, -1, value);
3839 * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value);
3842 static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
3843 int csrno,
3844 bool write_mask)
3846 /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
3847 bool read_only = get_field(csrno, 0xC00) == 3;
3848 int csr_min_priv = csr_ops[csrno].min_priv_ver;
3850 /* ensure the CSR extension is enabled */
3851 if (!riscv_cpu_cfg(env)->ext_icsr) {
3852 return RISCV_EXCP_ILLEGAL_INST;
3855 /* ensure CSR is implemented by checking predicate */
3856 if (!csr_ops[csrno].predicate) {
3857 return RISCV_EXCP_ILLEGAL_INST;
3860 /* privileged spec version check */
3861 if (env->priv_ver < csr_min_priv) {
3862 return RISCV_EXCP_ILLEGAL_INST;
3865 /* read / write check */
3866 if (write_mask && read_only) {
3867 return RISCV_EXCP_ILLEGAL_INST;
3871 * The predicate() not only does existence check but also does some
3872 * access control check which triggers for example virtual instruction
3873 * exception in some cases. When writing read-only CSRs in those cases
3874 * illegal instruction exception should be triggered instead of virtual
3875 * instruction exception. Hence this comes after the read / write check.
3877 RISCVException ret = csr_ops[csrno].predicate(env, csrno);
3878 if (ret != RISCV_EXCP_NONE) {
3879 return ret;
3882 #if !defined(CONFIG_USER_ONLY)
3883 int csr_priv, effective_priv = env->priv;
3885 if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
3886 !env->virt_enabled) {
3888 * We are in HS mode. Add 1 to the effective privledge level to
3889 * allow us to access the Hypervisor CSRs.
3891 effective_priv++;
3894 csr_priv = get_field(csrno, 0x300);
3895 if (!env->debugger && (effective_priv < csr_priv)) {
3896 if (csr_priv == (PRV_S + 1) && env->virt_enabled) {
3897 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
3899 return RISCV_EXCP_ILLEGAL_INST;
3901 #endif
3902 return RISCV_EXCP_NONE;
3905 static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
3906 target_ulong *ret_value,
3907 target_ulong new_value,
3908 target_ulong write_mask)
3910 RISCVException ret;
3911 target_ulong old_value;
3913 /* execute combined read/write operation if it exists */
3914 if (csr_ops[csrno].op) {
3915 return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
3918 /* if no accessor exists then return failure */
3919 if (!csr_ops[csrno].read) {
3920 return RISCV_EXCP_ILLEGAL_INST;
3922 /* read old value */
3923 ret = csr_ops[csrno].read(env, csrno, &old_value);
3924 if (ret != RISCV_EXCP_NONE) {
3925 return ret;
3928 /* write value if writable and write mask set, otherwise drop writes */
3929 if (write_mask) {
3930 new_value = (old_value & ~write_mask) | (new_value & write_mask);
3931 if (csr_ops[csrno].write) {
3932 ret = csr_ops[csrno].write(env, csrno, new_value);
3933 if (ret != RISCV_EXCP_NONE) {
3934 return ret;
3939 /* return old value */
3940 if (ret_value) {
3941 *ret_value = old_value;
3944 return RISCV_EXCP_NONE;
3947 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
3948 target_ulong *ret_value,
3949 target_ulong new_value, target_ulong write_mask)
3951 RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
3952 if (ret != RISCV_EXCP_NONE) {
3953 return ret;
3956 return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
3959 static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
3960 Int128 *ret_value,
3961 Int128 new_value,
3962 Int128 write_mask)
3964 RISCVException ret;
3965 Int128 old_value;
3967 /* read old value */
3968 ret = csr_ops[csrno].read128(env, csrno, &old_value);
3969 if (ret != RISCV_EXCP_NONE) {
3970 return ret;
3973 /* write value if writable and write mask set, otherwise drop writes */
3974 if (int128_nz(write_mask)) {
3975 new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
3976 int128_and(new_value, write_mask));
3977 if (csr_ops[csrno].write128) {
3978 ret = csr_ops[csrno].write128(env, csrno, new_value);
3979 if (ret != RISCV_EXCP_NONE) {
3980 return ret;
3982 } else if (csr_ops[csrno].write) {
3983 /* avoids having to write wrappers for all registers */
3984 ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
3985 if (ret != RISCV_EXCP_NONE) {
3986 return ret;
3991 /* return old value */
3992 if (ret_value) {
3993 *ret_value = old_value;
3996 return RISCV_EXCP_NONE;
3999 RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
4000 Int128 *ret_value,
4001 Int128 new_value, Int128 write_mask)
4003 RISCVException ret;
4005 ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
4006 if (ret != RISCV_EXCP_NONE) {
4007 return ret;
4010 if (csr_ops[csrno].read128) {
4011 return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
4015 * Fall back to 64-bit version for now, if the 128-bit alternative isn't
4016 * at all defined.
4017 * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
4018 * significant), for those, this fallback is correctly handling the
4019 * accesses
4021 target_ulong old_value;
4022 ret = riscv_csrrw_do64(env, csrno, &old_value,
4023 int128_getlo(new_value),
4024 int128_getlo(write_mask));
4025 if (ret == RISCV_EXCP_NONE && ret_value) {
4026 *ret_value = int128_make64(old_value);
4028 return ret;
4032 * Debugger support. If not in user mode, set env->debugger before the
4033 * riscv_csrrw call and clear it after the call.
4035 RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
4036 target_ulong *ret_value,
4037 target_ulong new_value,
4038 target_ulong write_mask)
4040 RISCVException ret;
4041 #if !defined(CONFIG_USER_ONLY)
4042 env->debugger = true;
4043 #endif
4044 ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
4045 #if !defined(CONFIG_USER_ONLY)
4046 env->debugger = false;
4047 #endif
4048 return ret;
4051 static RISCVException read_jvt(CPURISCVState *env, int csrno,
4052 target_ulong *val)
4054 *val = env->jvt;
4055 return RISCV_EXCP_NONE;
4058 static RISCVException write_jvt(CPURISCVState *env, int csrno,
4059 target_ulong val)
4061 env->jvt = val;
4062 return RISCV_EXCP_NONE;
4066 * Control and Status Register function table
4067 * riscv_csr_operations::predicate() must be provided for an implemented CSR
4069 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
4070 /* User Floating-Point CSRs */
4071 [CSR_FFLAGS] = { "fflags", fs, read_fflags, write_fflags },
4072 [CSR_FRM] = { "frm", fs, read_frm, write_frm },
4073 [CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr },
4074 /* Vector CSRs */
4075 [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart },
4076 [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat },
4077 [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm },
4078 [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr },
4079 [CSR_VL] = { "vl", vs, read_vl },
4080 [CSR_VTYPE] = { "vtype", vs, read_vtype },
4081 [CSR_VLENB] = { "vlenb", vs, read_vlenb },
4082 /* User Timers and Counters */
4083 [CSR_CYCLE] = { "cycle", ctr, read_hpmcounter },
4084 [CSR_INSTRET] = { "instret", ctr, read_hpmcounter },
4085 [CSR_CYCLEH] = { "cycleh", ctr32, read_hpmcounterh },
4086 [CSR_INSTRETH] = { "instreth", ctr32, read_hpmcounterh },
4089 * In privileged mode, the monitor will have to emulate TIME CSRs only if
4090 * rdtime callback is not provided by machine/platform emulation.
4092 [CSR_TIME] = { "time", ctr, read_time },
4093 [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
4095 /* Crypto Extension */
4096 [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
4098 /* Zcmt Extension */
4099 [CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
4101 #if !defined(CONFIG_USER_ONLY)
4102 /* Machine Timers and Counters */
4103 [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter,
4104 write_mhpmcounter },
4105 [CSR_MINSTRET] = { "minstret", any, read_hpmcounter,
4106 write_mhpmcounter },
4107 [CSR_MCYCLEH] = { "mcycleh", any32, read_hpmcounterh,
4108 write_mhpmcounterh },
4109 [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh,
4110 write_mhpmcounterh },
4112 /* Machine Information Registers */
4113 [CSR_MVENDORID] = { "mvendorid", any, read_mvendorid },
4114 [CSR_MARCHID] = { "marchid", any, read_marchid },
4115 [CSR_MIMPID] = { "mimpid", any, read_mimpid },
4116 [CSR_MHARTID] = { "mhartid", any, read_mhartid },
4118 [CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero,
4119 .min_priv_ver = PRIV_VERSION_1_12_0 },
4120 /* Machine Trap Setup */
4121 [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus,
4122 NULL, read_mstatus_i128 },
4123 [CSR_MISA] = { "misa", any, read_misa, write_misa,
4124 NULL, read_misa_i128 },
4125 [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg },
4126 [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
4127 [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
4128 [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
4129 [CSR_MCOUNTEREN] = { "mcounteren", umode, read_mcounteren,
4130 write_mcounteren },
4132 [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush,
4133 write_mstatush },
4135 /* Machine Trap Handling */
4136 [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch,
4137 NULL, read_mscratch_i128, write_mscratch_i128 },
4138 [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc },
4139 [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause },
4140 [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval },
4141 [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip },
4143 /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
4144 [CSR_MISELECT] = { "miselect", aia_any, NULL, NULL, rmw_xiselect },
4145 [CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg },
4147 /* Machine-Level Interrupts (AIA) */
4148 [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
4149 [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
4151 /* Virtual Interrupts for Supervisor Level (AIA) */
4152 [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore },
4153 [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore },
4155 /* Machine-Level High-Half CSRs (AIA) */
4156 [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
4157 [CSR_MIEH] = { "mieh", aia_any32, NULL, NULL, rmw_mieh },
4158 [CSR_MVIENH] = { "mvienh", aia_any32, read_zero, write_ignore },
4159 [CSR_MVIPH] = { "mviph", aia_any32, read_zero, write_ignore },
4160 [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
4162 /* Execution environment configuration */
4163 [CSR_MENVCFG] = { "menvcfg", umode, read_menvcfg, write_menvcfg,
4164 .min_priv_ver = PRIV_VERSION_1_12_0 },
4165 [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh,
4166 .min_priv_ver = PRIV_VERSION_1_12_0 },
4167 [CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
4168 .min_priv_ver = PRIV_VERSION_1_12_0 },
4169 [CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg,
4170 .min_priv_ver = PRIV_VERSION_1_12_0 },
4171 [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
4172 .min_priv_ver = PRIV_VERSION_1_12_0 },
4174 /* Smstateen extension CSRs */
4175 [CSR_MSTATEEN0] = { "mstateen0", mstateen, read_mstateen, write_mstateen0,
4176 .min_priv_ver = PRIV_VERSION_1_12_0 },
4177 [CSR_MSTATEEN0H] = { "mstateen0h", mstateen, read_mstateenh,
4178 write_mstateen0h,
4179 .min_priv_ver = PRIV_VERSION_1_12_0 },
4180 [CSR_MSTATEEN1] = { "mstateen1", mstateen, read_mstateen,
4181 write_mstateen_1_3,
4182 .min_priv_ver = PRIV_VERSION_1_12_0 },
4183 [CSR_MSTATEEN1H] = { "mstateen1h", mstateen, read_mstateenh,
4184 write_mstateenh_1_3,
4185 .min_priv_ver = PRIV_VERSION_1_12_0 },
4186 [CSR_MSTATEEN2] = { "mstateen2", mstateen, read_mstateen,
4187 write_mstateen_1_3,
4188 .min_priv_ver = PRIV_VERSION_1_12_0 },
4189 [CSR_MSTATEEN2H] = { "mstateen2h", mstateen, read_mstateenh,
4190 write_mstateenh_1_3,
4191 .min_priv_ver = PRIV_VERSION_1_12_0 },
4192 [CSR_MSTATEEN3] = { "mstateen3", mstateen, read_mstateen,
4193 write_mstateen_1_3,
4194 .min_priv_ver = PRIV_VERSION_1_12_0 },
4195 [CSR_MSTATEEN3H] = { "mstateen3h", mstateen, read_mstateenh,
4196 write_mstateenh_1_3,
4197 .min_priv_ver = PRIV_VERSION_1_12_0 },
4198 [CSR_HSTATEEN0] = { "hstateen0", hstateen, read_hstateen, write_hstateen0,
4199 .min_priv_ver = PRIV_VERSION_1_12_0 },
4200 [CSR_HSTATEEN0H] = { "hstateen0h", hstateenh, read_hstateenh,
4201 write_hstateen0h,
4202 .min_priv_ver = PRIV_VERSION_1_12_0 },
4203 [CSR_HSTATEEN1] = { "hstateen1", hstateen, read_hstateen,
4204 write_hstateen_1_3,
4205 .min_priv_ver = PRIV_VERSION_1_12_0 },
4206 [CSR_HSTATEEN1H] = { "hstateen1h", hstateenh, read_hstateenh,
4207 write_hstateenh_1_3,
4208 .min_priv_ver = PRIV_VERSION_1_12_0 },
4209 [CSR_HSTATEEN2] = { "hstateen2", hstateen, read_hstateen,
4210 write_hstateen_1_3,
4211 .min_priv_ver = PRIV_VERSION_1_12_0 },
4212 [CSR_HSTATEEN2H] = { "hstateen2h", hstateenh, read_hstateenh,
4213 write_hstateenh_1_3,
4214 .min_priv_ver = PRIV_VERSION_1_12_0 },
4215 [CSR_HSTATEEN3] = { "hstateen3", hstateen, read_hstateen,
4216 write_hstateen_1_3,
4217 .min_priv_ver = PRIV_VERSION_1_12_0 },
4218 [CSR_HSTATEEN3H] = { "hstateen3h", hstateenh, read_hstateenh,
4219 write_hstateenh_1_3,
4220 .min_priv_ver = PRIV_VERSION_1_12_0 },
4221 [CSR_SSTATEEN0] = { "sstateen0", sstateen, read_sstateen, write_sstateen0,
4222 .min_priv_ver = PRIV_VERSION_1_12_0 },
4223 [CSR_SSTATEEN1] = { "sstateen1", sstateen, read_sstateen,
4224 write_sstateen_1_3,
4225 .min_priv_ver = PRIV_VERSION_1_12_0 },
4226 [CSR_SSTATEEN2] = { "sstateen2", sstateen, read_sstateen,
4227 write_sstateen_1_3,
4228 .min_priv_ver = PRIV_VERSION_1_12_0 },
4229 [CSR_SSTATEEN3] = { "sstateen3", sstateen, read_sstateen,
4230 write_sstateen_1_3,
4231 .min_priv_ver = PRIV_VERSION_1_12_0 },
4233 /* Supervisor Trap Setup */
4234 [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus,
4235 NULL, read_sstatus_i128 },
4236 [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie },
4237 [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
4238 [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren,
4239 write_scounteren },
4241 /* Supervisor Trap Handling */
4242 [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch,
4243 NULL, read_sscratch_i128, write_sscratch_i128 },
4244 [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc },
4245 [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
4246 [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
4247 [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
4248 [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp,
4249 .min_priv_ver = PRIV_VERSION_1_12_0 },
4250 [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
4251 .min_priv_ver = PRIV_VERSION_1_12_0 },
4252 [CSR_VSTIMECMP] = { "vstimecmp", sstc, read_vstimecmp,
4253 write_vstimecmp,
4254 .min_priv_ver = PRIV_VERSION_1_12_0 },
4255 [CSR_VSTIMECMPH] = { "vstimecmph", sstc_32, read_vstimecmph,
4256 write_vstimecmph,
4257 .min_priv_ver = PRIV_VERSION_1_12_0 },
4259 /* Supervisor Protection and Translation */
4260 [CSR_SATP] = { "satp", satp, read_satp, write_satp },
4262 /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
4263 [CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect },
4264 [CSR_SIREG] = { "sireg", aia_smode, NULL, NULL, rmw_xireg },
4266 /* Supervisor-Level Interrupts (AIA) */
4267 [CSR_STOPEI] = { "stopei", aia_smode, NULL, NULL, rmw_xtopei },
4268 [CSR_STOPI] = { "stopi", aia_smode, read_stopi },
4270 /* Supervisor-Level High-Half CSRs (AIA) */
4271 [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh },
4272 [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph },
4274 [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus,
4275 .min_priv_ver = PRIV_VERSION_1_12_0 },
4276 [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg,
4277 .min_priv_ver = PRIV_VERSION_1_12_0 },
4278 [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg,
4279 .min_priv_ver = PRIV_VERSION_1_12_0 },
4280 [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip,
4281 .min_priv_ver = PRIV_VERSION_1_12_0 },
4282 [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip,
4283 .min_priv_ver = PRIV_VERSION_1_12_0 },
4284 [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie,
4285 .min_priv_ver = PRIV_VERSION_1_12_0 },
4286 [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren,
4287 write_hcounteren,
4288 .min_priv_ver = PRIV_VERSION_1_12_0 },
4289 [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie,
4290 .min_priv_ver = PRIV_VERSION_1_12_0 },
4291 [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval,
4292 .min_priv_ver = PRIV_VERSION_1_12_0 },
4293 [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst,
4294 .min_priv_ver = PRIV_VERSION_1_12_0 },
4295 [CSR_HGEIP] = { "hgeip", hmode, read_hgeip,
4296 .min_priv_ver = PRIV_VERSION_1_12_0 },
4297 [CSR_HGATP] = { "hgatp", hgatp, read_hgatp, write_hgatp,
4298 .min_priv_ver = PRIV_VERSION_1_12_0 },
4299 [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta,
4300 write_htimedelta,
4301 .min_priv_ver = PRIV_VERSION_1_12_0 },
4302 [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah,
4303 write_htimedeltah,
4304 .min_priv_ver = PRIV_VERSION_1_12_0 },
4306 [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus,
4307 write_vsstatus,
4308 .min_priv_ver = PRIV_VERSION_1_12_0 },
4309 [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip,
4310 .min_priv_ver = PRIV_VERSION_1_12_0 },
4311 [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie ,
4312 .min_priv_ver = PRIV_VERSION_1_12_0 },
4313 [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec,
4314 .min_priv_ver = PRIV_VERSION_1_12_0 },
4315 [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch,
4316 write_vsscratch,
4317 .min_priv_ver = PRIV_VERSION_1_12_0 },
4318 [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc,
4319 .min_priv_ver = PRIV_VERSION_1_12_0 },
4320 [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause,
4321 .min_priv_ver = PRIV_VERSION_1_12_0 },
4322 [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval,
4323 .min_priv_ver = PRIV_VERSION_1_12_0 },
4324 [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
4325 .min_priv_ver = PRIV_VERSION_1_12_0 },
4327 [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
4328 .min_priv_ver = PRIV_VERSION_1_12_0 },
4329 [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
4330 .min_priv_ver = PRIV_VERSION_1_12_0 },
4332 /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
4333 [CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore },
4334 [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl,
4335 write_hvictl },
4336 [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1,
4337 write_hviprio1 },
4338 [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2,
4339 write_hviprio2 },
4342 * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
4344 [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL,
4345 rmw_xiselect },
4346 [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
4348 /* VS-Level Interrupts (H-extension with AIA) */
4349 [CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei },
4350 [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi },
4352 /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
4353 [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL,
4354 rmw_hidelegh },
4355 [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero,
4356 write_ignore },
4357 [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph },
4358 [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h,
4359 write_hviprio1h },
4360 [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h,
4361 write_hviprio2h },
4362 [CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh },
4363 [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph },
4365 /* Physical Memory Protection */
4366 [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg,
4367 .min_priv_ver = PRIV_VERSION_1_11_0 },
4368 [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
4369 [CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
4370 [CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
4371 [CSR_PMPCFG3] = { "pmpcfg3", pmp, read_pmpcfg, write_pmpcfg },
4372 [CSR_PMPADDR0] = { "pmpaddr0", pmp, read_pmpaddr, write_pmpaddr },
4373 [CSR_PMPADDR1] = { "pmpaddr1", pmp, read_pmpaddr, write_pmpaddr },
4374 [CSR_PMPADDR2] = { "pmpaddr2", pmp, read_pmpaddr, write_pmpaddr },
4375 [CSR_PMPADDR3] = { "pmpaddr3", pmp, read_pmpaddr, write_pmpaddr },
4376 [CSR_PMPADDR4] = { "pmpaddr4", pmp, read_pmpaddr, write_pmpaddr },
4377 [CSR_PMPADDR5] = { "pmpaddr5", pmp, read_pmpaddr, write_pmpaddr },
4378 [CSR_PMPADDR6] = { "pmpaddr6", pmp, read_pmpaddr, write_pmpaddr },
4379 [CSR_PMPADDR7] = { "pmpaddr7", pmp, read_pmpaddr, write_pmpaddr },
4380 [CSR_PMPADDR8] = { "pmpaddr8", pmp, read_pmpaddr, write_pmpaddr },
4381 [CSR_PMPADDR9] = { "pmpaddr9", pmp, read_pmpaddr, write_pmpaddr },
4382 [CSR_PMPADDR10] = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
4383 [CSR_PMPADDR11] = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
4384 [CSR_PMPADDR12] = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
4385 [CSR_PMPADDR13] = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
4386 [CSR_PMPADDR14] = { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
4387 [CSR_PMPADDR15] = { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
4389 /* Debug CSRs */
4390 [CSR_TSELECT] = { "tselect", debug, read_tselect, write_tselect },
4391 [CSR_TDATA1] = { "tdata1", debug, read_tdata, write_tdata },
4392 [CSR_TDATA2] = { "tdata2", debug, read_tdata, write_tdata },
4393 [CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata },
4394 [CSR_TINFO] = { "tinfo", debug, read_tinfo, write_ignore },
4396 /* User Pointer Masking */
4397 [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
4398 [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask,
4399 write_upmmask },
4400 [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase,
4401 write_upmbase },
4402 /* Machine Pointer Masking */
4403 [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
4404 [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask,
4405 write_mpmmask },
4406 [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase,
4407 write_mpmbase },
4408 /* Supervisor Pointer Masking */
4409 [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
4410 [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask,
4411 write_spmmask },
4412 [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase,
4413 write_spmbase },
4415 /* Performance Counters */
4416 [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_hpmcounter },
4417 [CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_hpmcounter },
4418 [CSR_HPMCOUNTER5] = { "hpmcounter5", ctr, read_hpmcounter },
4419 [CSR_HPMCOUNTER6] = { "hpmcounter6", ctr, read_hpmcounter },
4420 [CSR_HPMCOUNTER7] = { "hpmcounter7", ctr, read_hpmcounter },
4421 [CSR_HPMCOUNTER8] = { "hpmcounter8", ctr, read_hpmcounter },
4422 [CSR_HPMCOUNTER9] = { "hpmcounter9", ctr, read_hpmcounter },
4423 [CSR_HPMCOUNTER10] = { "hpmcounter10", ctr, read_hpmcounter },
4424 [CSR_HPMCOUNTER11] = { "hpmcounter11", ctr, read_hpmcounter },
4425 [CSR_HPMCOUNTER12] = { "hpmcounter12", ctr, read_hpmcounter },
4426 [CSR_HPMCOUNTER13] = { "hpmcounter13", ctr, read_hpmcounter },
4427 [CSR_HPMCOUNTER14] = { "hpmcounter14", ctr, read_hpmcounter },
4428 [CSR_HPMCOUNTER15] = { "hpmcounter15", ctr, read_hpmcounter },
4429 [CSR_HPMCOUNTER16] = { "hpmcounter16", ctr, read_hpmcounter },
4430 [CSR_HPMCOUNTER17] = { "hpmcounter17", ctr, read_hpmcounter },
4431 [CSR_HPMCOUNTER18] = { "hpmcounter18", ctr, read_hpmcounter },
4432 [CSR_HPMCOUNTER19] = { "hpmcounter19", ctr, read_hpmcounter },
4433 [CSR_HPMCOUNTER20] = { "hpmcounter20", ctr, read_hpmcounter },
4434 [CSR_HPMCOUNTER21] = { "hpmcounter21", ctr, read_hpmcounter },
4435 [CSR_HPMCOUNTER22] = { "hpmcounter22", ctr, read_hpmcounter },
4436 [CSR_HPMCOUNTER23] = { "hpmcounter23", ctr, read_hpmcounter },
4437 [CSR_HPMCOUNTER24] = { "hpmcounter24", ctr, read_hpmcounter },
4438 [CSR_HPMCOUNTER25] = { "hpmcounter25", ctr, read_hpmcounter },
4439 [CSR_HPMCOUNTER26] = { "hpmcounter26", ctr, read_hpmcounter },
4440 [CSR_HPMCOUNTER27] = { "hpmcounter27", ctr, read_hpmcounter },
4441 [CSR_HPMCOUNTER28] = { "hpmcounter28", ctr, read_hpmcounter },
4442 [CSR_HPMCOUNTER29] = { "hpmcounter29", ctr, read_hpmcounter },
4443 [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_hpmcounter },
4444 [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_hpmcounter },
4446 [CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_hpmcounter,
4447 write_mhpmcounter },
4448 [CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_hpmcounter,
4449 write_mhpmcounter },
4450 [CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_hpmcounter,
4451 write_mhpmcounter },
4452 [CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_hpmcounter,
4453 write_mhpmcounter },
4454 [CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_hpmcounter,
4455 write_mhpmcounter },
4456 [CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_hpmcounter,
4457 write_mhpmcounter },
4458 [CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_hpmcounter,
4459 write_mhpmcounter },
4460 [CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_hpmcounter,
4461 write_mhpmcounter },
4462 [CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_hpmcounter,
4463 write_mhpmcounter },
4464 [CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_hpmcounter,
4465 write_mhpmcounter },
4466 [CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_hpmcounter,
4467 write_mhpmcounter },
4468 [CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_hpmcounter,
4469 write_mhpmcounter },
4470 [CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_hpmcounter,
4471 write_mhpmcounter },
4472 [CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_hpmcounter,
4473 write_mhpmcounter },
4474 [CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_hpmcounter,
4475 write_mhpmcounter },
4476 [CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_hpmcounter,
4477 write_mhpmcounter },
4478 [CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_hpmcounter,
4479 write_mhpmcounter },
4480 [CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_hpmcounter,
4481 write_mhpmcounter },
4482 [CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_hpmcounter,
4483 write_mhpmcounter },
4484 [CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_hpmcounter,
4485 write_mhpmcounter },
4486 [CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_hpmcounter,
4487 write_mhpmcounter },
4488 [CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_hpmcounter,
4489 write_mhpmcounter },
4490 [CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_hpmcounter,
4491 write_mhpmcounter },
4492 [CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_hpmcounter,
4493 write_mhpmcounter },
4494 [CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_hpmcounter,
4495 write_mhpmcounter },
4496 [CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_hpmcounter,
4497 write_mhpmcounter },
4498 [CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_hpmcounter,
4499 write_mhpmcounter },
4500 [CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_hpmcounter,
4501 write_mhpmcounter },
4502 [CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_hpmcounter,
4503 write_mhpmcounter },
4505 [CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_mcountinhibit,
4506 write_mcountinhibit,
4507 .min_priv_ver = PRIV_VERSION_1_11_0 },
4509 [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_mhpmevent,
4510 write_mhpmevent },
4511 [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_mhpmevent,
4512 write_mhpmevent },
4513 [CSR_MHPMEVENT5] = { "mhpmevent5", any, read_mhpmevent,
4514 write_mhpmevent },
4515 [CSR_MHPMEVENT6] = { "mhpmevent6", any, read_mhpmevent,
4516 write_mhpmevent },
4517 [CSR_MHPMEVENT7] = { "mhpmevent7", any, read_mhpmevent,
4518 write_mhpmevent },
4519 [CSR_MHPMEVENT8] = { "mhpmevent8", any, read_mhpmevent,
4520 write_mhpmevent },
4521 [CSR_MHPMEVENT9] = { "mhpmevent9", any, read_mhpmevent,
4522 write_mhpmevent },
4523 [CSR_MHPMEVENT10] = { "mhpmevent10", any, read_mhpmevent,
4524 write_mhpmevent },
4525 [CSR_MHPMEVENT11] = { "mhpmevent11", any, read_mhpmevent,
4526 write_mhpmevent },
4527 [CSR_MHPMEVENT12] = { "mhpmevent12", any, read_mhpmevent,
4528 write_mhpmevent },
4529 [CSR_MHPMEVENT13] = { "mhpmevent13", any, read_mhpmevent,
4530 write_mhpmevent },
4531 [CSR_MHPMEVENT14] = { "mhpmevent14", any, read_mhpmevent,
4532 write_mhpmevent },
4533 [CSR_MHPMEVENT15] = { "mhpmevent15", any, read_mhpmevent,
4534 write_mhpmevent },
4535 [CSR_MHPMEVENT16] = { "mhpmevent16", any, read_mhpmevent,
4536 write_mhpmevent },
4537 [CSR_MHPMEVENT17] = { "mhpmevent17", any, read_mhpmevent,
4538 write_mhpmevent },
4539 [CSR_MHPMEVENT18] = { "mhpmevent18", any, read_mhpmevent,
4540 write_mhpmevent },
4541 [CSR_MHPMEVENT19] = { "mhpmevent19", any, read_mhpmevent,
4542 write_mhpmevent },
4543 [CSR_MHPMEVENT20] = { "mhpmevent20", any, read_mhpmevent,
4544 write_mhpmevent },
4545 [CSR_MHPMEVENT21] = { "mhpmevent21", any, read_mhpmevent,
4546 write_mhpmevent },
4547 [CSR_MHPMEVENT22] = { "mhpmevent22", any, read_mhpmevent,
4548 write_mhpmevent },
4549 [CSR_MHPMEVENT23] = { "mhpmevent23", any, read_mhpmevent,
4550 write_mhpmevent },
4551 [CSR_MHPMEVENT24] = { "mhpmevent24", any, read_mhpmevent,
4552 write_mhpmevent },
4553 [CSR_MHPMEVENT25] = { "mhpmevent25", any, read_mhpmevent,
4554 write_mhpmevent },
4555 [CSR_MHPMEVENT26] = { "mhpmevent26", any, read_mhpmevent,
4556 write_mhpmevent },
4557 [CSR_MHPMEVENT27] = { "mhpmevent27", any, read_mhpmevent,
4558 write_mhpmevent },
4559 [CSR_MHPMEVENT28] = { "mhpmevent28", any, read_mhpmevent,
4560 write_mhpmevent },
4561 [CSR_MHPMEVENT29] = { "mhpmevent29", any, read_mhpmevent,
4562 write_mhpmevent },
4563 [CSR_MHPMEVENT30] = { "mhpmevent30", any, read_mhpmevent,
4564 write_mhpmevent },
4565 [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent,
4566 write_mhpmevent },
4568 [CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf, read_mhpmeventh,
4569 write_mhpmeventh,
4570 .min_priv_ver = PRIV_VERSION_1_12_0 },
4571 [CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf, read_mhpmeventh,
4572 write_mhpmeventh,
4573 .min_priv_ver = PRIV_VERSION_1_12_0 },
4574 [CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf, read_mhpmeventh,
4575 write_mhpmeventh,
4576 .min_priv_ver = PRIV_VERSION_1_12_0 },
4577 [CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf, read_mhpmeventh,
4578 write_mhpmeventh,
4579 .min_priv_ver = PRIV_VERSION_1_12_0 },
4580 [CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf, read_mhpmeventh,
4581 write_mhpmeventh,
4582 .min_priv_ver = PRIV_VERSION_1_12_0 },
4583 [CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf, read_mhpmeventh,
4584 write_mhpmeventh,
4585 .min_priv_ver = PRIV_VERSION_1_12_0 },
4586 [CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf, read_mhpmeventh,
4587 write_mhpmeventh,
4588 .min_priv_ver = PRIV_VERSION_1_12_0 },
4589 [CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf, read_mhpmeventh,
4590 write_mhpmeventh,
4591 .min_priv_ver = PRIV_VERSION_1_12_0 },
4592 [CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf, read_mhpmeventh,
4593 write_mhpmeventh,
4594 .min_priv_ver = PRIV_VERSION_1_12_0 },
4595 [CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf, read_mhpmeventh,
4596 write_mhpmeventh,
4597 .min_priv_ver = PRIV_VERSION_1_12_0 },
4598 [CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf, read_mhpmeventh,
4599 write_mhpmeventh,
4600 .min_priv_ver = PRIV_VERSION_1_12_0 },
4601 [CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf, read_mhpmeventh,
4602 write_mhpmeventh,
4603 .min_priv_ver = PRIV_VERSION_1_12_0 },
4604 [CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf, read_mhpmeventh,
4605 write_mhpmeventh,
4606 .min_priv_ver = PRIV_VERSION_1_12_0 },
4607 [CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf, read_mhpmeventh,
4608 write_mhpmeventh,
4609 .min_priv_ver = PRIV_VERSION_1_12_0 },
4610 [CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf, read_mhpmeventh,
4611 write_mhpmeventh,
4612 .min_priv_ver = PRIV_VERSION_1_12_0 },
4613 [CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf, read_mhpmeventh,
4614 write_mhpmeventh,
4615 .min_priv_ver = PRIV_VERSION_1_12_0 },
4616 [CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf, read_mhpmeventh,
4617 write_mhpmeventh,
4618 .min_priv_ver = PRIV_VERSION_1_12_0 },
4619 [CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf, read_mhpmeventh,
4620 write_mhpmeventh,
4621 .min_priv_ver = PRIV_VERSION_1_12_0 },
4622 [CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf, read_mhpmeventh,
4623 write_mhpmeventh,
4624 .min_priv_ver = PRIV_VERSION_1_12_0 },
4625 [CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf, read_mhpmeventh,
4626 write_mhpmeventh,
4627 .min_priv_ver = PRIV_VERSION_1_12_0 },
4628 [CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf, read_mhpmeventh,
4629 write_mhpmeventh,
4630 .min_priv_ver = PRIV_VERSION_1_12_0 },
4631 [CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf, read_mhpmeventh,
4632 write_mhpmeventh,
4633 .min_priv_ver = PRIV_VERSION_1_12_0 },
4634 [CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf, read_mhpmeventh,
4635 write_mhpmeventh,
4636 .min_priv_ver = PRIV_VERSION_1_12_0 },
4637 [CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf, read_mhpmeventh,
4638 write_mhpmeventh,
4639 .min_priv_ver = PRIV_VERSION_1_12_0 },
4640 [CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf, read_mhpmeventh,
4641 write_mhpmeventh,
4642 .min_priv_ver = PRIV_VERSION_1_12_0 },
4643 [CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf, read_mhpmeventh,
4644 write_mhpmeventh,
4645 .min_priv_ver = PRIV_VERSION_1_12_0 },
4646 [CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf, read_mhpmeventh,
4647 write_mhpmeventh,
4648 .min_priv_ver = PRIV_VERSION_1_12_0 },
4649 [CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf, read_mhpmeventh,
4650 write_mhpmeventh,
4651 .min_priv_ver = PRIV_VERSION_1_12_0 },
4652 [CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf, read_mhpmeventh,
4653 write_mhpmeventh,
4654 .min_priv_ver = PRIV_VERSION_1_12_0 },
4656 [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh },
4657 [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh },
4658 [CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_hpmcounterh },
4659 [CSR_HPMCOUNTER6H] = { "hpmcounter6h", ctr32, read_hpmcounterh },
4660 [CSR_HPMCOUNTER7H] = { "hpmcounter7h", ctr32, read_hpmcounterh },
4661 [CSR_HPMCOUNTER8H] = { "hpmcounter8h", ctr32, read_hpmcounterh },
4662 [CSR_HPMCOUNTER9H] = { "hpmcounter9h", ctr32, read_hpmcounterh },
4663 [CSR_HPMCOUNTER10H] = { "hpmcounter10h", ctr32, read_hpmcounterh },
4664 [CSR_HPMCOUNTER11H] = { "hpmcounter11h", ctr32, read_hpmcounterh },
4665 [CSR_HPMCOUNTER12H] = { "hpmcounter12h", ctr32, read_hpmcounterh },
4666 [CSR_HPMCOUNTER13H] = { "hpmcounter13h", ctr32, read_hpmcounterh },
4667 [CSR_HPMCOUNTER14H] = { "hpmcounter14h", ctr32, read_hpmcounterh },
4668 [CSR_HPMCOUNTER15H] = { "hpmcounter15h", ctr32, read_hpmcounterh },
4669 [CSR_HPMCOUNTER16H] = { "hpmcounter16h", ctr32, read_hpmcounterh },
4670 [CSR_HPMCOUNTER17H] = { "hpmcounter17h", ctr32, read_hpmcounterh },
4671 [CSR_HPMCOUNTER18H] = { "hpmcounter18h", ctr32, read_hpmcounterh },
4672 [CSR_HPMCOUNTER19H] = { "hpmcounter19h", ctr32, read_hpmcounterh },
4673 [CSR_HPMCOUNTER20H] = { "hpmcounter20h", ctr32, read_hpmcounterh },
4674 [CSR_HPMCOUNTER21H] = { "hpmcounter21h", ctr32, read_hpmcounterh },
4675 [CSR_HPMCOUNTER22H] = { "hpmcounter22h", ctr32, read_hpmcounterh },
4676 [CSR_HPMCOUNTER23H] = { "hpmcounter23h", ctr32, read_hpmcounterh },
4677 [CSR_HPMCOUNTER24H] = { "hpmcounter24h", ctr32, read_hpmcounterh },
4678 [CSR_HPMCOUNTER25H] = { "hpmcounter25h", ctr32, read_hpmcounterh },
4679 [CSR_HPMCOUNTER26H] = { "hpmcounter26h", ctr32, read_hpmcounterh },
4680 [CSR_HPMCOUNTER27H] = { "hpmcounter27h", ctr32, read_hpmcounterh },
4681 [CSR_HPMCOUNTER28H] = { "hpmcounter28h", ctr32, read_hpmcounterh },
4682 [CSR_HPMCOUNTER29H] = { "hpmcounter29h", ctr32, read_hpmcounterh },
4683 [CSR_HPMCOUNTER30H] = { "hpmcounter30h", ctr32, read_hpmcounterh },
4684 [CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_hpmcounterh },
4686 [CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", mctr32, read_hpmcounterh,
4687 write_mhpmcounterh },
4688 [CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", mctr32, read_hpmcounterh,
4689 write_mhpmcounterh },
4690 [CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", mctr32, read_hpmcounterh,
4691 write_mhpmcounterh },
4692 [CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", mctr32, read_hpmcounterh,
4693 write_mhpmcounterh },
4694 [CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", mctr32, read_hpmcounterh,
4695 write_mhpmcounterh },
4696 [CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", mctr32, read_hpmcounterh,
4697 write_mhpmcounterh },
4698 [CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", mctr32, read_hpmcounterh,
4699 write_mhpmcounterh },
4700 [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32, read_hpmcounterh,
4701 write_mhpmcounterh },
4702 [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32, read_hpmcounterh,
4703 write_mhpmcounterh },
4704 [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32, read_hpmcounterh,
4705 write_mhpmcounterh },
4706 [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32, read_hpmcounterh,
4707 write_mhpmcounterh },
4708 [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32, read_hpmcounterh,
4709 write_mhpmcounterh },
4710 [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32, read_hpmcounterh,
4711 write_mhpmcounterh },
4712 [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32, read_hpmcounterh,
4713 write_mhpmcounterh },
4714 [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32, read_hpmcounterh,
4715 write_mhpmcounterh },
4716 [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32, read_hpmcounterh,
4717 write_mhpmcounterh },
4718 [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32, read_hpmcounterh,
4719 write_mhpmcounterh },
4720 [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32, read_hpmcounterh,
4721 write_mhpmcounterh },
4722 [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32, read_hpmcounterh,
4723 write_mhpmcounterh },
4724 [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32, read_hpmcounterh,
4725 write_mhpmcounterh },
4726 [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32, read_hpmcounterh,
4727 write_mhpmcounterh },
4728 [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32, read_hpmcounterh,
4729 write_mhpmcounterh },
4730 [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32, read_hpmcounterh,
4731 write_mhpmcounterh },
4732 [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32, read_hpmcounterh,
4733 write_mhpmcounterh },
4734 [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32, read_hpmcounterh,
4735 write_mhpmcounterh },
4736 [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32, read_hpmcounterh,
4737 write_mhpmcounterh },
4738 [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32, read_hpmcounterh,
4739 write_mhpmcounterh },
4740 [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32, read_hpmcounterh,
4741 write_mhpmcounterh },
4742 [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh,
4743 write_mhpmcounterh },
4744 [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf,
4745 .min_priv_ver = PRIV_VERSION_1_12_0 },
4747 #endif /* !CONFIG_USER_ONLY */