tcg: Add INDEX_op_qemu_{ld,st}_i128
[qemu/ar7.git] / target / riscv / csr.c
blob4451bd1263d99048dfcfc884d649eae6681b2baf
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;
85 #endif
86 return RISCV_EXCP_NONE;
89 static RISCVException vs(CPURISCVState *env, int csrno)
91 if (riscv_cpu_cfg(env)->ext_zve32f) {
92 #if !defined(CONFIG_USER_ONLY)
93 if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
94 return RISCV_EXCP_ILLEGAL_INST;
96 #endif
97 return RISCV_EXCP_NONE;
99 return RISCV_EXCP_ILLEGAL_INST;
102 static RISCVException ctr(CPURISCVState *env, int csrno)
104 #if !defined(CONFIG_USER_ONLY)
105 RISCVCPU *cpu = env_archcpu(env);
106 int ctr_index;
107 target_ulong ctr_mask;
108 int base_csrno = CSR_CYCLE;
109 bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
111 if (rv32 && csrno >= CSR_CYCLEH) {
112 /* Offset for RV32 hpmcounternh counters */
113 base_csrno += 0x80;
115 ctr_index = csrno - base_csrno;
116 ctr_mask = BIT(ctr_index);
118 if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
119 (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
120 goto skip_ext_pmu_check;
123 if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
124 /* No counter is enabled in PMU or the counter is out of range */
125 return RISCV_EXCP_ILLEGAL_INST;
128 skip_ext_pmu_check:
130 if (env->debugger) {
131 return RISCV_EXCP_NONE;
134 if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
135 return RISCV_EXCP_ILLEGAL_INST;
138 if (env->virt_enabled) {
139 if (!get_field(env->hcounteren, ctr_mask) ||
140 (env->priv == PRV_U && !get_field(env->scounteren, ctr_mask))) {
141 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
145 if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
146 !get_field(env->scounteren, ctr_mask)) {
147 return RISCV_EXCP_ILLEGAL_INST;
150 #endif
151 return RISCV_EXCP_NONE;
154 static RISCVException ctr32(CPURISCVState *env, int csrno)
156 if (riscv_cpu_mxl(env) != MXL_RV32) {
157 return RISCV_EXCP_ILLEGAL_INST;
160 return ctr(env, csrno);
163 static RISCVException zcmt(CPURISCVState *env, int csrno)
165 if (!riscv_cpu_cfg(env)->ext_zcmt) {
166 return RISCV_EXCP_ILLEGAL_INST;
169 #if !defined(CONFIG_USER_ONLY)
170 RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
171 if (ret != RISCV_EXCP_NONE) {
172 return ret;
174 #endif
176 return RISCV_EXCP_NONE;
179 #if !defined(CONFIG_USER_ONLY)
180 static RISCVException mctr(CPURISCVState *env, int csrno)
182 int pmu_num = riscv_cpu_cfg(env)->pmu_num;
183 int ctr_index;
184 int base_csrno = CSR_MHPMCOUNTER3;
186 if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) {
187 /* Offset for RV32 mhpmcounternh counters */
188 base_csrno += 0x80;
190 ctr_index = csrno - base_csrno;
191 if (!pmu_num || ctr_index >= pmu_num) {
192 /* The PMU is not enabled or counter is out of range */
193 return RISCV_EXCP_ILLEGAL_INST;
196 return RISCV_EXCP_NONE;
199 static RISCVException mctr32(CPURISCVState *env, int csrno)
201 if (riscv_cpu_mxl(env) != MXL_RV32) {
202 return RISCV_EXCP_ILLEGAL_INST;
205 return mctr(env, csrno);
208 static RISCVException sscofpmf(CPURISCVState *env, int csrno)
210 if (!riscv_cpu_cfg(env)->ext_sscofpmf) {
211 return RISCV_EXCP_ILLEGAL_INST;
214 return RISCV_EXCP_NONE;
217 static RISCVException any(CPURISCVState *env, int csrno)
219 return RISCV_EXCP_NONE;
222 static RISCVException any32(CPURISCVState *env, int csrno)
224 if (riscv_cpu_mxl(env) != MXL_RV32) {
225 return RISCV_EXCP_ILLEGAL_INST;
228 return any(env, csrno);
232 static int aia_any(CPURISCVState *env, int csrno)
234 if (!riscv_cpu_cfg(env)->ext_smaia) {
235 return RISCV_EXCP_ILLEGAL_INST;
238 return any(env, csrno);
241 static int aia_any32(CPURISCVState *env, int csrno)
243 if (!riscv_cpu_cfg(env)->ext_smaia) {
244 return RISCV_EXCP_ILLEGAL_INST;
247 return any32(env, csrno);
250 static RISCVException smode(CPURISCVState *env, int csrno)
252 if (riscv_has_ext(env, RVS)) {
253 return RISCV_EXCP_NONE;
256 return RISCV_EXCP_ILLEGAL_INST;
259 static int smode32(CPURISCVState *env, int csrno)
261 if (riscv_cpu_mxl(env) != MXL_RV32) {
262 return RISCV_EXCP_ILLEGAL_INST;
265 return smode(env, csrno);
268 static int aia_smode(CPURISCVState *env, int csrno)
270 if (!riscv_cpu_cfg(env)->ext_ssaia) {
271 return RISCV_EXCP_ILLEGAL_INST;
274 return smode(env, csrno);
277 static int aia_smode32(CPURISCVState *env, int csrno)
279 if (!riscv_cpu_cfg(env)->ext_ssaia) {
280 return RISCV_EXCP_ILLEGAL_INST;
283 return smode32(env, csrno);
286 static RISCVException hmode(CPURISCVState *env, int csrno)
288 if (riscv_has_ext(env, RVH)) {
289 return RISCV_EXCP_NONE;
292 return RISCV_EXCP_ILLEGAL_INST;
295 static RISCVException hmode32(CPURISCVState *env, int csrno)
297 if (riscv_cpu_mxl(env) != MXL_RV32) {
298 return RISCV_EXCP_ILLEGAL_INST;
301 return hmode(env, csrno);
305 static RISCVException umode(CPURISCVState *env, int csrno)
307 if (riscv_has_ext(env, RVU)) {
308 return RISCV_EXCP_NONE;
311 return RISCV_EXCP_ILLEGAL_INST;
314 static RISCVException umode32(CPURISCVState *env, int csrno)
316 if (riscv_cpu_mxl(env) != MXL_RV32) {
317 return RISCV_EXCP_ILLEGAL_INST;
320 return umode(env, csrno);
323 static RISCVException mstateen(CPURISCVState *env, int csrno)
325 if (!riscv_cpu_cfg(env)->ext_smstateen) {
326 return RISCV_EXCP_ILLEGAL_INST;
329 return any(env, csrno);
332 static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
334 if (!riscv_cpu_cfg(env)->ext_smstateen) {
335 return RISCV_EXCP_ILLEGAL_INST;
338 RISCVException ret = hmode(env, csrno);
339 if (ret != RISCV_EXCP_NONE) {
340 return ret;
343 if (env->debugger) {
344 return RISCV_EXCP_NONE;
347 if (env->priv < PRV_M) {
348 if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
349 return RISCV_EXCP_ILLEGAL_INST;
353 return RISCV_EXCP_NONE;
356 static RISCVException hstateen(CPURISCVState *env, int csrno)
358 return hstateen_pred(env, csrno, CSR_HSTATEEN0);
361 static RISCVException hstateenh(CPURISCVState *env, int csrno)
363 return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
366 static RISCVException sstateen(CPURISCVState *env, int csrno)
368 bool virt = env->virt_enabled;
369 int index = csrno - CSR_SSTATEEN0;
371 if (!riscv_cpu_cfg(env)->ext_smstateen) {
372 return RISCV_EXCP_ILLEGAL_INST;
375 RISCVException ret = smode(env, csrno);
376 if (ret != RISCV_EXCP_NONE) {
377 return ret;
380 if (env->debugger) {
381 return RISCV_EXCP_NONE;
384 if (env->priv < PRV_M) {
385 if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
386 return RISCV_EXCP_ILLEGAL_INST;
389 if (virt) {
390 if (!(env->hstateen[index] & SMSTATEEN_STATEEN)) {
391 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
396 return RISCV_EXCP_NONE;
399 static RISCVException sstc(CPURISCVState *env, int csrno)
401 bool hmode_check = false;
403 if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn) {
404 return RISCV_EXCP_ILLEGAL_INST;
407 if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
408 hmode_check = true;
411 RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
412 if (ret != RISCV_EXCP_NONE) {
413 return ret;
416 if (env->debugger) {
417 return RISCV_EXCP_NONE;
420 if (env->priv == PRV_M) {
421 return RISCV_EXCP_NONE;
425 * No need of separate function for rv32 as menvcfg stores both menvcfg
426 * menvcfgh for RV32.
428 if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
429 get_field(env->menvcfg, MENVCFG_STCE))) {
430 return RISCV_EXCP_ILLEGAL_INST;
433 if (env->virt_enabled) {
434 if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
435 get_field(env->henvcfg, HENVCFG_STCE))) {
436 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
440 return RISCV_EXCP_NONE;
443 static RISCVException sstc_32(CPURISCVState *env, int csrno)
445 if (riscv_cpu_mxl(env) != MXL_RV32) {
446 return RISCV_EXCP_ILLEGAL_INST;
449 return sstc(env, csrno);
452 static RISCVException satp(CPURISCVState *env, int csrno)
454 if (env->priv == PRV_S && !env->virt_enabled &&
455 get_field(env->mstatus, MSTATUS_TVM)) {
456 return RISCV_EXCP_ILLEGAL_INST;
458 if (env->priv == PRV_S && env->virt_enabled &&
459 get_field(env->hstatus, HSTATUS_VTVM)) {
460 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
463 return smode(env, csrno);
466 static RISCVException hgatp(CPURISCVState *env, int csrno)
468 if (env->priv == PRV_S && !env->virt_enabled &&
469 get_field(env->mstatus, MSTATUS_TVM)) {
470 return RISCV_EXCP_ILLEGAL_INST;
473 return hmode(env, csrno);
476 /* Checks if PointerMasking registers could be accessed */
477 static RISCVException pointer_masking(CPURISCVState *env, int csrno)
479 /* Check if j-ext is present */
480 if (riscv_has_ext(env, RVJ)) {
481 return RISCV_EXCP_NONE;
483 return RISCV_EXCP_ILLEGAL_INST;
486 static int aia_hmode(CPURISCVState *env, int csrno)
488 if (!riscv_cpu_cfg(env)->ext_ssaia) {
489 return RISCV_EXCP_ILLEGAL_INST;
492 return hmode(env, csrno);
495 static int aia_hmode32(CPURISCVState *env, int csrno)
497 if (!riscv_cpu_cfg(env)->ext_ssaia) {
498 return RISCV_EXCP_ILLEGAL_INST;
501 return hmode32(env, csrno);
504 static RISCVException pmp(CPURISCVState *env, int csrno)
506 if (riscv_cpu_cfg(env)->pmp) {
507 if (csrno <= CSR_PMPCFG3) {
508 uint32_t reg_index = csrno - CSR_PMPCFG0;
510 /* TODO: RV128 restriction check */
511 if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
512 return RISCV_EXCP_ILLEGAL_INST;
516 return RISCV_EXCP_NONE;
519 return RISCV_EXCP_ILLEGAL_INST;
522 static RISCVException epmp(CPURISCVState *env, int csrno)
524 if (riscv_cpu_cfg(env)->epmp) {
525 return RISCV_EXCP_NONE;
528 return RISCV_EXCP_ILLEGAL_INST;
531 static RISCVException debug(CPURISCVState *env, int csrno)
533 if (riscv_cpu_cfg(env)->debug) {
534 return RISCV_EXCP_NONE;
537 return RISCV_EXCP_ILLEGAL_INST;
539 #endif
541 static RISCVException seed(CPURISCVState *env, int csrno)
543 if (!riscv_cpu_cfg(env)->ext_zkr) {
544 return RISCV_EXCP_ILLEGAL_INST;
547 #if !defined(CONFIG_USER_ONLY)
548 if (env->debugger) {
549 return RISCV_EXCP_NONE;
553 * With a CSR read-write instruction:
554 * 1) The seed CSR is always available in machine mode as normal.
555 * 2) Attempted access to seed from virtual modes VS and VU always raises
556 * an exception(virtual instruction exception only if mseccfg.sseed=1).
557 * 3) Without the corresponding access control bit set to 1, any attempted
558 * access to seed from U, S or HS modes will raise an illegal instruction
559 * exception.
561 if (env->priv == PRV_M) {
562 return RISCV_EXCP_NONE;
563 } else if (env->virt_enabled) {
564 if (env->mseccfg & MSECCFG_SSEED) {
565 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
566 } else {
567 return RISCV_EXCP_ILLEGAL_INST;
569 } else {
570 if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) {
571 return RISCV_EXCP_NONE;
572 } else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) {
573 return RISCV_EXCP_NONE;
574 } else {
575 return RISCV_EXCP_ILLEGAL_INST;
578 #else
579 return RISCV_EXCP_NONE;
580 #endif
583 /* User Floating-Point CSRs */
584 static RISCVException read_fflags(CPURISCVState *env, int csrno,
585 target_ulong *val)
587 *val = riscv_cpu_get_fflags(env);
588 return RISCV_EXCP_NONE;
591 static RISCVException write_fflags(CPURISCVState *env, int csrno,
592 target_ulong val)
594 #if !defined(CONFIG_USER_ONLY)
595 if (riscv_has_ext(env, RVF)) {
596 env->mstatus |= MSTATUS_FS;
598 #endif
599 riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
600 return RISCV_EXCP_NONE;
603 static RISCVException read_frm(CPURISCVState *env, int csrno,
604 target_ulong *val)
606 *val = env->frm;
607 return RISCV_EXCP_NONE;
610 static RISCVException write_frm(CPURISCVState *env, int csrno,
611 target_ulong val)
613 #if !defined(CONFIG_USER_ONLY)
614 if (riscv_has_ext(env, RVF)) {
615 env->mstatus |= MSTATUS_FS;
617 #endif
618 env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
619 return RISCV_EXCP_NONE;
622 static RISCVException read_fcsr(CPURISCVState *env, int csrno,
623 target_ulong *val)
625 *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
626 | (env->frm << FSR_RD_SHIFT);
627 return RISCV_EXCP_NONE;
630 static RISCVException write_fcsr(CPURISCVState *env, int csrno,
631 target_ulong val)
633 #if !defined(CONFIG_USER_ONLY)
634 if (riscv_has_ext(env, RVF)) {
635 env->mstatus |= MSTATUS_FS;
637 #endif
638 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
639 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
640 return RISCV_EXCP_NONE;
643 static RISCVException read_vtype(CPURISCVState *env, int csrno,
644 target_ulong *val)
646 uint64_t vill;
647 switch (env->xl) {
648 case MXL_RV32:
649 vill = (uint32_t)env->vill << 31;
650 break;
651 case MXL_RV64:
652 vill = (uint64_t)env->vill << 63;
653 break;
654 default:
655 g_assert_not_reached();
657 *val = (target_ulong)vill | env->vtype;
658 return RISCV_EXCP_NONE;
661 static RISCVException read_vl(CPURISCVState *env, int csrno,
662 target_ulong *val)
664 *val = env->vl;
665 return RISCV_EXCP_NONE;
668 static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
670 *val = riscv_cpu_cfg(env)->vlen >> 3;
671 return RISCV_EXCP_NONE;
674 static RISCVException read_vxrm(CPURISCVState *env, int csrno,
675 target_ulong *val)
677 *val = env->vxrm;
678 return RISCV_EXCP_NONE;
681 static RISCVException write_vxrm(CPURISCVState *env, int csrno,
682 target_ulong val)
684 #if !defined(CONFIG_USER_ONLY)
685 env->mstatus |= MSTATUS_VS;
686 #endif
687 env->vxrm = val;
688 return RISCV_EXCP_NONE;
691 static RISCVException read_vxsat(CPURISCVState *env, int csrno,
692 target_ulong *val)
694 *val = env->vxsat;
695 return RISCV_EXCP_NONE;
698 static RISCVException write_vxsat(CPURISCVState *env, int csrno,
699 target_ulong val)
701 #if !defined(CONFIG_USER_ONLY)
702 env->mstatus |= MSTATUS_VS;
703 #endif
704 env->vxsat = val;
705 return RISCV_EXCP_NONE;
708 static RISCVException read_vstart(CPURISCVState *env, int csrno,
709 target_ulong *val)
711 *val = env->vstart;
712 return RISCV_EXCP_NONE;
715 static RISCVException write_vstart(CPURISCVState *env, int csrno,
716 target_ulong val)
718 #if !defined(CONFIG_USER_ONLY)
719 env->mstatus |= MSTATUS_VS;
720 #endif
722 * The vstart CSR is defined to have only enough writable bits
723 * to hold the largest element index, i.e. lg2(VLEN) bits.
725 env->vstart = val & ~(~0ULL << ctzl(riscv_cpu_cfg(env)->vlen));
726 return RISCV_EXCP_NONE;
729 static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
731 *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
732 return RISCV_EXCP_NONE;
735 static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
737 #if !defined(CONFIG_USER_ONLY)
738 env->mstatus |= MSTATUS_VS;
739 #endif
740 env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
741 env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
742 return RISCV_EXCP_NONE;
745 /* User Timers and Counters */
746 static target_ulong get_ticks(bool shift)
748 int64_t val;
749 target_ulong result;
751 #if !defined(CONFIG_USER_ONLY)
752 if (icount_enabled()) {
753 val = icount_get();
754 } else {
755 val = cpu_get_host_ticks();
757 #else
758 val = cpu_get_host_ticks();
759 #endif
761 if (shift) {
762 result = val >> 32;
763 } else {
764 result = val;
767 return result;
770 #if defined(CONFIG_USER_ONLY)
771 static RISCVException read_time(CPURISCVState *env, int csrno,
772 target_ulong *val)
774 *val = cpu_get_host_ticks();
775 return RISCV_EXCP_NONE;
778 static RISCVException read_timeh(CPURISCVState *env, int csrno,
779 target_ulong *val)
781 *val = cpu_get_host_ticks() >> 32;
782 return RISCV_EXCP_NONE;
785 static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
787 *val = get_ticks(false);
788 return RISCV_EXCP_NONE;
791 static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
793 *val = get_ticks(true);
794 return RISCV_EXCP_NONE;
797 #else /* CONFIG_USER_ONLY */
799 static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
801 int evt_index = csrno - CSR_MCOUNTINHIBIT;
803 *val = env->mhpmevent_val[evt_index];
805 return RISCV_EXCP_NONE;
808 static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
810 int evt_index = csrno - CSR_MCOUNTINHIBIT;
811 uint64_t mhpmevt_val = val;
813 env->mhpmevent_val[evt_index] = val;
815 if (riscv_cpu_mxl(env) == MXL_RV32) {
816 mhpmevt_val = mhpmevt_val |
817 ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
819 riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
821 return RISCV_EXCP_NONE;
824 static int read_mhpmeventh(CPURISCVState *env, int csrno, target_ulong *val)
826 int evt_index = csrno - CSR_MHPMEVENT3H + 3;
828 *val = env->mhpmeventh_val[evt_index];
830 return RISCV_EXCP_NONE;
833 static int write_mhpmeventh(CPURISCVState *env, int csrno, target_ulong val)
835 int evt_index = csrno - CSR_MHPMEVENT3H + 3;
836 uint64_t mhpmevth_val = val;
837 uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
839 mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
840 env->mhpmeventh_val[evt_index] = val;
842 riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
844 return RISCV_EXCP_NONE;
847 static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
849 int ctr_idx = csrno - CSR_MCYCLE;
850 PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
851 uint64_t mhpmctr_val = val;
853 counter->mhpmcounter_val = val;
854 if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
855 riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
856 counter->mhpmcounter_prev = get_ticks(false);
857 if (ctr_idx > 2) {
858 if (riscv_cpu_mxl(env) == MXL_RV32) {
859 mhpmctr_val = mhpmctr_val |
860 ((uint64_t)counter->mhpmcounterh_val << 32);
862 riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
864 } else {
865 /* Other counters can keep incrementing from the given value */
866 counter->mhpmcounter_prev = val;
869 return RISCV_EXCP_NONE;
872 static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
874 int ctr_idx = csrno - CSR_MCYCLEH;
875 PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
876 uint64_t mhpmctr_val = counter->mhpmcounter_val;
877 uint64_t mhpmctrh_val = val;
879 counter->mhpmcounterh_val = val;
880 mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
881 if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
882 riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
883 counter->mhpmcounterh_prev = get_ticks(true);
884 if (ctr_idx > 2) {
885 riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
887 } else {
888 counter->mhpmcounterh_prev = val;
891 return RISCV_EXCP_NONE;
894 static RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
895 bool upper_half, uint32_t ctr_idx)
897 PMUCTRState counter = env->pmu_ctrs[ctr_idx];
898 target_ulong ctr_prev = upper_half ? counter.mhpmcounterh_prev :
899 counter.mhpmcounter_prev;
900 target_ulong ctr_val = upper_half ? counter.mhpmcounterh_val :
901 counter.mhpmcounter_val;
903 if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
905 * Counter should not increment if inhibit bit is set. We can't really
906 * stop the icount counting. Just return the counter value written by
907 * the supervisor to indicate that counter was not incremented.
909 if (!counter.started) {
910 *val = ctr_val;
911 return RISCV_EXCP_NONE;
912 } else {
913 /* Mark that the counter has been stopped */
914 counter.started = false;
919 * The kernel computes the perf delta by subtracting the current value from
920 * the value it initialized previously (ctr_val).
922 if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
923 riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
924 *val = get_ticks(upper_half) - ctr_prev + ctr_val;
925 } else {
926 *val = ctr_val;
929 return RISCV_EXCP_NONE;
932 static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
934 uint16_t ctr_index;
936 if (csrno >= CSR_MCYCLE && csrno <= CSR_MHPMCOUNTER31) {
937 ctr_index = csrno - CSR_MCYCLE;
938 } else if (csrno >= CSR_CYCLE && csrno <= CSR_HPMCOUNTER31) {
939 ctr_index = csrno - CSR_CYCLE;
940 } else {
941 return RISCV_EXCP_ILLEGAL_INST;
944 return riscv_pmu_read_ctr(env, val, false, ctr_index);
947 static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
949 uint16_t ctr_index;
951 if (csrno >= CSR_MCYCLEH && csrno <= CSR_MHPMCOUNTER31H) {
952 ctr_index = csrno - CSR_MCYCLEH;
953 } else if (csrno >= CSR_CYCLEH && csrno <= CSR_HPMCOUNTER31H) {
954 ctr_index = csrno - CSR_CYCLEH;
955 } else {
956 return RISCV_EXCP_ILLEGAL_INST;
959 return riscv_pmu_read_ctr(env, val, true, ctr_index);
962 static int read_scountovf(CPURISCVState *env, int csrno, target_ulong *val)
964 int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
965 int i;
966 *val = 0;
967 target_ulong *mhpm_evt_val;
968 uint64_t of_bit_mask;
970 if (riscv_cpu_mxl(env) == MXL_RV32) {
971 mhpm_evt_val = env->mhpmeventh_val;
972 of_bit_mask = MHPMEVENTH_BIT_OF;
973 } else {
974 mhpm_evt_val = env->mhpmevent_val;
975 of_bit_mask = MHPMEVENT_BIT_OF;
978 for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
979 if ((get_field(env->mcounteren, BIT(i))) &&
980 (mhpm_evt_val[i] & of_bit_mask)) {
981 *val |= BIT(i);
985 return RISCV_EXCP_NONE;
988 static RISCVException read_time(CPURISCVState *env, int csrno,
989 target_ulong *val)
991 uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
993 if (!env->rdtime_fn) {
994 return RISCV_EXCP_ILLEGAL_INST;
997 *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
998 return RISCV_EXCP_NONE;
1001 static RISCVException read_timeh(CPURISCVState *env, int csrno,
1002 target_ulong *val)
1004 uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
1006 if (!env->rdtime_fn) {
1007 return RISCV_EXCP_ILLEGAL_INST;
1010 *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
1011 return RISCV_EXCP_NONE;
1014 static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
1015 target_ulong *val)
1017 *val = env->vstimecmp;
1019 return RISCV_EXCP_NONE;
1022 static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
1023 target_ulong *val)
1025 *val = env->vstimecmp >> 32;
1027 return RISCV_EXCP_NONE;
1030 static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
1031 target_ulong val)
1033 if (riscv_cpu_mxl(env) == MXL_RV32) {
1034 env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
1035 } else {
1036 env->vstimecmp = val;
1039 riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
1040 env->htimedelta, MIP_VSTIP);
1042 return RISCV_EXCP_NONE;
1045 static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
1046 target_ulong val)
1048 env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
1049 riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
1050 env->htimedelta, MIP_VSTIP);
1052 return RISCV_EXCP_NONE;
1055 static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
1056 target_ulong *val)
1058 if (env->virt_enabled) {
1059 *val = env->vstimecmp;
1060 } else {
1061 *val = env->stimecmp;
1064 return RISCV_EXCP_NONE;
1067 static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
1068 target_ulong *val)
1070 if (env->virt_enabled) {
1071 *val = env->vstimecmp >> 32;
1072 } else {
1073 *val = env->stimecmp >> 32;
1076 return RISCV_EXCP_NONE;
1079 static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
1080 target_ulong val)
1082 if (env->virt_enabled) {
1083 if (env->hvictl & HVICTL_VTI) {
1084 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1086 return write_vstimecmp(env, csrno, val);
1089 if (riscv_cpu_mxl(env) == MXL_RV32) {
1090 env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
1091 } else {
1092 env->stimecmp = val;
1095 riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
1097 return RISCV_EXCP_NONE;
1100 static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
1101 target_ulong val)
1103 if (env->virt_enabled) {
1104 if (env->hvictl & HVICTL_VTI) {
1105 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1107 return write_vstimecmph(env, csrno, val);
1110 env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
1111 riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
1113 return RISCV_EXCP_NONE;
1116 /* Machine constants */
1118 #define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
1119 #define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP | \
1120 MIP_LCOFIP))
1121 #define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
1122 #define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
1124 #define VSTOPI_NUM_SRCS 5
1126 static const uint64_t delegable_ints = S_MODE_INTERRUPTS |
1127 VS_MODE_INTERRUPTS;
1128 static const uint64_t vs_delegable_ints = VS_MODE_INTERRUPTS;
1129 static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
1130 HS_MODE_INTERRUPTS;
1131 #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
1132 (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
1133 (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
1134 (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
1135 (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
1136 (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
1137 (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
1138 (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
1139 (1ULL << (RISCV_EXCP_U_ECALL)) | \
1140 (1ULL << (RISCV_EXCP_S_ECALL)) | \
1141 (1ULL << (RISCV_EXCP_VS_ECALL)) | \
1142 (1ULL << (RISCV_EXCP_M_ECALL)) | \
1143 (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
1144 (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
1145 (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
1146 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
1147 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
1148 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
1149 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
1150 static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
1151 ~((1ULL << (RISCV_EXCP_S_ECALL)) |
1152 (1ULL << (RISCV_EXCP_VS_ECALL)) |
1153 (1ULL << (RISCV_EXCP_M_ECALL)) |
1154 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
1155 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
1156 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
1157 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
1158 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
1159 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
1160 SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
1161 static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP |
1162 SIP_LCOFIP;
1163 static const target_ulong hip_writable_mask = MIP_VSSIP;
1164 static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP |
1165 MIP_VSEIP;
1166 static const target_ulong vsip_writable_mask = MIP_VSSIP;
1168 const bool valid_vm_1_10_32[16] = {
1169 [VM_1_10_MBARE] = true,
1170 [VM_1_10_SV32] = true
1173 const bool valid_vm_1_10_64[16] = {
1174 [VM_1_10_MBARE] = true,
1175 [VM_1_10_SV39] = true,
1176 [VM_1_10_SV48] = true,
1177 [VM_1_10_SV57] = true
1180 /* Machine Information Registers */
1181 static RISCVException read_zero(CPURISCVState *env, int csrno,
1182 target_ulong *val)
1184 *val = 0;
1185 return RISCV_EXCP_NONE;
1188 static RISCVException write_ignore(CPURISCVState *env, int csrno,
1189 target_ulong val)
1191 return RISCV_EXCP_NONE;
1194 static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
1195 target_ulong *val)
1197 *val = riscv_cpu_cfg(env)->mvendorid;
1198 return RISCV_EXCP_NONE;
1201 static RISCVException read_marchid(CPURISCVState *env, int csrno,
1202 target_ulong *val)
1204 *val = riscv_cpu_cfg(env)->marchid;
1205 return RISCV_EXCP_NONE;
1208 static RISCVException read_mimpid(CPURISCVState *env, int csrno,
1209 target_ulong *val)
1211 *val = riscv_cpu_cfg(env)->mimpid;
1212 return RISCV_EXCP_NONE;
1215 static RISCVException read_mhartid(CPURISCVState *env, int csrno,
1216 target_ulong *val)
1218 *val = env->mhartid;
1219 return RISCV_EXCP_NONE;
1222 /* Machine Trap Setup */
1224 /* We do not store SD explicitly, only compute it on demand. */
1225 static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
1227 if ((status & MSTATUS_FS) == MSTATUS_FS ||
1228 (status & MSTATUS_VS) == MSTATUS_VS ||
1229 (status & MSTATUS_XS) == MSTATUS_XS) {
1230 switch (xl) {
1231 case MXL_RV32:
1232 return status | MSTATUS32_SD;
1233 case MXL_RV64:
1234 return status | MSTATUS64_SD;
1235 case MXL_RV128:
1236 return MSTATUSH128_SD;
1237 default:
1238 g_assert_not_reached();
1241 return status;
1244 static RISCVException read_mstatus(CPURISCVState *env, int csrno,
1245 target_ulong *val)
1247 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
1248 return RISCV_EXCP_NONE;
1251 static bool validate_vm(CPURISCVState *env, target_ulong vm)
1253 return (vm & 0xf) <=
1254 satp_mode_max_from_map(riscv_cpu_cfg(env)->satp_mode.map);
1257 static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
1258 target_ulong val)
1260 bool valid = false;
1261 target_ulong new_mpp = get_field(val, MSTATUS_MPP);
1263 switch (new_mpp) {
1264 case PRV_M:
1265 valid = true;
1266 break;
1267 case PRV_S:
1268 valid = riscv_has_ext(env, RVS);
1269 break;
1270 case PRV_U:
1271 valid = riscv_has_ext(env, RVU);
1272 break;
1275 /* Remain field unchanged if new_mpp value is invalid */
1276 if (!valid) {
1277 val = set_field(val, MSTATUS_MPP, old_mpp);
1280 return val;
1283 static RISCVException write_mstatus(CPURISCVState *env, int csrno,
1284 target_ulong val)
1286 uint64_t mstatus = env->mstatus;
1287 uint64_t mask = 0;
1288 RISCVMXL xl = riscv_cpu_mxl(env);
1291 * MPP field have been made WARL since priv version 1.11. However,
1292 * legalization for it will not break any software running on 1.10.
1294 val = legalize_mpp(env, get_field(mstatus, MSTATUS_MPP), val);
1296 /* flush tlb on mstatus fields that affect VM */
1297 if ((val ^ mstatus) & MSTATUS_MXR) {
1298 tlb_flush(env_cpu(env));
1300 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
1301 MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
1302 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
1303 MSTATUS_TW | MSTATUS_VS;
1305 if (riscv_has_ext(env, RVF)) {
1306 mask |= MSTATUS_FS;
1309 if (xl != MXL_RV32 || env->debugger) {
1311 * RV32: MPV and GVA are not in mstatus. The current plan is to
1312 * add them to mstatush. For now, we just don't support it.
1314 mask |= MSTATUS_MPV | MSTATUS_GVA;
1315 if ((val & MSTATUS64_UXL) != 0) {
1316 mask |= MSTATUS64_UXL;
1320 mstatus = (mstatus & ~mask) | (val & mask);
1322 if (xl > MXL_RV32) {
1323 /* SXL field is for now read only */
1324 mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
1326 env->mstatus = mstatus;
1327 env->xl = cpu_recompute_xl(env);
1329 return RISCV_EXCP_NONE;
1332 static RISCVException read_mstatush(CPURISCVState *env, int csrno,
1333 target_ulong *val)
1335 *val = env->mstatus >> 32;
1336 return RISCV_EXCP_NONE;
1339 static RISCVException write_mstatush(CPURISCVState *env, int csrno,
1340 target_ulong val)
1342 uint64_t valh = (uint64_t)val << 32;
1343 uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
1345 env->mstatus = (env->mstatus & ~mask) | (valh & mask);
1347 return RISCV_EXCP_NONE;
1350 static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
1351 Int128 *val)
1353 *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128,
1354 env->mstatus));
1355 return RISCV_EXCP_NONE;
1358 static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
1359 Int128 *val)
1361 *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
1362 return RISCV_EXCP_NONE;
1365 static RISCVException read_misa(CPURISCVState *env, int csrno,
1366 target_ulong *val)
1368 target_ulong misa;
1370 switch (env->misa_mxl) {
1371 case MXL_RV32:
1372 misa = (target_ulong)MXL_RV32 << 30;
1373 break;
1374 #ifdef TARGET_RISCV64
1375 case MXL_RV64:
1376 misa = (target_ulong)MXL_RV64 << 62;
1377 break;
1378 #endif
1379 default:
1380 g_assert_not_reached();
1383 *val = misa | env->misa_ext;
1384 return RISCV_EXCP_NONE;
1387 static RISCVException write_misa(CPURISCVState *env, int csrno,
1388 target_ulong val)
1390 if (!riscv_cpu_cfg(env)->misa_w) {
1391 /* drop write to misa */
1392 return RISCV_EXCP_NONE;
1395 /* 'I' or 'E' must be present */
1396 if (!(val & (RVI | RVE))) {
1397 /* It is not, drop write to misa */
1398 return RISCV_EXCP_NONE;
1401 /* 'E' excludes all other extensions */
1402 if (val & RVE) {
1404 * when we support 'E' we can do "val = RVE;" however
1405 * for now we just drop writes if 'E' is present.
1407 return RISCV_EXCP_NONE;
1411 * misa.MXL writes are not supported by QEMU.
1412 * Drop writes to those bits.
1415 /* Mask extensions that are not supported by this hart */
1416 val &= env->misa_ext_mask;
1418 /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
1419 if ((val & RVD) && !(val & RVF)) {
1420 val &= ~RVD;
1424 * Suppress 'C' if next instruction is not aligned
1425 * TODO: this should check next_pc
1427 if ((val & RVC) && (GETPC() & ~3) != 0) {
1428 val &= ~RVC;
1431 /* If nothing changed, do nothing. */
1432 if (val == env->misa_ext) {
1433 return RISCV_EXCP_NONE;
1436 if (!(val & RVF)) {
1437 env->mstatus &= ~MSTATUS_FS;
1440 /* flush translation cache */
1441 tb_flush(env_cpu(env));
1442 env->misa_ext = val;
1443 env->xl = riscv_cpu_mxl(env);
1444 return RISCV_EXCP_NONE;
1447 static RISCVException read_medeleg(CPURISCVState *env, int csrno,
1448 target_ulong *val)
1450 *val = env->medeleg;
1451 return RISCV_EXCP_NONE;
1454 static RISCVException write_medeleg(CPURISCVState *env, int csrno,
1455 target_ulong val)
1457 env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
1458 return RISCV_EXCP_NONE;
1461 static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
1462 uint64_t *ret_val,
1463 uint64_t new_val, uint64_t wr_mask)
1465 uint64_t mask = wr_mask & delegable_ints;
1467 if (ret_val) {
1468 *ret_val = env->mideleg;
1471 env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
1473 if (riscv_has_ext(env, RVH)) {
1474 env->mideleg |= HS_MODE_INTERRUPTS;
1477 return RISCV_EXCP_NONE;
1480 static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
1481 target_ulong *ret_val,
1482 target_ulong new_val, target_ulong wr_mask)
1484 uint64_t rval;
1485 RISCVException ret;
1487 ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
1488 if (ret_val) {
1489 *ret_val = rval;
1492 return ret;
1495 static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
1496 target_ulong *ret_val,
1497 target_ulong new_val,
1498 target_ulong wr_mask)
1500 uint64_t rval;
1501 RISCVException ret;
1503 ret = rmw_mideleg64(env, csrno, &rval,
1504 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1505 if (ret_val) {
1506 *ret_val = rval >> 32;
1509 return ret;
1512 static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
1513 uint64_t *ret_val,
1514 uint64_t new_val, uint64_t wr_mask)
1516 uint64_t mask = wr_mask & all_ints;
1518 if (ret_val) {
1519 *ret_val = env->mie;
1522 env->mie = (env->mie & ~mask) | (new_val & mask);
1524 if (!riscv_has_ext(env, RVH)) {
1525 env->mie &= ~((uint64_t)MIP_SGEIP);
1528 return RISCV_EXCP_NONE;
1531 static RISCVException rmw_mie(CPURISCVState *env, int csrno,
1532 target_ulong *ret_val,
1533 target_ulong new_val, target_ulong wr_mask)
1535 uint64_t rval;
1536 RISCVException ret;
1538 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
1539 if (ret_val) {
1540 *ret_val = rval;
1543 return ret;
1546 static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
1547 target_ulong *ret_val,
1548 target_ulong new_val, target_ulong wr_mask)
1550 uint64_t rval;
1551 RISCVException ret;
1553 ret = rmw_mie64(env, csrno, &rval,
1554 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1555 if (ret_val) {
1556 *ret_val = rval >> 32;
1559 return ret;
1562 static int read_mtopi(CPURISCVState *env, int csrno, target_ulong *val)
1564 int irq;
1565 uint8_t iprio;
1567 irq = riscv_cpu_mirq_pending(env);
1568 if (irq <= 0 || irq > 63) {
1569 *val = 0;
1570 } else {
1571 iprio = env->miprio[irq];
1572 if (!iprio) {
1573 if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) {
1574 iprio = IPRIO_MMAXIPRIO;
1577 *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
1578 *val |= iprio;
1581 return RISCV_EXCP_NONE;
1584 static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
1586 if (!env->virt_enabled) {
1587 return csrno;
1590 switch (csrno) {
1591 case CSR_SISELECT:
1592 return CSR_VSISELECT;
1593 case CSR_SIREG:
1594 return CSR_VSIREG;
1595 case CSR_STOPEI:
1596 return CSR_VSTOPEI;
1597 default:
1598 return csrno;
1602 static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
1603 target_ulong new_val, target_ulong wr_mask)
1605 target_ulong *iselect;
1607 /* Translate CSR number for VS-mode */
1608 csrno = aia_xlate_vs_csrno(env, csrno);
1610 /* Find the iselect CSR based on CSR number */
1611 switch (csrno) {
1612 case CSR_MISELECT:
1613 iselect = &env->miselect;
1614 break;
1615 case CSR_SISELECT:
1616 iselect = &env->siselect;
1617 break;
1618 case CSR_VSISELECT:
1619 iselect = &env->vsiselect;
1620 break;
1621 default:
1622 return RISCV_EXCP_ILLEGAL_INST;
1625 if (val) {
1626 *val = *iselect;
1629 wr_mask &= ISELECT_MASK;
1630 if (wr_mask) {
1631 *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
1634 return RISCV_EXCP_NONE;
1637 static int rmw_iprio(target_ulong xlen,
1638 target_ulong iselect, uint8_t *iprio,
1639 target_ulong *val, target_ulong new_val,
1640 target_ulong wr_mask, int ext_irq_no)
1642 int i, firq, nirqs;
1643 target_ulong old_val;
1645 if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
1646 return -EINVAL;
1648 if (xlen != 32 && iselect & 0x1) {
1649 return -EINVAL;
1652 nirqs = 4 * (xlen / 32);
1653 firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
1655 old_val = 0;
1656 for (i = 0; i < nirqs; i++) {
1657 old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i);
1660 if (val) {
1661 *val = old_val;
1664 if (wr_mask) {
1665 new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
1666 for (i = 0; i < nirqs; i++) {
1668 * M-level and S-level external IRQ priority always read-only
1669 * zero. This means default priority order is always preferred
1670 * for M-level and S-level external IRQs.
1672 if ((firq + i) == ext_irq_no) {
1673 continue;
1675 iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
1679 return 0;
1682 static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
1683 target_ulong new_val, target_ulong wr_mask)
1685 bool virt;
1686 uint8_t *iprio;
1687 int ret = -EINVAL;
1688 target_ulong priv, isel, vgein;
1690 /* Translate CSR number for VS-mode */
1691 csrno = aia_xlate_vs_csrno(env, csrno);
1693 /* Decode register details from CSR number */
1694 virt = false;
1695 switch (csrno) {
1696 case CSR_MIREG:
1697 iprio = env->miprio;
1698 isel = env->miselect;
1699 priv = PRV_M;
1700 break;
1701 case CSR_SIREG:
1702 iprio = env->siprio;
1703 isel = env->siselect;
1704 priv = PRV_S;
1705 break;
1706 case CSR_VSIREG:
1707 iprio = env->hviprio;
1708 isel = env->vsiselect;
1709 priv = PRV_S;
1710 virt = true;
1711 break;
1712 default:
1713 goto done;
1716 /* Find the selected guest interrupt file */
1717 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1719 if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
1720 /* Local interrupt priority registers not available for VS-mode */
1721 if (!virt) {
1722 ret = rmw_iprio(riscv_cpu_mxl_bits(env),
1723 isel, iprio, val, new_val, wr_mask,
1724 (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
1726 } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) {
1727 /* IMSIC registers only available when machine implements it. */
1728 if (env->aia_ireg_rmw_fn[priv]) {
1729 /* Selected guest interrupt file should not be zero */
1730 if (virt && (!vgein || env->geilen < vgein)) {
1731 goto done;
1733 /* Call machine specific IMSIC register emulation */
1734 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1735 AIA_MAKE_IREG(isel, priv, virt, vgein,
1736 riscv_cpu_mxl_bits(env)),
1737 val, new_val, wr_mask);
1741 done:
1742 if (ret) {
1743 return (env->virt_enabled && virt) ?
1744 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1746 return RISCV_EXCP_NONE;
1749 static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
1750 target_ulong new_val, target_ulong wr_mask)
1752 bool virt;
1753 int ret = -EINVAL;
1754 target_ulong priv, vgein;
1756 /* Translate CSR number for VS-mode */
1757 csrno = aia_xlate_vs_csrno(env, csrno);
1759 /* Decode register details from CSR number */
1760 virt = false;
1761 switch (csrno) {
1762 case CSR_MTOPEI:
1763 priv = PRV_M;
1764 break;
1765 case CSR_STOPEI:
1766 priv = PRV_S;
1767 break;
1768 case CSR_VSTOPEI:
1769 priv = PRV_S;
1770 virt = true;
1771 break;
1772 default:
1773 goto done;
1776 /* IMSIC CSRs only available when machine implements IMSIC. */
1777 if (!env->aia_ireg_rmw_fn[priv]) {
1778 goto done;
1781 /* Find the selected guest interrupt file */
1782 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1784 /* Selected guest interrupt file should be valid */
1785 if (virt && (!vgein || env->geilen < vgein)) {
1786 goto done;
1789 /* Call machine specific IMSIC register emulation for TOPEI */
1790 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1791 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein,
1792 riscv_cpu_mxl_bits(env)),
1793 val, new_val, wr_mask);
1795 done:
1796 if (ret) {
1797 return (env->virt_enabled && virt) ?
1798 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1800 return RISCV_EXCP_NONE;
1803 static RISCVException read_mtvec(CPURISCVState *env, int csrno,
1804 target_ulong *val)
1806 *val = env->mtvec;
1807 return RISCV_EXCP_NONE;
1810 static RISCVException write_mtvec(CPURISCVState *env, int csrno,
1811 target_ulong val)
1813 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
1814 if ((val & 3) < 2) {
1815 env->mtvec = val;
1816 } else {
1817 qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
1819 return RISCV_EXCP_NONE;
1822 static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
1823 target_ulong *val)
1825 *val = env->mcountinhibit;
1826 return RISCV_EXCP_NONE;
1829 static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
1830 target_ulong val)
1832 int cidx;
1833 PMUCTRState *counter;
1835 env->mcountinhibit = val;
1837 /* Check if any other counter is also monitoring cycles/instructions */
1838 for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
1839 if (!get_field(env->mcountinhibit, BIT(cidx))) {
1840 counter = &env->pmu_ctrs[cidx];
1841 counter->started = true;
1845 return RISCV_EXCP_NONE;
1848 static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
1849 target_ulong *val)
1851 *val = env->mcounteren;
1852 return RISCV_EXCP_NONE;
1855 static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
1856 target_ulong val)
1858 env->mcounteren = val;
1859 return RISCV_EXCP_NONE;
1862 /* Machine Trap Handling */
1863 static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
1864 Int128 *val)
1866 *val = int128_make128(env->mscratch, env->mscratchh);
1867 return RISCV_EXCP_NONE;
1870 static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
1871 Int128 val)
1873 env->mscratch = int128_getlo(val);
1874 env->mscratchh = int128_gethi(val);
1875 return RISCV_EXCP_NONE;
1878 static RISCVException read_mscratch(CPURISCVState *env, int csrno,
1879 target_ulong *val)
1881 *val = env->mscratch;
1882 return RISCV_EXCP_NONE;
1885 static RISCVException write_mscratch(CPURISCVState *env, int csrno,
1886 target_ulong val)
1888 env->mscratch = val;
1889 return RISCV_EXCP_NONE;
1892 static RISCVException read_mepc(CPURISCVState *env, int csrno,
1893 target_ulong *val)
1895 *val = env->mepc;
1896 return RISCV_EXCP_NONE;
1899 static RISCVException write_mepc(CPURISCVState *env, int csrno,
1900 target_ulong val)
1902 env->mepc = val;
1903 return RISCV_EXCP_NONE;
1906 static RISCVException read_mcause(CPURISCVState *env, int csrno,
1907 target_ulong *val)
1909 *val = env->mcause;
1910 return RISCV_EXCP_NONE;
1913 static RISCVException write_mcause(CPURISCVState *env, int csrno,
1914 target_ulong val)
1916 env->mcause = val;
1917 return RISCV_EXCP_NONE;
1920 static RISCVException read_mtval(CPURISCVState *env, int csrno,
1921 target_ulong *val)
1923 *val = env->mtval;
1924 return RISCV_EXCP_NONE;
1927 static RISCVException write_mtval(CPURISCVState *env, int csrno,
1928 target_ulong val)
1930 env->mtval = val;
1931 return RISCV_EXCP_NONE;
1934 /* Execution environment configuration setup */
1935 static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
1936 target_ulong *val)
1938 *val = env->menvcfg;
1939 return RISCV_EXCP_NONE;
1942 static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
1943 target_ulong val)
1945 const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
1946 uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
1948 if (riscv_cpu_mxl(env) == MXL_RV64) {
1949 mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
1950 (cfg->ext_sstc ? MENVCFG_STCE : 0) |
1951 (cfg->ext_svadu ? MENVCFG_HADE : 0);
1953 env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
1955 return RISCV_EXCP_NONE;
1958 static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
1959 target_ulong *val)
1961 *val = env->menvcfg >> 32;
1962 return RISCV_EXCP_NONE;
1965 static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
1966 target_ulong val)
1968 const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
1969 uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
1970 (cfg->ext_sstc ? MENVCFG_STCE : 0) |
1971 (cfg->ext_svadu ? MENVCFG_HADE : 0);
1972 uint64_t valh = (uint64_t)val << 32;
1974 env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
1976 return RISCV_EXCP_NONE;
1979 static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
1980 target_ulong *val)
1982 RISCVException ret;
1984 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
1985 if (ret != RISCV_EXCP_NONE) {
1986 return ret;
1989 *val = env->senvcfg;
1990 return RISCV_EXCP_NONE;
1993 static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
1994 target_ulong val)
1996 uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
1997 RISCVException ret;
1999 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2000 if (ret != RISCV_EXCP_NONE) {
2001 return ret;
2004 env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
2005 return RISCV_EXCP_NONE;
2008 static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
2009 target_ulong *val)
2011 RISCVException ret;
2013 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2014 if (ret != RISCV_EXCP_NONE) {
2015 return ret;
2019 * henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
2020 * henvcfg.stce is read_only 0 when menvcfg.stce = 0
2021 * henvcfg.hade is read_only 0 when menvcfg.hade = 0
2023 *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
2024 env->menvcfg);
2025 return RISCV_EXCP_NONE;
2028 static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
2029 target_ulong val)
2031 uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
2032 RISCVException ret;
2034 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2035 if (ret != RISCV_EXCP_NONE) {
2036 return ret;
2039 if (riscv_cpu_mxl(env) == MXL_RV64) {
2040 mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE);
2043 env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
2045 return RISCV_EXCP_NONE;
2048 static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
2049 target_ulong *val)
2051 RISCVException ret;
2053 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2054 if (ret != RISCV_EXCP_NONE) {
2055 return ret;
2058 *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
2059 env->menvcfg)) >> 32;
2060 return RISCV_EXCP_NONE;
2063 static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
2064 target_ulong val)
2066 uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
2067 HENVCFG_HADE);
2068 uint64_t valh = (uint64_t)val << 32;
2069 RISCVException ret;
2071 ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2072 if (ret != RISCV_EXCP_NONE) {
2073 return ret;
2076 env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
2077 return RISCV_EXCP_NONE;
2080 static RISCVException read_mstateen(CPURISCVState *env, int csrno,
2081 target_ulong *val)
2083 *val = env->mstateen[csrno - CSR_MSTATEEN0];
2085 return RISCV_EXCP_NONE;
2088 static RISCVException write_mstateen(CPURISCVState *env, int csrno,
2089 uint64_t wr_mask, target_ulong new_val)
2091 uint64_t *reg;
2093 reg = &env->mstateen[csrno - CSR_MSTATEEN0];
2094 *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2096 return RISCV_EXCP_NONE;
2099 static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
2100 target_ulong new_val)
2102 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2104 return write_mstateen(env, csrno, wr_mask, new_val);
2107 static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
2108 target_ulong new_val)
2110 return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2113 static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
2114 target_ulong *val)
2116 *val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
2118 return RISCV_EXCP_NONE;
2121 static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
2122 uint64_t wr_mask, target_ulong new_val)
2124 uint64_t *reg, val;
2126 reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
2127 val = (uint64_t)new_val << 32;
2128 val |= *reg & 0xFFFFFFFF;
2129 *reg = (*reg & ~wr_mask) | (val & wr_mask);
2131 return RISCV_EXCP_NONE;
2134 static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
2135 target_ulong new_val)
2137 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2139 return write_mstateenh(env, csrno, wr_mask, new_val);
2142 static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
2143 target_ulong new_val)
2145 return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
2148 static RISCVException read_hstateen(CPURISCVState *env, int csrno,
2149 target_ulong *val)
2151 int index = csrno - CSR_HSTATEEN0;
2153 *val = env->hstateen[index] & env->mstateen[index];
2155 return RISCV_EXCP_NONE;
2158 static RISCVException write_hstateen(CPURISCVState *env, int csrno,
2159 uint64_t mask, target_ulong new_val)
2161 int index = csrno - CSR_HSTATEEN0;
2162 uint64_t *reg, wr_mask;
2164 reg = &env->hstateen[index];
2165 wr_mask = env->mstateen[index] & mask;
2166 *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2168 return RISCV_EXCP_NONE;
2171 static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
2172 target_ulong new_val)
2174 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2176 return write_hstateen(env, csrno, wr_mask, new_val);
2179 static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
2180 target_ulong new_val)
2182 return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2185 static RISCVException read_hstateenh(CPURISCVState *env, int csrno,
2186 target_ulong *val)
2188 int index = csrno - CSR_HSTATEEN0H;
2190 *val = (env->hstateen[index] >> 32) & (env->mstateen[index] >> 32);
2192 return RISCV_EXCP_NONE;
2195 static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
2196 uint64_t mask, target_ulong new_val)
2198 int index = csrno - CSR_HSTATEEN0H;
2199 uint64_t *reg, wr_mask, val;
2201 reg = &env->hstateen[index];
2202 val = (uint64_t)new_val << 32;
2203 val |= *reg & 0xFFFFFFFF;
2204 wr_mask = env->mstateen[index] & mask;
2205 *reg = (*reg & ~wr_mask) | (val & wr_mask);
2207 return RISCV_EXCP_NONE;
2210 static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
2211 target_ulong new_val)
2213 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2215 return write_hstateenh(env, csrno, wr_mask, new_val);
2218 static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
2219 target_ulong new_val)
2221 return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
2224 static RISCVException read_sstateen(CPURISCVState *env, int csrno,
2225 target_ulong *val)
2227 bool virt = env->virt_enabled;
2228 int index = csrno - CSR_SSTATEEN0;
2230 *val = env->sstateen[index] & env->mstateen[index];
2231 if (virt) {
2232 *val &= env->hstateen[index];
2235 return RISCV_EXCP_NONE;
2238 static RISCVException write_sstateen(CPURISCVState *env, int csrno,
2239 uint64_t mask, target_ulong new_val)
2241 bool virt = env->virt_enabled;
2242 int index = csrno - CSR_SSTATEEN0;
2243 uint64_t wr_mask;
2244 uint64_t *reg;
2246 wr_mask = env->mstateen[index] & mask;
2247 if (virt) {
2248 wr_mask &= env->hstateen[index];
2251 reg = &env->sstateen[index];
2252 *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2254 return RISCV_EXCP_NONE;
2257 static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
2258 target_ulong new_val)
2260 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2262 return write_sstateen(env, csrno, wr_mask, new_val);
2265 static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
2266 target_ulong new_val)
2268 return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2271 static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
2272 uint64_t *ret_val,
2273 uint64_t new_val, uint64_t wr_mask)
2275 uint64_t old_mip, mask = wr_mask & delegable_ints;
2276 uint32_t gin;
2278 if (mask & MIP_SEIP) {
2279 env->software_seip = new_val & MIP_SEIP;
2280 new_val |= env->external_seip * MIP_SEIP;
2283 if (riscv_cpu_cfg(env)->ext_sstc && (env->priv == PRV_M) &&
2284 get_field(env->menvcfg, MENVCFG_STCE)) {
2285 /* sstc extension forbids STIP & VSTIP to be writeable in mip */
2286 mask = mask & ~(MIP_STIP | MIP_VSTIP);
2289 if (mask) {
2290 old_mip = riscv_cpu_update_mip(env, mask, (new_val & mask));
2291 } else {
2292 old_mip = env->mip;
2295 if (csrno != CSR_HVIP) {
2296 gin = get_field(env->hstatus, HSTATUS_VGEIN);
2297 old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
2298 old_mip |= env->vstime_irq ? MIP_VSTIP : 0;
2301 if (ret_val) {
2302 *ret_val = old_mip;
2305 return RISCV_EXCP_NONE;
2308 static RISCVException rmw_mip(CPURISCVState *env, int csrno,
2309 target_ulong *ret_val,
2310 target_ulong new_val, target_ulong wr_mask)
2312 uint64_t rval;
2313 RISCVException ret;
2315 ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
2316 if (ret_val) {
2317 *ret_val = rval;
2320 return ret;
2323 static RISCVException rmw_miph(CPURISCVState *env, int csrno,
2324 target_ulong *ret_val,
2325 target_ulong new_val, target_ulong wr_mask)
2327 uint64_t rval;
2328 RISCVException ret;
2330 ret = rmw_mip64(env, csrno, &rval,
2331 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2332 if (ret_val) {
2333 *ret_val = rval >> 32;
2336 return ret;
2339 /* Supervisor Trap Setup */
2340 static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
2341 Int128 *val)
2343 uint64_t mask = sstatus_v1_10_mask;
2344 uint64_t sstatus = env->mstatus & mask;
2345 if (env->xl != MXL_RV32 || env->debugger) {
2346 mask |= SSTATUS64_UXL;
2349 *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
2350 return RISCV_EXCP_NONE;
2353 static RISCVException read_sstatus(CPURISCVState *env, int csrno,
2354 target_ulong *val)
2356 target_ulong mask = (sstatus_v1_10_mask);
2357 if (env->xl != MXL_RV32 || env->debugger) {
2358 mask |= SSTATUS64_UXL;
2360 /* TODO: Use SXL not MXL. */
2361 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
2362 return RISCV_EXCP_NONE;
2365 static RISCVException write_sstatus(CPURISCVState *env, int csrno,
2366 target_ulong val)
2368 target_ulong mask = (sstatus_v1_10_mask);
2370 if (env->xl != MXL_RV32 || env->debugger) {
2371 if ((val & SSTATUS64_UXL) != 0) {
2372 mask |= SSTATUS64_UXL;
2375 target_ulong newval = (env->mstatus & ~mask) | (val & mask);
2376 return write_mstatus(env, CSR_MSTATUS, newval);
2379 static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
2380 uint64_t *ret_val,
2381 uint64_t new_val, uint64_t wr_mask)
2383 RISCVException ret;
2384 uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
2386 /* Bring VS-level bits to correct position */
2387 new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1;
2388 wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1;
2390 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask);
2391 if (ret_val) {
2392 *ret_val = (rval & mask) >> 1;
2395 return ret;
2398 static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
2399 target_ulong *ret_val,
2400 target_ulong new_val, target_ulong wr_mask)
2402 uint64_t rval;
2403 RISCVException ret;
2405 ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
2406 if (ret_val) {
2407 *ret_val = rval;
2410 return ret;
2413 static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
2414 target_ulong *ret_val,
2415 target_ulong new_val, target_ulong wr_mask)
2417 uint64_t rval;
2418 RISCVException ret;
2420 ret = rmw_vsie64(env, csrno, &rval,
2421 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2422 if (ret_val) {
2423 *ret_val = rval >> 32;
2426 return ret;
2429 static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
2430 uint64_t *ret_val,
2431 uint64_t new_val, uint64_t wr_mask)
2433 RISCVException ret;
2434 uint64_t mask = env->mideleg & S_MODE_INTERRUPTS;
2436 if (env->virt_enabled) {
2437 if (env->hvictl & HVICTL_VTI) {
2438 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
2440 ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
2441 } else {
2442 ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask);
2445 if (ret_val) {
2446 *ret_val &= mask;
2449 return ret;
2452 static RISCVException rmw_sie(CPURISCVState *env, int csrno,
2453 target_ulong *ret_val,
2454 target_ulong new_val, target_ulong wr_mask)
2456 uint64_t rval;
2457 RISCVException ret;
2459 ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
2460 if (ret == RISCV_EXCP_NONE && ret_val) {
2461 *ret_val = rval;
2464 return ret;
2467 static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
2468 target_ulong *ret_val,
2469 target_ulong new_val, target_ulong wr_mask)
2471 uint64_t rval;
2472 RISCVException ret;
2474 ret = rmw_sie64(env, csrno, &rval,
2475 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2476 if (ret_val) {
2477 *ret_val = rval >> 32;
2480 return ret;
2483 static RISCVException read_stvec(CPURISCVState *env, int csrno,
2484 target_ulong *val)
2486 *val = env->stvec;
2487 return RISCV_EXCP_NONE;
2490 static RISCVException write_stvec(CPURISCVState *env, int csrno,
2491 target_ulong val)
2493 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
2494 if ((val & 3) < 2) {
2495 env->stvec = val;
2496 } else {
2497 qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
2499 return RISCV_EXCP_NONE;
2502 static RISCVException read_scounteren(CPURISCVState *env, int csrno,
2503 target_ulong *val)
2505 *val = env->scounteren;
2506 return RISCV_EXCP_NONE;
2509 static RISCVException write_scounteren(CPURISCVState *env, int csrno,
2510 target_ulong val)
2512 env->scounteren = val;
2513 return RISCV_EXCP_NONE;
2516 /* Supervisor Trap Handling */
2517 static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
2518 Int128 *val)
2520 *val = int128_make128(env->sscratch, env->sscratchh);
2521 return RISCV_EXCP_NONE;
2524 static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
2525 Int128 val)
2527 env->sscratch = int128_getlo(val);
2528 env->sscratchh = int128_gethi(val);
2529 return RISCV_EXCP_NONE;
2532 static RISCVException read_sscratch(CPURISCVState *env, int csrno,
2533 target_ulong *val)
2535 *val = env->sscratch;
2536 return RISCV_EXCP_NONE;
2539 static RISCVException write_sscratch(CPURISCVState *env, int csrno,
2540 target_ulong val)
2542 env->sscratch = val;
2543 return RISCV_EXCP_NONE;
2546 static RISCVException read_sepc(CPURISCVState *env, int csrno,
2547 target_ulong *val)
2549 *val = env->sepc;
2550 return RISCV_EXCP_NONE;
2553 static RISCVException write_sepc(CPURISCVState *env, int csrno,
2554 target_ulong val)
2556 env->sepc = val;
2557 return RISCV_EXCP_NONE;
2560 static RISCVException read_scause(CPURISCVState *env, int csrno,
2561 target_ulong *val)
2563 *val = env->scause;
2564 return RISCV_EXCP_NONE;
2567 static RISCVException write_scause(CPURISCVState *env, int csrno,
2568 target_ulong val)
2570 env->scause = val;
2571 return RISCV_EXCP_NONE;
2574 static RISCVException read_stval(CPURISCVState *env, int csrno,
2575 target_ulong *val)
2577 *val = env->stval;
2578 return RISCV_EXCP_NONE;
2581 static RISCVException write_stval(CPURISCVState *env, int csrno,
2582 target_ulong val)
2584 env->stval = val;
2585 return RISCV_EXCP_NONE;
2588 static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
2589 uint64_t *ret_val,
2590 uint64_t new_val, uint64_t wr_mask)
2592 RISCVException ret;
2593 uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
2595 /* Bring VS-level bits to correct position */
2596 new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1;
2597 wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1;
2599 ret = rmw_mip64(env, csrno, &rval, new_val,
2600 wr_mask & mask & vsip_writable_mask);
2601 if (ret_val) {
2602 *ret_val = (rval & mask) >> 1;
2605 return ret;
2608 static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
2609 target_ulong *ret_val,
2610 target_ulong new_val, target_ulong wr_mask)
2612 uint64_t rval;
2613 RISCVException ret;
2615 ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
2616 if (ret_val) {
2617 *ret_val = rval;
2620 return ret;
2623 static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
2624 target_ulong *ret_val,
2625 target_ulong new_val, target_ulong wr_mask)
2627 uint64_t rval;
2628 RISCVException ret;
2630 ret = rmw_vsip64(env, csrno, &rval,
2631 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2632 if (ret_val) {
2633 *ret_val = rval >> 32;
2636 return ret;
2639 static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
2640 uint64_t *ret_val,
2641 uint64_t new_val, uint64_t wr_mask)
2643 RISCVException ret;
2644 uint64_t mask = env->mideleg & sip_writable_mask;
2646 if (env->virt_enabled) {
2647 if (env->hvictl & HVICTL_VTI) {
2648 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
2650 ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
2651 } else {
2652 ret = rmw_mip64(env, csrno, ret_val, new_val, wr_mask & mask);
2655 if (ret_val) {
2656 *ret_val &= env->mideleg & S_MODE_INTERRUPTS;
2659 return ret;
2662 static RISCVException rmw_sip(CPURISCVState *env, int csrno,
2663 target_ulong *ret_val,
2664 target_ulong new_val, target_ulong wr_mask)
2666 uint64_t rval;
2667 RISCVException ret;
2669 ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
2670 if (ret_val) {
2671 *ret_val = rval;
2674 return ret;
2677 static RISCVException rmw_siph(CPURISCVState *env, int csrno,
2678 target_ulong *ret_val,
2679 target_ulong new_val, target_ulong wr_mask)
2681 uint64_t rval;
2682 RISCVException ret;
2684 ret = rmw_sip64(env, csrno, &rval,
2685 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2686 if (ret_val) {
2687 *ret_val = rval >> 32;
2690 return ret;
2693 /* Supervisor Protection and Translation */
2694 static RISCVException read_satp(CPURISCVState *env, int csrno,
2695 target_ulong *val)
2697 if (!riscv_cpu_cfg(env)->mmu) {
2698 *val = 0;
2699 return RISCV_EXCP_NONE;
2701 *val = env->satp;
2702 return RISCV_EXCP_NONE;
2705 static RISCVException write_satp(CPURISCVState *env, int csrno,
2706 target_ulong val)
2708 target_ulong mask;
2709 bool vm;
2711 if (!riscv_cpu_cfg(env)->mmu) {
2712 return RISCV_EXCP_NONE;
2715 if (riscv_cpu_mxl(env) == MXL_RV32) {
2716 vm = validate_vm(env, get_field(val, SATP32_MODE));
2717 mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
2718 } else {
2719 vm = validate_vm(env, get_field(val, SATP64_MODE));
2720 mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
2723 if (vm && mask) {
2725 * The ISA defines SATP.MODE=Bare as "no translation", but we still
2726 * pass these through QEMU's TLB emulation as it improves
2727 * performance. Flushing the TLB on SATP writes with paging
2728 * enabled avoids leaking those invalid cached mappings.
2730 tlb_flush(env_cpu(env));
2731 env->satp = val;
2733 return RISCV_EXCP_NONE;
2736 static int read_vstopi(CPURISCVState *env, int csrno, target_ulong *val)
2738 int irq, ret;
2739 target_ulong topei;
2740 uint64_t vseip, vsgein;
2741 uint32_t iid, iprio, hviid, hviprio, gein;
2742 uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS];
2744 gein = get_field(env->hstatus, HSTATUS_VGEIN);
2745 hviid = get_field(env->hvictl, HVICTL_IID);
2746 hviprio = get_field(env->hvictl, HVICTL_IPRIO);
2748 if (gein) {
2749 vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
2750 vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP;
2751 if (gein <= env->geilen && vseip) {
2752 siid[scount] = IRQ_S_EXT;
2753 siprio[scount] = IPRIO_MMAXIPRIO + 1;
2754 if (env->aia_ireg_rmw_fn[PRV_S]) {
2756 * Call machine specific IMSIC register emulation for
2757 * reading TOPEI.
2759 ret = env->aia_ireg_rmw_fn[PRV_S](
2760 env->aia_ireg_rmw_fn_arg[PRV_S],
2761 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein,
2762 riscv_cpu_mxl_bits(env)),
2763 &topei, 0, 0);
2764 if (!ret && topei) {
2765 siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK;
2768 scount++;
2770 } else {
2771 if (hviid == IRQ_S_EXT && hviprio) {
2772 siid[scount] = IRQ_S_EXT;
2773 siprio[scount] = hviprio;
2774 scount++;
2778 if (env->hvictl & HVICTL_VTI) {
2779 if (hviid != IRQ_S_EXT) {
2780 siid[scount] = hviid;
2781 siprio[scount] = hviprio;
2782 scount++;
2784 } else {
2785 irq = riscv_cpu_vsirq_pending(env);
2786 if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) {
2787 siid[scount] = irq;
2788 siprio[scount] = env->hviprio[irq];
2789 scount++;
2793 iid = 0;
2794 iprio = UINT_MAX;
2795 for (s = 0; s < scount; s++) {
2796 if (siprio[s] < iprio) {
2797 iid = siid[s];
2798 iprio = siprio[s];
2802 if (iid) {
2803 if (env->hvictl & HVICTL_IPRIOM) {
2804 if (iprio > IPRIO_MMAXIPRIO) {
2805 iprio = IPRIO_MMAXIPRIO;
2807 if (!iprio) {
2808 if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) {
2809 iprio = IPRIO_MMAXIPRIO;
2812 } else {
2813 iprio = 1;
2815 } else {
2816 iprio = 0;
2819 *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2820 *val |= iprio;
2821 return RISCV_EXCP_NONE;
2824 static int read_stopi(CPURISCVState *env, int csrno, target_ulong *val)
2826 int irq;
2827 uint8_t iprio;
2829 if (env->virt_enabled) {
2830 return read_vstopi(env, CSR_VSTOPI, val);
2833 irq = riscv_cpu_sirq_pending(env);
2834 if (irq <= 0 || irq > 63) {
2835 *val = 0;
2836 } else {
2837 iprio = env->siprio[irq];
2838 if (!iprio) {
2839 if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) {
2840 iprio = IPRIO_MMAXIPRIO;
2843 *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2844 *val |= iprio;
2847 return RISCV_EXCP_NONE;
2850 /* Hypervisor Extensions */
2851 static RISCVException read_hstatus(CPURISCVState *env, int csrno,
2852 target_ulong *val)
2854 *val = env->hstatus;
2855 if (riscv_cpu_mxl(env) != MXL_RV32) {
2856 /* We only support 64-bit VSXL */
2857 *val = set_field(*val, HSTATUS_VSXL, 2);
2859 /* We only support little endian */
2860 *val = set_field(*val, HSTATUS_VSBE, 0);
2861 return RISCV_EXCP_NONE;
2864 static RISCVException write_hstatus(CPURISCVState *env, int csrno,
2865 target_ulong val)
2867 env->hstatus = val;
2868 if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
2869 qemu_log_mask(LOG_UNIMP,
2870 "QEMU does not support mixed HSXLEN options.");
2872 if (get_field(val, HSTATUS_VSBE) != 0) {
2873 qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
2875 return RISCV_EXCP_NONE;
2878 static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
2879 target_ulong *val)
2881 *val = env->hedeleg;
2882 return RISCV_EXCP_NONE;
2885 static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
2886 target_ulong val)
2888 env->hedeleg = val & vs_delegable_excps;
2889 return RISCV_EXCP_NONE;
2892 static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
2893 uint64_t *ret_val,
2894 uint64_t new_val, uint64_t wr_mask)
2896 uint64_t mask = wr_mask & vs_delegable_ints;
2898 if (ret_val) {
2899 *ret_val = env->hideleg & vs_delegable_ints;
2902 env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
2903 return RISCV_EXCP_NONE;
2906 static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
2907 target_ulong *ret_val,
2908 target_ulong new_val, target_ulong wr_mask)
2910 uint64_t rval;
2911 RISCVException ret;
2913 ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
2914 if (ret_val) {
2915 *ret_val = rval;
2918 return ret;
2921 static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
2922 target_ulong *ret_val,
2923 target_ulong new_val, target_ulong wr_mask)
2925 uint64_t rval;
2926 RISCVException ret;
2928 ret = rmw_hideleg64(env, csrno, &rval,
2929 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2930 if (ret_val) {
2931 *ret_val = rval >> 32;
2934 return ret;
2937 static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
2938 uint64_t *ret_val,
2939 uint64_t new_val, uint64_t wr_mask)
2941 RISCVException ret;
2943 ret = rmw_mip64(env, csrno, ret_val, new_val,
2944 wr_mask & hvip_writable_mask);
2945 if (ret_val) {
2946 *ret_val &= VS_MODE_INTERRUPTS;
2949 return ret;
2952 static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
2953 target_ulong *ret_val,
2954 target_ulong new_val, target_ulong wr_mask)
2956 uint64_t rval;
2957 RISCVException ret;
2959 ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
2960 if (ret_val) {
2961 *ret_val = rval;
2964 return ret;
2967 static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
2968 target_ulong *ret_val,
2969 target_ulong new_val, target_ulong wr_mask)
2971 uint64_t rval;
2972 RISCVException ret;
2974 ret = rmw_hvip64(env, csrno, &rval,
2975 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2976 if (ret_val) {
2977 *ret_val = rval >> 32;
2980 return ret;
2983 static RISCVException rmw_hip(CPURISCVState *env, int csrno,
2984 target_ulong *ret_value,
2985 target_ulong new_value, target_ulong write_mask)
2987 int ret = rmw_mip(env, csrno, ret_value, new_value,
2988 write_mask & hip_writable_mask);
2990 if (ret_value) {
2991 *ret_value &= HS_MODE_INTERRUPTS;
2993 return ret;
2996 static RISCVException rmw_hie(CPURISCVState *env, int csrno,
2997 target_ulong *ret_val,
2998 target_ulong new_val, target_ulong wr_mask)
3000 uint64_t rval;
3001 RISCVException ret;
3003 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
3004 if (ret_val) {
3005 *ret_val = rval & HS_MODE_INTERRUPTS;
3008 return ret;
3011 static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
3012 target_ulong *val)
3014 *val = env->hcounteren;
3015 return RISCV_EXCP_NONE;
3018 static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
3019 target_ulong val)
3021 env->hcounteren = val;
3022 return RISCV_EXCP_NONE;
3025 static RISCVException read_hgeie(CPURISCVState *env, int csrno,
3026 target_ulong *val)
3028 if (val) {
3029 *val = env->hgeie;
3031 return RISCV_EXCP_NONE;
3034 static RISCVException write_hgeie(CPURISCVState *env, int csrno,
3035 target_ulong val)
3037 /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
3038 val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
3039 env->hgeie = val;
3040 /* Update mip.SGEIP bit */
3041 riscv_cpu_update_mip(env, MIP_SGEIP,
3042 BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
3043 return RISCV_EXCP_NONE;
3046 static RISCVException read_htval(CPURISCVState *env, int csrno,
3047 target_ulong *val)
3049 *val = env->htval;
3050 return RISCV_EXCP_NONE;
3053 static RISCVException write_htval(CPURISCVState *env, int csrno,
3054 target_ulong val)
3056 env->htval = val;
3057 return RISCV_EXCP_NONE;
3060 static RISCVException read_htinst(CPURISCVState *env, int csrno,
3061 target_ulong *val)
3063 *val = env->htinst;
3064 return RISCV_EXCP_NONE;
3067 static RISCVException write_htinst(CPURISCVState *env, int csrno,
3068 target_ulong val)
3070 return RISCV_EXCP_NONE;
3073 static RISCVException read_hgeip(CPURISCVState *env, int csrno,
3074 target_ulong *val)
3076 if (val) {
3077 *val = env->hgeip;
3079 return RISCV_EXCP_NONE;
3082 static RISCVException read_hgatp(CPURISCVState *env, int csrno,
3083 target_ulong *val)
3085 *val = env->hgatp;
3086 return RISCV_EXCP_NONE;
3089 static RISCVException write_hgatp(CPURISCVState *env, int csrno,
3090 target_ulong val)
3092 env->hgatp = val;
3093 return RISCV_EXCP_NONE;
3096 static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
3097 target_ulong *val)
3099 if (!env->rdtime_fn) {
3100 return RISCV_EXCP_ILLEGAL_INST;
3103 *val = env->htimedelta;
3104 return RISCV_EXCP_NONE;
3107 static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
3108 target_ulong val)
3110 if (!env->rdtime_fn) {
3111 return RISCV_EXCP_ILLEGAL_INST;
3114 if (riscv_cpu_mxl(env) == MXL_RV32) {
3115 env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
3116 } else {
3117 env->htimedelta = val;
3120 if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
3121 riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
3122 env->htimedelta, MIP_VSTIP);
3125 return RISCV_EXCP_NONE;
3128 static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
3129 target_ulong *val)
3131 if (!env->rdtime_fn) {
3132 return RISCV_EXCP_ILLEGAL_INST;
3135 *val = env->htimedelta >> 32;
3136 return RISCV_EXCP_NONE;
3139 static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
3140 target_ulong val)
3142 if (!env->rdtime_fn) {
3143 return RISCV_EXCP_ILLEGAL_INST;
3146 env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
3148 if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
3149 riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
3150 env->htimedelta, MIP_VSTIP);
3153 return RISCV_EXCP_NONE;
3156 static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val)
3158 *val = env->hvictl;
3159 return RISCV_EXCP_NONE;
3162 static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val)
3164 env->hvictl = val & HVICTL_VALID_MASK;
3165 return RISCV_EXCP_NONE;
3168 static int read_hvipriox(CPURISCVState *env, int first_index,
3169 uint8_t *iprio, target_ulong *val)
3171 int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
3173 /* First index has to be a multiple of number of irqs per register */
3174 if (first_index % num_irqs) {
3175 return (env->virt_enabled) ?
3176 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
3179 /* Fill-up return value */
3180 *val = 0;
3181 for (i = 0; i < num_irqs; i++) {
3182 if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
3183 continue;
3185 if (rdzero) {
3186 continue;
3188 *val |= ((target_ulong)iprio[irq]) << (i * 8);
3191 return RISCV_EXCP_NONE;
3194 static int write_hvipriox(CPURISCVState *env, int first_index,
3195 uint8_t *iprio, target_ulong val)
3197 int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
3199 /* First index has to be a multiple of number of irqs per register */
3200 if (first_index % num_irqs) {
3201 return (env->virt_enabled) ?
3202 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
3205 /* Fill-up priority arrary */
3206 for (i = 0; i < num_irqs; i++) {
3207 if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
3208 continue;
3210 if (rdzero) {
3211 iprio[irq] = 0;
3212 } else {
3213 iprio[irq] = (val >> (i * 8)) & 0xff;
3217 return RISCV_EXCP_NONE;
3220 static int read_hviprio1(CPURISCVState *env, int csrno, target_ulong *val)
3222 return read_hvipriox(env, 0, env->hviprio, val);
3225 static int write_hviprio1(CPURISCVState *env, int csrno, target_ulong val)
3227 return write_hvipriox(env, 0, env->hviprio, val);
3230 static int read_hviprio1h(CPURISCVState *env, int csrno, target_ulong *val)
3232 return read_hvipriox(env, 4, env->hviprio, val);
3235 static int write_hviprio1h(CPURISCVState *env, int csrno, target_ulong val)
3237 return write_hvipriox(env, 4, env->hviprio, val);
3240 static int read_hviprio2(CPURISCVState *env, int csrno, target_ulong *val)
3242 return read_hvipriox(env, 8, env->hviprio, val);
3245 static int write_hviprio2(CPURISCVState *env, int csrno, target_ulong val)
3247 return write_hvipriox(env, 8, env->hviprio, val);
3250 static int read_hviprio2h(CPURISCVState *env, int csrno, target_ulong *val)
3252 return read_hvipriox(env, 12, env->hviprio, val);
3255 static int write_hviprio2h(CPURISCVState *env, int csrno, target_ulong val)
3257 return write_hvipriox(env, 12, env->hviprio, val);
3260 /* Virtual CSR Registers */
3261 static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
3262 target_ulong *val)
3264 *val = env->vsstatus;
3265 return RISCV_EXCP_NONE;
3268 static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
3269 target_ulong val)
3271 uint64_t mask = (target_ulong)-1;
3272 if ((val & VSSTATUS64_UXL) == 0) {
3273 mask &= ~VSSTATUS64_UXL;
3275 env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
3276 return RISCV_EXCP_NONE;
3279 static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
3281 *val = env->vstvec;
3282 return RISCV_EXCP_NONE;
3285 static RISCVException write_vstvec(CPURISCVState *env, int csrno,
3286 target_ulong val)
3288 env->vstvec = val;
3289 return RISCV_EXCP_NONE;
3292 static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
3293 target_ulong *val)
3295 *val = env->vsscratch;
3296 return RISCV_EXCP_NONE;
3299 static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
3300 target_ulong val)
3302 env->vsscratch = val;
3303 return RISCV_EXCP_NONE;
3306 static RISCVException read_vsepc(CPURISCVState *env, int csrno,
3307 target_ulong *val)
3309 *val = env->vsepc;
3310 return RISCV_EXCP_NONE;
3313 static RISCVException write_vsepc(CPURISCVState *env, int csrno,
3314 target_ulong val)
3316 env->vsepc = val;
3317 return RISCV_EXCP_NONE;
3320 static RISCVException read_vscause(CPURISCVState *env, int csrno,
3321 target_ulong *val)
3323 *val = env->vscause;
3324 return RISCV_EXCP_NONE;
3327 static RISCVException write_vscause(CPURISCVState *env, int csrno,
3328 target_ulong val)
3330 env->vscause = val;
3331 return RISCV_EXCP_NONE;
3334 static RISCVException read_vstval(CPURISCVState *env, int csrno,
3335 target_ulong *val)
3337 *val = env->vstval;
3338 return RISCV_EXCP_NONE;
3341 static RISCVException write_vstval(CPURISCVState *env, int csrno,
3342 target_ulong val)
3344 env->vstval = val;
3345 return RISCV_EXCP_NONE;
3348 static RISCVException read_vsatp(CPURISCVState *env, int csrno,
3349 target_ulong *val)
3351 *val = env->vsatp;
3352 return RISCV_EXCP_NONE;
3355 static RISCVException write_vsatp(CPURISCVState *env, int csrno,
3356 target_ulong val)
3358 env->vsatp = val;
3359 return RISCV_EXCP_NONE;
3362 static RISCVException read_mtval2(CPURISCVState *env, int csrno,
3363 target_ulong *val)
3365 *val = env->mtval2;
3366 return RISCV_EXCP_NONE;
3369 static RISCVException write_mtval2(CPURISCVState *env, int csrno,
3370 target_ulong val)
3372 env->mtval2 = val;
3373 return RISCV_EXCP_NONE;
3376 static RISCVException read_mtinst(CPURISCVState *env, int csrno,
3377 target_ulong *val)
3379 *val = env->mtinst;
3380 return RISCV_EXCP_NONE;
3383 static RISCVException write_mtinst(CPURISCVState *env, int csrno,
3384 target_ulong val)
3386 env->mtinst = val;
3387 return RISCV_EXCP_NONE;
3390 /* Physical Memory Protection */
3391 static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
3392 target_ulong *val)
3394 *val = mseccfg_csr_read(env);
3395 return RISCV_EXCP_NONE;
3398 static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
3399 target_ulong val)
3401 mseccfg_csr_write(env, val);
3402 return RISCV_EXCP_NONE;
3405 static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
3406 target_ulong *val)
3408 uint32_t reg_index = csrno - CSR_PMPCFG0;
3410 *val = pmpcfg_csr_read(env, reg_index);
3411 return RISCV_EXCP_NONE;
3414 static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
3415 target_ulong val)
3417 uint32_t reg_index = csrno - CSR_PMPCFG0;
3419 pmpcfg_csr_write(env, reg_index, val);
3420 return RISCV_EXCP_NONE;
3423 static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
3424 target_ulong *val)
3426 *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
3427 return RISCV_EXCP_NONE;
3430 static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
3431 target_ulong val)
3433 pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
3434 return RISCV_EXCP_NONE;
3437 static RISCVException read_tselect(CPURISCVState *env, int csrno,
3438 target_ulong *val)
3440 *val = tselect_csr_read(env);
3441 return RISCV_EXCP_NONE;
3444 static RISCVException write_tselect(CPURISCVState *env, int csrno,
3445 target_ulong val)
3447 tselect_csr_write(env, val);
3448 return RISCV_EXCP_NONE;
3451 static RISCVException read_tdata(CPURISCVState *env, int csrno,
3452 target_ulong *val)
3454 /* return 0 in tdata1 to end the trigger enumeration */
3455 if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
3456 *val = 0;
3457 return RISCV_EXCP_NONE;
3460 if (!tdata_available(env, csrno - CSR_TDATA1)) {
3461 return RISCV_EXCP_ILLEGAL_INST;
3464 *val = tdata_csr_read(env, csrno - CSR_TDATA1);
3465 return RISCV_EXCP_NONE;
3468 static RISCVException write_tdata(CPURISCVState *env, int csrno,
3469 target_ulong val)
3471 if (!tdata_available(env, csrno - CSR_TDATA1)) {
3472 return RISCV_EXCP_ILLEGAL_INST;
3475 tdata_csr_write(env, csrno - CSR_TDATA1, val);
3476 return RISCV_EXCP_NONE;
3479 static RISCVException read_tinfo(CPURISCVState *env, int csrno,
3480 target_ulong *val)
3482 *val = tinfo_csr_read(env);
3483 return RISCV_EXCP_NONE;
3487 * Functions to access Pointer Masking feature registers
3488 * We have to check if current priv lvl could modify
3489 * csr in given mode
3491 static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
3493 int csr_priv = get_field(csrno, 0x300);
3494 int pm_current;
3496 if (env->debugger) {
3497 return false;
3500 * If priv lvls differ that means we're accessing csr from higher priv lvl,
3501 * so allow the access
3503 if (env->priv != csr_priv) {
3504 return false;
3506 switch (env->priv) {
3507 case PRV_M:
3508 pm_current = get_field(env->mmte, M_PM_CURRENT);
3509 break;
3510 case PRV_S:
3511 pm_current = get_field(env->mmte, S_PM_CURRENT);
3512 break;
3513 case PRV_U:
3514 pm_current = get_field(env->mmte, U_PM_CURRENT);
3515 break;
3516 default:
3517 g_assert_not_reached();
3519 /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
3520 return !pm_current;
3523 static RISCVException read_mmte(CPURISCVState *env, int csrno,
3524 target_ulong *val)
3526 *val = env->mmte & MMTE_MASK;
3527 return RISCV_EXCP_NONE;
3530 static RISCVException write_mmte(CPURISCVState *env, int csrno,
3531 target_ulong val)
3533 uint64_t mstatus;
3534 target_ulong wpri_val = val & MMTE_MASK;
3536 if (val != wpri_val) {
3537 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
3538 TARGET_FMT_lx "\n", "MMTE: WPRI violation written 0x",
3539 val, "vs expected 0x", wpri_val);
3541 /* for machine mode pm.current is hardwired to 1 */
3542 wpri_val |= MMTE_M_PM_CURRENT;
3544 /* hardwiring pm.instruction bit to 0, since it's not supported yet */
3545 wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
3546 env->mmte = wpri_val | EXT_STATUS_DIRTY;
3547 riscv_cpu_update_mask(env);
3549 /* Set XS and SD bits, since PM CSRs are dirty */
3550 mstatus = env->mstatus | MSTATUS_XS;
3551 write_mstatus(env, csrno, mstatus);
3552 return RISCV_EXCP_NONE;
3555 static RISCVException read_smte(CPURISCVState *env, int csrno,
3556 target_ulong *val)
3558 *val = env->mmte & SMTE_MASK;
3559 return RISCV_EXCP_NONE;
3562 static RISCVException write_smte(CPURISCVState *env, int csrno,
3563 target_ulong val)
3565 target_ulong wpri_val = val & SMTE_MASK;
3567 if (val != wpri_val) {
3568 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
3569 TARGET_FMT_lx "\n", "SMTE: WPRI violation written 0x",
3570 val, "vs expected 0x", wpri_val);
3573 /* if pm.current==0 we can't modify current PM CSRs */
3574 if (check_pm_current_disabled(env, csrno)) {
3575 return RISCV_EXCP_NONE;
3578 wpri_val |= (env->mmte & ~SMTE_MASK);
3579 write_mmte(env, csrno, wpri_val);
3580 return RISCV_EXCP_NONE;
3583 static RISCVException read_umte(CPURISCVState *env, int csrno,
3584 target_ulong *val)
3586 *val = env->mmte & UMTE_MASK;
3587 return RISCV_EXCP_NONE;
3590 static RISCVException write_umte(CPURISCVState *env, int csrno,
3591 target_ulong val)
3593 target_ulong wpri_val = val & UMTE_MASK;
3595 if (val != wpri_val) {
3596 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
3597 TARGET_FMT_lx "\n", "UMTE: WPRI violation written 0x",
3598 val, "vs expected 0x", wpri_val);
3601 if (check_pm_current_disabled(env, csrno)) {
3602 return RISCV_EXCP_NONE;
3605 wpri_val |= (env->mmte & ~UMTE_MASK);
3606 write_mmte(env, csrno, wpri_val);
3607 return RISCV_EXCP_NONE;
3610 static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
3611 target_ulong *val)
3613 *val = env->mpmmask;
3614 return RISCV_EXCP_NONE;
3617 static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
3618 target_ulong val)
3620 uint64_t mstatus;
3622 env->mpmmask = val;
3623 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
3624 env->cur_pmmask = val;
3626 env->mmte |= EXT_STATUS_DIRTY;
3628 /* Set XS and SD bits, since PM CSRs are dirty */
3629 mstatus = env->mstatus | MSTATUS_XS;
3630 write_mstatus(env, csrno, mstatus);
3631 return RISCV_EXCP_NONE;
3634 static RISCVException read_spmmask(CPURISCVState *env, int csrno,
3635 target_ulong *val)
3637 *val = env->spmmask;
3638 return RISCV_EXCP_NONE;
3641 static RISCVException write_spmmask(CPURISCVState *env, int csrno,
3642 target_ulong val)
3644 uint64_t mstatus;
3646 /* if pm.current==0 we can't modify current PM CSRs */
3647 if (check_pm_current_disabled(env, csrno)) {
3648 return RISCV_EXCP_NONE;
3650 env->spmmask = val;
3651 if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
3652 env->cur_pmmask = val;
3654 env->mmte |= EXT_STATUS_DIRTY;
3656 /* Set XS and SD bits, since PM CSRs are dirty */
3657 mstatus = env->mstatus | MSTATUS_XS;
3658 write_mstatus(env, csrno, mstatus);
3659 return RISCV_EXCP_NONE;
3662 static RISCVException read_upmmask(CPURISCVState *env, int csrno,
3663 target_ulong *val)
3665 *val = env->upmmask;
3666 return RISCV_EXCP_NONE;
3669 static RISCVException write_upmmask(CPURISCVState *env, int csrno,
3670 target_ulong val)
3672 uint64_t mstatus;
3674 /* if pm.current==0 we can't modify current PM CSRs */
3675 if (check_pm_current_disabled(env, csrno)) {
3676 return RISCV_EXCP_NONE;
3678 env->upmmask = val;
3679 if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
3680 env->cur_pmmask = val;
3682 env->mmte |= EXT_STATUS_DIRTY;
3684 /* Set XS and SD bits, since PM CSRs are dirty */
3685 mstatus = env->mstatus | MSTATUS_XS;
3686 write_mstatus(env, csrno, mstatus);
3687 return RISCV_EXCP_NONE;
3690 static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
3691 target_ulong *val)
3693 *val = env->mpmbase;
3694 return RISCV_EXCP_NONE;
3697 static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
3698 target_ulong val)
3700 uint64_t mstatus;
3702 env->mpmbase = val;
3703 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
3704 env->cur_pmbase = val;
3706 env->mmte |= EXT_STATUS_DIRTY;
3708 /* Set XS and SD bits, since PM CSRs are dirty */
3709 mstatus = env->mstatus | MSTATUS_XS;
3710 write_mstatus(env, csrno, mstatus);
3711 return RISCV_EXCP_NONE;
3714 static RISCVException read_spmbase(CPURISCVState *env, int csrno,
3715 target_ulong *val)
3717 *val = env->spmbase;
3718 return RISCV_EXCP_NONE;
3721 static RISCVException write_spmbase(CPURISCVState *env, int csrno,
3722 target_ulong val)
3724 uint64_t mstatus;
3726 /* if pm.current==0 we can't modify current PM CSRs */
3727 if (check_pm_current_disabled(env, csrno)) {
3728 return RISCV_EXCP_NONE;
3730 env->spmbase = val;
3731 if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
3732 env->cur_pmbase = val;
3734 env->mmte |= EXT_STATUS_DIRTY;
3736 /* Set XS and SD bits, since PM CSRs are dirty */
3737 mstatus = env->mstatus | MSTATUS_XS;
3738 write_mstatus(env, csrno, mstatus);
3739 return RISCV_EXCP_NONE;
3742 static RISCVException read_upmbase(CPURISCVState *env, int csrno,
3743 target_ulong *val)
3745 *val = env->upmbase;
3746 return RISCV_EXCP_NONE;
3749 static RISCVException write_upmbase(CPURISCVState *env, int csrno,
3750 target_ulong val)
3752 uint64_t mstatus;
3754 /* if pm.current==0 we can't modify current PM CSRs */
3755 if (check_pm_current_disabled(env, csrno)) {
3756 return RISCV_EXCP_NONE;
3758 env->upmbase = val;
3759 if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
3760 env->cur_pmbase = val;
3762 env->mmte |= EXT_STATUS_DIRTY;
3764 /* Set XS and SD bits, since PM CSRs are dirty */
3765 mstatus = env->mstatus | MSTATUS_XS;
3766 write_mstatus(env, csrno, mstatus);
3767 return RISCV_EXCP_NONE;
3770 #endif
3772 /* Crypto Extension */
3773 static RISCVException rmw_seed(CPURISCVState *env, int csrno,
3774 target_ulong *ret_value,
3775 target_ulong new_value,
3776 target_ulong write_mask)
3778 uint16_t random_v;
3779 Error *random_e = NULL;
3780 int random_r;
3781 target_ulong rval;
3783 random_r = qemu_guest_getrandom(&random_v, 2, &random_e);
3784 if (unlikely(random_r < 0)) {
3786 * Failed, for unknown reasons in the crypto subsystem.
3787 * The best we can do is log the reason and return a
3788 * failure indication to the guest. There is no reason
3789 * we know to expect the failure to be transitory, so
3790 * indicate DEAD to avoid having the guest spin on WAIT.
3792 qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
3793 __func__, error_get_pretty(random_e));
3794 error_free(random_e);
3795 rval = SEED_OPST_DEAD;
3796 } else {
3797 rval = random_v | SEED_OPST_ES16;
3800 if (ret_value) {
3801 *ret_value = rval;
3804 return RISCV_EXCP_NONE;
3808 * riscv_csrrw - read and/or update control and status register
3810 * csrr <-> riscv_csrrw(env, csrno, ret_value, 0, 0);
3811 * csrrw <-> riscv_csrrw(env, csrno, ret_value, value, -1);
3812 * csrrs <-> riscv_csrrw(env, csrno, ret_value, -1, value);
3813 * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value);
3816 static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
3817 int csrno,
3818 bool write_mask)
3820 /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
3821 bool read_only = get_field(csrno, 0xC00) == 3;
3822 int csr_min_priv = csr_ops[csrno].min_priv_ver;
3824 /* ensure the CSR extension is enabled */
3825 if (!riscv_cpu_cfg(env)->ext_icsr) {
3826 return RISCV_EXCP_ILLEGAL_INST;
3829 /* ensure CSR is implemented by checking predicate */
3830 if (!csr_ops[csrno].predicate) {
3831 return RISCV_EXCP_ILLEGAL_INST;
3834 /* privileged spec version check */
3835 if (env->priv_ver < csr_min_priv) {
3836 return RISCV_EXCP_ILLEGAL_INST;
3839 /* read / write check */
3840 if (write_mask && read_only) {
3841 return RISCV_EXCP_ILLEGAL_INST;
3845 * The predicate() not only does existence check but also does some
3846 * access control check which triggers for example virtual instruction
3847 * exception in some cases. When writing read-only CSRs in those cases
3848 * illegal instruction exception should be triggered instead of virtual
3849 * instruction exception. Hence this comes after the read / write check.
3851 RISCVException ret = csr_ops[csrno].predicate(env, csrno);
3852 if (ret != RISCV_EXCP_NONE) {
3853 return ret;
3856 #if !defined(CONFIG_USER_ONLY)
3857 int csr_priv, effective_priv = env->priv;
3859 if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
3860 !env->virt_enabled) {
3862 * We are in HS mode. Add 1 to the effective privledge level to
3863 * allow us to access the Hypervisor CSRs.
3865 effective_priv++;
3868 csr_priv = get_field(csrno, 0x300);
3869 if (!env->debugger && (effective_priv < csr_priv)) {
3870 if (csr_priv == (PRV_S + 1) && env->virt_enabled) {
3871 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
3873 return RISCV_EXCP_ILLEGAL_INST;
3875 #endif
3876 return RISCV_EXCP_NONE;
3879 static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
3880 target_ulong *ret_value,
3881 target_ulong new_value,
3882 target_ulong write_mask)
3884 RISCVException ret;
3885 target_ulong old_value;
3887 /* execute combined read/write operation if it exists */
3888 if (csr_ops[csrno].op) {
3889 return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
3892 /* if no accessor exists then return failure */
3893 if (!csr_ops[csrno].read) {
3894 return RISCV_EXCP_ILLEGAL_INST;
3896 /* read old value */
3897 ret = csr_ops[csrno].read(env, csrno, &old_value);
3898 if (ret != RISCV_EXCP_NONE) {
3899 return ret;
3902 /* write value if writable and write mask set, otherwise drop writes */
3903 if (write_mask) {
3904 new_value = (old_value & ~write_mask) | (new_value & write_mask);
3905 if (csr_ops[csrno].write) {
3906 ret = csr_ops[csrno].write(env, csrno, new_value);
3907 if (ret != RISCV_EXCP_NONE) {
3908 return ret;
3913 /* return old value */
3914 if (ret_value) {
3915 *ret_value = old_value;
3918 return RISCV_EXCP_NONE;
3921 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
3922 target_ulong *ret_value,
3923 target_ulong new_value, target_ulong write_mask)
3925 RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
3926 if (ret != RISCV_EXCP_NONE) {
3927 return ret;
3930 return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
3933 static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
3934 Int128 *ret_value,
3935 Int128 new_value,
3936 Int128 write_mask)
3938 RISCVException ret;
3939 Int128 old_value;
3941 /* read old value */
3942 ret = csr_ops[csrno].read128(env, csrno, &old_value);
3943 if (ret != RISCV_EXCP_NONE) {
3944 return ret;
3947 /* write value if writable and write mask set, otherwise drop writes */
3948 if (int128_nz(write_mask)) {
3949 new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
3950 int128_and(new_value, write_mask));
3951 if (csr_ops[csrno].write128) {
3952 ret = csr_ops[csrno].write128(env, csrno, new_value);
3953 if (ret != RISCV_EXCP_NONE) {
3954 return ret;
3956 } else if (csr_ops[csrno].write) {
3957 /* avoids having to write wrappers for all registers */
3958 ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
3959 if (ret != RISCV_EXCP_NONE) {
3960 return ret;
3965 /* return old value */
3966 if (ret_value) {
3967 *ret_value = old_value;
3970 return RISCV_EXCP_NONE;
3973 RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
3974 Int128 *ret_value,
3975 Int128 new_value, Int128 write_mask)
3977 RISCVException ret;
3979 ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
3980 if (ret != RISCV_EXCP_NONE) {
3981 return ret;
3984 if (csr_ops[csrno].read128) {
3985 return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
3989 * Fall back to 64-bit version for now, if the 128-bit alternative isn't
3990 * at all defined.
3991 * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
3992 * significant), for those, this fallback is correctly handling the
3993 * accesses
3995 target_ulong old_value;
3996 ret = riscv_csrrw_do64(env, csrno, &old_value,
3997 int128_getlo(new_value),
3998 int128_getlo(write_mask));
3999 if (ret == RISCV_EXCP_NONE && ret_value) {
4000 *ret_value = int128_make64(old_value);
4002 return ret;
4006 * Debugger support. If not in user mode, set env->debugger before the
4007 * riscv_csrrw call and clear it after the call.
4009 RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
4010 target_ulong *ret_value,
4011 target_ulong new_value,
4012 target_ulong write_mask)
4014 RISCVException ret;
4015 #if !defined(CONFIG_USER_ONLY)
4016 env->debugger = true;
4017 #endif
4018 ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
4019 #if !defined(CONFIG_USER_ONLY)
4020 env->debugger = false;
4021 #endif
4022 return ret;
4025 static RISCVException read_jvt(CPURISCVState *env, int csrno,
4026 target_ulong *val)
4028 *val = env->jvt;
4029 return RISCV_EXCP_NONE;
4032 static RISCVException write_jvt(CPURISCVState *env, int csrno,
4033 target_ulong val)
4035 env->jvt = val;
4036 return RISCV_EXCP_NONE;
4040 * Control and Status Register function table
4041 * riscv_csr_operations::predicate() must be provided for an implemented CSR
4043 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
4044 /* User Floating-Point CSRs */
4045 [CSR_FFLAGS] = { "fflags", fs, read_fflags, write_fflags },
4046 [CSR_FRM] = { "frm", fs, read_frm, write_frm },
4047 [CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr },
4048 /* Vector CSRs */
4049 [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart },
4050 [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat },
4051 [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm },
4052 [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr },
4053 [CSR_VL] = { "vl", vs, read_vl },
4054 [CSR_VTYPE] = { "vtype", vs, read_vtype },
4055 [CSR_VLENB] = { "vlenb", vs, read_vlenb },
4056 /* User Timers and Counters */
4057 [CSR_CYCLE] = { "cycle", ctr, read_hpmcounter },
4058 [CSR_INSTRET] = { "instret", ctr, read_hpmcounter },
4059 [CSR_CYCLEH] = { "cycleh", ctr32, read_hpmcounterh },
4060 [CSR_INSTRETH] = { "instreth", ctr32, read_hpmcounterh },
4063 * In privileged mode, the monitor will have to emulate TIME CSRs only if
4064 * rdtime callback is not provided by machine/platform emulation.
4066 [CSR_TIME] = { "time", ctr, read_time },
4067 [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
4069 /* Crypto Extension */
4070 [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
4072 /* Zcmt Extension */
4073 [CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
4075 #if !defined(CONFIG_USER_ONLY)
4076 /* Machine Timers and Counters */
4077 [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter,
4078 write_mhpmcounter },
4079 [CSR_MINSTRET] = { "minstret", any, read_hpmcounter,
4080 write_mhpmcounter },
4081 [CSR_MCYCLEH] = { "mcycleh", any32, read_hpmcounterh,
4082 write_mhpmcounterh },
4083 [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh,
4084 write_mhpmcounterh },
4086 /* Machine Information Registers */
4087 [CSR_MVENDORID] = { "mvendorid", any, read_mvendorid },
4088 [CSR_MARCHID] = { "marchid", any, read_marchid },
4089 [CSR_MIMPID] = { "mimpid", any, read_mimpid },
4090 [CSR_MHARTID] = { "mhartid", any, read_mhartid },
4092 [CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero,
4093 .min_priv_ver = PRIV_VERSION_1_12_0 },
4094 /* Machine Trap Setup */
4095 [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus,
4096 NULL, read_mstatus_i128 },
4097 [CSR_MISA] = { "misa", any, read_misa, write_misa,
4098 NULL, read_misa_i128 },
4099 [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg },
4100 [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
4101 [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
4102 [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
4103 [CSR_MCOUNTEREN] = { "mcounteren", umode, read_mcounteren,
4104 write_mcounteren },
4106 [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush,
4107 write_mstatush },
4109 /* Machine Trap Handling */
4110 [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch,
4111 NULL, read_mscratch_i128, write_mscratch_i128 },
4112 [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc },
4113 [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause },
4114 [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval },
4115 [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip },
4117 /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
4118 [CSR_MISELECT] = { "miselect", aia_any, NULL, NULL, rmw_xiselect },
4119 [CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg },
4121 /* Machine-Level Interrupts (AIA) */
4122 [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
4123 [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
4125 /* Virtual Interrupts for Supervisor Level (AIA) */
4126 [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore },
4127 [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore },
4129 /* Machine-Level High-Half CSRs (AIA) */
4130 [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
4131 [CSR_MIEH] = { "mieh", aia_any32, NULL, NULL, rmw_mieh },
4132 [CSR_MVIENH] = { "mvienh", aia_any32, read_zero, write_ignore },
4133 [CSR_MVIPH] = { "mviph", aia_any32, read_zero, write_ignore },
4134 [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
4136 /* Execution environment configuration */
4137 [CSR_MENVCFG] = { "menvcfg", umode, read_menvcfg, write_menvcfg,
4138 .min_priv_ver = PRIV_VERSION_1_12_0 },
4139 [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh,
4140 .min_priv_ver = PRIV_VERSION_1_12_0 },
4141 [CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
4142 .min_priv_ver = PRIV_VERSION_1_12_0 },
4143 [CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg,
4144 .min_priv_ver = PRIV_VERSION_1_12_0 },
4145 [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
4146 .min_priv_ver = PRIV_VERSION_1_12_0 },
4148 /* Smstateen extension CSRs */
4149 [CSR_MSTATEEN0] = { "mstateen0", mstateen, read_mstateen, write_mstateen0,
4150 .min_priv_ver = PRIV_VERSION_1_12_0 },
4151 [CSR_MSTATEEN0H] = { "mstateen0h", mstateen, read_mstateenh,
4152 write_mstateen0h,
4153 .min_priv_ver = PRIV_VERSION_1_12_0 },
4154 [CSR_MSTATEEN1] = { "mstateen1", mstateen, read_mstateen,
4155 write_mstateen_1_3,
4156 .min_priv_ver = PRIV_VERSION_1_12_0 },
4157 [CSR_MSTATEEN1H] = { "mstateen1h", mstateen, read_mstateenh,
4158 write_mstateenh_1_3,
4159 .min_priv_ver = PRIV_VERSION_1_12_0 },
4160 [CSR_MSTATEEN2] = { "mstateen2", mstateen, read_mstateen,
4161 write_mstateen_1_3,
4162 .min_priv_ver = PRIV_VERSION_1_12_0 },
4163 [CSR_MSTATEEN2H] = { "mstateen2h", mstateen, read_mstateenh,
4164 write_mstateenh_1_3,
4165 .min_priv_ver = PRIV_VERSION_1_12_0 },
4166 [CSR_MSTATEEN3] = { "mstateen3", mstateen, read_mstateen,
4167 write_mstateen_1_3,
4168 .min_priv_ver = PRIV_VERSION_1_12_0 },
4169 [CSR_MSTATEEN3H] = { "mstateen3h", mstateen, read_mstateenh,
4170 write_mstateenh_1_3,
4171 .min_priv_ver = PRIV_VERSION_1_12_0 },
4172 [CSR_HSTATEEN0] = { "hstateen0", hstateen, read_hstateen, write_hstateen0,
4173 .min_priv_ver = PRIV_VERSION_1_12_0 },
4174 [CSR_HSTATEEN0H] = { "hstateen0h", hstateenh, read_hstateenh,
4175 write_hstateen0h,
4176 .min_priv_ver = PRIV_VERSION_1_12_0 },
4177 [CSR_HSTATEEN1] = { "hstateen1", hstateen, read_hstateen,
4178 write_hstateen_1_3,
4179 .min_priv_ver = PRIV_VERSION_1_12_0 },
4180 [CSR_HSTATEEN1H] = { "hstateen1h", hstateenh, read_hstateenh,
4181 write_hstateenh_1_3,
4182 .min_priv_ver = PRIV_VERSION_1_12_0 },
4183 [CSR_HSTATEEN2] = { "hstateen2", hstateen, read_hstateen,
4184 write_hstateen_1_3,
4185 .min_priv_ver = PRIV_VERSION_1_12_0 },
4186 [CSR_HSTATEEN2H] = { "hstateen2h", hstateenh, read_hstateenh,
4187 write_hstateenh_1_3,
4188 .min_priv_ver = PRIV_VERSION_1_12_0 },
4189 [CSR_HSTATEEN3] = { "hstateen3", hstateen, read_hstateen,
4190 write_hstateen_1_3,
4191 .min_priv_ver = PRIV_VERSION_1_12_0 },
4192 [CSR_HSTATEEN3H] = { "hstateen3h", hstateenh, read_hstateenh,
4193 write_hstateenh_1_3,
4194 .min_priv_ver = PRIV_VERSION_1_12_0 },
4195 [CSR_SSTATEEN0] = { "sstateen0", sstateen, read_sstateen, write_sstateen0,
4196 .min_priv_ver = PRIV_VERSION_1_12_0 },
4197 [CSR_SSTATEEN1] = { "sstateen1", sstateen, read_sstateen,
4198 write_sstateen_1_3,
4199 .min_priv_ver = PRIV_VERSION_1_12_0 },
4200 [CSR_SSTATEEN2] = { "sstateen2", sstateen, read_sstateen,
4201 write_sstateen_1_3,
4202 .min_priv_ver = PRIV_VERSION_1_12_0 },
4203 [CSR_SSTATEEN3] = { "sstateen3", sstateen, read_sstateen,
4204 write_sstateen_1_3,
4205 .min_priv_ver = PRIV_VERSION_1_12_0 },
4207 /* Supervisor Trap Setup */
4208 [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus,
4209 NULL, read_sstatus_i128 },
4210 [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie },
4211 [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
4212 [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren,
4213 write_scounteren },
4215 /* Supervisor Trap Handling */
4216 [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch,
4217 NULL, read_sscratch_i128, write_sscratch_i128 },
4218 [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc },
4219 [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
4220 [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
4221 [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
4222 [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp,
4223 .min_priv_ver = PRIV_VERSION_1_12_0 },
4224 [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
4225 .min_priv_ver = PRIV_VERSION_1_12_0 },
4226 [CSR_VSTIMECMP] = { "vstimecmp", sstc, read_vstimecmp,
4227 write_vstimecmp,
4228 .min_priv_ver = PRIV_VERSION_1_12_0 },
4229 [CSR_VSTIMECMPH] = { "vstimecmph", sstc_32, read_vstimecmph,
4230 write_vstimecmph,
4231 .min_priv_ver = PRIV_VERSION_1_12_0 },
4233 /* Supervisor Protection and Translation */
4234 [CSR_SATP] = { "satp", satp, read_satp, write_satp },
4236 /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
4237 [CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect },
4238 [CSR_SIREG] = { "sireg", aia_smode, NULL, NULL, rmw_xireg },
4240 /* Supervisor-Level Interrupts (AIA) */
4241 [CSR_STOPEI] = { "stopei", aia_smode, NULL, NULL, rmw_xtopei },
4242 [CSR_STOPI] = { "stopi", aia_smode, read_stopi },
4244 /* Supervisor-Level High-Half CSRs (AIA) */
4245 [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh },
4246 [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph },
4248 [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus,
4249 .min_priv_ver = PRIV_VERSION_1_12_0 },
4250 [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg,
4251 .min_priv_ver = PRIV_VERSION_1_12_0 },
4252 [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg,
4253 .min_priv_ver = PRIV_VERSION_1_12_0 },
4254 [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip,
4255 .min_priv_ver = PRIV_VERSION_1_12_0 },
4256 [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip,
4257 .min_priv_ver = PRIV_VERSION_1_12_0 },
4258 [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie,
4259 .min_priv_ver = PRIV_VERSION_1_12_0 },
4260 [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren,
4261 write_hcounteren,
4262 .min_priv_ver = PRIV_VERSION_1_12_0 },
4263 [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie,
4264 .min_priv_ver = PRIV_VERSION_1_12_0 },
4265 [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval,
4266 .min_priv_ver = PRIV_VERSION_1_12_0 },
4267 [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst,
4268 .min_priv_ver = PRIV_VERSION_1_12_0 },
4269 [CSR_HGEIP] = { "hgeip", hmode, read_hgeip,
4270 .min_priv_ver = PRIV_VERSION_1_12_0 },
4271 [CSR_HGATP] = { "hgatp", hgatp, read_hgatp, write_hgatp,
4272 .min_priv_ver = PRIV_VERSION_1_12_0 },
4273 [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta,
4274 write_htimedelta,
4275 .min_priv_ver = PRIV_VERSION_1_12_0 },
4276 [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah,
4277 write_htimedeltah,
4278 .min_priv_ver = PRIV_VERSION_1_12_0 },
4280 [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus,
4281 write_vsstatus,
4282 .min_priv_ver = PRIV_VERSION_1_12_0 },
4283 [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip,
4284 .min_priv_ver = PRIV_VERSION_1_12_0 },
4285 [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie ,
4286 .min_priv_ver = PRIV_VERSION_1_12_0 },
4287 [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec,
4288 .min_priv_ver = PRIV_VERSION_1_12_0 },
4289 [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch,
4290 write_vsscratch,
4291 .min_priv_ver = PRIV_VERSION_1_12_0 },
4292 [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc,
4293 .min_priv_ver = PRIV_VERSION_1_12_0 },
4294 [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause,
4295 .min_priv_ver = PRIV_VERSION_1_12_0 },
4296 [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval,
4297 .min_priv_ver = PRIV_VERSION_1_12_0 },
4298 [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
4299 .min_priv_ver = PRIV_VERSION_1_12_0 },
4301 [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
4302 .min_priv_ver = PRIV_VERSION_1_12_0 },
4303 [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
4304 .min_priv_ver = PRIV_VERSION_1_12_0 },
4306 /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
4307 [CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore },
4308 [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl,
4309 write_hvictl },
4310 [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1,
4311 write_hviprio1 },
4312 [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2,
4313 write_hviprio2 },
4316 * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
4318 [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL,
4319 rmw_xiselect },
4320 [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
4322 /* VS-Level Interrupts (H-extension with AIA) */
4323 [CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei },
4324 [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi },
4326 /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
4327 [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL,
4328 rmw_hidelegh },
4329 [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero,
4330 write_ignore },
4331 [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph },
4332 [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h,
4333 write_hviprio1h },
4334 [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h,
4335 write_hviprio2h },
4336 [CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh },
4337 [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph },
4339 /* Physical Memory Protection */
4340 [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg,
4341 .min_priv_ver = PRIV_VERSION_1_11_0 },
4342 [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
4343 [CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
4344 [CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
4345 [CSR_PMPCFG3] = { "pmpcfg3", pmp, read_pmpcfg, write_pmpcfg },
4346 [CSR_PMPADDR0] = { "pmpaddr0", pmp, read_pmpaddr, write_pmpaddr },
4347 [CSR_PMPADDR1] = { "pmpaddr1", pmp, read_pmpaddr, write_pmpaddr },
4348 [CSR_PMPADDR2] = { "pmpaddr2", pmp, read_pmpaddr, write_pmpaddr },
4349 [CSR_PMPADDR3] = { "pmpaddr3", pmp, read_pmpaddr, write_pmpaddr },
4350 [CSR_PMPADDR4] = { "pmpaddr4", pmp, read_pmpaddr, write_pmpaddr },
4351 [CSR_PMPADDR5] = { "pmpaddr5", pmp, read_pmpaddr, write_pmpaddr },
4352 [CSR_PMPADDR6] = { "pmpaddr6", pmp, read_pmpaddr, write_pmpaddr },
4353 [CSR_PMPADDR7] = { "pmpaddr7", pmp, read_pmpaddr, write_pmpaddr },
4354 [CSR_PMPADDR8] = { "pmpaddr8", pmp, read_pmpaddr, write_pmpaddr },
4355 [CSR_PMPADDR9] = { "pmpaddr9", pmp, read_pmpaddr, write_pmpaddr },
4356 [CSR_PMPADDR10] = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
4357 [CSR_PMPADDR11] = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
4358 [CSR_PMPADDR12] = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
4359 [CSR_PMPADDR13] = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
4360 [CSR_PMPADDR14] = { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
4361 [CSR_PMPADDR15] = { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
4363 /* Debug CSRs */
4364 [CSR_TSELECT] = { "tselect", debug, read_tselect, write_tselect },
4365 [CSR_TDATA1] = { "tdata1", debug, read_tdata, write_tdata },
4366 [CSR_TDATA2] = { "tdata2", debug, read_tdata, write_tdata },
4367 [CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata },
4368 [CSR_TINFO] = { "tinfo", debug, read_tinfo, write_ignore },
4370 /* User Pointer Masking */
4371 [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
4372 [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask,
4373 write_upmmask },
4374 [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase,
4375 write_upmbase },
4376 /* Machine Pointer Masking */
4377 [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
4378 [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask,
4379 write_mpmmask },
4380 [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase,
4381 write_mpmbase },
4382 /* Supervisor Pointer Masking */
4383 [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
4384 [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask,
4385 write_spmmask },
4386 [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase,
4387 write_spmbase },
4389 /* Performance Counters */
4390 [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_hpmcounter },
4391 [CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_hpmcounter },
4392 [CSR_HPMCOUNTER5] = { "hpmcounter5", ctr, read_hpmcounter },
4393 [CSR_HPMCOUNTER6] = { "hpmcounter6", ctr, read_hpmcounter },
4394 [CSR_HPMCOUNTER7] = { "hpmcounter7", ctr, read_hpmcounter },
4395 [CSR_HPMCOUNTER8] = { "hpmcounter8", ctr, read_hpmcounter },
4396 [CSR_HPMCOUNTER9] = { "hpmcounter9", ctr, read_hpmcounter },
4397 [CSR_HPMCOUNTER10] = { "hpmcounter10", ctr, read_hpmcounter },
4398 [CSR_HPMCOUNTER11] = { "hpmcounter11", ctr, read_hpmcounter },
4399 [CSR_HPMCOUNTER12] = { "hpmcounter12", ctr, read_hpmcounter },
4400 [CSR_HPMCOUNTER13] = { "hpmcounter13", ctr, read_hpmcounter },
4401 [CSR_HPMCOUNTER14] = { "hpmcounter14", ctr, read_hpmcounter },
4402 [CSR_HPMCOUNTER15] = { "hpmcounter15", ctr, read_hpmcounter },
4403 [CSR_HPMCOUNTER16] = { "hpmcounter16", ctr, read_hpmcounter },
4404 [CSR_HPMCOUNTER17] = { "hpmcounter17", ctr, read_hpmcounter },
4405 [CSR_HPMCOUNTER18] = { "hpmcounter18", ctr, read_hpmcounter },
4406 [CSR_HPMCOUNTER19] = { "hpmcounter19", ctr, read_hpmcounter },
4407 [CSR_HPMCOUNTER20] = { "hpmcounter20", ctr, read_hpmcounter },
4408 [CSR_HPMCOUNTER21] = { "hpmcounter21", ctr, read_hpmcounter },
4409 [CSR_HPMCOUNTER22] = { "hpmcounter22", ctr, read_hpmcounter },
4410 [CSR_HPMCOUNTER23] = { "hpmcounter23", ctr, read_hpmcounter },
4411 [CSR_HPMCOUNTER24] = { "hpmcounter24", ctr, read_hpmcounter },
4412 [CSR_HPMCOUNTER25] = { "hpmcounter25", ctr, read_hpmcounter },
4413 [CSR_HPMCOUNTER26] = { "hpmcounter26", ctr, read_hpmcounter },
4414 [CSR_HPMCOUNTER27] = { "hpmcounter27", ctr, read_hpmcounter },
4415 [CSR_HPMCOUNTER28] = { "hpmcounter28", ctr, read_hpmcounter },
4416 [CSR_HPMCOUNTER29] = { "hpmcounter29", ctr, read_hpmcounter },
4417 [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_hpmcounter },
4418 [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_hpmcounter },
4420 [CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_hpmcounter,
4421 write_mhpmcounter },
4422 [CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_hpmcounter,
4423 write_mhpmcounter },
4424 [CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_hpmcounter,
4425 write_mhpmcounter },
4426 [CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_hpmcounter,
4427 write_mhpmcounter },
4428 [CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_hpmcounter,
4429 write_mhpmcounter },
4430 [CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_hpmcounter,
4431 write_mhpmcounter },
4432 [CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_hpmcounter,
4433 write_mhpmcounter },
4434 [CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_hpmcounter,
4435 write_mhpmcounter },
4436 [CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_hpmcounter,
4437 write_mhpmcounter },
4438 [CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_hpmcounter,
4439 write_mhpmcounter },
4440 [CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_hpmcounter,
4441 write_mhpmcounter },
4442 [CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_hpmcounter,
4443 write_mhpmcounter },
4444 [CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_hpmcounter,
4445 write_mhpmcounter },
4446 [CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_hpmcounter,
4447 write_mhpmcounter },
4448 [CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_hpmcounter,
4449 write_mhpmcounter },
4450 [CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_hpmcounter,
4451 write_mhpmcounter },
4452 [CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_hpmcounter,
4453 write_mhpmcounter },
4454 [CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_hpmcounter,
4455 write_mhpmcounter },
4456 [CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_hpmcounter,
4457 write_mhpmcounter },
4458 [CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_hpmcounter,
4459 write_mhpmcounter },
4460 [CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_hpmcounter,
4461 write_mhpmcounter },
4462 [CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_hpmcounter,
4463 write_mhpmcounter },
4464 [CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_hpmcounter,
4465 write_mhpmcounter },
4466 [CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_hpmcounter,
4467 write_mhpmcounter },
4468 [CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_hpmcounter,
4469 write_mhpmcounter },
4470 [CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_hpmcounter,
4471 write_mhpmcounter },
4472 [CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_hpmcounter,
4473 write_mhpmcounter },
4474 [CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_hpmcounter,
4475 write_mhpmcounter },
4476 [CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_hpmcounter,
4477 write_mhpmcounter },
4479 [CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_mcountinhibit,
4480 write_mcountinhibit,
4481 .min_priv_ver = PRIV_VERSION_1_11_0 },
4483 [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_mhpmevent,
4484 write_mhpmevent },
4485 [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_mhpmevent,
4486 write_mhpmevent },
4487 [CSR_MHPMEVENT5] = { "mhpmevent5", any, read_mhpmevent,
4488 write_mhpmevent },
4489 [CSR_MHPMEVENT6] = { "mhpmevent6", any, read_mhpmevent,
4490 write_mhpmevent },
4491 [CSR_MHPMEVENT7] = { "mhpmevent7", any, read_mhpmevent,
4492 write_mhpmevent },
4493 [CSR_MHPMEVENT8] = { "mhpmevent8", any, read_mhpmevent,
4494 write_mhpmevent },
4495 [CSR_MHPMEVENT9] = { "mhpmevent9", any, read_mhpmevent,
4496 write_mhpmevent },
4497 [CSR_MHPMEVENT10] = { "mhpmevent10", any, read_mhpmevent,
4498 write_mhpmevent },
4499 [CSR_MHPMEVENT11] = { "mhpmevent11", any, read_mhpmevent,
4500 write_mhpmevent },
4501 [CSR_MHPMEVENT12] = { "mhpmevent12", any, read_mhpmevent,
4502 write_mhpmevent },
4503 [CSR_MHPMEVENT13] = { "mhpmevent13", any, read_mhpmevent,
4504 write_mhpmevent },
4505 [CSR_MHPMEVENT14] = { "mhpmevent14", any, read_mhpmevent,
4506 write_mhpmevent },
4507 [CSR_MHPMEVENT15] = { "mhpmevent15", any, read_mhpmevent,
4508 write_mhpmevent },
4509 [CSR_MHPMEVENT16] = { "mhpmevent16", any, read_mhpmevent,
4510 write_mhpmevent },
4511 [CSR_MHPMEVENT17] = { "mhpmevent17", any, read_mhpmevent,
4512 write_mhpmevent },
4513 [CSR_MHPMEVENT18] = { "mhpmevent18", any, read_mhpmevent,
4514 write_mhpmevent },
4515 [CSR_MHPMEVENT19] = { "mhpmevent19", any, read_mhpmevent,
4516 write_mhpmevent },
4517 [CSR_MHPMEVENT20] = { "mhpmevent20", any, read_mhpmevent,
4518 write_mhpmevent },
4519 [CSR_MHPMEVENT21] = { "mhpmevent21", any, read_mhpmevent,
4520 write_mhpmevent },
4521 [CSR_MHPMEVENT22] = { "mhpmevent22", any, read_mhpmevent,
4522 write_mhpmevent },
4523 [CSR_MHPMEVENT23] = { "mhpmevent23", any, read_mhpmevent,
4524 write_mhpmevent },
4525 [CSR_MHPMEVENT24] = { "mhpmevent24", any, read_mhpmevent,
4526 write_mhpmevent },
4527 [CSR_MHPMEVENT25] = { "mhpmevent25", any, read_mhpmevent,
4528 write_mhpmevent },
4529 [CSR_MHPMEVENT26] = { "mhpmevent26", any, read_mhpmevent,
4530 write_mhpmevent },
4531 [CSR_MHPMEVENT27] = { "mhpmevent27", any, read_mhpmevent,
4532 write_mhpmevent },
4533 [CSR_MHPMEVENT28] = { "mhpmevent28", any, read_mhpmevent,
4534 write_mhpmevent },
4535 [CSR_MHPMEVENT29] = { "mhpmevent29", any, read_mhpmevent,
4536 write_mhpmevent },
4537 [CSR_MHPMEVENT30] = { "mhpmevent30", any, read_mhpmevent,
4538 write_mhpmevent },
4539 [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent,
4540 write_mhpmevent },
4542 [CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf, read_mhpmeventh,
4543 write_mhpmeventh,
4544 .min_priv_ver = PRIV_VERSION_1_12_0 },
4545 [CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf, read_mhpmeventh,
4546 write_mhpmeventh,
4547 .min_priv_ver = PRIV_VERSION_1_12_0 },
4548 [CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf, read_mhpmeventh,
4549 write_mhpmeventh,
4550 .min_priv_ver = PRIV_VERSION_1_12_0 },
4551 [CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf, read_mhpmeventh,
4552 write_mhpmeventh,
4553 .min_priv_ver = PRIV_VERSION_1_12_0 },
4554 [CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf, read_mhpmeventh,
4555 write_mhpmeventh,
4556 .min_priv_ver = PRIV_VERSION_1_12_0 },
4557 [CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf, read_mhpmeventh,
4558 write_mhpmeventh,
4559 .min_priv_ver = PRIV_VERSION_1_12_0 },
4560 [CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf, read_mhpmeventh,
4561 write_mhpmeventh,
4562 .min_priv_ver = PRIV_VERSION_1_12_0 },
4563 [CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf, read_mhpmeventh,
4564 write_mhpmeventh,
4565 .min_priv_ver = PRIV_VERSION_1_12_0 },
4566 [CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf, read_mhpmeventh,
4567 write_mhpmeventh,
4568 .min_priv_ver = PRIV_VERSION_1_12_0 },
4569 [CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf, read_mhpmeventh,
4570 write_mhpmeventh,
4571 .min_priv_ver = PRIV_VERSION_1_12_0 },
4572 [CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf, read_mhpmeventh,
4573 write_mhpmeventh,
4574 .min_priv_ver = PRIV_VERSION_1_12_0 },
4575 [CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf, read_mhpmeventh,
4576 write_mhpmeventh,
4577 .min_priv_ver = PRIV_VERSION_1_12_0 },
4578 [CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf, read_mhpmeventh,
4579 write_mhpmeventh,
4580 .min_priv_ver = PRIV_VERSION_1_12_0 },
4581 [CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf, read_mhpmeventh,
4582 write_mhpmeventh,
4583 .min_priv_ver = PRIV_VERSION_1_12_0 },
4584 [CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf, read_mhpmeventh,
4585 write_mhpmeventh,
4586 .min_priv_ver = PRIV_VERSION_1_12_0 },
4587 [CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf, read_mhpmeventh,
4588 write_mhpmeventh,
4589 .min_priv_ver = PRIV_VERSION_1_12_0 },
4590 [CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf, read_mhpmeventh,
4591 write_mhpmeventh,
4592 .min_priv_ver = PRIV_VERSION_1_12_0 },
4593 [CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf, read_mhpmeventh,
4594 write_mhpmeventh,
4595 .min_priv_ver = PRIV_VERSION_1_12_0 },
4596 [CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf, read_mhpmeventh,
4597 write_mhpmeventh,
4598 .min_priv_ver = PRIV_VERSION_1_12_0 },
4599 [CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf, read_mhpmeventh,
4600 write_mhpmeventh,
4601 .min_priv_ver = PRIV_VERSION_1_12_0 },
4602 [CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf, read_mhpmeventh,
4603 write_mhpmeventh,
4604 .min_priv_ver = PRIV_VERSION_1_12_0 },
4605 [CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf, read_mhpmeventh,
4606 write_mhpmeventh,
4607 .min_priv_ver = PRIV_VERSION_1_12_0 },
4608 [CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf, read_mhpmeventh,
4609 write_mhpmeventh,
4610 .min_priv_ver = PRIV_VERSION_1_12_0 },
4611 [CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf, read_mhpmeventh,
4612 write_mhpmeventh,
4613 .min_priv_ver = PRIV_VERSION_1_12_0 },
4614 [CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf, read_mhpmeventh,
4615 write_mhpmeventh,
4616 .min_priv_ver = PRIV_VERSION_1_12_0 },
4617 [CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf, read_mhpmeventh,
4618 write_mhpmeventh,
4619 .min_priv_ver = PRIV_VERSION_1_12_0 },
4620 [CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf, read_mhpmeventh,
4621 write_mhpmeventh,
4622 .min_priv_ver = PRIV_VERSION_1_12_0 },
4623 [CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf, read_mhpmeventh,
4624 write_mhpmeventh,
4625 .min_priv_ver = PRIV_VERSION_1_12_0 },
4626 [CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf, read_mhpmeventh,
4627 write_mhpmeventh,
4628 .min_priv_ver = PRIV_VERSION_1_12_0 },
4630 [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh },
4631 [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh },
4632 [CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_hpmcounterh },
4633 [CSR_HPMCOUNTER6H] = { "hpmcounter6h", ctr32, read_hpmcounterh },
4634 [CSR_HPMCOUNTER7H] = { "hpmcounter7h", ctr32, read_hpmcounterh },
4635 [CSR_HPMCOUNTER8H] = { "hpmcounter8h", ctr32, read_hpmcounterh },
4636 [CSR_HPMCOUNTER9H] = { "hpmcounter9h", ctr32, read_hpmcounterh },
4637 [CSR_HPMCOUNTER10H] = { "hpmcounter10h", ctr32, read_hpmcounterh },
4638 [CSR_HPMCOUNTER11H] = { "hpmcounter11h", ctr32, read_hpmcounterh },
4639 [CSR_HPMCOUNTER12H] = { "hpmcounter12h", ctr32, read_hpmcounterh },
4640 [CSR_HPMCOUNTER13H] = { "hpmcounter13h", ctr32, read_hpmcounterh },
4641 [CSR_HPMCOUNTER14H] = { "hpmcounter14h", ctr32, read_hpmcounterh },
4642 [CSR_HPMCOUNTER15H] = { "hpmcounter15h", ctr32, read_hpmcounterh },
4643 [CSR_HPMCOUNTER16H] = { "hpmcounter16h", ctr32, read_hpmcounterh },
4644 [CSR_HPMCOUNTER17H] = { "hpmcounter17h", ctr32, read_hpmcounterh },
4645 [CSR_HPMCOUNTER18H] = { "hpmcounter18h", ctr32, read_hpmcounterh },
4646 [CSR_HPMCOUNTER19H] = { "hpmcounter19h", ctr32, read_hpmcounterh },
4647 [CSR_HPMCOUNTER20H] = { "hpmcounter20h", ctr32, read_hpmcounterh },
4648 [CSR_HPMCOUNTER21H] = { "hpmcounter21h", ctr32, read_hpmcounterh },
4649 [CSR_HPMCOUNTER22H] = { "hpmcounter22h", ctr32, read_hpmcounterh },
4650 [CSR_HPMCOUNTER23H] = { "hpmcounter23h", ctr32, read_hpmcounterh },
4651 [CSR_HPMCOUNTER24H] = { "hpmcounter24h", ctr32, read_hpmcounterh },
4652 [CSR_HPMCOUNTER25H] = { "hpmcounter25h", ctr32, read_hpmcounterh },
4653 [CSR_HPMCOUNTER26H] = { "hpmcounter26h", ctr32, read_hpmcounterh },
4654 [CSR_HPMCOUNTER27H] = { "hpmcounter27h", ctr32, read_hpmcounterh },
4655 [CSR_HPMCOUNTER28H] = { "hpmcounter28h", ctr32, read_hpmcounterh },
4656 [CSR_HPMCOUNTER29H] = { "hpmcounter29h", ctr32, read_hpmcounterh },
4657 [CSR_HPMCOUNTER30H] = { "hpmcounter30h", ctr32, read_hpmcounterh },
4658 [CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_hpmcounterh },
4660 [CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", mctr32, read_hpmcounterh,
4661 write_mhpmcounterh },
4662 [CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", mctr32, read_hpmcounterh,
4663 write_mhpmcounterh },
4664 [CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", mctr32, read_hpmcounterh,
4665 write_mhpmcounterh },
4666 [CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", mctr32, read_hpmcounterh,
4667 write_mhpmcounterh },
4668 [CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", mctr32, read_hpmcounterh,
4669 write_mhpmcounterh },
4670 [CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", mctr32, read_hpmcounterh,
4671 write_mhpmcounterh },
4672 [CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", mctr32, read_hpmcounterh,
4673 write_mhpmcounterh },
4674 [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32, read_hpmcounterh,
4675 write_mhpmcounterh },
4676 [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32, read_hpmcounterh,
4677 write_mhpmcounterh },
4678 [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32, read_hpmcounterh,
4679 write_mhpmcounterh },
4680 [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32, read_hpmcounterh,
4681 write_mhpmcounterh },
4682 [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32, read_hpmcounterh,
4683 write_mhpmcounterh },
4684 [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32, read_hpmcounterh,
4685 write_mhpmcounterh },
4686 [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32, read_hpmcounterh,
4687 write_mhpmcounterh },
4688 [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32, read_hpmcounterh,
4689 write_mhpmcounterh },
4690 [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32, read_hpmcounterh,
4691 write_mhpmcounterh },
4692 [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32, read_hpmcounterh,
4693 write_mhpmcounterh },
4694 [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32, read_hpmcounterh,
4695 write_mhpmcounterh },
4696 [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32, read_hpmcounterh,
4697 write_mhpmcounterh },
4698 [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32, read_hpmcounterh,
4699 write_mhpmcounterh },
4700 [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32, read_hpmcounterh,
4701 write_mhpmcounterh },
4702 [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32, read_hpmcounterh,
4703 write_mhpmcounterh },
4704 [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32, read_hpmcounterh,
4705 write_mhpmcounterh },
4706 [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32, read_hpmcounterh,
4707 write_mhpmcounterh },
4708 [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32, read_hpmcounterh,
4709 write_mhpmcounterh },
4710 [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32, read_hpmcounterh,
4711 write_mhpmcounterh },
4712 [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32, read_hpmcounterh,
4713 write_mhpmcounterh },
4714 [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32, read_hpmcounterh,
4715 write_mhpmcounterh },
4716 [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh,
4717 write_mhpmcounterh },
4718 [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf,
4719 .min_priv_ver = PRIV_VERSION_1_12_0 },
4721 #endif /* !CONFIG_USER_ONLY */