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
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"
25 #include "time_helper.h"
26 #include "exec/exec-all.h"
27 #include "exec/tb-flush.h"
28 #include "sysemu/cpu-timers.h"
29 #include "qemu/guest-random.h"
30 #include "qapi/error.h"
32 /* CSR function table public API */
33 void riscv_get_csr_ops(int csrno
, riscv_csr_operations
*ops
)
35 *ops
= csr_ops
[csrno
& (CSR_TABLE_SIZE
- 1)];
38 void riscv_set_csr_ops(int csrno
, riscv_csr_operations
*ops
)
40 csr_ops
[csrno
& (CSR_TABLE_SIZE
- 1)] = *ops
;
44 #if !defined(CONFIG_USER_ONLY)
45 RISCVException
smstateen_acc_ok(CPURISCVState
*env
, int index
, uint64_t bit
)
47 bool virt
= env
->virt_enabled
;
49 if (env
->priv
== PRV_M
|| !riscv_cpu_cfg(env
)->ext_smstateen
) {
50 return RISCV_EXCP_NONE
;
53 if (!(env
->mstateen
[index
] & bit
)) {
54 return RISCV_EXCP_ILLEGAL_INST
;
58 if (!(env
->hstateen
[index
] & bit
)) {
59 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
62 if (env
->priv
== PRV_U
&& !(env
->sstateen
[index
] & bit
)) {
63 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
67 if (env
->priv
== PRV_U
&& riscv_has_ext(env
, RVS
)) {
68 if (!(env
->sstateen
[index
] & bit
)) {
69 return RISCV_EXCP_ILLEGAL_INST
;
73 return RISCV_EXCP_NONE
;
77 static RISCVException
fs(CPURISCVState
*env
, int csrno
)
79 #if !defined(CONFIG_USER_ONLY)
80 if (!env
->debugger
&& !riscv_cpu_fp_enabled(env
) &&
81 !riscv_cpu_cfg(env
)->ext_zfinx
) {
82 return RISCV_EXCP_ILLEGAL_INST
;
85 if (!env
->debugger
&& !riscv_cpu_fp_enabled(env
)) {
86 return smstateen_acc_ok(env
, 0, SMSTATEEN0_FCSR
);
89 return RISCV_EXCP_NONE
;
92 static RISCVException
vs(CPURISCVState
*env
, int csrno
)
94 if (riscv_cpu_cfg(env
)->ext_zve32f
) {
95 #if !defined(CONFIG_USER_ONLY)
96 if (!env
->debugger
&& !riscv_cpu_vector_enabled(env
)) {
97 return RISCV_EXCP_ILLEGAL_INST
;
100 return RISCV_EXCP_NONE
;
102 return RISCV_EXCP_ILLEGAL_INST
;
105 static RISCVException
ctr(CPURISCVState
*env
, int csrno
)
107 #if !defined(CONFIG_USER_ONLY)
108 RISCVCPU
*cpu
= env_archcpu(env
);
110 target_ulong ctr_mask
;
111 int base_csrno
= CSR_CYCLE
;
112 bool rv32
= riscv_cpu_mxl(env
) == MXL_RV32
? true : false;
114 if (rv32
&& csrno
>= CSR_CYCLEH
) {
115 /* Offset for RV32 hpmcounternh counters */
118 ctr_index
= csrno
- base_csrno
;
119 ctr_mask
= BIT(ctr_index
);
121 if ((csrno
>= CSR_CYCLE
&& csrno
<= CSR_INSTRET
) ||
122 (csrno
>= CSR_CYCLEH
&& csrno
<= CSR_INSTRETH
)) {
123 goto skip_ext_pmu_check
;
126 if (!(cpu
->pmu_avail_ctrs
& ctr_mask
)) {
127 /* No counter is enabled in PMU or the counter is out of range */
128 return RISCV_EXCP_ILLEGAL_INST
;
134 return RISCV_EXCP_NONE
;
137 if (env
->priv
< PRV_M
&& !get_field(env
->mcounteren
, ctr_mask
)) {
138 return RISCV_EXCP_ILLEGAL_INST
;
141 if (env
->virt_enabled
) {
142 if (!get_field(env
->hcounteren
, ctr_mask
) ||
143 (env
->priv
== PRV_U
&& !get_field(env
->scounteren
, ctr_mask
))) {
144 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
148 if (riscv_has_ext(env
, RVS
) && env
->priv
== PRV_U
&&
149 !get_field(env
->scounteren
, ctr_mask
)) {
150 return RISCV_EXCP_ILLEGAL_INST
;
154 return RISCV_EXCP_NONE
;
157 static RISCVException
ctr32(CPURISCVState
*env
, int csrno
)
159 if (riscv_cpu_mxl(env
) != MXL_RV32
) {
160 return RISCV_EXCP_ILLEGAL_INST
;
163 return ctr(env
, csrno
);
166 static RISCVException
zcmt(CPURISCVState
*env
, int csrno
)
168 if (!riscv_cpu_cfg(env
)->ext_zcmt
) {
169 return RISCV_EXCP_ILLEGAL_INST
;
172 #if !defined(CONFIG_USER_ONLY)
173 RISCVException ret
= smstateen_acc_ok(env
, 0, SMSTATEEN0_JVT
);
174 if (ret
!= RISCV_EXCP_NONE
) {
179 return RISCV_EXCP_NONE
;
182 #if !defined(CONFIG_USER_ONLY)
183 static RISCVException
mctr(CPURISCVState
*env
, int csrno
)
185 int pmu_num
= riscv_cpu_cfg(env
)->pmu_num
;
187 int base_csrno
= CSR_MHPMCOUNTER3
;
189 if ((riscv_cpu_mxl(env
) == MXL_RV32
) && csrno
>= CSR_MCYCLEH
) {
190 /* Offset for RV32 mhpmcounternh counters */
193 ctr_index
= csrno
- base_csrno
;
194 if (!pmu_num
|| ctr_index
>= pmu_num
) {
195 /* The PMU is not enabled or counter is out of range */
196 return RISCV_EXCP_ILLEGAL_INST
;
199 return RISCV_EXCP_NONE
;
202 static RISCVException
mctr32(CPURISCVState
*env
, int csrno
)
204 if (riscv_cpu_mxl(env
) != MXL_RV32
) {
205 return RISCV_EXCP_ILLEGAL_INST
;
208 return mctr(env
, csrno
);
211 static RISCVException
sscofpmf(CPURISCVState
*env
, int csrno
)
213 if (!riscv_cpu_cfg(env
)->ext_sscofpmf
) {
214 return RISCV_EXCP_ILLEGAL_INST
;
217 return RISCV_EXCP_NONE
;
220 static RISCVException
any(CPURISCVState
*env
, int csrno
)
222 return RISCV_EXCP_NONE
;
225 static RISCVException
any32(CPURISCVState
*env
, int csrno
)
227 if (riscv_cpu_mxl(env
) != MXL_RV32
) {
228 return RISCV_EXCP_ILLEGAL_INST
;
231 return any(env
, csrno
);
235 static int aia_any(CPURISCVState
*env
, int csrno
)
237 if (!riscv_cpu_cfg(env
)->ext_smaia
) {
238 return RISCV_EXCP_ILLEGAL_INST
;
241 return any(env
, csrno
);
244 static int aia_any32(CPURISCVState
*env
, int csrno
)
246 if (!riscv_cpu_cfg(env
)->ext_smaia
) {
247 return RISCV_EXCP_ILLEGAL_INST
;
250 return any32(env
, csrno
);
253 static RISCVException
smode(CPURISCVState
*env
, int csrno
)
255 if (riscv_has_ext(env
, RVS
)) {
256 return RISCV_EXCP_NONE
;
259 return RISCV_EXCP_ILLEGAL_INST
;
262 static int smode32(CPURISCVState
*env
, int csrno
)
264 if (riscv_cpu_mxl(env
) != MXL_RV32
) {
265 return RISCV_EXCP_ILLEGAL_INST
;
268 return smode(env
, csrno
);
271 static int aia_smode(CPURISCVState
*env
, int csrno
)
273 if (!riscv_cpu_cfg(env
)->ext_ssaia
) {
274 return RISCV_EXCP_ILLEGAL_INST
;
277 return smode(env
, csrno
);
280 static int aia_smode32(CPURISCVState
*env
, int csrno
)
282 if (!riscv_cpu_cfg(env
)->ext_ssaia
) {
283 return RISCV_EXCP_ILLEGAL_INST
;
286 return smode32(env
, csrno
);
289 static RISCVException
hmode(CPURISCVState
*env
, int csrno
)
291 if (riscv_has_ext(env
, RVH
)) {
292 return RISCV_EXCP_NONE
;
295 return RISCV_EXCP_ILLEGAL_INST
;
298 static RISCVException
hmode32(CPURISCVState
*env
, int csrno
)
300 if (riscv_cpu_mxl(env
) != MXL_RV32
) {
301 return RISCV_EXCP_ILLEGAL_INST
;
304 return hmode(env
, csrno
);
308 static RISCVException
umode(CPURISCVState
*env
, int csrno
)
310 if (riscv_has_ext(env
, RVU
)) {
311 return RISCV_EXCP_NONE
;
314 return RISCV_EXCP_ILLEGAL_INST
;
317 static RISCVException
umode32(CPURISCVState
*env
, int csrno
)
319 if (riscv_cpu_mxl(env
) != MXL_RV32
) {
320 return RISCV_EXCP_ILLEGAL_INST
;
323 return umode(env
, csrno
);
326 static RISCVException
mstateen(CPURISCVState
*env
, int csrno
)
328 if (!riscv_cpu_cfg(env
)->ext_smstateen
) {
329 return RISCV_EXCP_ILLEGAL_INST
;
332 return any(env
, csrno
);
335 static RISCVException
hstateen_pred(CPURISCVState
*env
, int csrno
, int base
)
337 if (!riscv_cpu_cfg(env
)->ext_smstateen
) {
338 return RISCV_EXCP_ILLEGAL_INST
;
341 RISCVException ret
= hmode(env
, csrno
);
342 if (ret
!= RISCV_EXCP_NONE
) {
347 return RISCV_EXCP_NONE
;
350 if (env
->priv
< PRV_M
) {
351 if (!(env
->mstateen
[csrno
- base
] & SMSTATEEN_STATEEN
)) {
352 return RISCV_EXCP_ILLEGAL_INST
;
356 return RISCV_EXCP_NONE
;
359 static RISCVException
hstateen(CPURISCVState
*env
, int csrno
)
361 return hstateen_pred(env
, csrno
, CSR_HSTATEEN0
);
364 static RISCVException
hstateenh(CPURISCVState
*env
, int csrno
)
366 return hstateen_pred(env
, csrno
, CSR_HSTATEEN0H
);
369 static RISCVException
sstateen(CPURISCVState
*env
, int csrno
)
371 bool virt
= env
->virt_enabled
;
372 int index
= csrno
- CSR_SSTATEEN0
;
374 if (!riscv_cpu_cfg(env
)->ext_smstateen
) {
375 return RISCV_EXCP_ILLEGAL_INST
;
378 RISCVException ret
= smode(env
, csrno
);
379 if (ret
!= RISCV_EXCP_NONE
) {
384 return RISCV_EXCP_NONE
;
387 if (env
->priv
< PRV_M
) {
388 if (!(env
->mstateen
[index
] & SMSTATEEN_STATEEN
)) {
389 return RISCV_EXCP_ILLEGAL_INST
;
393 if (!(env
->hstateen
[index
] & SMSTATEEN_STATEEN
)) {
394 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
399 return RISCV_EXCP_NONE
;
402 static RISCVException
sstc(CPURISCVState
*env
, int csrno
)
404 bool hmode_check
= false;
406 if (!riscv_cpu_cfg(env
)->ext_sstc
|| !env
->rdtime_fn
) {
407 return RISCV_EXCP_ILLEGAL_INST
;
410 if ((csrno
== CSR_VSTIMECMP
) || (csrno
== CSR_VSTIMECMPH
)) {
414 RISCVException ret
= hmode_check
? hmode(env
, csrno
) : smode(env
, csrno
);
415 if (ret
!= RISCV_EXCP_NONE
) {
420 return RISCV_EXCP_NONE
;
423 if (env
->priv
== PRV_M
) {
424 return RISCV_EXCP_NONE
;
428 * No need of separate function for rv32 as menvcfg stores both menvcfg
431 if (!(get_field(env
->mcounteren
, COUNTEREN_TM
) &&
432 get_field(env
->menvcfg
, MENVCFG_STCE
))) {
433 return RISCV_EXCP_ILLEGAL_INST
;
436 if (env
->virt_enabled
) {
437 if (!(get_field(env
->hcounteren
, COUNTEREN_TM
) &&
438 get_field(env
->henvcfg
, HENVCFG_STCE
))) {
439 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
443 return RISCV_EXCP_NONE
;
446 static RISCVException
sstc_32(CPURISCVState
*env
, int csrno
)
448 if (riscv_cpu_mxl(env
) != MXL_RV32
) {
449 return RISCV_EXCP_ILLEGAL_INST
;
452 return sstc(env
, csrno
);
455 static RISCVException
satp(CPURISCVState
*env
, int csrno
)
457 if (env
->priv
== PRV_S
&& !env
->virt_enabled
&&
458 get_field(env
->mstatus
, MSTATUS_TVM
)) {
459 return RISCV_EXCP_ILLEGAL_INST
;
461 if (env
->priv
== PRV_S
&& env
->virt_enabled
&&
462 get_field(env
->hstatus
, HSTATUS_VTVM
)) {
463 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
466 return smode(env
, csrno
);
469 static RISCVException
hgatp(CPURISCVState
*env
, int csrno
)
471 if (env
->priv
== PRV_S
&& !env
->virt_enabled
&&
472 get_field(env
->mstatus
, MSTATUS_TVM
)) {
473 return RISCV_EXCP_ILLEGAL_INST
;
476 return hmode(env
, csrno
);
479 /* Checks if PointerMasking registers could be accessed */
480 static RISCVException
pointer_masking(CPURISCVState
*env
, int csrno
)
482 /* Check if j-ext is present */
483 if (riscv_has_ext(env
, RVJ
)) {
484 return RISCV_EXCP_NONE
;
486 return RISCV_EXCP_ILLEGAL_INST
;
489 static int aia_hmode(CPURISCVState
*env
, int csrno
)
491 if (!riscv_cpu_cfg(env
)->ext_ssaia
) {
492 return RISCV_EXCP_ILLEGAL_INST
;
495 return hmode(env
, csrno
);
498 static int aia_hmode32(CPURISCVState
*env
, int csrno
)
500 if (!riscv_cpu_cfg(env
)->ext_ssaia
) {
501 return RISCV_EXCP_ILLEGAL_INST
;
504 return hmode32(env
, csrno
);
507 static RISCVException
pmp(CPURISCVState
*env
, int csrno
)
509 if (riscv_cpu_cfg(env
)->pmp
) {
510 if (csrno
<= CSR_PMPCFG3
) {
511 uint32_t reg_index
= csrno
- CSR_PMPCFG0
;
513 /* TODO: RV128 restriction check */
514 if ((reg_index
& 1) && (riscv_cpu_mxl(env
) == MXL_RV64
)) {
515 return RISCV_EXCP_ILLEGAL_INST
;
519 return RISCV_EXCP_NONE
;
522 return RISCV_EXCP_ILLEGAL_INST
;
525 static RISCVException
epmp(CPURISCVState
*env
, int csrno
)
527 if (riscv_cpu_cfg(env
)->epmp
) {
528 return RISCV_EXCP_NONE
;
531 return RISCV_EXCP_ILLEGAL_INST
;
534 static RISCVException
debug(CPURISCVState
*env
, int csrno
)
536 if (riscv_cpu_cfg(env
)->debug
) {
537 return RISCV_EXCP_NONE
;
540 return RISCV_EXCP_ILLEGAL_INST
;
544 static RISCVException
seed(CPURISCVState
*env
, int csrno
)
546 if (!riscv_cpu_cfg(env
)->ext_zkr
) {
547 return RISCV_EXCP_ILLEGAL_INST
;
550 #if !defined(CONFIG_USER_ONLY)
552 return RISCV_EXCP_NONE
;
556 * With a CSR read-write instruction:
557 * 1) The seed CSR is always available in machine mode as normal.
558 * 2) Attempted access to seed from virtual modes VS and VU always raises
559 * an exception(virtual instruction exception only if mseccfg.sseed=1).
560 * 3) Without the corresponding access control bit set to 1, any attempted
561 * access to seed from U, S or HS modes will raise an illegal instruction
564 if (env
->priv
== PRV_M
) {
565 return RISCV_EXCP_NONE
;
566 } else if (env
->virt_enabled
) {
567 if (env
->mseccfg
& MSECCFG_SSEED
) {
568 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
570 return RISCV_EXCP_ILLEGAL_INST
;
573 if (env
->priv
== PRV_S
&& (env
->mseccfg
& MSECCFG_SSEED
)) {
574 return RISCV_EXCP_NONE
;
575 } else if (env
->priv
== PRV_U
&& (env
->mseccfg
& MSECCFG_USEED
)) {
576 return RISCV_EXCP_NONE
;
578 return RISCV_EXCP_ILLEGAL_INST
;
582 return RISCV_EXCP_NONE
;
586 /* User Floating-Point CSRs */
587 static RISCVException
read_fflags(CPURISCVState
*env
, int csrno
,
590 *val
= riscv_cpu_get_fflags(env
);
591 return RISCV_EXCP_NONE
;
594 static RISCVException
write_fflags(CPURISCVState
*env
, int csrno
,
597 #if !defined(CONFIG_USER_ONLY)
598 if (riscv_has_ext(env
, RVF
)) {
599 env
->mstatus
|= MSTATUS_FS
;
602 riscv_cpu_set_fflags(env
, val
& (FSR_AEXC
>> FSR_AEXC_SHIFT
));
603 return RISCV_EXCP_NONE
;
606 static RISCVException
read_frm(CPURISCVState
*env
, int csrno
,
610 return RISCV_EXCP_NONE
;
613 static RISCVException
write_frm(CPURISCVState
*env
, int csrno
,
616 #if !defined(CONFIG_USER_ONLY)
617 if (riscv_has_ext(env
, RVF
)) {
618 env
->mstatus
|= MSTATUS_FS
;
621 env
->frm
= val
& (FSR_RD
>> FSR_RD_SHIFT
);
622 return RISCV_EXCP_NONE
;
625 static RISCVException
read_fcsr(CPURISCVState
*env
, int csrno
,
628 *val
= (riscv_cpu_get_fflags(env
) << FSR_AEXC_SHIFT
)
629 | (env
->frm
<< FSR_RD_SHIFT
);
630 return RISCV_EXCP_NONE
;
633 static RISCVException
write_fcsr(CPURISCVState
*env
, int csrno
,
636 #if !defined(CONFIG_USER_ONLY)
637 if (riscv_has_ext(env
, RVF
)) {
638 env
->mstatus
|= MSTATUS_FS
;
641 env
->frm
= (val
& FSR_RD
) >> FSR_RD_SHIFT
;
642 riscv_cpu_set_fflags(env
, (val
& FSR_AEXC
) >> FSR_AEXC_SHIFT
);
643 return RISCV_EXCP_NONE
;
646 static RISCVException
read_vtype(CPURISCVState
*env
, int csrno
,
652 vill
= (uint32_t)env
->vill
<< 31;
655 vill
= (uint64_t)env
->vill
<< 63;
658 g_assert_not_reached();
660 *val
= (target_ulong
)vill
| env
->vtype
;
661 return RISCV_EXCP_NONE
;
664 static RISCVException
read_vl(CPURISCVState
*env
, int csrno
,
668 return RISCV_EXCP_NONE
;
671 static int read_vlenb(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
673 *val
= riscv_cpu_cfg(env
)->vlen
>> 3;
674 return RISCV_EXCP_NONE
;
677 static RISCVException
read_vxrm(CPURISCVState
*env
, int csrno
,
681 return RISCV_EXCP_NONE
;
684 static RISCVException
write_vxrm(CPURISCVState
*env
, int csrno
,
687 #if !defined(CONFIG_USER_ONLY)
688 env
->mstatus
|= MSTATUS_VS
;
691 return RISCV_EXCP_NONE
;
694 static RISCVException
read_vxsat(CPURISCVState
*env
, int csrno
,
698 return RISCV_EXCP_NONE
;
701 static RISCVException
write_vxsat(CPURISCVState
*env
, int csrno
,
704 #if !defined(CONFIG_USER_ONLY)
705 env
->mstatus
|= MSTATUS_VS
;
708 return RISCV_EXCP_NONE
;
711 static RISCVException
read_vstart(CPURISCVState
*env
, int csrno
,
715 return RISCV_EXCP_NONE
;
718 static RISCVException
write_vstart(CPURISCVState
*env
, int csrno
,
721 #if !defined(CONFIG_USER_ONLY)
722 env
->mstatus
|= MSTATUS_VS
;
725 * The vstart CSR is defined to have only enough writable bits
726 * to hold the largest element index, i.e. lg2(VLEN) bits.
728 env
->vstart
= val
& ~(~0ULL << ctzl(riscv_cpu_cfg(env
)->vlen
));
729 return RISCV_EXCP_NONE
;
732 static int read_vcsr(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
734 *val
= (env
->vxrm
<< VCSR_VXRM_SHIFT
) | (env
->vxsat
<< VCSR_VXSAT_SHIFT
);
735 return RISCV_EXCP_NONE
;
738 static int write_vcsr(CPURISCVState
*env
, int csrno
, target_ulong val
)
740 #if !defined(CONFIG_USER_ONLY)
741 env
->mstatus
|= MSTATUS_VS
;
743 env
->vxrm
= (val
& VCSR_VXRM
) >> VCSR_VXRM_SHIFT
;
744 env
->vxsat
= (val
& VCSR_VXSAT
) >> VCSR_VXSAT_SHIFT
;
745 return RISCV_EXCP_NONE
;
748 /* User Timers and Counters */
749 static target_ulong
get_ticks(bool shift
)
754 #if !defined(CONFIG_USER_ONLY)
755 if (icount_enabled()) {
758 val
= cpu_get_host_ticks();
761 val
= cpu_get_host_ticks();
773 #if defined(CONFIG_USER_ONLY)
774 static RISCVException
read_time(CPURISCVState
*env
, int csrno
,
777 *val
= cpu_get_host_ticks();
778 return RISCV_EXCP_NONE
;
781 static RISCVException
read_timeh(CPURISCVState
*env
, int csrno
,
784 *val
= cpu_get_host_ticks() >> 32;
785 return RISCV_EXCP_NONE
;
788 static int read_hpmcounter(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
790 *val
= get_ticks(false);
791 return RISCV_EXCP_NONE
;
794 static int read_hpmcounterh(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
796 *val
= get_ticks(true);
797 return RISCV_EXCP_NONE
;
800 #else /* CONFIG_USER_ONLY */
802 static int read_mhpmevent(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
804 int evt_index
= csrno
- CSR_MCOUNTINHIBIT
;
806 *val
= env
->mhpmevent_val
[evt_index
];
808 return RISCV_EXCP_NONE
;
811 static int write_mhpmevent(CPURISCVState
*env
, int csrno
, target_ulong val
)
813 int evt_index
= csrno
- CSR_MCOUNTINHIBIT
;
814 uint64_t mhpmevt_val
= val
;
816 env
->mhpmevent_val
[evt_index
] = val
;
818 if (riscv_cpu_mxl(env
) == MXL_RV32
) {
819 mhpmevt_val
= mhpmevt_val
|
820 ((uint64_t)env
->mhpmeventh_val
[evt_index
] << 32);
822 riscv_pmu_update_event_map(env
, mhpmevt_val
, evt_index
);
824 return RISCV_EXCP_NONE
;
827 static int read_mhpmeventh(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
829 int evt_index
= csrno
- CSR_MHPMEVENT3H
+ 3;
831 *val
= env
->mhpmeventh_val
[evt_index
];
833 return RISCV_EXCP_NONE
;
836 static int write_mhpmeventh(CPURISCVState
*env
, int csrno
, target_ulong val
)
838 int evt_index
= csrno
- CSR_MHPMEVENT3H
+ 3;
839 uint64_t mhpmevth_val
= val
;
840 uint64_t mhpmevt_val
= env
->mhpmevent_val
[evt_index
];
842 mhpmevt_val
= mhpmevt_val
| (mhpmevth_val
<< 32);
843 env
->mhpmeventh_val
[evt_index
] = val
;
845 riscv_pmu_update_event_map(env
, mhpmevt_val
, evt_index
);
847 return RISCV_EXCP_NONE
;
850 static int write_mhpmcounter(CPURISCVState
*env
, int csrno
, target_ulong val
)
852 int ctr_idx
= csrno
- CSR_MCYCLE
;
853 PMUCTRState
*counter
= &env
->pmu_ctrs
[ctr_idx
];
854 uint64_t mhpmctr_val
= val
;
856 counter
->mhpmcounter_val
= val
;
857 if (riscv_pmu_ctr_monitor_cycles(env
, ctr_idx
) ||
858 riscv_pmu_ctr_monitor_instructions(env
, ctr_idx
)) {
859 counter
->mhpmcounter_prev
= get_ticks(false);
861 if (riscv_cpu_mxl(env
) == MXL_RV32
) {
862 mhpmctr_val
= mhpmctr_val
|
863 ((uint64_t)counter
->mhpmcounterh_val
<< 32);
865 riscv_pmu_setup_timer(env
, mhpmctr_val
, ctr_idx
);
868 /* Other counters can keep incrementing from the given value */
869 counter
->mhpmcounter_prev
= val
;
872 return RISCV_EXCP_NONE
;
875 static int write_mhpmcounterh(CPURISCVState
*env
, int csrno
, target_ulong val
)
877 int ctr_idx
= csrno
- CSR_MCYCLEH
;
878 PMUCTRState
*counter
= &env
->pmu_ctrs
[ctr_idx
];
879 uint64_t mhpmctr_val
= counter
->mhpmcounter_val
;
880 uint64_t mhpmctrh_val
= val
;
882 counter
->mhpmcounterh_val
= val
;
883 mhpmctr_val
= mhpmctr_val
| (mhpmctrh_val
<< 32);
884 if (riscv_pmu_ctr_monitor_cycles(env
, ctr_idx
) ||
885 riscv_pmu_ctr_monitor_instructions(env
, ctr_idx
)) {
886 counter
->mhpmcounterh_prev
= get_ticks(true);
888 riscv_pmu_setup_timer(env
, mhpmctr_val
, ctr_idx
);
891 counter
->mhpmcounterh_prev
= val
;
894 return RISCV_EXCP_NONE
;
897 static RISCVException
riscv_pmu_read_ctr(CPURISCVState
*env
, target_ulong
*val
,
898 bool upper_half
, uint32_t ctr_idx
)
900 PMUCTRState counter
= env
->pmu_ctrs
[ctr_idx
];
901 target_ulong ctr_prev
= upper_half
? counter
.mhpmcounterh_prev
:
902 counter
.mhpmcounter_prev
;
903 target_ulong ctr_val
= upper_half
? counter
.mhpmcounterh_val
:
904 counter
.mhpmcounter_val
;
906 if (get_field(env
->mcountinhibit
, BIT(ctr_idx
))) {
908 * Counter should not increment if inhibit bit is set. We can't really
909 * stop the icount counting. Just return the counter value written by
910 * the supervisor to indicate that counter was not incremented.
912 if (!counter
.started
) {
914 return RISCV_EXCP_NONE
;
916 /* Mark that the counter has been stopped */
917 counter
.started
= false;
922 * The kernel computes the perf delta by subtracting the current value from
923 * the value it initialized previously (ctr_val).
925 if (riscv_pmu_ctr_monitor_cycles(env
, ctr_idx
) ||
926 riscv_pmu_ctr_monitor_instructions(env
, ctr_idx
)) {
927 *val
= get_ticks(upper_half
) - ctr_prev
+ ctr_val
;
932 return RISCV_EXCP_NONE
;
935 static int read_hpmcounter(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
939 if (csrno
>= CSR_MCYCLE
&& csrno
<= CSR_MHPMCOUNTER31
) {
940 ctr_index
= csrno
- CSR_MCYCLE
;
941 } else if (csrno
>= CSR_CYCLE
&& csrno
<= CSR_HPMCOUNTER31
) {
942 ctr_index
= csrno
- CSR_CYCLE
;
944 return RISCV_EXCP_ILLEGAL_INST
;
947 return riscv_pmu_read_ctr(env
, val
, false, ctr_index
);
950 static int read_hpmcounterh(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
954 if (csrno
>= CSR_MCYCLEH
&& csrno
<= CSR_MHPMCOUNTER31H
) {
955 ctr_index
= csrno
- CSR_MCYCLEH
;
956 } else if (csrno
>= CSR_CYCLEH
&& csrno
<= CSR_HPMCOUNTER31H
) {
957 ctr_index
= csrno
- CSR_CYCLEH
;
959 return RISCV_EXCP_ILLEGAL_INST
;
962 return riscv_pmu_read_ctr(env
, val
, true, ctr_index
);
965 static int read_scountovf(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
967 int mhpmevt_start
= CSR_MHPMEVENT3
- CSR_MCOUNTINHIBIT
;
970 target_ulong
*mhpm_evt_val
;
971 uint64_t of_bit_mask
;
973 if (riscv_cpu_mxl(env
) == MXL_RV32
) {
974 mhpm_evt_val
= env
->mhpmeventh_val
;
975 of_bit_mask
= MHPMEVENTH_BIT_OF
;
977 mhpm_evt_val
= env
->mhpmevent_val
;
978 of_bit_mask
= MHPMEVENT_BIT_OF
;
981 for (i
= mhpmevt_start
; i
< RV_MAX_MHPMEVENTS
; i
++) {
982 if ((get_field(env
->mcounteren
, BIT(i
))) &&
983 (mhpm_evt_val
[i
] & of_bit_mask
)) {
988 return RISCV_EXCP_NONE
;
991 static RISCVException
read_time(CPURISCVState
*env
, int csrno
,
994 uint64_t delta
= env
->virt_enabled
? env
->htimedelta
: 0;
996 if (!env
->rdtime_fn
) {
997 return RISCV_EXCP_ILLEGAL_INST
;
1000 *val
= env
->rdtime_fn(env
->rdtime_fn_arg
) + delta
;
1001 return RISCV_EXCP_NONE
;
1004 static RISCVException
read_timeh(CPURISCVState
*env
, int csrno
,
1007 uint64_t delta
= env
->virt_enabled
? env
->htimedelta
: 0;
1009 if (!env
->rdtime_fn
) {
1010 return RISCV_EXCP_ILLEGAL_INST
;
1013 *val
= (env
->rdtime_fn(env
->rdtime_fn_arg
) + delta
) >> 32;
1014 return RISCV_EXCP_NONE
;
1017 static RISCVException
read_vstimecmp(CPURISCVState
*env
, int csrno
,
1020 *val
= env
->vstimecmp
;
1022 return RISCV_EXCP_NONE
;
1025 static RISCVException
read_vstimecmph(CPURISCVState
*env
, int csrno
,
1028 *val
= env
->vstimecmp
>> 32;
1030 return RISCV_EXCP_NONE
;
1033 static RISCVException
write_vstimecmp(CPURISCVState
*env
, int csrno
,
1036 if (riscv_cpu_mxl(env
) == MXL_RV32
) {
1037 env
->vstimecmp
= deposit64(env
->vstimecmp
, 0, 32, (uint64_t)val
);
1039 env
->vstimecmp
= val
;
1042 riscv_timer_write_timecmp(env
, env
->vstimer
, env
->vstimecmp
,
1043 env
->htimedelta
, MIP_VSTIP
);
1045 return RISCV_EXCP_NONE
;
1048 static RISCVException
write_vstimecmph(CPURISCVState
*env
, int csrno
,
1051 env
->vstimecmp
= deposit64(env
->vstimecmp
, 32, 32, (uint64_t)val
);
1052 riscv_timer_write_timecmp(env
, env
->vstimer
, env
->vstimecmp
,
1053 env
->htimedelta
, MIP_VSTIP
);
1055 return RISCV_EXCP_NONE
;
1058 static RISCVException
read_stimecmp(CPURISCVState
*env
, int csrno
,
1061 if (env
->virt_enabled
) {
1062 *val
= env
->vstimecmp
;
1064 *val
= env
->stimecmp
;
1067 return RISCV_EXCP_NONE
;
1070 static RISCVException
read_stimecmph(CPURISCVState
*env
, int csrno
,
1073 if (env
->virt_enabled
) {
1074 *val
= env
->vstimecmp
>> 32;
1076 *val
= env
->stimecmp
>> 32;
1079 return RISCV_EXCP_NONE
;
1082 static RISCVException
write_stimecmp(CPURISCVState
*env
, int csrno
,
1085 if (env
->virt_enabled
) {
1086 if (env
->hvictl
& HVICTL_VTI
) {
1087 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
1089 return write_vstimecmp(env
, csrno
, val
);
1092 if (riscv_cpu_mxl(env
) == MXL_RV32
) {
1093 env
->stimecmp
= deposit64(env
->stimecmp
, 0, 32, (uint64_t)val
);
1095 env
->stimecmp
= val
;
1098 riscv_timer_write_timecmp(env
, env
->stimer
, env
->stimecmp
, 0, MIP_STIP
);
1100 return RISCV_EXCP_NONE
;
1103 static RISCVException
write_stimecmph(CPURISCVState
*env
, int csrno
,
1106 if (env
->virt_enabled
) {
1107 if (env
->hvictl
& HVICTL_VTI
) {
1108 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
1110 return write_vstimecmph(env
, csrno
, val
);
1113 env
->stimecmp
= deposit64(env
->stimecmp
, 32, 32, (uint64_t)val
);
1114 riscv_timer_write_timecmp(env
, env
->stimer
, env
->stimecmp
, 0, MIP_STIP
);
1116 return RISCV_EXCP_NONE
;
1119 /* Machine constants */
1121 #define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
1122 #define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP | \
1124 #define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
1125 #define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
1127 #define VSTOPI_NUM_SRCS 5
1129 static const uint64_t delegable_ints
= S_MODE_INTERRUPTS
|
1131 static const uint64_t vs_delegable_ints
= VS_MODE_INTERRUPTS
;
1132 static const uint64_t all_ints
= M_MODE_INTERRUPTS
| S_MODE_INTERRUPTS
|
1134 #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
1135 (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
1136 (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
1137 (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
1138 (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
1139 (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
1140 (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
1141 (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
1142 (1ULL << (RISCV_EXCP_U_ECALL)) | \
1143 (1ULL << (RISCV_EXCP_S_ECALL)) | \
1144 (1ULL << (RISCV_EXCP_VS_ECALL)) | \
1145 (1ULL << (RISCV_EXCP_M_ECALL)) | \
1146 (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
1147 (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
1148 (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
1149 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
1150 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
1151 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
1152 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
1153 static const target_ulong vs_delegable_excps
= DELEGABLE_EXCPS
&
1154 ~((1ULL << (RISCV_EXCP_S_ECALL
)) |
1155 (1ULL << (RISCV_EXCP_VS_ECALL
)) |
1156 (1ULL << (RISCV_EXCP_M_ECALL
)) |
1157 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT
)) |
1158 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT
)) |
1159 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT
)) |
1160 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT
)));
1161 static const target_ulong sstatus_v1_10_mask
= SSTATUS_SIE
| SSTATUS_SPIE
|
1162 SSTATUS_UIE
| SSTATUS_UPIE
| SSTATUS_SPP
| SSTATUS_FS
| SSTATUS_XS
|
1163 SSTATUS_SUM
| SSTATUS_MXR
| SSTATUS_VS
;
1164 static const target_ulong sip_writable_mask
= SIP_SSIP
| MIP_USIP
| MIP_UEIP
|
1166 static const target_ulong hip_writable_mask
= MIP_VSSIP
;
1167 static const target_ulong hvip_writable_mask
= MIP_VSSIP
| MIP_VSTIP
|
1169 static const target_ulong vsip_writable_mask
= MIP_VSSIP
;
1171 const bool valid_vm_1_10_32
[16] = {
1172 [VM_1_10_MBARE
] = true,
1173 [VM_1_10_SV32
] = true
1176 const bool valid_vm_1_10_64
[16] = {
1177 [VM_1_10_MBARE
] = true,
1178 [VM_1_10_SV39
] = true,
1179 [VM_1_10_SV48
] = true,
1180 [VM_1_10_SV57
] = true
1183 /* Machine Information Registers */
1184 static RISCVException
read_zero(CPURISCVState
*env
, int csrno
,
1188 return RISCV_EXCP_NONE
;
1191 static RISCVException
write_ignore(CPURISCVState
*env
, int csrno
,
1194 return RISCV_EXCP_NONE
;
1197 static RISCVException
read_mvendorid(CPURISCVState
*env
, int csrno
,
1200 *val
= riscv_cpu_cfg(env
)->mvendorid
;
1201 return RISCV_EXCP_NONE
;
1204 static RISCVException
read_marchid(CPURISCVState
*env
, int csrno
,
1207 *val
= riscv_cpu_cfg(env
)->marchid
;
1208 return RISCV_EXCP_NONE
;
1211 static RISCVException
read_mimpid(CPURISCVState
*env
, int csrno
,
1214 *val
= riscv_cpu_cfg(env
)->mimpid
;
1215 return RISCV_EXCP_NONE
;
1218 static RISCVException
read_mhartid(CPURISCVState
*env
, int csrno
,
1221 *val
= env
->mhartid
;
1222 return RISCV_EXCP_NONE
;
1225 /* Machine Trap Setup */
1227 /* We do not store SD explicitly, only compute it on demand. */
1228 static uint64_t add_status_sd(RISCVMXL xl
, uint64_t status
)
1230 if ((status
& MSTATUS_FS
) == MSTATUS_FS
||
1231 (status
& MSTATUS_VS
) == MSTATUS_VS
||
1232 (status
& MSTATUS_XS
) == MSTATUS_XS
) {
1235 return status
| MSTATUS32_SD
;
1237 return status
| MSTATUS64_SD
;
1239 return MSTATUSH128_SD
;
1241 g_assert_not_reached();
1247 static RISCVException
read_mstatus(CPURISCVState
*env
, int csrno
,
1250 *val
= add_status_sd(riscv_cpu_mxl(env
), env
->mstatus
);
1251 return RISCV_EXCP_NONE
;
1254 static bool validate_vm(CPURISCVState
*env
, target_ulong vm
)
1256 return (vm
& 0xf) <=
1257 satp_mode_max_from_map(riscv_cpu_cfg(env
)->satp_mode
.map
);
1260 static target_ulong
legalize_mpp(CPURISCVState
*env
, target_ulong old_mpp
,
1264 target_ulong new_mpp
= get_field(val
, MSTATUS_MPP
);
1271 valid
= riscv_has_ext(env
, RVS
);
1274 valid
= riscv_has_ext(env
, RVU
);
1278 /* Remain field unchanged if new_mpp value is invalid */
1280 val
= set_field(val
, MSTATUS_MPP
, old_mpp
);
1286 static RISCVException
write_mstatus(CPURISCVState
*env
, int csrno
,
1289 uint64_t mstatus
= env
->mstatus
;
1291 RISCVMXL xl
= riscv_cpu_mxl(env
);
1294 * MPP field have been made WARL since priv version 1.11. However,
1295 * legalization for it will not break any software running on 1.10.
1297 val
= legalize_mpp(env
, get_field(mstatus
, MSTATUS_MPP
), val
);
1299 /* flush tlb on mstatus fields that affect VM */
1300 if ((val
^ mstatus
) & MSTATUS_MXR
) {
1301 tlb_flush(env_cpu(env
));
1303 mask
= MSTATUS_SIE
| MSTATUS_SPIE
| MSTATUS_MIE
| MSTATUS_MPIE
|
1304 MSTATUS_SPP
| MSTATUS_MPRV
| MSTATUS_SUM
|
1305 MSTATUS_MPP
| MSTATUS_MXR
| MSTATUS_TVM
| MSTATUS_TSR
|
1306 MSTATUS_TW
| MSTATUS_VS
;
1308 if (riscv_has_ext(env
, RVF
)) {
1312 if (xl
!= MXL_RV32
|| env
->debugger
) {
1313 if (riscv_has_ext(env
, RVH
)) {
1314 mask
|= MSTATUS_MPV
| MSTATUS_GVA
;
1316 if ((val
& MSTATUS64_UXL
) != 0) {
1317 mask
|= MSTATUS64_UXL
;
1321 mstatus
= (mstatus
& ~mask
) | (val
& mask
);
1323 env
->mstatus
= mstatus
;
1326 * Except in debug mode, UXL/SXL can only be modified by higher
1327 * privilege mode. So xl will not be changed in normal mode.
1329 if (env
->debugger
) {
1330 env
->xl
= cpu_recompute_xl(env
);
1333 riscv_cpu_update_mask(env
);
1334 return RISCV_EXCP_NONE
;
1337 static RISCVException
read_mstatush(CPURISCVState
*env
, int csrno
,
1340 *val
= env
->mstatus
>> 32;
1341 return RISCV_EXCP_NONE
;
1344 static RISCVException
write_mstatush(CPURISCVState
*env
, int csrno
,
1347 uint64_t valh
= (uint64_t)val
<< 32;
1348 uint64_t mask
= riscv_has_ext(env
, RVH
) ? MSTATUS_MPV
| MSTATUS_GVA
: 0;
1350 env
->mstatus
= (env
->mstatus
& ~mask
) | (valh
& mask
);
1352 return RISCV_EXCP_NONE
;
1355 static RISCVException
read_mstatus_i128(CPURISCVState
*env
, int csrno
,
1358 *val
= int128_make128(env
->mstatus
, add_status_sd(MXL_RV128
,
1360 return RISCV_EXCP_NONE
;
1363 static RISCVException
read_misa_i128(CPURISCVState
*env
, int csrno
,
1366 *val
= int128_make128(env
->misa_ext
, (uint64_t)MXL_RV128
<< 62);
1367 return RISCV_EXCP_NONE
;
1370 static RISCVException
read_misa(CPURISCVState
*env
, int csrno
,
1375 switch (env
->misa_mxl
) {
1377 misa
= (target_ulong
)MXL_RV32
<< 30;
1379 #ifdef TARGET_RISCV64
1381 misa
= (target_ulong
)MXL_RV64
<< 62;
1385 g_assert_not_reached();
1388 *val
= misa
| env
->misa_ext
;
1389 return RISCV_EXCP_NONE
;
1392 static RISCVException
write_misa(CPURISCVState
*env
, int csrno
,
1395 RISCVCPU
*cpu
= env_archcpu(env
);
1396 uint32_t orig_misa_ext
= env
->misa_ext
;
1397 Error
*local_err
= NULL
;
1399 if (!riscv_cpu_cfg(env
)->misa_w
) {
1400 /* drop write to misa */
1401 return RISCV_EXCP_NONE
;
1404 /* Mask extensions that are not supported by this hart */
1405 val
&= env
->misa_ext_mask
;
1408 * Suppress 'C' if next instruction is not aligned
1409 * TODO: this should check next_pc
1411 if ((val
& RVC
) && (GETPC() & ~3) != 0) {
1415 /* Disable RVG if any of its dependencies are disabled */
1416 if (!(val
& RVI
&& val
& RVM
&& val
& RVA
&&
1417 val
& RVF
&& val
& RVD
)) {
1421 /* If nothing changed, do nothing. */
1422 if (val
== env
->misa_ext
) {
1423 return RISCV_EXCP_NONE
;
1426 env
->misa_ext
= val
;
1427 riscv_cpu_validate_set_extensions(cpu
, &local_err
);
1428 if (local_err
!= NULL
) {
1429 /* Rollback on validation error */
1430 qemu_log_mask(LOG_GUEST_ERROR
, "Unable to write MISA ext value "
1431 "0x%x, keeping existing MISA ext 0x%x\n",
1432 env
->misa_ext
, orig_misa_ext
);
1434 env
->misa_ext
= orig_misa_ext
;
1436 return RISCV_EXCP_NONE
;
1439 if (!(env
->misa_ext
& RVF
)) {
1440 env
->mstatus
&= ~MSTATUS_FS
;
1443 /* flush translation cache */
1444 tb_flush(env_cpu(env
));
1445 env
->xl
= riscv_cpu_mxl(env
);
1446 return RISCV_EXCP_NONE
;
1449 static RISCVException
read_medeleg(CPURISCVState
*env
, int csrno
,
1452 *val
= env
->medeleg
;
1453 return RISCV_EXCP_NONE
;
1456 static RISCVException
write_medeleg(CPURISCVState
*env
, int csrno
,
1459 env
->medeleg
= (env
->medeleg
& ~DELEGABLE_EXCPS
) | (val
& DELEGABLE_EXCPS
);
1460 return RISCV_EXCP_NONE
;
1463 static RISCVException
rmw_mideleg64(CPURISCVState
*env
, int csrno
,
1465 uint64_t new_val
, uint64_t wr_mask
)
1467 uint64_t mask
= wr_mask
& delegable_ints
;
1470 *ret_val
= env
->mideleg
;
1473 env
->mideleg
= (env
->mideleg
& ~mask
) | (new_val
& mask
);
1475 if (riscv_has_ext(env
, RVH
)) {
1476 env
->mideleg
|= HS_MODE_INTERRUPTS
;
1479 return RISCV_EXCP_NONE
;
1482 static RISCVException
rmw_mideleg(CPURISCVState
*env
, int csrno
,
1483 target_ulong
*ret_val
,
1484 target_ulong new_val
, target_ulong wr_mask
)
1489 ret
= rmw_mideleg64(env
, csrno
, &rval
, new_val
, wr_mask
);
1497 static RISCVException
rmw_midelegh(CPURISCVState
*env
, int csrno
,
1498 target_ulong
*ret_val
,
1499 target_ulong new_val
,
1500 target_ulong wr_mask
)
1505 ret
= rmw_mideleg64(env
, csrno
, &rval
,
1506 ((uint64_t)new_val
) << 32, ((uint64_t)wr_mask
) << 32);
1508 *ret_val
= rval
>> 32;
1514 static RISCVException
rmw_mie64(CPURISCVState
*env
, int csrno
,
1516 uint64_t new_val
, uint64_t wr_mask
)
1518 uint64_t mask
= wr_mask
& all_ints
;
1521 *ret_val
= env
->mie
;
1524 env
->mie
= (env
->mie
& ~mask
) | (new_val
& mask
);
1526 if (!riscv_has_ext(env
, RVH
)) {
1527 env
->mie
&= ~((uint64_t)MIP_SGEIP
);
1530 return RISCV_EXCP_NONE
;
1533 static RISCVException
rmw_mie(CPURISCVState
*env
, int csrno
,
1534 target_ulong
*ret_val
,
1535 target_ulong new_val
, target_ulong wr_mask
)
1540 ret
= rmw_mie64(env
, csrno
, &rval
, new_val
, wr_mask
);
1548 static RISCVException
rmw_mieh(CPURISCVState
*env
, int csrno
,
1549 target_ulong
*ret_val
,
1550 target_ulong new_val
, target_ulong wr_mask
)
1555 ret
= rmw_mie64(env
, csrno
, &rval
,
1556 ((uint64_t)new_val
) << 32, ((uint64_t)wr_mask
) << 32);
1558 *ret_val
= rval
>> 32;
1564 static int read_mtopi(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
1569 irq
= riscv_cpu_mirq_pending(env
);
1570 if (irq
<= 0 || irq
> 63) {
1573 iprio
= env
->miprio
[irq
];
1575 if (riscv_cpu_default_priority(irq
) > IPRIO_DEFAULT_M
) {
1576 iprio
= IPRIO_MMAXIPRIO
;
1579 *val
= (irq
& TOPI_IID_MASK
) << TOPI_IID_SHIFT
;
1583 return RISCV_EXCP_NONE
;
1586 static int aia_xlate_vs_csrno(CPURISCVState
*env
, int csrno
)
1588 if (!env
->virt_enabled
) {
1594 return CSR_VSISELECT
;
1604 static int rmw_xiselect(CPURISCVState
*env
, int csrno
, target_ulong
*val
,
1605 target_ulong new_val
, target_ulong wr_mask
)
1607 target_ulong
*iselect
;
1609 /* Translate CSR number for VS-mode */
1610 csrno
= aia_xlate_vs_csrno(env
, csrno
);
1612 /* Find the iselect CSR based on CSR number */
1615 iselect
= &env
->miselect
;
1618 iselect
= &env
->siselect
;
1621 iselect
= &env
->vsiselect
;
1624 return RISCV_EXCP_ILLEGAL_INST
;
1631 wr_mask
&= ISELECT_MASK
;
1633 *iselect
= (*iselect
& ~wr_mask
) | (new_val
& wr_mask
);
1636 return RISCV_EXCP_NONE
;
1639 static int rmw_iprio(target_ulong xlen
,
1640 target_ulong iselect
, uint8_t *iprio
,
1641 target_ulong
*val
, target_ulong new_val
,
1642 target_ulong wr_mask
, int ext_irq_no
)
1645 target_ulong old_val
;
1647 if (iselect
< ISELECT_IPRIO0
|| ISELECT_IPRIO15
< iselect
) {
1650 if (xlen
!= 32 && iselect
& 0x1) {
1654 nirqs
= 4 * (xlen
/ 32);
1655 firq
= ((iselect
- ISELECT_IPRIO0
) / (xlen
/ 32)) * (nirqs
);
1658 for (i
= 0; i
< nirqs
; i
++) {
1659 old_val
|= ((target_ulong
)iprio
[firq
+ i
]) << (IPRIO_IRQ_BITS
* i
);
1667 new_val
= (old_val
& ~wr_mask
) | (new_val
& wr_mask
);
1668 for (i
= 0; i
< nirqs
; i
++) {
1670 * M-level and S-level external IRQ priority always read-only
1671 * zero. This means default priority order is always preferred
1672 * for M-level and S-level external IRQs.
1674 if ((firq
+ i
) == ext_irq_no
) {
1677 iprio
[firq
+ i
] = (new_val
>> (IPRIO_IRQ_BITS
* i
)) & 0xff;
1684 static int rmw_xireg(CPURISCVState
*env
, int csrno
, target_ulong
*val
,
1685 target_ulong new_val
, target_ulong wr_mask
)
1687 bool virt
, isel_reserved
;
1690 target_ulong priv
, isel
, vgein
;
1692 /* Translate CSR number for VS-mode */
1693 csrno
= aia_xlate_vs_csrno(env
, csrno
);
1695 /* Decode register details from CSR number */
1697 isel_reserved
= false;
1700 iprio
= env
->miprio
;
1701 isel
= env
->miselect
;
1705 iprio
= env
->siprio
;
1706 isel
= env
->siselect
;
1710 iprio
= env
->hviprio
;
1711 isel
= env
->vsiselect
;
1719 /* Find the selected guest interrupt file */
1720 vgein
= (virt
) ? get_field(env
->hstatus
, HSTATUS_VGEIN
) : 0;
1722 if (ISELECT_IPRIO0
<= isel
&& isel
<= ISELECT_IPRIO15
) {
1723 /* Local interrupt priority registers not available for VS-mode */
1725 ret
= rmw_iprio(riscv_cpu_mxl_bits(env
),
1726 isel
, iprio
, val
, new_val
, wr_mask
,
1727 (priv
== PRV_M
) ? IRQ_M_EXT
: IRQ_S_EXT
);
1729 } else if (ISELECT_IMSIC_FIRST
<= isel
&& isel
<= ISELECT_IMSIC_LAST
) {
1730 /* IMSIC registers only available when machine implements it. */
1731 if (env
->aia_ireg_rmw_fn
[priv
]) {
1732 /* Selected guest interrupt file should not be zero */
1733 if (virt
&& (!vgein
|| env
->geilen
< vgein
)) {
1736 /* Call machine specific IMSIC register emulation */
1737 ret
= env
->aia_ireg_rmw_fn
[priv
](env
->aia_ireg_rmw_fn_arg
[priv
],
1738 AIA_MAKE_IREG(isel
, priv
, virt
, vgein
,
1739 riscv_cpu_mxl_bits(env
)),
1740 val
, new_val
, wr_mask
);
1743 isel_reserved
= true;
1748 return (env
->virt_enabled
&& virt
&& !isel_reserved
) ?
1749 RISCV_EXCP_VIRT_INSTRUCTION_FAULT
: RISCV_EXCP_ILLEGAL_INST
;
1751 return RISCV_EXCP_NONE
;
1754 static int rmw_xtopei(CPURISCVState
*env
, int csrno
, target_ulong
*val
,
1755 target_ulong new_val
, target_ulong wr_mask
)
1759 target_ulong priv
, vgein
;
1761 /* Translate CSR number for VS-mode */
1762 csrno
= aia_xlate_vs_csrno(env
, csrno
);
1764 /* Decode register details from CSR number */
1781 /* IMSIC CSRs only available when machine implements IMSIC. */
1782 if (!env
->aia_ireg_rmw_fn
[priv
]) {
1786 /* Find the selected guest interrupt file */
1787 vgein
= (virt
) ? get_field(env
->hstatus
, HSTATUS_VGEIN
) : 0;
1789 /* Selected guest interrupt file should be valid */
1790 if (virt
&& (!vgein
|| env
->geilen
< vgein
)) {
1794 /* Call machine specific IMSIC register emulation for TOPEI */
1795 ret
= env
->aia_ireg_rmw_fn
[priv
](env
->aia_ireg_rmw_fn_arg
[priv
],
1796 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI
, priv
, virt
, vgein
,
1797 riscv_cpu_mxl_bits(env
)),
1798 val
, new_val
, wr_mask
);
1802 return (env
->virt_enabled
&& virt
) ?
1803 RISCV_EXCP_VIRT_INSTRUCTION_FAULT
: RISCV_EXCP_ILLEGAL_INST
;
1805 return RISCV_EXCP_NONE
;
1808 static RISCVException
read_mtvec(CPURISCVState
*env
, int csrno
,
1812 return RISCV_EXCP_NONE
;
1815 static RISCVException
write_mtvec(CPURISCVState
*env
, int csrno
,
1818 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
1819 if ((val
& 3) < 2) {
1822 qemu_log_mask(LOG_UNIMP
, "CSR_MTVEC: reserved mode not supported\n");
1824 return RISCV_EXCP_NONE
;
1827 static RISCVException
read_mcountinhibit(CPURISCVState
*env
, int csrno
,
1830 *val
= env
->mcountinhibit
;
1831 return RISCV_EXCP_NONE
;
1834 static RISCVException
write_mcountinhibit(CPURISCVState
*env
, int csrno
,
1838 PMUCTRState
*counter
;
1839 RISCVCPU
*cpu
= env_archcpu(env
);
1841 /* WARL register - disable unavailable counters; TM bit is always 0 */
1842 env
->mcountinhibit
=
1843 val
& (cpu
->pmu_avail_ctrs
| COUNTEREN_CY
| COUNTEREN_IR
);
1845 /* Check if any other counter is also monitoring cycles/instructions */
1846 for (cidx
= 0; cidx
< RV_MAX_MHPMCOUNTERS
; cidx
++) {
1847 if (!get_field(env
->mcountinhibit
, BIT(cidx
))) {
1848 counter
= &env
->pmu_ctrs
[cidx
];
1849 counter
->started
= true;
1853 return RISCV_EXCP_NONE
;
1856 static RISCVException
read_mcounteren(CPURISCVState
*env
, int csrno
,
1859 *val
= env
->mcounteren
;
1860 return RISCV_EXCP_NONE
;
1863 static RISCVException
write_mcounteren(CPURISCVState
*env
, int csrno
,
1866 RISCVCPU
*cpu
= env_archcpu(env
);
1868 /* WARL register - disable unavailable counters */
1869 env
->mcounteren
= val
& (cpu
->pmu_avail_ctrs
| COUNTEREN_CY
| COUNTEREN_TM
|
1871 return RISCV_EXCP_NONE
;
1874 /* Machine Trap Handling */
1875 static RISCVException
read_mscratch_i128(CPURISCVState
*env
, int csrno
,
1878 *val
= int128_make128(env
->mscratch
, env
->mscratchh
);
1879 return RISCV_EXCP_NONE
;
1882 static RISCVException
write_mscratch_i128(CPURISCVState
*env
, int csrno
,
1885 env
->mscratch
= int128_getlo(val
);
1886 env
->mscratchh
= int128_gethi(val
);
1887 return RISCV_EXCP_NONE
;
1890 static RISCVException
read_mscratch(CPURISCVState
*env
, int csrno
,
1893 *val
= env
->mscratch
;
1894 return RISCV_EXCP_NONE
;
1897 static RISCVException
write_mscratch(CPURISCVState
*env
, int csrno
,
1900 env
->mscratch
= val
;
1901 return RISCV_EXCP_NONE
;
1904 static RISCVException
read_mepc(CPURISCVState
*env
, int csrno
,
1908 return RISCV_EXCP_NONE
;
1911 static RISCVException
write_mepc(CPURISCVState
*env
, int csrno
,
1915 return RISCV_EXCP_NONE
;
1918 static RISCVException
read_mcause(CPURISCVState
*env
, int csrno
,
1922 return RISCV_EXCP_NONE
;
1925 static RISCVException
write_mcause(CPURISCVState
*env
, int csrno
,
1929 return RISCV_EXCP_NONE
;
1932 static RISCVException
read_mtval(CPURISCVState
*env
, int csrno
,
1936 return RISCV_EXCP_NONE
;
1939 static RISCVException
write_mtval(CPURISCVState
*env
, int csrno
,
1943 return RISCV_EXCP_NONE
;
1946 /* Execution environment configuration setup */
1947 static RISCVException
read_menvcfg(CPURISCVState
*env
, int csrno
,
1950 *val
= env
->menvcfg
;
1951 return RISCV_EXCP_NONE
;
1954 static RISCVException
write_menvcfg(CPURISCVState
*env
, int csrno
,
1957 const RISCVCPUConfig
*cfg
= riscv_cpu_cfg(env
);
1958 uint64_t mask
= MENVCFG_FIOM
| MENVCFG_CBIE
| MENVCFG_CBCFE
| MENVCFG_CBZE
;
1960 if (riscv_cpu_mxl(env
) == MXL_RV64
) {
1961 mask
|= (cfg
->ext_svpbmt
? MENVCFG_PBMTE
: 0) |
1962 (cfg
->ext_sstc
? MENVCFG_STCE
: 0) |
1963 (cfg
->ext_svadu
? MENVCFG_ADUE
: 0);
1965 env
->menvcfg
= (env
->menvcfg
& ~mask
) | (val
& mask
);
1967 return RISCV_EXCP_NONE
;
1970 static RISCVException
read_menvcfgh(CPURISCVState
*env
, int csrno
,
1973 *val
= env
->menvcfg
>> 32;
1974 return RISCV_EXCP_NONE
;
1977 static RISCVException
write_menvcfgh(CPURISCVState
*env
, int csrno
,
1980 const RISCVCPUConfig
*cfg
= riscv_cpu_cfg(env
);
1981 uint64_t mask
= (cfg
->ext_svpbmt
? MENVCFG_PBMTE
: 0) |
1982 (cfg
->ext_sstc
? MENVCFG_STCE
: 0) |
1983 (cfg
->ext_svadu
? MENVCFG_ADUE
: 0);
1984 uint64_t valh
= (uint64_t)val
<< 32;
1986 env
->menvcfg
= (env
->menvcfg
& ~mask
) | (valh
& mask
);
1988 return RISCV_EXCP_NONE
;
1991 static RISCVException
read_senvcfg(CPURISCVState
*env
, int csrno
,
1996 ret
= smstateen_acc_ok(env
, 0, SMSTATEEN0_HSENVCFG
);
1997 if (ret
!= RISCV_EXCP_NONE
) {
2001 *val
= env
->senvcfg
;
2002 return RISCV_EXCP_NONE
;
2005 static RISCVException
write_senvcfg(CPURISCVState
*env
, int csrno
,
2008 uint64_t mask
= SENVCFG_FIOM
| SENVCFG_CBIE
| SENVCFG_CBCFE
| SENVCFG_CBZE
;
2011 ret
= smstateen_acc_ok(env
, 0, SMSTATEEN0_HSENVCFG
);
2012 if (ret
!= RISCV_EXCP_NONE
) {
2016 env
->senvcfg
= (env
->senvcfg
& ~mask
) | (val
& mask
);
2017 return RISCV_EXCP_NONE
;
2020 static RISCVException
read_henvcfg(CPURISCVState
*env
, int csrno
,
2025 ret
= smstateen_acc_ok(env
, 0, SMSTATEEN0_HSENVCFG
);
2026 if (ret
!= RISCV_EXCP_NONE
) {
2031 * henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
2032 * henvcfg.stce is read_only 0 when menvcfg.stce = 0
2033 * henvcfg.hade is read_only 0 when menvcfg.hade = 0
2035 *val
= env
->henvcfg
& (~(HENVCFG_PBMTE
| HENVCFG_STCE
| HENVCFG_ADUE
) |
2037 return RISCV_EXCP_NONE
;
2040 static RISCVException
write_henvcfg(CPURISCVState
*env
, int csrno
,
2043 uint64_t mask
= HENVCFG_FIOM
| HENVCFG_CBIE
| HENVCFG_CBCFE
| HENVCFG_CBZE
;
2046 ret
= smstateen_acc_ok(env
, 0, SMSTATEEN0_HSENVCFG
);
2047 if (ret
!= RISCV_EXCP_NONE
) {
2051 if (riscv_cpu_mxl(env
) == MXL_RV64
) {
2052 mask
|= env
->menvcfg
& (HENVCFG_PBMTE
| HENVCFG_STCE
| HENVCFG_ADUE
);
2055 env
->henvcfg
= (env
->henvcfg
& ~mask
) | (val
& mask
);
2057 return RISCV_EXCP_NONE
;
2060 static RISCVException
read_henvcfgh(CPURISCVState
*env
, int csrno
,
2065 ret
= smstateen_acc_ok(env
, 0, SMSTATEEN0_HSENVCFG
);
2066 if (ret
!= RISCV_EXCP_NONE
) {
2070 *val
= (env
->henvcfg
& (~(HENVCFG_PBMTE
| HENVCFG_STCE
| HENVCFG_ADUE
) |
2071 env
->menvcfg
)) >> 32;
2072 return RISCV_EXCP_NONE
;
2075 static RISCVException
write_henvcfgh(CPURISCVState
*env
, int csrno
,
2078 uint64_t mask
= env
->menvcfg
& (HENVCFG_PBMTE
| HENVCFG_STCE
|
2080 uint64_t valh
= (uint64_t)val
<< 32;
2083 ret
= smstateen_acc_ok(env
, 0, SMSTATEEN0_HSENVCFG
);
2084 if (ret
!= RISCV_EXCP_NONE
) {
2088 env
->henvcfg
= (env
->henvcfg
& ~mask
) | (valh
& mask
);
2089 return RISCV_EXCP_NONE
;
2092 static RISCVException
read_mstateen(CPURISCVState
*env
, int csrno
,
2095 *val
= env
->mstateen
[csrno
- CSR_MSTATEEN0
];
2097 return RISCV_EXCP_NONE
;
2100 static RISCVException
write_mstateen(CPURISCVState
*env
, int csrno
,
2101 uint64_t wr_mask
, target_ulong new_val
)
2105 reg
= &env
->mstateen
[csrno
- CSR_MSTATEEN0
];
2106 *reg
= (*reg
& ~wr_mask
) | (new_val
& wr_mask
);
2108 return RISCV_EXCP_NONE
;
2111 static RISCVException
write_mstateen0(CPURISCVState
*env
, int csrno
,
2112 target_ulong new_val
)
2114 uint64_t wr_mask
= SMSTATEEN_STATEEN
| SMSTATEEN0_HSENVCFG
;
2115 if (!riscv_has_ext(env
, RVF
)) {
2116 wr_mask
|= SMSTATEEN0_FCSR
;
2119 return write_mstateen(env
, csrno
, wr_mask
, new_val
);
2122 static RISCVException
write_mstateen_1_3(CPURISCVState
*env
, int csrno
,
2123 target_ulong new_val
)
2125 return write_mstateen(env
, csrno
, SMSTATEEN_STATEEN
, new_val
);
2128 static RISCVException
read_mstateenh(CPURISCVState
*env
, int csrno
,
2131 *val
= env
->mstateen
[csrno
- CSR_MSTATEEN0H
] >> 32;
2133 return RISCV_EXCP_NONE
;
2136 static RISCVException
write_mstateenh(CPURISCVState
*env
, int csrno
,
2137 uint64_t wr_mask
, target_ulong new_val
)
2141 reg
= &env
->mstateen
[csrno
- CSR_MSTATEEN0H
];
2142 val
= (uint64_t)new_val
<< 32;
2143 val
|= *reg
& 0xFFFFFFFF;
2144 *reg
= (*reg
& ~wr_mask
) | (val
& wr_mask
);
2146 return RISCV_EXCP_NONE
;
2149 static RISCVException
write_mstateen0h(CPURISCVState
*env
, int csrno
,
2150 target_ulong new_val
)
2152 uint64_t wr_mask
= SMSTATEEN_STATEEN
| SMSTATEEN0_HSENVCFG
;
2154 return write_mstateenh(env
, csrno
, wr_mask
, new_val
);
2157 static RISCVException
write_mstateenh_1_3(CPURISCVState
*env
, int csrno
,
2158 target_ulong new_val
)
2160 return write_mstateenh(env
, csrno
, SMSTATEEN_STATEEN
, new_val
);
2163 static RISCVException
read_hstateen(CPURISCVState
*env
, int csrno
,
2166 int index
= csrno
- CSR_HSTATEEN0
;
2168 *val
= env
->hstateen
[index
] & env
->mstateen
[index
];
2170 return RISCV_EXCP_NONE
;
2173 static RISCVException
write_hstateen(CPURISCVState
*env
, int csrno
,
2174 uint64_t mask
, target_ulong new_val
)
2176 int index
= csrno
- CSR_HSTATEEN0
;
2177 uint64_t *reg
, wr_mask
;
2179 reg
= &env
->hstateen
[index
];
2180 wr_mask
= env
->mstateen
[index
] & mask
;
2181 *reg
= (*reg
& ~wr_mask
) | (new_val
& wr_mask
);
2183 return RISCV_EXCP_NONE
;
2186 static RISCVException
write_hstateen0(CPURISCVState
*env
, int csrno
,
2187 target_ulong new_val
)
2189 uint64_t wr_mask
= SMSTATEEN_STATEEN
| SMSTATEEN0_HSENVCFG
;
2191 if (!riscv_has_ext(env
, RVF
)) {
2192 wr_mask
|= SMSTATEEN0_FCSR
;
2195 return write_hstateen(env
, csrno
, wr_mask
, new_val
);
2198 static RISCVException
write_hstateen_1_3(CPURISCVState
*env
, int csrno
,
2199 target_ulong new_val
)
2201 return write_hstateen(env
, csrno
, SMSTATEEN_STATEEN
, new_val
);
2204 static RISCVException
read_hstateenh(CPURISCVState
*env
, int csrno
,
2207 int index
= csrno
- CSR_HSTATEEN0H
;
2209 *val
= (env
->hstateen
[index
] >> 32) & (env
->mstateen
[index
] >> 32);
2211 return RISCV_EXCP_NONE
;
2214 static RISCVException
write_hstateenh(CPURISCVState
*env
, int csrno
,
2215 uint64_t mask
, target_ulong new_val
)
2217 int index
= csrno
- CSR_HSTATEEN0H
;
2218 uint64_t *reg
, wr_mask
, val
;
2220 reg
= &env
->hstateen
[index
];
2221 val
= (uint64_t)new_val
<< 32;
2222 val
|= *reg
& 0xFFFFFFFF;
2223 wr_mask
= env
->mstateen
[index
] & mask
;
2224 *reg
= (*reg
& ~wr_mask
) | (val
& wr_mask
);
2226 return RISCV_EXCP_NONE
;
2229 static RISCVException
write_hstateen0h(CPURISCVState
*env
, int csrno
,
2230 target_ulong new_val
)
2232 uint64_t wr_mask
= SMSTATEEN_STATEEN
| SMSTATEEN0_HSENVCFG
;
2234 return write_hstateenh(env
, csrno
, wr_mask
, new_val
);
2237 static RISCVException
write_hstateenh_1_3(CPURISCVState
*env
, int csrno
,
2238 target_ulong new_val
)
2240 return write_hstateenh(env
, csrno
, SMSTATEEN_STATEEN
, new_val
);
2243 static RISCVException
read_sstateen(CPURISCVState
*env
, int csrno
,
2246 bool virt
= env
->virt_enabled
;
2247 int index
= csrno
- CSR_SSTATEEN0
;
2249 *val
= env
->sstateen
[index
] & env
->mstateen
[index
];
2251 *val
&= env
->hstateen
[index
];
2254 return RISCV_EXCP_NONE
;
2257 static RISCVException
write_sstateen(CPURISCVState
*env
, int csrno
,
2258 uint64_t mask
, target_ulong new_val
)
2260 bool virt
= env
->virt_enabled
;
2261 int index
= csrno
- CSR_SSTATEEN0
;
2265 wr_mask
= env
->mstateen
[index
] & mask
;
2267 wr_mask
&= env
->hstateen
[index
];
2270 reg
= &env
->sstateen
[index
];
2271 *reg
= (*reg
& ~wr_mask
) | (new_val
& wr_mask
);
2273 return RISCV_EXCP_NONE
;
2276 static RISCVException
write_sstateen0(CPURISCVState
*env
, int csrno
,
2277 target_ulong new_val
)
2279 uint64_t wr_mask
= SMSTATEEN_STATEEN
| SMSTATEEN0_HSENVCFG
;
2281 if (!riscv_has_ext(env
, RVF
)) {
2282 wr_mask
|= SMSTATEEN0_FCSR
;
2285 return write_sstateen(env
, csrno
, wr_mask
, new_val
);
2288 static RISCVException
write_sstateen_1_3(CPURISCVState
*env
, int csrno
,
2289 target_ulong new_val
)
2291 return write_sstateen(env
, csrno
, SMSTATEEN_STATEEN
, new_val
);
2294 static RISCVException
rmw_mip64(CPURISCVState
*env
, int csrno
,
2296 uint64_t new_val
, uint64_t wr_mask
)
2298 uint64_t old_mip
, mask
= wr_mask
& delegable_ints
;
2301 if (mask
& MIP_SEIP
) {
2302 env
->software_seip
= new_val
& MIP_SEIP
;
2303 new_val
|= env
->external_seip
* MIP_SEIP
;
2306 if (riscv_cpu_cfg(env
)->ext_sstc
&& (env
->priv
== PRV_M
) &&
2307 get_field(env
->menvcfg
, MENVCFG_STCE
)) {
2308 /* sstc extension forbids STIP & VSTIP to be writeable in mip */
2309 mask
= mask
& ~(MIP_STIP
| MIP_VSTIP
);
2313 old_mip
= riscv_cpu_update_mip(env
, mask
, (new_val
& mask
));
2318 if (csrno
!= CSR_HVIP
) {
2319 gin
= get_field(env
->hstatus
, HSTATUS_VGEIN
);
2320 old_mip
|= (env
->hgeip
& ((target_ulong
)1 << gin
)) ? MIP_VSEIP
: 0;
2321 old_mip
|= env
->vstime_irq
? MIP_VSTIP
: 0;
2328 return RISCV_EXCP_NONE
;
2331 static RISCVException
rmw_mip(CPURISCVState
*env
, int csrno
,
2332 target_ulong
*ret_val
,
2333 target_ulong new_val
, target_ulong wr_mask
)
2338 ret
= rmw_mip64(env
, csrno
, &rval
, new_val
, wr_mask
);
2346 static RISCVException
rmw_miph(CPURISCVState
*env
, int csrno
,
2347 target_ulong
*ret_val
,
2348 target_ulong new_val
, target_ulong wr_mask
)
2353 ret
= rmw_mip64(env
, csrno
, &rval
,
2354 ((uint64_t)new_val
) << 32, ((uint64_t)wr_mask
) << 32);
2356 *ret_val
= rval
>> 32;
2362 /* Supervisor Trap Setup */
2363 static RISCVException
read_sstatus_i128(CPURISCVState
*env
, int csrno
,
2366 uint64_t mask
= sstatus_v1_10_mask
;
2367 uint64_t sstatus
= env
->mstatus
& mask
;
2368 if (env
->xl
!= MXL_RV32
|| env
->debugger
) {
2369 mask
|= SSTATUS64_UXL
;
2372 *val
= int128_make128(sstatus
, add_status_sd(MXL_RV128
, sstatus
));
2373 return RISCV_EXCP_NONE
;
2376 static RISCVException
read_sstatus(CPURISCVState
*env
, int csrno
,
2379 target_ulong mask
= (sstatus_v1_10_mask
);
2380 if (env
->xl
!= MXL_RV32
|| env
->debugger
) {
2381 mask
|= SSTATUS64_UXL
;
2383 /* TODO: Use SXL not MXL. */
2384 *val
= add_status_sd(riscv_cpu_mxl(env
), env
->mstatus
& mask
);
2385 return RISCV_EXCP_NONE
;
2388 static RISCVException
write_sstatus(CPURISCVState
*env
, int csrno
,
2391 target_ulong mask
= (sstatus_v1_10_mask
);
2393 if (env
->xl
!= MXL_RV32
|| env
->debugger
) {
2394 if ((val
& SSTATUS64_UXL
) != 0) {
2395 mask
|= SSTATUS64_UXL
;
2398 target_ulong newval
= (env
->mstatus
& ~mask
) | (val
& mask
);
2399 return write_mstatus(env
, CSR_MSTATUS
, newval
);
2402 static RISCVException
rmw_vsie64(CPURISCVState
*env
, int csrno
,
2404 uint64_t new_val
, uint64_t wr_mask
)
2407 uint64_t rval
, mask
= env
->hideleg
& VS_MODE_INTERRUPTS
;
2409 /* Bring VS-level bits to correct position */
2410 new_val
= (new_val
& (VS_MODE_INTERRUPTS
>> 1)) << 1;
2411 wr_mask
= (wr_mask
& (VS_MODE_INTERRUPTS
>> 1)) << 1;
2413 ret
= rmw_mie64(env
, csrno
, &rval
, new_val
, wr_mask
& mask
);
2415 *ret_val
= (rval
& mask
) >> 1;
2421 static RISCVException
rmw_vsie(CPURISCVState
*env
, int csrno
,
2422 target_ulong
*ret_val
,
2423 target_ulong new_val
, target_ulong wr_mask
)
2428 ret
= rmw_vsie64(env
, csrno
, &rval
, new_val
, wr_mask
);
2436 static RISCVException
rmw_vsieh(CPURISCVState
*env
, int csrno
,
2437 target_ulong
*ret_val
,
2438 target_ulong new_val
, target_ulong wr_mask
)
2443 ret
= rmw_vsie64(env
, csrno
, &rval
,
2444 ((uint64_t)new_val
) << 32, ((uint64_t)wr_mask
) << 32);
2446 *ret_val
= rval
>> 32;
2452 static RISCVException
rmw_sie64(CPURISCVState
*env
, int csrno
,
2454 uint64_t new_val
, uint64_t wr_mask
)
2457 uint64_t mask
= env
->mideleg
& S_MODE_INTERRUPTS
;
2459 if (env
->virt_enabled
) {
2460 if (env
->hvictl
& HVICTL_VTI
) {
2461 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
2463 ret
= rmw_vsie64(env
, CSR_VSIE
, ret_val
, new_val
, wr_mask
);
2465 ret
= rmw_mie64(env
, csrno
, ret_val
, new_val
, wr_mask
& mask
);
2475 static RISCVException
rmw_sie(CPURISCVState
*env
, int csrno
,
2476 target_ulong
*ret_val
,
2477 target_ulong new_val
, target_ulong wr_mask
)
2482 ret
= rmw_sie64(env
, csrno
, &rval
, new_val
, wr_mask
);
2483 if (ret
== RISCV_EXCP_NONE
&& ret_val
) {
2490 static RISCVException
rmw_sieh(CPURISCVState
*env
, int csrno
,
2491 target_ulong
*ret_val
,
2492 target_ulong new_val
, target_ulong wr_mask
)
2497 ret
= rmw_sie64(env
, csrno
, &rval
,
2498 ((uint64_t)new_val
) << 32, ((uint64_t)wr_mask
) << 32);
2500 *ret_val
= rval
>> 32;
2506 static RISCVException
read_stvec(CPURISCVState
*env
, int csrno
,
2510 return RISCV_EXCP_NONE
;
2513 static RISCVException
write_stvec(CPURISCVState
*env
, int csrno
,
2516 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
2517 if ((val
& 3) < 2) {
2520 qemu_log_mask(LOG_UNIMP
, "CSR_STVEC: reserved mode not supported\n");
2522 return RISCV_EXCP_NONE
;
2525 static RISCVException
read_scounteren(CPURISCVState
*env
, int csrno
,
2528 *val
= env
->scounteren
;
2529 return RISCV_EXCP_NONE
;
2532 static RISCVException
write_scounteren(CPURISCVState
*env
, int csrno
,
2535 env
->scounteren
= val
;
2536 return RISCV_EXCP_NONE
;
2539 /* Supervisor Trap Handling */
2540 static RISCVException
read_sscratch_i128(CPURISCVState
*env
, int csrno
,
2543 *val
= int128_make128(env
->sscratch
, env
->sscratchh
);
2544 return RISCV_EXCP_NONE
;
2547 static RISCVException
write_sscratch_i128(CPURISCVState
*env
, int csrno
,
2550 env
->sscratch
= int128_getlo(val
);
2551 env
->sscratchh
= int128_gethi(val
);
2552 return RISCV_EXCP_NONE
;
2555 static RISCVException
read_sscratch(CPURISCVState
*env
, int csrno
,
2558 *val
= env
->sscratch
;
2559 return RISCV_EXCP_NONE
;
2562 static RISCVException
write_sscratch(CPURISCVState
*env
, int csrno
,
2565 env
->sscratch
= val
;
2566 return RISCV_EXCP_NONE
;
2569 static RISCVException
read_sepc(CPURISCVState
*env
, int csrno
,
2573 return RISCV_EXCP_NONE
;
2576 static RISCVException
write_sepc(CPURISCVState
*env
, int csrno
,
2580 return RISCV_EXCP_NONE
;
2583 static RISCVException
read_scause(CPURISCVState
*env
, int csrno
,
2587 return RISCV_EXCP_NONE
;
2590 static RISCVException
write_scause(CPURISCVState
*env
, int csrno
,
2594 return RISCV_EXCP_NONE
;
2597 static RISCVException
read_stval(CPURISCVState
*env
, int csrno
,
2601 return RISCV_EXCP_NONE
;
2604 static RISCVException
write_stval(CPURISCVState
*env
, int csrno
,
2608 return RISCV_EXCP_NONE
;
2611 static RISCVException
rmw_vsip64(CPURISCVState
*env
, int csrno
,
2613 uint64_t new_val
, uint64_t wr_mask
)
2616 uint64_t rval
, mask
= env
->hideleg
& VS_MODE_INTERRUPTS
;
2618 /* Bring VS-level bits to correct position */
2619 new_val
= (new_val
& (VS_MODE_INTERRUPTS
>> 1)) << 1;
2620 wr_mask
= (wr_mask
& (VS_MODE_INTERRUPTS
>> 1)) << 1;
2622 ret
= rmw_mip64(env
, csrno
, &rval
, new_val
,
2623 wr_mask
& mask
& vsip_writable_mask
);
2625 *ret_val
= (rval
& mask
) >> 1;
2631 static RISCVException
rmw_vsip(CPURISCVState
*env
, int csrno
,
2632 target_ulong
*ret_val
,
2633 target_ulong new_val
, target_ulong wr_mask
)
2638 ret
= rmw_vsip64(env
, csrno
, &rval
, new_val
, wr_mask
);
2646 static RISCVException
rmw_vsiph(CPURISCVState
*env
, int csrno
,
2647 target_ulong
*ret_val
,
2648 target_ulong new_val
, target_ulong wr_mask
)
2653 ret
= rmw_vsip64(env
, csrno
, &rval
,
2654 ((uint64_t)new_val
) << 32, ((uint64_t)wr_mask
) << 32);
2656 *ret_val
= rval
>> 32;
2662 static RISCVException
rmw_sip64(CPURISCVState
*env
, int csrno
,
2664 uint64_t new_val
, uint64_t wr_mask
)
2667 uint64_t mask
= env
->mideleg
& sip_writable_mask
;
2669 if (env
->virt_enabled
) {
2670 if (env
->hvictl
& HVICTL_VTI
) {
2671 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
2673 ret
= rmw_vsip64(env
, CSR_VSIP
, ret_val
, new_val
, wr_mask
);
2675 ret
= rmw_mip64(env
, csrno
, ret_val
, new_val
, wr_mask
& mask
);
2679 *ret_val
&= env
->mideleg
& S_MODE_INTERRUPTS
;
2685 static RISCVException
rmw_sip(CPURISCVState
*env
, int csrno
,
2686 target_ulong
*ret_val
,
2687 target_ulong new_val
, target_ulong wr_mask
)
2692 ret
= rmw_sip64(env
, csrno
, &rval
, new_val
, wr_mask
);
2700 static RISCVException
rmw_siph(CPURISCVState
*env
, int csrno
,
2701 target_ulong
*ret_val
,
2702 target_ulong new_val
, target_ulong wr_mask
)
2707 ret
= rmw_sip64(env
, csrno
, &rval
,
2708 ((uint64_t)new_val
) << 32, ((uint64_t)wr_mask
) << 32);
2710 *ret_val
= rval
>> 32;
2716 /* Supervisor Protection and Translation */
2717 static RISCVException
read_satp(CPURISCVState
*env
, int csrno
,
2720 if (!riscv_cpu_cfg(env
)->mmu
) {
2722 return RISCV_EXCP_NONE
;
2725 return RISCV_EXCP_NONE
;
2728 static RISCVException
write_satp(CPURISCVState
*env
, int csrno
,
2734 if (!riscv_cpu_cfg(env
)->mmu
) {
2735 return RISCV_EXCP_NONE
;
2738 if (riscv_cpu_mxl(env
) == MXL_RV32
) {
2739 vm
= validate_vm(env
, get_field(val
, SATP32_MODE
));
2740 mask
= (val
^ env
->satp
) & (SATP32_MODE
| SATP32_ASID
| SATP32_PPN
);
2742 vm
= validate_vm(env
, get_field(val
, SATP64_MODE
));
2743 mask
= (val
^ env
->satp
) & (SATP64_MODE
| SATP64_ASID
| SATP64_PPN
);
2748 * The ISA defines SATP.MODE=Bare as "no translation", but we still
2749 * pass these through QEMU's TLB emulation as it improves
2750 * performance. Flushing the TLB on SATP writes with paging
2751 * enabled avoids leaking those invalid cached mappings.
2753 tlb_flush(env_cpu(env
));
2756 return RISCV_EXCP_NONE
;
2759 static int read_vstopi(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
2763 uint64_t vseip
, vsgein
;
2764 uint32_t iid
, iprio
, hviid
, hviprio
, gein
;
2765 uint32_t s
, scount
= 0, siid
[VSTOPI_NUM_SRCS
], siprio
[VSTOPI_NUM_SRCS
];
2767 gein
= get_field(env
->hstatus
, HSTATUS_VGEIN
);
2768 hviid
= get_field(env
->hvictl
, HVICTL_IID
);
2769 hviprio
= get_field(env
->hvictl
, HVICTL_IPRIO
);
2772 vsgein
= (env
->hgeip
& (1ULL << gein
)) ? MIP_VSEIP
: 0;
2773 vseip
= env
->mie
& (env
->mip
| vsgein
) & MIP_VSEIP
;
2774 if (gein
<= env
->geilen
&& vseip
) {
2775 siid
[scount
] = IRQ_S_EXT
;
2776 siprio
[scount
] = IPRIO_MMAXIPRIO
+ 1;
2777 if (env
->aia_ireg_rmw_fn
[PRV_S
]) {
2779 * Call machine specific IMSIC register emulation for
2782 ret
= env
->aia_ireg_rmw_fn
[PRV_S
](
2783 env
->aia_ireg_rmw_fn_arg
[PRV_S
],
2784 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI
, PRV_S
, true, gein
,
2785 riscv_cpu_mxl_bits(env
)),
2787 if (!ret
&& topei
) {
2788 siprio
[scount
] = topei
& IMSIC_TOPEI_IPRIO_MASK
;
2794 if (hviid
== IRQ_S_EXT
&& hviprio
) {
2795 siid
[scount
] = IRQ_S_EXT
;
2796 siprio
[scount
] = hviprio
;
2801 if (env
->hvictl
& HVICTL_VTI
) {
2802 if (hviid
!= IRQ_S_EXT
) {
2803 siid
[scount
] = hviid
;
2804 siprio
[scount
] = hviprio
;
2808 irq
= riscv_cpu_vsirq_pending(env
);
2809 if (irq
!= IRQ_S_EXT
&& 0 < irq
&& irq
<= 63) {
2811 siprio
[scount
] = env
->hviprio
[irq
];
2818 for (s
= 0; s
< scount
; s
++) {
2819 if (siprio
[s
] < iprio
) {
2826 if (env
->hvictl
& HVICTL_IPRIOM
) {
2827 if (iprio
> IPRIO_MMAXIPRIO
) {
2828 iprio
= IPRIO_MMAXIPRIO
;
2831 if (riscv_cpu_default_priority(iid
) > IPRIO_DEFAULT_S
) {
2832 iprio
= IPRIO_MMAXIPRIO
;
2842 *val
= (iid
& TOPI_IID_MASK
) << TOPI_IID_SHIFT
;
2844 return RISCV_EXCP_NONE
;
2847 static int read_stopi(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
2852 if (env
->virt_enabled
) {
2853 return read_vstopi(env
, CSR_VSTOPI
, val
);
2856 irq
= riscv_cpu_sirq_pending(env
);
2857 if (irq
<= 0 || irq
> 63) {
2860 iprio
= env
->siprio
[irq
];
2862 if (riscv_cpu_default_priority(irq
) > IPRIO_DEFAULT_S
) {
2863 iprio
= IPRIO_MMAXIPRIO
;
2866 *val
= (irq
& TOPI_IID_MASK
) << TOPI_IID_SHIFT
;
2870 return RISCV_EXCP_NONE
;
2873 /* Hypervisor Extensions */
2874 static RISCVException
read_hstatus(CPURISCVState
*env
, int csrno
,
2877 *val
= env
->hstatus
;
2878 if (riscv_cpu_mxl(env
) != MXL_RV32
) {
2879 /* We only support 64-bit VSXL */
2880 *val
= set_field(*val
, HSTATUS_VSXL
, 2);
2882 /* We only support little endian */
2883 *val
= set_field(*val
, HSTATUS_VSBE
, 0);
2884 return RISCV_EXCP_NONE
;
2887 static RISCVException
write_hstatus(CPURISCVState
*env
, int csrno
,
2891 if (riscv_cpu_mxl(env
) != MXL_RV32
&& get_field(val
, HSTATUS_VSXL
) != 2) {
2892 qemu_log_mask(LOG_UNIMP
,
2893 "QEMU does not support mixed HSXLEN options.");
2895 if (get_field(val
, HSTATUS_VSBE
) != 0) {
2896 qemu_log_mask(LOG_UNIMP
, "QEMU does not support big endian guests.");
2898 return RISCV_EXCP_NONE
;
2901 static RISCVException
read_hedeleg(CPURISCVState
*env
, int csrno
,
2904 *val
= env
->hedeleg
;
2905 return RISCV_EXCP_NONE
;
2908 static RISCVException
write_hedeleg(CPURISCVState
*env
, int csrno
,
2911 env
->hedeleg
= val
& vs_delegable_excps
;
2912 return RISCV_EXCP_NONE
;
2915 static RISCVException
rmw_hideleg64(CPURISCVState
*env
, int csrno
,
2917 uint64_t new_val
, uint64_t wr_mask
)
2919 uint64_t mask
= wr_mask
& vs_delegable_ints
;
2922 *ret_val
= env
->hideleg
& vs_delegable_ints
;
2925 env
->hideleg
= (env
->hideleg
& ~mask
) | (new_val
& mask
);
2926 return RISCV_EXCP_NONE
;
2929 static RISCVException
rmw_hideleg(CPURISCVState
*env
, int csrno
,
2930 target_ulong
*ret_val
,
2931 target_ulong new_val
, target_ulong wr_mask
)
2936 ret
= rmw_hideleg64(env
, csrno
, &rval
, new_val
, wr_mask
);
2944 static RISCVException
rmw_hidelegh(CPURISCVState
*env
, int csrno
,
2945 target_ulong
*ret_val
,
2946 target_ulong new_val
, target_ulong wr_mask
)
2951 ret
= rmw_hideleg64(env
, csrno
, &rval
,
2952 ((uint64_t)new_val
) << 32, ((uint64_t)wr_mask
) << 32);
2954 *ret_val
= rval
>> 32;
2960 static RISCVException
rmw_hvip64(CPURISCVState
*env
, int csrno
,
2962 uint64_t new_val
, uint64_t wr_mask
)
2966 ret
= rmw_mip64(env
, csrno
, ret_val
, new_val
,
2967 wr_mask
& hvip_writable_mask
);
2969 *ret_val
&= VS_MODE_INTERRUPTS
;
2975 static RISCVException
rmw_hvip(CPURISCVState
*env
, int csrno
,
2976 target_ulong
*ret_val
,
2977 target_ulong new_val
, target_ulong wr_mask
)
2982 ret
= rmw_hvip64(env
, csrno
, &rval
, new_val
, wr_mask
);
2990 static RISCVException
rmw_hviph(CPURISCVState
*env
, int csrno
,
2991 target_ulong
*ret_val
,
2992 target_ulong new_val
, target_ulong wr_mask
)
2997 ret
= rmw_hvip64(env
, csrno
, &rval
,
2998 ((uint64_t)new_val
) << 32, ((uint64_t)wr_mask
) << 32);
3000 *ret_val
= rval
>> 32;
3006 static RISCVException
rmw_hip(CPURISCVState
*env
, int csrno
,
3007 target_ulong
*ret_value
,
3008 target_ulong new_value
, target_ulong write_mask
)
3010 int ret
= rmw_mip(env
, csrno
, ret_value
, new_value
,
3011 write_mask
& hip_writable_mask
);
3014 *ret_value
&= HS_MODE_INTERRUPTS
;
3019 static RISCVException
rmw_hie(CPURISCVState
*env
, int csrno
,
3020 target_ulong
*ret_val
,
3021 target_ulong new_val
, target_ulong wr_mask
)
3026 ret
= rmw_mie64(env
, csrno
, &rval
, new_val
, wr_mask
& HS_MODE_INTERRUPTS
);
3028 *ret_val
= rval
& HS_MODE_INTERRUPTS
;
3034 static RISCVException
read_hcounteren(CPURISCVState
*env
, int csrno
,
3037 *val
= env
->hcounteren
;
3038 return RISCV_EXCP_NONE
;
3041 static RISCVException
write_hcounteren(CPURISCVState
*env
, int csrno
,
3044 env
->hcounteren
= val
;
3045 return RISCV_EXCP_NONE
;
3048 static RISCVException
read_hgeie(CPURISCVState
*env
, int csrno
,
3054 return RISCV_EXCP_NONE
;
3057 static RISCVException
write_hgeie(CPURISCVState
*env
, int csrno
,
3060 /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
3061 val
&= ((((target_ulong
)1) << env
->geilen
) - 1) << 1;
3063 /* Update mip.SGEIP bit */
3064 riscv_cpu_update_mip(env
, MIP_SGEIP
,
3065 BOOL_TO_MASK(!!(env
->hgeie
& env
->hgeip
)));
3066 return RISCV_EXCP_NONE
;
3069 static RISCVException
read_htval(CPURISCVState
*env
, int csrno
,
3073 return RISCV_EXCP_NONE
;
3076 static RISCVException
write_htval(CPURISCVState
*env
, int csrno
,
3080 return RISCV_EXCP_NONE
;
3083 static RISCVException
read_htinst(CPURISCVState
*env
, int csrno
,
3087 return RISCV_EXCP_NONE
;
3090 static RISCVException
write_htinst(CPURISCVState
*env
, int csrno
,
3093 return RISCV_EXCP_NONE
;
3096 static RISCVException
read_hgeip(CPURISCVState
*env
, int csrno
,
3102 return RISCV_EXCP_NONE
;
3105 static RISCVException
read_hgatp(CPURISCVState
*env
, int csrno
,
3109 return RISCV_EXCP_NONE
;
3112 static RISCVException
write_hgatp(CPURISCVState
*env
, int csrno
,
3116 return RISCV_EXCP_NONE
;
3119 static RISCVException
read_htimedelta(CPURISCVState
*env
, int csrno
,
3122 if (!env
->rdtime_fn
) {
3123 return RISCV_EXCP_ILLEGAL_INST
;
3126 *val
= env
->htimedelta
;
3127 return RISCV_EXCP_NONE
;
3130 static RISCVException
write_htimedelta(CPURISCVState
*env
, int csrno
,
3133 if (!env
->rdtime_fn
) {
3134 return RISCV_EXCP_ILLEGAL_INST
;
3137 if (riscv_cpu_mxl(env
) == MXL_RV32
) {
3138 env
->htimedelta
= deposit64(env
->htimedelta
, 0, 32, (uint64_t)val
);
3140 env
->htimedelta
= val
;
3143 if (riscv_cpu_cfg(env
)->ext_sstc
&& env
->rdtime_fn
) {
3144 riscv_timer_write_timecmp(env
, env
->vstimer
, env
->vstimecmp
,
3145 env
->htimedelta
, MIP_VSTIP
);
3148 return RISCV_EXCP_NONE
;
3151 static RISCVException
read_htimedeltah(CPURISCVState
*env
, int csrno
,
3154 if (!env
->rdtime_fn
) {
3155 return RISCV_EXCP_ILLEGAL_INST
;
3158 *val
= env
->htimedelta
>> 32;
3159 return RISCV_EXCP_NONE
;
3162 static RISCVException
write_htimedeltah(CPURISCVState
*env
, int csrno
,
3165 if (!env
->rdtime_fn
) {
3166 return RISCV_EXCP_ILLEGAL_INST
;
3169 env
->htimedelta
= deposit64(env
->htimedelta
, 32, 32, (uint64_t)val
);
3171 if (riscv_cpu_cfg(env
)->ext_sstc
&& env
->rdtime_fn
) {
3172 riscv_timer_write_timecmp(env
, env
->vstimer
, env
->vstimecmp
,
3173 env
->htimedelta
, MIP_VSTIP
);
3176 return RISCV_EXCP_NONE
;
3179 static int read_hvictl(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
3182 return RISCV_EXCP_NONE
;
3185 static int write_hvictl(CPURISCVState
*env
, int csrno
, target_ulong val
)
3187 env
->hvictl
= val
& HVICTL_VALID_MASK
;
3188 return RISCV_EXCP_NONE
;
3191 static int read_hvipriox(CPURISCVState
*env
, int first_index
,
3192 uint8_t *iprio
, target_ulong
*val
)
3194 int i
, irq
, rdzero
, num_irqs
= 4 * (riscv_cpu_mxl_bits(env
) / 32);
3196 /* First index has to be a multiple of number of irqs per register */
3197 if (first_index
% num_irqs
) {
3198 return (env
->virt_enabled
) ?
3199 RISCV_EXCP_VIRT_INSTRUCTION_FAULT
: RISCV_EXCP_ILLEGAL_INST
;
3202 /* Fill-up return value */
3204 for (i
= 0; i
< num_irqs
; i
++) {
3205 if (riscv_cpu_hviprio_index2irq(first_index
+ i
, &irq
, &rdzero
)) {
3211 *val
|= ((target_ulong
)iprio
[irq
]) << (i
* 8);
3214 return RISCV_EXCP_NONE
;
3217 static int write_hvipriox(CPURISCVState
*env
, int first_index
,
3218 uint8_t *iprio
, target_ulong val
)
3220 int i
, irq
, rdzero
, num_irqs
= 4 * (riscv_cpu_mxl_bits(env
) / 32);
3222 /* First index has to be a multiple of number of irqs per register */
3223 if (first_index
% num_irqs
) {
3224 return (env
->virt_enabled
) ?
3225 RISCV_EXCP_VIRT_INSTRUCTION_FAULT
: RISCV_EXCP_ILLEGAL_INST
;
3228 /* Fill-up priority array */
3229 for (i
= 0; i
< num_irqs
; i
++) {
3230 if (riscv_cpu_hviprio_index2irq(first_index
+ i
, &irq
, &rdzero
)) {
3236 iprio
[irq
] = (val
>> (i
* 8)) & 0xff;
3240 return RISCV_EXCP_NONE
;
3243 static int read_hviprio1(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
3245 return read_hvipriox(env
, 0, env
->hviprio
, val
);
3248 static int write_hviprio1(CPURISCVState
*env
, int csrno
, target_ulong val
)
3250 return write_hvipriox(env
, 0, env
->hviprio
, val
);
3253 static int read_hviprio1h(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
3255 return read_hvipriox(env
, 4, env
->hviprio
, val
);
3258 static int write_hviprio1h(CPURISCVState
*env
, int csrno
, target_ulong val
)
3260 return write_hvipriox(env
, 4, env
->hviprio
, val
);
3263 static int read_hviprio2(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
3265 return read_hvipriox(env
, 8, env
->hviprio
, val
);
3268 static int write_hviprio2(CPURISCVState
*env
, int csrno
, target_ulong val
)
3270 return write_hvipriox(env
, 8, env
->hviprio
, val
);
3273 static int read_hviprio2h(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
3275 return read_hvipriox(env
, 12, env
->hviprio
, val
);
3278 static int write_hviprio2h(CPURISCVState
*env
, int csrno
, target_ulong val
)
3280 return write_hvipriox(env
, 12, env
->hviprio
, val
);
3283 /* Virtual CSR Registers */
3284 static RISCVException
read_vsstatus(CPURISCVState
*env
, int csrno
,
3287 *val
= env
->vsstatus
;
3288 return RISCV_EXCP_NONE
;
3291 static RISCVException
write_vsstatus(CPURISCVState
*env
, int csrno
,
3294 uint64_t mask
= (target_ulong
)-1;
3295 if ((val
& VSSTATUS64_UXL
) == 0) {
3296 mask
&= ~VSSTATUS64_UXL
;
3298 env
->vsstatus
= (env
->vsstatus
& ~mask
) | (uint64_t)val
;
3299 return RISCV_EXCP_NONE
;
3302 static int read_vstvec(CPURISCVState
*env
, int csrno
, target_ulong
*val
)
3305 return RISCV_EXCP_NONE
;
3308 static RISCVException
write_vstvec(CPURISCVState
*env
, int csrno
,
3312 return RISCV_EXCP_NONE
;
3315 static RISCVException
read_vsscratch(CPURISCVState
*env
, int csrno
,
3318 *val
= env
->vsscratch
;
3319 return RISCV_EXCP_NONE
;
3322 static RISCVException
write_vsscratch(CPURISCVState
*env
, int csrno
,
3325 env
->vsscratch
= val
;
3326 return RISCV_EXCP_NONE
;
3329 static RISCVException
read_vsepc(CPURISCVState
*env
, int csrno
,
3333 return RISCV_EXCP_NONE
;
3336 static RISCVException
write_vsepc(CPURISCVState
*env
, int csrno
,
3340 return RISCV_EXCP_NONE
;
3343 static RISCVException
read_vscause(CPURISCVState
*env
, int csrno
,
3346 *val
= env
->vscause
;
3347 return RISCV_EXCP_NONE
;
3350 static RISCVException
write_vscause(CPURISCVState
*env
, int csrno
,
3354 return RISCV_EXCP_NONE
;
3357 static RISCVException
read_vstval(CPURISCVState
*env
, int csrno
,
3361 return RISCV_EXCP_NONE
;
3364 static RISCVException
write_vstval(CPURISCVState
*env
, int csrno
,
3368 return RISCV_EXCP_NONE
;
3371 static RISCVException
read_vsatp(CPURISCVState
*env
, int csrno
,
3375 return RISCV_EXCP_NONE
;
3378 static RISCVException
write_vsatp(CPURISCVState
*env
, int csrno
,
3382 return RISCV_EXCP_NONE
;
3385 static RISCVException
read_mtval2(CPURISCVState
*env
, int csrno
,
3389 return RISCV_EXCP_NONE
;
3392 static RISCVException
write_mtval2(CPURISCVState
*env
, int csrno
,
3396 return RISCV_EXCP_NONE
;
3399 static RISCVException
read_mtinst(CPURISCVState
*env
, int csrno
,
3403 return RISCV_EXCP_NONE
;
3406 static RISCVException
write_mtinst(CPURISCVState
*env
, int csrno
,
3410 return RISCV_EXCP_NONE
;
3413 /* Physical Memory Protection */
3414 static RISCVException
read_mseccfg(CPURISCVState
*env
, int csrno
,
3417 *val
= mseccfg_csr_read(env
);
3418 return RISCV_EXCP_NONE
;
3421 static RISCVException
write_mseccfg(CPURISCVState
*env
, int csrno
,
3424 mseccfg_csr_write(env
, val
);
3425 return RISCV_EXCP_NONE
;
3428 static RISCVException
read_pmpcfg(CPURISCVState
*env
, int csrno
,
3431 uint32_t reg_index
= csrno
- CSR_PMPCFG0
;
3433 *val
= pmpcfg_csr_read(env
, reg_index
);
3434 return RISCV_EXCP_NONE
;
3437 static RISCVException
write_pmpcfg(CPURISCVState
*env
, int csrno
,
3440 uint32_t reg_index
= csrno
- CSR_PMPCFG0
;
3442 pmpcfg_csr_write(env
, reg_index
, val
);
3443 return RISCV_EXCP_NONE
;
3446 static RISCVException
read_pmpaddr(CPURISCVState
*env
, int csrno
,
3449 *val
= pmpaddr_csr_read(env
, csrno
- CSR_PMPADDR0
);
3450 return RISCV_EXCP_NONE
;
3453 static RISCVException
write_pmpaddr(CPURISCVState
*env
, int csrno
,
3456 pmpaddr_csr_write(env
, csrno
- CSR_PMPADDR0
, val
);
3457 return RISCV_EXCP_NONE
;
3460 static RISCVException
read_tselect(CPURISCVState
*env
, int csrno
,
3463 *val
= tselect_csr_read(env
);
3464 return RISCV_EXCP_NONE
;
3467 static RISCVException
write_tselect(CPURISCVState
*env
, int csrno
,
3470 tselect_csr_write(env
, val
);
3471 return RISCV_EXCP_NONE
;
3474 static RISCVException
read_tdata(CPURISCVState
*env
, int csrno
,
3477 /* return 0 in tdata1 to end the trigger enumeration */
3478 if (env
->trigger_cur
>= RV_MAX_TRIGGERS
&& csrno
== CSR_TDATA1
) {
3480 return RISCV_EXCP_NONE
;
3483 if (!tdata_available(env
, csrno
- CSR_TDATA1
)) {
3484 return RISCV_EXCP_ILLEGAL_INST
;
3487 *val
= tdata_csr_read(env
, csrno
- CSR_TDATA1
);
3488 return RISCV_EXCP_NONE
;
3491 static RISCVException
write_tdata(CPURISCVState
*env
, int csrno
,
3494 if (!tdata_available(env
, csrno
- CSR_TDATA1
)) {
3495 return RISCV_EXCP_ILLEGAL_INST
;
3498 tdata_csr_write(env
, csrno
- CSR_TDATA1
, val
);
3499 return RISCV_EXCP_NONE
;
3502 static RISCVException
read_tinfo(CPURISCVState
*env
, int csrno
,
3505 *val
= tinfo_csr_read(env
);
3506 return RISCV_EXCP_NONE
;
3510 * Functions to access Pointer Masking feature registers
3511 * We have to check if current priv lvl could modify
3514 static bool check_pm_current_disabled(CPURISCVState
*env
, int csrno
)
3516 int csr_priv
= get_field(csrno
, 0x300);
3519 if (env
->debugger
) {
3523 * If priv lvls differ that means we're accessing csr from higher priv lvl,
3524 * so allow the access
3526 if (env
->priv
!= csr_priv
) {
3529 switch (env
->priv
) {
3531 pm_current
= get_field(env
->mmte
, M_PM_CURRENT
);
3534 pm_current
= get_field(env
->mmte
, S_PM_CURRENT
);
3537 pm_current
= get_field(env
->mmte
, U_PM_CURRENT
);
3540 g_assert_not_reached();
3542 /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
3546 static RISCVException
read_mmte(CPURISCVState
*env
, int csrno
,
3549 *val
= env
->mmte
& MMTE_MASK
;
3550 return RISCV_EXCP_NONE
;
3553 static RISCVException
write_mmte(CPURISCVState
*env
, int csrno
,
3557 target_ulong wpri_val
= val
& MMTE_MASK
;
3559 if (val
!= wpri_val
) {
3560 qemu_log_mask(LOG_GUEST_ERROR
, "%s" TARGET_FMT_lx
" %s"
3561 TARGET_FMT_lx
"\n", "MMTE: WPRI violation written 0x",
3562 val
, "vs expected 0x", wpri_val
);
3564 /* for machine mode pm.current is hardwired to 1 */
3565 wpri_val
|= MMTE_M_PM_CURRENT
;
3567 /* hardwiring pm.instruction bit to 0, since it's not supported yet */
3568 wpri_val
&= ~(MMTE_M_PM_INSN
| MMTE_S_PM_INSN
| MMTE_U_PM_INSN
);
3569 env
->mmte
= wpri_val
| EXT_STATUS_DIRTY
;
3570 riscv_cpu_update_mask(env
);
3572 /* Set XS and SD bits, since PM CSRs are dirty */
3573 mstatus
= env
->mstatus
| MSTATUS_XS
;
3574 write_mstatus(env
, csrno
, mstatus
);
3575 return RISCV_EXCP_NONE
;
3578 static RISCVException
read_smte(CPURISCVState
*env
, int csrno
,
3581 *val
= env
->mmte
& SMTE_MASK
;
3582 return RISCV_EXCP_NONE
;
3585 static RISCVException
write_smte(CPURISCVState
*env
, int csrno
,
3588 target_ulong wpri_val
= val
& SMTE_MASK
;
3590 if (val
!= wpri_val
) {
3591 qemu_log_mask(LOG_GUEST_ERROR
, "%s" TARGET_FMT_lx
" %s"
3592 TARGET_FMT_lx
"\n", "SMTE: WPRI violation written 0x",
3593 val
, "vs expected 0x", wpri_val
);
3596 /* if pm.current==0 we can't modify current PM CSRs */
3597 if (check_pm_current_disabled(env
, csrno
)) {
3598 return RISCV_EXCP_NONE
;
3601 wpri_val
|= (env
->mmte
& ~SMTE_MASK
);
3602 write_mmte(env
, csrno
, wpri_val
);
3603 return RISCV_EXCP_NONE
;
3606 static RISCVException
read_umte(CPURISCVState
*env
, int csrno
,
3609 *val
= env
->mmte
& UMTE_MASK
;
3610 return RISCV_EXCP_NONE
;
3613 static RISCVException
write_umte(CPURISCVState
*env
, int csrno
,
3616 target_ulong wpri_val
= val
& UMTE_MASK
;
3618 if (val
!= wpri_val
) {
3619 qemu_log_mask(LOG_GUEST_ERROR
, "%s" TARGET_FMT_lx
" %s"
3620 TARGET_FMT_lx
"\n", "UMTE: WPRI violation written 0x",
3621 val
, "vs expected 0x", wpri_val
);
3624 if (check_pm_current_disabled(env
, csrno
)) {
3625 return RISCV_EXCP_NONE
;
3628 wpri_val
|= (env
->mmte
& ~UMTE_MASK
);
3629 write_mmte(env
, csrno
, wpri_val
);
3630 return RISCV_EXCP_NONE
;
3633 static RISCVException
read_mpmmask(CPURISCVState
*env
, int csrno
,
3636 *val
= env
->mpmmask
;
3637 return RISCV_EXCP_NONE
;
3640 static RISCVException
write_mpmmask(CPURISCVState
*env
, int csrno
,
3646 if ((cpu_address_mode(env
) == PRV_M
) && (env
->mmte
& M_PM_ENABLE
)) {
3647 env
->cur_pmmask
= val
;
3649 env
->mmte
|= EXT_STATUS_DIRTY
;
3651 /* Set XS and SD bits, since PM CSRs are dirty */
3652 mstatus
= env
->mstatus
| MSTATUS_XS
;
3653 write_mstatus(env
, csrno
, mstatus
);
3654 return RISCV_EXCP_NONE
;
3657 static RISCVException
read_spmmask(CPURISCVState
*env
, int csrno
,
3660 *val
= env
->spmmask
;
3661 return RISCV_EXCP_NONE
;
3664 static RISCVException
write_spmmask(CPURISCVState
*env
, int csrno
,
3669 /* if pm.current==0 we can't modify current PM CSRs */
3670 if (check_pm_current_disabled(env
, csrno
)) {
3671 return RISCV_EXCP_NONE
;
3674 if ((cpu_address_mode(env
) == PRV_S
) && (env
->mmte
& S_PM_ENABLE
)) {
3675 env
->cur_pmmask
= val
;
3676 if (cpu_get_xl(env
, PRV_S
) == MXL_RV32
) {
3677 env
->cur_pmmask
&= UINT32_MAX
;
3680 env
->mmte
|= EXT_STATUS_DIRTY
;
3682 /* Set XS and SD bits, since PM CSRs are dirty */
3683 mstatus
= env
->mstatus
| MSTATUS_XS
;
3684 write_mstatus(env
, csrno
, mstatus
);
3685 return RISCV_EXCP_NONE
;
3688 static RISCVException
read_upmmask(CPURISCVState
*env
, int csrno
,
3691 *val
= env
->upmmask
;
3692 return RISCV_EXCP_NONE
;
3695 static RISCVException
write_upmmask(CPURISCVState
*env
, int csrno
,
3700 /* if pm.current==0 we can't modify current PM CSRs */
3701 if (check_pm_current_disabled(env
, csrno
)) {
3702 return RISCV_EXCP_NONE
;
3705 if ((cpu_address_mode(env
) == PRV_U
) && (env
->mmte
& U_PM_ENABLE
)) {
3706 env
->cur_pmmask
= val
;
3707 if (cpu_get_xl(env
, PRV_U
) == MXL_RV32
) {
3708 env
->cur_pmmask
&= UINT32_MAX
;
3711 env
->mmte
|= EXT_STATUS_DIRTY
;
3713 /* Set XS and SD bits, since PM CSRs are dirty */
3714 mstatus
= env
->mstatus
| MSTATUS_XS
;
3715 write_mstatus(env
, csrno
, mstatus
);
3716 return RISCV_EXCP_NONE
;
3719 static RISCVException
read_mpmbase(CPURISCVState
*env
, int csrno
,
3722 *val
= env
->mpmbase
;
3723 return RISCV_EXCP_NONE
;
3726 static RISCVException
write_mpmbase(CPURISCVState
*env
, int csrno
,
3732 if ((cpu_address_mode(env
) == PRV_M
) && (env
->mmte
& M_PM_ENABLE
)) {
3733 env
->cur_pmbase
= val
;
3735 env
->mmte
|= EXT_STATUS_DIRTY
;
3737 /* Set XS and SD bits, since PM CSRs are dirty */
3738 mstatus
= env
->mstatus
| MSTATUS_XS
;
3739 write_mstatus(env
, csrno
, mstatus
);
3740 return RISCV_EXCP_NONE
;
3743 static RISCVException
read_spmbase(CPURISCVState
*env
, int csrno
,
3746 *val
= env
->spmbase
;
3747 return RISCV_EXCP_NONE
;
3750 static RISCVException
write_spmbase(CPURISCVState
*env
, int csrno
,
3755 /* if pm.current==0 we can't modify current PM CSRs */
3756 if (check_pm_current_disabled(env
, csrno
)) {
3757 return RISCV_EXCP_NONE
;
3760 if ((cpu_address_mode(env
) == PRV_S
) && (env
->mmte
& S_PM_ENABLE
)) {
3761 env
->cur_pmbase
= val
;
3762 if (cpu_get_xl(env
, PRV_S
) == MXL_RV32
) {
3763 env
->cur_pmbase
&= UINT32_MAX
;
3766 env
->mmte
|= EXT_STATUS_DIRTY
;
3768 /* Set XS and SD bits, since PM CSRs are dirty */
3769 mstatus
= env
->mstatus
| MSTATUS_XS
;
3770 write_mstatus(env
, csrno
, mstatus
);
3771 return RISCV_EXCP_NONE
;
3774 static RISCVException
read_upmbase(CPURISCVState
*env
, int csrno
,
3777 *val
= env
->upmbase
;
3778 return RISCV_EXCP_NONE
;
3781 static RISCVException
write_upmbase(CPURISCVState
*env
, int csrno
,
3786 /* if pm.current==0 we can't modify current PM CSRs */
3787 if (check_pm_current_disabled(env
, csrno
)) {
3788 return RISCV_EXCP_NONE
;
3791 if ((cpu_address_mode(env
) == PRV_U
) && (env
->mmte
& U_PM_ENABLE
)) {
3792 env
->cur_pmbase
= val
;
3793 if (cpu_get_xl(env
, PRV_U
) == MXL_RV32
) {
3794 env
->cur_pmbase
&= UINT32_MAX
;
3797 env
->mmte
|= EXT_STATUS_DIRTY
;
3799 /* Set XS and SD bits, since PM CSRs are dirty */
3800 mstatus
= env
->mstatus
| MSTATUS_XS
;
3801 write_mstatus(env
, csrno
, mstatus
);
3802 return RISCV_EXCP_NONE
;
3807 /* Crypto Extension */
3808 static RISCVException
rmw_seed(CPURISCVState
*env
, int csrno
,
3809 target_ulong
*ret_value
,
3810 target_ulong new_value
,
3811 target_ulong write_mask
)
3814 Error
*random_e
= NULL
;
3818 random_r
= qemu_guest_getrandom(&random_v
, 2, &random_e
);
3819 if (unlikely(random_r
< 0)) {
3821 * Failed, for unknown reasons in the crypto subsystem.
3822 * The best we can do is log the reason and return a
3823 * failure indication to the guest. There is no reason
3824 * we know to expect the failure to be transitory, so
3825 * indicate DEAD to avoid having the guest spin on WAIT.
3827 qemu_log_mask(LOG_UNIMP
, "%s: Crypto failure: %s",
3828 __func__
, error_get_pretty(random_e
));
3829 error_free(random_e
);
3830 rval
= SEED_OPST_DEAD
;
3832 rval
= random_v
| SEED_OPST_ES16
;
3839 return RISCV_EXCP_NONE
;
3843 * riscv_csrrw - read and/or update control and status register
3845 * csrr <-> riscv_csrrw(env, csrno, ret_value, 0, 0);
3846 * csrrw <-> riscv_csrrw(env, csrno, ret_value, value, -1);
3847 * csrrs <-> riscv_csrrw(env, csrno, ret_value, -1, value);
3848 * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value);
3851 static inline RISCVException
riscv_csrrw_check(CPURISCVState
*env
,
3855 /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
3856 bool read_only
= get_field(csrno
, 0xC00) == 3;
3857 int csr_min_priv
= csr_ops
[csrno
].min_priv_ver
;
3859 /* ensure the CSR extension is enabled */
3860 if (!riscv_cpu_cfg(env
)->ext_icsr
) {
3861 return RISCV_EXCP_ILLEGAL_INST
;
3864 /* ensure CSR is implemented by checking predicate */
3865 if (!csr_ops
[csrno
].predicate
) {
3866 return RISCV_EXCP_ILLEGAL_INST
;
3869 /* privileged spec version check */
3870 if (env
->priv_ver
< csr_min_priv
) {
3871 return RISCV_EXCP_ILLEGAL_INST
;
3874 /* read / write check */
3875 if (write_mask
&& read_only
) {
3876 return RISCV_EXCP_ILLEGAL_INST
;
3880 * The predicate() not only does existence check but also does some
3881 * access control check which triggers for example virtual instruction
3882 * exception in some cases. When writing read-only CSRs in those cases
3883 * illegal instruction exception should be triggered instead of virtual
3884 * instruction exception. Hence this comes after the read / write check.
3886 RISCVException ret
= csr_ops
[csrno
].predicate(env
, csrno
);
3887 if (ret
!= RISCV_EXCP_NONE
) {
3891 #if !defined(CONFIG_USER_ONLY)
3892 int csr_priv
, effective_priv
= env
->priv
;
3894 if (riscv_has_ext(env
, RVH
) && env
->priv
== PRV_S
&&
3895 !env
->virt_enabled
) {
3897 * We are in HS mode. Add 1 to the effective privilege level to
3898 * allow us to access the Hypervisor CSRs.
3903 csr_priv
= get_field(csrno
, 0x300);
3904 if (!env
->debugger
&& (effective_priv
< csr_priv
)) {
3905 if (csr_priv
== (PRV_S
+ 1) && env
->virt_enabled
) {
3906 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT
;
3908 return RISCV_EXCP_ILLEGAL_INST
;
3911 return RISCV_EXCP_NONE
;
3914 static RISCVException
riscv_csrrw_do64(CPURISCVState
*env
, int csrno
,
3915 target_ulong
*ret_value
,
3916 target_ulong new_value
,
3917 target_ulong write_mask
)
3920 target_ulong old_value
= 0;
3922 /* execute combined read/write operation if it exists */
3923 if (csr_ops
[csrno
].op
) {
3924 return csr_ops
[csrno
].op(env
, csrno
, ret_value
, new_value
, write_mask
);
3928 * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
3929 * and we can't throw side effects caused by CSR reads.
3932 /* if no accessor exists then return failure */
3933 if (!csr_ops
[csrno
].read
) {
3934 return RISCV_EXCP_ILLEGAL_INST
;
3936 /* read old value */
3937 ret
= csr_ops
[csrno
].read(env
, csrno
, &old_value
);
3938 if (ret
!= RISCV_EXCP_NONE
) {
3943 /* write value if writable and write mask set, otherwise drop writes */
3945 new_value
= (old_value
& ~write_mask
) | (new_value
& write_mask
);
3946 if (csr_ops
[csrno
].write
) {
3947 ret
= csr_ops
[csrno
].write(env
, csrno
, new_value
);
3948 if (ret
!= RISCV_EXCP_NONE
) {
3954 /* return old value */
3956 *ret_value
= old_value
;
3959 return RISCV_EXCP_NONE
;
3962 RISCVException
riscv_csrrw(CPURISCVState
*env
, int csrno
,
3963 target_ulong
*ret_value
,
3964 target_ulong new_value
, target_ulong write_mask
)
3966 RISCVException ret
= riscv_csrrw_check(env
, csrno
, write_mask
);
3967 if (ret
!= RISCV_EXCP_NONE
) {
3971 return riscv_csrrw_do64(env
, csrno
, ret_value
, new_value
, write_mask
);
3974 static RISCVException
riscv_csrrw_do128(CPURISCVState
*env
, int csrno
,
3982 /* read old value */
3983 ret
= csr_ops
[csrno
].read128(env
, csrno
, &old_value
);
3984 if (ret
!= RISCV_EXCP_NONE
) {
3988 /* write value if writable and write mask set, otherwise drop writes */
3989 if (int128_nz(write_mask
)) {
3990 new_value
= int128_or(int128_and(old_value
, int128_not(write_mask
)),
3991 int128_and(new_value
, write_mask
));
3992 if (csr_ops
[csrno
].write128
) {
3993 ret
= csr_ops
[csrno
].write128(env
, csrno
, new_value
);
3994 if (ret
!= RISCV_EXCP_NONE
) {
3997 } else if (csr_ops
[csrno
].write
) {
3998 /* avoids having to write wrappers for all registers */
3999 ret
= csr_ops
[csrno
].write(env
, csrno
, int128_getlo(new_value
));
4000 if (ret
!= RISCV_EXCP_NONE
) {
4006 /* return old value */
4008 *ret_value
= old_value
;
4011 return RISCV_EXCP_NONE
;
4014 RISCVException
riscv_csrrw_i128(CPURISCVState
*env
, int csrno
,
4016 Int128 new_value
, Int128 write_mask
)
4020 ret
= riscv_csrrw_check(env
, csrno
, int128_nz(write_mask
));
4021 if (ret
!= RISCV_EXCP_NONE
) {
4025 if (csr_ops
[csrno
].read128
) {
4026 return riscv_csrrw_do128(env
, csrno
, ret_value
, new_value
, write_mask
);
4030 * Fall back to 64-bit version for now, if the 128-bit alternative isn't
4032 * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
4033 * significant), for those, this fallback is correctly handling the
4036 target_ulong old_value
;
4037 ret
= riscv_csrrw_do64(env
, csrno
, &old_value
,
4038 int128_getlo(new_value
),
4039 int128_getlo(write_mask
));
4040 if (ret
== RISCV_EXCP_NONE
&& ret_value
) {
4041 *ret_value
= int128_make64(old_value
);
4047 * Debugger support. If not in user mode, set env->debugger before the
4048 * riscv_csrrw call and clear it after the call.
4050 RISCVException
riscv_csrrw_debug(CPURISCVState
*env
, int csrno
,
4051 target_ulong
*ret_value
,
4052 target_ulong new_value
,
4053 target_ulong write_mask
)
4056 #if !defined(CONFIG_USER_ONLY)
4057 env
->debugger
= true;
4059 ret
= riscv_csrrw(env
, csrno
, ret_value
, new_value
, write_mask
);
4060 #if !defined(CONFIG_USER_ONLY)
4061 env
->debugger
= false;
4066 static RISCVException
read_jvt(CPURISCVState
*env
, int csrno
,
4070 return RISCV_EXCP_NONE
;
4073 static RISCVException
write_jvt(CPURISCVState
*env
, int csrno
,
4077 return RISCV_EXCP_NONE
;
4081 * Control and Status Register function table
4082 * riscv_csr_operations::predicate() must be provided for an implemented CSR
4084 riscv_csr_operations csr_ops
[CSR_TABLE_SIZE
] = {
4085 /* User Floating-Point CSRs */
4086 [CSR_FFLAGS
] = { "fflags", fs
, read_fflags
, write_fflags
},
4087 [CSR_FRM
] = { "frm", fs
, read_frm
, write_frm
},
4088 [CSR_FCSR
] = { "fcsr", fs
, read_fcsr
, write_fcsr
},
4090 [CSR_VSTART
] = { "vstart", vs
, read_vstart
, write_vstart
},
4091 [CSR_VXSAT
] = { "vxsat", vs
, read_vxsat
, write_vxsat
},
4092 [CSR_VXRM
] = { "vxrm", vs
, read_vxrm
, write_vxrm
},
4093 [CSR_VCSR
] = { "vcsr", vs
, read_vcsr
, write_vcsr
},
4094 [CSR_VL
] = { "vl", vs
, read_vl
},
4095 [CSR_VTYPE
] = { "vtype", vs
, read_vtype
},
4096 [CSR_VLENB
] = { "vlenb", vs
, read_vlenb
},
4097 /* User Timers and Counters */
4098 [CSR_CYCLE
] = { "cycle", ctr
, read_hpmcounter
},
4099 [CSR_INSTRET
] = { "instret", ctr
, read_hpmcounter
},
4100 [CSR_CYCLEH
] = { "cycleh", ctr32
, read_hpmcounterh
},
4101 [CSR_INSTRETH
] = { "instreth", ctr32
, read_hpmcounterh
},
4104 * In privileged mode, the monitor will have to emulate TIME CSRs only if
4105 * rdtime callback is not provided by machine/platform emulation.
4107 [CSR_TIME
] = { "time", ctr
, read_time
},
4108 [CSR_TIMEH
] = { "timeh", ctr32
, read_timeh
},
4110 /* Crypto Extension */
4111 [CSR_SEED
] = { "seed", seed
, NULL
, NULL
, rmw_seed
},
4113 /* Zcmt Extension */
4114 [CSR_JVT
] = {"jvt", zcmt
, read_jvt
, write_jvt
},
4116 #if !defined(CONFIG_USER_ONLY)
4117 /* Machine Timers and Counters */
4118 [CSR_MCYCLE
] = { "mcycle", any
, read_hpmcounter
,
4119 write_mhpmcounter
},
4120 [CSR_MINSTRET
] = { "minstret", any
, read_hpmcounter
,
4121 write_mhpmcounter
},
4122 [CSR_MCYCLEH
] = { "mcycleh", any32
, read_hpmcounterh
,
4123 write_mhpmcounterh
},
4124 [CSR_MINSTRETH
] = { "minstreth", any32
, read_hpmcounterh
,
4125 write_mhpmcounterh
},
4127 /* Machine Information Registers */
4128 [CSR_MVENDORID
] = { "mvendorid", any
, read_mvendorid
},
4129 [CSR_MARCHID
] = { "marchid", any
, read_marchid
},
4130 [CSR_MIMPID
] = { "mimpid", any
, read_mimpid
},
4131 [CSR_MHARTID
] = { "mhartid", any
, read_mhartid
},
4133 [CSR_MCONFIGPTR
] = { "mconfigptr", any
, read_zero
,
4134 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4135 /* Machine Trap Setup */
4136 [CSR_MSTATUS
] = { "mstatus", any
, read_mstatus
, write_mstatus
,
4137 NULL
, read_mstatus_i128
},
4138 [CSR_MISA
] = { "misa", any
, read_misa
, write_misa
,
4139 NULL
, read_misa_i128
},
4140 [CSR_MIDELEG
] = { "mideleg", any
, NULL
, NULL
, rmw_mideleg
},
4141 [CSR_MEDELEG
] = { "medeleg", any
, read_medeleg
, write_medeleg
},
4142 [CSR_MIE
] = { "mie", any
, NULL
, NULL
, rmw_mie
},
4143 [CSR_MTVEC
] = { "mtvec", any
, read_mtvec
, write_mtvec
},
4144 [CSR_MCOUNTEREN
] = { "mcounteren", umode
, read_mcounteren
,
4147 [CSR_MSTATUSH
] = { "mstatush", any32
, read_mstatush
,
4150 /* Machine Trap Handling */
4151 [CSR_MSCRATCH
] = { "mscratch", any
, read_mscratch
, write_mscratch
,
4152 NULL
, read_mscratch_i128
, write_mscratch_i128
},
4153 [CSR_MEPC
] = { "mepc", any
, read_mepc
, write_mepc
},
4154 [CSR_MCAUSE
] = { "mcause", any
, read_mcause
, write_mcause
},
4155 [CSR_MTVAL
] = { "mtval", any
, read_mtval
, write_mtval
},
4156 [CSR_MIP
] = { "mip", any
, NULL
, NULL
, rmw_mip
},
4158 /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
4159 [CSR_MISELECT
] = { "miselect", aia_any
, NULL
, NULL
, rmw_xiselect
},
4160 [CSR_MIREG
] = { "mireg", aia_any
, NULL
, NULL
, rmw_xireg
},
4162 /* Machine-Level Interrupts (AIA) */
4163 [CSR_MTOPEI
] = { "mtopei", aia_any
, NULL
, NULL
, rmw_xtopei
},
4164 [CSR_MTOPI
] = { "mtopi", aia_any
, read_mtopi
},
4166 /* Virtual Interrupts for Supervisor Level (AIA) */
4167 [CSR_MVIEN
] = { "mvien", aia_any
, read_zero
, write_ignore
},
4168 [CSR_MVIP
] = { "mvip", aia_any
, read_zero
, write_ignore
},
4170 /* Machine-Level High-Half CSRs (AIA) */
4171 [CSR_MIDELEGH
] = { "midelegh", aia_any32
, NULL
, NULL
, rmw_midelegh
},
4172 [CSR_MIEH
] = { "mieh", aia_any32
, NULL
, NULL
, rmw_mieh
},
4173 [CSR_MVIENH
] = { "mvienh", aia_any32
, read_zero
, write_ignore
},
4174 [CSR_MVIPH
] = { "mviph", aia_any32
, read_zero
, write_ignore
},
4175 [CSR_MIPH
] = { "miph", aia_any32
, NULL
, NULL
, rmw_miph
},
4177 /* Execution environment configuration */
4178 [CSR_MENVCFG
] = { "menvcfg", umode
, read_menvcfg
, write_menvcfg
,
4179 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4180 [CSR_MENVCFGH
] = { "menvcfgh", umode32
, read_menvcfgh
, write_menvcfgh
,
4181 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4182 [CSR_SENVCFG
] = { "senvcfg", smode
, read_senvcfg
, write_senvcfg
,
4183 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4184 [CSR_HENVCFG
] = { "henvcfg", hmode
, read_henvcfg
, write_henvcfg
,
4185 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4186 [CSR_HENVCFGH
] = { "henvcfgh", hmode32
, read_henvcfgh
, write_henvcfgh
,
4187 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4189 /* Smstateen extension CSRs */
4190 [CSR_MSTATEEN0
] = { "mstateen0", mstateen
, read_mstateen
, write_mstateen0
,
4191 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4192 [CSR_MSTATEEN0H
] = { "mstateen0h", mstateen
, read_mstateenh
,
4194 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4195 [CSR_MSTATEEN1
] = { "mstateen1", mstateen
, read_mstateen
,
4197 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4198 [CSR_MSTATEEN1H
] = { "mstateen1h", mstateen
, read_mstateenh
,
4199 write_mstateenh_1_3
,
4200 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4201 [CSR_MSTATEEN2
] = { "mstateen2", mstateen
, read_mstateen
,
4203 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4204 [CSR_MSTATEEN2H
] = { "mstateen2h", mstateen
, read_mstateenh
,
4205 write_mstateenh_1_3
,
4206 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4207 [CSR_MSTATEEN3
] = { "mstateen3", mstateen
, read_mstateen
,
4209 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4210 [CSR_MSTATEEN3H
] = { "mstateen3h", mstateen
, read_mstateenh
,
4211 write_mstateenh_1_3
,
4212 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4213 [CSR_HSTATEEN0
] = { "hstateen0", hstateen
, read_hstateen
, write_hstateen0
,
4214 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4215 [CSR_HSTATEEN0H
] = { "hstateen0h", hstateenh
, read_hstateenh
,
4217 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4218 [CSR_HSTATEEN1
] = { "hstateen1", hstateen
, read_hstateen
,
4220 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4221 [CSR_HSTATEEN1H
] = { "hstateen1h", hstateenh
, read_hstateenh
,
4222 write_hstateenh_1_3
,
4223 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4224 [CSR_HSTATEEN2
] = { "hstateen2", hstateen
, read_hstateen
,
4226 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4227 [CSR_HSTATEEN2H
] = { "hstateen2h", hstateenh
, read_hstateenh
,
4228 write_hstateenh_1_3
,
4229 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4230 [CSR_HSTATEEN3
] = { "hstateen3", hstateen
, read_hstateen
,
4232 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4233 [CSR_HSTATEEN3H
] = { "hstateen3h", hstateenh
, read_hstateenh
,
4234 write_hstateenh_1_3
,
4235 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4236 [CSR_SSTATEEN0
] = { "sstateen0", sstateen
, read_sstateen
, write_sstateen0
,
4237 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4238 [CSR_SSTATEEN1
] = { "sstateen1", sstateen
, read_sstateen
,
4240 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4241 [CSR_SSTATEEN2
] = { "sstateen2", sstateen
, read_sstateen
,
4243 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4244 [CSR_SSTATEEN3
] = { "sstateen3", sstateen
, read_sstateen
,
4246 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4248 /* Supervisor Trap Setup */
4249 [CSR_SSTATUS
] = { "sstatus", smode
, read_sstatus
, write_sstatus
,
4250 NULL
, read_sstatus_i128
},
4251 [CSR_SIE
] = { "sie", smode
, NULL
, NULL
, rmw_sie
},
4252 [CSR_STVEC
] = { "stvec", smode
, read_stvec
, write_stvec
},
4253 [CSR_SCOUNTEREN
] = { "scounteren", smode
, read_scounteren
,
4256 /* Supervisor Trap Handling */
4257 [CSR_SSCRATCH
] = { "sscratch", smode
, read_sscratch
, write_sscratch
,
4258 NULL
, read_sscratch_i128
, write_sscratch_i128
},
4259 [CSR_SEPC
] = { "sepc", smode
, read_sepc
, write_sepc
},
4260 [CSR_SCAUSE
] = { "scause", smode
, read_scause
, write_scause
},
4261 [CSR_STVAL
] = { "stval", smode
, read_stval
, write_stval
},
4262 [CSR_SIP
] = { "sip", smode
, NULL
, NULL
, rmw_sip
},
4263 [CSR_STIMECMP
] = { "stimecmp", sstc
, read_stimecmp
, write_stimecmp
,
4264 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4265 [CSR_STIMECMPH
] = { "stimecmph", sstc_32
, read_stimecmph
, write_stimecmph
,
4266 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4267 [CSR_VSTIMECMP
] = { "vstimecmp", sstc
, read_vstimecmp
,
4269 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4270 [CSR_VSTIMECMPH
] = { "vstimecmph", sstc_32
, read_vstimecmph
,
4272 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4274 /* Supervisor Protection and Translation */
4275 [CSR_SATP
] = { "satp", satp
, read_satp
, write_satp
},
4277 /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
4278 [CSR_SISELECT
] = { "siselect", aia_smode
, NULL
, NULL
, rmw_xiselect
},
4279 [CSR_SIREG
] = { "sireg", aia_smode
, NULL
, NULL
, rmw_xireg
},
4281 /* Supervisor-Level Interrupts (AIA) */
4282 [CSR_STOPEI
] = { "stopei", aia_smode
, NULL
, NULL
, rmw_xtopei
},
4283 [CSR_STOPI
] = { "stopi", aia_smode
, read_stopi
},
4285 /* Supervisor-Level High-Half CSRs (AIA) */
4286 [CSR_SIEH
] = { "sieh", aia_smode32
, NULL
, NULL
, rmw_sieh
},
4287 [CSR_SIPH
] = { "siph", aia_smode32
, NULL
, NULL
, rmw_siph
},
4289 [CSR_HSTATUS
] = { "hstatus", hmode
, read_hstatus
, write_hstatus
,
4290 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4291 [CSR_HEDELEG
] = { "hedeleg", hmode
, read_hedeleg
, write_hedeleg
,
4292 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4293 [CSR_HIDELEG
] = { "hideleg", hmode
, NULL
, NULL
, rmw_hideleg
,
4294 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4295 [CSR_HVIP
] = { "hvip", hmode
, NULL
, NULL
, rmw_hvip
,
4296 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4297 [CSR_HIP
] = { "hip", hmode
, NULL
, NULL
, rmw_hip
,
4298 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4299 [CSR_HIE
] = { "hie", hmode
, NULL
, NULL
, rmw_hie
,
4300 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4301 [CSR_HCOUNTEREN
] = { "hcounteren", hmode
, read_hcounteren
,
4303 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4304 [CSR_HGEIE
] = { "hgeie", hmode
, read_hgeie
, write_hgeie
,
4305 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4306 [CSR_HTVAL
] = { "htval", hmode
, read_htval
, write_htval
,
4307 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4308 [CSR_HTINST
] = { "htinst", hmode
, read_htinst
, write_htinst
,
4309 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4310 [CSR_HGEIP
] = { "hgeip", hmode
, read_hgeip
,
4311 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4312 [CSR_HGATP
] = { "hgatp", hgatp
, read_hgatp
, write_hgatp
,
4313 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4314 [CSR_HTIMEDELTA
] = { "htimedelta", hmode
, read_htimedelta
,
4316 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4317 [CSR_HTIMEDELTAH
] = { "htimedeltah", hmode32
, read_htimedeltah
,
4319 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4321 [CSR_VSSTATUS
] = { "vsstatus", hmode
, read_vsstatus
,
4323 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4324 [CSR_VSIP
] = { "vsip", hmode
, NULL
, NULL
, rmw_vsip
,
4325 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4326 [CSR_VSIE
] = { "vsie", hmode
, NULL
, NULL
, rmw_vsie
,
4327 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4328 [CSR_VSTVEC
] = { "vstvec", hmode
, read_vstvec
, write_vstvec
,
4329 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4330 [CSR_VSSCRATCH
] = { "vsscratch", hmode
, read_vsscratch
,
4332 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4333 [CSR_VSEPC
] = { "vsepc", hmode
, read_vsepc
, write_vsepc
,
4334 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4335 [CSR_VSCAUSE
] = { "vscause", hmode
, read_vscause
, write_vscause
,
4336 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4337 [CSR_VSTVAL
] = { "vstval", hmode
, read_vstval
, write_vstval
,
4338 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4339 [CSR_VSATP
] = { "vsatp", hmode
, read_vsatp
, write_vsatp
,
4340 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4342 [CSR_MTVAL2
] = { "mtval2", hmode
, read_mtval2
, write_mtval2
,
4343 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4344 [CSR_MTINST
] = { "mtinst", hmode
, read_mtinst
, write_mtinst
,
4345 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4347 /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
4348 [CSR_HVIEN
] = { "hvien", aia_hmode
, read_zero
, write_ignore
},
4349 [CSR_HVICTL
] = { "hvictl", aia_hmode
, read_hvictl
,
4351 [CSR_HVIPRIO1
] = { "hviprio1", aia_hmode
, read_hviprio1
,
4353 [CSR_HVIPRIO2
] = { "hviprio2", aia_hmode
, read_hviprio2
,
4357 * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
4359 [CSR_VSISELECT
] = { "vsiselect", aia_hmode
, NULL
, NULL
,
4361 [CSR_VSIREG
] = { "vsireg", aia_hmode
, NULL
, NULL
, rmw_xireg
},
4363 /* VS-Level Interrupts (H-extension with AIA) */
4364 [CSR_VSTOPEI
] = { "vstopei", aia_hmode
, NULL
, NULL
, rmw_xtopei
},
4365 [CSR_VSTOPI
] = { "vstopi", aia_hmode
, read_vstopi
},
4367 /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
4368 [CSR_HIDELEGH
] = { "hidelegh", aia_hmode32
, NULL
, NULL
,
4370 [CSR_HVIENH
] = { "hvienh", aia_hmode32
, read_zero
,
4372 [CSR_HVIPH
] = { "hviph", aia_hmode32
, NULL
, NULL
, rmw_hviph
},
4373 [CSR_HVIPRIO1H
] = { "hviprio1h", aia_hmode32
, read_hviprio1h
,
4375 [CSR_HVIPRIO2H
] = { "hviprio2h", aia_hmode32
, read_hviprio2h
,
4377 [CSR_VSIEH
] = { "vsieh", aia_hmode32
, NULL
, NULL
, rmw_vsieh
},
4378 [CSR_VSIPH
] = { "vsiph", aia_hmode32
, NULL
, NULL
, rmw_vsiph
},
4380 /* Physical Memory Protection */
4381 [CSR_MSECCFG
] = { "mseccfg", epmp
, read_mseccfg
, write_mseccfg
,
4382 .min_priv_ver
= PRIV_VERSION_1_11_0
},
4383 [CSR_PMPCFG0
] = { "pmpcfg0", pmp
, read_pmpcfg
, write_pmpcfg
},
4384 [CSR_PMPCFG1
] = { "pmpcfg1", pmp
, read_pmpcfg
, write_pmpcfg
},
4385 [CSR_PMPCFG2
] = { "pmpcfg2", pmp
, read_pmpcfg
, write_pmpcfg
},
4386 [CSR_PMPCFG3
] = { "pmpcfg3", pmp
, read_pmpcfg
, write_pmpcfg
},
4387 [CSR_PMPADDR0
] = { "pmpaddr0", pmp
, read_pmpaddr
, write_pmpaddr
},
4388 [CSR_PMPADDR1
] = { "pmpaddr1", pmp
, read_pmpaddr
, write_pmpaddr
},
4389 [CSR_PMPADDR2
] = { "pmpaddr2", pmp
, read_pmpaddr
, write_pmpaddr
},
4390 [CSR_PMPADDR3
] = { "pmpaddr3", pmp
, read_pmpaddr
, write_pmpaddr
},
4391 [CSR_PMPADDR4
] = { "pmpaddr4", pmp
, read_pmpaddr
, write_pmpaddr
},
4392 [CSR_PMPADDR5
] = { "pmpaddr5", pmp
, read_pmpaddr
, write_pmpaddr
},
4393 [CSR_PMPADDR6
] = { "pmpaddr6", pmp
, read_pmpaddr
, write_pmpaddr
},
4394 [CSR_PMPADDR7
] = { "pmpaddr7", pmp
, read_pmpaddr
, write_pmpaddr
},
4395 [CSR_PMPADDR8
] = { "pmpaddr8", pmp
, read_pmpaddr
, write_pmpaddr
},
4396 [CSR_PMPADDR9
] = { "pmpaddr9", pmp
, read_pmpaddr
, write_pmpaddr
},
4397 [CSR_PMPADDR10
] = { "pmpaddr10", pmp
, read_pmpaddr
, write_pmpaddr
},
4398 [CSR_PMPADDR11
] = { "pmpaddr11", pmp
, read_pmpaddr
, write_pmpaddr
},
4399 [CSR_PMPADDR12
] = { "pmpaddr12", pmp
, read_pmpaddr
, write_pmpaddr
},
4400 [CSR_PMPADDR13
] = { "pmpaddr13", pmp
, read_pmpaddr
, write_pmpaddr
},
4401 [CSR_PMPADDR14
] = { "pmpaddr14", pmp
, read_pmpaddr
, write_pmpaddr
},
4402 [CSR_PMPADDR15
] = { "pmpaddr15", pmp
, read_pmpaddr
, write_pmpaddr
},
4405 [CSR_TSELECT
] = { "tselect", debug
, read_tselect
, write_tselect
},
4406 [CSR_TDATA1
] = { "tdata1", debug
, read_tdata
, write_tdata
},
4407 [CSR_TDATA2
] = { "tdata2", debug
, read_tdata
, write_tdata
},
4408 [CSR_TDATA3
] = { "tdata3", debug
, read_tdata
, write_tdata
},
4409 [CSR_TINFO
] = { "tinfo", debug
, read_tinfo
, write_ignore
},
4411 /* User Pointer Masking */
4412 [CSR_UMTE
] = { "umte", pointer_masking
, read_umte
, write_umte
},
4413 [CSR_UPMMASK
] = { "upmmask", pointer_masking
, read_upmmask
,
4415 [CSR_UPMBASE
] = { "upmbase", pointer_masking
, read_upmbase
,
4417 /* Machine Pointer Masking */
4418 [CSR_MMTE
] = { "mmte", pointer_masking
, read_mmte
, write_mmte
},
4419 [CSR_MPMMASK
] = { "mpmmask", pointer_masking
, read_mpmmask
,
4421 [CSR_MPMBASE
] = { "mpmbase", pointer_masking
, read_mpmbase
,
4423 /* Supervisor Pointer Masking */
4424 [CSR_SMTE
] = { "smte", pointer_masking
, read_smte
, write_smte
},
4425 [CSR_SPMMASK
] = { "spmmask", pointer_masking
, read_spmmask
,
4427 [CSR_SPMBASE
] = { "spmbase", pointer_masking
, read_spmbase
,
4430 /* Performance Counters */
4431 [CSR_HPMCOUNTER3
] = { "hpmcounter3", ctr
, read_hpmcounter
},
4432 [CSR_HPMCOUNTER4
] = { "hpmcounter4", ctr
, read_hpmcounter
},
4433 [CSR_HPMCOUNTER5
] = { "hpmcounter5", ctr
, read_hpmcounter
},
4434 [CSR_HPMCOUNTER6
] = { "hpmcounter6", ctr
, read_hpmcounter
},
4435 [CSR_HPMCOUNTER7
] = { "hpmcounter7", ctr
, read_hpmcounter
},
4436 [CSR_HPMCOUNTER8
] = { "hpmcounter8", ctr
, read_hpmcounter
},
4437 [CSR_HPMCOUNTER9
] = { "hpmcounter9", ctr
, read_hpmcounter
},
4438 [CSR_HPMCOUNTER10
] = { "hpmcounter10", ctr
, read_hpmcounter
},
4439 [CSR_HPMCOUNTER11
] = { "hpmcounter11", ctr
, read_hpmcounter
},
4440 [CSR_HPMCOUNTER12
] = { "hpmcounter12", ctr
, read_hpmcounter
},
4441 [CSR_HPMCOUNTER13
] = { "hpmcounter13", ctr
, read_hpmcounter
},
4442 [CSR_HPMCOUNTER14
] = { "hpmcounter14", ctr
, read_hpmcounter
},
4443 [CSR_HPMCOUNTER15
] = { "hpmcounter15", ctr
, read_hpmcounter
},
4444 [CSR_HPMCOUNTER16
] = { "hpmcounter16", ctr
, read_hpmcounter
},
4445 [CSR_HPMCOUNTER17
] = { "hpmcounter17", ctr
, read_hpmcounter
},
4446 [CSR_HPMCOUNTER18
] = { "hpmcounter18", ctr
, read_hpmcounter
},
4447 [CSR_HPMCOUNTER19
] = { "hpmcounter19", ctr
, read_hpmcounter
},
4448 [CSR_HPMCOUNTER20
] = { "hpmcounter20", ctr
, read_hpmcounter
},
4449 [CSR_HPMCOUNTER21
] = { "hpmcounter21", ctr
, read_hpmcounter
},
4450 [CSR_HPMCOUNTER22
] = { "hpmcounter22", ctr
, read_hpmcounter
},
4451 [CSR_HPMCOUNTER23
] = { "hpmcounter23", ctr
, read_hpmcounter
},
4452 [CSR_HPMCOUNTER24
] = { "hpmcounter24", ctr
, read_hpmcounter
},
4453 [CSR_HPMCOUNTER25
] = { "hpmcounter25", ctr
, read_hpmcounter
},
4454 [CSR_HPMCOUNTER26
] = { "hpmcounter26", ctr
, read_hpmcounter
},
4455 [CSR_HPMCOUNTER27
] = { "hpmcounter27", ctr
, read_hpmcounter
},
4456 [CSR_HPMCOUNTER28
] = { "hpmcounter28", ctr
, read_hpmcounter
},
4457 [CSR_HPMCOUNTER29
] = { "hpmcounter29", ctr
, read_hpmcounter
},
4458 [CSR_HPMCOUNTER30
] = { "hpmcounter30", ctr
, read_hpmcounter
},
4459 [CSR_HPMCOUNTER31
] = { "hpmcounter31", ctr
, read_hpmcounter
},
4461 [CSR_MHPMCOUNTER3
] = { "mhpmcounter3", mctr
, read_hpmcounter
,
4462 write_mhpmcounter
},
4463 [CSR_MHPMCOUNTER4
] = { "mhpmcounter4", mctr
, read_hpmcounter
,
4464 write_mhpmcounter
},
4465 [CSR_MHPMCOUNTER5
] = { "mhpmcounter5", mctr
, read_hpmcounter
,
4466 write_mhpmcounter
},
4467 [CSR_MHPMCOUNTER6
] = { "mhpmcounter6", mctr
, read_hpmcounter
,
4468 write_mhpmcounter
},
4469 [CSR_MHPMCOUNTER7
] = { "mhpmcounter7", mctr
, read_hpmcounter
,
4470 write_mhpmcounter
},
4471 [CSR_MHPMCOUNTER8
] = { "mhpmcounter8", mctr
, read_hpmcounter
,
4472 write_mhpmcounter
},
4473 [CSR_MHPMCOUNTER9
] = { "mhpmcounter9", mctr
, read_hpmcounter
,
4474 write_mhpmcounter
},
4475 [CSR_MHPMCOUNTER10
] = { "mhpmcounter10", mctr
, read_hpmcounter
,
4476 write_mhpmcounter
},
4477 [CSR_MHPMCOUNTER11
] = { "mhpmcounter11", mctr
, read_hpmcounter
,
4478 write_mhpmcounter
},
4479 [CSR_MHPMCOUNTER12
] = { "mhpmcounter12", mctr
, read_hpmcounter
,
4480 write_mhpmcounter
},
4481 [CSR_MHPMCOUNTER13
] = { "mhpmcounter13", mctr
, read_hpmcounter
,
4482 write_mhpmcounter
},
4483 [CSR_MHPMCOUNTER14
] = { "mhpmcounter14", mctr
, read_hpmcounter
,
4484 write_mhpmcounter
},
4485 [CSR_MHPMCOUNTER15
] = { "mhpmcounter15", mctr
, read_hpmcounter
,
4486 write_mhpmcounter
},
4487 [CSR_MHPMCOUNTER16
] = { "mhpmcounter16", mctr
, read_hpmcounter
,
4488 write_mhpmcounter
},
4489 [CSR_MHPMCOUNTER17
] = { "mhpmcounter17", mctr
, read_hpmcounter
,
4490 write_mhpmcounter
},
4491 [CSR_MHPMCOUNTER18
] = { "mhpmcounter18", mctr
, read_hpmcounter
,
4492 write_mhpmcounter
},
4493 [CSR_MHPMCOUNTER19
] = { "mhpmcounter19", mctr
, read_hpmcounter
,
4494 write_mhpmcounter
},
4495 [CSR_MHPMCOUNTER20
] = { "mhpmcounter20", mctr
, read_hpmcounter
,
4496 write_mhpmcounter
},
4497 [CSR_MHPMCOUNTER21
] = { "mhpmcounter21", mctr
, read_hpmcounter
,
4498 write_mhpmcounter
},
4499 [CSR_MHPMCOUNTER22
] = { "mhpmcounter22", mctr
, read_hpmcounter
,
4500 write_mhpmcounter
},
4501 [CSR_MHPMCOUNTER23
] = { "mhpmcounter23", mctr
, read_hpmcounter
,
4502 write_mhpmcounter
},
4503 [CSR_MHPMCOUNTER24
] = { "mhpmcounter24", mctr
, read_hpmcounter
,
4504 write_mhpmcounter
},
4505 [CSR_MHPMCOUNTER25
] = { "mhpmcounter25", mctr
, read_hpmcounter
,
4506 write_mhpmcounter
},
4507 [CSR_MHPMCOUNTER26
] = { "mhpmcounter26", mctr
, read_hpmcounter
,
4508 write_mhpmcounter
},
4509 [CSR_MHPMCOUNTER27
] = { "mhpmcounter27", mctr
, read_hpmcounter
,
4510 write_mhpmcounter
},
4511 [CSR_MHPMCOUNTER28
] = { "mhpmcounter28", mctr
, read_hpmcounter
,
4512 write_mhpmcounter
},
4513 [CSR_MHPMCOUNTER29
] = { "mhpmcounter29", mctr
, read_hpmcounter
,
4514 write_mhpmcounter
},
4515 [CSR_MHPMCOUNTER30
] = { "mhpmcounter30", mctr
, read_hpmcounter
,
4516 write_mhpmcounter
},
4517 [CSR_MHPMCOUNTER31
] = { "mhpmcounter31", mctr
, read_hpmcounter
,
4518 write_mhpmcounter
},
4520 [CSR_MCOUNTINHIBIT
] = { "mcountinhibit", any
, read_mcountinhibit
,
4521 write_mcountinhibit
,
4522 .min_priv_ver
= PRIV_VERSION_1_11_0
},
4524 [CSR_MHPMEVENT3
] = { "mhpmevent3", any
, read_mhpmevent
,
4526 [CSR_MHPMEVENT4
] = { "mhpmevent4", any
, read_mhpmevent
,
4528 [CSR_MHPMEVENT5
] = { "mhpmevent5", any
, read_mhpmevent
,
4530 [CSR_MHPMEVENT6
] = { "mhpmevent6", any
, read_mhpmevent
,
4532 [CSR_MHPMEVENT7
] = { "mhpmevent7", any
, read_mhpmevent
,
4534 [CSR_MHPMEVENT8
] = { "mhpmevent8", any
, read_mhpmevent
,
4536 [CSR_MHPMEVENT9
] = { "mhpmevent9", any
, read_mhpmevent
,
4538 [CSR_MHPMEVENT10
] = { "mhpmevent10", any
, read_mhpmevent
,
4540 [CSR_MHPMEVENT11
] = { "mhpmevent11", any
, read_mhpmevent
,
4542 [CSR_MHPMEVENT12
] = { "mhpmevent12", any
, read_mhpmevent
,
4544 [CSR_MHPMEVENT13
] = { "mhpmevent13", any
, read_mhpmevent
,
4546 [CSR_MHPMEVENT14
] = { "mhpmevent14", any
, read_mhpmevent
,
4548 [CSR_MHPMEVENT15
] = { "mhpmevent15", any
, read_mhpmevent
,
4550 [CSR_MHPMEVENT16
] = { "mhpmevent16", any
, read_mhpmevent
,
4552 [CSR_MHPMEVENT17
] = { "mhpmevent17", any
, read_mhpmevent
,
4554 [CSR_MHPMEVENT18
] = { "mhpmevent18", any
, read_mhpmevent
,
4556 [CSR_MHPMEVENT19
] = { "mhpmevent19", any
, read_mhpmevent
,
4558 [CSR_MHPMEVENT20
] = { "mhpmevent20", any
, read_mhpmevent
,
4560 [CSR_MHPMEVENT21
] = { "mhpmevent21", any
, read_mhpmevent
,
4562 [CSR_MHPMEVENT22
] = { "mhpmevent22", any
, read_mhpmevent
,
4564 [CSR_MHPMEVENT23
] = { "mhpmevent23", any
, read_mhpmevent
,
4566 [CSR_MHPMEVENT24
] = { "mhpmevent24", any
, read_mhpmevent
,
4568 [CSR_MHPMEVENT25
] = { "mhpmevent25", any
, read_mhpmevent
,
4570 [CSR_MHPMEVENT26
] = { "mhpmevent26", any
, read_mhpmevent
,
4572 [CSR_MHPMEVENT27
] = { "mhpmevent27", any
, read_mhpmevent
,
4574 [CSR_MHPMEVENT28
] = { "mhpmevent28", any
, read_mhpmevent
,
4576 [CSR_MHPMEVENT29
] = { "mhpmevent29", any
, read_mhpmevent
,
4578 [CSR_MHPMEVENT30
] = { "mhpmevent30", any
, read_mhpmevent
,
4580 [CSR_MHPMEVENT31
] = { "mhpmevent31", any
, read_mhpmevent
,
4583 [CSR_MHPMEVENT3H
] = { "mhpmevent3h", sscofpmf
, read_mhpmeventh
,
4585 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4586 [CSR_MHPMEVENT4H
] = { "mhpmevent4h", sscofpmf
, read_mhpmeventh
,
4588 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4589 [CSR_MHPMEVENT5H
] = { "mhpmevent5h", sscofpmf
, read_mhpmeventh
,
4591 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4592 [CSR_MHPMEVENT6H
] = { "mhpmevent6h", sscofpmf
, read_mhpmeventh
,
4594 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4595 [CSR_MHPMEVENT7H
] = { "mhpmevent7h", sscofpmf
, read_mhpmeventh
,
4597 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4598 [CSR_MHPMEVENT8H
] = { "mhpmevent8h", sscofpmf
, read_mhpmeventh
,
4600 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4601 [CSR_MHPMEVENT9H
] = { "mhpmevent9h", sscofpmf
, read_mhpmeventh
,
4603 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4604 [CSR_MHPMEVENT10H
] = { "mhpmevent10h", sscofpmf
, read_mhpmeventh
,
4606 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4607 [CSR_MHPMEVENT11H
] = { "mhpmevent11h", sscofpmf
, read_mhpmeventh
,
4609 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4610 [CSR_MHPMEVENT12H
] = { "mhpmevent12h", sscofpmf
, read_mhpmeventh
,
4612 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4613 [CSR_MHPMEVENT13H
] = { "mhpmevent13h", sscofpmf
, read_mhpmeventh
,
4615 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4616 [CSR_MHPMEVENT14H
] = { "mhpmevent14h", sscofpmf
, read_mhpmeventh
,
4618 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4619 [CSR_MHPMEVENT15H
] = { "mhpmevent15h", sscofpmf
, read_mhpmeventh
,
4621 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4622 [CSR_MHPMEVENT16H
] = { "mhpmevent16h", sscofpmf
, read_mhpmeventh
,
4624 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4625 [CSR_MHPMEVENT17H
] = { "mhpmevent17h", sscofpmf
, read_mhpmeventh
,
4627 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4628 [CSR_MHPMEVENT18H
] = { "mhpmevent18h", sscofpmf
, read_mhpmeventh
,
4630 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4631 [CSR_MHPMEVENT19H
] = { "mhpmevent19h", sscofpmf
, read_mhpmeventh
,
4633 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4634 [CSR_MHPMEVENT20H
] = { "mhpmevent20h", sscofpmf
, read_mhpmeventh
,
4636 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4637 [CSR_MHPMEVENT21H
] = { "mhpmevent21h", sscofpmf
, read_mhpmeventh
,
4639 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4640 [CSR_MHPMEVENT22H
] = { "mhpmevent22h", sscofpmf
, read_mhpmeventh
,
4642 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4643 [CSR_MHPMEVENT23H
] = { "mhpmevent23h", sscofpmf
, read_mhpmeventh
,
4645 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4646 [CSR_MHPMEVENT24H
] = { "mhpmevent24h", sscofpmf
, read_mhpmeventh
,
4648 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4649 [CSR_MHPMEVENT25H
] = { "mhpmevent25h", sscofpmf
, read_mhpmeventh
,
4651 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4652 [CSR_MHPMEVENT26H
] = { "mhpmevent26h", sscofpmf
, read_mhpmeventh
,
4654 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4655 [CSR_MHPMEVENT27H
] = { "mhpmevent27h", sscofpmf
, read_mhpmeventh
,
4657 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4658 [CSR_MHPMEVENT28H
] = { "mhpmevent28h", sscofpmf
, read_mhpmeventh
,
4660 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4661 [CSR_MHPMEVENT29H
] = { "mhpmevent29h", sscofpmf
, read_mhpmeventh
,
4663 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4664 [CSR_MHPMEVENT30H
] = { "mhpmevent30h", sscofpmf
, read_mhpmeventh
,
4666 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4667 [CSR_MHPMEVENT31H
] = { "mhpmevent31h", sscofpmf
, read_mhpmeventh
,
4669 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4671 [CSR_HPMCOUNTER3H
] = { "hpmcounter3h", ctr32
, read_hpmcounterh
},
4672 [CSR_HPMCOUNTER4H
] = { "hpmcounter4h", ctr32
, read_hpmcounterh
},
4673 [CSR_HPMCOUNTER5H
] = { "hpmcounter5h", ctr32
, read_hpmcounterh
},
4674 [CSR_HPMCOUNTER6H
] = { "hpmcounter6h", ctr32
, read_hpmcounterh
},
4675 [CSR_HPMCOUNTER7H
] = { "hpmcounter7h", ctr32
, read_hpmcounterh
},
4676 [CSR_HPMCOUNTER8H
] = { "hpmcounter8h", ctr32
, read_hpmcounterh
},
4677 [CSR_HPMCOUNTER9H
] = { "hpmcounter9h", ctr32
, read_hpmcounterh
},
4678 [CSR_HPMCOUNTER10H
] = { "hpmcounter10h", ctr32
, read_hpmcounterh
},
4679 [CSR_HPMCOUNTER11H
] = { "hpmcounter11h", ctr32
, read_hpmcounterh
},
4680 [CSR_HPMCOUNTER12H
] = { "hpmcounter12h", ctr32
, read_hpmcounterh
},
4681 [CSR_HPMCOUNTER13H
] = { "hpmcounter13h", ctr32
, read_hpmcounterh
},
4682 [CSR_HPMCOUNTER14H
] = { "hpmcounter14h", ctr32
, read_hpmcounterh
},
4683 [CSR_HPMCOUNTER15H
] = { "hpmcounter15h", ctr32
, read_hpmcounterh
},
4684 [CSR_HPMCOUNTER16H
] = { "hpmcounter16h", ctr32
, read_hpmcounterh
},
4685 [CSR_HPMCOUNTER17H
] = { "hpmcounter17h", ctr32
, read_hpmcounterh
},
4686 [CSR_HPMCOUNTER18H
] = { "hpmcounter18h", ctr32
, read_hpmcounterh
},
4687 [CSR_HPMCOUNTER19H
] = { "hpmcounter19h", ctr32
, read_hpmcounterh
},
4688 [CSR_HPMCOUNTER20H
] = { "hpmcounter20h", ctr32
, read_hpmcounterh
},
4689 [CSR_HPMCOUNTER21H
] = { "hpmcounter21h", ctr32
, read_hpmcounterh
},
4690 [CSR_HPMCOUNTER22H
] = { "hpmcounter22h", ctr32
, read_hpmcounterh
},
4691 [CSR_HPMCOUNTER23H
] = { "hpmcounter23h", ctr32
, read_hpmcounterh
},
4692 [CSR_HPMCOUNTER24H
] = { "hpmcounter24h", ctr32
, read_hpmcounterh
},
4693 [CSR_HPMCOUNTER25H
] = { "hpmcounter25h", ctr32
, read_hpmcounterh
},
4694 [CSR_HPMCOUNTER26H
] = { "hpmcounter26h", ctr32
, read_hpmcounterh
},
4695 [CSR_HPMCOUNTER27H
] = { "hpmcounter27h", ctr32
, read_hpmcounterh
},
4696 [CSR_HPMCOUNTER28H
] = { "hpmcounter28h", ctr32
, read_hpmcounterh
},
4697 [CSR_HPMCOUNTER29H
] = { "hpmcounter29h", ctr32
, read_hpmcounterh
},
4698 [CSR_HPMCOUNTER30H
] = { "hpmcounter30h", ctr32
, read_hpmcounterh
},
4699 [CSR_HPMCOUNTER31H
] = { "hpmcounter31h", ctr32
, read_hpmcounterh
},
4701 [CSR_MHPMCOUNTER3H
] = { "mhpmcounter3h", mctr32
, read_hpmcounterh
,
4702 write_mhpmcounterh
},
4703 [CSR_MHPMCOUNTER4H
] = { "mhpmcounter4h", mctr32
, read_hpmcounterh
,
4704 write_mhpmcounterh
},
4705 [CSR_MHPMCOUNTER5H
] = { "mhpmcounter5h", mctr32
, read_hpmcounterh
,
4706 write_mhpmcounterh
},
4707 [CSR_MHPMCOUNTER6H
] = { "mhpmcounter6h", mctr32
, read_hpmcounterh
,
4708 write_mhpmcounterh
},
4709 [CSR_MHPMCOUNTER7H
] = { "mhpmcounter7h", mctr32
, read_hpmcounterh
,
4710 write_mhpmcounterh
},
4711 [CSR_MHPMCOUNTER8H
] = { "mhpmcounter8h", mctr32
, read_hpmcounterh
,
4712 write_mhpmcounterh
},
4713 [CSR_MHPMCOUNTER9H
] = { "mhpmcounter9h", mctr32
, read_hpmcounterh
,
4714 write_mhpmcounterh
},
4715 [CSR_MHPMCOUNTER10H
] = { "mhpmcounter10h", mctr32
, read_hpmcounterh
,
4716 write_mhpmcounterh
},
4717 [CSR_MHPMCOUNTER11H
] = { "mhpmcounter11h", mctr32
, read_hpmcounterh
,
4718 write_mhpmcounterh
},
4719 [CSR_MHPMCOUNTER12H
] = { "mhpmcounter12h", mctr32
, read_hpmcounterh
,
4720 write_mhpmcounterh
},
4721 [CSR_MHPMCOUNTER13H
] = { "mhpmcounter13h", mctr32
, read_hpmcounterh
,
4722 write_mhpmcounterh
},
4723 [CSR_MHPMCOUNTER14H
] = { "mhpmcounter14h", mctr32
, read_hpmcounterh
,
4724 write_mhpmcounterh
},
4725 [CSR_MHPMCOUNTER15H
] = { "mhpmcounter15h", mctr32
, read_hpmcounterh
,
4726 write_mhpmcounterh
},
4727 [CSR_MHPMCOUNTER16H
] = { "mhpmcounter16h", mctr32
, read_hpmcounterh
,
4728 write_mhpmcounterh
},
4729 [CSR_MHPMCOUNTER17H
] = { "mhpmcounter17h", mctr32
, read_hpmcounterh
,
4730 write_mhpmcounterh
},
4731 [CSR_MHPMCOUNTER18H
] = { "mhpmcounter18h", mctr32
, read_hpmcounterh
,
4732 write_mhpmcounterh
},
4733 [CSR_MHPMCOUNTER19H
] = { "mhpmcounter19h", mctr32
, read_hpmcounterh
,
4734 write_mhpmcounterh
},
4735 [CSR_MHPMCOUNTER20H
] = { "mhpmcounter20h", mctr32
, read_hpmcounterh
,
4736 write_mhpmcounterh
},
4737 [CSR_MHPMCOUNTER21H
] = { "mhpmcounter21h", mctr32
, read_hpmcounterh
,
4738 write_mhpmcounterh
},
4739 [CSR_MHPMCOUNTER22H
] = { "mhpmcounter22h", mctr32
, read_hpmcounterh
,
4740 write_mhpmcounterh
},
4741 [CSR_MHPMCOUNTER23H
] = { "mhpmcounter23h", mctr32
, read_hpmcounterh
,
4742 write_mhpmcounterh
},
4743 [CSR_MHPMCOUNTER24H
] = { "mhpmcounter24h", mctr32
, read_hpmcounterh
,
4744 write_mhpmcounterh
},
4745 [CSR_MHPMCOUNTER25H
] = { "mhpmcounter25h", mctr32
, read_hpmcounterh
,
4746 write_mhpmcounterh
},
4747 [CSR_MHPMCOUNTER26H
] = { "mhpmcounter26h", mctr32
, read_hpmcounterh
,
4748 write_mhpmcounterh
},
4749 [CSR_MHPMCOUNTER27H
] = { "mhpmcounter27h", mctr32
, read_hpmcounterh
,
4750 write_mhpmcounterh
},
4751 [CSR_MHPMCOUNTER28H
] = { "mhpmcounter28h", mctr32
, read_hpmcounterh
,
4752 write_mhpmcounterh
},
4753 [CSR_MHPMCOUNTER29H
] = { "mhpmcounter29h", mctr32
, read_hpmcounterh
,
4754 write_mhpmcounterh
},
4755 [CSR_MHPMCOUNTER30H
] = { "mhpmcounter30h", mctr32
, read_hpmcounterh
,
4756 write_mhpmcounterh
},
4757 [CSR_MHPMCOUNTER31H
] = { "mhpmcounter31h", mctr32
, read_hpmcounterh
,
4758 write_mhpmcounterh
},
4759 [CSR_SCOUNTOVF
] = { "scountovf", sscofpmf
, read_scountovf
,
4760 .min_priv_ver
= PRIV_VERSION_1_12_0
},
4762 #endif /* !CONFIG_USER_ONLY */