2 * RISC-V Control and Status Registers.
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
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"
22 #include "qemu/timer.h"
24 #include "qemu/main-loop.h"
25 #include "exec/exec-all.h"
26 #include "sysemu/cpu-timers.h"
28 /* CSR function table public API */
29 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
31 *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
34 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
36 csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
40 static RISCVException fs(CPURISCVState *env, int csrno)
42 #if !defined(CONFIG_USER_ONLY)
43 if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
44 !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
45 return RISCV_EXCP_ILLEGAL_INST;
48 return RISCV_EXCP_NONE;
51 static RISCVException vs(CPURISCVState *env, int csrno)
53 CPUState *cs = env_cpu(env);
54 RISCVCPU *cpu = RISCV_CPU(cs);
56 if (env->misa_ext & RVV ||
57 cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
58 #if !defined(CONFIG_USER_ONLY)
59 if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
60 return RISCV_EXCP_ILLEGAL_INST;
63 return RISCV_EXCP_NONE;
65 return RISCV_EXCP_ILLEGAL_INST;
68 static RISCVException ctr(CPURISCVState *env, int csrno)
70 #if !defined(CONFIG_USER_ONLY)
71 CPUState *cs = env_cpu(env);
72 RISCVCPU *cpu = RISCV_CPU(cs);
74 if (!cpu->cfg.ext_counters) {
75 /* The Counters extensions is not enabled */
76 return RISCV_EXCP_ILLEGAL_INST;
79 if (riscv_cpu_virt_enabled(env)) {
82 if (!get_field(env->hcounteren, COUNTEREN_CY) &&
83 get_field(env->mcounteren, COUNTEREN_CY)) {
84 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
88 if (!get_field(env->hcounteren, COUNTEREN_TM) &&
89 get_field(env->mcounteren, COUNTEREN_TM)) {
90 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
94 if (!get_field(env->hcounteren, COUNTEREN_IR) &&
95 get_field(env->mcounteren, COUNTEREN_IR)) {
96 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
99 case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
100 if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
101 get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
102 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
106 if (riscv_cpu_mxl(env) == MXL_RV32) {
109 if (!get_field(env->hcounteren, COUNTEREN_CY) &&
110 get_field(env->mcounteren, COUNTEREN_CY)) {
111 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
115 if (!get_field(env->hcounteren, COUNTEREN_TM) &&
116 get_field(env->mcounteren, COUNTEREN_TM)) {
117 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
121 if (!get_field(env->hcounteren, COUNTEREN_IR) &&
122 get_field(env->mcounteren, COUNTEREN_IR)) {
123 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
126 case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
127 if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
128 get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
129 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
136 return RISCV_EXCP_NONE;
139 static RISCVException ctr32(CPURISCVState *env, int csrno)
141 if (riscv_cpu_mxl(env) != MXL_RV32) {
142 return RISCV_EXCP_ILLEGAL_INST;
145 return ctr(env, csrno);
148 #if !defined(CONFIG_USER_ONLY)
149 static RISCVException any(CPURISCVState *env, int csrno)
151 return RISCV_EXCP_NONE;
154 static RISCVException any32(CPURISCVState *env, int csrno)
156 if (riscv_cpu_mxl(env) != MXL_RV32) {
157 return RISCV_EXCP_ILLEGAL_INST;
160 return any(env, csrno);
164 static int aia_any(CPURISCVState *env, int csrno)
166 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
167 return RISCV_EXCP_ILLEGAL_INST;
170 return any(env, csrno);
173 static int aia_any32(CPURISCVState *env, int csrno)
175 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
176 return RISCV_EXCP_ILLEGAL_INST;
179 return any32(env, csrno);
182 static RISCVException smode(CPURISCVState *env, int csrno)
184 if (riscv_has_ext(env, RVS)) {
185 return RISCV_EXCP_NONE;
188 return RISCV_EXCP_ILLEGAL_INST;
191 static int smode32(CPURISCVState *env, int csrno)
193 if (riscv_cpu_mxl(env) != MXL_RV32) {
194 return RISCV_EXCP_ILLEGAL_INST;
197 return smode(env, csrno);
200 static int aia_smode(CPURISCVState *env, int csrno)
202 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
203 return RISCV_EXCP_ILLEGAL_INST;
206 return smode(env, csrno);
209 static int aia_smode32(CPURISCVState *env, int csrno)
211 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
212 return RISCV_EXCP_ILLEGAL_INST;
215 return smode32(env, csrno);
218 static RISCVException hmode(CPURISCVState *env, int csrno)
220 if (riscv_has_ext(env, RVS) &&
221 riscv_has_ext(env, RVH)) {
222 /* Hypervisor extension is supported */
223 if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
224 env->priv == PRV_M) {
225 return RISCV_EXCP_NONE;
227 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
231 return RISCV_EXCP_ILLEGAL_INST;
234 static RISCVException hmode32(CPURISCVState *env, int csrno)
236 if (riscv_cpu_mxl(env) != MXL_RV32) {
237 if (!riscv_cpu_virt_enabled(env)) {
238 return RISCV_EXCP_ILLEGAL_INST;
240 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
244 return hmode(env, csrno);
248 /* Checks if PointerMasking registers could be accessed */
249 static RISCVException pointer_masking(CPURISCVState *env, int csrno)
251 /* Check if j-ext is present */
252 if (riscv_has_ext(env, RVJ)) {
253 return RISCV_EXCP_NONE;
255 return RISCV_EXCP_ILLEGAL_INST;
258 static int aia_hmode(CPURISCVState *env, int csrno)
260 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
261 return RISCV_EXCP_ILLEGAL_INST;
264 return hmode(env, csrno);
267 static int aia_hmode32(CPURISCVState *env, int csrno)
269 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
270 return RISCV_EXCP_ILLEGAL_INST;
273 return hmode32(env, csrno);
276 static RISCVException pmp(CPURISCVState *env, int csrno)
278 if (riscv_feature(env, RISCV_FEATURE_PMP)) {
279 return RISCV_EXCP_NONE;
282 return RISCV_EXCP_ILLEGAL_INST;
285 static RISCVException epmp(CPURISCVState *env, int csrno)
287 if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
288 return RISCV_EXCP_NONE;
291 return RISCV_EXCP_ILLEGAL_INST;
294 static RISCVException debug(CPURISCVState *env, int csrno)
296 if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
297 return RISCV_EXCP_NONE;
300 return RISCV_EXCP_ILLEGAL_INST;
304 /* User Floating-Point CSRs */
305 static RISCVException read_fflags(CPURISCVState *env, int csrno,
308 *val = riscv_cpu_get_fflags(env);
309 return RISCV_EXCP_NONE;
312 static RISCVException write_fflags(CPURISCVState *env, int csrno,
315 #if !defined(CONFIG_USER_ONLY)
316 if (riscv_has_ext(env, RVF)) {
317 env->mstatus |= MSTATUS_FS;
320 riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
321 return RISCV_EXCP_NONE;
324 static RISCVException read_frm(CPURISCVState *env, int csrno,
328 return RISCV_EXCP_NONE;
331 static RISCVException write_frm(CPURISCVState *env, int csrno,
334 #if !defined(CONFIG_USER_ONLY)
335 if (riscv_has_ext(env, RVF)) {
336 env->mstatus |= MSTATUS_FS;
339 env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
340 return RISCV_EXCP_NONE;
343 static RISCVException read_fcsr(CPURISCVState *env, int csrno,
346 *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
347 | (env->frm << FSR_RD_SHIFT);
348 return RISCV_EXCP_NONE;
351 static RISCVException write_fcsr(CPURISCVState *env, int csrno,
354 #if !defined(CONFIG_USER_ONLY)
355 if (riscv_has_ext(env, RVF)) {
356 env->mstatus |= MSTATUS_FS;
359 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
360 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
361 return RISCV_EXCP_NONE;
364 static RISCVException read_vtype(CPURISCVState *env, int csrno,
370 vill = (uint32_t)env->vill << 31;
373 vill = (uint64_t)env->vill << 63;
376 g_assert_not_reached();
378 *val = (target_ulong)vill | env->vtype;
379 return RISCV_EXCP_NONE;
382 static RISCVException read_vl(CPURISCVState *env, int csrno,
386 return RISCV_EXCP_NONE;
389 static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
391 *val = env_archcpu(env)->cfg.vlen >> 3;
392 return RISCV_EXCP_NONE;
395 static RISCVException read_vxrm(CPURISCVState *env, int csrno,
399 return RISCV_EXCP_NONE;
402 static RISCVException write_vxrm(CPURISCVState *env, int csrno,
405 #if !defined(CONFIG_USER_ONLY)
406 env->mstatus |= MSTATUS_VS;
409 return RISCV_EXCP_NONE;
412 static RISCVException read_vxsat(CPURISCVState *env, int csrno,
416 return RISCV_EXCP_NONE;
419 static RISCVException write_vxsat(CPURISCVState *env, int csrno,
422 #if !defined(CONFIG_USER_ONLY)
423 env->mstatus |= MSTATUS_VS;
426 return RISCV_EXCP_NONE;
429 static RISCVException read_vstart(CPURISCVState *env, int csrno,
433 return RISCV_EXCP_NONE;
436 static RISCVException write_vstart(CPURISCVState *env, int csrno,
439 #if !defined(CONFIG_USER_ONLY)
440 env->mstatus |= MSTATUS_VS;
443 * The vstart CSR is defined to have only enough writable bits
444 * to hold the largest element index, i.e. lg2(VLEN) bits.
446 env->vstart = val & ~(~0ULL << ctzl(env_archcpu(env)->cfg.vlen));
447 return RISCV_EXCP_NONE;
450 static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
452 *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
453 return RISCV_EXCP_NONE;
456 static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
458 #if !defined(CONFIG_USER_ONLY)
459 env->mstatus |= MSTATUS_VS;
461 env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
462 env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
463 return RISCV_EXCP_NONE;
466 /* User Timers and Counters */
467 static RISCVException read_instret(CPURISCVState *env, int csrno,
470 #if !defined(CONFIG_USER_ONLY)
471 if (icount_enabled()) {
474 *val = cpu_get_host_ticks();
477 *val = cpu_get_host_ticks();
479 return RISCV_EXCP_NONE;
482 static RISCVException read_instreth(CPURISCVState *env, int csrno,
485 #if !defined(CONFIG_USER_ONLY)
486 if (icount_enabled()) {
487 *val = icount_get() >> 32;
489 *val = cpu_get_host_ticks() >> 32;
492 *val = cpu_get_host_ticks() >> 32;
494 return RISCV_EXCP_NONE;
497 #if defined(CONFIG_USER_ONLY)
498 static RISCVException read_time(CPURISCVState *env, int csrno,
501 *val = cpu_get_host_ticks();
502 return RISCV_EXCP_NONE;
505 static RISCVException read_timeh(CPURISCVState *env, int csrno,
508 *val = cpu_get_host_ticks() >> 32;
509 return RISCV_EXCP_NONE;
512 #else /* CONFIG_USER_ONLY */
514 static RISCVException read_time(CPURISCVState *env, int csrno,
517 uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
519 if (!env->rdtime_fn) {
520 return RISCV_EXCP_ILLEGAL_INST;
523 *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
524 return RISCV_EXCP_NONE;
527 static RISCVException read_timeh(CPURISCVState *env, int csrno,
530 uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
532 if (!env->rdtime_fn) {
533 return RISCV_EXCP_ILLEGAL_INST;
536 *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
537 return RISCV_EXCP_NONE;
540 /* Machine constants */
542 #define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
543 #define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP))
544 #define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
545 #define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
547 #define VSTOPI_NUM_SRCS 5
549 static const uint64_t delegable_ints = S_MODE_INTERRUPTS |
551 static const uint64_t vs_delegable_ints = VS_MODE_INTERRUPTS;
552 static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
554 #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
555 (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
556 (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
557 (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
558 (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
559 (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
560 (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
561 (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
562 (1ULL << (RISCV_EXCP_U_ECALL)) | \
563 (1ULL << (RISCV_EXCP_S_ECALL)) | \
564 (1ULL << (RISCV_EXCP_VS_ECALL)) | \
565 (1ULL << (RISCV_EXCP_M_ECALL)) | \
566 (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
567 (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
568 (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
569 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
570 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
571 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
572 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
573 static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
574 ~((1ULL << (RISCV_EXCP_S_ECALL)) |
575 (1ULL << (RISCV_EXCP_VS_ECALL)) |
576 (1ULL << (RISCV_EXCP_M_ECALL)) |
577 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
578 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
579 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
580 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
581 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
582 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
583 SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
584 static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
585 static const target_ulong hip_writable_mask = MIP_VSSIP;
586 static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
587 static const target_ulong vsip_writable_mask = MIP_VSSIP;
589 static const char valid_vm_1_10_32[16] = {
594 static const char valid_vm_1_10_64[16] = {
601 /* Machine Information Registers */
602 static RISCVException read_zero(CPURISCVState *env, int csrno,
606 return RISCV_EXCP_NONE;
609 static RISCVException write_ignore(CPURISCVState *env, int csrno,
612 return RISCV_EXCP_NONE;
615 static RISCVException read_mhartid(CPURISCVState *env, int csrno,
619 return RISCV_EXCP_NONE;
622 /* Machine Trap Setup */
624 /* We do not store SD explicitly, only compute it on demand. */
625 static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
627 if ((status & MSTATUS_FS) == MSTATUS_FS ||
628 (status & MSTATUS_VS) == MSTATUS_VS ||
629 (status & MSTATUS_XS) == MSTATUS_XS) {
632 return status | MSTATUS32_SD;
634 return status | MSTATUS64_SD;
636 return MSTATUSH128_SD;
638 g_assert_not_reached();
644 static RISCVException read_mstatus(CPURISCVState *env, int csrno,
647 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
648 return RISCV_EXCP_NONE;
651 static int validate_vm(CPURISCVState *env, target_ulong vm)
653 if (riscv_cpu_mxl(env) == MXL_RV32) {
654 return valid_vm_1_10_32[vm & 0xf];
656 return valid_vm_1_10_64[vm & 0xf];
660 static RISCVException write_mstatus(CPURISCVState *env, int csrno,
663 uint64_t mstatus = env->mstatus;
665 RISCVMXL xl = riscv_cpu_mxl(env);
667 /* flush tlb on mstatus fields that affect VM */
668 if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
669 MSTATUS_MPRV | MSTATUS_SUM)) {
670 tlb_flush(env_cpu(env));
672 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
673 MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
674 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
675 MSTATUS_TW | MSTATUS_VS;
677 if (riscv_has_ext(env, RVF)) {
681 if (xl != MXL_RV32 || env->debugger) {
683 * RV32: MPV and GVA are not in mstatus. The current plan is to
684 * add them to mstatush. For now, we just don't support it.
686 mask |= MSTATUS_MPV | MSTATUS_GVA;
687 if ((val & MSTATUS64_UXL) != 0) {
688 mask |= MSTATUS64_UXL;
692 mstatus = (mstatus & ~mask) | (val & mask);
695 /* SXL field is for now read only */
696 mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
698 env->mstatus = mstatus;
699 env->xl = cpu_recompute_xl(env);
701 return RISCV_EXCP_NONE;
704 static RISCVException read_mstatush(CPURISCVState *env, int csrno,
707 *val = env->mstatus >> 32;
708 return RISCV_EXCP_NONE;
711 static RISCVException write_mstatush(CPURISCVState *env, int csrno,
714 uint64_t valh = (uint64_t)val << 32;
715 uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
717 if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
718 tlb_flush(env_cpu(env));
721 env->mstatus = (env->mstatus & ~mask) | (valh & mask);
723 return RISCV_EXCP_NONE;
726 static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
729 *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, env->mstatus));
730 return RISCV_EXCP_NONE;
733 static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
736 *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
737 return RISCV_EXCP_NONE;
740 static RISCVException read_misa(CPURISCVState *env, int csrno,
745 switch (env->misa_mxl) {
747 misa = (target_ulong)MXL_RV32 << 30;
749 #ifdef TARGET_RISCV64
751 misa = (target_ulong)MXL_RV64 << 62;
755 g_assert_not_reached();
758 *val = misa | env->misa_ext;
759 return RISCV_EXCP_NONE;
762 static RISCVException write_misa(CPURISCVState *env, int csrno,
765 if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
766 /* drop write to misa */
767 return RISCV_EXCP_NONE;
770 /* 'I' or 'E' must be present */
771 if (!(val & (RVI | RVE))) {
772 /* It is not, drop write to misa */
773 return RISCV_EXCP_NONE;
776 /* 'E' excludes all other extensions */
778 /* when we support 'E' we can do "val = RVE;" however
779 * for now we just drop writes if 'E' is present.
781 return RISCV_EXCP_NONE;
785 * misa.MXL writes are not supported by QEMU.
786 * Drop writes to those bits.
789 /* Mask extensions that are not supported by this hart */
790 val &= env->misa_ext_mask;
792 /* Mask extensions that are not supported by QEMU */
793 val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
795 /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
796 if ((val & RVD) && !(val & RVF)) {
800 /* Suppress 'C' if next instruction is not aligned
801 * TODO: this should check next_pc
803 if ((val & RVC) && (GETPC() & ~3) != 0) {
807 /* If nothing changed, do nothing. */
808 if (val == env->misa_ext) {
809 return RISCV_EXCP_NONE;
813 env->mstatus &= ~MSTATUS_FS;
816 /* flush translation cache */
817 tb_flush(env_cpu(env));
819 env->xl = riscv_cpu_mxl(env);
820 return RISCV_EXCP_NONE;
823 static RISCVException read_medeleg(CPURISCVState *env, int csrno,
827 return RISCV_EXCP_NONE;
830 static RISCVException write_medeleg(CPURISCVState *env, int csrno,
833 env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
834 return RISCV_EXCP_NONE;
837 static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
839 uint64_t new_val, uint64_t wr_mask)
841 uint64_t mask = wr_mask & delegable_ints;
844 *ret_val = env->mideleg;
847 env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
849 if (riscv_has_ext(env, RVH)) {
850 env->mideleg |= HS_MODE_INTERRUPTS;
853 return RISCV_EXCP_NONE;
856 static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
857 target_ulong *ret_val,
858 target_ulong new_val, target_ulong wr_mask)
863 ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
871 static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
872 target_ulong *ret_val,
873 target_ulong new_val,
874 target_ulong wr_mask)
879 ret = rmw_mideleg64(env, csrno, &rval,
880 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
882 *ret_val = rval >> 32;
888 static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
890 uint64_t new_val, uint64_t wr_mask)
892 uint64_t mask = wr_mask & all_ints;
898 env->mie = (env->mie & ~mask) | (new_val & mask);
900 if (!riscv_has_ext(env, RVH)) {
901 env->mie &= ~((uint64_t)MIP_SGEIP);
904 return RISCV_EXCP_NONE;
907 static RISCVException rmw_mie(CPURISCVState *env, int csrno,
908 target_ulong *ret_val,
909 target_ulong new_val, target_ulong wr_mask)
914 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
922 static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
923 target_ulong *ret_val,
924 target_ulong new_val, target_ulong wr_mask)
929 ret = rmw_mie64(env, csrno, &rval,
930 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
932 *ret_val = rval >> 32;
938 static int read_mtopi(CPURISCVState *env, int csrno, target_ulong *val)
943 irq = riscv_cpu_mirq_pending(env);
944 if (irq <= 0 || irq > 63) {
947 iprio = env->miprio[irq];
949 if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) {
950 iprio = IPRIO_MMAXIPRIO;
953 *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
957 return RISCV_EXCP_NONE;
960 static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
962 if (!riscv_cpu_virt_enabled(env)) {
968 return CSR_VSISELECT;
972 return CSR_VSSETEIPNUM;
974 return CSR_VSCLREIPNUM;
976 return CSR_VSSETEIENUM;
978 return CSR_VSCLREIENUM;
986 static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
987 target_ulong new_val, target_ulong wr_mask)
989 target_ulong *iselect;
991 /* Translate CSR number for VS-mode */
992 csrno = aia_xlate_vs_csrno(env, csrno);
994 /* Find the iselect CSR based on CSR number */
997 iselect = &env->miselect;
1000 iselect = &env->siselect;
1003 iselect = &env->vsiselect;
1006 return RISCV_EXCP_ILLEGAL_INST;
1013 wr_mask &= ISELECT_MASK;
1015 *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
1018 return RISCV_EXCP_NONE;
1021 static int rmw_iprio(target_ulong xlen,
1022 target_ulong iselect, uint8_t *iprio,
1023 target_ulong *val, target_ulong new_val,
1024 target_ulong wr_mask, int ext_irq_no)
1027 target_ulong old_val;
1029 if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
1032 if (xlen != 32 && iselect & 0x1) {
1036 nirqs = 4 * (xlen / 32);
1037 firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
1040 for (i = 0; i < nirqs; i++) {
1041 old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i);
1049 new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
1050 for (i = 0; i < nirqs; i++) {
1052 * M-level and S-level external IRQ priority always read-only
1053 * zero. This means default priority order is always preferred
1054 * for M-level and S-level external IRQs.
1056 if ((firq + i) == ext_irq_no) {
1059 iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
1066 static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
1067 target_ulong new_val, target_ulong wr_mask)
1072 target_ulong priv, isel, vgein;
1074 /* Translate CSR number for VS-mode */
1075 csrno = aia_xlate_vs_csrno(env, csrno);
1077 /* Decode register details from CSR number */
1081 iprio = env->miprio;
1082 isel = env->miselect;
1086 iprio = env->siprio;
1087 isel = env->siselect;
1091 iprio = env->hviprio;
1092 isel = env->vsiselect;
1100 /* Find the selected guest interrupt file */
1101 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1103 if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
1104 /* Local interrupt priority registers not available for VS-mode */
1106 ret = rmw_iprio(riscv_cpu_mxl_bits(env),
1107 isel, iprio, val, new_val, wr_mask,
1108 (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
1110 } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) {
1111 /* IMSIC registers only available when machine implements it. */
1112 if (env->aia_ireg_rmw_fn[priv]) {
1113 /* Selected guest interrupt file should not be zero */
1114 if (virt && (!vgein || env->geilen < vgein)) {
1117 /* Call machine specific IMSIC register emulation */
1118 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1119 AIA_MAKE_IREG(isel, priv, virt, vgein,
1120 riscv_cpu_mxl_bits(env)),
1121 val, new_val, wr_mask);
1127 return (riscv_cpu_virt_enabled(env) && virt) ?
1128 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1130 return RISCV_EXCP_NONE;
1133 static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong *val,
1134 target_ulong new_val, target_ulong wr_mask)
1137 bool set, pend, virt;
1138 target_ulong priv, isel, vgein, xlen, nval, wmask;
1140 /* Translate CSR number for VS-mode */
1141 csrno = aia_xlate_vs_csrno(env, csrno);
1143 /* Decode register details from CSR number */
1144 virt = set = pend = false;
1146 case CSR_MSETEIPNUM:
1151 case CSR_MCLREIPNUM:
1155 case CSR_MSETEIENUM:
1159 case CSR_MCLREIENUM:
1162 case CSR_SSETEIPNUM:
1167 case CSR_SCLREIPNUM:
1171 case CSR_SSETEIENUM:
1175 case CSR_SCLREIENUM:
1178 case CSR_VSSETEIPNUM:
1184 case CSR_VSCLREIPNUM:
1189 case CSR_VSSETEIENUM:
1194 case CSR_VSCLREIENUM:
1202 /* IMSIC CSRs only available when machine implements IMSIC. */
1203 if (!env->aia_ireg_rmw_fn[priv]) {
1207 /* Find the selected guest interrupt file */
1208 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1210 /* Selected guest interrupt file should be valid */
1211 if (virt && (!vgein || env->geilen < vgein)) {
1215 /* Set/Clear CSRs always read zero */
1221 /* Get interrupt number */
1224 /* Find target interrupt pending/enable register */
1225 xlen = riscv_cpu_mxl_bits(env);
1226 isel = (new_val / xlen);
1227 isel *= (xlen / IMSIC_EIPx_BITS);
1228 isel += (pend) ? ISELECT_IMSIC_EIP0 : ISELECT_IMSIC_EIE0;
1230 /* Find the interrupt bit to be set/clear */
1231 wmask = ((target_ulong)1) << (new_val % xlen);
1232 nval = (set) ? wmask : 0;
1234 /* Call machine specific IMSIC register emulation */
1235 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1236 AIA_MAKE_IREG(isel, priv, virt,
1245 return (riscv_cpu_virt_enabled(env) && virt) ?
1246 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1248 return RISCV_EXCP_NONE;
1251 static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
1252 target_ulong new_val, target_ulong wr_mask)
1256 target_ulong priv, vgein;
1258 /* Translate CSR number for VS-mode */
1259 csrno = aia_xlate_vs_csrno(env, csrno);
1261 /* Decode register details from CSR number */
1278 /* IMSIC CSRs only available when machine implements IMSIC. */
1279 if (!env->aia_ireg_rmw_fn[priv]) {
1283 /* Find the selected guest interrupt file */
1284 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1286 /* Selected guest interrupt file should be valid */
1287 if (virt && (!vgein || env->geilen < vgein)) {
1291 /* Call machine specific IMSIC register emulation for TOPEI */
1292 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1293 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein,
1294 riscv_cpu_mxl_bits(env)),
1295 val, new_val, wr_mask);
1299 return (riscv_cpu_virt_enabled(env) && virt) ?
1300 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1302 return RISCV_EXCP_NONE;
1305 static RISCVException read_mtvec(CPURISCVState *env, int csrno,
1309 return RISCV_EXCP_NONE;
1312 static RISCVException write_mtvec(CPURISCVState *env, int csrno,
1315 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
1316 if ((val & 3) < 2) {
1319 qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
1321 return RISCV_EXCP_NONE;
1324 static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
1327 *val = env->mcounteren;
1328 return RISCV_EXCP_NONE;
1331 static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
1334 env->mcounteren = val;
1335 return RISCV_EXCP_NONE;
1338 /* Machine Trap Handling */
1339 static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
1342 *val = int128_make128(env->mscratch, env->mscratchh);
1343 return RISCV_EXCP_NONE;
1346 static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
1349 env->mscratch = int128_getlo(val);
1350 env->mscratchh = int128_gethi(val);
1351 return RISCV_EXCP_NONE;
1354 static RISCVException read_mscratch(CPURISCVState *env, int csrno,
1357 *val = env->mscratch;
1358 return RISCV_EXCP_NONE;
1361 static RISCVException write_mscratch(CPURISCVState *env, int csrno,
1364 env->mscratch = val;
1365 return RISCV_EXCP_NONE;
1368 static RISCVException read_mepc(CPURISCVState *env, int csrno,
1372 return RISCV_EXCP_NONE;
1375 static RISCVException write_mepc(CPURISCVState *env, int csrno,
1379 return RISCV_EXCP_NONE;
1382 static RISCVException read_mcause(CPURISCVState *env, int csrno,
1386 return RISCV_EXCP_NONE;
1389 static RISCVException write_mcause(CPURISCVState *env, int csrno,
1393 return RISCV_EXCP_NONE;
1396 static RISCVException read_mtval(CPURISCVState *env, int csrno,
1400 return RISCV_EXCP_NONE;
1403 static RISCVException write_mtval(CPURISCVState *env, int csrno,
1407 return RISCV_EXCP_NONE;
1410 /* Execution environment configuration setup */
1411 static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
1414 *val = env->menvcfg;
1415 return RISCV_EXCP_NONE;
1418 static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
1421 uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
1423 if (riscv_cpu_mxl(env) == MXL_RV64) {
1424 mask |= MENVCFG_PBMTE | MENVCFG_STCE;
1426 env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
1428 return RISCV_EXCP_NONE;
1431 static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
1434 *val = env->menvcfg >> 32;
1435 return RISCV_EXCP_NONE;
1438 static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
1441 uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE;
1442 uint64_t valh = (uint64_t)val << 32;
1444 env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
1446 return RISCV_EXCP_NONE;
1449 static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
1452 *val = env->senvcfg;
1453 return RISCV_EXCP_NONE;
1456 static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
1459 uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
1461 env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
1463 return RISCV_EXCP_NONE;
1466 static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
1469 *val = env->henvcfg;
1470 return RISCV_EXCP_NONE;
1473 static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
1476 uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
1478 if (riscv_cpu_mxl(env) == MXL_RV64) {
1479 mask |= HENVCFG_PBMTE | HENVCFG_STCE;
1482 env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
1484 return RISCV_EXCP_NONE;
1487 static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
1490 *val = env->henvcfg >> 32;
1491 return RISCV_EXCP_NONE;
1494 static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
1497 uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
1498 uint64_t valh = (uint64_t)val << 32;
1500 env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
1502 return RISCV_EXCP_NONE;
1505 static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
1507 uint64_t new_val, uint64_t wr_mask)
1509 RISCVCPU *cpu = env_archcpu(env);
1510 uint64_t old_mip, mask = wr_mask & delegable_ints;
1513 if (mask & MIP_SEIP) {
1514 env->software_seip = new_val & MIP_SEIP;
1515 new_val |= env->external_seip * MIP_SEIP;
1519 old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
1524 if (csrno != CSR_HVIP) {
1525 gin = get_field(env->hstatus, HSTATUS_VGEIN);
1526 old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
1533 return RISCV_EXCP_NONE;
1536 static RISCVException rmw_mip(CPURISCVState *env, int csrno,
1537 target_ulong *ret_val,
1538 target_ulong new_val, target_ulong wr_mask)
1543 ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
1551 static RISCVException rmw_miph(CPURISCVState *env, int csrno,
1552 target_ulong *ret_val,
1553 target_ulong new_val, target_ulong wr_mask)
1558 ret = rmw_mip64(env, csrno, &rval,
1559 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1561 *ret_val = rval >> 32;
1567 /* Supervisor Trap Setup */
1568 static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
1571 uint64_t mask = sstatus_v1_10_mask;
1572 uint64_t sstatus = env->mstatus & mask;
1573 if (env->xl != MXL_RV32 || env->debugger) {
1574 mask |= SSTATUS64_UXL;
1577 *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
1578 return RISCV_EXCP_NONE;
1581 static RISCVException read_sstatus(CPURISCVState *env, int csrno,
1584 target_ulong mask = (sstatus_v1_10_mask);
1585 if (env->xl != MXL_RV32 || env->debugger) {
1586 mask |= SSTATUS64_UXL;
1588 /* TODO: Use SXL not MXL. */
1589 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
1590 return RISCV_EXCP_NONE;
1593 static RISCVException write_sstatus(CPURISCVState *env, int csrno,
1596 target_ulong mask = (sstatus_v1_10_mask);
1598 if (env->xl != MXL_RV32 || env->debugger) {
1599 if ((val & SSTATUS64_UXL) != 0) {
1600 mask |= SSTATUS64_UXL;
1603 target_ulong newval = (env->mstatus & ~mask) | (val & mask);
1604 return write_mstatus(env, CSR_MSTATUS, newval);
1607 static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
1609 uint64_t new_val, uint64_t wr_mask)
1612 uint64_t rval, vsbits, mask = env->hideleg & VS_MODE_INTERRUPTS;
1614 /* Bring VS-level bits to correct position */
1615 vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
1616 new_val &= ~(VS_MODE_INTERRUPTS >> 1);
1617 new_val |= vsbits << 1;
1618 vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
1619 wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
1620 wr_mask |= vsbits << 1;
1622 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask);
1625 vsbits = rval & VS_MODE_INTERRUPTS;
1626 rval &= ~VS_MODE_INTERRUPTS;
1627 *ret_val = rval | (vsbits >> 1);
1633 static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
1634 target_ulong *ret_val,
1635 target_ulong new_val, target_ulong wr_mask)
1640 ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
1648 static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
1649 target_ulong *ret_val,
1650 target_ulong new_val, target_ulong wr_mask)
1655 ret = rmw_vsie64(env, csrno, &rval,
1656 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1658 *ret_val = rval >> 32;
1664 static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
1666 uint64_t new_val, uint64_t wr_mask)
1669 uint64_t mask = env->mideleg & S_MODE_INTERRUPTS;
1671 if (riscv_cpu_virt_enabled(env)) {
1672 if (env->hvictl & HVICTL_VTI) {
1673 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1675 ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
1677 ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask);
1687 static RISCVException rmw_sie(CPURISCVState *env, int csrno,
1688 target_ulong *ret_val,
1689 target_ulong new_val, target_ulong wr_mask)
1694 ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
1695 if (ret == RISCV_EXCP_NONE && ret_val) {
1702 static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
1703 target_ulong *ret_val,
1704 target_ulong new_val, target_ulong wr_mask)
1709 ret = rmw_sie64(env, csrno, &rval,
1710 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1712 *ret_val = rval >> 32;
1718 static RISCVException read_stvec(CPURISCVState *env, int csrno,
1722 return RISCV_EXCP_NONE;
1725 static RISCVException write_stvec(CPURISCVState *env, int csrno,
1728 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
1729 if ((val & 3) < 2) {
1732 qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
1734 return RISCV_EXCP_NONE;
1737 static RISCVException read_scounteren(CPURISCVState *env, int csrno,
1740 *val = env->scounteren;
1741 return RISCV_EXCP_NONE;
1744 static RISCVException write_scounteren(CPURISCVState *env, int csrno,
1747 env->scounteren = val;
1748 return RISCV_EXCP_NONE;
1751 /* Supervisor Trap Handling */
1752 static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
1755 *val = int128_make128(env->sscratch, env->sscratchh);
1756 return RISCV_EXCP_NONE;
1759 static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
1762 env->sscratch = int128_getlo(val);
1763 env->sscratchh = int128_gethi(val);
1764 return RISCV_EXCP_NONE;
1767 static RISCVException read_sscratch(CPURISCVState *env, int csrno,
1770 *val = env->sscratch;
1771 return RISCV_EXCP_NONE;
1774 static RISCVException write_sscratch(CPURISCVState *env, int csrno,
1777 env->sscratch = val;
1778 return RISCV_EXCP_NONE;
1781 static RISCVException read_sepc(CPURISCVState *env, int csrno,
1785 return RISCV_EXCP_NONE;
1788 static RISCVException write_sepc(CPURISCVState *env, int csrno,
1792 return RISCV_EXCP_NONE;
1795 static RISCVException read_scause(CPURISCVState *env, int csrno,
1799 return RISCV_EXCP_NONE;
1802 static RISCVException write_scause(CPURISCVState *env, int csrno,
1806 return RISCV_EXCP_NONE;
1809 static RISCVException read_stval(CPURISCVState *env, int csrno,
1813 return RISCV_EXCP_NONE;
1816 static RISCVException write_stval(CPURISCVState *env, int csrno,
1820 return RISCV_EXCP_NONE;
1823 static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
1825 uint64_t new_val, uint64_t wr_mask)
1828 uint64_t rval, vsbits, mask = env->hideleg & vsip_writable_mask;
1830 /* Bring VS-level bits to correct position */
1831 vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
1832 new_val &= ~(VS_MODE_INTERRUPTS >> 1);
1833 new_val |= vsbits << 1;
1834 vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
1835 wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
1836 wr_mask |= vsbits << 1;
1838 ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask & mask);
1841 vsbits = rval & VS_MODE_INTERRUPTS;
1842 rval &= ~VS_MODE_INTERRUPTS;
1843 *ret_val = rval | (vsbits >> 1);
1849 static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
1850 target_ulong *ret_val,
1851 target_ulong new_val, target_ulong wr_mask)
1856 ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
1864 static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
1865 target_ulong *ret_val,
1866 target_ulong new_val, target_ulong wr_mask)
1871 ret = rmw_vsip64(env, csrno, &rval,
1872 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1874 *ret_val = rval >> 32;
1880 static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
1882 uint64_t new_val, uint64_t wr_mask)
1885 uint64_t mask = env->mideleg & sip_writable_mask;
1887 if (riscv_cpu_virt_enabled(env)) {
1888 if (env->hvictl & HVICTL_VTI) {
1889 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1891 ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
1893 ret = rmw_mip64(env, csrno, ret_val, new_val, wr_mask & mask);
1897 *ret_val &= env->mideleg & S_MODE_INTERRUPTS;
1903 static RISCVException rmw_sip(CPURISCVState *env, int csrno,
1904 target_ulong *ret_val,
1905 target_ulong new_val, target_ulong wr_mask)
1910 ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
1918 static RISCVException rmw_siph(CPURISCVState *env, int csrno,
1919 target_ulong *ret_val,
1920 target_ulong new_val, target_ulong wr_mask)
1925 ret = rmw_sip64(env, csrno, &rval,
1926 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1928 *ret_val = rval >> 32;
1934 /* Supervisor Protection and Translation */
1935 static RISCVException read_satp(CPURISCVState *env, int csrno,
1938 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
1940 return RISCV_EXCP_NONE;
1943 if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
1944 return RISCV_EXCP_ILLEGAL_INST;
1949 return RISCV_EXCP_NONE;
1952 static RISCVException write_satp(CPURISCVState *env, int csrno,
1955 target_ulong vm, mask;
1957 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
1958 return RISCV_EXCP_NONE;
1961 if (riscv_cpu_mxl(env) == MXL_RV32) {
1962 vm = validate_vm(env, get_field(val, SATP32_MODE));
1963 mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
1965 vm = validate_vm(env, get_field(val, SATP64_MODE));
1966 mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
1970 if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
1971 return RISCV_EXCP_ILLEGAL_INST;
1974 * The ISA defines SATP.MODE=Bare as "no translation", but we still
1975 * pass these through QEMU's TLB emulation as it improves
1976 * performance. Flushing the TLB on SATP writes with paging
1977 * enabled avoids leaking those invalid cached mappings.
1979 tlb_flush(env_cpu(env));
1983 return RISCV_EXCP_NONE;
1986 static int read_vstopi(CPURISCVState *env, int csrno, target_ulong *val)
1990 uint64_t vseip, vsgein;
1991 uint32_t iid, iprio, hviid, hviprio, gein;
1992 uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS];
1994 gein = get_field(env->hstatus, HSTATUS_VGEIN);
1995 hviid = get_field(env->hvictl, HVICTL_IID);
1996 hviprio = get_field(env->hvictl, HVICTL_IPRIO);
1999 vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
2000 vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP;
2001 if (gein <= env->geilen && vseip) {
2002 siid[scount] = IRQ_S_EXT;
2003 siprio[scount] = IPRIO_MMAXIPRIO + 1;
2004 if (env->aia_ireg_rmw_fn[PRV_S]) {
2006 * Call machine specific IMSIC register emulation for
2009 ret = env->aia_ireg_rmw_fn[PRV_S](
2010 env->aia_ireg_rmw_fn_arg[PRV_S],
2011 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein,
2012 riscv_cpu_mxl_bits(env)),
2014 if (!ret && topei) {
2015 siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK;
2021 if (hviid == IRQ_S_EXT && hviprio) {
2022 siid[scount] = IRQ_S_EXT;
2023 siprio[scount] = hviprio;
2028 if (env->hvictl & HVICTL_VTI) {
2029 if (hviid != IRQ_S_EXT) {
2030 siid[scount] = hviid;
2031 siprio[scount] = hviprio;
2035 irq = riscv_cpu_vsirq_pending(env);
2036 if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) {
2038 siprio[scount] = env->hviprio[irq];
2045 for (s = 0; s < scount; s++) {
2046 if (siprio[s] < iprio) {
2053 if (env->hvictl & HVICTL_IPRIOM) {
2054 if (iprio > IPRIO_MMAXIPRIO) {
2055 iprio = IPRIO_MMAXIPRIO;
2058 if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) {
2059 iprio = IPRIO_MMAXIPRIO;
2069 *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2071 return RISCV_EXCP_NONE;
2074 static int read_stopi(CPURISCVState *env, int csrno, target_ulong *val)
2079 if (riscv_cpu_virt_enabled(env)) {
2080 return read_vstopi(env, CSR_VSTOPI, val);
2083 irq = riscv_cpu_sirq_pending(env);
2084 if (irq <= 0 || irq > 63) {
2087 iprio = env->siprio[irq];
2089 if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) {
2090 iprio = IPRIO_MMAXIPRIO;
2093 *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2097 return RISCV_EXCP_NONE;
2100 /* Hypervisor Extensions */
2101 static RISCVException read_hstatus(CPURISCVState *env, int csrno,
2104 *val = env->hstatus;
2105 if (riscv_cpu_mxl(env) != MXL_RV32) {
2106 /* We only support 64-bit VSXL */
2107 *val = set_field(*val, HSTATUS_VSXL, 2);
2109 /* We only support little endian */
2110 *val = set_field(*val, HSTATUS_VSBE, 0);
2111 return RISCV_EXCP_NONE;
2114 static RISCVException write_hstatus(CPURISCVState *env, int csrno,
2118 if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
2119 qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
2121 if (get_field(val, HSTATUS_VSBE) != 0) {
2122 qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
2124 return RISCV_EXCP_NONE;
2127 static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
2130 *val = env->hedeleg;
2131 return RISCV_EXCP_NONE;
2134 static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
2137 env->hedeleg = val & vs_delegable_excps;
2138 return RISCV_EXCP_NONE;
2141 static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
2143 uint64_t new_val, uint64_t wr_mask)
2145 uint64_t mask = wr_mask & vs_delegable_ints;
2148 *ret_val = env->hideleg & vs_delegable_ints;
2151 env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
2152 return RISCV_EXCP_NONE;
2155 static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
2156 target_ulong *ret_val,
2157 target_ulong new_val, target_ulong wr_mask)
2162 ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
2170 static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
2171 target_ulong *ret_val,
2172 target_ulong new_val, target_ulong wr_mask)
2177 ret = rmw_hideleg64(env, csrno, &rval,
2178 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2180 *ret_val = rval >> 32;
2186 static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
2188 uint64_t new_val, uint64_t wr_mask)
2192 ret = rmw_mip64(env, csrno, ret_val, new_val,
2193 wr_mask & hvip_writable_mask);
2195 *ret_val &= VS_MODE_INTERRUPTS;
2201 static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
2202 target_ulong *ret_val,
2203 target_ulong new_val, target_ulong wr_mask)
2208 ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
2216 static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
2217 target_ulong *ret_val,
2218 target_ulong new_val, target_ulong wr_mask)
2223 ret = rmw_hvip64(env, csrno, &rval,
2224 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2226 *ret_val = rval >> 32;
2232 static RISCVException rmw_hip(CPURISCVState *env, int csrno,
2233 target_ulong *ret_value,
2234 target_ulong new_value, target_ulong write_mask)
2236 int ret = rmw_mip(env, csrno, ret_value, new_value,
2237 write_mask & hip_writable_mask);
2240 *ret_value &= HS_MODE_INTERRUPTS;
2245 static RISCVException rmw_hie(CPURISCVState *env, int csrno,
2246 target_ulong *ret_val,
2247 target_ulong new_val, target_ulong wr_mask)
2252 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
2254 *ret_val = rval & HS_MODE_INTERRUPTS;
2260 static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
2263 *val = env->hcounteren;
2264 return RISCV_EXCP_NONE;
2267 static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
2270 env->hcounteren = val;
2271 return RISCV_EXCP_NONE;
2274 static RISCVException read_hgeie(CPURISCVState *env, int csrno,
2280 return RISCV_EXCP_NONE;
2283 static RISCVException write_hgeie(CPURISCVState *env, int csrno,
2286 /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
2287 val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
2289 /* Update mip.SGEIP bit */
2290 riscv_cpu_update_mip(env_archcpu(env), MIP_SGEIP,
2291 BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
2292 return RISCV_EXCP_NONE;
2295 static RISCVException read_htval(CPURISCVState *env, int csrno,
2299 return RISCV_EXCP_NONE;
2302 static RISCVException write_htval(CPURISCVState *env, int csrno,
2306 return RISCV_EXCP_NONE;
2309 static RISCVException read_htinst(CPURISCVState *env, int csrno,
2313 return RISCV_EXCP_NONE;
2316 static RISCVException write_htinst(CPURISCVState *env, int csrno,
2319 return RISCV_EXCP_NONE;
2322 static RISCVException read_hgeip(CPURISCVState *env, int csrno,
2328 return RISCV_EXCP_NONE;
2331 static RISCVException read_hgatp(CPURISCVState *env, int csrno,
2335 return RISCV_EXCP_NONE;
2338 static RISCVException write_hgatp(CPURISCVState *env, int csrno,
2342 return RISCV_EXCP_NONE;
2345 static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
2348 if (!env->rdtime_fn) {
2349 return RISCV_EXCP_ILLEGAL_INST;
2352 *val = env->htimedelta;
2353 return RISCV_EXCP_NONE;
2356 static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
2359 if (!env->rdtime_fn) {
2360 return RISCV_EXCP_ILLEGAL_INST;
2363 if (riscv_cpu_mxl(env) == MXL_RV32) {
2364 env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
2366 env->htimedelta = val;
2368 return RISCV_EXCP_NONE;
2371 static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
2374 if (!env->rdtime_fn) {
2375 return RISCV_EXCP_ILLEGAL_INST;
2378 *val = env->htimedelta >> 32;
2379 return RISCV_EXCP_NONE;
2382 static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
2385 if (!env->rdtime_fn) {
2386 return RISCV_EXCP_ILLEGAL_INST;
2389 env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
2390 return RISCV_EXCP_NONE;
2393 static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val)
2396 return RISCV_EXCP_NONE;
2399 static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val)
2401 env->hvictl = val & HVICTL_VALID_MASK;
2402 return RISCV_EXCP_NONE;
2405 static int read_hvipriox(CPURISCVState *env, int first_index,
2406 uint8_t *iprio, target_ulong *val)
2408 int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
2410 /* First index has to be a multiple of number of irqs per register */
2411 if (first_index % num_irqs) {
2412 return (riscv_cpu_virt_enabled(env)) ?
2413 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2416 /* Fill-up return value */
2418 for (i = 0; i < num_irqs; i++) {
2419 if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
2425 *val |= ((target_ulong)iprio[irq]) << (i * 8);
2428 return RISCV_EXCP_NONE;
2431 static int write_hvipriox(CPURISCVState *env, int first_index,
2432 uint8_t *iprio, target_ulong val)
2434 int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
2436 /* First index has to be a multiple of number of irqs per register */
2437 if (first_index % num_irqs) {
2438 return (riscv_cpu_virt_enabled(env)) ?
2439 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2442 /* Fill-up priority arrary */
2443 for (i = 0; i < num_irqs; i++) {
2444 if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
2450 iprio[irq] = (val >> (i * 8)) & 0xff;
2454 return RISCV_EXCP_NONE;
2457 static int read_hviprio1(CPURISCVState *env, int csrno, target_ulong *val)
2459 return read_hvipriox(env, 0, env->hviprio, val);
2462 static int write_hviprio1(CPURISCVState *env, int csrno, target_ulong val)
2464 return write_hvipriox(env, 0, env->hviprio, val);
2467 static int read_hviprio1h(CPURISCVState *env, int csrno, target_ulong *val)
2469 return read_hvipriox(env, 4, env->hviprio, val);
2472 static int write_hviprio1h(CPURISCVState *env, int csrno, target_ulong val)
2474 return write_hvipriox(env, 4, env->hviprio, val);
2477 static int read_hviprio2(CPURISCVState *env, int csrno, target_ulong *val)
2479 return read_hvipriox(env, 8, env->hviprio, val);
2482 static int write_hviprio2(CPURISCVState *env, int csrno, target_ulong val)
2484 return write_hvipriox(env, 8, env->hviprio, val);
2487 static int read_hviprio2h(CPURISCVState *env, int csrno, target_ulong *val)
2489 return read_hvipriox(env, 12, env->hviprio, val);
2492 static int write_hviprio2h(CPURISCVState *env, int csrno, target_ulong val)
2494 return write_hvipriox(env, 12, env->hviprio, val);
2497 /* Virtual CSR Registers */
2498 static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
2501 *val = env->vsstatus;
2502 return RISCV_EXCP_NONE;
2505 static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
2508 uint64_t mask = (target_ulong)-1;
2509 if ((val & VSSTATUS64_UXL) == 0) {
2510 mask &= ~VSSTATUS64_UXL;
2512 env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
2513 return RISCV_EXCP_NONE;
2516 static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
2519 return RISCV_EXCP_NONE;
2522 static RISCVException write_vstvec(CPURISCVState *env, int csrno,
2526 return RISCV_EXCP_NONE;
2529 static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
2532 *val = env->vsscratch;
2533 return RISCV_EXCP_NONE;
2536 static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
2539 env->vsscratch = val;
2540 return RISCV_EXCP_NONE;
2543 static RISCVException read_vsepc(CPURISCVState *env, int csrno,
2547 return RISCV_EXCP_NONE;
2550 static RISCVException write_vsepc(CPURISCVState *env, int csrno,
2554 return RISCV_EXCP_NONE;
2557 static RISCVException read_vscause(CPURISCVState *env, int csrno,
2560 *val = env->vscause;
2561 return RISCV_EXCP_NONE;
2564 static RISCVException write_vscause(CPURISCVState *env, int csrno,
2568 return RISCV_EXCP_NONE;
2571 static RISCVException read_vstval(CPURISCVState *env, int csrno,
2575 return RISCV_EXCP_NONE;
2578 static RISCVException write_vstval(CPURISCVState *env, int csrno,
2582 return RISCV_EXCP_NONE;
2585 static RISCVException read_vsatp(CPURISCVState *env, int csrno,
2589 return RISCV_EXCP_NONE;
2592 static RISCVException write_vsatp(CPURISCVState *env, int csrno,
2596 return RISCV_EXCP_NONE;
2599 static RISCVException read_mtval2(CPURISCVState *env, int csrno,
2603 return RISCV_EXCP_NONE;
2606 static RISCVException write_mtval2(CPURISCVState *env, int csrno,
2610 return RISCV_EXCP_NONE;
2613 static RISCVException read_mtinst(CPURISCVState *env, int csrno,
2617 return RISCV_EXCP_NONE;
2620 static RISCVException write_mtinst(CPURISCVState *env, int csrno,
2624 return RISCV_EXCP_NONE;
2627 /* Physical Memory Protection */
2628 static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
2631 *val = mseccfg_csr_read(env);
2632 return RISCV_EXCP_NONE;
2635 static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
2638 mseccfg_csr_write(env, val);
2639 return RISCV_EXCP_NONE;
2642 static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
2644 /* TODO: RV128 restriction check */
2645 if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
2651 static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
2654 uint32_t reg_index = csrno - CSR_PMPCFG0;
2656 if (!check_pmp_reg_index(env, reg_index)) {
2657 return RISCV_EXCP_ILLEGAL_INST;
2659 *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
2660 return RISCV_EXCP_NONE;
2663 static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
2666 uint32_t reg_index = csrno - CSR_PMPCFG0;
2668 if (!check_pmp_reg_index(env, reg_index)) {
2669 return RISCV_EXCP_ILLEGAL_INST;
2671 pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
2672 return RISCV_EXCP_NONE;
2675 static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
2678 *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
2679 return RISCV_EXCP_NONE;
2682 static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
2685 pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
2686 return RISCV_EXCP_NONE;
2689 static RISCVException read_tselect(CPURISCVState *env, int csrno,
2692 *val = tselect_csr_read(env);
2693 return RISCV_EXCP_NONE;
2696 static RISCVException write_tselect(CPURISCVState *env, int csrno,
2699 tselect_csr_write(env, val);
2700 return RISCV_EXCP_NONE;
2703 static RISCVException read_tdata(CPURISCVState *env, int csrno,
2706 /* return 0 in tdata1 to end the trigger enumeration */
2707 if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
2709 return RISCV_EXCP_NONE;
2712 if (!tdata_available(env, csrno - CSR_TDATA1)) {
2713 return RISCV_EXCP_ILLEGAL_INST;
2716 *val = tdata_csr_read(env, csrno - CSR_TDATA1);
2717 return RISCV_EXCP_NONE;
2720 static RISCVException write_tdata(CPURISCVState *env, int csrno,
2723 if (!tdata_available(env, csrno - CSR_TDATA1)) {
2724 return RISCV_EXCP_ILLEGAL_INST;
2727 tdata_csr_write(env, csrno - CSR_TDATA1, val);
2728 return RISCV_EXCP_NONE;
2732 * Functions to access Pointer Masking feature registers
2733 * We have to check if current priv lvl could modify
2736 static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
2738 int csr_priv = get_field(csrno, 0x300);
2741 if (env->debugger) {
2745 * If priv lvls differ that means we're accessing csr from higher priv lvl,
2746 * so allow the access
2748 if (env->priv != csr_priv) {
2751 switch (env->priv) {
2753 pm_current = get_field(env->mmte, M_PM_CURRENT);
2756 pm_current = get_field(env->mmte, S_PM_CURRENT);
2759 pm_current = get_field(env->mmte, U_PM_CURRENT);
2762 g_assert_not_reached();
2764 /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
2768 static RISCVException read_mmte(CPURISCVState *env, int csrno,
2771 *val = env->mmte & MMTE_MASK;
2772 return RISCV_EXCP_NONE;
2775 static RISCVException write_mmte(CPURISCVState *env, int csrno,
2779 target_ulong wpri_val = val & MMTE_MASK;
2781 if (val != wpri_val) {
2782 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2783 "MMTE: WPRI violation written 0x", val,
2784 "vs expected 0x", wpri_val);
2786 /* for machine mode pm.current is hardwired to 1 */
2787 wpri_val |= MMTE_M_PM_CURRENT;
2789 /* hardwiring pm.instruction bit to 0, since it's not supported yet */
2790 wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
2791 env->mmte = wpri_val | PM_EXT_DIRTY;
2792 riscv_cpu_update_mask(env);
2794 /* Set XS and SD bits, since PM CSRs are dirty */
2795 mstatus = env->mstatus | MSTATUS_XS;
2796 write_mstatus(env, csrno, mstatus);
2797 return RISCV_EXCP_NONE;
2800 static RISCVException read_smte(CPURISCVState *env, int csrno,
2803 *val = env->mmte & SMTE_MASK;
2804 return RISCV_EXCP_NONE;
2807 static RISCVException write_smte(CPURISCVState *env, int csrno,
2810 target_ulong wpri_val = val & SMTE_MASK;
2812 if (val != wpri_val) {
2813 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2814 "SMTE: WPRI violation written 0x", val,
2815 "vs expected 0x", wpri_val);
2818 /* if pm.current==0 we can't modify current PM CSRs */
2819 if (check_pm_current_disabled(env, csrno)) {
2820 return RISCV_EXCP_NONE;
2823 wpri_val |= (env->mmte & ~SMTE_MASK);
2824 write_mmte(env, csrno, wpri_val);
2825 return RISCV_EXCP_NONE;
2828 static RISCVException read_umte(CPURISCVState *env, int csrno,
2831 *val = env->mmte & UMTE_MASK;
2832 return RISCV_EXCP_NONE;
2835 static RISCVException write_umte(CPURISCVState *env, int csrno,
2838 target_ulong wpri_val = val & UMTE_MASK;
2840 if (val != wpri_val) {
2841 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2842 "UMTE: WPRI violation written 0x", val,
2843 "vs expected 0x", wpri_val);
2846 if (check_pm_current_disabled(env, csrno)) {
2847 return RISCV_EXCP_NONE;
2850 wpri_val |= (env->mmte & ~UMTE_MASK);
2851 write_mmte(env, csrno, wpri_val);
2852 return RISCV_EXCP_NONE;
2855 static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
2858 *val = env->mpmmask;
2859 return RISCV_EXCP_NONE;
2862 static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
2868 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
2869 env->cur_pmmask = val;
2871 env->mmte |= PM_EXT_DIRTY;
2873 /* Set XS and SD bits, since PM CSRs are dirty */
2874 mstatus = env->mstatus | MSTATUS_XS;
2875 write_mstatus(env, csrno, mstatus);
2876 return RISCV_EXCP_NONE;
2879 static RISCVException read_spmmask(CPURISCVState *env, int csrno,
2882 *val = env->spmmask;
2883 return RISCV_EXCP_NONE;
2886 static RISCVException write_spmmask(CPURISCVState *env, int csrno,
2891 /* if pm.current==0 we can't modify current PM CSRs */
2892 if (check_pm_current_disabled(env, csrno)) {
2893 return RISCV_EXCP_NONE;
2896 if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
2897 env->cur_pmmask = val;
2899 env->mmte |= PM_EXT_DIRTY;
2901 /* Set XS and SD bits, since PM CSRs are dirty */
2902 mstatus = env->mstatus | MSTATUS_XS;
2903 write_mstatus(env, csrno, mstatus);
2904 return RISCV_EXCP_NONE;
2907 static RISCVException read_upmmask(CPURISCVState *env, int csrno,
2910 *val = env->upmmask;
2911 return RISCV_EXCP_NONE;
2914 static RISCVException write_upmmask(CPURISCVState *env, int csrno,
2919 /* if pm.current==0 we can't modify current PM CSRs */
2920 if (check_pm_current_disabled(env, csrno)) {
2921 return RISCV_EXCP_NONE;
2924 if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
2925 env->cur_pmmask = val;
2927 env->mmte |= PM_EXT_DIRTY;
2929 /* Set XS and SD bits, since PM CSRs are dirty */
2930 mstatus = env->mstatus | MSTATUS_XS;
2931 write_mstatus(env, csrno, mstatus);
2932 return RISCV_EXCP_NONE;
2935 static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
2938 *val = env->mpmbase;
2939 return RISCV_EXCP_NONE;
2942 static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
2948 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
2949 env->cur_pmbase = val;
2951 env->mmte |= PM_EXT_DIRTY;
2953 /* Set XS and SD bits, since PM CSRs are dirty */
2954 mstatus = env->mstatus | MSTATUS_XS;
2955 write_mstatus(env, csrno, mstatus);
2956 return RISCV_EXCP_NONE;
2959 static RISCVException read_spmbase(CPURISCVState *env, int csrno,
2962 *val = env->spmbase;
2963 return RISCV_EXCP_NONE;
2966 static RISCVException write_spmbase(CPURISCVState *env, int csrno,
2971 /* if pm.current==0 we can't modify current PM CSRs */
2972 if (check_pm_current_disabled(env, csrno)) {
2973 return RISCV_EXCP_NONE;
2976 if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
2977 env->cur_pmbase = val;
2979 env->mmte |= PM_EXT_DIRTY;
2981 /* Set XS and SD bits, since PM CSRs are dirty */
2982 mstatus = env->mstatus | MSTATUS_XS;
2983 write_mstatus(env, csrno, mstatus);
2984 return RISCV_EXCP_NONE;
2987 static RISCVException read_upmbase(CPURISCVState *env, int csrno,
2990 *val = env->upmbase;
2991 return RISCV_EXCP_NONE;
2994 static RISCVException write_upmbase(CPURISCVState *env, int csrno,
2999 /* if pm.current==0 we can't modify current PM CSRs */
3000 if (check_pm_current_disabled(env, csrno)) {
3001 return RISCV_EXCP_NONE;
3004 if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
3005 env->cur_pmbase = val;
3007 env->mmte |= PM_EXT_DIRTY;
3009 /* Set XS and SD bits, since PM CSRs are dirty */
3010 mstatus = env->mstatus | MSTATUS_XS;
3011 write_mstatus(env, csrno, mstatus);
3012 return RISCV_EXCP_NONE;
3018 * riscv_csrrw - read and/or update control and status register
3020 * csrr <-> riscv_csrrw(env, csrno, ret_value, 0, 0);
3021 * csrrw <-> riscv_csrrw(env, csrno, ret_value, value, -1);
3022 * csrrs <-> riscv_csrrw(env, csrno, ret_value, -1, value);
3023 * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value);
3026 static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
3031 /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
3032 int read_only = get_field(csrno, 0xC00) == 3;
3033 int csr_min_priv = csr_ops[csrno].min_priv_ver;
3034 #if !defined(CONFIG_USER_ONLY)
3035 int effective_priv = env->priv;
3037 if (riscv_has_ext(env, RVH) &&
3038 env->priv == PRV_S &&
3039 !riscv_cpu_virt_enabled(env)) {
3041 * We are in S mode without virtualisation, therefore we are in HS Mode.
3042 * Add 1 to the effective privledge level to allow us to access the
3048 if (!env->debugger && (effective_priv < get_field(csrno, 0x300))) {
3049 return RISCV_EXCP_ILLEGAL_INST;
3052 if (write_mask && read_only) {
3053 return RISCV_EXCP_ILLEGAL_INST;
3056 /* ensure the CSR extension is enabled. */
3057 if (!cpu->cfg.ext_icsr) {
3058 return RISCV_EXCP_ILLEGAL_INST;
3061 /* check predicate */
3062 if (!csr_ops[csrno].predicate) {
3063 return RISCV_EXCP_ILLEGAL_INST;
3066 if (env->priv_ver < csr_min_priv) {
3067 return RISCV_EXCP_ILLEGAL_INST;
3070 return csr_ops[csrno].predicate(env, csrno);
3073 static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
3074 target_ulong *ret_value,
3075 target_ulong new_value,
3076 target_ulong write_mask)
3079 target_ulong old_value;
3081 /* execute combined read/write operation if it exists */
3082 if (csr_ops[csrno].op) {
3083 return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
3086 /* if no accessor exists then return failure */
3087 if (!csr_ops[csrno].read) {
3088 return RISCV_EXCP_ILLEGAL_INST;
3090 /* read old value */
3091 ret = csr_ops[csrno].read(env, csrno, &old_value);
3092 if (ret != RISCV_EXCP_NONE) {
3096 /* write value if writable and write mask set, otherwise drop writes */
3098 new_value = (old_value & ~write_mask) | (new_value & write_mask);
3099 if (csr_ops[csrno].write) {
3100 ret = csr_ops[csrno].write(env, csrno, new_value);
3101 if (ret != RISCV_EXCP_NONE) {
3107 /* return old value */
3109 *ret_value = old_value;
3112 return RISCV_EXCP_NONE;
3115 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
3116 target_ulong *ret_value,
3117 target_ulong new_value, target_ulong write_mask)
3119 RISCVCPU *cpu = env_archcpu(env);
3121 RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu);
3122 if (ret != RISCV_EXCP_NONE) {
3126 return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
3129 static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
3137 /* read old value */
3138 ret = csr_ops[csrno].read128(env, csrno, &old_value);
3139 if (ret != RISCV_EXCP_NONE) {
3143 /* write value if writable and write mask set, otherwise drop writes */
3144 if (int128_nz(write_mask)) {
3145 new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
3146 int128_and(new_value, write_mask));
3147 if (csr_ops[csrno].write128) {
3148 ret = csr_ops[csrno].write128(env, csrno, new_value);
3149 if (ret != RISCV_EXCP_NONE) {
3152 } else if (csr_ops[csrno].write) {
3153 /* avoids having to write wrappers for all registers */
3154 ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
3155 if (ret != RISCV_EXCP_NONE) {
3161 /* return old value */
3163 *ret_value = old_value;
3166 return RISCV_EXCP_NONE;
3169 RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
3171 Int128 new_value, Int128 write_mask)
3174 RISCVCPU *cpu = env_archcpu(env);
3176 ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu);
3177 if (ret != RISCV_EXCP_NONE) {
3181 if (csr_ops[csrno].read128) {
3182 return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
3186 * Fall back to 64-bit version for now, if the 128-bit alternative isn't
3188 * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
3189 * significant), for those, this fallback is correctly handling the accesses
3191 target_ulong old_value;
3192 ret = riscv_csrrw_do64(env, csrno, &old_value,
3193 int128_getlo(new_value),
3194 int128_getlo(write_mask));
3195 if (ret == RISCV_EXCP_NONE && ret_value) {
3196 *ret_value = int128_make64(old_value);
3202 * Debugger support. If not in user mode, set env->debugger before the
3203 * riscv_csrrw call and clear it after the call.
3205 RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
3206 target_ulong *ret_value,
3207 target_ulong new_value,
3208 target_ulong write_mask)
3211 #if !defined(CONFIG_USER_ONLY)
3212 env->debugger = true;
3214 ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
3215 #if !defined(CONFIG_USER_ONLY)
3216 env->debugger = false;
3221 /* Control and Status Register function table */
3222 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
3223 /* User Floating-Point CSRs */
3224 [CSR_FFLAGS] = { "fflags", fs, read_fflags, write_fflags },
3225 [CSR_FRM] = { "frm", fs, read_frm, write_frm },
3226 [CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr },
3228 [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart,
3229 .min_priv_ver = PRIV_VERSION_1_12_0 },
3230 [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat,
3231 .min_priv_ver = PRIV_VERSION_1_12_0 },
3232 [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm,
3233 .min_priv_ver = PRIV_VERSION_1_12_0 },
3234 [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr,
3235 .min_priv_ver = PRIV_VERSION_1_12_0 },
3236 [CSR_VL] = { "vl", vs, read_vl,
3237 .min_priv_ver = PRIV_VERSION_1_12_0 },
3238 [CSR_VTYPE] = { "vtype", vs, read_vtype,
3239 .min_priv_ver = PRIV_VERSION_1_12_0 },
3240 [CSR_VLENB] = { "vlenb", vs, read_vlenb,
3241 .min_priv_ver = PRIV_VERSION_1_12_0 },
3242 /* User Timers and Counters */
3243 [CSR_CYCLE] = { "cycle", ctr, read_instret },
3244 [CSR_INSTRET] = { "instret", ctr, read_instret },
3245 [CSR_CYCLEH] = { "cycleh", ctr32, read_instreth },
3246 [CSR_INSTRETH] = { "instreth", ctr32, read_instreth },
3249 * In privileged mode, the monitor will have to emulate TIME CSRs only if
3250 * rdtime callback is not provided by machine/platform emulation.
3252 [CSR_TIME] = { "time", ctr, read_time },
3253 [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
3255 #if !defined(CONFIG_USER_ONLY)
3256 /* Machine Timers and Counters */
3257 [CSR_MCYCLE] = { "mcycle", any, read_instret },
3258 [CSR_MINSTRET] = { "minstret", any, read_instret },
3259 [CSR_MCYCLEH] = { "mcycleh", any32, read_instreth },
3260 [CSR_MINSTRETH] = { "minstreth", any32, read_instreth },
3262 /* Machine Information Registers */
3263 [CSR_MVENDORID] = { "mvendorid", any, read_zero },
3264 [CSR_MARCHID] = { "marchid", any, read_zero },
3265 [CSR_MIMPID] = { "mimpid", any, read_zero },
3266 [CSR_MHARTID] = { "mhartid", any, read_mhartid },
3268 [CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero,
3269 .min_priv_ver = PRIV_VERSION_1_12_0 },
3270 /* Machine Trap Setup */
3271 [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL,
3272 read_mstatus_i128 },
3273 [CSR_MISA] = { "misa", any, read_misa, write_misa, NULL,
3275 [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg },
3276 [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
3277 [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
3278 [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
3279 [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, write_mcounteren },
3281 [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush },
3283 /* Machine Trap Handling */
3284 [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch, NULL,
3285 read_mscratch_i128, write_mscratch_i128 },
3286 [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc },
3287 [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause },
3288 [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval },
3289 [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip },
3291 /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
3292 [CSR_MISELECT] = { "miselect", aia_any, NULL, NULL, rmw_xiselect },
3293 [CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg },
3295 /* Machine-Level Interrupts (AIA) */
3296 [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
3298 /* Machine-Level IMSIC Interface (AIA) */
3299 [CSR_MSETEIPNUM] = { "mseteipnum", aia_any, NULL, NULL, rmw_xsetclreinum },
3300 [CSR_MCLREIPNUM] = { "mclreipnum", aia_any, NULL, NULL, rmw_xsetclreinum },
3301 [CSR_MSETEIENUM] = { "mseteienum", aia_any, NULL, NULL, rmw_xsetclreinum },
3302 [CSR_MCLREIENUM] = { "mclreienum", aia_any, NULL, NULL, rmw_xsetclreinum },
3303 [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
3305 /* Virtual Interrupts for Supervisor Level (AIA) */
3306 [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore },
3307 [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore },
3309 /* Machine-Level High-Half CSRs (AIA) */
3310 [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
3311 [CSR_MIEH] = { "mieh", aia_any32, NULL, NULL, rmw_mieh },
3312 [CSR_MVIENH] = { "mvienh", aia_any32, read_zero, write_ignore },
3313 [CSR_MVIPH] = { "mviph", aia_any32, read_zero, write_ignore },
3314 [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
3316 /* Execution environment configuration */
3317 [CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg,
3318 .min_priv_ver = PRIV_VERSION_1_12_0 },
3319 [CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh,
3320 .min_priv_ver = PRIV_VERSION_1_12_0 },
3321 [CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
3322 .min_priv_ver = PRIV_VERSION_1_12_0 },
3323 [CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg,
3324 .min_priv_ver = PRIV_VERSION_1_12_0 },
3325 [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
3326 .min_priv_ver = PRIV_VERSION_1_12_0 },
3328 /* Supervisor Trap Setup */
3329 [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
3330 read_sstatus_i128 },
3331 [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie },
3332 [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
3333 [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren },
3335 /* Supervisor Trap Handling */
3336 [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, NULL,
3337 read_sscratch_i128, write_sscratch_i128 },
3338 [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc },
3339 [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
3340 [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
3341 [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
3343 /* Supervisor Protection and Translation */
3344 [CSR_SATP] = { "satp", smode, read_satp, write_satp },
3346 /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
3347 [CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect },
3348 [CSR_SIREG] = { "sireg", aia_smode, NULL, NULL, rmw_xireg },
3350 /* Supervisor-Level Interrupts (AIA) */
3351 [CSR_STOPI] = { "stopi", aia_smode, read_stopi },
3353 /* Supervisor-Level IMSIC Interface (AIA) */
3354 [CSR_SSETEIPNUM] = { "sseteipnum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3355 [CSR_SCLREIPNUM] = { "sclreipnum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3356 [CSR_SSETEIENUM] = { "sseteienum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3357 [CSR_SCLREIENUM] = { "sclreienum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3358 [CSR_STOPEI] = { "stopei", aia_smode, NULL, NULL, rmw_xtopei },
3360 /* Supervisor-Level High-Half CSRs (AIA) */
3361 [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh },
3362 [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph },
3364 [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus,
3365 .min_priv_ver = PRIV_VERSION_1_12_0 },
3366 [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg,
3367 .min_priv_ver = PRIV_VERSION_1_12_0 },
3368 [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg,
3369 .min_priv_ver = PRIV_VERSION_1_12_0 },
3370 [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip,
3371 .min_priv_ver = PRIV_VERSION_1_12_0 },
3372 [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip,
3373 .min_priv_ver = PRIV_VERSION_1_12_0 },
3374 [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie,
3375 .min_priv_ver = PRIV_VERSION_1_12_0 },
3376 [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren,
3377 .min_priv_ver = PRIV_VERSION_1_12_0 },
3378 [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie,
3379 .min_priv_ver = PRIV_VERSION_1_12_0 },
3380 [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval,
3381 .min_priv_ver = PRIV_VERSION_1_12_0 },
3382 [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst,
3383 .min_priv_ver = PRIV_VERSION_1_12_0 },
3384 [CSR_HGEIP] = { "hgeip", hmode, read_hgeip,
3385 .min_priv_ver = PRIV_VERSION_1_12_0 },
3386 [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp,
3387 .min_priv_ver = PRIV_VERSION_1_12_0 },
3388 [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta,
3389 .min_priv_ver = PRIV_VERSION_1_12_0 },
3390 [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah,
3391 .min_priv_ver = PRIV_VERSION_1_12_0 },
3393 [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus,
3394 .min_priv_ver = PRIV_VERSION_1_12_0 },
3395 [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip,
3396 .min_priv_ver = PRIV_VERSION_1_12_0 },
3397 [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie ,
3398 .min_priv_ver = PRIV_VERSION_1_12_0 },
3399 [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec,
3400 .min_priv_ver = PRIV_VERSION_1_12_0 },
3401 [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch,
3402 .min_priv_ver = PRIV_VERSION_1_12_0 },
3403 [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc,
3404 .min_priv_ver = PRIV_VERSION_1_12_0 },
3405 [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause,
3406 .min_priv_ver = PRIV_VERSION_1_12_0 },
3407 [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval,
3408 .min_priv_ver = PRIV_VERSION_1_12_0 },
3409 [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
3410 .min_priv_ver = PRIV_VERSION_1_12_0 },
3412 [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
3413 .min_priv_ver = PRIV_VERSION_1_12_0 },
3414 [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
3415 .min_priv_ver = PRIV_VERSION_1_12_0 },
3417 /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
3418 [CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore },
3419 [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl, write_hvictl },
3420 [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, write_hviprio1 },
3421 [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, write_hviprio2 },
3424 * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
3426 [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL, rmw_xiselect },
3427 [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
3429 /* VS-Level Interrupts (H-extension with AIA) */
3430 [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi },
3432 /* VS-Level IMSIC Interface (H-extension with AIA) */
3433 [CSR_VSSETEIPNUM] = { "vsseteipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3434 [CSR_VSCLREIPNUM] = { "vsclreipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3435 [CSR_VSSETEIENUM] = { "vsseteienum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3436 [CSR_VSCLREIENUM] = { "vsclreienum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3437 [CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei },
3439 /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
3440 [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh },
3441 [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero, write_ignore },
3442 [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph },
3443 [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h, write_hviprio1h },
3444 [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h, write_hviprio2h },
3445 [CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh },
3446 [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph },
3448 /* Physical Memory Protection */
3449 [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg,
3450 .min_priv_ver = PRIV_VERSION_1_12_0 },
3451 [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
3452 [CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
3453 [CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
3454 [CSR_PMPCFG3] = { "pmpcfg3", pmp, read_pmpcfg, write_pmpcfg },
3455 [CSR_PMPADDR0] = { "pmpaddr0", pmp, read_pmpaddr, write_pmpaddr },
3456 [CSR_PMPADDR1] = { "pmpaddr1", pmp, read_pmpaddr, write_pmpaddr },
3457 [CSR_PMPADDR2] = { "pmpaddr2", pmp, read_pmpaddr, write_pmpaddr },
3458 [CSR_PMPADDR3] = { "pmpaddr3", pmp, read_pmpaddr, write_pmpaddr },
3459 [CSR_PMPADDR4] = { "pmpaddr4", pmp, read_pmpaddr, write_pmpaddr },
3460 [CSR_PMPADDR5] = { "pmpaddr5", pmp, read_pmpaddr, write_pmpaddr },
3461 [CSR_PMPADDR6] = { "pmpaddr6", pmp, read_pmpaddr, write_pmpaddr },
3462 [CSR_PMPADDR7] = { "pmpaddr7", pmp, read_pmpaddr, write_pmpaddr },
3463 [CSR_PMPADDR8] = { "pmpaddr8", pmp, read_pmpaddr, write_pmpaddr },
3464 [CSR_PMPADDR9] = { "pmpaddr9", pmp, read_pmpaddr, write_pmpaddr },
3465 [CSR_PMPADDR10] = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
3466 [CSR_PMPADDR11] = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
3467 [CSR_PMPADDR12] = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
3468 [CSR_PMPADDR13] = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
3469 [CSR_PMPADDR14] = { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
3470 [CSR_PMPADDR15] = { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
3473 [CSR_TSELECT] = { "tselect", debug, read_tselect, write_tselect },
3474 [CSR_TDATA1] = { "tdata1", debug, read_tdata, write_tdata },
3475 [CSR_TDATA2] = { "tdata2", debug, read_tdata, write_tdata },
3476 [CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata },
3478 /* User Pointer Masking */
3479 [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
3480 [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask, write_upmmask },
3481 [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase, write_upmbase },
3482 /* Machine Pointer Masking */
3483 [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
3484 [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask, write_mpmmask },
3485 [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase, write_mpmbase },
3486 /* Supervisor Pointer Masking */
3487 [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
3488 [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask, write_spmmask },
3489 [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase, write_spmbase },
3491 /* Performance Counters */
3492 [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_zero },
3493 [CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_zero },
3494 [CSR_HPMCOUNTER5] = { "hpmcounter5", ctr, read_zero },
3495 [CSR_HPMCOUNTER6] = { "hpmcounter6", ctr, read_zero },
3496 [CSR_HPMCOUNTER7] = { "hpmcounter7", ctr, read_zero },
3497 [CSR_HPMCOUNTER8] = { "hpmcounter8", ctr, read_zero },
3498 [CSR_HPMCOUNTER9] = { "hpmcounter9", ctr, read_zero },
3499 [CSR_HPMCOUNTER10] = { "hpmcounter10", ctr, read_zero },
3500 [CSR_HPMCOUNTER11] = { "hpmcounter11", ctr, read_zero },
3501 [CSR_HPMCOUNTER12] = { "hpmcounter12", ctr, read_zero },
3502 [CSR_HPMCOUNTER13] = { "hpmcounter13", ctr, read_zero },
3503 [CSR_HPMCOUNTER14] = { "hpmcounter14", ctr, read_zero },
3504 [CSR_HPMCOUNTER15] = { "hpmcounter15", ctr, read_zero },
3505 [CSR_HPMCOUNTER16] = { "hpmcounter16", ctr, read_zero },
3506 [CSR_HPMCOUNTER17] = { "hpmcounter17", ctr, read_zero },
3507 [CSR_HPMCOUNTER18] = { "hpmcounter18", ctr, read_zero },
3508 [CSR_HPMCOUNTER19] = { "hpmcounter19", ctr, read_zero },
3509 [CSR_HPMCOUNTER20] = { "hpmcounter20", ctr, read_zero },
3510 [CSR_HPMCOUNTER21] = { "hpmcounter21", ctr, read_zero },
3511 [CSR_HPMCOUNTER22] = { "hpmcounter22", ctr, read_zero },
3512 [CSR_HPMCOUNTER23] = { "hpmcounter23", ctr, read_zero },
3513 [CSR_HPMCOUNTER24] = { "hpmcounter24", ctr, read_zero },
3514 [CSR_HPMCOUNTER25] = { "hpmcounter25", ctr, read_zero },
3515 [CSR_HPMCOUNTER26] = { "hpmcounter26", ctr, read_zero },
3516 [CSR_HPMCOUNTER27] = { "hpmcounter27", ctr, read_zero },
3517 [CSR_HPMCOUNTER28] = { "hpmcounter28", ctr, read_zero },
3518 [CSR_HPMCOUNTER29] = { "hpmcounter29", ctr, read_zero },
3519 [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_zero },
3520 [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_zero },
3522 [CSR_MHPMCOUNTER3] = { "mhpmcounter3", any, read_zero },
3523 [CSR_MHPMCOUNTER4] = { "mhpmcounter4", any, read_zero },
3524 [CSR_MHPMCOUNTER5] = { "mhpmcounter5", any, read_zero },
3525 [CSR_MHPMCOUNTER6] = { "mhpmcounter6", any, read_zero },
3526 [CSR_MHPMCOUNTER7] = { "mhpmcounter7", any, read_zero },
3527 [CSR_MHPMCOUNTER8] = { "mhpmcounter8", any, read_zero },
3528 [CSR_MHPMCOUNTER9] = { "mhpmcounter9", any, read_zero },
3529 [CSR_MHPMCOUNTER10] = { "mhpmcounter10", any, read_zero },
3530 [CSR_MHPMCOUNTER11] = { "mhpmcounter11", any, read_zero },
3531 [CSR_MHPMCOUNTER12] = { "mhpmcounter12", any, read_zero },
3532 [CSR_MHPMCOUNTER13] = { "mhpmcounter13", any, read_zero },
3533 [CSR_MHPMCOUNTER14] = { "mhpmcounter14", any, read_zero },
3534 [CSR_MHPMCOUNTER15] = { "mhpmcounter15", any, read_zero },
3535 [CSR_MHPMCOUNTER16] = { "mhpmcounter16", any, read_zero },
3536 [CSR_MHPMCOUNTER17] = { "mhpmcounter17", any, read_zero },
3537 [CSR_MHPMCOUNTER18] = { "mhpmcounter18", any, read_zero },
3538 [CSR_MHPMCOUNTER19] = { "mhpmcounter19", any, read_zero },
3539 [CSR_MHPMCOUNTER20] = { "mhpmcounter20", any, read_zero },
3540 [CSR_MHPMCOUNTER21] = { "mhpmcounter21", any, read_zero },
3541 [CSR_MHPMCOUNTER22] = { "mhpmcounter22", any, read_zero },
3542 [CSR_MHPMCOUNTER23] = { "mhpmcounter23", any, read_zero },
3543 [CSR_MHPMCOUNTER24] = { "mhpmcounter24", any, read_zero },
3544 [CSR_MHPMCOUNTER25] = { "mhpmcounter25", any, read_zero },
3545 [CSR_MHPMCOUNTER26] = { "mhpmcounter26", any, read_zero },
3546 [CSR_MHPMCOUNTER27] = { "mhpmcounter27", any, read_zero },
3547 [CSR_MHPMCOUNTER28] = { "mhpmcounter28", any, read_zero },
3548 [CSR_MHPMCOUNTER29] = { "mhpmcounter29", any, read_zero },
3549 [CSR_MHPMCOUNTER30] = { "mhpmcounter30", any, read_zero },
3550 [CSR_MHPMCOUNTER31] = { "mhpmcounter31", any, read_zero },
3552 [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_zero },
3553 [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_zero },
3554 [CSR_MHPMEVENT5] = { "mhpmevent5", any, read_zero },
3555 [CSR_MHPMEVENT6] = { "mhpmevent6", any, read_zero },
3556 [CSR_MHPMEVENT7] = { "mhpmevent7", any, read_zero },
3557 [CSR_MHPMEVENT8] = { "mhpmevent8", any, read_zero },
3558 [CSR_MHPMEVENT9] = { "mhpmevent9", any, read_zero },
3559 [CSR_MHPMEVENT10] = { "mhpmevent10", any, read_zero },
3560 [CSR_MHPMEVENT11] = { "mhpmevent11", any, read_zero },
3561 [CSR_MHPMEVENT12] = { "mhpmevent12", any, read_zero },
3562 [CSR_MHPMEVENT13] = { "mhpmevent13", any, read_zero },
3563 [CSR_MHPMEVENT14] = { "mhpmevent14", any, read_zero },
3564 [CSR_MHPMEVENT15] = { "mhpmevent15", any, read_zero },
3565 [CSR_MHPMEVENT16] = { "mhpmevent16", any, read_zero },
3566 [CSR_MHPMEVENT17] = { "mhpmevent17", any, read_zero },
3567 [CSR_MHPMEVENT18] = { "mhpmevent18", any, read_zero },
3568 [CSR_MHPMEVENT19] = { "mhpmevent19", any, read_zero },
3569 [CSR_MHPMEVENT20] = { "mhpmevent20", any, read_zero },
3570 [CSR_MHPMEVENT21] = { "mhpmevent21", any, read_zero },
3571 [CSR_MHPMEVENT22] = { "mhpmevent22", any, read_zero },
3572 [CSR_MHPMEVENT23] = { "mhpmevent23", any, read_zero },
3573 [CSR_MHPMEVENT24] = { "mhpmevent24", any, read_zero },
3574 [CSR_MHPMEVENT25] = { "mhpmevent25", any, read_zero },
3575 [CSR_MHPMEVENT26] = { "mhpmevent26", any, read_zero },
3576 [CSR_MHPMEVENT27] = { "mhpmevent27", any, read_zero },
3577 [CSR_MHPMEVENT28] = { "mhpmevent28", any, read_zero },
3578 [CSR_MHPMEVENT29] = { "mhpmevent29", any, read_zero },
3579 [CSR_MHPMEVENT30] = { "mhpmevent30", any, read_zero },
3580 [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_zero },
3582 [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_zero },
3583 [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_zero },
3584 [CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_zero },
3585 [CSR_HPMCOUNTER6H] = { "hpmcounter6h", ctr32, read_zero },
3586 [CSR_HPMCOUNTER7H] = { "hpmcounter7h", ctr32, read_zero },
3587 [CSR_HPMCOUNTER8H] = { "hpmcounter8h", ctr32, read_zero },
3588 [CSR_HPMCOUNTER9H] = { "hpmcounter9h", ctr32, read_zero },
3589 [CSR_HPMCOUNTER10H] = { "hpmcounter10h", ctr32, read_zero },
3590 [CSR_HPMCOUNTER11H] = { "hpmcounter11h", ctr32, read_zero },
3591 [CSR_HPMCOUNTER12H] = { "hpmcounter12h", ctr32, read_zero },
3592 [CSR_HPMCOUNTER13H] = { "hpmcounter13h", ctr32, read_zero },
3593 [CSR_HPMCOUNTER14H] = { "hpmcounter14h", ctr32, read_zero },
3594 [CSR_HPMCOUNTER15H] = { "hpmcounter15h", ctr32, read_zero },
3595 [CSR_HPMCOUNTER16H] = { "hpmcounter16h", ctr32, read_zero },
3596 [CSR_HPMCOUNTER17H] = { "hpmcounter17h", ctr32, read_zero },
3597 [CSR_HPMCOUNTER18H] = { "hpmcounter18h", ctr32, read_zero },
3598 [CSR_HPMCOUNTER19H] = { "hpmcounter19h", ctr32, read_zero },
3599 [CSR_HPMCOUNTER20H] = { "hpmcounter20h", ctr32, read_zero },
3600 [CSR_HPMCOUNTER21H] = { "hpmcounter21h", ctr32, read_zero },
3601 [CSR_HPMCOUNTER22H] = { "hpmcounter22h", ctr32, read_zero },
3602 [CSR_HPMCOUNTER23H] = { "hpmcounter23h", ctr32, read_zero },
3603 [CSR_HPMCOUNTER24H] = { "hpmcounter24h", ctr32, read_zero },
3604 [CSR_HPMCOUNTER25H] = { "hpmcounter25h", ctr32, read_zero },
3605 [CSR_HPMCOUNTER26H] = { "hpmcounter26h", ctr32, read_zero },
3606 [CSR_HPMCOUNTER27H] = { "hpmcounter27h", ctr32, read_zero },
3607 [CSR_HPMCOUNTER28H] = { "hpmcounter28h", ctr32, read_zero },
3608 [CSR_HPMCOUNTER29H] = { "hpmcounter29h", ctr32, read_zero },
3609 [CSR_HPMCOUNTER30H] = { "hpmcounter30h", ctr32, read_zero },
3610 [CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_zero },
3612 [CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", any32, read_zero },
3613 [CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", any32, read_zero },
3614 [CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", any32, read_zero },
3615 [CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", any32, read_zero },
3616 [CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", any32, read_zero },
3617 [CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", any32, read_zero },
3618 [CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", any32, read_zero },
3619 [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32, read_zero },
3620 [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32, read_zero },
3621 [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32, read_zero },
3622 [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32, read_zero },
3623 [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32, read_zero },
3624 [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32, read_zero },
3625 [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32, read_zero },
3626 [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32, read_zero },
3627 [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32, read_zero },
3628 [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32, read_zero },
3629 [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32, read_zero },
3630 [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32, read_zero },
3631 [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32, read_zero },
3632 [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32, read_zero },
3633 [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32, read_zero },
3634 [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32, read_zero },
3635 [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32, read_zero },
3636 [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32, read_zero },
3637 [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32, read_zero },
3638 [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32, read_zero },
3639 [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32, read_zero },
3640 [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32, read_zero },
3641 #endif /* !CONFIG_USER_ONLY */