xref: /openbmc/qemu/target/riscv/csr.c (revision 646746a131d550372a33235ad0c09f03b8eb820e)
1c7b95171SMichael Clark /*
2c7b95171SMichael Clark  * RISC-V Control and Status Registers.
3c7b95171SMichael Clark  *
4c7b95171SMichael Clark  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5c7b95171SMichael Clark  * Copyright (c) 2017-2018 SiFive, Inc.
6c7b95171SMichael Clark  *
7c7b95171SMichael Clark  * This program is free software; you can redistribute it and/or modify it
8c7b95171SMichael Clark  * under the terms and conditions of the GNU General Public License,
9c7b95171SMichael Clark  * version 2 or later, as published by the Free Software Foundation.
10c7b95171SMichael Clark  *
11c7b95171SMichael Clark  * This program is distributed in the hope it will be useful, but WITHOUT
12c7b95171SMichael Clark  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13c7b95171SMichael Clark  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14c7b95171SMichael Clark  * more details.
15c7b95171SMichael Clark  *
16c7b95171SMichael Clark  * You should have received a copy of the GNU General Public License along with
17c7b95171SMichael Clark  * this program.  If not, see <http://www.gnu.org/licenses/>.
18c7b95171SMichael Clark  */
19c7b95171SMichael Clark 
20c7b95171SMichael Clark #include "qemu/osdep.h"
21c7b95171SMichael Clark #include "qemu/log.h"
22b8012ecfSPhilippe Mathieu-Daudé #include "qemu/timer.h"
23c7b95171SMichael Clark #include "cpu.h"
2436c1118dSDaniel Henrique Barboza #include "tcg/tcg-cpu.h"
253780e337SAtish Patra #include "pmu.h"
2643888c2fSAtish Patra #include "time_helper.h"
27c7b95171SMichael Clark #include "exec/exec-all.h"
28548c9609SAlex Bennée #include "exec/tb-flush.h"
2903ff4f8dSPhilippe Mathieu-Daudé #include "sysemu/cpu-timers.h"
3077442380SWeiwei Li #include "qemu/guest-random.h"
3177442380SWeiwei Li #include "qapi/error.h"
32c7b95171SMichael Clark 
33c7b95171SMichael Clark /* CSR function table public API */
riscv_get_csr_ops(int csrno,riscv_csr_operations * ops)34c7b95171SMichael Clark void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
35c7b95171SMichael Clark {
36c7b95171SMichael Clark     *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
37c7b95171SMichael Clark }
38c7b95171SMichael Clark 
riscv_set_csr_ops(int csrno,riscv_csr_operations * ops)39c7b95171SMichael Clark void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
40c7b95171SMichael Clark {
41c7b95171SMichael Clark     csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
42c7b95171SMichael Clark }
43c7b95171SMichael Clark 
44a88365c1SMichael Clark /* Predicates */
45252b06f6SMayuresh Chitale #if !defined(CONFIG_USER_ONLY)
smstateen_acc_ok(CPURISCVState * env,int index,uint64_t bit)46ce3af0bbSWeiwei Li RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
47252b06f6SMayuresh Chitale {
4838256529SWeiwei Li     bool virt = env->virt_enabled;
49252b06f6SMayuresh Chitale 
50a9a4e39fSDaniel Henrique Barboza     if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
51252b06f6SMayuresh Chitale         return RISCV_EXCP_NONE;
52252b06f6SMayuresh Chitale     }
53252b06f6SMayuresh Chitale 
54252b06f6SMayuresh Chitale     if (!(env->mstateen[index] & bit)) {
55252b06f6SMayuresh Chitale         return RISCV_EXCP_ILLEGAL_INST;
56252b06f6SMayuresh Chitale     }
57252b06f6SMayuresh Chitale 
58252b06f6SMayuresh Chitale     if (virt) {
59252b06f6SMayuresh Chitale         if (!(env->hstateen[index] & bit)) {
60252b06f6SMayuresh Chitale             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
61252b06f6SMayuresh Chitale         }
62252b06f6SMayuresh Chitale 
63252b06f6SMayuresh Chitale         if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
64252b06f6SMayuresh Chitale             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
65252b06f6SMayuresh Chitale         }
66252b06f6SMayuresh Chitale     }
67252b06f6SMayuresh Chitale 
68252b06f6SMayuresh Chitale     if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
69252b06f6SMayuresh Chitale         if (!(env->sstateen[index] & bit)) {
70252b06f6SMayuresh Chitale             return RISCV_EXCP_ILLEGAL_INST;
71252b06f6SMayuresh Chitale         }
72252b06f6SMayuresh Chitale     }
73252b06f6SMayuresh Chitale 
74252b06f6SMayuresh Chitale     return RISCV_EXCP_NONE;
75252b06f6SMayuresh Chitale }
76252b06f6SMayuresh Chitale #endif
77252b06f6SMayuresh Chitale 
fs(CPURISCVState * env,int csrno)780e62f92eSAlistair Francis static RISCVException fs(CPURISCVState *env, int csrno)
79a88365c1SMichael Clark {
80a88365c1SMichael Clark #if !defined(CONFIG_USER_ONLY)
81c163b3baSWeiwei Li     if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
82a9a4e39fSDaniel Henrique Barboza         !riscv_cpu_cfg(env)->ext_zfinx) {
830e62f92eSAlistair Francis         return RISCV_EXCP_ILLEGAL_INST;
84a88365c1SMichael Clark     }
859514fc72SMayuresh Chitale 
869514fc72SMayuresh Chitale     if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
879514fc72SMayuresh Chitale         return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
889514fc72SMayuresh Chitale     }
89a88365c1SMichael Clark #endif
900e62f92eSAlistair Francis     return RISCV_EXCP_NONE;
91a88365c1SMichael Clark }
92a88365c1SMichael Clark 
vs(CPURISCVState * env,int csrno)930e62f92eSAlistair Francis static RISCVException vs(CPURISCVState *env, int csrno)
948e3a1f18SLIU Zhiwei {
959fb41a44SJason Chien     if (riscv_cpu_cfg(env)->ext_zve32x) {
966bc3dfa9SFrank Chang #if !defined(CONFIG_USER_ONLY)
976bc3dfa9SFrank Chang         if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
986bc3dfa9SFrank Chang             return RISCV_EXCP_ILLEGAL_INST;
996bc3dfa9SFrank Chang         }
1006bc3dfa9SFrank Chang #endif
1010e62f92eSAlistair Francis         return RISCV_EXCP_NONE;
1028e3a1f18SLIU Zhiwei     }
1030e62f92eSAlistair Francis     return RISCV_EXCP_ILLEGAL_INST;
1048e3a1f18SLIU Zhiwei }
1058e3a1f18SLIU Zhiwei 
ctr(CPURISCVState * env,int csrno)1060e62f92eSAlistair Francis static RISCVException ctr(CPURISCVState *env, int csrno)
107a88365c1SMichael Clark {
108a88365c1SMichael Clark #if !defined(CONFIG_USER_ONLY)
10994e29707SBin Meng     RISCVCPU *cpu = env_archcpu(env);
110562009e4SAtish Patra     int ctr_index;
111ade445efSAtish Patra     target_ulong ctr_mask;
11214664483SAtish Patra     int base_csrno = CSR_CYCLE;
11318d6d89eSAtish Patra     bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
1140a13a5b8SAlistair Francis 
11518d6d89eSAtish Patra     if (rv32 && csrno >= CSR_CYCLEH) {
11618d6d89eSAtish Patra         /* Offset for RV32 hpmcounternh counters */
11718d6d89eSAtish Patra         base_csrno += 0x80;
11818d6d89eSAtish Patra     }
11918d6d89eSAtish Patra     ctr_index = csrno - base_csrno;
120ade445efSAtish Patra     ctr_mask = BIT(ctr_index);
12118d6d89eSAtish Patra 
12214664483SAtish Patra     if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
12314664483SAtish Patra         (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
124c0040993SDaniel Henrique Barboza         if (!riscv_cpu_cfg(env)->ext_zicntr) {
125c0040993SDaniel Henrique Barboza             return RISCV_EXCP_ILLEGAL_INST;
126c0040993SDaniel Henrique Barboza         }
127c0040993SDaniel Henrique Barboza 
12814664483SAtish Patra         goto skip_ext_pmu_check;
12914664483SAtish Patra     }
13014664483SAtish Patra 
131ade445efSAtish Patra     if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
13218d6d89eSAtish Patra         /* No counter is enabled in PMU or the counter is out of range */
1330e62f92eSAlistair Francis         return RISCV_EXCP_ILLEGAL_INST;
1340a13a5b8SAlistair Francis     }
135e39a8320SAlistair Francis 
13614664483SAtish Patra skip_ext_pmu_check:
13714664483SAtish Patra 
138fb517fdbSBin Meng     if (env->debugger) {
139fb517fdbSBin Meng         return RISCV_EXCP_NONE;
140fb517fdbSBin Meng     }
141fb517fdbSBin Meng 
142a4128294SWeiwei Li     if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
143a5a92fd6SAtish Patra         return RISCV_EXCP_ILLEGAL_INST;
144a5a92fd6SAtish Patra     }
145a5a92fd6SAtish Patra 
14638256529SWeiwei Li     if (env->virt_enabled) {
147a4128294SWeiwei Li         if (!get_field(env->hcounteren, ctr_mask) ||
148a4128294SWeiwei Li             (env->priv == PRV_U && !get_field(env->scounteren, ctr_mask))) {
1490e62f92eSAlistair Francis             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
150e39a8320SAlistair Francis         }
151e39a8320SAlistair Francis     }
152a4128294SWeiwei Li 
153a4128294SWeiwei Li     if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
154a4128294SWeiwei Li         !get_field(env->scounteren, ctr_mask)) {
155a4128294SWeiwei Li         return RISCV_EXCP_ILLEGAL_INST;
156a4128294SWeiwei Li     }
157a4128294SWeiwei Li 
158a88365c1SMichael Clark #endif
1590e62f92eSAlistair Francis     return RISCV_EXCP_NONE;
160a88365c1SMichael Clark }
161a88365c1SMichael Clark 
ctr32(CPURISCVState * env,int csrno)1620e62f92eSAlistair Francis static RISCVException ctr32(CPURISCVState *env, int csrno)
1638987cdc4SAlistair Francis {
164db23e5d9SRichard Henderson     if (riscv_cpu_mxl(env) != MXL_RV32) {
1650e62f92eSAlistair Francis         return RISCV_EXCP_ILLEGAL_INST;
1668987cdc4SAlistair Francis     }
1678987cdc4SAlistair Francis 
1688987cdc4SAlistair Francis     return ctr(env, csrno);
1698987cdc4SAlistair Francis }
1708987cdc4SAlistair Francis 
zcmt(CPURISCVState * env,int csrno)171ce3af0bbSWeiwei Li static RISCVException zcmt(CPURISCVState *env, int csrno)
172ce3af0bbSWeiwei Li {
173ce3af0bbSWeiwei Li     if (!riscv_cpu_cfg(env)->ext_zcmt) {
174ce3af0bbSWeiwei Li         return RISCV_EXCP_ILLEGAL_INST;
175ce3af0bbSWeiwei Li     }
176ce3af0bbSWeiwei Li 
177ce3af0bbSWeiwei Li #if !defined(CONFIG_USER_ONLY)
178ce3af0bbSWeiwei Li     RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
179ce3af0bbSWeiwei Li     if (ret != RISCV_EXCP_NONE) {
180ce3af0bbSWeiwei Li         return ret;
181ce3af0bbSWeiwei Li     }
182ce3af0bbSWeiwei Li #endif
183ce3af0bbSWeiwei Li 
184ce3af0bbSWeiwei Li     return RISCV_EXCP_NONE;
185ce3af0bbSWeiwei Li }
186ce3af0bbSWeiwei Li 
cfi_ss(CPURISCVState * env,int csrno)187a88365c1SMichael Clark static RISCVException cfi_ss(CPURISCVState *env, int csrno)
18818d6d89eSAtish Patra {
18918d6d89eSAtish Patra     if (!env_archcpu(env)->cfg.ext_zicfiss) {
1907c1bb1d8SRob Bradford         return RISCV_EXCP_ILLEGAL_INST;
1917c1bb1d8SRob Bradford     }
19218d6d89eSAtish Patra 
19318d6d89eSAtish Patra     /* if bcfi not active for current env, access to csr is illegal */
19418d6d89eSAtish Patra     if (!cpu_get_bcfien(env)) {
19518d6d89eSAtish Patra #if !defined(CONFIG_USER_ONLY)
19618d6d89eSAtish Patra         if (env->debugger) {
1979a7c6da4SAlistair Francis             return RISCV_EXCP_NONE;
19818d6d89eSAtish Patra         }
1999a7c6da4SAlistair Francis #endif
2009a7c6da4SAlistair Francis         return RISCV_EXCP_ILLEGAL_INST;
2019a7c6da4SAlistair Francis     }
20218d6d89eSAtish Patra 
2037c1bb1d8SRob Bradford     return RISCV_EXCP_NONE;
20418d6d89eSAtish Patra }
20518d6d89eSAtish Patra 
20618d6d89eSAtish Patra #if !defined(CONFIG_USER_ONLY)
mctr(CPURISCVState * env,int csrno)20718d6d89eSAtish Patra static RISCVException mctr(CPURISCVState *env, int csrno)
20818d6d89eSAtish Patra {
20918d6d89eSAtish Patra     RISCVCPU *cpu = env_archcpu(env);
21018d6d89eSAtish Patra     uint32_t pmu_avail_ctrs = cpu->pmu_avail_ctrs;
211621f35bbSAtish Patra     int ctr_index;
212621f35bbSAtish Patra     int base_csrno = CSR_MHPMCOUNTER3;
213621f35bbSAtish Patra 
214621f35bbSAtish Patra     if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) {
215621f35bbSAtish Patra         /* Offset for RV32 mhpmcounternh counters */
216621f35bbSAtish Patra         csrno -= 0x80;
217621f35bbSAtish Patra     }
218621f35bbSAtish Patra 
219621f35bbSAtish Patra     g_assert(csrno >= CSR_MHPMCOUNTER3 && csrno <= CSR_MHPMCOUNTER31);
22014664483SAtish Patra 
22114664483SAtish Patra     ctr_index = csrno - base_csrno;
2229c33e08bSWeiwei Li     if ((BIT(ctr_index) & pmu_avail_ctrs >> 3) == 0) {
22314664483SAtish Patra         /* The PMU is not enabled or counter is out of range */
22414664483SAtish Patra         return RISCV_EXCP_ILLEGAL_INST;
22514664483SAtish Patra     }
22614664483SAtish Patra 
22714664483SAtish Patra     return RISCV_EXCP_NONE;
22814664483SAtish Patra }
229be470e59SAtish Patra 
mctr32(CPURISCVState * env,int csrno)230be470e59SAtish Patra static RISCVException mctr32(CPURISCVState *env, int csrno)
231be470e59SAtish Patra {
232be470e59SAtish Patra     if (riscv_cpu_mxl(env) != MXL_RV32) {
233be470e59SAtish Patra         return RISCV_EXCP_ILLEGAL_INST;
234be470e59SAtish Patra     }
235be470e59SAtish Patra 
236be470e59SAtish Patra     return mctr(env, csrno);
237be470e59SAtish Patra }
238b54a84c1SKaiwen Xue 
sscofpmf(CPURISCVState * env,int csrno)239b54a84c1SKaiwen Xue static RISCVException sscofpmf(CPURISCVState *env, int csrno)
240b54a84c1SKaiwen Xue {
241b54a84c1SKaiwen Xue     if (!riscv_cpu_cfg(env)->ext_sscofpmf) {
242b54a84c1SKaiwen Xue         return RISCV_EXCP_ILLEGAL_INST;
243b54a84c1SKaiwen Xue     }
244b54a84c1SKaiwen Xue 
245b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
246b54a84c1SKaiwen Xue }
247b54a84c1SKaiwen Xue 
sscofpmf_32(CPURISCVState * env,int csrno)248b54a84c1SKaiwen Xue static RISCVException sscofpmf_32(CPURISCVState *env, int csrno)
249b54a84c1SKaiwen Xue {
250b54a84c1SKaiwen Xue     if (riscv_cpu_mxl(env) != MXL_RV32) {
251b54a84c1SKaiwen Xue         return RISCV_EXCP_ILLEGAL_INST;
252b54a84c1SKaiwen Xue     }
253b54a84c1SKaiwen Xue 
254b54a84c1SKaiwen Xue     return sscofpmf(env, csrno);
255b54a84c1SKaiwen Xue }
2560e62f92eSAlistair Francis 
smcntrpmf(CPURISCVState * env,int csrno)257a88365c1SMichael Clark static RISCVException smcntrpmf(CPURISCVState *env, int csrno)
2580e62f92eSAlistair Francis {
259a88365c1SMichael Clark     if (!riscv_cpu_cfg(env)->ext_smcntrpmf) {
260a88365c1SMichael Clark         return RISCV_EXCP_ILLEGAL_INST;
2610e62f92eSAlistair Francis     }
2628987cdc4SAlistair Francis 
263db23e5d9SRichard Henderson     return RISCV_EXCP_NONE;
2640e62f92eSAlistair Francis }
2658987cdc4SAlistair Francis 
smcntrpmf_32(CPURISCVState * env,int csrno)2668987cdc4SAlistair Francis static RISCVException smcntrpmf_32(CPURISCVState *env, int csrno)
2678987cdc4SAlistair Francis {
2688987cdc4SAlistair Francis     if (riscv_cpu_mxl(env) != MXL_RV32) {
2698987cdc4SAlistair Francis         return RISCV_EXCP_ILLEGAL_INST;
2708987cdc4SAlistair Francis     }
271a5cb044cSLIU Zhiwei 
272d0237b4dSAnup Patel     return smcntrpmf(env, csrno);
27301af27e3SDaniel Henrique Barboza }
274d0237b4dSAnup Patel 
any(CPURISCVState * env,int csrno)275d0237b4dSAnup Patel static RISCVException any(CPURISCVState *env, int csrno)
276d0237b4dSAnup Patel {
277d0237b4dSAnup Patel     return RISCV_EXCP_NONE;
278d0237b4dSAnup Patel }
279d0237b4dSAnup Patel 
any32(CPURISCVState * env,int csrno)280a5cb044cSLIU Zhiwei static RISCVException any32(CPURISCVState *env, int csrno)
281d028ac75SAnup Patel {
28201af27e3SDaniel Henrique Barboza     if (riscv_cpu_mxl(env) != MXL_RV32) {
283d028ac75SAnup Patel         return RISCV_EXCP_ILLEGAL_INST;
284d028ac75SAnup Patel     }
285d028ac75SAnup Patel 
286d028ac75SAnup Patel     return any(env, csrno);
287d028ac75SAnup Patel 
288d028ac75SAnup Patel }
2890e62f92eSAlistair Francis 
aia_any(CPURISCVState * env,int csrno)290a88365c1SMichael Clark static RISCVException aia_any(CPURISCVState *env, int csrno)
2910e62f92eSAlistair Francis {
2920e62f92eSAlistair Francis     if (!riscv_cpu_cfg(env)->ext_smaia) {
293a88365c1SMichael Clark         return RISCV_EXCP_ILLEGAL_INST;
294a88365c1SMichael Clark     }
2950e62f92eSAlistair Francis 
2960e62f92eSAlistair Francis     return any(env, csrno);
2970e62f92eSAlistair Francis }
298a5cb044cSLIU Zhiwei 
aia_any32(CPURISCVState * env,int csrno)299d028ac75SAnup Patel static RISCVException aia_any32(CPURISCVState *env, int csrno)
300d028ac75SAnup Patel {
301d028ac75SAnup Patel     if (!riscv_cpu_cfg(env)->ext_smaia) {
302d028ac75SAnup Patel         return RISCV_EXCP_ILLEGAL_INST;
303d028ac75SAnup Patel     }
304d028ac75SAnup Patel 
305d028ac75SAnup Patel     return any32(env, csrno);
306d028ac75SAnup Patel }
307a5cb044cSLIU Zhiwei 
smode(CPURISCVState * env,int csrno)308c7de92b4SAnup Patel static RISCVException smode(CPURISCVState *env, int csrno)
30901af27e3SDaniel Henrique Barboza {
310c7de92b4SAnup Patel     if (riscv_has_ext(env, RVS)) {
311c7de92b4SAnup Patel         return RISCV_EXCP_NONE;
312c7de92b4SAnup Patel     }
313c7de92b4SAnup Patel 
314c7de92b4SAnup Patel     return RISCV_EXCP_ILLEGAL_INST;
315c7de92b4SAnup Patel }
316a5cb044cSLIU Zhiwei 
smode32(CPURISCVState * env,int csrno)317d028ac75SAnup Patel static RISCVException smode32(CPURISCVState *env, int csrno)
31801af27e3SDaniel Henrique Barboza {
319d028ac75SAnup Patel     if (riscv_cpu_mxl(env) != MXL_RV32) {
320d028ac75SAnup Patel         return RISCV_EXCP_ILLEGAL_INST;
321d028ac75SAnup Patel     }
322d028ac75SAnup Patel 
323d028ac75SAnup Patel     return smode(env, csrno);
324d028ac75SAnup Patel }
3250e62f92eSAlistair Francis 
aia_smode(CPURISCVState * env,int csrno)326ff2cc129SAlistair Francis static RISCVException aia_smode(CPURISCVState *env, int csrno)
32762a09b9bSWeiwei Li {
3280e62f92eSAlistair Francis     if (!riscv_cpu_cfg(env)->ext_ssaia) {
329ff2cc129SAlistair Francis         return RISCV_EXCP_ILLEGAL_INST;
330ff2cc129SAlistair Francis     }
3310e62f92eSAlistair Francis 
332ff2cc129SAlistair Francis     return smode(env, csrno);
333ff2cc129SAlistair Francis }
3340e62f92eSAlistair Francis 
aia_smode32(CPURISCVState * env,int csrno)3358987cdc4SAlistair Francis static RISCVException aia_smode32(CPURISCVState *env, int csrno)
336db23e5d9SRichard Henderson {
337d6f20dacSAlistair Francis     if (!riscv_cpu_cfg(env)->ext_ssaia) {
3388987cdc4SAlistair Francis         return RISCV_EXCP_ILLEGAL_INST;
3398987cdc4SAlistair Francis     }
3408987cdc4SAlistair Francis 
3418987cdc4SAlistair Francis     return smode32(env, csrno);
3428987cdc4SAlistair Francis }
3438987cdc4SAlistair Francis 
hmode(CPURISCVState * env,int csrno)344c126f83cSWeiwei Li static RISCVException hmode(CPURISCVState *env, int csrno)
345c126f83cSWeiwei Li {
346c126f83cSWeiwei Li     if (riscv_has_ext(env, RVH)) {
347c126f83cSWeiwei Li         return RISCV_EXCP_NONE;
348c126f83cSWeiwei Li     }
349c126f83cSWeiwei Li 
350c126f83cSWeiwei Li     return RISCV_EXCP_ILLEGAL_INST;
351c126f83cSWeiwei Li }
352c126f83cSWeiwei Li 
hmode32(CPURISCVState * env,int csrno)353c126f83cSWeiwei Li static RISCVException hmode32(CPURISCVState *env, int csrno)
354c126f83cSWeiwei Li {
355c126f83cSWeiwei Li     if (riscv_cpu_mxl(env) != MXL_RV32) {
356c126f83cSWeiwei Li         return RISCV_EXCP_ILLEGAL_INST;
357c126f83cSWeiwei Li     }
358c126f83cSWeiwei Li 
359c126f83cSWeiwei Li     return hmode(env, csrno);
360c126f83cSWeiwei Li 
361c126f83cSWeiwei Li }
3623bee0e40SMayuresh Chitale 
umode(CPURISCVState * env,int csrno)3633bee0e40SMayuresh Chitale static RISCVException umode(CPURISCVState *env, int csrno)
3649c33e08bSWeiwei Li {
3653bee0e40SMayuresh Chitale     if (riscv_has_ext(env, RVU)) {
3663bee0e40SMayuresh Chitale         return RISCV_EXCP_NONE;
3673bee0e40SMayuresh Chitale     }
3683bee0e40SMayuresh Chitale 
3693bee0e40SMayuresh Chitale     return RISCV_EXCP_ILLEGAL_INST;
3703bee0e40SMayuresh Chitale }
3713bee0e40SMayuresh Chitale 
umode32(CPURISCVState * env,int csrno)3723bee0e40SMayuresh Chitale static RISCVException umode32(CPURISCVState *env, int csrno)
3739c33e08bSWeiwei Li {
3743bee0e40SMayuresh Chitale     if (riscv_cpu_mxl(env) != MXL_RV32) {
3753bee0e40SMayuresh Chitale         return RISCV_EXCP_ILLEGAL_INST;
3763bee0e40SMayuresh Chitale     }
3770308fc62SBin Meng 
3780308fc62SBin Meng     return umode(env, csrno);
3790308fc62SBin Meng }
3800308fc62SBin Meng 
mstateen(CPURISCVState * env,int csrno)3810308fc62SBin Meng static RISCVException mstateen(CPURISCVState *env, int csrno)
3820308fc62SBin Meng {
3830308fc62SBin Meng     if (!riscv_cpu_cfg(env)->ext_smstateen) {
3840308fc62SBin Meng         return RISCV_EXCP_ILLEGAL_INST;
3850308fc62SBin Meng     }
3863bee0e40SMayuresh Chitale 
3873bee0e40SMayuresh Chitale     return any(env, csrno);
3883bee0e40SMayuresh Chitale }
3893bee0e40SMayuresh Chitale 
hstateen_pred(CPURISCVState * env,int csrno,int base)3903bee0e40SMayuresh Chitale static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
3913bee0e40SMayuresh Chitale {
3920308fc62SBin Meng     if (!riscv_cpu_cfg(env)->ext_smstateen) {
3933bee0e40SMayuresh Chitale         return RISCV_EXCP_ILLEGAL_INST;
3943bee0e40SMayuresh Chitale     }
3953bee0e40SMayuresh Chitale 
3963bee0e40SMayuresh Chitale     RISCVException ret = hmode(env, csrno);
3973bee0e40SMayuresh Chitale     if (ret != RISCV_EXCP_NONE) {
3983bee0e40SMayuresh Chitale         return ret;
3993bee0e40SMayuresh Chitale     }
4003bee0e40SMayuresh Chitale 
4013bee0e40SMayuresh Chitale     if (env->debugger) {
4023bee0e40SMayuresh Chitale         return RISCV_EXCP_NONE;
4033bee0e40SMayuresh Chitale     }
4043bee0e40SMayuresh Chitale 
4053bee0e40SMayuresh Chitale     if (env->priv < PRV_M) {
4063bee0e40SMayuresh Chitale         if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
40738256529SWeiwei Li             return RISCV_EXCP_ILLEGAL_INST;
4083bee0e40SMayuresh Chitale         }
4093bee0e40SMayuresh Chitale     }
410a9a4e39fSDaniel Henrique Barboza 
4113bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
4123bee0e40SMayuresh Chitale }
4133bee0e40SMayuresh Chitale 
hstateen(CPURISCVState * env,int csrno)4140308fc62SBin Meng static RISCVException hstateen(CPURISCVState *env, int csrno)
4150308fc62SBin Meng {
4160308fc62SBin Meng     return hstateen_pred(env, csrno, CSR_HSTATEEN0);
4170308fc62SBin Meng }
4180308fc62SBin Meng 
hstateenh(CPURISCVState * env,int csrno)4190308fc62SBin Meng static RISCVException hstateenh(CPURISCVState *env, int csrno)
4200308fc62SBin Meng {
4210308fc62SBin Meng     return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
4220308fc62SBin Meng }
4233bee0e40SMayuresh Chitale 
sstateen(CPURISCVState * env,int csrno)4243bee0e40SMayuresh Chitale static RISCVException sstateen(CPURISCVState *env, int csrno)
4253bee0e40SMayuresh Chitale {
4263bee0e40SMayuresh Chitale     bool virt = env->virt_enabled;
4273bee0e40SMayuresh Chitale     int index = csrno - CSR_SSTATEEN0;
4283bee0e40SMayuresh Chitale 
4293bee0e40SMayuresh Chitale     if (!riscv_cpu_cfg(env)->ext_smstateen) {
4303bee0e40SMayuresh Chitale         return RISCV_EXCP_ILLEGAL_INST;
4313bee0e40SMayuresh Chitale     }
4323bee0e40SMayuresh Chitale 
4333bee0e40SMayuresh Chitale     RISCVException ret = smode(env, csrno);
4343bee0e40SMayuresh Chitale     if (ret != RISCV_EXCP_NONE) {
4350308fc62SBin Meng         return ret;
4363bee0e40SMayuresh Chitale     }
4373bee0e40SMayuresh Chitale 
438fb5bd4dcSBin Meng     if (env->debugger) {
439fb5bd4dcSBin Meng         return RISCV_EXCP_NONE;
440fb5bd4dcSBin Meng     }
441fb5bd4dcSBin Meng 
4429c33e08bSWeiwei Li     if (env->priv < PRV_M) {
443fb5bd4dcSBin Meng         if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
444fb5bd4dcSBin Meng             return RISCV_EXCP_ILLEGAL_INST;
445fb5bd4dcSBin Meng         }
446fb5bd4dcSBin Meng 
447fb5bd4dcSBin Meng         if (virt) {
448fb5bd4dcSBin Meng             if (!(env->hstateen[index] & SMSTATEEN_STATEEN)) {
449fb5bd4dcSBin Meng                 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
450fb5bd4dcSBin Meng             }
451fb5bd4dcSBin Meng         }
452fb5bd4dcSBin Meng     }
453fb5bd4dcSBin Meng 
454fb5bd4dcSBin Meng     return RISCV_EXCP_NONE;
455fb5bd4dcSBin Meng }
456fb5bd4dcSBin Meng 
sstc(CPURISCVState * env,int csrno)457fb5bd4dcSBin Meng static RISCVException sstc(CPURISCVState *env, int csrno)
458fb5bd4dcSBin Meng {
459fb5bd4dcSBin Meng     bool hmode_check = false;
460fb5bd4dcSBin Meng 
461fb5bd4dcSBin Meng     if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn) {
462fb5bd4dcSBin Meng         return RISCV_EXCP_ILLEGAL_INST;
463fb5bd4dcSBin Meng     }
464fb5bd4dcSBin Meng 
465fb5bd4dcSBin Meng     if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
466fb5bd4dcSBin Meng         hmode_check = true;
467fb5bd4dcSBin Meng     }
468fb5bd4dcSBin Meng 
469fb5bd4dcSBin Meng     RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
470fb5bd4dcSBin Meng     if (ret != RISCV_EXCP_NONE) {
471fb5bd4dcSBin Meng         return ret;
47238256529SWeiwei Li     }
473fb5bd4dcSBin Meng 
474fb5bd4dcSBin Meng     if (env->debugger) {
475fb5bd4dcSBin Meng         return RISCV_EXCP_NONE;
476fb5bd4dcSBin Meng     }
477fb5bd4dcSBin Meng 
478fb5bd4dcSBin Meng     if (env->priv == PRV_M) {
479fb5bd4dcSBin Meng         return RISCV_EXCP_NONE;
480fb5bd4dcSBin Meng     }
481fb5bd4dcSBin Meng 
482fb5bd4dcSBin Meng     /*
483fb5bd4dcSBin Meng      * No need of separate function for rv32 as menvcfg stores both menvcfg
484fb5bd4dcSBin Meng      * menvcfgh for RV32.
485fb5bd4dcSBin Meng      */
486fb5bd4dcSBin Meng     if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
487fb5bd4dcSBin Meng           get_field(env->menvcfg, MENVCFG_STCE))) {
488fb5bd4dcSBin Meng         return RISCV_EXCP_ILLEGAL_INST;
489a88365c1SMichael Clark     }
490a88365c1SMichael Clark 
491d6db7c97SYi Chen     if (env->virt_enabled) {
492d6db7c97SYi Chen         if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
493d6db7c97SYi Chen               get_field(env->henvcfg, HENVCFG_STCE))) {
494d6db7c97SYi Chen             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
495d6db7c97SYi Chen         }
496d6db7c97SYi Chen     }
497d6db7c97SYi Chen 
498d6db7c97SYi Chen     return RISCV_EXCP_NONE;
499d6db7c97SYi Chen }
500d6db7c97SYi Chen 
sstc_32(CPURISCVState * env,int csrno)501d6db7c97SYi Chen static RISCVException sstc_32(CPURISCVState *env, int csrno)
502d6db7c97SYi Chen {
503d6db7c97SYi Chen     if (riscv_cpu_mxl(env) != MXL_RV32) {
504d6db7c97SYi Chen         return RISCV_EXCP_ILLEGAL_INST;
505d6db7c97SYi Chen     }
506d6db7c97SYi Chen 
507d6db7c97SYi Chen     return sstc(env, csrno);
508d6db7c97SYi Chen }
509d6db7c97SYi Chen 
satp(CPURISCVState * env,int csrno)510d6db7c97SYi Chen static RISCVException satp(CPURISCVState *env, int csrno)
511d6db7c97SYi Chen {
512d6db7c97SYi Chen     if (env->priv == PRV_S && !env->virt_enabled &&
513d6db7c97SYi Chen         get_field(env->mstatus, MSTATUS_TVM)) {
514d6db7c97SYi Chen         return RISCV_EXCP_ILLEGAL_INST;
5154bbe8033SAlexey Baturo     }
5164bbe8033SAlexey Baturo     if (env->priv == PRV_S && env->virt_enabled &&
5174bbe8033SAlexey Baturo         get_field(env->hstatus, HSTATUS_VTVM)) {
5184bbe8033SAlexey Baturo         return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
5194bbe8033SAlexey Baturo     }
5204bbe8033SAlexey Baturo 
5214bbe8033SAlexey Baturo     return smode(env, csrno);
5224bbe8033SAlexey Baturo }
5234bbe8033SAlexey Baturo 
hgatp(CPURISCVState * env,int csrno)5244bbe8033SAlexey Baturo static RISCVException hgatp(CPURISCVState *env, int csrno)
525a5cb044cSLIU Zhiwei {
5262b602398SAnup Patel     if (env->priv == PRV_S && !env->virt_enabled &&
52701af27e3SDaniel Henrique Barboza         get_field(env->mstatus, MSTATUS_TVM)) {
5282b602398SAnup Patel         return RISCV_EXCP_ILLEGAL_INST;
5292b602398SAnup Patel     }
5302b602398SAnup Patel 
5312b602398SAnup Patel     return hmode(env, csrno);
5322b602398SAnup Patel }
5332b602398SAnup Patel 
534a5cb044cSLIU Zhiwei /* Checks if PointerMasking registers could be accessed */
pointer_masking(CPURISCVState * env,int csrno)535d028ac75SAnup Patel static RISCVException pointer_masking(CPURISCVState *env, int csrno)
53601af27e3SDaniel Henrique Barboza {
537d028ac75SAnup Patel     /* Check if j-ext is present */
538d028ac75SAnup Patel     if (riscv_has_ext(env, RVJ)) {
539d028ac75SAnup Patel         return RISCV_EXCP_NONE;
540d028ac75SAnup Patel     }
541d028ac75SAnup Patel     return RISCV_EXCP_ILLEGAL_INST;
542d028ac75SAnup Patel }
5430e62f92eSAlistair Francis 
aia_hmode(CPURISCVState * env,int csrno)544a88365c1SMichael Clark static RISCVException aia_hmode(CPURISCVState *env, int csrno)
5453fe40ef5SDaniel Henrique Barboza {
54604733fb0SBin Meng     if (!riscv_cpu_cfg(env)->ext_ssaia) {
54704733fb0SBin Meng         return RISCV_EXCP_ILLEGAL_INST;
54804733fb0SBin Meng      }
54904733fb0SBin Meng 
55004733fb0SBin Meng      return hmode(env, csrno);
55104733fb0SBin Meng }
55204733fb0SBin Meng 
aia_hmode32(CPURISCVState * env,int csrno)55304733fb0SBin Meng static RISCVException aia_hmode32(CPURISCVState *env, int csrno)
55404733fb0SBin Meng {
5550e62f92eSAlistair Francis     if (!riscv_cpu_cfg(env)->ext_ssaia) {
5560e62f92eSAlistair Francis         return RISCV_EXCP_ILLEGAL_INST;
5570e62f92eSAlistair Francis     }
5580e62f92eSAlistair Francis 
559a88365c1SMichael Clark     return hmode32(env, csrno);
5602582a95cSHou Weiying }
5612f32dcabSHeinrich Schuchardt 
pmp(CPURISCVState * env,int csrno)5622582a95cSHou Weiying static RISCVException pmp(CPURISCVState *env, int csrno)
563095fe72aSHimanshu Chauhan {
5642582a95cSHou Weiying     if (riscv_cpu_cfg(env)->pmp) {
5652582a95cSHou Weiying         if (csrno <= CSR_PMPCFG3) {
5662f32dcabSHeinrich Schuchardt             uint32_t reg_index = csrno - CSR_PMPCFG0;
5672f32dcabSHeinrich Schuchardt 
5682f32dcabSHeinrich Schuchardt             /* TODO: RV128 restriction check */
5692582a95cSHou Weiying             if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
5702582a95cSHou Weiying                 return RISCV_EXCP_ILLEGAL_INST;
5712582a95cSHou Weiying             }
572b6092544SBin Meng         }
573b6092544SBin Meng 
574b6092544SBin Meng         return RISCV_EXCP_NONE;
575cdfb2905SDaniel Henrique Barboza     }
576b6092544SBin Meng 
577b6092544SBin Meng     return RISCV_EXCP_ILLEGAL_INST;
578b6092544SBin Meng }
579b6092544SBin Meng 
have_mseccfg(CPURISCVState * env,int csrno)580b6092544SBin Meng static RISCVException have_mseccfg(CPURISCVState *env, int csrno)
581a88365c1SMichael Clark {
582a88365c1SMichael Clark     if (riscv_cpu_cfg(env)->ext_smepmp) {
58377442380SWeiwei Li         return RISCV_EXCP_NONE;
58477442380SWeiwei Li     }
58501af27e3SDaniel Henrique Barboza     if (riscv_cpu_cfg(env)->ext_zkr) {
58677442380SWeiwei Li         return RISCV_EXCP_NONE;
58777442380SWeiwei Li     }
58877442380SWeiwei Li 
58977442380SWeiwei Li     return RISCV_EXCP_ILLEGAL_INST;
590ddb10742SBin Meng }
591ddb10742SBin Meng 
debug(CPURISCVState * env,int csrno)592ddb10742SBin Meng static RISCVException debug(CPURISCVState *env, int csrno)
593ddb10742SBin Meng {
59477442380SWeiwei Li     if (riscv_cpu_cfg(env)->debug) {
59577442380SWeiwei Li         return RISCV_EXCP_NONE;
59677442380SWeiwei Li     }
59777442380SWeiwei Li 
59877442380SWeiwei Li     return RISCV_EXCP_ILLEGAL_INST;
59977442380SWeiwei Li }
60077442380SWeiwei Li #endif
60177442380SWeiwei Li 
seed(CPURISCVState * env,int csrno)60277442380SWeiwei Li static RISCVException seed(CPURISCVState *env, int csrno)
60377442380SWeiwei Li {
60477442380SWeiwei Li     if (!riscv_cpu_cfg(env)->ext_zkr) {
60538256529SWeiwei Li         return RISCV_EXCP_ILLEGAL_INST;
60677442380SWeiwei Li     }
60777442380SWeiwei Li 
60877442380SWeiwei Li #if !defined(CONFIG_USER_ONLY)
60977442380SWeiwei Li     if (env->debugger) {
61077442380SWeiwei Li         return RISCV_EXCP_NONE;
61177442380SWeiwei Li     }
61277442380SWeiwei Li 
61377442380SWeiwei Li     /*
61477442380SWeiwei Li      * With a CSR read-write instruction:
61577442380SWeiwei Li      * 1) The seed CSR is always available in machine mode as normal.
61677442380SWeiwei Li      * 2) Attempted access to seed from virtual modes VS and VU always raises
61777442380SWeiwei Li      * an exception(virtual instruction exception only if mseccfg.sseed=1).
61877442380SWeiwei Li      * 3) Without the corresponding access control bit set to 1, any attempted
61977442380SWeiwei Li      * access to seed from U, S or HS modes will raise an illegal instruction
62077442380SWeiwei Li      * exception.
62177442380SWeiwei Li      */
62277442380SWeiwei Li     if (env->priv == PRV_M) {
62377442380SWeiwei Li         return RISCV_EXCP_NONE;
62477442380SWeiwei Li     } else if (env->virt_enabled) {
625c7b95171SMichael Clark         if (env->mseccfg & MSECCFG_SSEED) {
626605def6eSAlistair Francis             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
627605def6eSAlistair Francis         } else {
628c7b95171SMichael Clark             return RISCV_EXCP_ILLEGAL_INST;
629fb738839SMichael Clark         }
630605def6eSAlistair Francis     } else {
631c7b95171SMichael Clark         if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) {
632c7b95171SMichael Clark             return RISCV_EXCP_NONE;
633605def6eSAlistair Francis         } else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) {
634605def6eSAlistair Francis             return RISCV_EXCP_NONE;
635c7b95171SMichael Clark         } else {
636c7b95171SMichael Clark             return RISCV_EXCP_ILLEGAL_INST;
637c163b3baSWeiwei Li         }
638c7b95171SMichael Clark     }
639c163b3baSWeiwei Li #else
640c7b95171SMichael Clark     return RISCV_EXCP_NONE;
641fb738839SMichael Clark #endif
642605def6eSAlistair Francis }
643c7b95171SMichael Clark 
644c7b95171SMichael Clark /* zicfiss CSR_SSP read and write */
read_ssp(CPURISCVState * env,int csrno,target_ulong * val)645605def6eSAlistair Francis static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
646605def6eSAlistair Francis {
647c7b95171SMichael Clark     *val = env->ssp;
648c7b95171SMichael Clark     return RISCV_EXCP_NONE;
649605def6eSAlistair Francis }
650c7b95171SMichael Clark 
write_ssp(CPURISCVState * env,int csrno,target_ulong val)651c7b95171SMichael Clark static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
652605def6eSAlistair Francis {
653605def6eSAlistair Francis     env->ssp = val;
654c7b95171SMichael Clark     return RISCV_EXCP_NONE;
655c7b95171SMichael Clark }
656c163b3baSWeiwei Li 
657c7b95171SMichael Clark /* User Floating-Point CSRs */
read_fflags(CPURISCVState * env,int csrno,target_ulong * val)658c163b3baSWeiwei Li static RISCVException read_fflags(CPURISCVState *env, int csrno,
659c7b95171SMichael Clark                                   target_ulong *val)
660c7b95171SMichael Clark {
661605def6eSAlistair Francis     *val = riscv_cpu_get_fflags(env);
662c7b95171SMichael Clark     return RISCV_EXCP_NONE;
663c7b95171SMichael Clark }
664605def6eSAlistair Francis 
write_fflags(CPURISCVState * env,int csrno,target_ulong val)665605def6eSAlistair Francis static RISCVException write_fflags(CPURISCVState *env, int csrno,
666c7b95171SMichael Clark                                    target_ulong val)
667fb738839SMichael Clark {
668c7b95171SMichael Clark #if !defined(CONFIG_USER_ONLY)
669605def6eSAlistair Francis     if (riscv_has_ext(env, RVF)) {
670c7b95171SMichael Clark         env->mstatus |= MSTATUS_FS;
671c7b95171SMichael Clark     }
672605def6eSAlistair Francis #endif
673605def6eSAlistair Francis     riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
674c7b95171SMichael Clark     return RISCV_EXCP_NONE;
675c7b95171SMichael Clark }
676c163b3baSWeiwei Li 
read_frm(CPURISCVState * env,int csrno,target_ulong * val)677c7b95171SMichael Clark static RISCVException read_frm(CPURISCVState *env, int csrno,
678c163b3baSWeiwei Li                                target_ulong *val)
679c7b95171SMichael Clark {
680c7b95171SMichael Clark     *val = env->frm;
681fb738839SMichael Clark     return RISCV_EXCP_NONE;
682605def6eSAlistair Francis }
683c7b95171SMichael Clark 
write_frm(CPURISCVState * env,int csrno,target_ulong val)684c7b95171SMichael Clark static RISCVException write_frm(CPURISCVState *env, int csrno,
685605def6eSAlistair Francis                                 target_ulong val)
686605def6eSAlistair Francis {
6878e3a1f18SLIU Zhiwei #if !defined(CONFIG_USER_ONLY)
688d96a271aSLIU Zhiwei     if (riscv_has_ext(env, RVF)) {
689d96a271aSLIU Zhiwei         env->mstatus |= MSTATUS_FS;
690d96a271aSLIU Zhiwei     }
691d96a271aSLIU Zhiwei #endif
692d96a271aSLIU Zhiwei     env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
693d96a271aSLIU Zhiwei     return RISCV_EXCP_NONE;
694d96a271aSLIU Zhiwei }
695d96a271aSLIU Zhiwei 
read_fcsr(CPURISCVState * env,int csrno,target_ulong * val)696d96a271aSLIU Zhiwei static RISCVException read_fcsr(CPURISCVState *env, int csrno,
697d96a271aSLIU Zhiwei                                 target_ulong *val)
698d96a271aSLIU Zhiwei {
699d96a271aSLIU Zhiwei     *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
700605def6eSAlistair Francis         | (env->frm << FSR_RD_SHIFT);
7018e3a1f18SLIU Zhiwei     return RISCV_EXCP_NONE;
7028e3a1f18SLIU Zhiwei }
703605def6eSAlistair Francis 
write_fcsr(CPURISCVState * env,int csrno,target_ulong val)704605def6eSAlistair Francis static RISCVException write_fcsr(CPURISCVState *env, int csrno,
7058e3a1f18SLIU Zhiwei                                  target_ulong val)
7068e3a1f18SLIU Zhiwei {
707605def6eSAlistair Francis #if !defined(CONFIG_USER_ONLY)
7088e3a1f18SLIU Zhiwei     if (riscv_has_ext(env, RVF)) {
7098e3a1f18SLIU Zhiwei         env->mstatus |= MSTATUS_FS;
710a5cb044cSLIU Zhiwei     }
711a5cb044cSLIU Zhiwei #endif
7122e565054SGreentime Hu     env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
71339b5efa5SDaniel Henrique Barboza     riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
7142e565054SGreentime Hu     return RISCV_EXCP_NONE;
7152e565054SGreentime Hu }
7162e565054SGreentime Hu 
read_vtype(CPURISCVState * env,int csrno,target_ulong * val)717605def6eSAlistair Francis static RISCVException read_vtype(CPURISCVState *env, int csrno,
718605def6eSAlistair Francis                                  target_ulong *val)
7198e3a1f18SLIU Zhiwei {
7208e3a1f18SLIU Zhiwei     uint64_t vill;
721605def6eSAlistair Francis     switch (env->xl) {
7228e3a1f18SLIU Zhiwei     case MXL_RV32:
7238e3a1f18SLIU Zhiwei         vill = (uint32_t)env->vill << 31;
724605def6eSAlistair Francis         break;
725605def6eSAlistair Francis     case MXL_RV64:
7268e3a1f18SLIU Zhiwei         vill = (uint64_t)env->vill << 63;
72761b4b69dSLIU Zhiwei         break;
72861b4b69dSLIU Zhiwei     default:
72961b4b69dSLIU Zhiwei         g_assert_not_reached();
7308e3a1f18SLIU Zhiwei     }
731605def6eSAlistair Francis     *val = (target_ulong)vill | env->vtype;
7328e3a1f18SLIU Zhiwei     return RISCV_EXCP_NONE;
7338e3a1f18SLIU Zhiwei }
734605def6eSAlistair Francis 
read_vl(CPURISCVState * env,int csrno,target_ulong * val)735605def6eSAlistair Francis static RISCVException read_vl(CPURISCVState *env, int csrno,
7368e3a1f18SLIU Zhiwei                               target_ulong *val)
737*646746a1SEvgenii Prokopiev {
738605def6eSAlistair Francis     *val = env->vl;
7398e3a1f18SLIU Zhiwei     return RISCV_EXCP_NONE;
7408e3a1f18SLIU Zhiwei }
741605def6eSAlistair Francis 
read_vlenb(CPURISCVState * env,int csrno,target_ulong * val)742605def6eSAlistair Francis static RISCVException read_vlenb(CPURISCVState *env, int csrno,
7438e3a1f18SLIU Zhiwei                                  target_ulong *val)
74461b4b69dSLIU Zhiwei {
74561b4b69dSLIU Zhiwei     *val = riscv_cpu_cfg(env)->vlenb;
74661b4b69dSLIU Zhiwei     return RISCV_EXCP_NONE;
747*646746a1SEvgenii Prokopiev }
748605def6eSAlistair Francis 
read_vxrm(CPURISCVState * env,int csrno,target_ulong * val)7498e3a1f18SLIU Zhiwei static RISCVException read_vxrm(CPURISCVState *env, int csrno,
7508e3a1f18SLIU Zhiwei                                 target_ulong *val)
751605def6eSAlistair Francis {
752605def6eSAlistair Francis     *val = env->vxrm;
7538e3a1f18SLIU Zhiwei     return RISCV_EXCP_NONE;
7548e3a1f18SLIU Zhiwei }
755605def6eSAlistair Francis 
write_vxrm(CPURISCVState * env,int csrno,target_ulong val)7568e3a1f18SLIU Zhiwei static RISCVException write_vxrm(CPURISCVState *env, int csrno,
7578e3a1f18SLIU Zhiwei                                  target_ulong val)
758605def6eSAlistair Francis {
759605def6eSAlistair Francis #if !defined(CONFIG_USER_ONLY)
7608e3a1f18SLIU Zhiwei     env->mstatus |= MSTATUS_VS;
76161b4b69dSLIU Zhiwei #endif
76261b4b69dSLIU Zhiwei     env->vxrm = val;
76361b4b69dSLIU Zhiwei     return RISCV_EXCP_NONE;
764f714361eSFrank Chang }
765f714361eSFrank Chang 
read_vxsat(CPURISCVState * env,int csrno,target_ulong * val)766f714361eSFrank Chang static RISCVException read_vxsat(CPURISCVState *env, int csrno,
767f714361eSFrank Chang                                  target_ulong *val)
76839b5efa5SDaniel Henrique Barboza {
769605def6eSAlistair Francis     *val = env->vxsat & BIT(0);
7708e3a1f18SLIU Zhiwei     return RISCV_EXCP_NONE;
7718e3a1f18SLIU Zhiwei }
772a5cb044cSLIU Zhiwei 
write_vxsat(CPURISCVState * env,int csrno,target_ulong val)773a5cb044cSLIU Zhiwei static RISCVException write_vxsat(CPURISCVState *env, int csrno,
7744594fa5aSLIU Zhiwei                                   target_ulong val)
7754594fa5aSLIU Zhiwei {
7764594fa5aSLIU Zhiwei #if !defined(CONFIG_USER_ONLY)
7774594fa5aSLIU Zhiwei     env->mstatus |= MSTATUS_VS;
7784594fa5aSLIU Zhiwei #endif
779a5cb044cSLIU Zhiwei     env->vxsat = val & BIT(0);
780a5cb044cSLIU Zhiwei     return RISCV_EXCP_NONE;
7814594fa5aSLIU Zhiwei }
7824594fa5aSLIU Zhiwei 
read_vstart(CPURISCVState * env,int csrno,target_ulong * val)7834594fa5aSLIU Zhiwei static RISCVException read_vstart(CPURISCVState *env, int csrno,
7844594fa5aSLIU Zhiwei                                   target_ulong *val)
7854594fa5aSLIU Zhiwei {
7864594fa5aSLIU Zhiwei     *val = env->vstart;
7874594fa5aSLIU Zhiwei     return RISCV_EXCP_NONE;
7884594fa5aSLIU Zhiwei }
7894594fa5aSLIU Zhiwei 
write_vstart(CPURISCVState * env,int csrno,target_ulong val)790b2d7a7c7SAtish Patra static RISCVException write_vstart(CPURISCVState *env, int csrno,
791c7b95171SMichael Clark                                    target_ulong val)
792b2d7a7c7SAtish Patra {
793c7b95171SMichael Clark #if !defined(CONFIG_USER_ONLY)
794b2d7a7c7SAtish Patra     env->mstatus |= MSTATUS_VS;
795b2d7a7c7SAtish Patra #endif
796c7b95171SMichael Clark     /*
7973780e337SAtish Patra      * The vstart CSR is defined to have only enough writable bits
798c7b95171SMichael Clark      * to hold the largest element index, i.e. lg2(VLEN) bits.
799c7b95171SMichael Clark      */
800605def6eSAlistair Francis     env->vstart = val & ~(~0ULL << ctzl(riscv_cpu_cfg(env)->vlenb << 3));
801605def6eSAlistair Francis     return RISCV_EXCP_NONE;
802c7b95171SMichael Clark }
803c7b95171SMichael Clark 
read_vcsr(CPURISCVState * env,int csrno,target_ulong * val)804605def6eSAlistair Francis static RISCVException read_vcsr(CPURISCVState *env, int csrno,
805c7b95171SMichael Clark                                 target_ulong *val)
806c7b95171SMichael Clark {
807605def6eSAlistair Francis     *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
808605def6eSAlistair Francis     return RISCV_EXCP_NONE;
809c7b95171SMichael Clark }
810c7b95171SMichael Clark 
write_vcsr(CPURISCVState * env,int csrno,target_ulong val)811605def6eSAlistair Francis static RISCVException write_vcsr(CPURISCVState *env, int csrno,
812c7b95171SMichael Clark                                  target_ulong val)
813c7b95171SMichael Clark {
814a5cb044cSLIU Zhiwei #if !defined(CONFIG_USER_ONLY)
815a5cb044cSLIU Zhiwei     env->mstatus |= MSTATUS_VS;
8163780e337SAtish Patra #endif
817b2d7a7c7SAtish Patra     env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
8183780e337SAtish Patra     env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
8193780e337SAtish Patra     return RISCV_EXCP_NONE;
8203780e337SAtish Patra }
821a5cb044cSLIU Zhiwei 
822a5cb044cSLIU Zhiwei #if defined(CONFIG_USER_ONLY)
8233780e337SAtish Patra /* User Timers and Counters */
get_ticks(bool shift)824b2d7a7c7SAtish Patra static target_ulong get_ticks(bool shift)
8253780e337SAtish Patra {
8263780e337SAtish Patra     int64_t val = cpu_get_host_ticks();
8273780e337SAtish Patra     target_ulong result = shift ? val >> 32 : val;
828c7b95171SMichael Clark 
829c7b95171SMichael Clark     return result;
830b54a84c1SKaiwen Xue }
831b54a84c1SKaiwen Xue 
read_time(CPURISCVState * env,int csrno,target_ulong * val)832b54a84c1SKaiwen Xue static RISCVException read_time(CPURISCVState *env, int csrno,
833b54a84c1SKaiwen Xue                                 target_ulong *val)
834b54a84c1SKaiwen Xue {
835b54a84c1SKaiwen Xue     *val = cpu_get_host_ticks();
836b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
837b54a84c1SKaiwen Xue }
838b54a84c1SKaiwen Xue 
read_timeh(CPURISCVState * env,int csrno,target_ulong * val)839b54a84c1SKaiwen Xue static RISCVException read_timeh(CPURISCVState *env, int csrno,
840b54a84c1SKaiwen Xue                                  target_ulong *val)
841b54a84c1SKaiwen Xue {
842b54a84c1SKaiwen Xue     *val = cpu_get_host_ticks() >> 32;
843b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
844b54a84c1SKaiwen Xue }
845b54a84c1SKaiwen Xue 
read_hpmcounter(CPURISCVState * env,int csrno,target_ulong * val)846b54a84c1SKaiwen Xue static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
847b54a84c1SKaiwen Xue                                       target_ulong *val)
848b54a84c1SKaiwen Xue {
849b54a84c1SKaiwen Xue     *val = get_ticks(false);
850b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
851b54a84c1SKaiwen Xue }
852b54a84c1SKaiwen Xue 
read_hpmcounterh(CPURISCVState * env,int csrno,target_ulong * val)853b54a84c1SKaiwen Xue static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
854b54a84c1SKaiwen Xue                                        target_ulong *val)
855b54a84c1SKaiwen Xue {
856b54a84c1SKaiwen Xue     *val = get_ticks(true);
857b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
858b54a84c1SKaiwen Xue }
859b54a84c1SKaiwen Xue 
860b54a84c1SKaiwen Xue #else /* CONFIG_USER_ONLY */
861b54a84c1SKaiwen Xue 
read_mcyclecfg(CPURISCVState * env,int csrno,target_ulong * val)862b54a84c1SKaiwen Xue static RISCVException read_mcyclecfg(CPURISCVState *env, int csrno,
863b54a84c1SKaiwen Xue                                      target_ulong *val)
864b54a84c1SKaiwen Xue {
865b54a84c1SKaiwen Xue     *val = env->mcyclecfg;
866b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
867b54a84c1SKaiwen Xue }
868b54a84c1SKaiwen Xue 
write_mcyclecfg(CPURISCVState * env,int csrno,target_ulong val)869b54a84c1SKaiwen Xue static RISCVException write_mcyclecfg(CPURISCVState *env, int csrno,
870b54a84c1SKaiwen Xue                                       target_ulong val)
871b54a84c1SKaiwen Xue {
872b54a84c1SKaiwen Xue     uint64_t inh_avail_mask;
873b54a84c1SKaiwen Xue 
874b54a84c1SKaiwen Xue     if (riscv_cpu_mxl(env) == MXL_RV32) {
875b54a84c1SKaiwen Xue         env->mcyclecfg = val;
876b54a84c1SKaiwen Xue     } else {
877b54a84c1SKaiwen Xue         /* Set xINH fields if priv mode supported */
878b54a84c1SKaiwen Xue         inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MCYCLECFG_BIT_MINH;
879b54a84c1SKaiwen Xue         inh_avail_mask |= riscv_has_ext(env, RVU) ? MCYCLECFG_BIT_UINH : 0;
880b54a84c1SKaiwen Xue         inh_avail_mask |= riscv_has_ext(env, RVS) ? MCYCLECFG_BIT_SINH : 0;
881b54a84c1SKaiwen Xue         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
882b54a84c1SKaiwen Xue                            riscv_has_ext(env, RVU)) ? MCYCLECFG_BIT_VUINH : 0;
883b54a84c1SKaiwen Xue         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
884b54a84c1SKaiwen Xue                            riscv_has_ext(env, RVS)) ? MCYCLECFG_BIT_VSINH : 0;
885b54a84c1SKaiwen Xue         env->mcyclecfg = val & inh_avail_mask;
886b54a84c1SKaiwen Xue     }
887b54a84c1SKaiwen Xue 
888b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
889b54a84c1SKaiwen Xue }
890b54a84c1SKaiwen Xue 
read_mcyclecfgh(CPURISCVState * env,int csrno,target_ulong * val)891b54a84c1SKaiwen Xue static RISCVException read_mcyclecfgh(CPURISCVState *env, int csrno,
892b54a84c1SKaiwen Xue                                       target_ulong *val)
893b54a84c1SKaiwen Xue {
894b54a84c1SKaiwen Xue     *val = env->mcyclecfgh;
895b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
896b54a84c1SKaiwen Xue }
897b54a84c1SKaiwen Xue 
write_mcyclecfgh(CPURISCVState * env,int csrno,target_ulong val)898b54a84c1SKaiwen Xue static RISCVException write_mcyclecfgh(CPURISCVState *env, int csrno,
899b54a84c1SKaiwen Xue                                        target_ulong val)
900b54a84c1SKaiwen Xue {
901b54a84c1SKaiwen Xue     target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
902b54a84c1SKaiwen Xue                                                  MCYCLECFGH_BIT_MINH);
903b54a84c1SKaiwen Xue 
904b54a84c1SKaiwen Xue     /* Set xINH fields if priv mode supported */
905b54a84c1SKaiwen Xue     inh_avail_mask |= riscv_has_ext(env, RVU) ? MCYCLECFGH_BIT_UINH : 0;
906b54a84c1SKaiwen Xue     inh_avail_mask |= riscv_has_ext(env, RVS) ? MCYCLECFGH_BIT_SINH : 0;
907b54a84c1SKaiwen Xue     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
908b54a84c1SKaiwen Xue                        riscv_has_ext(env, RVU)) ? MCYCLECFGH_BIT_VUINH : 0;
909b54a84c1SKaiwen Xue     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
910b54a84c1SKaiwen Xue                        riscv_has_ext(env, RVS)) ? MCYCLECFGH_BIT_VSINH : 0;
911b54a84c1SKaiwen Xue 
912b54a84c1SKaiwen Xue     env->mcyclecfgh = val & inh_avail_mask;
913b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
914b54a84c1SKaiwen Xue }
915b54a84c1SKaiwen Xue 
read_minstretcfg(CPURISCVState * env,int csrno,target_ulong * val)916b54a84c1SKaiwen Xue static RISCVException read_minstretcfg(CPURISCVState *env, int csrno,
917b54a84c1SKaiwen Xue                                        target_ulong *val)
918b54a84c1SKaiwen Xue {
919b54a84c1SKaiwen Xue     *val = env->minstretcfg;
920b54a84c1SKaiwen Xue     return RISCV_EXCP_NONE;
921b54a84c1SKaiwen Xue }
922b54a84c1SKaiwen Xue 
write_minstretcfg(CPURISCVState * env,int csrno,target_ulong val)923b54a84c1SKaiwen Xue static RISCVException write_minstretcfg(CPURISCVState *env, int csrno,
924b54a84c1SKaiwen Xue                                         target_ulong val)
925b54a84c1SKaiwen Xue {
926b54a84c1SKaiwen Xue     uint64_t inh_avail_mask;
927b54a84c1SKaiwen Xue 
928b54a84c1SKaiwen Xue     if (riscv_cpu_mxl(env) == MXL_RV32) {
929b54a84c1SKaiwen Xue         env->minstretcfg = val;
930b54a84c1SKaiwen Xue     } else {
931b54a84c1SKaiwen Xue         inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MINSTRETCFG_BIT_MINH;
932b54a84c1SKaiwen Xue         inh_avail_mask |= riscv_has_ext(env, RVU) ? MINSTRETCFG_BIT_UINH : 0;
933b54a84c1SKaiwen Xue         inh_avail_mask |= riscv_has_ext(env, RVS) ? MINSTRETCFG_BIT_SINH : 0;
934b54a84c1SKaiwen Xue         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
935a5cb044cSLIU Zhiwei                            riscv_has_ext(env, RVU)) ? MINSTRETCFG_BIT_VUINH : 0;
936a5cb044cSLIU Zhiwei         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
937621f35bbSAtish Patra                            riscv_has_ext(env, RVS)) ? MINSTRETCFG_BIT_VSINH : 0;
9383780e337SAtish Patra         env->minstretcfg = val & inh_avail_mask;
939621f35bbSAtish Patra     }
940621f35bbSAtish Patra     return RISCV_EXCP_NONE;
941621f35bbSAtish Patra }
942621f35bbSAtish Patra 
read_minstretcfgh(CPURISCVState * env,int csrno,target_ulong * val)943621f35bbSAtish Patra static RISCVException read_minstretcfgh(CPURISCVState *env, int csrno,
944621f35bbSAtish Patra                                         target_ulong *val)
945a5cb044cSLIU Zhiwei {
946a5cb044cSLIU Zhiwei     *val = env->minstretcfgh;
947621f35bbSAtish Patra     return RISCV_EXCP_NONE;
9483780e337SAtish Patra }
94914664483SAtish Patra 
write_minstretcfgh(CPURISCVState * env,int csrno,target_ulong val)9503b31b7baSAtish Patra static RISCVException write_minstretcfgh(CPURISCVState *env, int csrno,
951621f35bbSAtish Patra                                          target_ulong val)
95214664483SAtish Patra {
9533b31b7baSAtish Patra     target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
95414664483SAtish Patra                                                  MINSTRETCFGH_BIT_MINH);
95514664483SAtish Patra 
9563b31b7baSAtish Patra     inh_avail_mask |= riscv_has_ext(env, RVU) ? MINSTRETCFGH_BIT_UINH : 0;
9573b31b7baSAtish Patra     inh_avail_mask |= riscv_has_ext(env, RVS) ? MINSTRETCFGH_BIT_SINH : 0;
9583b31b7baSAtish Patra     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
9593b31b7baSAtish Patra                        riscv_has_ext(env, RVU)) ? MINSTRETCFGH_BIT_VUINH : 0;
9603b31b7baSAtish Patra     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
9613b31b7baSAtish Patra                        riscv_has_ext(env, RVS)) ? MINSTRETCFGH_BIT_VSINH : 0;
9623b31b7baSAtish Patra 
9633b31b7baSAtish Patra     env->minstretcfgh = val & inh_avail_mask;
9643b31b7baSAtish Patra     return RISCV_EXCP_NONE;
9653b31b7baSAtish Patra }
96614664483SAtish Patra 
read_mhpmevent(CPURISCVState * env,int csrno,target_ulong * val)9673b31b7baSAtish Patra static RISCVException read_mhpmevent(CPURISCVState *env, int csrno,
96814664483SAtish Patra                                      target_ulong *val)
96914664483SAtish Patra {
97014664483SAtish Patra     int evt_index = csrno - CSR_MCOUNTINHIBIT;
97114664483SAtish Patra 
97214664483SAtish Patra     *val = env->mhpmevent_val[evt_index];
973a5cb044cSLIU Zhiwei 
974a5cb044cSLIU Zhiwei     return RISCV_EXCP_NONE;
97514664483SAtish Patra }
97614664483SAtish Patra 
write_mhpmevent(CPURISCVState * env,int csrno,target_ulong val)97714664483SAtish Patra static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
97814664483SAtish Patra                                       target_ulong val)
97914664483SAtish Patra {
98014664483SAtish Patra     int evt_index = csrno - CSR_MCOUNTINHIBIT;
98114664483SAtish Patra     uint64_t mhpmevt_val = val;
98214664483SAtish Patra     uint64_t inh_avail_mask;
983a5cb044cSLIU Zhiwei 
984a5cb044cSLIU Zhiwei     if (riscv_cpu_mxl(env) == MXL_RV32) {
98514664483SAtish Patra         env->mhpmevent_val[evt_index] = val;
98614664483SAtish Patra         mhpmevt_val = mhpmevt_val |
9873b31b7baSAtish Patra                       ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
98814664483SAtish Patra     } else {
9893b31b7baSAtish Patra         inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MHPMEVENT_BIT_MINH;
9903b31b7baSAtish Patra         inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENT_BIT_UINH : 0;
99114664483SAtish Patra         inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENT_BIT_SINH : 0;
9923b31b7baSAtish Patra         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
9933b31b7baSAtish Patra                            riscv_has_ext(env, RVU)) ? MHPMEVENT_BIT_VUINH : 0;
9943b31b7baSAtish Patra         inh_avail_mask |= (riscv_has_ext(env, RVH) &&
9953b31b7baSAtish Patra                            riscv_has_ext(env, RVS)) ? MHPMEVENT_BIT_VSINH : 0;
9963b31b7baSAtish Patra         mhpmevt_val = val & inh_avail_mask;
9973b31b7baSAtish Patra         env->mhpmevent_val[evt_index] = mhpmevt_val;
9983b31b7baSAtish Patra     }
9993b31b7baSAtish Patra 
100014664483SAtish Patra     riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
10013b31b7baSAtish Patra 
100214664483SAtish Patra     return RISCV_EXCP_NONE;
100314664483SAtish Patra }
100414664483SAtish Patra 
read_mhpmeventh(CPURISCVState * env,int csrno,target_ulong * val)1005621f35bbSAtish Patra static RISCVException read_mhpmeventh(CPURISCVState *env, int csrno,
1006621f35bbSAtish Patra                                       target_ulong *val)
1007621f35bbSAtish Patra {
1008b2d7a7c7SAtish Patra     int evt_index = csrno - CSR_MHPMEVENT3H + 3;
1009b2d7a7c7SAtish Patra 
1010b2d7a7c7SAtish Patra     *val = env->mhpmeventh_val[evt_index];
1011b2d7a7c7SAtish Patra 
1012b2d7a7c7SAtish Patra     return RISCV_EXCP_NONE;
1013b2d7a7c7SAtish Patra }
1014b2d7a7c7SAtish Patra 
write_mhpmeventh(CPURISCVState * env,int csrno,target_ulong val)1015b2d7a7c7SAtish Patra static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
1016b2d7a7c7SAtish Patra                                        target_ulong val)
1017b2d7a7c7SAtish Patra {
1018b2d7a7c7SAtish Patra     int evt_index = csrno - CSR_MHPMEVENT3H + 3;
1019b2d7a7c7SAtish Patra     uint64_t mhpmevth_val;
1020b2d7a7c7SAtish Patra     uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
1021b2d7a7c7SAtish Patra     target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
1022b2d7a7c7SAtish Patra                                                   MHPMEVENTH_BIT_MINH);
1023b2d7a7c7SAtish Patra 
1024b2d7a7c7SAtish Patra     inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENTH_BIT_UINH : 0;
1025b2d7a7c7SAtish Patra     inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENTH_BIT_SINH : 0;
1026b2d7a7c7SAtish Patra     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1027b2d7a7c7SAtish Patra                        riscv_has_ext(env, RVU)) ? MHPMEVENTH_BIT_VUINH : 0;
1028b2d7a7c7SAtish Patra     inh_avail_mask |= (riscv_has_ext(env, RVH) &&
1029b2d7a7c7SAtish Patra                        riscv_has_ext(env, RVS)) ? MHPMEVENTH_BIT_VSINH : 0;
1030b2d7a7c7SAtish Patra 
1031b2d7a7c7SAtish Patra     mhpmevth_val = val & inh_avail_mask;
1032b2d7a7c7SAtish Patra     mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
1033b2d7a7c7SAtish Patra     env->mhpmeventh_val[evt_index] = mhpmevth_val;
1034b2d7a7c7SAtish Patra 
1035b2d7a7c7SAtish Patra     riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
1036b2d7a7c7SAtish Patra 
1037b2d7a7c7SAtish Patra     return RISCV_EXCP_NONE;
1038b2d7a7c7SAtish Patra }
1039b2d7a7c7SAtish Patra 
riscv_pmu_ctr_get_fixed_counters_val(CPURISCVState * env,int counter_idx,bool upper_half)1040b2d7a7c7SAtish Patra static target_ulong riscv_pmu_ctr_get_fixed_counters_val(CPURISCVState *env,
1041b2d7a7c7SAtish Patra                                                          int counter_idx,
104274112400SRajnesh Kanwal                                                          bool upper_half)
104374112400SRajnesh Kanwal {
104474112400SRajnesh Kanwal     int inst = riscv_pmu_ctr_monitor_instructions(env, counter_idx);
1045b2d7a7c7SAtish Patra     uint64_t *counter_arr_virt = env->pmu_fixed_ctrs[inst].counter_virt;
1046b2d7a7c7SAtish Patra     uint64_t *counter_arr = env->pmu_fixed_ctrs[inst].counter;
1047b2d7a7c7SAtish Patra     target_ulong result = 0;
1048b2d7a7c7SAtish Patra     uint64_t curr_val = 0;
1049b2d7a7c7SAtish Patra     uint64_t cfg_val = 0;
1050b2d7a7c7SAtish Patra 
1051b2d7a7c7SAtish Patra     if (counter_idx == 0) {
1052b2d7a7c7SAtish Patra         cfg_val = upper_half ? ((uint64_t)env->mcyclecfgh << 32) :
1053b2d7a7c7SAtish Patra                   env->mcyclecfg;
1054b2d7a7c7SAtish Patra     } else if (counter_idx == 2) {
1055b2d7a7c7SAtish Patra         cfg_val = upper_half ? ((uint64_t)env->minstretcfgh << 32) :
1056b2d7a7c7SAtish Patra                   env->minstretcfg;
1057b2d7a7c7SAtish Patra     } else {
1058b2d7a7c7SAtish Patra         cfg_val = upper_half ?
1059b2d7a7c7SAtish Patra                   ((uint64_t)env->mhpmeventh_val[counter_idx] << 32) :
1060b2d7a7c7SAtish Patra                   env->mhpmevent_val[counter_idx];
1061b2d7a7c7SAtish Patra         cfg_val &= MHPMEVENT_FILTER_MASK;
1062b2d7a7c7SAtish Patra     }
1063b2d7a7c7SAtish Patra 
1064b2d7a7c7SAtish Patra     if (!cfg_val) {
1065b2d7a7c7SAtish Patra         if (icount_enabled()) {
1066b2d7a7c7SAtish Patra                 curr_val = inst ? icount_get_raw() : icount_get();
1067b2d7a7c7SAtish Patra         } else {
1068b2d7a7c7SAtish Patra             curr_val = cpu_get_host_ticks();
1069b2d7a7c7SAtish Patra         }
1070b2d7a7c7SAtish Patra 
1071b2d7a7c7SAtish Patra         goto done;
1072b2d7a7c7SAtish Patra     }
1073b2d7a7c7SAtish Patra 
1074b2d7a7c7SAtish Patra     /* Update counter before reading. */
1075a5cb044cSLIU Zhiwei     riscv_pmu_update_fixed_ctrs(env, env->priv, env->virt_enabled);
1076a5cb044cSLIU Zhiwei 
1077621f35bbSAtish Patra     if (!(cfg_val & MCYCLECFG_BIT_MINH)) {
10783780e337SAtish Patra         curr_val += counter_arr[PRV_M];
10793780e337SAtish Patra     }
108014664483SAtish Patra 
1081621f35bbSAtish Patra     if (!(cfg_val & MCYCLECFG_BIT_SINH)) {
10823780e337SAtish Patra         curr_val += counter_arr[PRV_S];
108322c721c3SRajnesh Kanwal     }
108422c721c3SRajnesh Kanwal 
108522c721c3SRajnesh Kanwal     if (!(cfg_val & MCYCLECFG_BIT_UINH)) {
1086b2d7a7c7SAtish Patra         curr_val += counter_arr[PRV_U];
1087b2d7a7c7SAtish Patra     }
108814664483SAtish Patra 
108914664483SAtish Patra     if (!(cfg_val & MCYCLECFG_BIT_VSINH)) {
109014664483SAtish Patra         curr_val += counter_arr_virt[PRV_S];
109114664483SAtish Patra     }
109214664483SAtish Patra 
109314664483SAtish Patra     if (!(cfg_val & MCYCLECFG_BIT_VUINH)) {
109414664483SAtish Patra         curr_val += counter_arr_virt[PRV_U];
10953780e337SAtish Patra     }
10963780e337SAtish Patra 
10973780e337SAtish Patra done:
10983780e337SAtish Patra     if (riscv_cpu_mxl(env) == MXL_RV32) {
1099621f35bbSAtish Patra         result = upper_half ? curr_val >> 32 : curr_val;
1100621f35bbSAtish Patra     } else {
1101621f35bbSAtish Patra         result = curr_val;
1102621f35bbSAtish Patra     }
1103a5cb044cSLIU Zhiwei 
1104a5cb044cSLIU Zhiwei     return result;
1105621f35bbSAtish Patra }
11063780e337SAtish Patra 
write_mhpmcounter(CPURISCVState * env,int csrno,target_ulong val)11073780e337SAtish Patra static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
110814664483SAtish Patra                                         target_ulong val)
110914664483SAtish Patra {
1110621f35bbSAtish Patra     int ctr_idx = csrno - CSR_MCYCLE;
11113780e337SAtish Patra     PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
111214664483SAtish Patra     uint64_t mhpmctr_val = val;
111322c721c3SRajnesh Kanwal 
111422c721c3SRajnesh Kanwal     counter->mhpmcounter_val = val;
111522c721c3SRajnesh Kanwal     if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
1116b2d7a7c7SAtish Patra         (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
1117b2d7a7c7SAtish Patra          riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
111814664483SAtish Patra         counter->mhpmcounter_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
111914664483SAtish Patra                                                                 ctr_idx, false);
112014664483SAtish Patra         if (ctr_idx > 2) {
11213780e337SAtish Patra             if (riscv_cpu_mxl(env) == MXL_RV32) {
11223780e337SAtish Patra                 mhpmctr_val = mhpmctr_val |
11233780e337SAtish Patra                               ((uint64_t)counter->mhpmcounterh_val << 32);
11243780e337SAtish Patra             }
11253780e337SAtish Patra             riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
11263780e337SAtish Patra         }
11273780e337SAtish Patra      } else {
112874112400SRajnesh Kanwal         /* Other counters can keep incrementing from the given value */
11293780e337SAtish Patra         counter->mhpmcounter_prev = val;
11303780e337SAtish Patra     }
11315cb0e7abSXu Lu 
11325cb0e7abSXu Lu     return RISCV_EXCP_NONE;
11335cb0e7abSXu Lu }
11345cb0e7abSXu Lu 
write_mhpmcounterh(CPURISCVState * env,int csrno,target_ulong val)11355cb0e7abSXu Lu static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
11363780e337SAtish Patra                                          target_ulong val)
11373780e337SAtish Patra {
11383b57254dSWeiwei Li     int ctr_idx = csrno - CSR_MCYCLEH;
113946023470SAtish Patra     PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
114046023470SAtish Patra     uint64_t mhpmctr_val = counter->mhpmcounter_val;
11413780e337SAtish Patra     uint64_t mhpmctrh_val = val;
11423780e337SAtish Patra 
11433780e337SAtish Patra     counter->mhpmcounterh_val = val;
11443780e337SAtish Patra     mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
11453780e337SAtish Patra     if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
11463b57254dSWeiwei Li         (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
11473780e337SAtish Patra          riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
11483780e337SAtish Patra         counter->mhpmcounterh_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
11493780e337SAtish Patra                                                                  ctr_idx, true);
1150b2d7a7c7SAtish Patra         if (ctr_idx > 2) {
1151b2d7a7c7SAtish Patra             riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
1152b2d7a7c7SAtish Patra         }
1153b2d7a7c7SAtish Patra     } else {
11543780e337SAtish Patra         counter->mhpmcounterh_prev = val;
11553780e337SAtish Patra     }
11563780e337SAtish Patra 
1157621f35bbSAtish Patra     return RISCV_EXCP_NONE;
1158621f35bbSAtish Patra }
1159621f35bbSAtish Patra 
riscv_pmu_read_ctr(CPURISCVState * env,target_ulong * val,bool upper_half,uint32_t ctr_idx)1160621f35bbSAtish Patra RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
1161a5cb044cSLIU Zhiwei                                          bool upper_half, uint32_t ctr_idx)
1162a5cb044cSLIU Zhiwei {
1163621f35bbSAtish Patra     PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
11643780e337SAtish Patra     target_ulong ctr_prev = upper_half ? counter->mhpmcounterh_prev :
1165621f35bbSAtish Patra                                          counter->mhpmcounter_prev;
1166621f35bbSAtish Patra     target_ulong ctr_val = upper_half ? counter->mhpmcounterh_val :
11673780e337SAtish Patra                                         counter->mhpmcounter_val;
1168621f35bbSAtish Patra 
11693780e337SAtish Patra     if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
1170621f35bbSAtish Patra         /*
1171621f35bbSAtish Patra          * Counter should not increment if inhibit bit is set. Just return the
1172621f35bbSAtish Patra          * current counter value.
1173621f35bbSAtish Patra          */
11743780e337SAtish Patra          *val = ctr_val;
1175621f35bbSAtish Patra          return RISCV_EXCP_NONE;
1176621f35bbSAtish Patra     }
1177a5cb044cSLIU Zhiwei 
1178a5cb044cSLIU Zhiwei     /*
1179621f35bbSAtish Patra      * The kernel computes the perf delta by subtracting the current value from
11803780e337SAtish Patra      * the value it initialized previously (ctr_val).
1181621f35bbSAtish Patra      */
1182621f35bbSAtish Patra     if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
11833780e337SAtish Patra         riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
1184621f35bbSAtish Patra         *val = riscv_pmu_ctr_get_fixed_counters_val(env, ctr_idx, upper_half) -
11853780e337SAtish Patra                                                     ctr_prev + ctr_val;
1186621f35bbSAtish Patra     } else {
1187621f35bbSAtish Patra         *val = ctr_val;
1188621f35bbSAtish Patra     }
1189621f35bbSAtish Patra 
11903780e337SAtish Patra     return RISCV_EXCP_NONE;
1191621f35bbSAtish Patra }
1192621f35bbSAtish Patra 
read_hpmcounter(CPURISCVState * env,int csrno,target_ulong * val)1193a5cb044cSLIU Zhiwei static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
1194a5cb044cSLIU Zhiwei                                       target_ulong *val)
119514664483SAtish Patra {
119614664483SAtish Patra     uint16_t ctr_index;
119714664483SAtish Patra 
119814664483SAtish Patra     if (csrno >= CSR_MCYCLE && csrno <= CSR_MHPMCOUNTER31) {
119914664483SAtish Patra         ctr_index = csrno - CSR_MCYCLE;
120014664483SAtish Patra     } else if (csrno >= CSR_CYCLE && csrno <= CSR_HPMCOUNTER31) {
120114664483SAtish Patra         ctr_index = csrno - CSR_CYCLE;
120214664483SAtish Patra     } else {
120314664483SAtish Patra         return RISCV_EXCP_ILLEGAL_INST;
120414664483SAtish Patra     }
120514664483SAtish Patra 
120614664483SAtish Patra     return riscv_pmu_read_ctr(env, val, false, ctr_index);
120714664483SAtish Patra }
120814664483SAtish Patra 
read_hpmcounterh(CPURISCVState * env,int csrno,target_ulong * val)120914664483SAtish Patra static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
121014664483SAtish Patra                                        target_ulong *val)
121114664483SAtish Patra {
121214664483SAtish Patra     uint16_t ctr_index;
121314664483SAtish Patra 
121414664483SAtish Patra     if (csrno >= CSR_MCYCLEH && csrno <= CSR_MHPMCOUNTER31H) {
121514664483SAtish Patra         ctr_index = csrno - CSR_MCYCLEH;
121614664483SAtish Patra     } else if (csrno >= CSR_CYCLEH && csrno <= CSR_HPMCOUNTER31H) {
121714664483SAtish Patra         ctr_index = csrno - CSR_CYCLEH;
121814664483SAtish Patra     } else {
121914664483SAtish Patra         return RISCV_EXCP_ILLEGAL_INST;
1220605def6eSAlistair Francis     }
1221605def6eSAlistair Francis 
1222c6957248SAnup Patel     return riscv_pmu_read_ctr(env, val, true, ctr_index);
122338256529SWeiwei Li }
1224c6957248SAnup Patel 
read_scountovf(CPURISCVState * env,int csrno,target_ulong * val)1225c6957248SAnup Patel static RISCVException read_scountovf(CPURISCVState *env, int csrno,
1226605def6eSAlistair Francis                                      target_ulong *val)
1227c6957248SAnup Patel {
1228c6957248SAnup Patel     int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
1229a47ef6e9SBin Meng     int i;
1230605def6eSAlistair Francis     *val = 0;
1231c6957248SAnup Patel     target_ulong *mhpm_evt_val;
1232c6957248SAnup Patel     uint64_t of_bit_mask;
1233605def6eSAlistair Francis 
1234605def6eSAlistair Francis     if (riscv_cpu_mxl(env) == MXL_RV32) {
1235c6957248SAnup Patel         mhpm_evt_val = env->mhpmeventh_val;
123638256529SWeiwei Li         of_bit_mask = MHPMEVENTH_BIT_OF;
1237c6957248SAnup Patel     } else {
1238c6957248SAnup Patel         mhpm_evt_val = env->mhpmevent_val;
1239605def6eSAlistair Francis         of_bit_mask = MHPMEVENT_BIT_OF;
1240c6957248SAnup Patel     }
1241c6957248SAnup Patel 
1242a47ef6e9SBin Meng     for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
1243605def6eSAlistair Francis         if ((get_field(env->mcounteren, BIT(i))) &&
1244c6957248SAnup Patel             (mhpm_evt_val[i] & of_bit_mask)) {
1245c6957248SAnup Patel                     *val |= BIT(i);
12463ec0fe18SAtish Patra             }
12473ec0fe18SAtish Patra     }
12483ec0fe18SAtish Patra 
12493ec0fe18SAtish Patra     return RISCV_EXCP_NONE;
12503ec0fe18SAtish Patra }
12513ec0fe18SAtish Patra 
read_time(CPURISCVState * env,int csrno,target_ulong * val)12523ec0fe18SAtish Patra static RISCVException read_time(CPURISCVState *env, int csrno,
12533ec0fe18SAtish Patra                                 target_ulong *val)
12543ec0fe18SAtish Patra {
12553ec0fe18SAtish Patra     uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
12563ec0fe18SAtish Patra 
12573ec0fe18SAtish Patra     if (!env->rdtime_fn) {
12583ec0fe18SAtish Patra         return RISCV_EXCP_ILLEGAL_INST;
12593ec0fe18SAtish Patra     }
12603ec0fe18SAtish Patra 
12613ec0fe18SAtish Patra     *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
12623ec0fe18SAtish Patra     return RISCV_EXCP_NONE;
12633ec0fe18SAtish Patra }
12643ec0fe18SAtish Patra 
read_timeh(CPURISCVState * env,int csrno,target_ulong * val)12653ec0fe18SAtish Patra static RISCVException read_timeh(CPURISCVState *env, int csrno,
12663ec0fe18SAtish Patra                                  target_ulong *val)
12673ec0fe18SAtish Patra {
12683ec0fe18SAtish Patra     uint64_t delta = env->virt_enabled ? env->htimedelta : 0;
12693ec0fe18SAtish Patra 
12703ec0fe18SAtish Patra     if (!env->rdtime_fn) {
1271bbb9fc25SWeiwei Li         return RISCV_EXCP_ILLEGAL_INST;
12723ec0fe18SAtish Patra     }
12733ec0fe18SAtish Patra 
12743ec0fe18SAtish Patra     *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
12753ec0fe18SAtish Patra     return RISCV_EXCP_NONE;
12763ec0fe18SAtish Patra }
12773ec0fe18SAtish Patra 
read_vstimecmp(CPURISCVState * env,int csrno,target_ulong * val)12783ec0fe18SAtish Patra static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
12793ec0fe18SAtish Patra                                      target_ulong *val)
12803ec0fe18SAtish Patra {
1281bbb9fc25SWeiwei Li     *val = env->vstimecmp;
12823ec0fe18SAtish Patra 
12833ec0fe18SAtish Patra     return RISCV_EXCP_NONE;
12843ec0fe18SAtish Patra }
12853ec0fe18SAtish Patra 
read_vstimecmph(CPURISCVState * env,int csrno,target_ulong * val)12863ec0fe18SAtish Patra static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
128743888c2fSAtish Patra                                       target_ulong *val)
128843888c2fSAtish Patra {
128943888c2fSAtish Patra     *val = env->vstimecmp >> 32;
129038256529SWeiwei Li 
12913ec0fe18SAtish Patra     return RISCV_EXCP_NONE;
12923ec0fe18SAtish Patra }
129343888c2fSAtish Patra 
write_vstimecmp(CPURISCVState * env,int csrno,target_ulong val)12943ec0fe18SAtish Patra static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
12953ec0fe18SAtish Patra                                       target_ulong val)
129643888c2fSAtish Patra {
129743888c2fSAtish Patra     if (riscv_cpu_mxl(env) == MXL_RV32) {
129843888c2fSAtish Patra         env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
129943888c2fSAtish Patra     } else {
130043888c2fSAtish Patra         env->vstimecmp = val;
130143888c2fSAtish Patra     }
130238256529SWeiwei Li 
13033ec0fe18SAtish Patra     riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
13043ec0fe18SAtish Patra                               env->htimedelta, MIP_VSTIP);
130543888c2fSAtish Patra 
13063ec0fe18SAtish Patra     return RISCV_EXCP_NONE;
13073ec0fe18SAtish Patra }
130843888c2fSAtish Patra 
write_vstimecmph(CPURISCVState * env,int csrno,target_ulong val)130943888c2fSAtish Patra static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
131043888c2fSAtish Patra                                        target_ulong val)
131143888c2fSAtish Patra {
131243888c2fSAtish Patra     env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
131343888c2fSAtish Patra     riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
131438256529SWeiwei Li                               env->htimedelta, MIP_VSTIP);
1315e471a8c9SAndrew Bresticker 
1316e471a8c9SAndrew Bresticker     return RISCV_EXCP_NONE;
1317e471a8c9SAndrew Bresticker }
13183ec0fe18SAtish Patra 
read_stimecmp(CPURISCVState * env,int csrno,target_ulong * val)13193ec0fe18SAtish Patra static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
13203ec0fe18SAtish Patra                                     target_ulong *val)
132143888c2fSAtish Patra {
132243888c2fSAtish Patra     if (env->virt_enabled) {
132343888c2fSAtish Patra         *val = env->vstimecmp;
132443888c2fSAtish Patra     } else {
132543888c2fSAtish Patra         *val = env->stimecmp;
132643888c2fSAtish Patra     }
1327bbb9fc25SWeiwei Li 
132843888c2fSAtish Patra     return RISCV_EXCP_NONE;
132943888c2fSAtish Patra }
133043888c2fSAtish Patra 
read_stimecmph(CPURISCVState * env,int csrno,target_ulong * val)133143888c2fSAtish Patra static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
133243888c2fSAtish Patra                                      target_ulong *val)
133343888c2fSAtish Patra {
133443888c2fSAtish Patra     if (env->virt_enabled) {
133538256529SWeiwei Li         *val = env->vstimecmp >> 32;
1336e471a8c9SAndrew Bresticker     } else {
1337e471a8c9SAndrew Bresticker         *val = env->stimecmp >> 32;
1338e471a8c9SAndrew Bresticker     }
13393ec0fe18SAtish Patra 
13403ec0fe18SAtish Patra     return RISCV_EXCP_NONE;
13413ec0fe18SAtish Patra }
134243888c2fSAtish Patra 
write_stimecmp(CPURISCVState * env,int csrno,target_ulong val)1343bbb9fc25SWeiwei Li static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
134443888c2fSAtish Patra                                      target_ulong val)
134543888c2fSAtish Patra {
134643888c2fSAtish Patra     if (env->virt_enabled) {
134743888c2fSAtish Patra         if (env->hvictl & HVICTL_VTI) {
1348c7de92b4SAnup Patel             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1349c7de92b4SAnup Patel         }
135092c82a12SRajnesh Kanwal         return write_vstimecmp(env, csrno, val);
135192c82a12SRajnesh Kanwal     }
135292c82a12SRajnesh Kanwal 
135392c82a12SRajnesh Kanwal     if (riscv_cpu_mxl(env) == MXL_RV32) {
135492c82a12SRajnesh Kanwal         env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
135592c82a12SRajnesh Kanwal     } else {
135692c82a12SRajnesh Kanwal         env->stimecmp = val;
135792c82a12SRajnesh Kanwal     }
13581697837eSRajnesh Kanwal 
13591697837eSRajnesh Kanwal     riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
13601697837eSRajnesh Kanwal 
13611697837eSRajnesh Kanwal     return RISCV_EXCP_NONE;
13621697837eSRajnesh Kanwal }
1363d028ac75SAnup Patel 
write_stimecmph(CPURISCVState * env,int csrno,target_ulong val)13641697837eSRajnesh Kanwal static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
1365bc083a51SJose Martins                                       target_ulong val)
1366bc083a51SJose Martins {
1367bc083a51SJose Martins     if (env->virt_enabled) {
1368bc083a51SJose Martins         if (env->hvictl & HVICTL_VTI) {
1369bc083a51SJose Martins             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1370bc083a51SJose Martins         }
1371bc083a51SJose Martins         return write_vstimecmph(env, csrno, val);
1372bc083a51SJose Martins     }
1373bc083a51SJose Martins 
1374bc083a51SJose Martins     env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
1375bc083a51SJose Martins     riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
1376bc083a51SJose Martins 
1377bc083a51SJose Martins     return RISCV_EXCP_NONE;
1378bc083a51SJose Martins }
1379bc083a51SJose Martins 
1380bc083a51SJose Martins #define VSTOPI_NUM_SRCS 5
1381bc083a51SJose Martins 
1382bc083a51SJose Martins /*
1383bc083a51SJose Martins  * All core local interrupts except the fixed ones 0:12. This macro is for
1384bc083a51SJose Martins  * virtual interrupts logic so please don't change this to avoid messing up
1385bc083a51SJose Martins  * the whole support, For reference see AIA spec: `5.3 Interrupt filtering and
1386ab67a1d0SAlistair Francis  * virtual interrupts for supervisor level` and `6.3.2 Virtual interrupts for
1387c7b95171SMichael Clark  * VS level`.
1388ab67a1d0SAlistair Francis  */
1389ab67a1d0SAlistair Francis #define LOCAL_INTERRUPTS   (~0x1FFFULL)
1390e39a8320SAlistair Francis 
1391bc083a51SJose Martins static const uint64_t delegable_ints =
1392c7b95171SMichael Clark     S_MODE_INTERRUPTS | VS_MODE_INTERRUPTS | MIP_LCOFIP;
1393c7b95171SMichael Clark static const uint64_t vs_delegable_ints =
1394f310df58SLIU Zhiwei     (VS_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & ~MIP_LCOFIP;
13951697837eSRajnesh Kanwal static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
13961697837eSRajnesh Kanwal                                      HS_MODE_INTERRUPTS | LOCAL_INTERRUPTS;
13971697837eSRajnesh Kanwal #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
13981697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
13991697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
14001697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
14011697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
14021697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
14031697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
14041697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
14051697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_U_ECALL)) | \
14061697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_S_ECALL)) | \
14071697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_VS_ECALL)) | \
14081697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_M_ECALL)) | \
140987088fadSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
14101697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
141187088fadSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
14121697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_SW_CHECK)) | \
14131697837eSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
141487088fadSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
141587088fadSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
141687088fadSRajnesh Kanwal                          (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
14171697837eSRajnesh Kanwal static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
141887088fadSRajnesh Kanwal     ~((1ULL << (RISCV_EXCP_S_ECALL)) |
141940336d5bSRajnesh Kanwal       (1ULL << (RISCV_EXCP_VS_ECALL)) |
142087088fadSRajnesh Kanwal       (1ULL << (RISCV_EXCP_M_ECALL)) |
1421c7b95171SMichael Clark       (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
14226f23aaebSAlexandre Ghiti       (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
1423bf1a6abeSAlexandre Ghiti       (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
1424bf1a6abeSAlexandre Ghiti       (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
1425c7b95171SMichael Clark static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
14268987cdc4SAlistair Francis     SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
14276f23aaebSAlexandre Ghiti     SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
1428bf1a6abeSAlexandre Ghiti 
1429bf1a6abeSAlexandre Ghiti /*
1430bf1a6abeSAlexandre Ghiti  * Spec allows for bits 13:63 to be either read-only or writable.
1431bf1a6abeSAlexandre Ghiti  * So far we have interrupt LCOFIP in that region which is writable.
1432c7b95171SMichael Clark  *
1433c7b95171SMichael Clark  * Also, spec allows to inject virtual interrupts in this region even
1434c7b95171SMichael Clark  * without any hardware interrupts for that interrupt number.
1435605def6eSAlistair Francis  *
1436605def6eSAlistair Francis  * For now interrupt in 13:63 region are all kept writable. 13 being
1437c7b95171SMichael Clark  * LCOFIP and 14:63 being virtual only. Change this in future if we
1438605def6eSAlistair Francis  * introduce more interrupts that are not writable.
1439605def6eSAlistair Francis  */
1440c7b95171SMichael Clark 
1441c7b95171SMichael Clark /* Bit STIP can be an alias of mip.STIP that's why it's writable in mvip. */
1442d0237b4dSAnup Patel static const uint64_t mvip_writable_mask = MIP_SSIP | MIP_STIP | MIP_SEIP |
1443d0237b4dSAnup Patel                                     LOCAL_INTERRUPTS;
1444d0237b4dSAnup Patel static const uint64_t mvien_writable_mask = MIP_SSIP | MIP_SEIP |
1445d0237b4dSAnup Patel                                     LOCAL_INTERRUPTS;
1446d0237b4dSAnup Patel 
1447d0237b4dSAnup Patel static const uint64_t sip_writable_mask = SIP_SSIP | LOCAL_INTERRUPTS;
14489951ba94SFrank Chang static const uint64_t hip_writable_mask = MIP_VSSIP;
14499951ba94SFrank Chang static const uint64_t hvip_writable_mask = MIP_VSSIP | MIP_VSTIP |
14509951ba94SFrank Chang                                     MIP_VSEIP | LOCAL_INTERRUPTS;
14519c33e08bSWeiwei Li static const uint64_t hvien_writable_mask = LOCAL_INTERRUPTS;
14529951ba94SFrank Chang 
14539951ba94SFrank Chang static const uint64_t vsip_writable_mask = MIP_VSSIP | LOCAL_INTERRUPTS;
14549951ba94SFrank Chang 
14559951ba94SFrank Chang const bool valid_vm_1_10_32[16] = {
14569951ba94SFrank Chang     [VM_1_10_MBARE] = true,
14579951ba94SFrank Chang     [VM_1_10_SV32] = true
14589c33e08bSWeiwei Li };
14599951ba94SFrank Chang 
14609951ba94SFrank Chang const bool valid_vm_1_10_64[16] = {
14619951ba94SFrank Chang     [VM_1_10_MBARE] = true,
1462075eeda9SFrank Chang     [VM_1_10_SV39] = true,
14639951ba94SFrank Chang     [VM_1_10_SV48] = true,
14649951ba94SFrank Chang     [VM_1_10_SV57] = true
14659c33e08bSWeiwei Li };
14669951ba94SFrank Chang 
14679951ba94SFrank Chang /* Machine Information Registers */
read_zero(CPURISCVState * env,int csrno,target_ulong * val)14689951ba94SFrank Chang static RISCVException read_zero(CPURISCVState *env, int csrno,
1469605def6eSAlistair Francis                                 target_ulong *val)
1470605def6eSAlistair Francis {
1471c7b95171SMichael Clark     *val = 0;
1472c7b95171SMichael Clark     return RISCV_EXCP_NONE;
1473605def6eSAlistair Francis }
1474c7b95171SMichael Clark 
write_ignore(CPURISCVState * env,int csrno,target_ulong val)1475c7b95171SMichael Clark static RISCVException write_ignore(CPURISCVState *env, int csrno,
1476c7b95171SMichael Clark                                    target_ulong val)
1477b550f894SRichard Henderson {
1478b550f894SRichard Henderson     return RISCV_EXCP_NONE;
1479b550f894SRichard Henderson }
1480b550f894SRichard Henderson 
read_mvendorid(CPURISCVState * env,int csrno,target_ulong * val)1481b550f894SRichard Henderson static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
1482c36b2f1aSFrank Chang                                      target_ulong *val)
1483b550f894SRichard Henderson {
1484b550f894SRichard Henderson     *val = riscv_cpu_cfg(env)->mvendorid;
1485b550f894SRichard Henderson     return RISCV_EXCP_NONE;
1486b550f894SRichard Henderson }
1487b550f894SRichard Henderson 
read_marchid(CPURISCVState * env,int csrno,target_ulong * val)1488b550f894SRichard Henderson static RISCVException read_marchid(CPURISCVState *env, int csrno,
1489457c360fSFrédéric Pétrot                                    target_ulong *val)
1490457c360fSFrédéric Pétrot {
1491b550f894SRichard Henderson     *val = riscv_cpu_cfg(env)->marchid;
1492b550f894SRichard Henderson     return RISCV_EXCP_NONE;
1493b550f894SRichard Henderson }
1494b550f894SRichard Henderson 
read_mimpid(CPURISCVState * env,int csrno,target_ulong * val)1495b550f894SRichard Henderson static RISCVException read_mimpid(CPURISCVState *env, int csrno,
1496b550f894SRichard Henderson                                   target_ulong *val)
1497b550f894SRichard Henderson {
1498605def6eSAlistair Francis     *val = riscv_cpu_cfg(env)->mimpid;
1499605def6eSAlistair Francis     return RISCV_EXCP_NONE;
1500c7b95171SMichael Clark }
1501b550f894SRichard Henderson 
read_mhartid(CPURISCVState * env,int csrno,target_ulong * val)1502605def6eSAlistair Francis static RISCVException read_mhartid(CPURISCVState *env, int csrno,
1503c7b95171SMichael Clark                                    target_ulong *val)
1504c7b95171SMichael Clark {
1505bf1a6abeSAlexandre Ghiti     *val = env->mhartid;
1506c7b95171SMichael Clark     return RISCV_EXCP_NONE;
150757020a46SIrina Ryapolova }
150857020a46SIrina Ryapolova 
1509c7b95171SMichael Clark /* Machine Trap Setup */
1510c7b95171SMichael Clark 
15111349f969SIrina Ryapolova /* We do not store SD explicitly, only compute it on demand. */
add_status_sd(RISCVMXL xl,uint64_t status)15121349f969SIrina Ryapolova static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
15131349f969SIrina Ryapolova {
15141349f969SIrina Ryapolova     if ((status & MSTATUS_FS) == MSTATUS_FS ||
15151349f969SIrina Ryapolova         (status & MSTATUS_VS) == MSTATUS_VS ||
15161349f969SIrina Ryapolova         (status & MSTATUS_XS) == MSTATUS_XS) {
15171349f969SIrina Ryapolova         switch (xl) {
15181349f969SIrina Ryapolova         case MXL_RV32:
15191349f969SIrina Ryapolova             return status | MSTATUS32_SD;
15201349f969SIrina Ryapolova         case MXL_RV64:
15211349f969SIrina Ryapolova             return status | MSTATUS64_SD;
15221349f969SIrina Ryapolova         case MXL_RV128:
15231349f969SIrina Ryapolova             return MSTATUSH128_SD;
15241349f969SIrina Ryapolova         default:
15251349f969SIrina Ryapolova             g_assert_not_reached();
15261349f969SIrina Ryapolova         }
15271349f969SIrina Ryapolova     }
15281349f969SIrina Ryapolova     return status;
15291349f969SIrina Ryapolova }
15301349f969SIrina Ryapolova 
read_mstatus(CPURISCVState * env,int csrno,target_ulong * val)15311349f969SIrina Ryapolova static RISCVException read_mstatus(CPURISCVState *env, int csrno,
15321349f969SIrina Ryapolova                                    target_ulong *val)
15331349f969SIrina Ryapolova {
15341349f969SIrina Ryapolova     *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
15351349f969SIrina Ryapolova     return RISCV_EXCP_NONE;
15361349f969SIrina Ryapolova }
15370c98ccefSWeiwei Li 
validate_vm(CPURISCVState * env,target_ulong vm)15380c98ccefSWeiwei Li static bool validate_vm(CPURISCVState *env, target_ulong vm)
15390c98ccefSWeiwei Li {
15400c98ccefSWeiwei Li     uint64_t mode_supported = riscv_cpu_cfg(env)->satp_mode.map;
15410c98ccefSWeiwei Li     return get_field(mode_supported, (1 << vm));
15420c98ccefSWeiwei Li }
15430c98ccefSWeiwei Li 
legalize_xatp(CPURISCVState * env,target_ulong old_xatp,target_ulong val)15440c98ccefSWeiwei Li static target_ulong legalize_xatp(CPURISCVState *env, target_ulong old_xatp,
15450c98ccefSWeiwei Li                                   target_ulong val)
15460c98ccefSWeiwei Li {
15470c98ccefSWeiwei Li     target_ulong mask;
15480c98ccefSWeiwei Li     bool vm;
15490c98ccefSWeiwei Li     if (riscv_cpu_mxl(env) == MXL_RV32) {
15500c98ccefSWeiwei Li         vm = validate_vm(env, get_field(val, SATP32_MODE));
15510c98ccefSWeiwei Li         mask = (val ^ old_xatp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
15520c98ccefSWeiwei Li     } else {
15530c98ccefSWeiwei Li         vm = validate_vm(env, get_field(val, SATP64_MODE));
15540c98ccefSWeiwei Li         mask = (val ^ old_xatp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
15550c98ccefSWeiwei Li     }
15560c98ccefSWeiwei Li 
15570c98ccefSWeiwei Li     if (vm && mask) {
15580c98ccefSWeiwei Li         /*
15590c98ccefSWeiwei Li          * The ISA defines SATP.MODE=Bare as "no translation", but we still
15600c98ccefSWeiwei Li          * pass these through QEMU's TLB emulation as it improves
15610c98ccefSWeiwei Li          * performance.  Flushing the TLB on SATP writes with paging
15620c98ccefSWeiwei Li          * enabled avoids leaking those invalid cached mappings.
1563605def6eSAlistair Francis          */
1564605def6eSAlistair Francis         tlb_flush(env_cpu(env));
1565c7b95171SMichael Clark         return val;
1566284d697cSYifei Jiang     }
1567284d697cSYifei Jiang     return old_xatp;
1568f310df58SLIU Zhiwei }
1569c7b95171SMichael Clark 
legalize_mpp(CPURISCVState * env,target_ulong old_mpp,target_ulong val)15700c98ccefSWeiwei Li static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
15710c98ccefSWeiwei Li                                  target_ulong val)
15720c98ccefSWeiwei Li {
15730c98ccefSWeiwei Li     bool valid = false;
15740c98ccefSWeiwei Li     target_ulong new_mpp = get_field(val, MSTATUS_MPP);
15750c98ccefSWeiwei Li 
1576c7b95171SMichael Clark     switch (new_mpp) {
1577696bacdeSRichard Henderson     case PRV_M:
15783109cd98SRichard Henderson         valid = true;
1579c7b95171SMichael Clark         break;
1580c7b95171SMichael Clark     case PRV_S:
1581c163b3baSWeiwei Li         valid = riscv_has_ext(env, RVS);
15827f2b5ff1SMichael Clark         break;
15837767f8b1SLIU Zhiwei     case PRV_U:
15848987cdc4SAlistair Francis         valid = riscv_has_ext(env, RVU);
1585c163b3baSWeiwei Li         break;
1586c163b3baSWeiwei Li     }
1587c163b3baSWeiwei Li 
15887767f8b1SLIU Zhiwei     /* Remain field unchanged if new_mpp value is invalid */
15897767f8b1SLIU Zhiwei     if (!valid) {
15907767f8b1SLIU Zhiwei         val = set_field(val, MSTATUS_MPP, old_mpp);
1591c163b3baSWeiwei Li     }
1592f297245fSLIU Zhiwei 
159303dd405dSWeiwei Li     return val;
15949034e90aSAlistair Francis }
159503dd405dSWeiwei Li 
write_mstatus(CPURISCVState * env,int csrno,target_ulong val)1596f310df58SLIU Zhiwei static RISCVException write_mstatus(CPURISCVState *env, int csrno,
1597f310df58SLIU Zhiwei                                     target_ulong val)
1598f310df58SLIU Zhiwei {
15998987cdc4SAlistair Francis     uint64_t mstatus = env->mstatus;
1600c7b95171SMichael Clark     uint64_t mask = 0;
1601c7b95171SMichael Clark     RISCVMXL xl = riscv_cpu_mxl(env);
1602c7b95171SMichael Clark 
1603c7b95171SMichael Clark     /*
1604c7b95171SMichael Clark      * MPP field have been made WARL since priv version 1.11. However,
160530a0d776SWeiwei Li      * legalization for it will not break any software running on 1.10.
160630a0d776SWeiwei Li      */
160730a0d776SWeiwei Li     val = legalize_mpp(env, get_field(mstatus, MSTATUS_MPP), val);
160830a0d776SWeiwei Li 
160930a0d776SWeiwei Li     /* flush tlb on mstatus fields that affect VM */
161030a0d776SWeiwei Li     if ((val ^ mstatus) & MSTATUS_MXR) {
161130a0d776SWeiwei Li         tlb_flush(env_cpu(env));
1612ef1ba32aSWeiwei Li     }
1613ef1ba32aSWeiwei Li     mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
1614605def6eSAlistair Francis         MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
1615c7b95171SMichael Clark         MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
1616c7b95171SMichael Clark         MSTATUS_TW;
1617605def6eSAlistair Francis 
1618605def6eSAlistair Francis     if (riscv_has_ext(env, RVF)) {
1619551fa7e8SAlistair Francis         mask |= MSTATUS_FS;
1620284d697cSYifei Jiang     }
1621605def6eSAlistair Francis     if (riscv_has_ext(env, RVV)) {
1622551fa7e8SAlistair Francis         mask |= MSTATUS_VS;
1623551fa7e8SAlistair Francis     }
1624605def6eSAlistair Francis 
1625605def6eSAlistair Francis     if (xl != MXL_RV32 || env->debugger) {
1626551fa7e8SAlistair Francis         if (riscv_has_ext(env, RVH)) {
1627284d697cSYifei Jiang             mask |= MSTATUS_MPV | MSTATUS_GVA;
162803dd405dSWeiwei Li         }
1629284d697cSYifei Jiang         if ((val & MSTATUS64_UXL) != 0) {
1630284d697cSYifei Jiang             mask |= MSTATUS64_UXL;
1631551fa7e8SAlistair Francis         }
1632605def6eSAlistair Francis     }
1633551fa7e8SAlistair Francis 
1634551fa7e8SAlistair Francis     /* If cfi lp extension is available, then apply cfi lp mask */
1635457c360fSFrédéric Pétrot     if (env_archcpu(env)->cfg.ext_zicfilp) {
1636457c360fSFrédéric Pétrot         mask |= (MSTATUS_MPELP | MSTATUS_SPELP);
1637457c360fSFrédéric Pétrot     }
1638246f8796SWeiwei Li 
1639246f8796SWeiwei Li     mstatus = (mstatus & ~mask) | (val & mask);
1640457c360fSFrédéric Pétrot 
1641457c360fSFrédéric Pétrot     env->mstatus = mstatus;
1642457c360fSFrédéric Pétrot 
1643457c360fSFrédéric Pétrot     /*
1644457c360fSFrédéric Pétrot      * Except in debug mode, UXL/SXL can only be modified by higher
1645457c360fSFrédéric Pétrot      * privilege mode. So xl will not be changed in normal mode.
1646457c360fSFrédéric Pétrot      */
1647457c360fSFrédéric Pétrot     if (env->debugger) {
1648457c360fSFrédéric Pétrot         env->xl = cpu_recompute_xl(env);
1649457c360fSFrédéric Pétrot     }
1650605def6eSAlistair Francis 
1651605def6eSAlistair Francis     riscv_cpu_update_mask(env);
1652c7b95171SMichael Clark     return RISCV_EXCP_NONE;
1653e91a7227SRichard Henderson }
1654e91a7227SRichard Henderson 
read_mstatush(CPURISCVState * env,int csrno,target_ulong * val)1655e91a7227SRichard Henderson static RISCVException read_mstatush(CPURISCVState *env, int csrno,
1656e91a7227SRichard Henderson                                     target_ulong *val)
1657e91a7227SRichard Henderson {
1658e91a7227SRichard Henderson     *val = env->mstatus >> 32;
1659e91a7227SRichard Henderson     return RISCV_EXCP_NONE;
1660e91a7227SRichard Henderson }
1661e91a7227SRichard Henderson 
write_mstatush(CPURISCVState * env,int csrno,target_ulong val)1662e91a7227SRichard Henderson static RISCVException write_mstatush(CPURISCVState *env, int csrno,
1663e91a7227SRichard Henderson                                      target_ulong val)
1664e91a7227SRichard Henderson {
1665e91a7227SRichard Henderson     uint64_t valh = (uint64_t)val << 32;
1666e91a7227SRichard Henderson     uint64_t mask = riscv_has_ext(env, RVH) ? MSTATUS_MPV | MSTATUS_GVA : 0;
1667e91a7227SRichard Henderson 
1668e91a7227SRichard Henderson     env->mstatus = (env->mstatus & ~mask) | (valh & mask);
1669605def6eSAlistair Francis 
1670c7b95171SMichael Clark     return RISCV_EXCP_NONE;
1671c7b95171SMichael Clark }
1672605def6eSAlistair Francis 
read_mstatus_i128(CPURISCVState * env,int csrno,Int128 * val)1673605def6eSAlistair Francis static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
1674f18637cdSMichael Clark                                         Int128 *val)
1675faf3b5d8SDaniel Henrique Barboza {
1676faf3b5d8SDaniel Henrique Barboza     *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128,
1677faf3b5d8SDaniel Henrique Barboza                                                       env->mstatus));
1678faf3b5d8SDaniel Henrique Barboza     return RISCV_EXCP_NONE;
167954bd9b6eSDaniel Henrique Barboza }
1680f18637cdSMichael Clark 
read_misa_i128(CPURISCVState * env,int csrno,Int128 * val)1681605def6eSAlistair Francis static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
1682f18637cdSMichael Clark                                      Int128 *val)
1683f18637cdSMichael Clark {
1684f18637cdSMichael Clark     *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
1685e91a7227SRichard Henderson     return RISCV_EXCP_NONE;
1686f18637cdSMichael Clark }
16878c7fedddSBin Meng 
read_misa(CPURISCVState * env,int csrno,target_ulong * val)16888c7fedddSBin Meng static RISCVException read_misa(CPURISCVState *env, int csrno,
1689f18637cdSMichael Clark                                 target_ulong *val)
1690f18637cdSMichael Clark {
1691f18637cdSMichael Clark     target_ulong misa;
1692f18637cdSMichael Clark 
1693f18637cdSMichael Clark     switch (env->misa_mxl) {
1694f18637cdSMichael Clark     case MXL_RV32:
1695faf3b5d8SDaniel Henrique Barboza         misa = (target_ulong)MXL_RV32 << 30;
1696faf3b5d8SDaniel Henrique Barboza         break;
1697faf3b5d8SDaniel Henrique Barboza #ifdef TARGET_RISCV64
1698faf3b5d8SDaniel Henrique Barboza     case MXL_RV64:
1699faf3b5d8SDaniel Henrique Barboza         misa = (target_ulong)MXL_RV64 << 62;
1700faf3b5d8SDaniel Henrique Barboza         break;
1701e91a7227SRichard Henderson #endif
1702e91a7227SRichard Henderson     default:
1703e91a7227SRichard Henderson         g_assert_not_reached();
17044fd7455bSAlistair Francis     }
1705f18637cdSMichael Clark 
1706faf3b5d8SDaniel Henrique Barboza     *val = misa | env->misa_ext;
1707faf3b5d8SDaniel Henrique Barboza     return RISCV_EXCP_NONE;
1708faf3b5d8SDaniel Henrique Barboza }
1709faf3b5d8SDaniel Henrique Barboza 
write_misa(CPURISCVState * env,int csrno,target_ulong val)1710faf3b5d8SDaniel Henrique Barboza static RISCVException write_misa(CPURISCVState *env, int csrno,
1711faf3b5d8SDaniel Henrique Barboza                                  target_ulong val)
1712faf3b5d8SDaniel Henrique Barboza {
1713faf3b5d8SDaniel Henrique Barboza     RISCVCPU *cpu = env_archcpu(env);
1714faf3b5d8SDaniel Henrique Barboza     uint32_t orig_misa_ext = env->misa_ext;
1715faf3b5d8SDaniel Henrique Barboza     Error *local_err = NULL;
1716faf3b5d8SDaniel Henrique Barboza 
1717faf3b5d8SDaniel Henrique Barboza     if (!riscv_cpu_cfg(env)->misa_w) {
1718faf3b5d8SDaniel Henrique Barboza         /* drop write to misa */
1719faf3b5d8SDaniel Henrique Barboza         return RISCV_EXCP_NONE;
1720c163b3baSWeiwei Li     }
1721c163b3baSWeiwei Li 
1722c163b3baSWeiwei Li     /* Mask extensions that are not supported by this hart */
1723f18637cdSMichael Clark     val &= env->misa_ext_mask;
17243109cd98SRichard Henderson 
1725440544e1SLIU Zhiwei     /*
1726605def6eSAlistair Francis      * Suppress 'C' if next instruction is not aligned
1727f18637cdSMichael Clark      * TODO: this should check next_pc
1728f18637cdSMichael Clark      */
1729605def6eSAlistair Francis     if ((val & RVC) && (GETPC() & ~3) != 0) {
1730605def6eSAlistair Francis         val &= ~RVC;
1731c7b95171SMichael Clark     }
1732c7b95171SMichael Clark 
1733605def6eSAlistair Francis     /* Disable RVG if any of its dependencies are disabled */
1734c7b95171SMichael Clark     if (!(val & RVI && val & RVM && val & RVA &&
1735c7b95171SMichael Clark           val & RVF && val & RVD)) {
1736605def6eSAlistair Francis         val &= ~RVG;
1737605def6eSAlistair Francis     }
1738c7b95171SMichael Clark 
1739bc083a51SJose Martins     /* If nothing changed, do nothing. */
1740605def6eSAlistair Francis     if (val == env->misa_ext) {
1741c7b95171SMichael Clark         return RISCV_EXCP_NONE;
1742c7b95171SMichael Clark     }
1743d028ac75SAnup Patel 
1744d028ac75SAnup Patel     env->misa_ext = val;
1745d028ac75SAnup Patel     riscv_cpu_validate_set_extensions(cpu, &local_err);
1746c7b95171SMichael Clark     if (local_err != NULL) {
1747d028ac75SAnup Patel         /* Rollback on validation error */
1748d028ac75SAnup Patel         qemu_log_mask(LOG_GUEST_ERROR, "Unable to write MISA ext value "
1749d028ac75SAnup Patel                       "0x%x, keeping existing MISA ext 0x%x\n",
1750d028ac75SAnup Patel                       env->misa_ext, orig_misa_ext);
1751c7b95171SMichael Clark 
1752c7b95171SMichael Clark         env->misa_ext = orig_misa_ext;
1753d028ac75SAnup Patel 
1754d028ac75SAnup Patel         return RISCV_EXCP_NONE;
1755713d8363SAlistair Francis     }
1756881df35dSAnup Patel 
1757713d8363SAlistair Francis     if (!(env->misa_ext & RVF)) {
1758d028ac75SAnup Patel         env->mstatus &= ~MSTATUS_FS;
1759605def6eSAlistair Francis     }
1760c7b95171SMichael Clark 
1761c7b95171SMichael Clark     /* flush translation cache */
1762d028ac75SAnup Patel     tb_flush(env_cpu(env));
1763d028ac75SAnup Patel     env->xl = riscv_cpu_mxl(env);
1764d028ac75SAnup Patel     return RISCV_EXCP_NONE;
1765c7b95171SMichael Clark }
1766d028ac75SAnup Patel 
read_medeleg(CPURISCVState * env,int csrno,target_ulong * val)1767d028ac75SAnup Patel static RISCVException read_medeleg(CPURISCVState *env, int csrno,
1768d028ac75SAnup Patel                                    target_ulong *val)
1769d028ac75SAnup Patel {
1770d028ac75SAnup Patel     *val = env->medeleg;
1771d028ac75SAnup Patel     return RISCV_EXCP_NONE;
1772c7b95171SMichael Clark }
1773c7b95171SMichael Clark 
write_medeleg(CPURISCVState * env,int csrno,target_ulong val)1774d028ac75SAnup Patel static RISCVException write_medeleg(CPURISCVState *env, int csrno,
1775d028ac75SAnup Patel                                     target_ulong val)
1776d028ac75SAnup Patel {
1777d028ac75SAnup Patel     env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
1778d028ac75SAnup Patel     return RISCV_EXCP_NONE;
1779d028ac75SAnup Patel }
1780d028ac75SAnup Patel 
rmw_mideleg64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)1781c7b95171SMichael Clark static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
1782d028ac75SAnup Patel                                     uint64_t *ret_val,
1783d028ac75SAnup Patel                                     uint64_t new_val, uint64_t wr_mask)
1784d028ac75SAnup Patel {
1785d028ac75SAnup Patel     uint64_t mask = wr_mask & delegable_ints;
1786d028ac75SAnup Patel 
1787d028ac75SAnup Patel     if (ret_val) {
1788d028ac75SAnup Patel         *ret_val = env->mideleg;
1789d028ac75SAnup Patel     }
1790d028ac75SAnup Patel 
1791d028ac75SAnup Patel     env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
1792d028ac75SAnup Patel 
1793d028ac75SAnup Patel     if (riscv_has_ext(env, RVH)) {
1794d028ac75SAnup Patel         env->mideleg |= HS_MODE_INTERRUPTS;
1795d028ac75SAnup Patel     }
1796d028ac75SAnup Patel 
1797d028ac75SAnup Patel     return RISCV_EXCP_NONE;
1798d028ac75SAnup Patel }
1799d028ac75SAnup Patel 
rmw_mideleg(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1800d028ac75SAnup Patel static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
1801d028ac75SAnup Patel                                   target_ulong *ret_val,
1802d028ac75SAnup Patel                                   target_ulong new_val, target_ulong wr_mask)
1803d028ac75SAnup Patel {
1804d028ac75SAnup Patel     uint64_t rval;
1805d028ac75SAnup Patel     RISCVException ret;
1806881df35dSAnup Patel 
1807a7b69170SRajnesh Kanwal     ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
1808881df35dSAnup Patel     if (ret_val) {
1809d028ac75SAnup Patel         *ret_val = rval;
1810605def6eSAlistair Francis     }
1811c7b95171SMichael Clark 
1812c7b95171SMichael Clark     return ret;
1813d028ac75SAnup Patel }
1814d028ac75SAnup Patel 
rmw_midelegh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1815d028ac75SAnup Patel static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
1816d028ac75SAnup Patel                                    target_ulong *ret_val,
1817d028ac75SAnup Patel                                    target_ulong new_val,
1818d028ac75SAnup Patel                                    target_ulong wr_mask)
1819d028ac75SAnup Patel {
1820d028ac75SAnup Patel     uint64_t rval;
1821d028ac75SAnup Patel     RISCVException ret;
1822d028ac75SAnup Patel 
1823d028ac75SAnup Patel     ret = rmw_mideleg64(env, csrno, &rval,
1824d028ac75SAnup Patel         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1825d028ac75SAnup Patel     if (ret_val) {
1826d028ac75SAnup Patel         *ret_val = rval >> 32;
1827d028ac75SAnup Patel     }
1828d028ac75SAnup Patel 
1829d028ac75SAnup Patel     return ret;
1830d028ac75SAnup Patel }
1831d028ac75SAnup Patel 
rmw_mie64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)1832d028ac75SAnup Patel static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
1833d028ac75SAnup Patel                                 uint64_t *ret_val,
1834d028ac75SAnup Patel                                 uint64_t new_val, uint64_t wr_mask)
1835d028ac75SAnup Patel {
1836d028ac75SAnup Patel     uint64_t mask = wr_mask & all_ints;
1837d028ac75SAnup Patel 
1838d028ac75SAnup Patel     if (ret_val) {
1839d028ac75SAnup Patel         *ret_val = env->mie;
1840d028ac75SAnup Patel     }
1841d028ac75SAnup Patel 
1842d028ac75SAnup Patel     env->mie = (env->mie & ~mask) | (new_val & mask);
1843d028ac75SAnup Patel 
18441697837eSRajnesh Kanwal     if (!riscv_has_ext(env, RVH)) {
18451697837eSRajnesh Kanwal         env->mie &= ~((uint64_t)HS_MODE_INTERRUPTS);
18461697837eSRajnesh Kanwal     }
18471697837eSRajnesh Kanwal 
18481697837eSRajnesh Kanwal     return RISCV_EXCP_NONE;
18491697837eSRajnesh Kanwal }
18501697837eSRajnesh Kanwal 
rmw_mie(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)18511697837eSRajnesh Kanwal static RISCVException rmw_mie(CPURISCVState *env, int csrno,
18521697837eSRajnesh Kanwal                               target_ulong *ret_val,
18531697837eSRajnesh Kanwal                               target_ulong new_val, target_ulong wr_mask)
18541697837eSRajnesh Kanwal {
18551697837eSRajnesh Kanwal     uint64_t rval;
18561697837eSRajnesh Kanwal     RISCVException ret;
18571697837eSRajnesh Kanwal 
18581697837eSRajnesh Kanwal     ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
18591697837eSRajnesh Kanwal     if (ret_val) {
18601697837eSRajnesh Kanwal         *ret_val = rval;
18611697837eSRajnesh Kanwal     }
18621697837eSRajnesh Kanwal 
18631697837eSRajnesh Kanwal     return ret;
18641697837eSRajnesh Kanwal }
18651697837eSRajnesh Kanwal 
rmw_mieh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)18661697837eSRajnesh Kanwal static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
18671697837eSRajnesh Kanwal                                target_ulong *ret_val,
18681697837eSRajnesh Kanwal                                target_ulong new_val, target_ulong wr_mask)
18691697837eSRajnesh Kanwal {
18701697837eSRajnesh Kanwal     uint64_t rval;
18711697837eSRajnesh Kanwal     RISCVException ret;
18721697837eSRajnesh Kanwal 
18731697837eSRajnesh Kanwal     ret = rmw_mie64(env, csrno, &rval,
18741697837eSRajnesh Kanwal         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
18751697837eSRajnesh Kanwal     if (ret_val) {
18761697837eSRajnesh Kanwal         *ret_val = rval >> 32;
18771697837eSRajnesh Kanwal     }
18781697837eSRajnesh Kanwal 
18791697837eSRajnesh Kanwal     return ret;
18801697837eSRajnesh Kanwal }
18811697837eSRajnesh Kanwal 
rmw_mvien64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)18821697837eSRajnesh Kanwal static RISCVException rmw_mvien64(CPURISCVState *env, int csrno,
18831697837eSRajnesh Kanwal                                 uint64_t *ret_val,
18841697837eSRajnesh Kanwal                                 uint64_t new_val, uint64_t wr_mask)
18851697837eSRajnesh Kanwal {
18861697837eSRajnesh Kanwal     uint64_t mask = wr_mask & mvien_writable_mask;
18871697837eSRajnesh Kanwal 
18881697837eSRajnesh Kanwal     if (ret_val) {
18891697837eSRajnesh Kanwal         *ret_val = env->mvien;
1890a5cb044cSLIU Zhiwei     }
1891a5cb044cSLIU Zhiwei 
1892c7de92b4SAnup Patel     env->mvien = (env->mvien & ~mask) | (new_val & mask);
1893c7de92b4SAnup Patel 
1894c7de92b4SAnup Patel     return RISCV_EXCP_NONE;
1895c7de92b4SAnup Patel }
1896c7de92b4SAnup Patel 
rmw_mvien(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1897c7de92b4SAnup Patel static RISCVException rmw_mvien(CPURISCVState *env, int csrno,
1898c7de92b4SAnup Patel                               target_ulong *ret_val,
1899c7de92b4SAnup Patel                               target_ulong new_val, target_ulong wr_mask)
1900c7de92b4SAnup Patel {
1901c7de92b4SAnup Patel     uint64_t rval;
1902c7de92b4SAnup Patel     RISCVException ret;
1903c7de92b4SAnup Patel 
1904c7de92b4SAnup Patel     ret = rmw_mvien64(env, csrno, &rval, new_val, wr_mask);
1905c7de92b4SAnup Patel     if (ret_val) {
1906c7de92b4SAnup Patel         *ret_val = rval;
1907c7de92b4SAnup Patel     }
1908c7de92b4SAnup Patel 
1909c7de92b4SAnup Patel     return ret;
1910c7de92b4SAnup Patel }
1911c7de92b4SAnup Patel 
rmw_mvienh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)1912c7de92b4SAnup Patel static RISCVException rmw_mvienh(CPURISCVState *env, int csrno,
1913d1ceff40SAnup Patel                                 target_ulong *ret_val,
1914d1ceff40SAnup Patel                                 target_ulong new_val, target_ulong wr_mask)
191538256529SWeiwei Li {
1916d1ceff40SAnup Patel     uint64_t rval;
1917d1ceff40SAnup Patel     RISCVException ret;
1918d1ceff40SAnup Patel 
1919d1ceff40SAnup Patel     ret = rmw_mvien64(env, csrno, &rval,
1920d1ceff40SAnup Patel         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1921d1ceff40SAnup Patel     if (ret_val) {
1922d1ceff40SAnup Patel         *ret_val = rval >> 32;
1923d1ceff40SAnup Patel     }
1924ac4b0302SAnup Patel 
1925ac4b0302SAnup Patel     return ret;
1926d1ceff40SAnup Patel }
1927d1ceff40SAnup Patel 
read_mtopi(CPURISCVState * env,int csrno,target_ulong * val)1928d1ceff40SAnup Patel static RISCVException read_mtopi(CPURISCVState *env, int csrno,
1929d1ceff40SAnup Patel                                  target_ulong *val)
1930d1ceff40SAnup Patel {
1931a5cb044cSLIU Zhiwei     int irq;
1932a5cb044cSLIU Zhiwei     uint8_t iprio;
1933a5cb044cSLIU Zhiwei 
1934d1ceff40SAnup Patel     irq = riscv_cpu_mirq_pending(env);
1935d1ceff40SAnup Patel     if (irq <= 0 || irq > 63) {
1936d1ceff40SAnup Patel         *val = 0;
1937d1ceff40SAnup Patel     } else {
1938d1ceff40SAnup Patel         iprio = env->miprio[irq];
1939d1ceff40SAnup Patel         if (!iprio) {
1940d1ceff40SAnup Patel             if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) {
1941d1ceff40SAnup Patel                 iprio = IPRIO_MMAXIPRIO;
1942d1ceff40SAnup Patel             }
1943d1ceff40SAnup Patel         }
1944d1ceff40SAnup Patel         *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
1945d1ceff40SAnup Patel         *val |= iprio;
1946d1ceff40SAnup Patel     }
1947d1ceff40SAnup Patel 
1948d1ceff40SAnup Patel     return RISCV_EXCP_NONE;
1949d1ceff40SAnup Patel }
1950d1ceff40SAnup Patel 
aia_xlate_vs_csrno(CPURISCVState * env,int csrno)1951d1ceff40SAnup Patel static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
1952d1ceff40SAnup Patel {
1953d1ceff40SAnup Patel     if (!env->virt_enabled) {
1954d1ceff40SAnup Patel         return csrno;
1955d1ceff40SAnup Patel     }
1956d1ceff40SAnup Patel 
1957d1ceff40SAnup Patel     switch (csrno) {
1958d1ceff40SAnup Patel     case CSR_SISELECT:
1959d1ceff40SAnup Patel         return CSR_VSISELECT;
1960d1ceff40SAnup Patel     case CSR_SIREG:
1961d1ceff40SAnup Patel         return CSR_VSIREG;
1962d1ceff40SAnup Patel     case CSR_STOPEI:
1963d1ceff40SAnup Patel         return CSR_VSTOPEI;
1964d1ceff40SAnup Patel     default:
1965d1ceff40SAnup Patel         return csrno;
1966d1ceff40SAnup Patel     };
1967d1ceff40SAnup Patel }
1968d1ceff40SAnup Patel 
rmw_xiselect(CPURISCVState * env,int csrno,target_ulong * val,target_ulong new_val,target_ulong wr_mask)1969d1ceff40SAnup Patel static RISCVException rmw_xiselect(CPURISCVState *env, int csrno,
1970d1ceff40SAnup Patel                                    target_ulong *val, target_ulong new_val,
1971d1ceff40SAnup Patel                                    target_ulong wr_mask)
1972d1ceff40SAnup Patel {
1973d1ceff40SAnup Patel     target_ulong *iselect;
1974d1ceff40SAnup Patel 
1975d1ceff40SAnup Patel     /* Translate CSR number for VS-mode */
1976d1ceff40SAnup Patel     csrno = aia_xlate_vs_csrno(env, csrno);
1977d1ceff40SAnup Patel 
1978d1ceff40SAnup Patel     /* Find the iselect CSR based on CSR number */
1979d1ceff40SAnup Patel     switch (csrno) {
1980d1ceff40SAnup Patel     case CSR_MISELECT:
1981d1ceff40SAnup Patel         iselect = &env->miselect;
1982d1ceff40SAnup Patel         break;
1983d1ceff40SAnup Patel     case CSR_SISELECT:
1984d1ceff40SAnup Patel         iselect = &env->siselect;
1985d1ceff40SAnup Patel         break;
1986d1ceff40SAnup Patel     case CSR_VSISELECT:
1987d1ceff40SAnup Patel         iselect = &env->vsiselect;
1988d1ceff40SAnup Patel         break;
1989d1ceff40SAnup Patel     default:
1990d1ceff40SAnup Patel          return RISCV_EXCP_ILLEGAL_INST;
1991d1ceff40SAnup Patel     };
1992d1ceff40SAnup Patel 
1993d1ceff40SAnup Patel     if (val) {
1994d1ceff40SAnup Patel         *val = *iselect;
1995d1ceff40SAnup Patel     }
1996d1ceff40SAnup Patel 
1997d1ceff40SAnup Patel     wr_mask &= ISELECT_MASK;
1998d1ceff40SAnup Patel     if (wr_mask) {
1999d1ceff40SAnup Patel         *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
2000d1ceff40SAnup Patel     }
2001d1ceff40SAnup Patel 
2002d1ceff40SAnup Patel     return RISCV_EXCP_NONE;
2003d1ceff40SAnup Patel }
2004d1ceff40SAnup Patel 
rmw_iprio(target_ulong xlen,target_ulong iselect,uint8_t * iprio,target_ulong * val,target_ulong new_val,target_ulong wr_mask,int ext_irq_no)2005d1ceff40SAnup Patel static int rmw_iprio(target_ulong xlen,
2006d1ceff40SAnup Patel                      target_ulong iselect, uint8_t *iprio,
2007d1ceff40SAnup Patel                      target_ulong *val, target_ulong new_val,
2008d1ceff40SAnup Patel                      target_ulong wr_mask, int ext_irq_no)
2009d1ceff40SAnup Patel {
2010d1ceff40SAnup Patel     int i, firq, nirqs;
2011d1ceff40SAnup Patel     target_ulong old_val;
2012a5cb044cSLIU Zhiwei 
2013a5cb044cSLIU Zhiwei     if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
2014a5cb044cSLIU Zhiwei         return -EINVAL;
2015d1ceff40SAnup Patel     }
20164df28233STommy Wu     if (xlen != 32 && iselect & 0x1) {
2017d1ceff40SAnup Patel         return -EINVAL;
2018d1ceff40SAnup Patel     }
2019d1ceff40SAnup Patel 
2020d1ceff40SAnup Patel     nirqs = 4 * (xlen / 32);
2021d1ceff40SAnup Patel     firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
2022d1ceff40SAnup Patel 
2023d1ceff40SAnup Patel     old_val = 0;
2024d1ceff40SAnup Patel     for (i = 0; i < nirqs; i++) {
2025d1ceff40SAnup Patel         old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i);
20264df28233STommy Wu     }
2027d1ceff40SAnup Patel 
2028d1ceff40SAnup Patel     if (val) {
2029d1ceff40SAnup Patel         *val = old_val;
2030d1ceff40SAnup Patel     }
2031d1ceff40SAnup Patel 
2032d1ceff40SAnup Patel     if (wr_mask) {
2033d1ceff40SAnup Patel         new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
20341697837eSRajnesh Kanwal         for (i = 0; i < nirqs; i++) {
20351697837eSRajnesh Kanwal             /*
20361697837eSRajnesh Kanwal              * M-level and S-level external IRQ priority always read-only
20371697837eSRajnesh Kanwal              * zero. This means default priority order is always preferred
20381697837eSRajnesh Kanwal              * for M-level and S-level external IRQs.
2039d1ceff40SAnup Patel              */
2040d1ceff40SAnup Patel             if ((firq + i) == ext_irq_no) {
2041d1ceff40SAnup Patel                 continue;
2042d1ceff40SAnup Patel             }
2043d1ceff40SAnup Patel             iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
2044d1ceff40SAnup Patel         }
2045d1ceff40SAnup Patel     }
2046d1ceff40SAnup Patel 
2047d1ceff40SAnup Patel     return 0;
2048d1ceff40SAnup Patel }
2049d1ceff40SAnup Patel 
rmw_xireg(CPURISCVState * env,int csrno,target_ulong * val,target_ulong new_val,target_ulong wr_mask)2050d1ceff40SAnup Patel static RISCVException rmw_xireg(CPURISCVState *env, int csrno,
2051d1ceff40SAnup Patel                                 target_ulong *val, target_ulong new_val,
2052d1ceff40SAnup Patel                                 target_ulong wr_mask)
2053d1ceff40SAnup Patel {
2054d1ceff40SAnup Patel     bool virt, isel_reserved;
2055d1ceff40SAnup Patel     uint8_t *iprio;
2056d1ceff40SAnup Patel     int ret = -EINVAL;
2057d1ceff40SAnup Patel     target_ulong priv, isel, vgein;
2058d1ceff40SAnup Patel 
2059d1ceff40SAnup Patel     /* Translate CSR number for VS-mode */
2060d1ceff40SAnup Patel     csrno = aia_xlate_vs_csrno(env, csrno);
2061d1ceff40SAnup Patel 
2062d1ceff40SAnup Patel     /* Decode register details from CSR number */
2063d1ceff40SAnup Patel     virt = false;
2064d1ceff40SAnup Patel     isel_reserved = false;
2065d1ceff40SAnup Patel     switch (csrno) {
2066d1ceff40SAnup Patel     case CSR_MIREG:
2067d1ceff40SAnup Patel         iprio = env->miprio;
2068d1ceff40SAnup Patel         isel = env->miselect;
2069d1ceff40SAnup Patel         priv = PRV_M;
2070d1ceff40SAnup Patel         break;
2071d1ceff40SAnup Patel     case CSR_SIREG:
2072d1ceff40SAnup Patel         if (env->priv == PRV_S && env->mvien & MIP_SEIP &&
2073d1ceff40SAnup Patel             env->siselect >= ISELECT_IMSIC_EIDELIVERY &&
2074d1ceff40SAnup Patel             env->siselect <= ISELECT_IMSIC_EIE63) {
2075d1ceff40SAnup Patel             goto done;
20764df28233STommy Wu         }
20774df28233STommy Wu         iprio = env->siprio;
2078d1ceff40SAnup Patel         isel = env->siselect;
2079d1ceff40SAnup Patel         priv = PRV_S;
2080d1ceff40SAnup Patel         break;
2081d1ceff40SAnup Patel     case CSR_VSIREG:
20824df28233STommy Wu         iprio = env->hviprio;
2083d1ceff40SAnup Patel         isel = env->vsiselect;
2084d1ceff40SAnup Patel         priv = PRV_S;
2085d1ceff40SAnup Patel         virt = true;
2086d1ceff40SAnup Patel         break;
2087d1ceff40SAnup Patel     default:
2088a5cb044cSLIU Zhiwei          goto done;
2089a5cb044cSLIU Zhiwei     };
2090a5cb044cSLIU Zhiwei 
2091ac4b0302SAnup Patel     /* Find the selected guest interrupt file */
2092ac4b0302SAnup Patel     vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
2093ac4b0302SAnup Patel 
2094ac4b0302SAnup Patel     if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
2095ac4b0302SAnup Patel         /* Local interrupt priority registers not available for VS-mode */
2096ac4b0302SAnup Patel         if (!virt) {
2097ac4b0302SAnup Patel             ret = rmw_iprio(riscv_cpu_mxl_bits(env),
2098ac4b0302SAnup Patel                             isel, iprio, val, new_val, wr_mask,
2099ac4b0302SAnup Patel                             (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
2100ac4b0302SAnup Patel         }
2101ac4b0302SAnup Patel     } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) {
2102ac4b0302SAnup Patel         /* IMSIC registers only available when machine implements it. */
2103ac4b0302SAnup Patel         if (env->aia_ireg_rmw_fn[priv]) {
2104ac4b0302SAnup Patel             /* Selected guest interrupt file should not be zero */
2105ac4b0302SAnup Patel             if (virt && (!vgein || env->geilen < vgein)) {
21061697837eSRajnesh Kanwal                 goto done;
21071697837eSRajnesh Kanwal             }
21081697837eSRajnesh Kanwal             /* Call machine specific IMSIC register emulation */
2109ac4b0302SAnup Patel             ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
2110ac4b0302SAnup Patel                                     AIA_MAKE_IREG(isel, priv, virt, vgein,
2111ac4b0302SAnup Patel                                                   riscv_cpu_mxl_bits(env)),
2112ac4b0302SAnup Patel                                     val, new_val, wr_mask);
2113ac4b0302SAnup Patel         }
2114ac4b0302SAnup Patel     } else {
2115ac4b0302SAnup Patel         isel_reserved = true;
2116ac4b0302SAnup Patel     }
2117ac4b0302SAnup Patel 
2118ac4b0302SAnup Patel done:
2119ac4b0302SAnup Patel     if (ret) {
2120ac4b0302SAnup Patel         return (env->virt_enabled && virt && !isel_reserved) ?
2121ac4b0302SAnup Patel                RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2122ac4b0302SAnup Patel     }
2123ac4b0302SAnup Patel     return RISCV_EXCP_NONE;
2124ac4b0302SAnup Patel }
2125ac4b0302SAnup Patel 
rmw_xtopei(CPURISCVState * env,int csrno,target_ulong * val,target_ulong new_val,target_ulong wr_mask)2126ac4b0302SAnup Patel static RISCVException rmw_xtopei(CPURISCVState *env, int csrno,
2127ac4b0302SAnup Patel                                  target_ulong *val, target_ulong new_val,
2128ac4b0302SAnup Patel                                  target_ulong wr_mask)
2129ac4b0302SAnup Patel {
2130ac4b0302SAnup Patel     bool virt;
2131ac4b0302SAnup Patel     int ret = -EINVAL;
2132ac4b0302SAnup Patel     target_ulong priv, vgein;
2133ac4b0302SAnup Patel 
2134ac4b0302SAnup Patel     /* Translate CSR number for VS-mode */
2135ac4b0302SAnup Patel     csrno = aia_xlate_vs_csrno(env, csrno);
2136ac4b0302SAnup Patel 
2137ac4b0302SAnup Patel     /* Decode register details from CSR number */
2138ac4b0302SAnup Patel     virt = false;
2139ac4b0302SAnup Patel     switch (csrno) {
214038256529SWeiwei Li     case CSR_MTOPEI:
2141ac4b0302SAnup Patel         priv = PRV_M;
2142ac4b0302SAnup Patel         break;
2143ac4b0302SAnup Patel     case CSR_STOPEI:
2144ac4b0302SAnup Patel         if (env->mvien & MIP_SEIP && env->priv == PRV_S) {
2145ac4b0302SAnup Patel             goto done;
2146605def6eSAlistair Francis         }
2147605def6eSAlistair Francis         priv = PRV_S;
2148c7b95171SMichael Clark         break;
2149c7b95171SMichael Clark     case CSR_VSTOPEI:
2150605def6eSAlistair Francis         priv = PRV_S;
2151c7b95171SMichael Clark         virt = true;
2152c7b95171SMichael Clark         break;
2153605def6eSAlistair Francis     default:
2154605def6eSAlistair Francis         goto done;
2155c7b95171SMichael Clark     };
2156c7b95171SMichael Clark 
2157acbbb94eSMichael Clark     /* IMSIC CSRs only available when machine implements IMSIC. */
2158acbbb94eSMichael Clark     if (!env->aia_ireg_rmw_fn[priv]) {
2159c7b95171SMichael Clark         goto done;
2160acbbb94eSMichael Clark     }
2161c7b95171SMichael Clark 
2162605def6eSAlistair Francis     /* Find the selected guest interrupt file */
2163c7b95171SMichael Clark     vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
2164c7b95171SMichael Clark 
2165b1675eebSAtish Patra     /* Selected guest interrupt file should be valid */
2166b1675eebSAtish Patra     if (virt && (!vgein || env->geilen < vgein)) {
2167b1675eebSAtish Patra         goto done;
2168b1675eebSAtish Patra     }
2169b1675eebSAtish Patra 
2170b1675eebSAtish Patra     /* Call machine specific IMSIC register emulation for TOPEI */
2171b1675eebSAtish Patra     ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
2172b1675eebSAtish Patra                     AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein,
2173b1675eebSAtish Patra                                   riscv_cpu_mxl_bits(env)),
2174b1675eebSAtish Patra                     val, new_val, wr_mask);
21753780e337SAtish Patra 
21763780e337SAtish Patra done:
2177ebe16b90SRob Bradford     if (ret) {
217822c721c3SRajnesh Kanwal         return (env->virt_enabled && virt) ?
217922c721c3SRajnesh Kanwal                RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
218022c721c3SRajnesh Kanwal     }
21813780e337SAtish Patra     return RISCV_EXCP_NONE;
2182ebe16b90SRob Bradford }
218322c721c3SRajnesh Kanwal 
read_mtvec(CPURISCVState * env,int csrno,target_ulong * val)21843780e337SAtish Patra static RISCVException read_mtvec(CPURISCVState *env, int csrno,
21853780e337SAtish Patra                                  target_ulong *val)
21863780e337SAtish Patra {
218722c721c3SRajnesh Kanwal     *val = env->mtvec;
218822c721c3SRajnesh Kanwal     return RISCV_EXCP_NONE;
218922c721c3SRajnesh Kanwal }
219022c721c3SRajnesh Kanwal 
write_mtvec(CPURISCVState * env,int csrno,target_ulong val)219146023470SAtish Patra static RISCVException write_mtvec(CPURISCVState *env, int csrno,
219222c721c3SRajnesh Kanwal                                   target_ulong val)
219322c721c3SRajnesh Kanwal {
219422c721c3SRajnesh Kanwal     /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
219522c721c3SRajnesh Kanwal     if ((val & 3) < 2) {
219622c721c3SRajnesh Kanwal         env->mtvec = val;
219722c721c3SRajnesh Kanwal     } else {
219822c721c3SRajnesh Kanwal         qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
219922c721c3SRajnesh Kanwal     }
220022c721c3SRajnesh Kanwal     return RISCV_EXCP_NONE;
220122c721c3SRajnesh Kanwal }
220222c721c3SRajnesh Kanwal 
read_mcountinhibit(CPURISCVState * env,int csrno,target_ulong * val)220322c721c3SRajnesh Kanwal static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
220422c721c3SRajnesh Kanwal                                          target_ulong *val)
220522c721c3SRajnesh Kanwal {
220622c721c3SRajnesh Kanwal     *val = env->mcountinhibit;
220722c721c3SRajnesh Kanwal     return RISCV_EXCP_NONE;
220822c721c3SRajnesh Kanwal }
220922c721c3SRajnesh Kanwal 
write_mcountinhibit(CPURISCVState * env,int csrno,target_ulong val)221022c721c3SRajnesh Kanwal static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
221122c721c3SRajnesh Kanwal                                           target_ulong val)
221222c721c3SRajnesh Kanwal {
221322c721c3SRajnesh Kanwal     int cidx;
221422c721c3SRajnesh Kanwal     PMUCTRState *counter;
221522c721c3SRajnesh Kanwal     RISCVCPU *cpu = env_archcpu(env);
221622c721c3SRajnesh Kanwal     uint32_t present_ctrs = cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR;
221722c721c3SRajnesh Kanwal     target_ulong updated_ctrs = (env->mcountinhibit ^ val) & present_ctrs;
221822c721c3SRajnesh Kanwal     uint64_t mhpmctr_val, prev_count, curr_count;
221922c721c3SRajnesh Kanwal 
222022c721c3SRajnesh Kanwal     /* WARL register - disable unavailable counters; TM bit is always 0 */
222122c721c3SRajnesh Kanwal     env->mcountinhibit = val & present_ctrs;
222222c721c3SRajnesh Kanwal 
222322c721c3SRajnesh Kanwal     /* Check if any other counter is also monitoring cycles/instructions */
222422c721c3SRajnesh Kanwal     for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
222522c721c3SRajnesh Kanwal         if (!(updated_ctrs & BIT(cidx)) ||
222622c721c3SRajnesh Kanwal             (!riscv_pmu_ctr_monitor_cycles(env, cidx) &&
222722c721c3SRajnesh Kanwal             !riscv_pmu_ctr_monitor_instructions(env, cidx))) {
222822c721c3SRajnesh Kanwal             continue;
222922c721c3SRajnesh Kanwal         }
223022c721c3SRajnesh Kanwal 
223122c721c3SRajnesh Kanwal         counter = &env->pmu_ctrs[cidx];
223246023470SAtish Patra 
22333780e337SAtish Patra         if (!get_field(env->mcountinhibit, BIT(cidx))) {
22343780e337SAtish Patra             counter->mhpmcounter_prev =
22353780e337SAtish Patra                 riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false);
2236b1675eebSAtish Patra             if (riscv_cpu_mxl(env) == MXL_RV32) {
2237b1675eebSAtish Patra                 counter->mhpmcounterh_prev =
2238b1675eebSAtish Patra                     riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
2239605def6eSAlistair Francis             }
2240605def6eSAlistair Francis 
2241c7b95171SMichael Clark             if (cidx > 2) {
2242c7b95171SMichael Clark                 mhpmctr_val = counter->mhpmcounter_val;
2243605def6eSAlistair Francis                 if (riscv_cpu_mxl(env) == MXL_RV32) {
2244c7b95171SMichael Clark                     mhpmctr_val = mhpmctr_val |
2245c7b95171SMichael Clark                             ((uint64_t)counter->mhpmcounterh_val << 32);
2246605def6eSAlistair Francis                 }
2247605def6eSAlistair Francis                 riscv_pmu_setup_timer(env, mhpmctr_val, cidx);
2248c7b95171SMichael Clark             }
2249ebe16b90SRob Bradford         } else {
2250ebe16b90SRob Bradford             curr_count = riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false);
2251ebe16b90SRob Bradford 
2252ebe16b90SRob Bradford             mhpmctr_val = counter->mhpmcounter_val;
2253ebe16b90SRob Bradford             prev_count = counter->mhpmcounter_prev;
2254605def6eSAlistair Francis             if (riscv_cpu_mxl(env) == MXL_RV32) {
2255c7b95171SMichael Clark                 uint64_t tmp =
2256c7b95171SMichael Clark                     riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
2257c7b95171SMichael Clark 
2258457c360fSFrédéric Pétrot                 curr_count = curr_count | (tmp << 32);
2259457c360fSFrédéric Pétrot                 mhpmctr_val = mhpmctr_val |
2260457c360fSFrédéric Pétrot                     ((uint64_t)counter->mhpmcounterh_val << 32);
2261457c360fSFrédéric Pétrot                 prev_count = prev_count |
2262457c360fSFrédéric Pétrot                     ((uint64_t)counter->mhpmcounterh_prev << 32);
2263457c360fSFrédéric Pétrot             }
2264457c360fSFrédéric Pétrot 
2265457c360fSFrédéric Pétrot             /* Adjust the counter for later reads. */
2266457c360fSFrédéric Pétrot             mhpmctr_val = curr_count - prev_count + mhpmctr_val;
2267457c360fSFrédéric Pétrot             counter->mhpmcounter_val = mhpmctr_val;
2268457c360fSFrédéric Pétrot             if (riscv_cpu_mxl(env) == MXL_RV32) {
2269457c360fSFrédéric Pétrot                 counter->mhpmcounterh_val = mhpmctr_val >> 32;
2270457c360fSFrédéric Pétrot             }
2271457c360fSFrédéric Pétrot         }
2272457c360fSFrédéric Pétrot     }
2273605def6eSAlistair Francis 
2274605def6eSAlistair Francis     return RISCV_EXCP_NONE;
2275c7b95171SMichael Clark }
2276c7b95171SMichael Clark 
read_mcounteren(CPURISCVState * env,int csrno,target_ulong * val)2277605def6eSAlistair Francis static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
2278c7b95171SMichael Clark                                       target_ulong *val)
2279c7b95171SMichael Clark {
2280605def6eSAlistair Francis     *val = env->mcounteren;
2281605def6eSAlistair Francis     return RISCV_EXCP_NONE;
2282c7b95171SMichael Clark }
2283c7b95171SMichael Clark 
write_mcounteren(CPURISCVState * env,int csrno,target_ulong val)2284605def6eSAlistair Francis static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
2285c7b95171SMichael Clark                                        target_ulong val)
2286c7b95171SMichael Clark {
2287605def6eSAlistair Francis     RISCVCPU *cpu = env_archcpu(env);
2288605def6eSAlistair Francis 
2289c7b95171SMichael Clark     /* WARL register - disable unavailable counters */
2290c7b95171SMichael Clark     env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
2291605def6eSAlistair Francis                              COUNTEREN_IR);
2292c7b95171SMichael Clark     return RISCV_EXCP_NONE;
2293c7b95171SMichael Clark }
2294605def6eSAlistair Francis 
2295605def6eSAlistair Francis /* Machine Trap Handling */
read_mscratch_i128(CPURISCVState * env,int csrno,Int128 * val)2296c7b95171SMichael Clark static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
2297c7b95171SMichael Clark                                          Int128 *val)
2298605def6eSAlistair Francis {
2299c7b95171SMichael Clark     *val = int128_make128(env->mscratch, env->mscratchh);
2300c7b95171SMichael Clark     return RISCV_EXCP_NONE;
2301605def6eSAlistair Francis }
2302605def6eSAlistair Francis 
write_mscratch_i128(CPURISCVState * env,int csrno,Int128 val)2303c7b95171SMichael Clark static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
2304c7b95171SMichael Clark                                           Int128 val)
2305605def6eSAlistair Francis {
2306c7b95171SMichael Clark     env->mscratch = int128_getlo(val);
2307c7b95171SMichael Clark     env->mscratchh = int128_gethi(val);
2308605def6eSAlistair Francis     return RISCV_EXCP_NONE;
2309605def6eSAlistair Francis }
2310c7b95171SMichael Clark 
read_mscratch(CPURISCVState * env,int csrno,target_ulong * val)2311c7b95171SMichael Clark static RISCVException read_mscratch(CPURISCVState *env, int csrno,
2312605def6eSAlistair Francis                                     target_ulong *val)
2313c7b95171SMichael Clark {
2314c7b95171SMichael Clark     *val = env->mscratch;
2315605def6eSAlistair Francis     return RISCV_EXCP_NONE;
2316605def6eSAlistair Francis }
2317c7b95171SMichael Clark 
write_mscratch(CPURISCVState * env,int csrno,target_ulong val)2318ac12b601SAtish Patra static RISCVException write_mscratch(CPURISCVState *env, int csrno,
2319605def6eSAlistair Francis                                      target_ulong val)
2320c7b95171SMichael Clark {
2321c7b95171SMichael Clark     env->mscratch = val;
2322605def6eSAlistair Francis     return RISCV_EXCP_NONE;
2323605def6eSAlistair Francis }
2324c7b95171SMichael Clark 
read_mepc(CPURISCVState * env,int csrno,target_ulong * val)2325ac12b601SAtish Patra static RISCVException read_mepc(CPURISCVState *env, int csrno,
2326605def6eSAlistair Francis                                 target_ulong *val)
2327c7b95171SMichael Clark {
2328c7b95171SMichael Clark     *val = env->mepc;
232929a9ec9bSAtish Patra     return RISCV_EXCP_NONE;
233029a9ec9bSAtish Patra }
233129a9ec9bSAtish Patra 
write_mepc(CPURISCVState * env,int csrno,target_ulong val)233229a9ec9bSAtish Patra static RISCVException write_mepc(CPURISCVState *env, int csrno,
233329a9ec9bSAtish Patra                                  target_ulong val)
233429a9ec9bSAtish Patra {
233529a9ec9bSAtish Patra     env->mepc = val;
233629a9ec9bSAtish Patra     return RISCV_EXCP_NONE;
233729a9ec9bSAtish Patra }
233829a9ec9bSAtish Patra 
read_mcause(CPURISCVState * env,int csrno,target_ulong * val)233929a9ec9bSAtish Patra static RISCVException read_mcause(CPURISCVState *env, int csrno,
23409c33e08bSWeiwei Li                                   target_ulong *val)
234129a9ec9bSAtish Patra {
234229a9ec9bSAtish Patra     *val = env->mcause;
234329a9ec9bSAtish Patra     return RISCV_EXCP_NONE;
234473ec0eadSWeiwei Li }
23450d190bd3SWeiwei Li 
write_mcause(CPURISCVState * env,int csrno,target_ulong val)2346ed67d637SWeiwei Li static RISCVException write_mcause(CPURISCVState *env, int csrno,
234729a9ec9bSAtish Patra                                    target_ulong val)
234829a9ec9bSAtish Patra {
234929a9ec9bSAtish Patra     env->mcause = val;
235029a9ec9bSAtish Patra     return RISCV_EXCP_NONE;
235129a9ec9bSAtish Patra }
235229a9ec9bSAtish Patra 
read_mtval(CPURISCVState * env,int csrno,target_ulong * val)235329a9ec9bSAtish Patra static RISCVException read_mtval(CPURISCVState *env, int csrno,
235429a9ec9bSAtish Patra                                  target_ulong *val)
235529a9ec9bSAtish Patra {
235629a9ec9bSAtish Patra     *val = env->mtval;
235729a9ec9bSAtish Patra     return RISCV_EXCP_NONE;
235829a9ec9bSAtish Patra }
235929a9ec9bSAtish Patra 
write_mtval(CPURISCVState * env,int csrno,target_ulong val)236029a9ec9bSAtish Patra static RISCVException write_mtval(CPURISCVState *env, int csrno,
236129a9ec9bSAtish Patra                                   target_ulong val)
236229a9ec9bSAtish Patra {
23639c33e08bSWeiwei Li     env->mtval = val;
236473ec0eadSWeiwei Li     return RISCV_EXCP_NONE;
23650d190bd3SWeiwei Li }
2366ed67d637SWeiwei Li 
236729a9ec9bSAtish Patra /* Execution environment configuration setup */
read_menvcfg(CPURISCVState * env,int csrno,target_ulong * val)236829a9ec9bSAtish Patra static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
236929a9ec9bSAtish Patra                                    target_ulong *val)
237029a9ec9bSAtish Patra {
237129a9ec9bSAtish Patra     *val = env->menvcfg;
237229a9ec9bSAtish Patra     return RISCV_EXCP_NONE;
237329a9ec9bSAtish Patra }
237429a9ec9bSAtish Patra 
write_menvcfg(CPURISCVState * env,int csrno,target_ulong val)237529a9ec9bSAtish Patra static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
237629a9ec9bSAtish Patra                                     target_ulong val)
2377252b06f6SMayuresh Chitale {
2378252b06f6SMayuresh Chitale     const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
2379252b06f6SMayuresh Chitale     uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
2380252b06f6SMayuresh Chitale 
2381252b06f6SMayuresh Chitale     if (riscv_cpu_mxl(env) == MXL_RV64) {
2382252b06f6SMayuresh Chitale         mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
2383252b06f6SMayuresh Chitale                 (cfg->ext_sstc ? MENVCFG_STCE : 0) |
238429a9ec9bSAtish Patra                 (cfg->ext_svadu ? MENVCFG_ADUE : 0);
238529a9ec9bSAtish Patra 
238629a9ec9bSAtish Patra         if (env_archcpu(env)->cfg.ext_zicfilp) {
238729a9ec9bSAtish Patra             mask |= MENVCFG_LPE;
238829a9ec9bSAtish Patra         }
238929a9ec9bSAtish Patra 
239029a9ec9bSAtish Patra         if (env_archcpu(env)->cfg.ext_zicfiss) {
239129a9ec9bSAtish Patra             mask |= MENVCFG_SSE;
2392252b06f6SMayuresh Chitale         }
2393252b06f6SMayuresh Chitale     }
2394252b06f6SMayuresh Chitale     env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
2395252b06f6SMayuresh Chitale 
2396252b06f6SMayuresh Chitale     return RISCV_EXCP_NONE;
2397252b06f6SMayuresh Chitale }
239829a9ec9bSAtish Patra 
read_menvcfgh(CPURISCVState * env,int csrno,target_ulong * val)239929a9ec9bSAtish Patra static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
240029a9ec9bSAtish Patra                                     target_ulong *val)
240129a9ec9bSAtish Patra {
240229a9ec9bSAtish Patra     *val = env->menvcfg >> 32;
240329a9ec9bSAtish Patra     return RISCV_EXCP_NONE;
240429a9ec9bSAtish Patra }
240529a9ec9bSAtish Patra 
write_menvcfgh(CPURISCVState * env,int csrno,target_ulong val)2406252b06f6SMayuresh Chitale static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
2407252b06f6SMayuresh Chitale                                      target_ulong val)
2408252b06f6SMayuresh Chitale {
2409252b06f6SMayuresh Chitale     const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
2410252b06f6SMayuresh Chitale     uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
2411252b06f6SMayuresh Chitale                     (cfg->ext_sstc ? MENVCFG_STCE : 0) |
2412252b06f6SMayuresh Chitale                     (cfg->ext_svadu ? MENVCFG_ADUE : 0);
24136f3eb1a3SWeiwei Li     uint64_t valh = (uint64_t)val << 32;
24146f3eb1a3SWeiwei Li 
24156f3eb1a3SWeiwei Li     env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
2416148189ffSAndrew Jones 
24176f3eb1a3SWeiwei Li     return RISCV_EXCP_NONE;
2418ed67d637SWeiwei Li }
24190d190bd3SWeiwei Li 
read_senvcfg(CPURISCVState * env,int csrno,target_ulong * val)242029a9ec9bSAtish Patra static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
242129a9ec9bSAtish Patra                                    target_ulong *val)
242229a9ec9bSAtish Patra {
242329a9ec9bSAtish Patra     RISCVException ret;
242429a9ec9bSAtish Patra 
242529a9ec9bSAtish Patra     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
242629a9ec9bSAtish Patra     if (ret != RISCV_EXCP_NONE) {
2427252b06f6SMayuresh Chitale         return ret;
2428252b06f6SMayuresh Chitale     }
2429252b06f6SMayuresh Chitale 
2430252b06f6SMayuresh Chitale     *val = env->senvcfg;
2431252b06f6SMayuresh Chitale     return RISCV_EXCP_NONE;
2432252b06f6SMayuresh Chitale }
243329a9ec9bSAtish Patra 
write_senvcfg(CPURISCVState * env,int csrno,target_ulong val)243429a9ec9bSAtish Patra static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
2435ed67d637SWeiwei Li                                     target_ulong val)
243629a9ec9bSAtish Patra {
243729a9ec9bSAtish Patra     uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
243829a9ec9bSAtish Patra     RISCVException ret;
243929a9ec9bSAtish Patra 
244029a9ec9bSAtish Patra     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
244129a9ec9bSAtish Patra     if (ret != RISCV_EXCP_NONE) {
244229a9ec9bSAtish Patra         return ret;
244329a9ec9bSAtish Patra     }
244429a9ec9bSAtish Patra 
244529a9ec9bSAtish Patra     if (env_archcpu(env)->cfg.ext_zicfilp) {
2446252b06f6SMayuresh Chitale         mask |= SENVCFG_LPE;
2447252b06f6SMayuresh Chitale     }
2448252b06f6SMayuresh Chitale 
2449252b06f6SMayuresh Chitale     /* Higher mode SSE must be ON for next-less mode SSE to be ON */
2450252b06f6SMayuresh Chitale     if (env_archcpu(env)->cfg.ext_zicfiss &&
2451252b06f6SMayuresh Chitale         get_field(env->menvcfg, MENVCFG_SSE) &&
2452252b06f6SMayuresh Chitale         (env->virt_enabled ? get_field(env->henvcfg, HENVCFG_SSE) : true)) {
2453ed67d637SWeiwei Li         mask |= SENVCFG_SSE;
24546f3eb1a3SWeiwei Li     }
245529a9ec9bSAtish Patra 
245629a9ec9bSAtish Patra     env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
245729a9ec9bSAtish Patra     return RISCV_EXCP_NONE;
245829a9ec9bSAtish Patra }
245929a9ec9bSAtish Patra 
read_henvcfg(CPURISCVState * env,int csrno,target_ulong * val)246029a9ec9bSAtish Patra static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
24610d190bd3SWeiwei Li                                    target_ulong *val)
2462ed67d637SWeiwei Li {
246329a9ec9bSAtish Patra     RISCVException ret;
2464252b06f6SMayuresh Chitale 
2465252b06f6SMayuresh Chitale     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
2466252b06f6SMayuresh Chitale     if (ret != RISCV_EXCP_NONE) {
2467252b06f6SMayuresh Chitale         return ret;
2468252b06f6SMayuresh Chitale     }
2469252b06f6SMayuresh Chitale 
247029a9ec9bSAtish Patra     /*
247129a9ec9bSAtish Patra      * henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
247229a9ec9bSAtish Patra      * henvcfg.stce is read_only 0 when menvcfg.stce = 0
247329a9ec9bSAtish Patra      * henvcfg.adue is read_only 0 when menvcfg.adue = 0
247429a9ec9bSAtish Patra      */
24753bee0e40SMayuresh Chitale     *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
24763bee0e40SMayuresh Chitale                            env->menvcfg);
24773bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
24783bee0e40SMayuresh Chitale }
24793bee0e40SMayuresh Chitale 
write_henvcfg(CPURISCVState * env,int csrno,target_ulong val)24803bee0e40SMayuresh Chitale static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
24813bee0e40SMayuresh Chitale                                     target_ulong val)
24823bee0e40SMayuresh Chitale {
24833bee0e40SMayuresh Chitale     uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
24843bee0e40SMayuresh Chitale     RISCVException ret;
24853bee0e40SMayuresh Chitale 
24863bee0e40SMayuresh Chitale     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
24873bee0e40SMayuresh Chitale     if (ret != RISCV_EXCP_NONE) {
24883bee0e40SMayuresh Chitale         return ret;
24893bee0e40SMayuresh Chitale     }
24903bee0e40SMayuresh Chitale 
24913bee0e40SMayuresh Chitale     if (riscv_cpu_mxl(env) == MXL_RV64) {
24923bee0e40SMayuresh Chitale         mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
24933bee0e40SMayuresh Chitale 
24943bee0e40SMayuresh Chitale         if (env_archcpu(env)->cfg.ext_zicfilp) {
24953bee0e40SMayuresh Chitale             mask |= HENVCFG_LPE;
24963bee0e40SMayuresh Chitale         }
2497252b06f6SMayuresh Chitale 
24989514fc72SMayuresh Chitale         /* H can light up SSE for VS only if HS had it from menvcfg */
24999514fc72SMayuresh Chitale         if (env_archcpu(env)->cfg.ext_zicfiss &&
25009514fc72SMayuresh Chitale             get_field(env->menvcfg, MENVCFG_SSE)) {
25013bee0e40SMayuresh Chitale             mask |= HENVCFG_SSE;
25027750e106SFea.Wang         }
25037750e106SFea.Wang     }
25047750e106SFea.Wang 
25057750e106SFea.Wang     env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
25063bee0e40SMayuresh Chitale 
25073bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
25083bee0e40SMayuresh Chitale }
25093bee0e40SMayuresh Chitale 
read_henvcfgh(CPURISCVState * env,int csrno,target_ulong * val)25103bee0e40SMayuresh Chitale static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
25113bee0e40SMayuresh Chitale                                     target_ulong *val)
25123bee0e40SMayuresh Chitale {
25133bee0e40SMayuresh Chitale     RISCVException ret;
25143bee0e40SMayuresh Chitale 
25153bee0e40SMayuresh Chitale     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
25163bee0e40SMayuresh Chitale     if (ret != RISCV_EXCP_NONE) {
25173bee0e40SMayuresh Chitale         return ret;
25183bee0e40SMayuresh Chitale     }
25193bee0e40SMayuresh Chitale 
25203bee0e40SMayuresh Chitale     *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
25213bee0e40SMayuresh Chitale                             env->menvcfg)) >> 32;
25223bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
25233bee0e40SMayuresh Chitale }
25243bee0e40SMayuresh Chitale 
write_henvcfgh(CPURISCVState * env,int csrno,target_ulong val)25253bee0e40SMayuresh Chitale static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
25263bee0e40SMayuresh Chitale                                      target_ulong val)
25273bee0e40SMayuresh Chitale {
25283bee0e40SMayuresh Chitale     uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
25293bee0e40SMayuresh Chitale                                     HENVCFG_ADUE);
25303bee0e40SMayuresh Chitale     uint64_t valh = (uint64_t)val << 32;
25313bee0e40SMayuresh Chitale     RISCVException ret;
25323bee0e40SMayuresh Chitale 
25333bee0e40SMayuresh Chitale     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
25343bee0e40SMayuresh Chitale     if (ret != RISCV_EXCP_NONE) {
25353bee0e40SMayuresh Chitale         return ret;
25363bee0e40SMayuresh Chitale     }
25373bee0e40SMayuresh Chitale 
25383bee0e40SMayuresh Chitale     env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
2539252b06f6SMayuresh Chitale     return RISCV_EXCP_NONE;
25403bee0e40SMayuresh Chitale }
25417750e106SFea.Wang 
read_mstateen(CPURISCVState * env,int csrno,target_ulong * val)25427750e106SFea.Wang static RISCVException read_mstateen(CPURISCVState *env, int csrno,
25437750e106SFea.Wang                                     target_ulong *val)
25447750e106SFea.Wang {
25453bee0e40SMayuresh Chitale     *val = env->mstateen[csrno - CSR_MSTATEEN0];
25463bee0e40SMayuresh Chitale 
25473bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
25483bee0e40SMayuresh Chitale }
25493bee0e40SMayuresh Chitale 
write_mstateen(CPURISCVState * env,int csrno,uint64_t wr_mask,target_ulong new_val)25503bee0e40SMayuresh Chitale static RISCVException write_mstateen(CPURISCVState *env, int csrno,
25513bee0e40SMayuresh Chitale                                      uint64_t wr_mask, target_ulong new_val)
25523bee0e40SMayuresh Chitale {
25533bee0e40SMayuresh Chitale     uint64_t *reg;
25543bee0e40SMayuresh Chitale 
25553bee0e40SMayuresh Chitale     reg = &env->mstateen[csrno - CSR_MSTATEEN0];
25563bee0e40SMayuresh Chitale     *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
25573bee0e40SMayuresh Chitale 
25583bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
25593bee0e40SMayuresh Chitale }
25603bee0e40SMayuresh Chitale 
write_mstateen0(CPURISCVState * env,int csrno,target_ulong new_val)25613bee0e40SMayuresh Chitale static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
25623bee0e40SMayuresh Chitale                                       target_ulong new_val)
25633bee0e40SMayuresh Chitale {
25643bee0e40SMayuresh Chitale     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
25653bee0e40SMayuresh Chitale     if (!riscv_has_ext(env, RVF)) {
25663bee0e40SMayuresh Chitale         wr_mask |= SMSTATEEN0_FCSR;
25673bee0e40SMayuresh Chitale     }
25683bee0e40SMayuresh Chitale 
25693bee0e40SMayuresh Chitale     if (env->priv_ver >= PRIV_VERSION_1_13_0) {
25703bee0e40SMayuresh Chitale         wr_mask |= SMSTATEEN0_P1P13;
25713bee0e40SMayuresh Chitale     }
25723bee0e40SMayuresh Chitale 
25733bee0e40SMayuresh Chitale     return write_mstateen(env, csrno, wr_mask, new_val);
25743bee0e40SMayuresh Chitale }
25753bee0e40SMayuresh Chitale 
write_mstateen_1_3(CPURISCVState * env,int csrno,target_ulong new_val)25763bee0e40SMayuresh Chitale static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
25773bee0e40SMayuresh Chitale                                          target_ulong new_val)
25783bee0e40SMayuresh Chitale {
25793bee0e40SMayuresh Chitale     return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2580252b06f6SMayuresh Chitale }
25813bee0e40SMayuresh Chitale 
read_mstateenh(CPURISCVState * env,int csrno,target_ulong * val)25829514fc72SMayuresh Chitale static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
25839514fc72SMayuresh Chitale                                      target_ulong *val)
25849514fc72SMayuresh Chitale {
25859514fc72SMayuresh Chitale     *val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
25863bee0e40SMayuresh Chitale 
25873bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
25883bee0e40SMayuresh Chitale }
25893bee0e40SMayuresh Chitale 
write_mstateenh(CPURISCVState * env,int csrno,uint64_t wr_mask,target_ulong new_val)25903bee0e40SMayuresh Chitale static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
25913bee0e40SMayuresh Chitale                                       uint64_t wr_mask, target_ulong new_val)
25923bee0e40SMayuresh Chitale {
25933bee0e40SMayuresh Chitale     uint64_t *reg, val;
25943bee0e40SMayuresh Chitale 
25953bee0e40SMayuresh Chitale     reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
25963bee0e40SMayuresh Chitale     val = (uint64_t)new_val << 32;
25973bee0e40SMayuresh Chitale     val |= *reg & 0xFFFFFFFF;
25983bee0e40SMayuresh Chitale     *reg = (*reg & ~wr_mask) | (val & wr_mask);
25993bee0e40SMayuresh Chitale 
26003bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
26013bee0e40SMayuresh Chitale }
26023bee0e40SMayuresh Chitale 
write_mstateen0h(CPURISCVState * env,int csrno,target_ulong new_val)26033bee0e40SMayuresh Chitale static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
26043bee0e40SMayuresh Chitale                                        target_ulong new_val)
26053bee0e40SMayuresh Chitale {
26063bee0e40SMayuresh Chitale     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
26073bee0e40SMayuresh Chitale 
26083bee0e40SMayuresh Chitale     if (env->priv_ver >= PRIV_VERSION_1_13_0) {
26093bee0e40SMayuresh Chitale         wr_mask |= SMSTATEEN0_P1P13;
26103bee0e40SMayuresh Chitale     }
26113bee0e40SMayuresh Chitale 
26123bee0e40SMayuresh Chitale     return write_mstateenh(env, csrno, wr_mask, new_val);
26133bee0e40SMayuresh Chitale }
26143bee0e40SMayuresh Chitale 
write_mstateenh_1_3(CPURISCVState * env,int csrno,target_ulong new_val)26153bee0e40SMayuresh Chitale static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
26163bee0e40SMayuresh Chitale                                           target_ulong new_val)
26173bee0e40SMayuresh Chitale {
26183bee0e40SMayuresh Chitale     return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
26193bee0e40SMayuresh Chitale }
26203bee0e40SMayuresh Chitale 
read_hstateen(CPURISCVState * env,int csrno,target_ulong * val)26213bee0e40SMayuresh Chitale static RISCVException read_hstateen(CPURISCVState *env, int csrno,
26223bee0e40SMayuresh Chitale                                     target_ulong *val)
2623252b06f6SMayuresh Chitale {
26243bee0e40SMayuresh Chitale     int index = csrno - CSR_HSTATEEN0;
26253bee0e40SMayuresh Chitale 
26263bee0e40SMayuresh Chitale     *val = env->hstateen[index] & env->mstateen[index];
26273bee0e40SMayuresh Chitale 
26283bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
26293bee0e40SMayuresh Chitale }
26303bee0e40SMayuresh Chitale 
write_hstateen(CPURISCVState * env,int csrno,uint64_t mask,target_ulong new_val)26313bee0e40SMayuresh Chitale static RISCVException write_hstateen(CPURISCVState *env, int csrno,
26323bee0e40SMayuresh Chitale                                      uint64_t mask, target_ulong new_val)
26333bee0e40SMayuresh Chitale {
26343bee0e40SMayuresh Chitale     int index = csrno - CSR_HSTATEEN0;
26353bee0e40SMayuresh Chitale     uint64_t *reg, wr_mask;
26363bee0e40SMayuresh Chitale 
263738256529SWeiwei Li     reg = &env->hstateen[index];
26383bee0e40SMayuresh Chitale     wr_mask = env->mstateen[index] & mask;
26393bee0e40SMayuresh Chitale     *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
26403bee0e40SMayuresh Chitale 
26413bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
26423bee0e40SMayuresh Chitale }
26433bee0e40SMayuresh Chitale 
write_hstateen0(CPURISCVState * env,int csrno,target_ulong new_val)26443bee0e40SMayuresh Chitale static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
26453bee0e40SMayuresh Chitale                                       target_ulong new_val)
26463bee0e40SMayuresh Chitale {
26473bee0e40SMayuresh Chitale     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
26483bee0e40SMayuresh Chitale 
26493bee0e40SMayuresh Chitale     if (!riscv_has_ext(env, RVF)) {
26503bee0e40SMayuresh Chitale         wr_mask |= SMSTATEEN0_FCSR;
265138256529SWeiwei Li     }
26523bee0e40SMayuresh Chitale 
26533bee0e40SMayuresh Chitale     return write_hstateen(env, csrno, wr_mask, new_val);
26543bee0e40SMayuresh Chitale }
26553bee0e40SMayuresh Chitale 
write_hstateen_1_3(CPURISCVState * env,int csrno,target_ulong new_val)26563bee0e40SMayuresh Chitale static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
26573bee0e40SMayuresh Chitale                                          target_ulong new_val)
26583bee0e40SMayuresh Chitale {
26593bee0e40SMayuresh Chitale     return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
26603bee0e40SMayuresh Chitale }
26613bee0e40SMayuresh Chitale 
read_hstateenh(CPURISCVState * env,int csrno,target_ulong * val)26623bee0e40SMayuresh Chitale static RISCVException read_hstateenh(CPURISCVState *env, int csrno,
26633bee0e40SMayuresh Chitale                                      target_ulong *val)
26643bee0e40SMayuresh Chitale {
26653bee0e40SMayuresh Chitale     int index = csrno - CSR_HSTATEEN0H;
26663bee0e40SMayuresh Chitale 
26673bee0e40SMayuresh Chitale     *val = (env->hstateen[index] >> 32) & (env->mstateen[index] >> 32);
26683bee0e40SMayuresh Chitale 
26693bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
2670252b06f6SMayuresh Chitale }
26713bee0e40SMayuresh Chitale 
write_hstateenh(CPURISCVState * env,int csrno,uint64_t mask,target_ulong new_val)26729514fc72SMayuresh Chitale static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
26739514fc72SMayuresh Chitale                                       uint64_t mask, target_ulong new_val)
26749514fc72SMayuresh Chitale {
26759514fc72SMayuresh Chitale     int index = csrno - CSR_HSTATEEN0H;
26763bee0e40SMayuresh Chitale     uint64_t *reg, wr_mask, val;
26773bee0e40SMayuresh Chitale 
26783bee0e40SMayuresh Chitale     reg = &env->hstateen[index];
26793bee0e40SMayuresh Chitale     val = (uint64_t)new_val << 32;
26803bee0e40SMayuresh Chitale     val |= *reg & 0xFFFFFFFF;
26813bee0e40SMayuresh Chitale     wr_mask = env->mstateen[index] & mask;
26823bee0e40SMayuresh Chitale     *reg = (*reg & ~wr_mask) | (val & wr_mask);
26833bee0e40SMayuresh Chitale 
26843bee0e40SMayuresh Chitale     return RISCV_EXCP_NONE;
2685d028ac75SAnup Patel }
2686d028ac75SAnup Patel 
write_hstateen0h(CPURISCVState * env,int csrno,target_ulong new_val)2687d028ac75SAnup Patel static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
2688c7b95171SMichael Clark                                        target_ulong new_val)
268933fe584fSAlistair Francis {
2690d028ac75SAnup Patel     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2691c7b95171SMichael Clark 
269233fe584fSAlistair Francis     return write_hstateenh(env, csrno, wr_mask, new_val);
269333fe584fSAlistair Francis }
269433fe584fSAlistair Francis 
write_hstateenh_1_3(CPURISCVState * env,int csrno,target_ulong new_val)269533fe584fSAlistair Francis static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
269633fe584fSAlistair Francis                                           target_ulong new_val)
2697bbb9fc25SWeiwei Li {
269843888c2fSAtish Patra     return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
269943888c2fSAtish Patra }
270043888c2fSAtish Patra 
read_sstateen(CPURISCVState * env,int csrno,target_ulong * val)270143888c2fSAtish Patra static RISCVException read_sstateen(CPURISCVState *env, int csrno,
270243888c2fSAtish Patra                                     target_ulong *val)
270371877e29SMichael Clark {
2704bbb9fc25SWeiwei Li     bool virt = env->virt_enabled;
270571877e29SMichael Clark     int index = csrno - CSR_SSTATEEN0;
27067ec5d303SAlistair Francis 
270771877e29SMichael Clark     *val = env->sstateen[index] & env->mstateen[index];
270871877e29SMichael Clark     if (virt) {
2709cd032fe7SAnup Patel         *val &= env->hstateen[index];
2710cd032fe7SAnup Patel     }
2711cd032fe7SAnup Patel 
27123ec0fe18SAtish Patra     return RISCV_EXCP_NONE;
2713cd032fe7SAnup Patel }
2714cd032fe7SAnup Patel 
write_sstateen(CPURISCVState * env,int csrno,uint64_t mask,target_ulong new_val)2715d028ac75SAnup Patel static RISCVException write_sstateen(CPURISCVState *env, int csrno,
2716d028ac75SAnup Patel                                      uint64_t mask, target_ulong new_val)
271771877e29SMichael Clark {
2718c7b95171SMichael Clark     bool virt = env->virt_enabled;
2719605def6eSAlistair Francis     int index = csrno - CSR_SSTATEEN0;
2720c7b95171SMichael Clark     uint64_t wr_mask;
2721c7b95171SMichael Clark     uint64_t *reg;
2722d028ac75SAnup Patel 
2723d028ac75SAnup Patel     wr_mask = env->mstateen[index] & mask;
2724d028ac75SAnup Patel     if (virt) {
2725d028ac75SAnup Patel         wr_mask &= env->hstateen[index];
2726d028ac75SAnup Patel     }
2727d028ac75SAnup Patel 
2728d028ac75SAnup Patel     reg = &env->sstateen[index];
2729d028ac75SAnup Patel     *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
2730d028ac75SAnup Patel 
2731d028ac75SAnup Patel     return RISCV_EXCP_NONE;
2732d028ac75SAnup Patel }
2733d028ac75SAnup Patel 
write_sstateen0(CPURISCVState * env,int csrno,target_ulong new_val)2734d028ac75SAnup Patel static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
2735d028ac75SAnup Patel                                       target_ulong new_val)
2736d028ac75SAnup Patel {
2737d028ac75SAnup Patel     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
2738d028ac75SAnup Patel 
2739d028ac75SAnup Patel     if (!riscv_has_ext(env, RVF)) {
2740d028ac75SAnup Patel         wr_mask |= SMSTATEEN0_FCSR;
2741d028ac75SAnup Patel     }
2742d028ac75SAnup Patel 
2743d028ac75SAnup Patel     return write_sstateen(env, csrno, wr_mask, new_val);
2744d028ac75SAnup Patel }
2745d028ac75SAnup Patel 
write_sstateen_1_3(CPURISCVState * env,int csrno,target_ulong new_val)2746d028ac75SAnup Patel static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
2747d028ac75SAnup Patel                                       target_ulong new_val)
2748d028ac75SAnup Patel {
2749d028ac75SAnup Patel     return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
2750d028ac75SAnup Patel }
2751d028ac75SAnup Patel 
rmw_mip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)2752d028ac75SAnup Patel static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
27531697837eSRajnesh Kanwal                                 uint64_t *ret_val,
27541697837eSRajnesh Kanwal                                 uint64_t new_val, uint64_t wr_mask)
27551697837eSRajnesh Kanwal {
27561697837eSRajnesh Kanwal     uint64_t old_mip, mask = wr_mask & delegable_ints;
27571697837eSRajnesh Kanwal     uint32_t gin;
27581697837eSRajnesh Kanwal 
27591697837eSRajnesh Kanwal     if (mask & MIP_SEIP) {
27601697837eSRajnesh Kanwal         env->software_seip = new_val & MIP_SEIP;
27611697837eSRajnesh Kanwal         new_val |= env->external_seip * MIP_SEIP;
27621697837eSRajnesh Kanwal     }
27631697837eSRajnesh Kanwal 
27641697837eSRajnesh Kanwal     if (riscv_cpu_cfg(env)->ext_sstc && (env->priv == PRV_M) &&
27651697837eSRajnesh Kanwal         get_field(env->menvcfg, MENVCFG_STCE)) {
27661697837eSRajnesh Kanwal         /* sstc extension forbids STIP & VSTIP to be writeable in mip */
27671697837eSRajnesh Kanwal         mask = mask & ~(MIP_STIP | MIP_VSTIP);
27681697837eSRajnesh Kanwal     }
27691697837eSRajnesh Kanwal 
27701697837eSRajnesh Kanwal     if (mask) {
27711697837eSRajnesh Kanwal         old_mip = riscv_cpu_update_mip(env, mask, (new_val & mask));
27721697837eSRajnesh Kanwal     } else {
27731697837eSRajnesh Kanwal         old_mip = env->mip;
27741697837eSRajnesh Kanwal     }
27751697837eSRajnesh Kanwal 
27761697837eSRajnesh Kanwal     if (csrno != CSR_HVIP) {
27771697837eSRajnesh Kanwal         gin = get_field(env->hstatus, HSTATUS_VGEIN);
27781697837eSRajnesh Kanwal         old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
27791697837eSRajnesh Kanwal         old_mip |= env->vstime_irq ? MIP_VSTIP : 0;
27801697837eSRajnesh Kanwal     }
27811697837eSRajnesh Kanwal 
27821697837eSRajnesh Kanwal     if (ret_val) {
27831697837eSRajnesh Kanwal         *ret_val = old_mip;
27841697837eSRajnesh Kanwal     }
27851697837eSRajnesh Kanwal 
27861697837eSRajnesh Kanwal     return RISCV_EXCP_NONE;
27871697837eSRajnesh Kanwal }
27881697837eSRajnesh Kanwal 
rmw_mip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)27891697837eSRajnesh Kanwal static RISCVException rmw_mip(CPURISCVState *env, int csrno,
27901697837eSRajnesh Kanwal                               target_ulong *ret_val,
27911697837eSRajnesh Kanwal                               target_ulong new_val, target_ulong wr_mask)
27921697837eSRajnesh Kanwal {
27931697837eSRajnesh Kanwal     uint64_t rval;
27941697837eSRajnesh Kanwal     RISCVException ret;
27951697837eSRajnesh Kanwal 
27961697837eSRajnesh Kanwal     ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
27971697837eSRajnesh Kanwal     if (ret_val) {
27981697837eSRajnesh Kanwal         *ret_val = rval;
27991697837eSRajnesh Kanwal     }
28001697837eSRajnesh Kanwal 
28011697837eSRajnesh Kanwal     return ret;
28021697837eSRajnesh Kanwal }
28031697837eSRajnesh Kanwal 
rmw_miph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)28041697837eSRajnesh Kanwal static RISCVException rmw_miph(CPURISCVState *env, int csrno,
28051697837eSRajnesh Kanwal                                target_ulong *ret_val,
28061697837eSRajnesh Kanwal                                target_ulong new_val, target_ulong wr_mask)
28071697837eSRajnesh Kanwal {
28081697837eSRajnesh Kanwal     uint64_t rval;
28091697837eSRajnesh Kanwal     RISCVException ret;
28101697837eSRajnesh Kanwal 
28111697837eSRajnesh Kanwal     ret = rmw_mip64(env, csrno, &rval,
28121697837eSRajnesh Kanwal         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
28131697837eSRajnesh Kanwal     if (ret_val) {
28141697837eSRajnesh Kanwal         *ret_val = rval >> 32;
28151697837eSRajnesh Kanwal     }
28161697837eSRajnesh Kanwal 
28171697837eSRajnesh Kanwal     return ret;
28181697837eSRajnesh Kanwal }
28191697837eSRajnesh Kanwal 
28201697837eSRajnesh Kanwal /*
28211697837eSRajnesh Kanwal  * The function is written for two use-cases:
28221697837eSRajnesh Kanwal  * 1- To access mvip csr as is for m-mode access.
28231697837eSRajnesh Kanwal  * 2- To access sip as a combination of mip and mvip for s-mode.
28241697837eSRajnesh Kanwal  *
28251697837eSRajnesh Kanwal  * Both report bits 1, 5, 9 and 13:63 but with the exception of
28261697837eSRajnesh Kanwal  * STIP being read-only zero in case of mvip when sstc extension
28271697837eSRajnesh Kanwal  * is present.
28281697837eSRajnesh Kanwal  * Also, sip needs to be read-only zero when both mideleg[i] and
28291697837eSRajnesh Kanwal  * mvien[i] are zero but mvip needs to be an alias of mip.
28301697837eSRajnesh Kanwal  */
rmw_mvip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)28311697837eSRajnesh Kanwal static RISCVException rmw_mvip64(CPURISCVState *env, int csrno,
28321697837eSRajnesh Kanwal                                 uint64_t *ret_val,
28331697837eSRajnesh Kanwal                                 uint64_t new_val, uint64_t wr_mask)
28341697837eSRajnesh Kanwal {
28351697837eSRajnesh Kanwal     RISCVCPU *cpu = env_archcpu(env);
28361697837eSRajnesh Kanwal     target_ulong ret_mip = 0;
28371697837eSRajnesh Kanwal     RISCVException ret;
28381697837eSRajnesh Kanwal     uint64_t old_mvip;
28391697837eSRajnesh Kanwal 
28401697837eSRajnesh Kanwal     /*
28411697837eSRajnesh Kanwal      * mideleg[i]  mvien[i]
28421697837eSRajnesh Kanwal      *   0           0      No delegation. mvip[i] is alias of mip[i].
28431697837eSRajnesh Kanwal      *   0           1      mvip[i] becomes source of interrupt, mip bypassed.
28441697837eSRajnesh Kanwal      *   1           X      mip[i] is source of interrupt and mvip[i] aliases
28451697837eSRajnesh Kanwal      *                      mip[i].
28461697837eSRajnesh Kanwal      *
28471697837eSRajnesh Kanwal      *   So alias condition would be for bits:
28481697837eSRajnesh Kanwal      *      ((S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & (mideleg | ~mvien)) |
28491697837eSRajnesh Kanwal      *          (!sstc & MIP_STIP)
28501697837eSRajnesh Kanwal      *
28511697837eSRajnesh Kanwal      *   Non-alias condition will be for bits:
28521697837eSRajnesh Kanwal      *      (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & (~mideleg & mvien)
28531697837eSRajnesh Kanwal      *
28541697837eSRajnesh Kanwal      *  alias_mask denotes the bits that come from mip nalias_mask denotes bits
28551697837eSRajnesh Kanwal      *  that come from hvip.
28561697837eSRajnesh Kanwal      */
28571697837eSRajnesh Kanwal     uint64_t alias_mask = ((S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) &
28581697837eSRajnesh Kanwal         (env->mideleg | ~env->mvien)) | MIP_STIP;
28591697837eSRajnesh Kanwal     uint64_t nalias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) &
28601697837eSRajnesh Kanwal         (~env->mideleg & env->mvien);
28611697837eSRajnesh Kanwal     uint64_t wr_mask_mvip;
28621697837eSRajnesh Kanwal     uint64_t wr_mask_mip;
28631697837eSRajnesh Kanwal 
28641697837eSRajnesh Kanwal     /*
28651697837eSRajnesh Kanwal      * mideleg[i]  mvien[i]
28661697837eSRajnesh Kanwal      *   0           0      sip[i] read-only zero.
28671697837eSRajnesh Kanwal      *   0           1      sip[i] alias of mvip[i].
28681697837eSRajnesh Kanwal      *   1           X      sip[i] alias of mip[i].
28691697837eSRajnesh Kanwal      *
28701697837eSRajnesh Kanwal      *  Both alias and non-alias mask remain same for sip except for bits
28711697837eSRajnesh Kanwal      *  which are zero in both mideleg and mvien.
28721697837eSRajnesh Kanwal      */
28731697837eSRajnesh Kanwal     if (csrno == CSR_SIP) {
28741697837eSRajnesh Kanwal         /* Remove bits that are zero in both mideleg and mvien. */
28751697837eSRajnesh Kanwal         alias_mask &= (env->mideleg | env->mvien);
28761697837eSRajnesh Kanwal         nalias_mask &= (env->mideleg | env->mvien);
28771697837eSRajnesh Kanwal     }
28781697837eSRajnesh Kanwal 
28791697837eSRajnesh Kanwal     /*
28801697837eSRajnesh Kanwal      * If sstc is present, mvip.STIP is not an alias of mip.STIP so clear
28811697837eSRajnesh Kanwal      * that our in mip returned value.
28821697837eSRajnesh Kanwal      */
28831697837eSRajnesh Kanwal     if (cpu->cfg.ext_sstc && (env->priv == PRV_M) &&
28841697837eSRajnesh Kanwal         get_field(env->menvcfg, MENVCFG_STCE)) {
28851697837eSRajnesh Kanwal         alias_mask &= ~MIP_STIP;
28861697837eSRajnesh Kanwal     }
28871697837eSRajnesh Kanwal 
28881697837eSRajnesh Kanwal     wr_mask_mip = wr_mask & alias_mask & mvip_writable_mask;
28891697837eSRajnesh Kanwal     wr_mask_mvip = wr_mask & nalias_mask & mvip_writable_mask;
2890c7b95171SMichael Clark 
2891457c360fSFrédéric Pétrot     /*
2892457c360fSFrédéric Pétrot      * For bits set in alias_mask, mvip needs to be alias of mip, so forward
2893457c360fSFrédéric Pétrot      * this to rmw_mip.
2894457c360fSFrédéric Pétrot      */
2895457c360fSFrédéric Pétrot     ret = rmw_mip(env, CSR_MIP, &ret_mip, new_val, wr_mask_mip);
2896f297245fSLIU Zhiwei     if (ret != RISCV_EXCP_NONE) {
2897f310df58SLIU Zhiwei         return ret;
2898f310df58SLIU Zhiwei     }
2899457c360fSFrédéric Pétrot 
2900457c360fSFrédéric Pétrot     old_mvip = env->mvip;
2901457c360fSFrédéric Pétrot 
2902457c360fSFrédéric Pétrot     /*
2903457c360fSFrédéric Pétrot      * Write to mvip. Update only non-alias bits. Alias bits were updated
2904605def6eSAlistair Francis      * in mip in rmw_mip above.
2905605def6eSAlistair Francis      */
2906c7b95171SMichael Clark     if (wr_mask_mvip) {
29071a9540d1SAlistair Francis         env->mvip = (env->mvip & ~wr_mask_mvip) | (new_val & wr_mask_mvip);
2908f297245fSLIU Zhiwei 
2909f310df58SLIU Zhiwei         /*
2910f310df58SLIU Zhiwei          * Given mvip is separate source from mip, we need to trigger interrupt
2911b550f894SRichard Henderson          * from here separately. Normally this happen from riscv_cpu_update_mip.
2912b550f894SRichard Henderson          */
2913605def6eSAlistair Francis         riscv_cpu_interrupt(env);
2914c7b95171SMichael Clark     }
2915c7b95171SMichael Clark 
2916605def6eSAlistair Francis     if (ret_val) {
2917605def6eSAlistair Francis         ret_mip &= alias_mask;
2918c7b95171SMichael Clark         old_mvip &= nalias_mask;
29191a9540d1SAlistair Francis 
2920f310df58SLIU Zhiwei         *ret_val = old_mvip | ret_mip;
2921f297245fSLIU Zhiwei     }
2922f310df58SLIU Zhiwei 
2923f310df58SLIU Zhiwei     return RISCV_EXCP_NONE;
2924f310df58SLIU Zhiwei }
2925f310df58SLIU Zhiwei 
rmw_mvip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)2926c7b95171SMichael Clark static RISCVException rmw_mvip(CPURISCVState *env, int csrno,
2927c7b95171SMichael Clark                               target_ulong *ret_val,
2928c7b95171SMichael Clark                               target_ulong new_val, target_ulong wr_mask)
2929c7b95171SMichael Clark {
2930d028ac75SAnup Patel     uint64_t rval;
2931d028ac75SAnup Patel     RISCVException ret;
2932d028ac75SAnup Patel 
29339d5451e0SGeorg Kotheimer     ret = rmw_mvip64(env, csrno, &rval, new_val, wr_mask);
293440336d5bSRajnesh Kanwal     if (ret_val) {
293540336d5bSRajnesh Kanwal         *ret_val = rval;
293640336d5bSRajnesh Kanwal     }
293740336d5bSRajnesh Kanwal 
293840336d5bSRajnesh Kanwal     return ret;
293940336d5bSRajnesh Kanwal }
2940d028ac75SAnup Patel 
rmw_mviph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)2941d028ac75SAnup Patel static RISCVException rmw_mviph(CPURISCVState *env, int csrno,
2942d028ac75SAnup Patel                                target_ulong *ret_val,
294340336d5bSRajnesh Kanwal                                target_ulong new_val, target_ulong wr_mask)
294440336d5bSRajnesh Kanwal {
294540336d5bSRajnesh Kanwal     uint64_t rval;
2946d028ac75SAnup Patel     RISCVException ret;
294740336d5bSRajnesh Kanwal 
294840336d5bSRajnesh Kanwal     ret = rmw_mvip64(env, csrno, &rval,
294940336d5bSRajnesh Kanwal         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
295040336d5bSRajnesh Kanwal     if (ret_val) {
295140336d5bSRajnesh Kanwal         *ret_val = rval >> 32;
295240336d5bSRajnesh Kanwal     }
295340336d5bSRajnesh Kanwal 
295440336d5bSRajnesh Kanwal     return ret;
295540336d5bSRajnesh Kanwal }
295640336d5bSRajnesh Kanwal 
295740336d5bSRajnesh Kanwal /* Supervisor Trap Setup */
read_sstatus_i128(CPURISCVState * env,int csrno,Int128 * val)295840336d5bSRajnesh Kanwal static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
2959d028ac75SAnup Patel                                         Int128 *val)
296040336d5bSRajnesh Kanwal {
296140336d5bSRajnesh Kanwal     uint64_t mask = sstatus_v1_10_mask;
296240336d5bSRajnesh Kanwal     uint64_t sstatus = env->mstatus & mask;
296340336d5bSRajnesh Kanwal     if (env->xl != MXL_RV32 || env->debugger) {
29649d5451e0SGeorg Kotheimer         mask |= SSTATUS64_UXL;
29659d5451e0SGeorg Kotheimer     }
2966d028ac75SAnup Patel 
2967d028ac75SAnup Patel     if (env_archcpu(env)->cfg.ext_zicfilp) {
2968d028ac75SAnup Patel         mask |= SSTATUS_SPELP;
2969d028ac75SAnup Patel     }
2970d028ac75SAnup Patel 
2971d028ac75SAnup Patel     *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
2972c7b95171SMichael Clark     return RISCV_EXCP_NONE;
2973d028ac75SAnup Patel }
2974d028ac75SAnup Patel 
read_sstatus(CPURISCVState * env,int csrno,target_ulong * val)2975d028ac75SAnup Patel static RISCVException read_sstatus(CPURISCVState *env, int csrno,
2976d028ac75SAnup Patel                                    target_ulong *val)
2977d028ac75SAnup Patel {
2978d028ac75SAnup Patel     target_ulong mask = (sstatus_v1_10_mask);
2979d028ac75SAnup Patel     if (env->xl != MXL_RV32 || env->debugger) {
2980d028ac75SAnup Patel         mask |= SSTATUS64_UXL;
2981d028ac75SAnup Patel     }
2982d028ac75SAnup Patel 
2983d028ac75SAnup Patel     if (env_archcpu(env)->cfg.ext_zicfilp) {
2984d028ac75SAnup Patel         mask |= SSTATUS_SPELP;
2985d028ac75SAnup Patel     }
2986d028ac75SAnup Patel 
2987d028ac75SAnup Patel     /* TODO: Use SXL not MXL. */
2988d028ac75SAnup Patel     *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
2989d028ac75SAnup Patel     return RISCV_EXCP_NONE;
2990d028ac75SAnup Patel }
2991d028ac75SAnup Patel 
write_sstatus(CPURISCVState * env,int csrno,target_ulong val)2992d028ac75SAnup Patel static RISCVException write_sstatus(CPURISCVState *env, int csrno,
2993d028ac75SAnup Patel                                     target_ulong val)
2994d028ac75SAnup Patel {
2995d028ac75SAnup Patel     target_ulong mask = (sstatus_v1_10_mask);
2996d028ac75SAnup Patel 
2997d028ac75SAnup Patel     if (env->xl != MXL_RV32 || env->debugger) {
2998d028ac75SAnup Patel         if ((val & SSTATUS64_UXL) != 0) {
2999d028ac75SAnup Patel             mask |= SSTATUS64_UXL;
3000d028ac75SAnup Patel         }
3001d028ac75SAnup Patel     }
3002d028ac75SAnup Patel 
3003d028ac75SAnup Patel     if (env_archcpu(env)->cfg.ext_zicfilp) {
30041697837eSRajnesh Kanwal         mask |= SSTATUS_SPELP;
30051697837eSRajnesh Kanwal     }
30061697837eSRajnesh Kanwal 
30071697837eSRajnesh Kanwal     target_ulong newval = (env->mstatus & ~mask) | (val & mask);
3008d028ac75SAnup Patel     return write_mstatus(env, CSR_MSTATUS, newval);
3009d028ac75SAnup Patel }
30101697837eSRajnesh Kanwal 
rmw_vsie64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)30111697837eSRajnesh Kanwal static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
30121697837eSRajnesh Kanwal                                  uint64_t *ret_val,
30131697837eSRajnesh Kanwal                                  uint64_t new_val, uint64_t wr_mask)
30141697837eSRajnesh Kanwal {
30151697837eSRajnesh Kanwal     uint64_t alias_mask = (LOCAL_INTERRUPTS | VS_MODE_INTERRUPTS) &
30161697837eSRajnesh Kanwal                             env->hideleg;
30171697837eSRajnesh Kanwal     uint64_t nalias_mask = LOCAL_INTERRUPTS & (~env->hideleg & env->hvien);
30181697837eSRajnesh Kanwal     uint64_t rval, rval_vs, vsbits;
301938256529SWeiwei Li     uint64_t wr_mask_vsie;
30202b602398SAnup Patel     uint64_t wr_mask_mie;
30212b602398SAnup Patel     RISCVException ret;
30222b602398SAnup Patel 
3023d028ac75SAnup Patel     /* Bring VS-level bits to correct position */
30241697837eSRajnesh Kanwal     vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
30251697837eSRajnesh Kanwal     new_val &= ~(VS_MODE_INTERRUPTS >> 1);
30261697837eSRajnesh Kanwal     new_val |= vsbits << 1;
3027d0e53ce3SAlistair Francis 
30281697837eSRajnesh Kanwal     vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
30291697837eSRajnesh Kanwal     wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
30301697837eSRajnesh Kanwal     wr_mask |= vsbits << 1;
30311697837eSRajnesh Kanwal 
3032c7b95171SMichael Clark     wr_mask_mie = wr_mask & alias_mask;
3033c7b95171SMichael Clark     wr_mask_vsie = wr_mask & nalias_mask;
30341697837eSRajnesh Kanwal 
3035d028ac75SAnup Patel     ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask_mie);
3036d028ac75SAnup Patel 
3037d028ac75SAnup Patel     rval_vs = env->vsie & nalias_mask;
3038d028ac75SAnup Patel     env->vsie = (env->vsie & ~wr_mask_vsie) | (new_val & wr_mask_vsie);
3039d028ac75SAnup Patel 
3040d028ac75SAnup Patel     if (ret_val) {
3041d028ac75SAnup Patel         rval &= alias_mask;
3042d028ac75SAnup Patel         vsbits = rval & VS_MODE_INTERRUPTS;
3043c7b95171SMichael Clark         rval &= ~VS_MODE_INTERRUPTS;
3044d028ac75SAnup Patel         *ret_val = rval | (vsbits >> 1) | rval_vs;
3045d028ac75SAnup Patel     }
3046d028ac75SAnup Patel 
3047d028ac75SAnup Patel     return ret;
30482b602398SAnup Patel }
3049d028ac75SAnup Patel 
rmw_vsie(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3050d0e53ce3SAlistair Francis static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
3051d0e53ce3SAlistair Francis                                target_ulong *ret_val,
3052d028ac75SAnup Patel                                target_ulong new_val, target_ulong wr_mask)
3053d028ac75SAnup Patel {
3054d028ac75SAnup Patel     uint64_t rval;
3055d028ac75SAnup Patel     RISCVException ret;
3056d028ac75SAnup Patel 
3057d028ac75SAnup Patel     ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
30589d5451e0SGeorg Kotheimer     if (ret_val) {
3059d028ac75SAnup Patel         *ret_val = rval;
3060d028ac75SAnup Patel     }
3061d028ac75SAnup Patel 
3062d028ac75SAnup Patel     return ret;
3063d028ac75SAnup Patel }
3064d028ac75SAnup Patel 
rmw_vsieh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3065d028ac75SAnup Patel static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
30669d5451e0SGeorg Kotheimer                                 target_ulong *ret_val,
30679d5451e0SGeorg Kotheimer                                 target_ulong new_val, target_ulong wr_mask)
3068d028ac75SAnup Patel {
3069c7b95171SMichael Clark     uint64_t rval;
3070c7b95171SMichael Clark     RISCVException ret;
3071605def6eSAlistair Francis 
3072605def6eSAlistair Francis     ret = rmw_vsie64(env, csrno, &rval,
3073c7b95171SMichael Clark         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3074c7b95171SMichael Clark     if (ret_val) {
3075605def6eSAlistair Francis         *ret_val = rval >> 32;
3076c7b95171SMichael Clark     }
3077c7b95171SMichael Clark 
3078605def6eSAlistair Francis     return ret;
3079605def6eSAlistair Francis }
3080c7b95171SMichael Clark 
rmw_sie64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3081c7b95171SMichael Clark static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
3082acbbb94eSMichael Clark                                 uint64_t *ret_val,
3083acbbb94eSMichael Clark                                 uint64_t new_val, uint64_t wr_mask)
3084c7b95171SMichael Clark {
3085acbbb94eSMichael Clark     uint64_t nalias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) &
3086c7b95171SMichael Clark         (~env->mideleg & env->mvien);
3087605def6eSAlistair Francis     uint64_t alias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & env->mideleg;
3088c7b95171SMichael Clark     uint64_t sie_mask = wr_mask & nalias_mask;
3089c7b95171SMichael Clark     RISCVException ret;
3090605def6eSAlistair Francis 
3091605def6eSAlistair Francis     /*
3092c7b95171SMichael Clark      * mideleg[i]  mvien[i]
3093c7b95171SMichael Clark      *   0           0      sie[i] read-only zero.
3094605def6eSAlistair Francis      *   0           1      sie[i] is a separate writable bit.
3095c7b95171SMichael Clark      *   1           X      sie[i] alias of mie[i].
3096c7b95171SMichael Clark      *
3097605def6eSAlistair Francis      *  Both alias and non-alias mask remain same for sip except for bits
3098605def6eSAlistair Francis      *  which are zero in both mideleg and mvien.
3099c7b95171SMichael Clark      */
31008cff74c2SAtish Patra     if (env->virt_enabled) {
31018cff74c2SAtish Patra         if (env->hvictl & HVICTL_VTI) {
31028cff74c2SAtish Patra             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
31038cff74c2SAtish Patra         }
31048cff74c2SAtish Patra         ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
3105605def6eSAlistair Francis         if (ret_val) {
3106c7b95171SMichael Clark             *ret_val &= alias_mask;
3107c7b95171SMichael Clark         }
3108c7b95171SMichael Clark     } else {
3109457c360fSFrédéric Pétrot         ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & alias_mask);
3110457c360fSFrédéric Pétrot         if (ret_val) {
3111457c360fSFrédéric Pétrot             *ret_val &= alias_mask;
3112457c360fSFrédéric Pétrot             *ret_val |= env->sie & nalias_mask;
3113457c360fSFrédéric Pétrot         }
3114457c360fSFrédéric Pétrot 
3115457c360fSFrédéric Pétrot         env->sie = (env->sie & ~sie_mask) | (new_val & sie_mask);
3116457c360fSFrédéric Pétrot     }
3117457c360fSFrédéric Pétrot 
3118457c360fSFrédéric Pétrot     return ret;
3119457c360fSFrédéric Pétrot }
3120457c360fSFrédéric Pétrot 
rmw_sie(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3121457c360fSFrédéric Pétrot static RISCVException rmw_sie(CPURISCVState *env, int csrno,
3122457c360fSFrédéric Pétrot                               target_ulong *ret_val,
3123457c360fSFrédéric Pétrot                               target_ulong new_val, target_ulong wr_mask)
3124605def6eSAlistair Francis {
3125605def6eSAlistair Francis     uint64_t rval;
3126c7b95171SMichael Clark     RISCVException ret;
3127c7b95171SMichael Clark 
3128605def6eSAlistair Francis     ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
3129c7b95171SMichael Clark     if (ret == RISCV_EXCP_NONE && ret_val) {
3130c7b95171SMichael Clark         *ret_val = rval;
3131605def6eSAlistair Francis     }
3132605def6eSAlistair Francis 
3133c7b95171SMichael Clark     return ret;
3134c7b95171SMichael Clark }
3135605def6eSAlistair Francis 
rmw_sieh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3136c7b95171SMichael Clark static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
3137c7b95171SMichael Clark                                target_ulong *ret_val,
3138605def6eSAlistair Francis                                target_ulong new_val, target_ulong wr_mask)
3139605def6eSAlistair Francis {
3140c7b95171SMichael Clark     uint64_t rval;
3141c7b95171SMichael Clark     RISCVException ret;
3142605def6eSAlistair Francis 
3143c7b95171SMichael Clark     ret = rmw_sie64(env, csrno, &rval,
3144c7b95171SMichael Clark         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3145605def6eSAlistair Francis     if (ret_val) {
3146605def6eSAlistair Francis         *ret_val = rval >> 32;
3147c7b95171SMichael Clark     }
3148c7b95171SMichael Clark 
3149605def6eSAlistair Francis     return ret;
3150c7b95171SMichael Clark }
3151c7b95171SMichael Clark 
read_stvec(CPURISCVState * env,int csrno,target_ulong * val)3152605def6eSAlistair Francis static RISCVException read_stvec(CPURISCVState *env, int csrno,
3153605def6eSAlistair Francis                                  target_ulong *val)
3154c7b95171SMichael Clark {
3155c7b95171SMichael Clark     *val = env->stvec;
3156605def6eSAlistair Francis     return RISCV_EXCP_NONE;
3157c7b95171SMichael Clark }
3158c7b95171SMichael Clark 
write_stvec(CPURISCVState * env,int csrno,target_ulong val)3159605def6eSAlistair Francis static RISCVException write_stvec(CPURISCVState *env, int csrno,
3160605def6eSAlistair Francis                                   target_ulong val)
3161c7b95171SMichael Clark {
3162c7b95171SMichael Clark     /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
3163605def6eSAlistair Francis     if ((val & 3) < 2) {
3164c7b95171SMichael Clark         env->stvec = val;
3165c7b95171SMichael Clark     } else {
3166605def6eSAlistair Francis         qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
3167605def6eSAlistair Francis     }
3168c7b95171SMichael Clark     return RISCV_EXCP_NONE;
3169ac12b601SAtish Patra }
3170605def6eSAlistair Francis 
read_scounteren(CPURISCVState * env,int csrno,target_ulong * val)3171c7b95171SMichael Clark static RISCVException read_scounteren(CPURISCVState *env, int csrno,
3172c7b95171SMichael Clark                                       target_ulong *val)
3173605def6eSAlistair Francis {
3174605def6eSAlistair Francis     *val = env->scounteren;
3175c7b95171SMichael Clark     return RISCV_EXCP_NONE;
3176ac12b601SAtish Patra }
3177605def6eSAlistair Francis 
write_scounteren(CPURISCVState * env,int csrno,target_ulong val)3178c7b95171SMichael Clark static RISCVException write_scounteren(CPURISCVState *env, int csrno,
3179c7b95171SMichael Clark                                        target_ulong val)
318040336d5bSRajnesh Kanwal {
318140336d5bSRajnesh Kanwal     RISCVCPU *cpu = env_archcpu(env);
318240336d5bSRajnesh Kanwal 
318340336d5bSRajnesh Kanwal     /* WARL register - disable unavailable counters */
3184d028ac75SAnup Patel     env->scounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
3185d028ac75SAnup Patel                              COUNTEREN_IR);
3186d028ac75SAnup Patel     return RISCV_EXCP_NONE;
31879d5451e0SGeorg Kotheimer }
3188d028ac75SAnup Patel 
318906d85c24SAndrew Bresticker /* Supervisor Trap Handling */
read_sscratch_i128(CPURISCVState * env,int csrno,Int128 * val)319040336d5bSRajnesh Kanwal static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
319140336d5bSRajnesh Kanwal                                          Int128 *val)
319240336d5bSRajnesh Kanwal {
319340336d5bSRajnesh Kanwal     *val = int128_make128(env->sscratch, env->sscratchh);
319433979526SRichard Henderson     return RISCV_EXCP_NONE;
3195d028ac75SAnup Patel }
319640336d5bSRajnesh Kanwal 
write_sscratch_i128(CPURISCVState * env,int csrno,Int128 val)319740336d5bSRajnesh Kanwal static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
319840336d5bSRajnesh Kanwal                                           Int128 val)
319940336d5bSRajnesh Kanwal {
320040336d5bSRajnesh Kanwal     env->sscratch = int128_getlo(val);
320140336d5bSRajnesh Kanwal     env->sscratchh = int128_gethi(val);
3202d028ac75SAnup Patel     return RISCV_EXCP_NONE;
320340336d5bSRajnesh Kanwal }
320406d85c24SAndrew Bresticker 
read_sscratch(CPURISCVState * env,int csrno,target_ulong * val)3205d028ac75SAnup Patel static RISCVException read_sscratch(CPURISCVState *env, int csrno,
320640336d5bSRajnesh Kanwal                                     target_ulong *val)
320740336d5bSRajnesh Kanwal {
320840336d5bSRajnesh Kanwal     *val = env->sscratch;
320940336d5bSRajnesh Kanwal     return RISCV_EXCP_NONE;
321033979526SRichard Henderson }
3211d028ac75SAnup Patel 
write_sscratch(CPURISCVState * env,int csrno,target_ulong val)3212d028ac75SAnup Patel static RISCVException write_sscratch(CPURISCVState *env, int csrno,
3213d028ac75SAnup Patel                                      target_ulong val)
3214d028ac75SAnup Patel {
3215d028ac75SAnup Patel     env->sscratch = val;
3216d028ac75SAnup Patel     return RISCV_EXCP_NONE;
3217d028ac75SAnup Patel }
3218d028ac75SAnup Patel 
read_sepc(CPURISCVState * env,int csrno,target_ulong * val)3219d028ac75SAnup Patel static RISCVException read_sepc(CPURISCVState *env, int csrno,
3220d028ac75SAnup Patel                                 target_ulong *val)
3221d028ac75SAnup Patel {
3222d028ac75SAnup Patel     *val = env->sepc;
3223d028ac75SAnup Patel     return RISCV_EXCP_NONE;
3224d028ac75SAnup Patel }
3225d028ac75SAnup Patel 
write_sepc(CPURISCVState * env,int csrno,target_ulong val)3226d028ac75SAnup Patel static RISCVException write_sepc(CPURISCVState *env, int csrno,
3227d028ac75SAnup Patel                                  target_ulong val)
3228d028ac75SAnup Patel {
3229d028ac75SAnup Patel     env->sepc = val;
3230d028ac75SAnup Patel     return RISCV_EXCP_NONE;
3231d028ac75SAnup Patel }
3232d028ac75SAnup Patel 
read_scause(CPURISCVState * env,int csrno,target_ulong * val)3233d028ac75SAnup Patel static RISCVException read_scause(CPURISCVState *env, int csrno,
3234d028ac75SAnup Patel                                   target_ulong *val)
3235d028ac75SAnup Patel {
3236d028ac75SAnup Patel     *val = env->scause;
3237d028ac75SAnup Patel     return RISCV_EXCP_NONE;
3238d028ac75SAnup Patel }
3239d028ac75SAnup Patel 
write_scause(CPURISCVState * env,int csrno,target_ulong val)3240d028ac75SAnup Patel static RISCVException write_scause(CPURISCVState *env, int csrno,
3241d028ac75SAnup Patel                                    target_ulong val)
3242d028ac75SAnup Patel {
3243d028ac75SAnup Patel     env->scause = val;
3244d028ac75SAnup Patel     return RISCV_EXCP_NONE;
3245d028ac75SAnup Patel }
3246d028ac75SAnup Patel 
read_stval(CPURISCVState * env,int csrno,target_ulong * val)3247d028ac75SAnup Patel static RISCVException read_stval(CPURISCVState *env, int csrno,
3248d028ac75SAnup Patel                                  target_ulong *val)
3249d028ac75SAnup Patel {
3250d028ac75SAnup Patel     *val = env->stval;
32511697837eSRajnesh Kanwal     return RISCV_EXCP_NONE;
3252d028ac75SAnup Patel }
325338256529SWeiwei Li 
write_stval(CPURISCVState * env,int csrno,target_ulong val)32542b602398SAnup Patel static RISCVException write_stval(CPURISCVState *env, int csrno,
32552b602398SAnup Patel                                   target_ulong val)
32562b602398SAnup Patel {
3257d028ac75SAnup Patel     env->stval = val;
3258d028ac75SAnup Patel     return RISCV_EXCP_NONE;
32591697837eSRajnesh Kanwal }
3260d028ac75SAnup Patel 
3261d028ac75SAnup Patel static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
3262d028ac75SAnup Patel                                  uint64_t *ret_val,
32631697837eSRajnesh Kanwal                                  uint64_t new_val, uint64_t wr_mask);
32641697837eSRajnesh Kanwal 
rmw_vsip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3265d028ac75SAnup Patel static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
3266d028ac75SAnup Patel                                  uint64_t *ret_val,
32679d5451e0SGeorg Kotheimer                                  uint64_t new_val, uint64_t wr_mask)
32689d5451e0SGeorg Kotheimer {
32699d5451e0SGeorg Kotheimer     RISCVException ret;
3270605def6eSAlistair Francis     uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
3271d028ac75SAnup Patel     uint64_t vsbits;
3272d028ac75SAnup Patel 
3273c7b95171SMichael Clark     /* Add virtualized bits into vsip mask. */
3274d028ac75SAnup Patel     mask |= env->hvien & ~env->hideleg;
3275d028ac75SAnup Patel 
3276a2e9f57dSAlistair Francis     /* Bring VS-level bits to correct position */
3277d028ac75SAnup Patel     vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
3278d028ac75SAnup Patel     new_val &= ~(VS_MODE_INTERRUPTS >> 1);
3279d028ac75SAnup Patel     new_val |= vsbits << 1;
3280a2e9f57dSAlistair Francis     vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
3281a2e9f57dSAlistair Francis     wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
3282d028ac75SAnup Patel     wr_mask |= vsbits << 1;
328333979526SRichard Henderson 
3284d028ac75SAnup Patel     ret = rmw_hvip64(env, csrno, &rval, new_val,
3285d028ac75SAnup Patel                      wr_mask & mask & vsip_writable_mask);
3286d028ac75SAnup Patel     if (ret_val) {
3287d028ac75SAnup Patel         rval &= mask;
3288d028ac75SAnup Patel         vsbits = rval & VS_MODE_INTERRUPTS;
3289d028ac75SAnup Patel         rval &= ~VS_MODE_INTERRUPTS;
3290d028ac75SAnup Patel         *ret_val = rval | (vsbits >> 1);
3291d028ac75SAnup Patel     }
3292d028ac75SAnup Patel 
3293d028ac75SAnup Patel     return ret;
3294d028ac75SAnup Patel }
3295d028ac75SAnup Patel 
rmw_vsip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3296d028ac75SAnup Patel static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
3297d028ac75SAnup Patel                                target_ulong *ret_val,
3298087b051aSJonathan Behrens                                target_ulong new_val, target_ulong wr_mask)
3299c7b95171SMichael Clark {
3300c7b95171SMichael Clark     uint64_t rval;
3301c7b95171SMichael Clark     RISCVException ret;
3302605def6eSAlistair Francis 
3303605def6eSAlistair Francis     ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
3304c7b95171SMichael Clark     if (ret_val) {
3305dcf654a3SDaniel Henrique Barboza         *ret_val = rval;
3306c7b95171SMichael Clark     }
3307605def6eSAlistair Francis 
33081a9540d1SAlistair Francis     return ret;
3309c7b95171SMichael Clark }
3310605def6eSAlistair Francis 
rmw_vsiph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3311c7b95171SMichael Clark static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
3312c7b95171SMichael Clark                                 target_ulong *ret_val,
3313605def6eSAlistair Francis                                 target_ulong new_val, target_ulong wr_mask)
3314605def6eSAlistair Francis {
3315c7b95171SMichael Clark     uint64_t rval;
3316dcf654a3SDaniel Henrique Barboza     RISCVException ret;
3317605def6eSAlistair Francis 
3318c7b95171SMichael Clark     ret = rmw_vsip64(env, csrno, &rval,
3319419ddf00SAlistair Francis         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
33201349f969SIrina Ryapolova     if (ret_val) {
3321605def6eSAlistair Francis         *ret_val = rval >> 32;
3322c7b95171SMichael Clark     }
3323c7b95171SMichael Clark 
3324a5cb044cSLIU Zhiwei     return ret;
3325a5cb044cSLIU Zhiwei }
3326c7de92b4SAnup Patel 
rmw_sip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3327c7de92b4SAnup Patel static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
3328c7de92b4SAnup Patel                                 uint64_t *ret_val,
3329c7de92b4SAnup Patel                                 uint64_t new_val, uint64_t wr_mask)
3330c7de92b4SAnup Patel {
3331c7de92b4SAnup Patel     RISCVException ret;
3332c7de92b4SAnup Patel     uint64_t mask = (env->mideleg | env->mvien) & sip_writable_mask;
3333c7de92b4SAnup Patel 
3334c7de92b4SAnup Patel     if (env->virt_enabled) {
3335c7de92b4SAnup Patel         if (env->hvictl & HVICTL_VTI) {
3336c7de92b4SAnup Patel             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
3337c7de92b4SAnup Patel         }
3338c7de92b4SAnup Patel         ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
3339c7de92b4SAnup Patel     } else {
3340c7de92b4SAnup Patel         ret = rmw_mvip64(env, csrno, ret_val, new_val, wr_mask & mask);
3341c7de92b4SAnup Patel     }
3342c7de92b4SAnup Patel 
3343c7de92b4SAnup Patel     if (ret_val) {
3344c7de92b4SAnup Patel         *ret_val &= (env->mideleg | env->mvien) &
3345c7de92b4SAnup Patel             (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS);
3346c7de92b4SAnup Patel     }
3347c7de92b4SAnup Patel 
3348c7de92b4SAnup Patel     return ret;
3349c7de92b4SAnup Patel }
3350c7de92b4SAnup Patel 
rmw_sip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3351c7de92b4SAnup Patel static RISCVException rmw_sip(CPURISCVState *env, int csrno,
3352c7de92b4SAnup Patel                               target_ulong *ret_val,
3353c7de92b4SAnup Patel                               target_ulong new_val, target_ulong wr_mask)
3354c7de92b4SAnup Patel {
3355c7de92b4SAnup Patel     uint64_t rval;
3356c7de92b4SAnup Patel     RISCVException ret;
3357c7de92b4SAnup Patel 
3358c7de92b4SAnup Patel     ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
3359c7de92b4SAnup Patel     if (ret_val) {
3360c7de92b4SAnup Patel         *ret_val = rval;
3361c7de92b4SAnup Patel     }
3362c7de92b4SAnup Patel 
3363c7de92b4SAnup Patel     return ret;
3364c7de92b4SAnup Patel }
3365c7de92b4SAnup Patel 
rmw_siph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3366c7de92b4SAnup Patel static RISCVException rmw_siph(CPURISCVState *env, int csrno,
3367c7de92b4SAnup Patel                                target_ulong *ret_val,
3368c7de92b4SAnup Patel                                target_ulong new_val, target_ulong wr_mask)
3369c7de92b4SAnup Patel {
3370c7de92b4SAnup Patel     uint64_t rval;
3371c7de92b4SAnup Patel     RISCVException ret;
3372c7de92b4SAnup Patel 
3373c7de92b4SAnup Patel     ret = rmw_sip64(env, csrno, &rval,
3374c7de92b4SAnup Patel         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3375c7de92b4SAnup Patel     if (ret_val) {
3376c7de92b4SAnup Patel         *ret_val = rval >> 32;
3377c7de92b4SAnup Patel     }
3378c7de92b4SAnup Patel 
3379c7de92b4SAnup Patel     return ret;
3380c7de92b4SAnup Patel }
3381c7de92b4SAnup Patel 
3382c7de92b4SAnup Patel /* Supervisor Protection and Translation */
read_satp(CPURISCVState * env,int csrno,target_ulong * val)3383c7de92b4SAnup Patel static RISCVException read_satp(CPURISCVState *env, int csrno,
3384c7de92b4SAnup Patel                                 target_ulong *val)
3385c7de92b4SAnup Patel {
3386c7de92b4SAnup Patel     if (!riscv_cpu_cfg(env)->mmu) {
3387c7de92b4SAnup Patel         *val = 0;
3388c7de92b4SAnup Patel         return RISCV_EXCP_NONE;
3389c7de92b4SAnup Patel     }
3390c7de92b4SAnup Patel     *val = env->satp;
3391c7de92b4SAnup Patel     return RISCV_EXCP_NONE;
3392c7de92b4SAnup Patel }
3393c7de92b4SAnup Patel 
write_satp(CPURISCVState * env,int csrno,target_ulong val)3394c7de92b4SAnup Patel static RISCVException write_satp(CPURISCVState *env, int csrno,
3395c7de92b4SAnup Patel                                  target_ulong val)
3396c7de92b4SAnup Patel {
3397c7de92b4SAnup Patel     if (!riscv_cpu_cfg(env)->mmu) {
3398c7de92b4SAnup Patel         return RISCV_EXCP_NONE;
3399c7de92b4SAnup Patel     }
3400c7de92b4SAnup Patel 
3401c7de92b4SAnup Patel     env->satp = legalize_xatp(env, env->satp, val);
3402c7de92b4SAnup Patel     return RISCV_EXCP_NONE;
3403c7de92b4SAnup Patel }
3404c7de92b4SAnup Patel 
read_vstopi(CPURISCVState * env,int csrno,target_ulong * val)3405c7de92b4SAnup Patel static RISCVException read_vstopi(CPURISCVState *env, int csrno,
3406c7de92b4SAnup Patel                                   target_ulong *val)
3407c7de92b4SAnup Patel {
3408c7de92b4SAnup Patel     int irq, ret;
3409c7de92b4SAnup Patel     target_ulong topei;
34101697837eSRajnesh Kanwal     uint64_t vseip, vsgein;
3411c7de92b4SAnup Patel     uint32_t iid, iprio, hviid, hviprio, gein;
3412c7de92b4SAnup Patel     uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS];
3413c7de92b4SAnup Patel 
3414a5cb044cSLIU Zhiwei     gein = get_field(env->hstatus, HSTATUS_VGEIN);
3415a5cb044cSLIU Zhiwei     hviid = get_field(env->hvictl, HVICTL_IID);
3416c7de92b4SAnup Patel     hviprio = get_field(env->hvictl, HVICTL_IPRIO);
3417c7de92b4SAnup Patel 
3418c7de92b4SAnup Patel     if (gein) {
3419c7de92b4SAnup Patel         vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
342038256529SWeiwei Li         vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP;
3421c7de92b4SAnup Patel         if (gein <= env->geilen && vseip) {
3422c7de92b4SAnup Patel             siid[scount] = IRQ_S_EXT;
3423c7de92b4SAnup Patel             siprio[scount] = IPRIO_MMAXIPRIO + 1;
3424c7de92b4SAnup Patel             if (env->aia_ireg_rmw_fn[PRV_S]) {
3425c7de92b4SAnup Patel                 /*
3426c7de92b4SAnup Patel                  * Call machine specific IMSIC register emulation for
3427c7de92b4SAnup Patel                  * reading TOPEI.
3428c7de92b4SAnup Patel                  */
3429c7de92b4SAnup Patel                 ret = env->aia_ireg_rmw_fn[PRV_S](
3430c7de92b4SAnup Patel                         env->aia_ireg_rmw_fn_arg[PRV_S],
3431c7de92b4SAnup Patel                         AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein,
3432c7de92b4SAnup Patel                                       riscv_cpu_mxl_bits(env)),
3433c7de92b4SAnup Patel                         &topei, 0, 0);
3434c7de92b4SAnup Patel                 if (!ret && topei) {
3435c7de92b4SAnup Patel                     siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK;
3436c7de92b4SAnup Patel                 }
3437c7de92b4SAnup Patel             }
3438c7de92b4SAnup Patel             scount++;
3439c7de92b4SAnup Patel         }
3440c7de92b4SAnup Patel     } else {
3441ff2cc129SAlistair Francis         if (hviid == IRQ_S_EXT && hviprio) {
3442605def6eSAlistair Francis             siid[scount] = IRQ_S_EXT;
3443605def6eSAlistair Francis             siprio[scount] = hviprio;
3444ff2cc129SAlistair Francis             scount++;
3445ff2cc129SAlistair Francis         }
3446db23e5d9SRichard Henderson     }
3447f8dc878eSAlistair Francis 
3448f8dc878eSAlistair Francis     if (env->hvictl & HVICTL_VTI) {
34498987cdc4SAlistair Francis         if (hviid != IRQ_S_EXT) {
345030f663b1SAlistair Francis             siid[scount] = hviid;
345130f663b1SAlistair Francis             siprio[scount] = hviprio;
3452605def6eSAlistair Francis             scount++;
3453ff2cc129SAlistair Francis         }
3454ff2cc129SAlistair Francis     } else {
3455605def6eSAlistair Francis         irq = riscv_cpu_vsirq_pending(env);
3456605def6eSAlistair Francis         if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) {
3457ff2cc129SAlistair Francis             siid[scount] = irq;
3458ff2cc129SAlistair Francis             siprio[scount] = env->hviprio[irq];
3459db23e5d9SRichard Henderson             scount++;
3460246f8796SWeiwei Li         }
3461246f8796SWeiwei Li     }
3462f8dc878eSAlistair Francis 
346330f663b1SAlistair Francis     iid = 0;
346430f663b1SAlistair Francis     iprio = UINT_MAX;
346530f663b1SAlistair Francis     for (s = 0; s < scount; s++) {
3466605def6eSAlistair Francis         if (siprio[s] < iprio) {
3467ff2cc129SAlistair Francis             iid = siid[s];
3468ff2cc129SAlistair Francis             iprio = siprio[s];
3469605def6eSAlistair Francis         }
3470605def6eSAlistair Francis     }
3471ff2cc129SAlistair Francis 
3472ff2cc129SAlistair Francis     if (iid) {
3473605def6eSAlistair Francis         if (env->hvictl & HVICTL_IPRIOM) {
3474ff2cc129SAlistair Francis             if (iprio > IPRIO_MMAXIPRIO) {
3475ff2cc129SAlistair Francis                 iprio = IPRIO_MMAXIPRIO;
3476605def6eSAlistair Francis             }
3477605def6eSAlistair Francis             if (!iprio) {
3478ff2cc129SAlistair Francis                 if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) {
3479bc083a51SJose Martins                     iprio = IPRIO_MMAXIPRIO;
3480605def6eSAlistair Francis                 }
3481ff2cc129SAlistair Francis             }
3482ff2cc129SAlistair Francis         } else {
348327796989SFea.Wang             iprio = 1;
348427796989SFea.Wang         }
348527796989SFea.Wang     } else {
348627796989SFea.Wang         iprio = 0;
348727796989SFea.Wang     }
348827796989SFea.Wang 
348927796989SFea.Wang     *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT;
349027796989SFea.Wang     *val |= iprio;
349127796989SFea.Wang 
349227796989SFea.Wang     return RISCV_EXCP_NONE;
349327796989SFea.Wang }
349427796989SFea.Wang 
read_stopi(CPURISCVState * env,int csrno,target_ulong * val)349527796989SFea.Wang static RISCVException read_stopi(CPURISCVState *env, int csrno,
349627796989SFea.Wang                                  target_ulong *val)
349727796989SFea.Wang {
349827796989SFea.Wang     int irq;
349927796989SFea.Wang     uint8_t iprio;
350027796989SFea.Wang 
350127796989SFea.Wang     if (env->virt_enabled) {
350227796989SFea.Wang         return read_vstopi(env, CSR_VSTOPI, val);
350327796989SFea.Wang     }
350427796989SFea.Wang 
350527796989SFea.Wang     irq = riscv_cpu_sirq_pending(env);
350627796989SFea.Wang     if (irq <= 0 || irq > 63) {
350727796989SFea.Wang         *val = 0;
350827796989SFea.Wang     } else {
350927796989SFea.Wang         iprio = env->siprio[irq];
351040336d5bSRajnesh Kanwal         if (!iprio) {
351140336d5bSRajnesh Kanwal             if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) {
351240336d5bSRajnesh Kanwal                 iprio = IPRIO_MMAXIPRIO;
351340336d5bSRajnesh Kanwal            }
351440336d5bSRajnesh Kanwal         }
351540336d5bSRajnesh Kanwal         *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
351640336d5bSRajnesh Kanwal         *val |= iprio;
351740336d5bSRajnesh Kanwal     }
351840336d5bSRajnesh Kanwal 
351940336d5bSRajnesh Kanwal     return RISCV_EXCP_NONE;
352040336d5bSRajnesh Kanwal }
352140336d5bSRajnesh Kanwal 
352240336d5bSRajnesh Kanwal /* Hypervisor Extensions */
read_hstatus(CPURISCVState * env,int csrno,target_ulong * val)352340336d5bSRajnesh Kanwal static RISCVException read_hstatus(CPURISCVState *env, int csrno,
352440336d5bSRajnesh Kanwal                                    target_ulong *val)
352540336d5bSRajnesh Kanwal {
352640336d5bSRajnesh Kanwal     *val = env->hstatus;
352740336d5bSRajnesh Kanwal     if (riscv_cpu_mxl(env) != MXL_RV32) {
352840336d5bSRajnesh Kanwal         /* We only support 64-bit VSXL */
352940336d5bSRajnesh Kanwal         *val = set_field(*val, HSTATUS_VSXL, 2);
353040336d5bSRajnesh Kanwal     }
353140336d5bSRajnesh Kanwal     /* We only support little endian */
353240336d5bSRajnesh Kanwal     *val = set_field(*val, HSTATUS_VSBE, 0);
353340336d5bSRajnesh Kanwal     return RISCV_EXCP_NONE;
353440336d5bSRajnesh Kanwal }
353540336d5bSRajnesh Kanwal 
write_hstatus(CPURISCVState * env,int csrno,target_ulong val)353640336d5bSRajnesh Kanwal static RISCVException write_hstatus(CPURISCVState *env, int csrno,
353740336d5bSRajnesh Kanwal                                     target_ulong val)
353840336d5bSRajnesh Kanwal {
353940336d5bSRajnesh Kanwal     env->hstatus = val;
354040336d5bSRajnesh Kanwal     if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
354140336d5bSRajnesh Kanwal         qemu_log_mask(LOG_UNIMP,
354240336d5bSRajnesh Kanwal                       "QEMU does not support mixed HSXLEN options.");
354340336d5bSRajnesh Kanwal     }
354440336d5bSRajnesh Kanwal     if (get_field(val, HSTATUS_VSBE) != 0) {
354540336d5bSRajnesh Kanwal         qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
354640336d5bSRajnesh Kanwal     }
354740336d5bSRajnesh Kanwal     return RISCV_EXCP_NONE;
354840336d5bSRajnesh Kanwal }
354940336d5bSRajnesh Kanwal 
read_hedeleg(CPURISCVState * env,int csrno,target_ulong * val)355040336d5bSRajnesh Kanwal static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
355140336d5bSRajnesh Kanwal                                    target_ulong *val)
355240336d5bSRajnesh Kanwal {
355340336d5bSRajnesh Kanwal     *val = env->hedeleg;
355440336d5bSRajnesh Kanwal     return RISCV_EXCP_NONE;
355540336d5bSRajnesh Kanwal }
3556d028ac75SAnup Patel 
write_hedeleg(CPURISCVState * env,int csrno,target_ulong val)3557d028ac75SAnup Patel static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
3558d028ac75SAnup Patel                                     target_ulong val)
3559ff2cc129SAlistair Francis {
3560d028ac75SAnup Patel     env->hedeleg = val & vs_delegable_excps;
3561d028ac75SAnup Patel     return RISCV_EXCP_NONE;
3562d028ac75SAnup Patel }
3563d028ac75SAnup Patel 
read_hedelegh(CPURISCVState * env,int csrno,target_ulong * val)3564d028ac75SAnup Patel static RISCVException read_hedelegh(CPURISCVState *env, int csrno,
3565d028ac75SAnup Patel                                    target_ulong *val)
3566d028ac75SAnup Patel {
3567605def6eSAlistair Francis     RISCVException ret;
3568ff2cc129SAlistair Francis     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_P1P13);
3569ff2cc129SAlistair Francis     if (ret != RISCV_EXCP_NONE) {
3570d028ac75SAnup Patel         return ret;
3571d028ac75SAnup Patel     }
3572d028ac75SAnup Patel 
3573ff2cc129SAlistair Francis     /* Reserved, now read zero */
3574d028ac75SAnup Patel     *val = 0;
3575d028ac75SAnup Patel     return RISCV_EXCP_NONE;
3576d028ac75SAnup Patel }
3577d028ac75SAnup Patel 
write_hedelegh(CPURISCVState * env,int csrno,target_ulong val)3578d028ac75SAnup Patel static RISCVException write_hedelegh(CPURISCVState *env, int csrno,
3579d028ac75SAnup Patel                                     target_ulong val)
3580d028ac75SAnup Patel {
3581d028ac75SAnup Patel     RISCVException ret;
3582d028ac75SAnup Patel     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_P1P13);
3583d028ac75SAnup Patel     if (ret != RISCV_EXCP_NONE) {
3584d028ac75SAnup Patel         return ret;
3585d028ac75SAnup Patel     }
3586d028ac75SAnup Patel 
3587d028ac75SAnup Patel     /* Reserved, now write ignore */
3588d028ac75SAnup Patel     return RISCV_EXCP_NONE;
3589d028ac75SAnup Patel }
3590d028ac75SAnup Patel 
rmw_hvien64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3591d028ac75SAnup Patel static RISCVException rmw_hvien64(CPURISCVState *env, int csrno,
3592d028ac75SAnup Patel                                     uint64_t *ret_val,
3593d028ac75SAnup Patel                                     uint64_t new_val, uint64_t wr_mask)
3594d028ac75SAnup Patel {
3595d028ac75SAnup Patel     uint64_t mask = wr_mask & hvien_writable_mask;
3596d028ac75SAnup Patel 
3597d028ac75SAnup Patel     if (ret_val) {
3598d028ac75SAnup Patel         *ret_val = env->hvien;
3599d028ac75SAnup Patel     }
3600d028ac75SAnup Patel 
360140336d5bSRajnesh Kanwal     env->hvien = (env->hvien & ~mask) | (new_val & mask);
360240336d5bSRajnesh Kanwal 
360340336d5bSRajnesh Kanwal     return RISCV_EXCP_NONE;
360440336d5bSRajnesh Kanwal }
360540336d5bSRajnesh Kanwal 
rmw_hvien(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)360640336d5bSRajnesh Kanwal static RISCVException rmw_hvien(CPURISCVState *env, int csrno,
360740336d5bSRajnesh Kanwal                                target_ulong *ret_val,
360840336d5bSRajnesh Kanwal                                target_ulong new_val, target_ulong wr_mask)
360940336d5bSRajnesh Kanwal {
3610d028ac75SAnup Patel     uint64_t rval;
3611d028ac75SAnup Patel     RISCVException ret;
3612d028ac75SAnup Patel 
3613d028ac75SAnup Patel     ret = rmw_hvien64(env, csrno, &rval, new_val, wr_mask);
3614d028ac75SAnup Patel     if (ret_val) {
361540336d5bSRajnesh Kanwal         *ret_val = rval;
361640336d5bSRajnesh Kanwal     }
3617d028ac75SAnup Patel 
361840336d5bSRajnesh Kanwal     return ret;
361940336d5bSRajnesh Kanwal }
362040336d5bSRajnesh Kanwal 
rmw_hvienh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)362140336d5bSRajnesh Kanwal static RISCVException rmw_hvienh(CPURISCVState *env, int csrno,
362240336d5bSRajnesh Kanwal                                    target_ulong *ret_val,
362340336d5bSRajnesh Kanwal                                    target_ulong new_val, target_ulong wr_mask)
362440336d5bSRajnesh Kanwal {
362540336d5bSRajnesh Kanwal     uint64_t rval;
362640336d5bSRajnesh Kanwal     RISCVException ret;
362740336d5bSRajnesh Kanwal 
362840336d5bSRajnesh Kanwal     ret = rmw_hvien64(env, csrno, &rval,
362940336d5bSRajnesh Kanwal         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
363040336d5bSRajnesh Kanwal     if (ret_val) {
363140336d5bSRajnesh Kanwal         *ret_val = rval >> 32;
363240336d5bSRajnesh Kanwal     }
363340336d5bSRajnesh Kanwal 
363440336d5bSRajnesh Kanwal     return ret;
363540336d5bSRajnesh Kanwal }
363640336d5bSRajnesh Kanwal 
rmw_hideleg64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)363740336d5bSRajnesh Kanwal static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
363840336d5bSRajnesh Kanwal                                     uint64_t *ret_val,
363940336d5bSRajnesh Kanwal                                     uint64_t new_val, uint64_t wr_mask)
364040336d5bSRajnesh Kanwal {
364140336d5bSRajnesh Kanwal     uint64_t mask = wr_mask & vs_delegable_ints;
364240336d5bSRajnesh Kanwal 
364340336d5bSRajnesh Kanwal     if (ret_val) {
364440336d5bSRajnesh Kanwal         *ret_val = env->hideleg & vs_delegable_ints;
364540336d5bSRajnesh Kanwal     }
364640336d5bSRajnesh Kanwal 
364740336d5bSRajnesh Kanwal     env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
364840336d5bSRajnesh Kanwal     return RISCV_EXCP_NONE;
364940336d5bSRajnesh Kanwal }
365040336d5bSRajnesh Kanwal 
rmw_hideleg(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)365140336d5bSRajnesh Kanwal static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
365240336d5bSRajnesh Kanwal                                   target_ulong *ret_val,
365340336d5bSRajnesh Kanwal                                   target_ulong new_val, target_ulong wr_mask)
365440336d5bSRajnesh Kanwal {
365540336d5bSRajnesh Kanwal     uint64_t rval;
365640336d5bSRajnesh Kanwal     RISCVException ret;
365740336d5bSRajnesh Kanwal 
365840336d5bSRajnesh Kanwal     ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
365940336d5bSRajnesh Kanwal     if (ret_val) {
366040336d5bSRajnesh Kanwal         *ret_val = rval;
366140336d5bSRajnesh Kanwal     }
366240336d5bSRajnesh Kanwal 
366340336d5bSRajnesh Kanwal     return ret;
366440336d5bSRajnesh Kanwal }
366540336d5bSRajnesh Kanwal 
rmw_hidelegh(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)366640336d5bSRajnesh Kanwal static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
366740336d5bSRajnesh Kanwal                                    target_ulong *ret_val,
366840336d5bSRajnesh Kanwal                                    target_ulong new_val, target_ulong wr_mask)
366940336d5bSRajnesh Kanwal {
367040336d5bSRajnesh Kanwal     uint64_t rval;
367140336d5bSRajnesh Kanwal     RISCVException ret;
367240336d5bSRajnesh Kanwal 
367340336d5bSRajnesh Kanwal     ret = rmw_hideleg64(env, csrno, &rval,
367440336d5bSRajnesh Kanwal         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
367540336d5bSRajnesh Kanwal     if (ret_val) {
367640336d5bSRajnesh Kanwal         *ret_val = rval >> 32;
367740336d5bSRajnesh Kanwal     }
367840336d5bSRajnesh Kanwal 
367940336d5bSRajnesh Kanwal     return ret;
368040336d5bSRajnesh Kanwal }
3681d028ac75SAnup Patel 
368240336d5bSRajnesh Kanwal /*
368340336d5bSRajnesh Kanwal  * The function is written for two use-cases:
368440336d5bSRajnesh Kanwal  * 1- To access hvip csr as is for HS-mode access.
368540336d5bSRajnesh Kanwal  * 2- To access vsip as a combination of hvip, and mip for vs-mode.
368640336d5bSRajnesh Kanwal  *
368740336d5bSRajnesh Kanwal  * Both report bits 2, 6, 10 and 13:63.
368840336d5bSRajnesh Kanwal  * vsip needs to be read-only zero when both hideleg[i] and
3689d028ac75SAnup Patel  * hvien[i] are zero.
3690d028ac75SAnup Patel  */
rmw_hvip64(CPURISCVState * env,int csrno,uint64_t * ret_val,uint64_t new_val,uint64_t wr_mask)3691d028ac75SAnup Patel static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
3692ff2cc129SAlistair Francis                                  uint64_t *ret_val,
3693ff2cc129SAlistair Francis                                  uint64_t new_val, uint64_t wr_mask)
3694605def6eSAlistair Francis {
3695d028ac75SAnup Patel     RISCVException ret;
3696d028ac75SAnup Patel     uint64_t old_hvip;
369783028098SAlistair Francis     uint64_t ret_mip;
3698d028ac75SAnup Patel 
3699d028ac75SAnup Patel     /*
370083028098SAlistair Francis      * For bits 10, 6 and 2, vsip[i] is an alias of hip[i]. These bits are
3701d028ac75SAnup Patel      * present in hip, hvip and mip. Where mip[i] is alias of hip[i] and hvip[i]
3702d028ac75SAnup Patel      * is OR'ed in hip[i] to inject virtual interrupts from hypervisor. These
3703d028ac75SAnup Patel      * bits are actually being maintained in mip so we read them from there.
370433979526SRichard Henderson      * This way we have a single source of truth and allows for easier
3705d028ac75SAnup Patel      * implementation.
3706d028ac75SAnup Patel      *
3707d028ac75SAnup Patel      * For bits 13:63 we have:
3708d028ac75SAnup Patel      *
3709d028ac75SAnup Patel      * hideleg[i]  hvien[i]
3710d028ac75SAnup Patel      *   0           0      No delegation. vsip[i] readonly zero.
3711d028ac75SAnup Patel      *   0           1      vsip[i] is alias of hvip[i], sip bypassed.
3712d028ac75SAnup Patel      *   1           X      vsip[i] is alias of sip[i], hvip bypassed.
3713d028ac75SAnup Patel      *
3714d028ac75SAnup Patel      *  alias_mask denotes the bits that come from sip (mip here given we
3715d028ac75SAnup Patel      *  maintain all bits there). nalias_mask denotes bits that come from
3716d028ac75SAnup Patel      *  hvip.
3717d028ac75SAnup Patel      */
3718d028ac75SAnup Patel     uint64_t alias_mask = (env->hideleg | ~env->hvien) | VS_MODE_INTERRUPTS;
3719d028ac75SAnup Patel     uint64_t nalias_mask = (~env->hideleg & env->hvien);
3720d028ac75SAnup Patel     uint64_t wr_mask_hvip;
3721d028ac75SAnup Patel     uint64_t wr_mask_mip;
372283028098SAlistair Francis 
372383028098SAlistair Francis     /*
372483028098SAlistair Francis      * Both alias and non-alias mask remain same for vsip except:
3725605def6eSAlistair Francis      *  1- For VS* bits if they are zero in hideleg.
3726605def6eSAlistair Francis      *  2- For 13:63 bits if they are zero in both hideleg and hvien.
3727ff2cc129SAlistair Francis      */
3728ff2cc129SAlistair Francis     if (csrno == CSR_VSIP) {
3729cd032fe7SAnup Patel         /* zero-out VS* bits that are not delegated to VS mode. */
3730ff2cc129SAlistair Francis         alias_mask &= (env->hideleg | ~VS_MODE_INTERRUPTS);
3731ff2cc129SAlistair Francis 
373233979526SRichard Henderson         /*
3733881df35dSAnup Patel          * zero-out 13:63 bits that are zero in both hideleg and hvien.
373433979526SRichard Henderson          * nalias_mask mask can not contain any VS* bits so only second
3735ff2cc129SAlistair Francis          * condition applies on it.
3736ff2cc129SAlistair Francis          */
3737ff2cc129SAlistair Francis         nalias_mask &= (env->hideleg | env->hvien);
3738d028ac75SAnup Patel         alias_mask &= (env->hideleg | env->hvien);
3739d028ac75SAnup Patel     }
3740d028ac75SAnup Patel 
3741ff2cc129SAlistair Francis     wr_mask_hvip = wr_mask & nalias_mask & hvip_writable_mask;
3742d028ac75SAnup Patel     wr_mask_mip = wr_mask & alias_mask & hvip_writable_mask;
3743d028ac75SAnup Patel 
3744d028ac75SAnup Patel     /* Aliased bits, bits 10, 6, 2 need to come from mip. */
3745d028ac75SAnup Patel     ret = rmw_mip64(env, csrno, &ret_mip, new_val, wr_mask_mip);
3746d028ac75SAnup Patel     if (ret != RISCV_EXCP_NONE) {
3747d028ac75SAnup Patel         return ret;
3748ff2cc129SAlistair Francis     }
3749ff2cc129SAlistair Francis 
3750d028ac75SAnup Patel     old_hvip = env->hvip;
3751ff2cc129SAlistair Francis 
3752ff2cc129SAlistair Francis     if (wr_mask_hvip) {
3753605def6eSAlistair Francis         env->hvip = (env->hvip & ~wr_mask_hvip) | (new_val & wr_mask_hvip);
3754605def6eSAlistair Francis 
3755ff2cc129SAlistair Francis         /*
3756ff2cc129SAlistair Francis          * Given hvip is separate source from mip, we need to trigger interrupt
3757605def6eSAlistair Francis          * from here separately. Normally this happen from riscv_cpu_update_mip.
3758ff2cc129SAlistair Francis          */
3759ff2cc129SAlistair Francis         riscv_cpu_interrupt(env);
3760605def6eSAlistair Francis     }
3761605def6eSAlistair Francis 
3762ff2cc129SAlistair Francis     if (ret_val) {
37638cff74c2SAtish Patra         /* Only take VS* bits from mip. */
37648cff74c2SAtish Patra         ret_mip &= alias_mask;
37658cff74c2SAtish Patra 
37668cff74c2SAtish Patra         /* Take in non-delegated 13:63 bits from hvip. */
37678cff74c2SAtish Patra         old_hvip &= nalias_mask;
3768605def6eSAlistair Francis 
3769ff2cc129SAlistair Francis         *ret_val = ret_mip | old_hvip;
3770ff2cc129SAlistair Francis     }
3771cd032fe7SAnup Patel 
3772cd032fe7SAnup Patel     return ret;
3773cd032fe7SAnup Patel }
3774cd032fe7SAnup Patel 
rmw_hvip(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3775cd032fe7SAnup Patel static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
3776cd032fe7SAnup Patel                                target_ulong *ret_val,
3777cd032fe7SAnup Patel                                target_ulong new_val, target_ulong wr_mask)
3778cd032fe7SAnup Patel {
3779cd032fe7SAnup Patel     uint64_t rval;
3780605def6eSAlistair Francis     RISCVException ret;
3781605def6eSAlistair Francis 
378283028098SAlistair Francis     ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
3783cd032fe7SAnup Patel     if (ret_val) {
3784cd032fe7SAnup Patel         *ret_val = rval;
3785cd032fe7SAnup Patel     }
3786cd032fe7SAnup Patel 
3787bbb9fc25SWeiwei Li     return ret;
3788cd032fe7SAnup Patel }
3789605def6eSAlistair Francis 
rmw_hviph(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)379083028098SAlistair Francis static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
379183028098SAlistair Francis                                 target_ulong *ret_val,
3792605def6eSAlistair Francis                                 target_ulong new_val, target_ulong wr_mask)
3793605def6eSAlistair Francis {
3794ff2cc129SAlistair Francis     uint64_t rval;
3795ff2cc129SAlistair Francis     RISCVException ret;
3796605def6eSAlistair Francis 
3797ff2cc129SAlistair Francis     ret = rmw_hvip64(env, csrno, &rval,
3798ff2cc129SAlistair Francis         ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
3799605def6eSAlistair Francis     if (ret_val) {
3800605def6eSAlistair Francis         *ret_val = rval >> 32;
3801ff2cc129SAlistair Francis     }
3802ff2cc129SAlistair Francis 
3803605def6eSAlistair Francis     return ret;
3804ff2cc129SAlistair Francis }
3805ff2cc129SAlistair Francis 
rmw_hip(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)3806605def6eSAlistair Francis static RISCVException rmw_hip(CPURISCVState *env, int csrno,
3807605def6eSAlistair Francis                               target_ulong *ret_value,
3808ff2cc129SAlistair Francis                               target_ulong new_value, target_ulong write_mask)
3809ff2cc129SAlistair Francis {
3810605def6eSAlistair Francis     int ret = rmw_mip(env, csrno, ret_value, new_value,
3811ff2cc129SAlistair Francis                       write_mask & hip_writable_mask);
3812ff2cc129SAlistair Francis 
3813605def6eSAlistair Francis     if (ret_value) {
3814605def6eSAlistair Francis         *ret_value &= HS_MODE_INTERRUPTS;
3815ff2cc129SAlistair Francis     }
3816605def6eSAlistair Francis     return ret;
3817ff2cc129SAlistair Francis }
3818ff2cc129SAlistair Francis 
rmw_hie(CPURISCVState * env,int csrno,target_ulong * ret_val,target_ulong new_val,target_ulong wr_mask)3819cd032fe7SAnup Patel static RISCVException rmw_hie(CPURISCVState *env, int csrno,
3820cd032fe7SAnup Patel                               target_ulong *ret_val,
382183028098SAlistair Francis                               target_ulong new_val, target_ulong wr_mask)
3822377cbb4bSRichard Henderson {
3823cd032fe7SAnup Patel     uint64_t rval;
3824377cbb4bSRichard Henderson     RISCVException ret;
3825605def6eSAlistair Francis 
382683028098SAlistair Francis     ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
382783028098SAlistair Francis     if (ret_val) {
3828605def6eSAlistair Francis         *ret_val = rval & HS_MODE_INTERRUPTS;
3829605def6eSAlistair Francis     }
3830ff2cc129SAlistair Francis 
3831ff2cc129SAlistair Francis     return ret;
3832605def6eSAlistair Francis }
3833ff2cc129SAlistair Francis 
read_hcounteren(CPURISCVState * env,int csrno,target_ulong * val)3834ff2cc129SAlistair Francis static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
3835605def6eSAlistair Francis                                       target_ulong *val)
3836605def6eSAlistair Francis {
3837ff2cc129SAlistair Francis     *val = env->hcounteren;
38381349f969SIrina Ryapolova     return RISCV_EXCP_NONE;
3839605def6eSAlistair Francis }
3840ff2cc129SAlistair Francis 
write_hcounteren(CPURISCVState * env,int csrno,target_ulong val)3841ff2cc129SAlistair Francis static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
3842605def6eSAlistair Francis                                        target_ulong val)
3843605def6eSAlistair Francis {
3844c6957248SAnup Patel     RISCVCPU *cpu = env_archcpu(env);
3845c6957248SAnup Patel 
3846605def6eSAlistair Francis     /* WARL register - disable unavailable counters */
3847c6957248SAnup Patel     env->hcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
3848c6957248SAnup Patel                              COUNTEREN_IR);
3849c6957248SAnup Patel     return RISCV_EXCP_NONE;
3850605def6eSAlistair Francis }
3851c6957248SAnup Patel 
read_hgeie(CPURISCVState * env,int csrno,target_ulong * val)3852c6957248SAnup Patel static RISCVException read_hgeie(CPURISCVState *env, int csrno,
3853605def6eSAlistair Francis                                  target_ulong *val)
3854605def6eSAlistair Francis {
3855c6957248SAnup Patel     if (val) {
3856c6957248SAnup Patel         *val = env->hgeie;
3857605def6eSAlistair Francis     }
3858c6957248SAnup Patel     return RISCV_EXCP_NONE;
3859c6957248SAnup Patel }
3860db23e5d9SRichard Henderson 
write_hgeie(CPURISCVState * env,int csrno,target_ulong val)3861c6957248SAnup Patel static RISCVException write_hgeie(CPURISCVState *env, int csrno,
38628987cdc4SAlistair Francis                                   target_ulong val)
3863c6957248SAnup Patel {
38648987cdc4SAlistair Francis     /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
38652cfb3b6cSAnup Patel     val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
3866bbb9fc25SWeiwei Li     env->hgeie = val;
3867bbb9fc25SWeiwei Li     /* Update mip.SGEIP bit */
38682cfb3b6cSAnup Patel     riscv_cpu_update_mip(env, MIP_SGEIP,
38692cfb3b6cSAnup Patel                          BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
38702cfb3b6cSAnup Patel     return RISCV_EXCP_NONE;
3871605def6eSAlistair Francis }
3872c6957248SAnup Patel 
read_htval(CPURISCVState * env,int csrno,target_ulong * val)3873c6957248SAnup Patel static RISCVException read_htval(CPURISCVState *env, int csrno,
3874605def6eSAlistair Francis                                  target_ulong *val)
3875605def6eSAlistair Francis {
3876c6957248SAnup Patel     *val = env->htval;
3877c6957248SAnup Patel     return RISCV_EXCP_NONE;
3878605def6eSAlistair Francis }
3879c6957248SAnup Patel 
write_htval(CPURISCVState * env,int csrno,target_ulong val)3880c6957248SAnup Patel static RISCVException write_htval(CPURISCVState *env, int csrno,
3881c6957248SAnup Patel                                   target_ulong val)
3882605def6eSAlistair Francis {
3883c6957248SAnup Patel     env->htval = val;
3884c6957248SAnup Patel     return RISCV_EXCP_NONE;
3885605def6eSAlistair Francis }
3886605def6eSAlistair Francis 
read_htinst(CPURISCVState * env,int csrno,target_ulong * val)3887c6957248SAnup Patel static RISCVException read_htinst(CPURISCVState *env, int csrno,
3888c6957248SAnup Patel                                   target_ulong *val)
3889605def6eSAlistair Francis {
3890c6957248SAnup Patel     *val = env->htinst;
3891c6957248SAnup Patel     return RISCV_EXCP_NONE;
3892c6957248SAnup Patel }
38932cfb3b6cSAnup Patel 
write_htinst(CPURISCVState * env,int csrno,target_ulong val)3894bbb9fc25SWeiwei Li static RISCVException write_htinst(CPURISCVState *env, int csrno,
3895bbb9fc25SWeiwei Li                                    target_ulong val)
38962cfb3b6cSAnup Patel {
38972cfb3b6cSAnup Patel     return RISCV_EXCP_NONE;
38982cfb3b6cSAnup Patel }
3899605def6eSAlistair Francis 
read_hgeip(CPURISCVState * env,int csrno,target_ulong * val)3900c6957248SAnup Patel static RISCVException read_hgeip(CPURISCVState *env, int csrno,
3901c6957248SAnup Patel                                  target_ulong *val)
3902a5cb044cSLIU Zhiwei {
3903a5cb044cSLIU Zhiwei     if (val) {
39042b602398SAnup Patel         *val = env->hgeip;
39052b602398SAnup Patel     }
39062b602398SAnup Patel     return RISCV_EXCP_NONE;
39072b602398SAnup Patel }
39082b602398SAnup Patel 
read_hgatp(CPURISCVState * env,int csrno,target_ulong * val)3909a5cb044cSLIU Zhiwei static RISCVException read_hgatp(CPURISCVState *env, int csrno,
3910a5cb044cSLIU Zhiwei                                  target_ulong *val)
39112b602398SAnup Patel {
39122b602398SAnup Patel     *val = env->hgatp;
39132b602398SAnup Patel     return RISCV_EXCP_NONE;
39142b602398SAnup Patel }
39152b602398SAnup Patel 
write_hgatp(CPURISCVState * env,int csrno,target_ulong val)3916a5cb044cSLIU Zhiwei static RISCVException write_hgatp(CPURISCVState *env, int csrno,
39172b602398SAnup Patel                                   target_ulong val)
39182b602398SAnup Patel {
39192b602398SAnup Patel     env->hgatp = legalize_xatp(env, env->hgatp, val);
39202b602398SAnup Patel     return RISCV_EXCP_NONE;
39212b602398SAnup Patel }
39222b602398SAnup Patel 
read_htimedelta(CPURISCVState * env,int csrno,target_ulong * val)392338256529SWeiwei Li static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
39242b602398SAnup Patel                                       target_ulong *val)
39252b602398SAnup Patel {
39262b602398SAnup Patel     if (!env->rdtime_fn) {
39272b602398SAnup Patel         return RISCV_EXCP_ILLEGAL_INST;
39282b602398SAnup Patel     }
39292b602398SAnup Patel 
39302b602398SAnup Patel     *val = env->htimedelta;
39312b602398SAnup Patel     return RISCV_EXCP_NONE;
39322b602398SAnup Patel }
39332b602398SAnup Patel 
write_htimedelta(CPURISCVState * env,int csrno,target_ulong val)39342b602398SAnup Patel static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
39352b602398SAnup Patel                                        target_ulong val)
39362b602398SAnup Patel {
39372b602398SAnup Patel     if (!env->rdtime_fn) {
39382b602398SAnup Patel         return RISCV_EXCP_ILLEGAL_INST;
39392b602398SAnup Patel     }
39402b602398SAnup Patel 
39412b602398SAnup Patel     if (riscv_cpu_mxl(env) == MXL_RV32) {
3942a5cb044cSLIU Zhiwei         env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
39432b602398SAnup Patel     } else {
39442b602398SAnup Patel         env->htimedelta = val;
39452b602398SAnup Patel     }
39462b602398SAnup Patel 
39472b602398SAnup Patel     if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
39482b602398SAnup Patel         riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
394938256529SWeiwei Li                                   env->htimedelta, MIP_VSTIP);
39502b602398SAnup Patel     }
39512b602398SAnup Patel 
39522b602398SAnup Patel     return RISCV_EXCP_NONE;
395342fe7499SMichael Tokarev }
39542b602398SAnup Patel 
read_htimedeltah(CPURISCVState * env,int csrno,target_ulong * val)39552b602398SAnup Patel static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
39562b602398SAnup Patel                                        target_ulong *val)
39572b602398SAnup Patel {
39582b602398SAnup Patel     if (!env->rdtime_fn) {
39592b602398SAnup Patel         return RISCV_EXCP_ILLEGAL_INST;
39602b602398SAnup Patel     }
39612b602398SAnup Patel 
39622b602398SAnup Patel     *val = env->htimedelta >> 32;
39632b602398SAnup Patel     return RISCV_EXCP_NONE;
39642b602398SAnup Patel }
39652b602398SAnup Patel 
write_htimedeltah(CPURISCVState * env,int csrno,target_ulong val)39662b602398SAnup Patel static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
39672b602398SAnup Patel                                         target_ulong val)
3968a5cb044cSLIU Zhiwei {
3969a5cb044cSLIU Zhiwei     if (!env->rdtime_fn) {
39702b602398SAnup Patel         return RISCV_EXCP_ILLEGAL_INST;
39712b602398SAnup Patel     }
39722b602398SAnup Patel 
39732b602398SAnup Patel     env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
3974a5cb044cSLIU Zhiwei 
3975a5cb044cSLIU Zhiwei     if (riscv_cpu_cfg(env)->ext_sstc && env->rdtime_fn) {
39762b602398SAnup Patel         riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
39772b602398SAnup Patel                                   env->htimedelta, MIP_VSTIP);
39782b602398SAnup Patel     }
39792b602398SAnup Patel 
3980a5cb044cSLIU Zhiwei     return RISCV_EXCP_NONE;
3981a5cb044cSLIU Zhiwei }
39822b602398SAnup Patel 
read_hvictl(CPURISCVState * env,int csrno,target_ulong * val)39832b602398SAnup Patel static RISCVException read_hvictl(CPURISCVState *env, int csrno,
39842b602398SAnup Patel                                   target_ulong *val)
39852b602398SAnup Patel {
3986a5cb044cSLIU Zhiwei     *val = env->hvictl;
3987a5cb044cSLIU Zhiwei     return RISCV_EXCP_NONE;
39882b602398SAnup Patel }
39892b602398SAnup Patel 
write_hvictl(CPURISCVState * env,int csrno,target_ulong val)39902b602398SAnup Patel static RISCVException write_hvictl(CPURISCVState *env, int csrno,
39912b602398SAnup Patel                                    target_ulong val)
3992a5cb044cSLIU Zhiwei {
3993a5cb044cSLIU Zhiwei     env->hvictl = val & HVICTL_VALID_MASK;
39942b602398SAnup Patel     return RISCV_EXCP_NONE;
39952b602398SAnup Patel }
39962b602398SAnup Patel 
read_hvipriox(CPURISCVState * env,int first_index,uint8_t * iprio,target_ulong * val)39972b602398SAnup Patel static RISCVException read_hvipriox(CPURISCVState *env, int first_index,
3998a5cb044cSLIU Zhiwei                          uint8_t *iprio, target_ulong *val)
3999a5cb044cSLIU Zhiwei {
40002b602398SAnup Patel     int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
40012b602398SAnup Patel 
40022b602398SAnup Patel     /* First index has to be a multiple of number of irqs per register */
40032b602398SAnup Patel     if (first_index % num_irqs) {
4004a5cb044cSLIU Zhiwei         return (env->virt_enabled) ?
4005a5cb044cSLIU Zhiwei                RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
40062b602398SAnup Patel     }
40072b602398SAnup Patel 
40082b602398SAnup Patel     /* Fill-up return value */
40092b602398SAnup Patel     *val = 0;
4010a5cb044cSLIU Zhiwei     for (i = 0; i < num_irqs; i++) {
4011a5cb044cSLIU Zhiwei         if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
40122b602398SAnup Patel             continue;
40132b602398SAnup Patel         }
40142b602398SAnup Patel         if (rdzero) {
40152b602398SAnup Patel             continue;
40168747c9eeSAlistair Francis         }
4017605def6eSAlistair Francis         *val |= ((target_ulong)iprio[irq]) << (i * 8);
4018605def6eSAlistair Francis     }
40198747c9eeSAlistair Francis 
40208747c9eeSAlistair Francis     return RISCV_EXCP_NONE;
4021605def6eSAlistair Francis }
40228747c9eeSAlistair Francis 
write_hvipriox(CPURISCVState * env,int first_index,uint8_t * iprio,target_ulong val)40238747c9eeSAlistair Francis static RISCVException write_hvipriox(CPURISCVState *env, int first_index,
4024605def6eSAlistair Francis                           uint8_t *iprio, target_ulong val)
4025605def6eSAlistair Francis {
40268747c9eeSAlistair Francis     int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
4027284d697cSYifei Jiang 
4028f310df58SLIU Zhiwei     /* First index has to be a multiple of number of irqs per register */
4029f310df58SLIU Zhiwei     if (first_index % num_irqs) {
4030f310df58SLIU Zhiwei         return (env->virt_enabled) ?
4031284d697cSYifei Jiang                RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
4032605def6eSAlistair Francis     }
40338747c9eeSAlistair Francis 
40348747c9eeSAlistair Francis     /* Fill-up priority array */
4035a5cb044cSLIU Zhiwei     for (i = 0; i < num_irqs; i++) {
4036a5cb044cSLIU Zhiwei         if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
40378747c9eeSAlistair Francis             continue;
40388747c9eeSAlistair Francis         }
4039605def6eSAlistair Francis         if (rdzero) {
40408747c9eeSAlistair Francis             iprio[irq] = 0;
40418747c9eeSAlistair Francis         } else {
4042605def6eSAlistair Francis             iprio[irq] = (val >> (i * 8)) & 0xff;
4043605def6eSAlistair Francis         }
40448747c9eeSAlistair Francis     }
4045910c18a9SJiayi Li 
4046910c18a9SJiayi Li     return RISCV_EXCP_NONE;
40478747c9eeSAlistair Francis }
4048910c18a9SJiayi Li 
read_hviprio1(CPURISCVState * env,int csrno,target_ulong * val)4049910c18a9SJiayi Li static RISCVException read_hviprio1(CPURISCVState *env, int csrno,
4050910c18a9SJiayi Li                                     target_ulong *val)
4051605def6eSAlistair Francis {
40528747c9eeSAlistair Francis     return read_hvipriox(env, 0, env->hviprio, val);
40538747c9eeSAlistair Francis }
4054605def6eSAlistair Francis 
write_hviprio1(CPURISCVState * env,int csrno,target_ulong val)4055605def6eSAlistair Francis static RISCVException write_hviprio1(CPURISCVState *env, int csrno,
40568747c9eeSAlistair Francis                                      target_ulong val)
40578747c9eeSAlistair Francis {
4058605def6eSAlistair Francis     return write_hvipriox(env, 0, env->hviprio, val);
40598747c9eeSAlistair Francis }
40608747c9eeSAlistair Francis 
read_hviprio1h(CPURISCVState * env,int csrno,target_ulong * val)4061605def6eSAlistair Francis static RISCVException read_hviprio1h(CPURISCVState *env, int csrno,
4062605def6eSAlistair Francis                                      target_ulong *val)
40638747c9eeSAlistair Francis {
40648747c9eeSAlistair Francis     return read_hvipriox(env, 4, env->hviprio, val);
4065605def6eSAlistair Francis }
40668747c9eeSAlistair Francis 
write_hviprio1h(CPURISCVState * env,int csrno,target_ulong val)40678747c9eeSAlistair Francis static RISCVException write_hviprio1h(CPURISCVState *env, int csrno,
4068605def6eSAlistair Francis                                       target_ulong val)
4069605def6eSAlistair Francis {
40708747c9eeSAlistair Francis     return write_hvipriox(env, 4, env->hviprio, val);
40718747c9eeSAlistair Francis }
4072605def6eSAlistair Francis 
read_hviprio2(CPURISCVState * env,int csrno,target_ulong * val)40738747c9eeSAlistair Francis static RISCVException read_hviprio2(CPURISCVState *env, int csrno,
40748747c9eeSAlistair Francis                                     target_ulong *val)
4075605def6eSAlistair Francis {
4076605def6eSAlistair Francis     return read_hvipriox(env, 8, env->hviprio, val);
40778747c9eeSAlistair Francis }
40788747c9eeSAlistair Francis 
write_hviprio2(CPURISCVState * env,int csrno,target_ulong val)4079605def6eSAlistair Francis static RISCVException write_hviprio2(CPURISCVState *env, int csrno,
40808747c9eeSAlistair Francis                                      target_ulong val)
40818747c9eeSAlistair Francis {
4082605def6eSAlistair Francis     return write_hvipriox(env, 8, env->hviprio, val);
4083605def6eSAlistair Francis }
40848747c9eeSAlistair Francis 
read_hviprio2h(CPURISCVState * env,int csrno,target_ulong * val)40858747c9eeSAlistair Francis static RISCVException read_hviprio2h(CPURISCVState *env, int csrno,
4086605def6eSAlistair Francis                                      target_ulong *val)
40878747c9eeSAlistair Francis {
40888747c9eeSAlistair Francis     return read_hvipriox(env, 12, env->hviprio, val);
4089605def6eSAlistair Francis }
4090605def6eSAlistair Francis 
write_hviprio2h(CPURISCVState * env,int csrno,target_ulong val)40918747c9eeSAlistair Francis static RISCVException write_hviprio2h(CPURISCVState *env, int csrno,
40928747c9eeSAlistair Francis                                       target_ulong val)
4093605def6eSAlistair Francis {
40948747c9eeSAlistair Francis     return write_hvipriox(env, 12, env->hviprio, val);
40958747c9eeSAlistair Francis }
4096605def6eSAlistair Francis 
4097605def6eSAlistair Francis /* Virtual CSR Registers */
read_vsstatus(CPURISCVState * env,int csrno,target_ulong * val)40988747c9eeSAlistair Francis static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
40998747c9eeSAlistair Francis                                     target_ulong *val)
4100605def6eSAlistair Francis {
41018747c9eeSAlistair Francis     *val = env->vsstatus;
41028747c9eeSAlistair Francis     return RISCV_EXCP_NONE;
4103605def6eSAlistair Francis }
4104605def6eSAlistair Francis 
write_vsstatus(CPURISCVState * env,int csrno,target_ulong val)41058747c9eeSAlistair Francis static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
41068747c9eeSAlistair Francis                                      target_ulong val)
4107605def6eSAlistair Francis {
41088747c9eeSAlistair Francis     uint64_t mask = (target_ulong)-1;
41098747c9eeSAlistair Francis     if ((val & VSSTATUS64_UXL) == 0) {
4110605def6eSAlistair Francis         mask &= ~VSSTATUS64_UXL;
4111605def6eSAlistair Francis     }
41128747c9eeSAlistair Francis     env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
41138747c9eeSAlistair Francis     return RISCV_EXCP_NONE;
4114605def6eSAlistair Francis }
41158747c9eeSAlistair Francis 
read_vstvec(CPURISCVState * env,int csrno,target_ulong * val)41168747c9eeSAlistair Francis static RISCVException read_vstvec(CPURISCVState *env, int csrno,
4117605def6eSAlistair Francis                                   target_ulong *val)
4118605def6eSAlistair Francis {
41198747c9eeSAlistair Francis     *val = env->vstvec;
41201349f969SIrina Ryapolova     return RISCV_EXCP_NONE;
4121605def6eSAlistair Francis }
41228747c9eeSAlistair Francis 
write_vstvec(CPURISCVState * env,int csrno,target_ulong val)41238747c9eeSAlistair Francis static RISCVException write_vstvec(CPURISCVState *env, int csrno,
4124605def6eSAlistair Francis                                    target_ulong val)
4125605def6eSAlistair Francis {
412634cfb5f6SAlistair Francis     /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
412734cfb5f6SAlistair Francis     if ((val & 3) < 2) {
4128605def6eSAlistair Francis         env->vstvec = val;
412934cfb5f6SAlistair Francis     } else {
413034cfb5f6SAlistair Francis         qemu_log_mask(LOG_UNIMP, "CSR_VSTVEC: reserved mode not supported\n");
4131605def6eSAlistair Francis     }
4132605def6eSAlistair Francis     return RISCV_EXCP_NONE;
413334cfb5f6SAlistair Francis }
413434cfb5f6SAlistair Francis 
read_vsscratch(CPURISCVState * env,int csrno,target_ulong * val)4135605def6eSAlistair Francis static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
413634cfb5f6SAlistair Francis                                      target_ulong *val)
413734cfb5f6SAlistair Francis {
4138605def6eSAlistair Francis     *val = env->vsscratch;
4139605def6eSAlistair Francis     return RISCV_EXCP_NONE;
414034cfb5f6SAlistair Francis }
414134cfb5f6SAlistair Francis 
write_vsscratch(CPURISCVState * env,int csrno,target_ulong val)4142605def6eSAlistair Francis static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
414334cfb5f6SAlistair Francis                                       target_ulong val)
414434cfb5f6SAlistair Francis {
4145605def6eSAlistair Francis     env->vsscratch = val;
4146605def6eSAlistair Francis     return RISCV_EXCP_NONE;
414734cfb5f6SAlistair Francis }
414834cfb5f6SAlistair Francis 
read_vsepc(CPURISCVState * env,int csrno,target_ulong * val)4149605def6eSAlistair Francis static RISCVException read_vsepc(CPURISCVState *env, int csrno,
415034cfb5f6SAlistair Francis                                  target_ulong *val)
415134cfb5f6SAlistair Francis {
4152c7b95171SMichael Clark     *val = env->vsepc;
41532582a95cSHou Weiying     return RISCV_EXCP_NONE;
41542582a95cSHou Weiying }
41552582a95cSHou Weiying 
write_vsepc(CPURISCVState * env,int csrno,target_ulong val)41562582a95cSHou Weiying static RISCVException write_vsepc(CPURISCVState *env, int csrno,
41572582a95cSHou Weiying                                   target_ulong val)
41582582a95cSHou Weiying {
41592582a95cSHou Weiying     env->vsepc = val;
41602582a95cSHou Weiying     return RISCV_EXCP_NONE;
41612582a95cSHou Weiying }
41622582a95cSHou Weiying 
read_vscause(CPURISCVState * env,int csrno,target_ulong * val)41632582a95cSHou Weiying static RISCVException read_vscause(CPURISCVState *env, int csrno,
41642582a95cSHou Weiying                                    target_ulong *val)
41652582a95cSHou Weiying {
41662582a95cSHou Weiying     *val = env->vscause;
4167605def6eSAlistair Francis     return RISCV_EXCP_NONE;
4168605def6eSAlistair Francis }
4169c7b95171SMichael Clark 
write_vscause(CPURISCVState * env,int csrno,target_ulong val)417079f26b3bSLIU Zhiwei static RISCVException write_vscause(CPURISCVState *env, int csrno,
417179f26b3bSLIU Zhiwei                                     target_ulong val)
417277ad639cSBin Meng {
4173605def6eSAlistair Francis     env->vscause = val;
4174c7b95171SMichael Clark     return RISCV_EXCP_NONE;
4175c7b95171SMichael Clark }
4176605def6eSAlistair Francis 
read_vstval(CPURISCVState * env,int csrno,target_ulong * val)4177605def6eSAlistair Francis static RISCVException read_vstval(CPURISCVState *env, int csrno,
4178c7b95171SMichael Clark                                   target_ulong *val)
417979f26b3bSLIU Zhiwei {
418079f26b3bSLIU Zhiwei     *val = env->vstval;
418177ad639cSBin Meng     return RISCV_EXCP_NONE;
4182605def6eSAlistair Francis }
4183c7b95171SMichael Clark 
write_vstval(CPURISCVState * env,int csrno,target_ulong val)4184c7b95171SMichael Clark static RISCVException write_vstval(CPURISCVState *env, int csrno,
4185605def6eSAlistair Francis                                    target_ulong val)
4186605def6eSAlistair Francis {
4187c7b95171SMichael Clark     env->vstval = val;
4188c7b95171SMichael Clark     return RISCV_EXCP_NONE;
4189605def6eSAlistair Francis }
4190c7b95171SMichael Clark 
read_vsatp(CPURISCVState * env,int csrno,target_ulong * val)4191c7b95171SMichael Clark static RISCVException read_vsatp(CPURISCVState *env, int csrno,
4192605def6eSAlistair Francis                                  target_ulong *val)
4193605def6eSAlistair Francis {
4194c7b95171SMichael Clark     *val = env->vsatp;
4195c7b95171SMichael Clark     return RISCV_EXCP_NONE;
4196605def6eSAlistair Francis }
4197c7b95171SMichael Clark 
write_vsatp(CPURISCVState * env,int csrno,target_ulong val)4198c7b95171SMichael Clark static RISCVException write_vsatp(CPURISCVState *env, int csrno,
4199b6092544SBin Meng                                   target_ulong val)
4200b6092544SBin Meng {
4201b6092544SBin Meng     env->vsatp = legalize_xatp(env, env->vsatp, val);
4202b6092544SBin Meng     return RISCV_EXCP_NONE;
4203b6092544SBin Meng }
4204b6092544SBin Meng 
read_mtval2(CPURISCVState * env,int csrno,target_ulong * val)4205b6092544SBin Meng static RISCVException read_mtval2(CPURISCVState *env, int csrno,
4206b6092544SBin Meng                                   target_ulong *val)
4207b6092544SBin Meng {
4208b6092544SBin Meng     *val = env->mtval2;
4209b6092544SBin Meng     return RISCV_EXCP_NONE;
4210b6092544SBin Meng }
4211b6092544SBin Meng 
write_mtval2(CPURISCVState * env,int csrno,target_ulong val)4212b6092544SBin Meng static RISCVException write_mtval2(CPURISCVState *env, int csrno,
4213b6092544SBin Meng                                    target_ulong val)
4214b6092544SBin Meng {
4215b6092544SBin Meng     env->mtval2 = val;
4216b6092544SBin Meng     return RISCV_EXCP_NONE;
4217a42bd001SFrank Chang }
4218b6092544SBin Meng 
read_mtinst(CPURISCVState * env,int csrno,target_ulong * val)4219b6092544SBin Meng static RISCVException read_mtinst(CPURISCVState *env, int csrno,
4220b6092544SBin Meng                                   target_ulong *val)
4221b6092544SBin Meng {
4222b6092544SBin Meng     *val = env->mtinst;
4223b6092544SBin Meng     return RISCV_EXCP_NONE;
4224b6092544SBin Meng }
4225b6092544SBin Meng 
write_mtinst(CPURISCVState * env,int csrno,target_ulong val)4226b6092544SBin Meng static RISCVException write_mtinst(CPURISCVState *env, int csrno,
4227b6092544SBin Meng                                    target_ulong val)
4228b6092544SBin Meng {
4229b6092544SBin Meng     env->mtinst = val;
4230b6092544SBin Meng     return RISCV_EXCP_NONE;
4231b6092544SBin Meng }
4232b6092544SBin Meng 
4233b6092544SBin Meng /* Physical Memory Protection */
read_mseccfg(CPURISCVState * env,int csrno,target_ulong * val)4234b6092544SBin Meng static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
4235b6092544SBin Meng                                    target_ulong *val)
4236b6092544SBin Meng {
4237b6092544SBin Meng     *val = mseccfg_csr_read(env);
4238b6092544SBin Meng     return RISCV_EXCP_NONE;
4239b6092544SBin Meng }
4240b6092544SBin Meng 
write_mseccfg(CPURISCVState * env,int csrno,target_ulong val)424131b9798dSFrank Chang static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
424231b9798dSFrank Chang                                     target_ulong val)
424331b9798dSFrank Chang {
424431b9798dSFrank Chang     mseccfg_csr_write(env, val);
424531b9798dSFrank Chang     return RISCV_EXCP_NONE;
424631b9798dSFrank Chang }
424731b9798dSFrank Chang 
read_pmpcfg(CPURISCVState * env,int csrno,target_ulong * val)42480c4e579aSAlvin Chang static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
42490c4e579aSAlvin Chang                                   target_ulong *val)
42500c4e579aSAlvin Chang {
42510c4e579aSAlvin Chang     uint32_t reg_index = csrno - CSR_PMPCFG0;
42520c4e579aSAlvin Chang 
42530c4e579aSAlvin Chang     *val = pmpcfg_csr_read(env, reg_index);
42540c4e579aSAlvin Chang     return RISCV_EXCP_NONE;
42550c4e579aSAlvin Chang }
42560c4e579aSAlvin Chang 
write_pmpcfg(CPURISCVState * env,int csrno,target_ulong val)42570c4e579aSAlvin Chang static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
42580c4e579aSAlvin Chang                                    target_ulong val)
42590c4e579aSAlvin Chang {
42600c4e579aSAlvin Chang     uint32_t reg_index = csrno - CSR_PMPCFG0;
42610c4e579aSAlvin Chang 
42620c4e579aSAlvin Chang     pmpcfg_csr_write(env, reg_index, val);
42630c4e579aSAlvin Chang     return RISCV_EXCP_NONE;
42640c4e579aSAlvin Chang }
42650c4e579aSAlvin Chang 
read_pmpaddr(CPURISCVState * env,int csrno,target_ulong * val)42660c4e579aSAlvin Chang static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
42670c4e579aSAlvin Chang                                    target_ulong *val)
42680c4e579aSAlvin Chang {
42690c4e579aSAlvin Chang     *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
42700c4e579aSAlvin Chang     return RISCV_EXCP_NONE;
42710c4e579aSAlvin Chang }
42720c4e579aSAlvin Chang 
write_pmpaddr(CPURISCVState * env,int csrno,target_ulong val)42734bbe8033SAlexey Baturo static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
42744bbe8033SAlexey Baturo                                     target_ulong val)
42754bbe8033SAlexey Baturo {
42764bbe8033SAlexey Baturo     pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
42774bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
42784bbe8033SAlexey Baturo }
42794bbe8033SAlexey Baturo 
read_tselect(CPURISCVState * env,int csrno,target_ulong * val)42804bbe8033SAlexey Baturo static RISCVException read_tselect(CPURISCVState *env, int csrno,
42814bbe8033SAlexey Baturo                                    target_ulong *val)
42824bbe8033SAlexey Baturo {
428347bdec82SLIU Zhiwei     *val = tselect_csr_read(env);
428447bdec82SLIU Zhiwei     return RISCV_EXCP_NONE;
428547bdec82SLIU Zhiwei }
42864bbe8033SAlexey Baturo 
write_tselect(CPURISCVState * env,int csrno,target_ulong val)42874bbe8033SAlexey Baturo static RISCVException write_tselect(CPURISCVState *env, int csrno,
42884bbe8033SAlexey Baturo                                     target_ulong val)
42894bbe8033SAlexey Baturo {
42904bbe8033SAlexey Baturo     tselect_csr_write(env, val);
42914bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
42924bbe8033SAlexey Baturo }
42934bbe8033SAlexey Baturo 
read_tdata(CPURISCVState * env,int csrno,target_ulong * val)42944bbe8033SAlexey Baturo static RISCVException read_tdata(CPURISCVState *env, int csrno,
42954bbe8033SAlexey Baturo                                  target_ulong *val)
42964bbe8033SAlexey Baturo {
42974bbe8033SAlexey Baturo     /* return 0 in tdata1 to end the trigger enumeration */
42984bbe8033SAlexey Baturo     if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
42994bbe8033SAlexey Baturo         *val = 0;
43004bbe8033SAlexey Baturo         return RISCV_EXCP_NONE;
43014bbe8033SAlexey Baturo     }
43024bbe8033SAlexey Baturo 
43034bbe8033SAlexey Baturo     if (!tdata_available(env, csrno - CSR_TDATA1)) {
43044bbe8033SAlexey Baturo         return RISCV_EXCP_ILLEGAL_INST;
43054bbe8033SAlexey Baturo     }
43064bbe8033SAlexey Baturo 
43074bbe8033SAlexey Baturo     *val = tdata_csr_read(env, csrno - CSR_TDATA1);
43084bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
43094bbe8033SAlexey Baturo }
43104bbe8033SAlexey Baturo 
write_tdata(CPURISCVState * env,int csrno,target_ulong val)43114bbe8033SAlexey Baturo static RISCVException write_tdata(CPURISCVState *env, int csrno,
43124bbe8033SAlexey Baturo                                   target_ulong val)
43134bbe8033SAlexey Baturo {
43144bbe8033SAlexey Baturo     if (!tdata_available(env, csrno - CSR_TDATA1)) {
43154bbe8033SAlexey Baturo         return RISCV_EXCP_ILLEGAL_INST;
43164bbe8033SAlexey Baturo     }
43174bbe8033SAlexey Baturo 
43184bbe8033SAlexey Baturo     tdata_csr_write(env, csrno - CSR_TDATA1, val);
43194bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
43204bbe8033SAlexey Baturo }
43214bbe8033SAlexey Baturo 
read_tinfo(CPURISCVState * env,int csrno,target_ulong * val)43224bbe8033SAlexey Baturo static RISCVException read_tinfo(CPURISCVState *env, int csrno,
43234bbe8033SAlexey Baturo                                  target_ulong *val)
4324246f8796SWeiwei Li {
4325246f8796SWeiwei Li     *val = tinfo_csr_read(env);
4326246f8796SWeiwei Li     return RISCV_EXCP_NONE;
43274bbe8033SAlexey Baturo }
43284bbe8033SAlexey Baturo 
read_mcontext(CPURISCVState * env,int csrno,target_ulong * val)43294bbe8033SAlexey Baturo static RISCVException read_mcontext(CPURISCVState *env, int csrno,
43304bbe8033SAlexey Baturo                                     target_ulong *val)
43314bbe8033SAlexey Baturo {
43324bbe8033SAlexey Baturo     *val = env->mcontext;
433342967f40SLIU Zhiwei     return RISCV_EXCP_NONE;
433440bfa5f6SLIU Zhiwei }
43354bbe8033SAlexey Baturo 
write_mcontext(CPURISCVState * env,int csrno,target_ulong val)43364bbe8033SAlexey Baturo static RISCVException write_mcontext(CPURISCVState *env, int csrno,
43374bbe8033SAlexey Baturo                                      target_ulong val)
43384bbe8033SAlexey Baturo {
43394bbe8033SAlexey Baturo     bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
43404bbe8033SAlexey Baturo     int32_t mask;
43414bbe8033SAlexey Baturo 
43424bbe8033SAlexey Baturo     if (riscv_has_ext(env, RVH)) {
43434bbe8033SAlexey Baturo         /* Spec suggest 7-bit for RV32 and 14-bit for RV64 w/ H extension */
43444bbe8033SAlexey Baturo         mask = rv32 ? MCONTEXT32_HCONTEXT : MCONTEXT64_HCONTEXT;
43454bbe8033SAlexey Baturo     } else {
43464bbe8033SAlexey Baturo         /* Spec suggest 6-bit for RV32 and 13-bit for RV64 w/o H extension */
43474bbe8033SAlexey Baturo         mask = rv32 ? MCONTEXT32 : MCONTEXT64;
43484bbe8033SAlexey Baturo     }
43494bbe8033SAlexey Baturo 
43504bbe8033SAlexey Baturo     env->mcontext = val & mask;
43514bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
43524bbe8033SAlexey Baturo }
43534bbe8033SAlexey Baturo 
43544bbe8033SAlexey Baturo /*
4355246f8796SWeiwei Li  * Functions to access Pointer Masking feature registers
4356246f8796SWeiwei Li  * We have to check if current priv lvl could modify
4357246f8796SWeiwei Li  * csr in given mode
43584bbe8033SAlexey Baturo  */
check_pm_current_disabled(CPURISCVState * env,int csrno)43594bbe8033SAlexey Baturo static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
43604bbe8033SAlexey Baturo {
43614bbe8033SAlexey Baturo     int csr_priv = get_field(csrno, 0x300);
43624bbe8033SAlexey Baturo     int pm_current;
43634bbe8033SAlexey Baturo 
43644bbe8033SAlexey Baturo     if (env->debugger) {
43654bbe8033SAlexey Baturo         return false;
43664bbe8033SAlexey Baturo     }
43674bbe8033SAlexey Baturo     /*
43684bbe8033SAlexey Baturo      * If priv lvls differ that means we're accessing csr from higher priv lvl,
43694bbe8033SAlexey Baturo      * so allow the access
43704bbe8033SAlexey Baturo      */
43714bbe8033SAlexey Baturo     if (env->priv != csr_priv) {
43724bbe8033SAlexey Baturo         return false;
43734bbe8033SAlexey Baturo     }
43744bbe8033SAlexey Baturo     switch (env->priv) {
43754bbe8033SAlexey Baturo     case PRV_M:
43764bbe8033SAlexey Baturo         pm_current = get_field(env->mmte, M_PM_CURRENT);
43774bbe8033SAlexey Baturo         break;
43784bbe8033SAlexey Baturo     case PRV_S:
43794bbe8033SAlexey Baturo         pm_current = get_field(env->mmte, S_PM_CURRENT);
43804bbe8033SAlexey Baturo         break;
43814bbe8033SAlexey Baturo     case PRV_U:
43824bbe8033SAlexey Baturo         pm_current = get_field(env->mmte, U_PM_CURRENT);
4383246f8796SWeiwei Li         break;
4384246f8796SWeiwei Li     default:
4385246f8796SWeiwei Li         g_assert_not_reached();
43864bbe8033SAlexey Baturo     }
43874bbe8033SAlexey Baturo     /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
43884bbe8033SAlexey Baturo     return !pm_current;
43894bbe8033SAlexey Baturo }
43904bbe8033SAlexey Baturo 
read_mmte(CPURISCVState * env,int csrno,target_ulong * val)43914bbe8033SAlexey Baturo static RISCVException read_mmte(CPURISCVState *env, int csrno,
43924bbe8033SAlexey Baturo                                 target_ulong *val)
43934bbe8033SAlexey Baturo {
43944bbe8033SAlexey Baturo     *val = env->mmte & MMTE_MASK;
43954bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
43964bbe8033SAlexey Baturo }
43974bbe8033SAlexey Baturo 
write_mmte(CPURISCVState * env,int csrno,target_ulong val)43984bbe8033SAlexey Baturo static RISCVException write_mmte(CPURISCVState *env, int csrno,
43994bbe8033SAlexey Baturo                                  target_ulong val)
44004bbe8033SAlexey Baturo {
44014bbe8033SAlexey Baturo     uint64_t mstatus;
44024bbe8033SAlexey Baturo     target_ulong wpri_val = val & MMTE_MASK;
44034bbe8033SAlexey Baturo 
44044bbe8033SAlexey Baturo     if (val != wpri_val) {
44054bbe8033SAlexey Baturo         qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
44064bbe8033SAlexey Baturo                       TARGET_FMT_lx "\n", "MMTE: WPRI violation written 0x",
44074bbe8033SAlexey Baturo                       val, "vs expected 0x", wpri_val);
44084bbe8033SAlexey Baturo     }
44094bbe8033SAlexey Baturo     /* for machine mode pm.current is hardwired to 1 */
4410ef1ba32aSWeiwei Li     wpri_val |= MMTE_M_PM_CURRENT;
441140bfa5f6SLIU Zhiwei 
441240bfa5f6SLIU Zhiwei     /* hardwiring pm.instruction bit to 0, since it's not supported yet */
441342967f40SLIU Zhiwei     wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
44144bbe8033SAlexey Baturo     env->mmte = wpri_val | EXT_STATUS_DIRTY;
44154bbe8033SAlexey Baturo     riscv_cpu_update_mask(env);
44164bbe8033SAlexey Baturo 
44174bbe8033SAlexey Baturo     /* Set XS and SD bits, since PM CSRs are dirty */
44184bbe8033SAlexey Baturo     mstatus = env->mstatus | MSTATUS_XS;
44194bbe8033SAlexey Baturo     write_mstatus(env, csrno, mstatus);
44204bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
44214bbe8033SAlexey Baturo }
44224bbe8033SAlexey Baturo 
read_smte(CPURISCVState * env,int csrno,target_ulong * val)44234bbe8033SAlexey Baturo static RISCVException read_smte(CPURISCVState *env, int csrno,
44244bbe8033SAlexey Baturo                                 target_ulong *val)
44254bbe8033SAlexey Baturo {
44264bbe8033SAlexey Baturo     *val = env->mmte & SMTE_MASK;
44274bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
44284bbe8033SAlexey Baturo }
44294bbe8033SAlexey Baturo 
write_smte(CPURISCVState * env,int csrno,target_ulong val)44304bbe8033SAlexey Baturo static RISCVException write_smte(CPURISCVState *env, int csrno,
44314bbe8033SAlexey Baturo                                  target_ulong val)
44324bbe8033SAlexey Baturo {
44334bbe8033SAlexey Baturo     target_ulong wpri_val = val & SMTE_MASK;
44344bbe8033SAlexey Baturo 
44354bbe8033SAlexey Baturo     if (val != wpri_val) {
44364bbe8033SAlexey Baturo         qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
44374bbe8033SAlexey Baturo                       TARGET_FMT_lx "\n", "SMTE: WPRI violation written 0x",
4438ef1ba32aSWeiwei Li                       val, "vs expected 0x", wpri_val);
443940bfa5f6SLIU Zhiwei     }
4440ef1ba32aSWeiwei Li 
4441ef1ba32aSWeiwei Li     /* if pm.current==0 we can't modify current PM CSRs */
4442ef1ba32aSWeiwei Li     if (check_pm_current_disabled(env, csrno)) {
444340bfa5f6SLIU Zhiwei         return RISCV_EXCP_NONE;
444442967f40SLIU Zhiwei     }
44454bbe8033SAlexey Baturo 
44464bbe8033SAlexey Baturo     wpri_val |= (env->mmte & ~SMTE_MASK);
44474bbe8033SAlexey Baturo     write_mmte(env, csrno, wpri_val);
44484bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
44494bbe8033SAlexey Baturo }
44504bbe8033SAlexey Baturo 
read_umte(CPURISCVState * env,int csrno,target_ulong * val)44514bbe8033SAlexey Baturo static RISCVException read_umte(CPURISCVState *env, int csrno,
44524bbe8033SAlexey Baturo                                 target_ulong *val)
44534bbe8033SAlexey Baturo {
44544bbe8033SAlexey Baturo     *val = env->mmte & UMTE_MASK;
44554bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
44564bbe8033SAlexey Baturo }
44574bbe8033SAlexey Baturo 
write_umte(CPURISCVState * env,int csrno,target_ulong val)44584bbe8033SAlexey Baturo static RISCVException write_umte(CPURISCVState *env, int csrno,
44594bbe8033SAlexey Baturo                                  target_ulong val)
44604bbe8033SAlexey Baturo {
44614bbe8033SAlexey Baturo     target_ulong wpri_val = val & UMTE_MASK;
44624bbe8033SAlexey Baturo 
44634bbe8033SAlexey Baturo     if (val != wpri_val) {
44644bbe8033SAlexey Baturo         qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
44654bbe8033SAlexey Baturo                       TARGET_FMT_lx "\n", "UMTE: WPRI violation written 0x",
44664bbe8033SAlexey Baturo                       val, "vs expected 0x", wpri_val);
44674bbe8033SAlexey Baturo     }
44684bbe8033SAlexey Baturo 
4469ef1ba32aSWeiwei Li     if (check_pm_current_disabled(env, csrno)) {
447040bfa5f6SLIU Zhiwei         return RISCV_EXCP_NONE;
4471ef1ba32aSWeiwei Li     }
4472ef1ba32aSWeiwei Li 
4473ef1ba32aSWeiwei Li     wpri_val |= (env->mmte & ~UMTE_MASK);
447440bfa5f6SLIU Zhiwei     write_mmte(env, csrno, wpri_val);
447542967f40SLIU Zhiwei     return RISCV_EXCP_NONE;
44764bbe8033SAlexey Baturo }
44774bbe8033SAlexey Baturo 
read_mpmmask(CPURISCVState * env,int csrno,target_ulong * val)44784bbe8033SAlexey Baturo static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
44794bbe8033SAlexey Baturo                                    target_ulong *val)
44804bbe8033SAlexey Baturo {
44814bbe8033SAlexey Baturo     *val = env->mpmmask;
44824bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
44834bbe8033SAlexey Baturo }
44844bbe8033SAlexey Baturo 
write_mpmmask(CPURISCVState * env,int csrno,target_ulong val)44854bbe8033SAlexey Baturo static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
44864bbe8033SAlexey Baturo                                     target_ulong val)
44874bbe8033SAlexey Baturo {
44884bbe8033SAlexey Baturo     uint64_t mstatus;
44894bbe8033SAlexey Baturo 
44904bbe8033SAlexey Baturo     env->mpmmask = val;
44914bbe8033SAlexey Baturo     if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
44924bbe8033SAlexey Baturo         env->cur_pmmask = val;
44934bbe8033SAlexey Baturo     }
44944bbe8033SAlexey Baturo     env->mmte |= EXT_STATUS_DIRTY;
44954bbe8033SAlexey Baturo 
4496ef1ba32aSWeiwei Li     /* Set XS and SD bits, since PM CSRs are dirty */
449740bfa5f6SLIU Zhiwei     mstatus = env->mstatus | MSTATUS_XS;
449840bfa5f6SLIU Zhiwei     write_mstatus(env, csrno, mstatus);
449942967f40SLIU Zhiwei     return RISCV_EXCP_NONE;
45004bbe8033SAlexey Baturo }
45014bbe8033SAlexey Baturo 
read_spmmask(CPURISCVState * env,int csrno,target_ulong * val)45024bbe8033SAlexey Baturo static RISCVException read_spmmask(CPURISCVState *env, int csrno,
45034bbe8033SAlexey Baturo                                    target_ulong *val)
45044bbe8033SAlexey Baturo {
45054bbe8033SAlexey Baturo     *val = env->spmmask;
45064bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
45074bbe8033SAlexey Baturo }
45084bbe8033SAlexey Baturo 
write_spmmask(CPURISCVState * env,int csrno,target_ulong val)45094bbe8033SAlexey Baturo static RISCVException write_spmmask(CPURISCVState *env, int csrno,
45104bbe8033SAlexey Baturo                                     target_ulong val)
45114bbe8033SAlexey Baturo {
45124bbe8033SAlexey Baturo     uint64_t mstatus;
45134bbe8033SAlexey Baturo 
45144bbe8033SAlexey Baturo     /* if pm.current==0 we can't modify current PM CSRs */
45154bbe8033SAlexey Baturo     if (check_pm_current_disabled(env, csrno)) {
45164bbe8033SAlexey Baturo         return RISCV_EXCP_NONE;
45174bbe8033SAlexey Baturo     }
45184bbe8033SAlexey Baturo     env->spmmask = val;
45194bbe8033SAlexey Baturo     if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
45204bbe8033SAlexey Baturo         env->cur_pmmask = val;
45214bbe8033SAlexey Baturo         if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
45224bbe8033SAlexey Baturo             env->cur_pmmask &= UINT32_MAX;
45234bbe8033SAlexey Baturo         }
4524ef1ba32aSWeiwei Li     }
452540bfa5f6SLIU Zhiwei     env->mmte |= EXT_STATUS_DIRTY;
4526ef1ba32aSWeiwei Li 
4527ef1ba32aSWeiwei Li     /* Set XS and SD bits, since PM CSRs are dirty */
4528ef1ba32aSWeiwei Li     mstatus = env->mstatus | MSTATUS_XS;
452940bfa5f6SLIU Zhiwei     write_mstatus(env, csrno, mstatus);
453042967f40SLIU Zhiwei     return RISCV_EXCP_NONE;
45314bbe8033SAlexey Baturo }
45324bbe8033SAlexey Baturo 
read_upmmask(CPURISCVState * env,int csrno,target_ulong * val)45334bbe8033SAlexey Baturo static RISCVException read_upmmask(CPURISCVState *env, int csrno,
45344bbe8033SAlexey Baturo                                    target_ulong *val)
45354bbe8033SAlexey Baturo {
45364bbe8033SAlexey Baturo     *val = env->upmmask;
45374bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
45384bbe8033SAlexey Baturo }
45394bbe8033SAlexey Baturo 
write_upmmask(CPURISCVState * env,int csrno,target_ulong val)45404bbe8033SAlexey Baturo static RISCVException write_upmmask(CPURISCVState *env, int csrno,
45414bbe8033SAlexey Baturo                                     target_ulong val)
45424bbe8033SAlexey Baturo {
45434bbe8033SAlexey Baturo     uint64_t mstatus;
45444bbe8033SAlexey Baturo 
45454bbe8033SAlexey Baturo     /* if pm.current==0 we can't modify current PM CSRs */
45464bbe8033SAlexey Baturo     if (check_pm_current_disabled(env, csrno)) {
45474bbe8033SAlexey Baturo         return RISCV_EXCP_NONE;
45484bbe8033SAlexey Baturo     }
45494bbe8033SAlexey Baturo     env->upmmask = val;
45504bbe8033SAlexey Baturo     if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
45514bbe8033SAlexey Baturo         env->cur_pmmask = val;
45524bbe8033SAlexey Baturo         if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
45534bbe8033SAlexey Baturo             env->cur_pmmask &= UINT32_MAX;
45544bbe8033SAlexey Baturo         }
4555ef1ba32aSWeiwei Li     }
455640bfa5f6SLIU Zhiwei     env->mmte |= EXT_STATUS_DIRTY;
4557ef1ba32aSWeiwei Li 
4558ef1ba32aSWeiwei Li     /* Set XS and SD bits, since PM CSRs are dirty */
4559ef1ba32aSWeiwei Li     mstatus = env->mstatus | MSTATUS_XS;
456040bfa5f6SLIU Zhiwei     write_mstatus(env, csrno, mstatus);
456142967f40SLIU Zhiwei     return RISCV_EXCP_NONE;
45624bbe8033SAlexey Baturo }
45634bbe8033SAlexey Baturo 
read_mpmbase(CPURISCVState * env,int csrno,target_ulong * val)45644bbe8033SAlexey Baturo static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
45654bbe8033SAlexey Baturo                                    target_ulong *val)
45664bbe8033SAlexey Baturo {
45674bbe8033SAlexey Baturo     *val = env->mpmbase;
45684bbe8033SAlexey Baturo     return RISCV_EXCP_NONE;
4569c7b95171SMichael Clark }
4570c7b95171SMichael Clark 
write_mpmbase(CPURISCVState * env,int csrno,target_ulong val)457177442380SWeiwei Li static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
457286997772SAndrew Jones                                     target_ulong val)
457377442380SWeiwei Li {
457477442380SWeiwei Li     uint64_t mstatus;
457577442380SWeiwei Li 
457677442380SWeiwei Li     env->mpmbase = val;
457777442380SWeiwei Li     if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
457877442380SWeiwei Li         env->cur_pmbase = val;
457977442380SWeiwei Li     }
458077442380SWeiwei Li     env->mmte |= EXT_STATUS_DIRTY;
458177442380SWeiwei Li 
458277442380SWeiwei Li     /* Set XS and SD bits, since PM CSRs are dirty */
458377442380SWeiwei Li     mstatus = env->mstatus | MSTATUS_XS;
458477442380SWeiwei Li     write_mstatus(env, csrno, mstatus);
458577442380SWeiwei Li     return RISCV_EXCP_NONE;
458677442380SWeiwei Li }
458777442380SWeiwei Li 
read_spmbase(CPURISCVState * env,int csrno,target_ulong * val)458877442380SWeiwei Li static RISCVException read_spmbase(CPURISCVState *env, int csrno,
458977442380SWeiwei Li                                    target_ulong *val)
459077442380SWeiwei Li {
459177442380SWeiwei Li     *val = env->spmbase;
459277442380SWeiwei Li     return RISCV_EXCP_NONE;
459377442380SWeiwei Li }
459477442380SWeiwei Li 
write_spmbase(CPURISCVState * env,int csrno,target_ulong val)459577442380SWeiwei Li static RISCVException write_spmbase(CPURISCVState *env, int csrno,
459677442380SWeiwei Li                                     target_ulong val)
459786997772SAndrew Jones {
459886997772SAndrew Jones     uint64_t mstatus;
459986997772SAndrew Jones 
460086997772SAndrew Jones     /* if pm.current==0 we can't modify current PM CSRs */
460186997772SAndrew Jones     if (check_pm_current_disabled(env, csrno)) {
460286997772SAndrew Jones         return RISCV_EXCP_NONE;
460386997772SAndrew Jones     }
460486997772SAndrew Jones     env->spmbase = val;
460586997772SAndrew Jones     if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
460686997772SAndrew Jones         env->cur_pmbase = val;
460786997772SAndrew Jones         if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
460886997772SAndrew Jones             env->cur_pmbase &= UINT32_MAX;
460977442380SWeiwei Li         }
461077442380SWeiwei Li     }
461177442380SWeiwei Li     env->mmte |= EXT_STATUS_DIRTY;
461277442380SWeiwei Li 
461377442380SWeiwei Li     /* Set XS and SD bits, since PM CSRs are dirty */
461477442380SWeiwei Li     mstatus = env->mstatus | MSTATUS_XS;
461577442380SWeiwei Li     write_mstatus(env, csrno, mstatus);
4616c7b95171SMichael Clark     return RISCV_EXCP_NONE;
4617c7b95171SMichael Clark }
4618c7b95171SMichael Clark 
read_upmbase(CPURISCVState * env,int csrno,target_ulong * val)4619c7b95171SMichael Clark static RISCVException read_upmbase(CPURISCVState *env, int csrno,
4620c7b95171SMichael Clark                                    target_ulong *val)
4621c7b95171SMichael Clark {
4622c7b95171SMichael Clark     *val = env->upmbase;
4623c7b95171SMichael Clark     return RISCV_EXCP_NONE;
4624c7b95171SMichael Clark }
4625457c360fSFrédéric Pétrot 
write_upmbase(CPURISCVState * env,int csrno,target_ulong val)4626457c360fSFrédéric Pétrot static RISCVException write_upmbase(CPURISCVState *env, int csrno,
462738c83e8dSYu-Ming Chang                                     target_ulong val)
4628c7b95171SMichael Clark {
462965e728a2SBin Meng     uint64_t mstatus;
4630a7e407b3SBin Meng 
46317100fe6cSAtish Patra     /* if pm.current==0 we can't modify current PM CSRs */
4632eacaf440SWeiwei Li     if (check_pm_current_disabled(env, csrno)) {
4633a5e0f686SBin Meng         return RISCV_EXCP_NONE;
4634960b389bSDaniel Henrique Barboza     }
4635eacaf440SWeiwei Li     env->upmbase = val;
4636eacaf440SWeiwei Li     if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
4637eacaf440SWeiwei Li         env->cur_pmbase = val;
4638eae04c4cSBin Meng         if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
4639eae04c4cSBin Meng             env->cur_pmbase &= UINT32_MAX;
4640eae04c4cSBin Meng         }
4641eae04c4cSBin Meng     }
4642eae04c4cSBin Meng     env->mmte |= EXT_STATUS_DIRTY;
4643a5e0f686SBin Meng 
4644eacaf440SWeiwei Li     /* Set XS and SD bits, since PM CSRs are dirty */
4645eacaf440SWeiwei Li     mstatus = env->mstatus | MSTATUS_XS;
4646eacaf440SWeiwei Li     write_mstatus(env, csrno, mstatus);
4647eacaf440SWeiwei Li     return RISCV_EXCP_NONE;
4648a5e0f686SBin Meng }
464938c83e8dSYu-Ming Chang 
4650eacaf440SWeiwei Li #endif
4651eacaf440SWeiwei Li 
4652eacaf440SWeiwei Li /* Crypto Extension */
riscv_new_csr_seed(target_ulong new_value,target_ulong write_mask)4653a5e0f686SBin Meng target_ulong riscv_new_csr_seed(target_ulong new_value,
4654a5e0f686SBin Meng                                 target_ulong write_mask)
4655a5e0f686SBin Meng {
4656a5e0f686SBin Meng     uint16_t random_v;
4657a5e0f686SBin Meng     Error *random_e = NULL;
4658a5e0f686SBin Meng     int random_r;
4659a5e0f686SBin Meng     target_ulong rval;
4660eacaf440SWeiwei Li 
4661eacaf440SWeiwei Li     random_r = qemu_guest_getrandom(&random_v, 2, &random_e);
4662eacaf440SWeiwei Li     if (unlikely(random_r < 0)) {
4663eacaf440SWeiwei Li         /*
4664eacaf440SWeiwei Li          * Failed, for unknown reasons in the crypto subsystem.
4665c7b95171SMichael Clark          * The best we can do is log the reason and return a
4666c1fbcecbSAnup Patel          * failure indication to the guest.  There is no reason
46670a42f4c4SAlistair Francis          * we know to expect the failure to be transitory, so
46685de12453SWeiwei Li          * indicate DEAD to avoid having the guest spin on WAIT.
466938256529SWeiwei Li          */
46700a42f4c4SAlistair Francis         qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
467142fe7499SMichael Tokarev                       __func__, error_get_pretty(random_e));
46725de12453SWeiwei Li         error_free(random_e);
46730a42f4c4SAlistair Francis         rval = SEED_OPST_DEAD;
46740a42f4c4SAlistair Francis     } else {
4675e6e03dcfSBin Meng         rval = random_v | SEED_OPST_ES16;
46760a42f4c4SAlistair Francis     }
4677c1fbcecbSAnup Patel 
4678c1fbcecbSAnup Patel     return rval;
467938256529SWeiwei Li }
4680c1fbcecbSAnup Patel 
rmw_seed(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)4681c1fbcecbSAnup Patel static RISCVException rmw_seed(CPURISCVState *env, int csrno,
4682533c91e8SAlistair Francis                                target_ulong *ret_value,
4683c7b95171SMichael Clark                                target_ulong new_value,
4684c7b95171SMichael Clark                                target_ulong write_mask)
4685eacaf440SWeiwei Li {
4686e39a8320SAlistair Francis     target_ulong rval;
4687a88365c1SMichael Clark 
4688457c360fSFrédéric Pétrot     rval = riscv_new_csr_seed(new_value, write_mask);
4689457c360fSFrédéric Pétrot 
4690457c360fSFrédéric Pétrot     if (ret_value) {
4691457c360fSFrédéric Pétrot         *ret_value = rval;
4692457c360fSFrédéric Pétrot     }
4693457c360fSFrédéric Pétrot 
4694e7a03409SNikita Shubin     return RISCV_EXCP_NONE;
4695457c360fSFrédéric Pétrot }
4696c7b95171SMichael Clark 
4697c7b95171SMichael Clark /*
4698533c91e8SAlistair Francis  * riscv_csrrw - read and/or update control and status register
4699c7b95171SMichael Clark  *
4700c7b95171SMichael Clark  * csrr   <->  riscv_csrrw(env, csrno, ret_value, 0, 0);
4701e7a03409SNikita Shubin  * csrrw  <->  riscv_csrrw(env, csrno, ret_value, value, -1);
4702e7a03409SNikita Shubin  * csrrs  <->  riscv_csrrw(env, csrno, ret_value, -1, value);
4703e7a03409SNikita Shubin  * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
4704e7a03409SNikita Shubin  */
4705e7a03409SNikita Shubin 
riscv_csrrw_check(CPURISCVState * env,int csrno,bool write)4706c7b95171SMichael Clark static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
4707c7b95171SMichael Clark                                                int csrno,
4708533c91e8SAlistair Francis                                                bool write)
4709c7b95171SMichael Clark {
4710c7b95171SMichael Clark     /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
4711c7b95171SMichael Clark     bool read_only = get_field(csrno, 0xC00) == 3;
4712605def6eSAlistair Francis     int csr_min_priv = csr_ops[csrno].min_priv_ver;
4713533c91e8SAlistair Francis 
4714c7b95171SMichael Clark     /* ensure the CSR extension is enabled */
4715e7a03409SNikita Shubin     if (!riscv_cpu_cfg(env)->ext_zicsr) {
4716c7b95171SMichael Clark         return RISCV_EXCP_ILLEGAL_INST;
4717c7b95171SMichael Clark     }
4718c7b95171SMichael Clark 
4719c7b95171SMichael Clark     /* ensure CSR is implemented by checking predicate */
4720c7b95171SMichael Clark     if (!csr_ops[csrno].predicate) {
4721c7b95171SMichael Clark         return RISCV_EXCP_ILLEGAL_INST;
4722605def6eSAlistair Francis     }
4723533c91e8SAlistair Francis 
4724c7b95171SMichael Clark     /* privileged spec version check */
4725c7b95171SMichael Clark     if (env->priv_ver < csr_min_priv) {
4726c7b95171SMichael Clark         return RISCV_EXCP_ILLEGAL_INST;
4727c7b95171SMichael Clark     }
4728c7b95171SMichael Clark 
4729c7b95171SMichael Clark     /* read / write check */
4730c7b95171SMichael Clark     if (write && read_only) {
4731c7b95171SMichael Clark         return RISCV_EXCP_ILLEGAL_INST;
4732c7b95171SMichael Clark     }
4733533c91e8SAlistair Francis 
4734c7b95171SMichael Clark     /*
4735c7b95171SMichael Clark      * The predicate() not only does existence check but also does some
473638c83e8dSYu-Ming Chang      * access control check which triggers for example virtual instruction
473738c83e8dSYu-Ming Chang      * exception in some cases. When writing read-only CSRs in those cases
473838c83e8dSYu-Ming Chang      * illegal instruction exception should be triggered instead of virtual
473938c83e8dSYu-Ming Chang      * instruction exception. Hence this comes after the read / write check.
474038c83e8dSYu-Ming Chang      */
474138c83e8dSYu-Ming Chang     RISCVException ret = csr_ops[csrno].predicate(env, csrno);
474238c83e8dSYu-Ming Chang     if (ret != RISCV_EXCP_NONE) {
474338c83e8dSYu-Ming Chang         return ret;
474438c83e8dSYu-Ming Chang     }
474538c83e8dSYu-Ming Chang 
474638c83e8dSYu-Ming Chang #if !defined(CONFIG_USER_ONLY)
4747457c360fSFrédéric Pétrot     int csr_priv, effective_priv = env->priv;
4748457c360fSFrédéric Pétrot 
4749457c360fSFrédéric Pétrot     if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
4750457c360fSFrédéric Pétrot         !env->virt_enabled) {
475138c83e8dSYu-Ming Chang         /*
4752457c360fSFrédéric Pétrot          * We are in HS mode. Add 1 to the effective privilege level to
4753457c360fSFrédéric Pétrot          * allow us to access the Hypervisor CSRs.
4754457c360fSFrédéric Pétrot          */
4755457c360fSFrédéric Pétrot         effective_priv++;
4756457c360fSFrédéric Pétrot     }
4757457c360fSFrédéric Pétrot 
4758457c360fSFrédéric Pétrot     csr_priv = get_field(csrno, 0x300);
4759457c360fSFrédéric Pétrot     if (!env->debugger && (effective_priv < csr_priv)) {
4760457c360fSFrédéric Pétrot         if (csr_priv == (PRV_S + 1) && env->virt_enabled) {
4761457c360fSFrédéric Pétrot             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
4762457c360fSFrédéric Pétrot         }
4763457c360fSFrédéric Pétrot         return RISCV_EXCP_ILLEGAL_INST;
4764457c360fSFrédéric Pétrot     }
4765457c360fSFrédéric Pétrot #endif
4766457c360fSFrédéric Pétrot     return RISCV_EXCP_NONE;
4767457c360fSFrédéric Pétrot }
4768457c360fSFrédéric Pétrot 
riscv_csrrw_do64(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)4769457c360fSFrédéric Pétrot static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
4770457c360fSFrédéric Pétrot                                        target_ulong *ret_value,
4771457c360fSFrédéric Pétrot                                        target_ulong new_value,
4772457c360fSFrédéric Pétrot                                        target_ulong write_mask)
4773457c360fSFrédéric Pétrot {
4774457c360fSFrédéric Pétrot     RISCVException ret;
4775457c360fSFrédéric Pétrot     target_ulong old_value = 0;
4776457c360fSFrédéric Pétrot 
4777457c360fSFrédéric Pétrot     /* execute combined read/write operation if it exists */
4778457c360fSFrédéric Pétrot     if (csr_ops[csrno].op) {
4779457c360fSFrédéric Pétrot         return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
4780457c360fSFrédéric Pétrot     }
4781457c360fSFrédéric Pétrot 
4782457c360fSFrédéric Pétrot     /*
4783457c360fSFrédéric Pétrot      * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
4784457c360fSFrédéric Pétrot      * and we can't throw side effects caused by CSR reads.
4785457c360fSFrédéric Pétrot      */
4786457c360fSFrédéric Pétrot     if (ret_value) {
4787457c360fSFrédéric Pétrot         /* if no accessor exists then return failure */
4788457c360fSFrédéric Pétrot         if (!csr_ops[csrno].read) {
4789457c360fSFrédéric Pétrot             return RISCV_EXCP_ILLEGAL_INST;
4790457c360fSFrédéric Pétrot         }
4791457c360fSFrédéric Pétrot         /* read old value */
4792457c360fSFrédéric Pétrot         ret = csr_ops[csrno].read(env, csrno, &old_value);
4793457c360fSFrédéric Pétrot         if (ret != RISCV_EXCP_NONE) {
4794457c360fSFrédéric Pétrot             return ret;
4795457c360fSFrédéric Pétrot         }
4796457c360fSFrédéric Pétrot     }
4797457c360fSFrédéric Pétrot 
4798457c360fSFrédéric Pétrot     /* write value if writable and write mask set, otherwise drop writes */
479938c83e8dSYu-Ming Chang     if (write_mask) {
480038c83e8dSYu-Ming Chang         new_value = (old_value & ~write_mask) | (new_value & write_mask);
480138c83e8dSYu-Ming Chang         if (csr_ops[csrno].write) {
480238c83e8dSYu-Ming Chang             ret = csr_ops[csrno].write(env, csrno, new_value);
480338c83e8dSYu-Ming Chang             if (ret != RISCV_EXCP_NONE) {
480438c83e8dSYu-Ming Chang                 return ret;
480538c83e8dSYu-Ming Chang             }
480638c83e8dSYu-Ming Chang         }
480738c83e8dSYu-Ming Chang     }
480838c83e8dSYu-Ming Chang 
480938c83e8dSYu-Ming Chang     /* return old value */
481038c83e8dSYu-Ming Chang     if (ret_value) {
481138c83e8dSYu-Ming Chang         *ret_value = old_value;
481238c83e8dSYu-Ming Chang     }
481338c83e8dSYu-Ming Chang 
481438c83e8dSYu-Ming Chang     return RISCV_EXCP_NONE;
481538c83e8dSYu-Ming Chang }
481638c83e8dSYu-Ming Chang 
riscv_csrr(CPURISCVState * env,int csrno,target_ulong * ret_value)481738c83e8dSYu-Ming Chang RISCVException riscv_csrr(CPURISCVState *env, int csrno,
481838c83e8dSYu-Ming Chang                            target_ulong *ret_value)
481938c83e8dSYu-Ming Chang {
482038c83e8dSYu-Ming Chang     RISCVException ret = riscv_csrrw_check(env, csrno, false);
482138c83e8dSYu-Ming Chang     if (ret != RISCV_EXCP_NONE) {
482238c83e8dSYu-Ming Chang         return ret;
482338c83e8dSYu-Ming Chang     }
482438c83e8dSYu-Ming Chang 
482538c83e8dSYu-Ming Chang     return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
482638c83e8dSYu-Ming Chang }
482738c83e8dSYu-Ming Chang 
riscv_csrrw(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)482838c83e8dSYu-Ming Chang RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
482938c83e8dSYu-Ming Chang                            target_ulong *ret_value,
483038c83e8dSYu-Ming Chang                            target_ulong new_value, target_ulong write_mask)
4831961738ffSFrédéric Pétrot {
4832961738ffSFrédéric Pétrot     RISCVException ret = riscv_csrrw_check(env, csrno, true);
4833961738ffSFrédéric Pétrot     if (ret != RISCV_EXCP_NONE) {
4834961738ffSFrédéric Pétrot         return ret;
4835457c360fSFrédéric Pétrot     }
4836961738ffSFrédéric Pétrot 
483738c83e8dSYu-Ming Chang     return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
4838457c360fSFrédéric Pétrot }
4839457c360fSFrédéric Pétrot 
riscv_csrrw_do128(CPURISCVState * env,int csrno,Int128 * ret_value,Int128 new_value,Int128 write_mask)4840961738ffSFrédéric Pétrot static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
4841961738ffSFrédéric Pétrot                                         Int128 *ret_value,
4842457c360fSFrédéric Pétrot                                         Int128 new_value,
4843457c360fSFrédéric Pétrot                                         Int128 write_mask)
4844457c360fSFrédéric Pétrot {
4845457c360fSFrédéric Pétrot     RISCVException ret;
4846457c360fSFrédéric Pétrot     Int128 old_value;
4847457c360fSFrédéric Pétrot 
4848457c360fSFrédéric Pétrot     /* read old value */
4849457c360fSFrédéric Pétrot     ret = csr_ops[csrno].read128(env, csrno, &old_value);
4850246f8796SWeiwei Li     if (ret != RISCV_EXCP_NONE) {
4851246f8796SWeiwei Li         return ret;
4852457c360fSFrédéric Pétrot     }
4853457c360fSFrédéric Pétrot 
4854457c360fSFrédéric Pétrot     /* write value if writable and write mask set, otherwise drop writes */
4855457c360fSFrédéric Pétrot     if (int128_nz(write_mask)) {
4856457c360fSFrédéric Pétrot         new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
4857457c360fSFrédéric Pétrot                               int128_and(new_value, write_mask));
4858457c360fSFrédéric Pétrot         if (csr_ops[csrno].write128) {
4859457c360fSFrédéric Pétrot             ret = csr_ops[csrno].write128(env, csrno, new_value);
4860961738ffSFrédéric Pétrot             if (ret != RISCV_EXCP_NONE) {
4861961738ffSFrédéric Pétrot                 return ret;
4862961738ffSFrédéric Pétrot             }
4863753e3fe2SJim Wilson         } else if (csr_ops[csrno].write) {
4864753e3fe2SJim Wilson             /* avoids having to write wrappers for all registers */
4865753e3fe2SJim Wilson             ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
4866753e3fe2SJim Wilson             if (ret != RISCV_EXCP_NONE) {
4867533c91e8SAlistair Francis                 return ret;
4868533c91e8SAlistair Francis             }
4869533c91e8SAlistair Francis         }
4870533c91e8SAlistair Francis     }
4871753e3fe2SJim Wilson 
4872533c91e8SAlistair Francis     /* return old value */
4873753e3fe2SJim Wilson     if (ret_value) {
4874753e3fe2SJim Wilson         *ret_value = old_value;
4875753e3fe2SJim Wilson     }
487638c83e8dSYu-Ming Chang 
487738c83e8dSYu-Ming Chang     return RISCV_EXCP_NONE;
487838c83e8dSYu-Ming Chang }
4879753e3fe2SJim Wilson 
riscv_csrr_i128(CPURISCVState * env,int csrno,Int128 * ret_value)488038c83e8dSYu-Ming Chang RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
4881753e3fe2SJim Wilson                                Int128 *ret_value)
4882753e3fe2SJim Wilson {
4883753e3fe2SJim Wilson     RISCVException ret;
4884753e3fe2SJim Wilson 
4885753e3fe2SJim Wilson     ret = riscv_csrrw_check(env, csrno, false);
4886753e3fe2SJim Wilson     if (ret != RISCV_EXCP_NONE) {
4887ce3af0bbSWeiwei Li         return ret;
4888ce3af0bbSWeiwei Li     }
4889ce3af0bbSWeiwei Li 
4890ce3af0bbSWeiwei Li     if (csr_ops[csrno].read128) {
4891ce3af0bbSWeiwei Li         return riscv_csrrw_do128(env, csrno, ret_value,
4892ce3af0bbSWeiwei Li                                  int128_zero(), int128_zero());
4893ce3af0bbSWeiwei Li     }
4894ce3af0bbSWeiwei Li 
4895ce3af0bbSWeiwei Li     /*
4896ce3af0bbSWeiwei Li      * Fall back to 64-bit version for now, if the 128-bit alternative isn't
4897ce3af0bbSWeiwei Li      * at all defined.
4898ce3af0bbSWeiwei Li      * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
4899ce3af0bbSWeiwei Li      * significant), for those, this fallback is correctly handling the
4900ce3af0bbSWeiwei Li      * accesses
4901eae04c4cSBin Meng      */
4902eae04c4cSBin Meng     target_ulong old_value;
4903eae04c4cSBin Meng     ret = riscv_csrrw_do64(env, csrno, &old_value,
4904eae04c4cSBin Meng                            (target_ulong)0,
490556118ee8SBin Meng                            (target_ulong)0);
4906c7b95171SMichael Clark     if (ret == RISCV_EXCP_NONE && ret_value) {
49078ceac5dcSBin Meng         *ret_value = int128_make64(old_value);
49088ceac5dcSBin Meng     }
49098ceac5dcSBin Meng     return ret;
49108e3a1f18SLIU Zhiwei }
49110e660142SFrank Chang 
riscv_csrrw_i128(CPURISCVState * env,int csrno,Int128 * ret_value,Int128 new_value,Int128 write_mask)49120e660142SFrank Chang RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
49130e660142SFrank Chang                                 Int128 *ret_value,
49140e660142SFrank Chang                                 Int128 new_value, Int128 write_mask)
49150e660142SFrank Chang {
49160e660142SFrank Chang     RISCVException ret;
49170e660142SFrank Chang 
4918c7b95171SMichael Clark     ret = riscv_csrrw_check(env, csrno, true);
49193780e337SAtish Patra     if (ret != RISCV_EXCP_NONE) {
49203780e337SAtish Patra         return ret;
49213780e337SAtish Patra     }
49223780e337SAtish Patra 
4923c7b95171SMichael Clark     if (csr_ops[csrno].read128) {
49248ceac5dcSBin Meng         return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
49258ceac5dcSBin Meng     }
49268ceac5dcSBin Meng 
49278ceac5dcSBin Meng     /*
49288ceac5dcSBin Meng      * Fall back to 64-bit version for now, if the 128-bit alternative isn't
49298ceac5dcSBin Meng      * at all defined.
4930c7b95171SMichael Clark      * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
493177442380SWeiwei Li      * significant), for those, this fallback is correctly handling the
493277442380SWeiwei Li      * accesses
493377442380SWeiwei Li      */
4934ce3af0bbSWeiwei Li     target_ulong old_value;
4935ce3af0bbSWeiwei Li     ret = riscv_csrrw_do64(env, csrno, &old_value,
4936ce3af0bbSWeiwei Li                            int128_getlo(new_value),
4937c7b95171SMichael Clark                            int128_getlo(write_mask));
4938c7b95171SMichael Clark     if (ret == RISCV_EXCP_NONE && ret_value) {
4939108c4f26SWeiwei Li         *ret_value = int128_make64(old_value);
4940108c4f26SWeiwei Li     }
4941108c4f26SWeiwei Li     return ret;
4942108c4f26SWeiwei Li }
4943108c4f26SWeiwei Li 
4944108c4f26SWeiwei Li /*
4945108c4f26SWeiwei Li  * Debugger support.  If not in user mode, set env->debugger before the
4946108c4f26SWeiwei Li  * riscv_csrrw call and clear it after the call.
4947c7b95171SMichael Clark  */
riscv_csrrw_debug(CPURISCVState * env,int csrno,target_ulong * ret_value,target_ulong new_value,target_ulong write_mask)4948c7b95171SMichael Clark RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
49499951ba94SFrank Chang                                  target_ulong *ret_value,
49509951ba94SFrank Chang                                  target_ulong new_value,
4951075eeda9SFrank Chang                                  target_ulong write_mask)
49528ceac5dcSBin Meng {
4953c7b95171SMichael Clark     RISCVException ret;
49543e6a417cSAtish Patra #if !defined(CONFIG_USER_ONLY)
49553e6a417cSAtish Patra     env->debugger = true;
4956c7b95171SMichael Clark #endif
4957108c4f26SWeiwei Li     if (!write_mask) {
4958108c4f26SWeiwei Li         ret = riscv_csrr(env, csrno, ret_value);
4959108c4f26SWeiwei Li     } else {
4960108c4f26SWeiwei Li         ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
4961d028ac75SAnup Patel     }
49628ceac5dcSBin Meng #if !defined(CONFIG_USER_ONLY)
4963d028ac75SAnup Patel     env->debugger = false;
49648ceac5dcSBin Meng #endif
4965c126f83cSWeiwei Li     return ret;
4966108c4f26SWeiwei Li }
4967c7b95171SMichael Clark 
read_jvt(CPURISCVState * env,int csrno,target_ulong * val)4968108c4f26SWeiwei Li static RISCVException read_jvt(CPURISCVState *env, int csrno,
4969108c4f26SWeiwei Li                                target_ulong *val)
497027796989SFea.Wang {
497127796989SFea.Wang     *val = env->jvt;
497227796989SFea.Wang     return RISCV_EXCP_NONE;
497327796989SFea.Wang }
4974551fa7e8SAlistair Francis 
write_jvt(CPURISCVState * env,int csrno,target_ulong val)4975c7b95171SMichael Clark static RISCVException write_jvt(CPURISCVState *env, int csrno,
4976108c4f26SWeiwei Li                                 target_ulong val)
4977108c4f26SWeiwei Li {
49788ceac5dcSBin Meng     env->jvt = val;
49798ceac5dcSBin Meng     return RISCV_EXCP_NONE;
4980ac12b601SAtish Patra }
49818ceac5dcSBin Meng 
4982c7b95171SMichael Clark /*
4983d1ceff40SAnup Patel  * Control and Status Register function table
4984d1ceff40SAnup Patel  * riscv_csr_operations::predicate() must be provided for an implemented CSR
4985d1ceff40SAnup Patel  */
4986d1ceff40SAnup Patel riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
4987c7de92b4SAnup Patel     /* User Floating-Point CSRs */
4988ac4b0302SAnup Patel     [CSR_FFLAGS]   = { "fflags",   fs,     read_fflags,  write_fflags },
4989df01af33SAnup Patel     [CSR_FRM]      = { "frm",      fs,     read_frm,     write_frm    },
4990ac4b0302SAnup Patel     [CSR_FCSR]     = { "fcsr",     fs,     read_fcsr,    write_fcsr   },
4991d0237b4dSAnup Patel     /* Vector CSRs */
49921697837eSRajnesh Kanwal     [CSR_VSTART]   = { "vstart",   vs,     read_vstart,  write_vstart },
49931697837eSRajnesh Kanwal     [CSR_VXSAT]    = { "vxsat",    vs,     read_vxsat,   write_vxsat  },
4994d0237b4dSAnup Patel     [CSR_VXRM]     = { "vxrm",     vs,     read_vxrm,    write_vxrm   },
4995d028ac75SAnup Patel     [CSR_VCSR]     = { "vcsr",     vs,     read_vcsr,    write_vcsr   },
4996d028ac75SAnup Patel     [CSR_VL]       = { "vl",       vs,     read_vl                    },
4997d028ac75SAnup Patel     [CSR_VTYPE]    = { "vtype",    vs,     read_vtype                 },
49981697837eSRajnesh Kanwal     [CSR_VLENB]    = { "vlenb",    vs,     read_vlenb                 },
49991697837eSRajnesh Kanwal     /* User Timers and Counters */
5000d028ac75SAnup Patel     [CSR_CYCLE]    = { "cycle",    ctr,    read_hpmcounter  },
5001d028ac75SAnup Patel     [CSR_INSTRET]  = { "instret",  ctr,    read_hpmcounter  },
500229a9ec9bSAtish Patra     [CSR_CYCLEH]   = { "cycleh",   ctr32,  read_hpmcounterh },
5003c126f83cSWeiwei Li     [CSR_INSTRETH] = { "instreth", ctr32,  read_hpmcounterh },
500429a9ec9bSAtish Patra 
5005c126f83cSWeiwei Li     /*
500629a9ec9bSAtish Patra      * In privileged mode, the monitor will have to emulate TIME CSRs only if
500729a9ec9bSAtish Patra      * rdtime callback is not provided by machine/platform emulation.
500829a9ec9bSAtish Patra      */
500929a9ec9bSAtish Patra     [CSR_TIME]  = { "time",  ctr,   read_time  },
501029a9ec9bSAtish Patra     [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
501129a9ec9bSAtish Patra 
501229a9ec9bSAtish Patra     /* Crypto Extension */
501329a9ec9bSAtish Patra     [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
50143bee0e40SMayuresh Chitale 
50153bee0e40SMayuresh Chitale     /* Zcmt Extension */
50163bee0e40SMayuresh Chitale     [CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
50173bee0e40SMayuresh Chitale 
50183bee0e40SMayuresh Chitale     /* zicfiss Extension, shadow stack register */
50193bee0e40SMayuresh Chitale     [CSR_SSP]  = { "ssp", cfi_ss, read_ssp, write_ssp },
50203bee0e40SMayuresh Chitale 
50213bee0e40SMayuresh Chitale #if !defined(CONFIG_USER_ONLY)
50223bee0e40SMayuresh Chitale     /* Machine Timers and Counters */
50233bee0e40SMayuresh Chitale     [CSR_MCYCLE]    = { "mcycle",    any,   read_hpmcounter,
50243bee0e40SMayuresh Chitale                         write_mhpmcounter                    },
50253bee0e40SMayuresh Chitale     [CSR_MINSTRET]  = { "minstret",  any,   read_hpmcounter,
50263bee0e40SMayuresh Chitale                         write_mhpmcounter                    },
50273bee0e40SMayuresh Chitale     [CSR_MCYCLEH]   = { "mcycleh",   any32, read_hpmcounterh,
50283bee0e40SMayuresh Chitale                         write_mhpmcounterh                   },
50293bee0e40SMayuresh Chitale     [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh,
50303bee0e40SMayuresh Chitale                         write_mhpmcounterh                   },
50313bee0e40SMayuresh Chitale 
50323bee0e40SMayuresh Chitale     /* Machine Information Registers */
50333bee0e40SMayuresh Chitale     [CSR_MVENDORID] = { "mvendorid", any,   read_mvendorid },
50343bee0e40SMayuresh Chitale     [CSR_MARCHID]   = { "marchid",   any,   read_marchid   },
50353bee0e40SMayuresh Chitale     [CSR_MIMPID]    = { "mimpid",    any,   read_mimpid    },
50363bee0e40SMayuresh Chitale     [CSR_MHARTID]   = { "mhartid",   any,   read_mhartid   },
50373bee0e40SMayuresh Chitale 
50383bee0e40SMayuresh Chitale     [CSR_MCONFIGPTR]  = { "mconfigptr", any,   read_zero,
50393bee0e40SMayuresh Chitale                           .min_priv_ver = PRIV_VERSION_1_12_0 },
50403bee0e40SMayuresh Chitale     /* Machine Trap Setup */
50413bee0e40SMayuresh Chitale     [CSR_MSTATUS]     = { "mstatus",    any,   read_mstatus, write_mstatus,
50423bee0e40SMayuresh Chitale                           NULL,                read_mstatus_i128           },
50433bee0e40SMayuresh Chitale     [CSR_MISA]        = { "misa",       any,   read_misa,    write_misa,
50443bee0e40SMayuresh Chitale                           NULL,                read_misa_i128              },
50453bee0e40SMayuresh Chitale     [CSR_MIDELEG]     = { "mideleg",    any,   NULL, NULL,   rmw_mideleg   },
50463bee0e40SMayuresh Chitale     [CSR_MEDELEG]     = { "medeleg",    any,   read_medeleg, write_medeleg },
50473bee0e40SMayuresh Chitale     [CSR_MIE]         = { "mie",        any,   NULL, NULL,   rmw_mie       },
50483bee0e40SMayuresh Chitale     [CSR_MTVEC]       = { "mtvec",      any,   read_mtvec,   write_mtvec   },
50493bee0e40SMayuresh Chitale     [CSR_MCOUNTEREN]  = { "mcounteren", umode, read_mcounteren,
50503bee0e40SMayuresh Chitale                           write_mcounteren                                 },
50513bee0e40SMayuresh Chitale 
50523bee0e40SMayuresh Chitale     [CSR_MSTATUSH]    = { "mstatush",   any32, read_mstatush,
50533bee0e40SMayuresh Chitale                           write_mstatush                                   },
50543bee0e40SMayuresh Chitale     [CSR_MEDELEGH]    = { "medelegh",   any32, read_zero, write_ignore,
50553bee0e40SMayuresh Chitale                           .min_priv_ver = PRIV_VERSION_1_13_0              },
50563bee0e40SMayuresh Chitale     [CSR_HEDELEGH]    = { "hedelegh",   hmode32, read_hedelegh, write_hedelegh,
50573bee0e40SMayuresh Chitale                           .min_priv_ver = PRIV_VERSION_1_13_0              },
50583bee0e40SMayuresh Chitale 
50593bee0e40SMayuresh Chitale     /* Machine Trap Handling */
50603bee0e40SMayuresh Chitale     [CSR_MSCRATCH] = { "mscratch", any,  read_mscratch, write_mscratch,
50613bee0e40SMayuresh Chitale                        NULL, read_mscratch_i128, write_mscratch_i128   },
50623bee0e40SMayuresh Chitale     [CSR_MEPC]     = { "mepc",     any,  read_mepc,     write_mepc     },
50633bee0e40SMayuresh Chitale     [CSR_MCAUSE]   = { "mcause",   any,  read_mcause,   write_mcause   },
50643bee0e40SMayuresh Chitale     [CSR_MTVAL]    = { "mtval",    any,  read_mtval,    write_mtval    },
50653bee0e40SMayuresh Chitale     [CSR_MIP]      = { "mip",      any,  NULL,    NULL, rmw_mip        },
50663bee0e40SMayuresh Chitale 
50673bee0e40SMayuresh Chitale     /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
50683bee0e40SMayuresh Chitale     [CSR_MISELECT] = { "miselect", aia_any,   NULL, NULL,    rmw_xiselect },
50693bee0e40SMayuresh Chitale     [CSR_MIREG]    = { "mireg",    aia_any,   NULL, NULL,    rmw_xireg },
50703bee0e40SMayuresh Chitale 
50713bee0e40SMayuresh Chitale     /* Machine-Level Interrupts (AIA) */
50723bee0e40SMayuresh Chitale     [CSR_MTOPEI]   = { "mtopei",   aia_any, NULL, NULL, rmw_xtopei },
5073c7b95171SMichael Clark     [CSR_MTOPI]    = { "mtopi",    aia_any, read_mtopi },
5074108c4f26SWeiwei Li 
5075108c4f26SWeiwei Li     /* Virtual Interrupts for Supervisor Level (AIA) */
5076d028ac75SAnup Patel     [CSR_MVIEN]    = { "mvien",    aia_any, NULL, NULL, rmw_mvien   },
50778ceac5dcSBin Meng     [CSR_MVIP]     = { "mvip",     aia_any, NULL, NULL, rmw_mvip    },
5078108c4f26SWeiwei Li 
5079108c4f26SWeiwei Li     /* Machine-Level High-Half CSRs (AIA) */
5080c7b95171SMichael Clark     [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
5081c7b95171SMichael Clark     [CSR_MIEH]     = { "mieh",     aia_any32, NULL, NULL, rmw_mieh     },
5082108c4f26SWeiwei Li     [CSR_MVIENH]   = { "mvienh",   aia_any32, NULL, NULL, rmw_mvienh   },
5083108c4f26SWeiwei Li     [CSR_MVIPH]    = { "mviph",    aia_any32, NULL, NULL, rmw_mviph    },
50848ceac5dcSBin Meng     [CSR_MIPH]     = { "miph",     aia_any32, NULL, NULL, rmw_miph     },
50858ceac5dcSBin Meng 
5086ac12b601SAtish Patra     /* Execution environment configuration */
50878ceac5dcSBin Meng     [CSR_MENVCFG]  = { "menvcfg",  umode, read_menvcfg,  write_menvcfg,
508843888c2fSAtish Patra                        .min_priv_ver = PRIV_VERSION_1_12_0              },
508943888c2fSAtish Patra     [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh,
509043888c2fSAtish Patra                        .min_priv_ver = PRIV_VERSION_1_12_0              },
509143888c2fSAtish Patra     [CSR_SENVCFG]  = { "senvcfg",  smode, read_senvcfg,  write_senvcfg,
50923ec0fe18SAtish Patra                        .min_priv_ver = PRIV_VERSION_1_12_0              },
50933ec0fe18SAtish Patra     [CSR_HENVCFG]  = { "henvcfg",  hmode, read_henvcfg, write_henvcfg,
50943ec0fe18SAtish Patra                        .min_priv_ver = PRIV_VERSION_1_12_0              },
50953ec0fe18SAtish Patra     [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
50963ec0fe18SAtish Patra                        .min_priv_ver = PRIV_VERSION_1_12_0              },
50973ec0fe18SAtish Patra 
5098c7b95171SMichael Clark     /* Smstateen extension CSRs */
5099c7b95171SMichael Clark     [CSR_MSTATEEN0] = { "mstateen0", mstateen, read_mstateen, write_mstateen0,
5100d6db7c97SYi Chen                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5101c7b95171SMichael Clark     [CSR_MSTATEEN0H] = { "mstateen0h", mstateen, read_mstateenh,
5102d1ceff40SAnup Patel                           write_mstateen0h,
5103d1ceff40SAnup Patel                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5104d1ceff40SAnup Patel     [CSR_MSTATEEN1] = { "mstateen1", mstateen, read_mstateen,
5105d1ceff40SAnup Patel                         write_mstateen_1_3,
5106c7de92b4SAnup Patel                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5107ac4b0302SAnup Patel     [CSR_MSTATEEN1H] = { "mstateen1h", mstateen, read_mstateenh,
5108df01af33SAnup Patel                          write_mstateenh_1_3,
5109ac4b0302SAnup Patel                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5110d028ac75SAnup Patel     [CSR_MSTATEEN2] = { "mstateen2", mstateen, read_mstateen,
5111d028ac75SAnup Patel                         write_mstateen_1_3,
5112d028ac75SAnup Patel                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5113d028ac75SAnup Patel     [CSR_MSTATEEN2H] = { "mstateen2h", mstateen, read_mstateenh,
5114a4b2fa43SAtish Patra                          write_mstateenh_1_3,
5115a4b2fa43SAtish Patra                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5116a4b2fa43SAtish Patra     [CSR_MSTATEEN3] = { "mstateen3", mstateen, read_mstateen,
5117a4b2fa43SAtish Patra                         write_mstateen_1_3,
5118a4b2fa43SAtish Patra                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5119a4b2fa43SAtish Patra     [CSR_MSTATEEN3H] = { "mstateen3h", mstateen, read_mstateenh,
5120a4b2fa43SAtish Patra                          write_mstateenh_1_3,
5121a4b2fa43SAtish Patra                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5122a4b2fa43SAtish Patra     [CSR_HSTATEEN0] = { "hstateen0", hstateen, read_hstateen, write_hstateen0,
5123a4b2fa43SAtish Patra                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5124a4b2fa43SAtish Patra     [CSR_HSTATEEN0H] = { "hstateen0h", hstateenh, read_hstateenh,
5125a4b2fa43SAtish Patra                          write_hstateen0h,
5126108c4f26SWeiwei Li                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5127108c4f26SWeiwei Li     [CSR_HSTATEEN1] = { "hstateen1", hstateen, read_hstateen,
5128a4b2fa43SAtish Patra                         write_hstateen_1_3,
5129a4b2fa43SAtish Patra                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5130a4b2fa43SAtish Patra     [CSR_HSTATEEN1H] = { "hstateen1h", hstateenh, read_hstateenh,
5131a4b2fa43SAtish Patra                          write_hstateenh_1_3,
5132a4b2fa43SAtish Patra                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5133a4b2fa43SAtish Patra     [CSR_HSTATEEN2] = { "hstateen2", hstateen, read_hstateen,
5134a4b2fa43SAtish Patra                         write_hstateen_1_3,
5135a4b2fa43SAtish Patra                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5136a4b2fa43SAtish Patra     [CSR_HSTATEEN2H] = { "hstateen2h", hstateenh, read_hstateenh,
5137d6db7c97SYi Chen                          write_hstateenh_1_3,
5138a4b2fa43SAtish Patra                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5139108c4f26SWeiwei Li     [CSR_HSTATEEN3] = { "hstateen3", hstateen, read_hstateen,
5140108c4f26SWeiwei Li                         write_hstateen_1_3,
5141a4b2fa43SAtish Patra                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5142108c4f26SWeiwei Li     [CSR_HSTATEEN3H] = { "hstateen3h", hstateenh, read_hstateenh,
5143108c4f26SWeiwei Li                          write_hstateenh_1_3,
5144a4b2fa43SAtish Patra                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5145ff2cc129SAlistair Francis     [CSR_SSTATEEN0] = { "sstateen0", sstateen, read_sstateen, write_sstateen0,
5146108c4f26SWeiwei Li                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5147108c4f26SWeiwei Li     [CSR_SSTATEEN1] = { "sstateen1", sstateen, read_sstateen,
5148a4b2fa43SAtish Patra                         write_sstateen_1_3,
5149a4b2fa43SAtish Patra                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5150a4b2fa43SAtish Patra     [CSR_SSTATEEN2] = { "sstateen2", sstateen, read_sstateen,
5151a4b2fa43SAtish Patra                         write_sstateen_1_3,
5152a4b2fa43SAtish Patra                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5153a4b2fa43SAtish Patra     [CSR_SSTATEEN3] = { "sstateen3", sstateen, read_sstateen,
5154a4b2fa43SAtish Patra                         write_sstateen_1_3,
5155108c4f26SWeiwei Li                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5156108c4f26SWeiwei Li 
5157a4b2fa43SAtish Patra     /* Supervisor Trap Setup */
5158a4b2fa43SAtish Patra     [CSR_SSTATUS]    = { "sstatus",    smode, read_sstatus,    write_sstatus,
5159a4b2fa43SAtish Patra                          NULL,                read_sstatus_i128              },
5160a4b2fa43SAtish Patra     [CSR_SIE]        = { "sie",        smode, NULL,   NULL,    rmw_sie       },
5161a4b2fa43SAtish Patra     [CSR_STVEC]      = { "stvec",      smode, read_stvec,      write_stvec   },
5162a4b2fa43SAtish Patra     [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren,
5163a4b2fa43SAtish Patra                          write_scounteren                                    },
5164a4b2fa43SAtish Patra 
5165a4b2fa43SAtish Patra     /* Supervisor Trap Handling */
51668747c9eeSAlistair Francis     [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch,
5167a4b2fa43SAtish Patra                        NULL, read_sscratch_i128, write_sscratch_i128    },
5168a4b2fa43SAtish Patra     [CSR_SEPC]     = { "sepc",     smode, read_sepc,     write_sepc     },
5169a4b2fa43SAtish Patra     [CSR_SCAUSE]   = { "scause",   smode, read_scause,   write_scause   },
5170a4b2fa43SAtish Patra     [CSR_STVAL]    = { "stval",    smode, read_stval,    write_stval    },
517134cfb5f6SAlistair Francis     [CSR_SIP]      = { "sip",      smode, NULL,    NULL, rmw_sip        },
51722b602398SAnup Patel     [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp,
517340336d5bSRajnesh Kanwal                        .min_priv_ver = PRIV_VERSION_1_12_0 },
5174108c4f26SWeiwei Li     [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
5175108c4f26SWeiwei Li                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5176108c4f26SWeiwei Li     [CSR_VSTIMECMP] = { "vstimecmp", sstc, read_vstimecmp,
5177108c4f26SWeiwei Li                         write_vstimecmp,
5178108c4f26SWeiwei Li                         .min_priv_ver = PRIV_VERSION_1_12_0 },
5179108c4f26SWeiwei Li     [CSR_VSTIMECMPH] = { "vstimecmph", sstc_32, read_vstimecmph,
5180d1ceff40SAnup Patel                          write_vstimecmph,
5181d1ceff40SAnup Patel                          .min_priv_ver = PRIV_VERSION_1_12_0 },
5182d1ceff40SAnup Patel 
5183108c4f26SWeiwei Li     /* Supervisor Protection and Translation */
5184108c4f26SWeiwei Li     [CSR_SATP]     = { "satp",     satp, read_satp,     write_satp     },
5185d1ceff40SAnup Patel 
5186d1ceff40SAnup Patel     /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
5187c7de92b4SAnup Patel     [CSR_SISELECT]   = { "siselect",   aia_smode, NULL, NULL, rmw_xiselect },
5188ac4b0302SAnup Patel     [CSR_SIREG]      = { "sireg",      aia_smode, NULL, NULL, rmw_xireg },
5189df01af33SAnup Patel 
5190ac4b0302SAnup Patel     /* Supervisor-Level Interrupts (AIA) */
5191d028ac75SAnup Patel     [CSR_STOPEI]     = { "stopei",     aia_smode, NULL, NULL, rmw_xtopei },
5192108c4f26SWeiwei Li     [CSR_STOPI]      = { "stopi",      aia_smode, read_stopi },
5193108c4f26SWeiwei Li 
519440336d5bSRajnesh Kanwal     /* Supervisor-Level High-Half CSRs (AIA) */
5195d028ac75SAnup Patel     [CSR_SIEH]       = { "sieh",   aia_smode32, NULL, NULL, rmw_sieh },
5196108c4f26SWeiwei Li     [CSR_SIPH]       = { "siph",   aia_smode32, NULL, NULL, rmw_siph },
5197108c4f26SWeiwei Li 
5198108c4f26SWeiwei Li     [CSR_HSTATUS]     = { "hstatus",     hmode,   read_hstatus, write_hstatus,
5199108c4f26SWeiwei Li                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5200d028ac75SAnup Patel     [CSR_HEDELEG]     = { "hedeleg",     hmode,   read_hedeleg, write_hedeleg,
5201d028ac75SAnup Patel                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5202d028ac75SAnup Patel     [CSR_HIDELEG]     = { "hideleg",     hmode,   NULL,   NULL, rmw_hideleg,
5203c7b95171SMichael Clark                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52042f32dcabSHeinrich Schuchardt     [CSR_HVIP]        = { "hvip",        hmode,   NULL,   NULL, rmw_hvip,
5205b509caceSAlistair Francis                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52068ceac5dcSBin Meng     [CSR_HIP]         = { "hip",         hmode,   NULL,   NULL, rmw_hip,
52078ceac5dcSBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52088ceac5dcSBin Meng     [CSR_HIE]         = { "hie",         hmode,   NULL,   NULL, rmw_hie,
52098ceac5dcSBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52108ceac5dcSBin Meng     [CSR_HCOUNTEREN]  = { "hcounteren",  hmode,   read_hcounteren,
52118ceac5dcSBin Meng                           write_hcounteren,
52128ceac5dcSBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52138ceac5dcSBin Meng     [CSR_HGEIE]       = { "hgeie",       hmode,   read_hgeie,   write_hgeie,
52148ceac5dcSBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52158ceac5dcSBin Meng     [CSR_HTVAL]       = { "htval",       hmode,   read_htval,   write_htval,
52168ceac5dcSBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52178ceac5dcSBin Meng     [CSR_HTINST]      = { "htinst",      hmode,   read_htinst,  write_htinst,
52188ceac5dcSBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52198ceac5dcSBin Meng     [CSR_HGEIP]       = { "hgeip",       hmode,   read_hgeip,
52208ceac5dcSBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52218ceac5dcSBin Meng     [CSR_HGATP]       = { "hgatp",       hgatp,   read_hgatp,   write_hgatp,
52228ceac5dcSBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52238ceac5dcSBin Meng     [CSR_HTIMEDELTA]  = { "htimedelta",  hmode,   read_htimedelta,
52248ceac5dcSBin Meng                           write_htimedelta,
52258ceac5dcSBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5226c7b95171SMichael Clark     [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah,
5227b6092544SBin Meng                           write_htimedeltah,
5228b6092544SBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5229b6092544SBin Meng 
5230b6092544SBin Meng     [CSR_VSSTATUS]    = { "vsstatus",    hmode,   read_vsstatus,
5231b6092544SBin Meng                           write_vsstatus,
523231b9798dSFrank Chang                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52330c4e579aSAlvin Chang     [CSR_VSIP]        = { "vsip",        hmode,   NULL,    NULL, rmw_vsip,
5234b6092544SBin Meng                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52354bbe8033SAlexey Baturo     [CSR_VSIE]        = { "vsie",        hmode,   NULL,    NULL, rmw_vsie ,
52364bbe8033SAlexey Baturo                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5237108c4f26SWeiwei Li     [CSR_VSTVEC]      = { "vstvec",      hmode,   read_vstvec,   write_vstvec,
5238108c4f26SWeiwei Li                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5239108c4f26SWeiwei Li     [CSR_VSSCRATCH]   = { "vsscratch",   hmode,   read_vsscratch,
5240108c4f26SWeiwei Li                           write_vsscratch,
52414bbe8033SAlexey Baturo                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52424bbe8033SAlexey Baturo     [CSR_VSEPC]       = { "vsepc",       hmode,   read_vsepc,    write_vsepc,
5243108c4f26SWeiwei Li                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5244108c4f26SWeiwei Li     [CSR_VSCAUSE]     = { "vscause",     hmode,   read_vscause,  write_vscause,
5245108c4f26SWeiwei Li                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5246108c4f26SWeiwei Li     [CSR_VSTVAL]      = { "vstval",      hmode,   read_vstval,   write_vstval,
52474bbe8033SAlexey Baturo                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52484bbe8033SAlexey Baturo     [CSR_VSATP]       = { "vsatp",       hmode,   read_vsatp,    write_vsatp,
5249108c4f26SWeiwei Li                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5250108c4f26SWeiwei Li 
5251108c4f26SWeiwei Li     [CSR_MTVAL2]      = { "mtval2",      hmode,   read_mtval2,   write_mtval2,
5252108c4f26SWeiwei Li                           .min_priv_ver = PRIV_VERSION_1_12_0                },
52534bbe8033SAlexey Baturo     [CSR_MTINST]      = { "mtinst",      hmode,   read_mtinst,   write_mtinst,
5254c7b95171SMichael Clark                           .min_priv_ver = PRIV_VERSION_1_12_0                },
5255621f35bbSAtish Patra 
5256621f35bbSAtish Patra     /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
5257621f35bbSAtish Patra     [CSR_HVIEN]       = { "hvien",       aia_hmode, NULL, NULL, rmw_hvien },
5258621f35bbSAtish Patra     [CSR_HVICTL]      = { "hvictl",      aia_hmode, read_hvictl,
5259621f35bbSAtish Patra                           write_hvictl                                      },
5260621f35bbSAtish Patra     [CSR_HVIPRIO1]    = { "hviprio1",    aia_hmode, read_hviprio1,
5261621f35bbSAtish Patra                           write_hviprio1                                    },
5262621f35bbSAtish Patra     [CSR_HVIPRIO2]    = { "hviprio2",    aia_hmode, read_hviprio2,
5263621f35bbSAtish Patra                           write_hviprio2                                    },
5264621f35bbSAtish Patra     /*
5265621f35bbSAtish Patra      * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
5266621f35bbSAtish Patra      */
5267621f35bbSAtish Patra     [CSR_VSISELECT]   = { "vsiselect",   aia_hmode, NULL, NULL,
5268621f35bbSAtish Patra                           rmw_xiselect                                     },
5269621f35bbSAtish Patra     [CSR_VSIREG]      = { "vsireg",      aia_hmode, NULL, NULL, rmw_xireg  },
5270621f35bbSAtish Patra 
5271621f35bbSAtish Patra     /* VS-Level Interrupts (H-extension with AIA) */
5272621f35bbSAtish Patra     [CSR_VSTOPEI]     = { "vstopei",     aia_hmode, NULL, NULL, rmw_xtopei },
5273621f35bbSAtish Patra     [CSR_VSTOPI]      = { "vstopi",      aia_hmode, read_vstopi },
5274621f35bbSAtish Patra 
5275621f35bbSAtish Patra     /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
5276621f35bbSAtish Patra     [CSR_HIDELEGH]    = { "hidelegh",    aia_hmode32, NULL, NULL,
5277621f35bbSAtish Patra                           rmw_hidelegh                                      },
5278621f35bbSAtish Patra     [CSR_HVIENH]      = { "hvienh",      aia_hmode32, NULL, NULL, rmw_hvienh },
5279621f35bbSAtish Patra     [CSR_HVIPH]       = { "hviph",       aia_hmode32, NULL, NULL, rmw_hviph },
5280621f35bbSAtish Patra     [CSR_HVIPRIO1H]   = { "hviprio1h",   aia_hmode32, read_hviprio1h,
5281621f35bbSAtish Patra                           write_hviprio1h                                   },
5282621f35bbSAtish Patra     [CSR_HVIPRIO2H]   = { "hviprio2h",   aia_hmode32, read_hviprio2h,
5283621f35bbSAtish Patra                           write_hviprio2h                                   },
52848ceac5dcSBin Meng     [CSR_VSIEH]       = { "vsieh",       aia_hmode32, NULL, NULL, rmw_vsieh },
5285621f35bbSAtish Patra     [CSR_VSIPH]       = { "vsiph",       aia_hmode32, NULL, NULL, rmw_vsiph },
5286621f35bbSAtish Patra 
5287621f35bbSAtish Patra     /* Physical Memory Protection */
5288621f35bbSAtish Patra     [CSR_MSECCFG]    = { "mseccfg",   have_mseccfg, read_mseccfg, write_mseccfg,
5289621f35bbSAtish Patra                          .min_priv_ver = PRIV_VERSION_1_11_0           },
5290621f35bbSAtish Patra     [CSR_PMPCFG0]    = { "pmpcfg0",   pmp, read_pmpcfg,  write_pmpcfg  },
5291621f35bbSAtish Patra     [CSR_PMPCFG1]    = { "pmpcfg1",   pmp, read_pmpcfg,  write_pmpcfg  },
5292621f35bbSAtish Patra     [CSR_PMPCFG2]    = { "pmpcfg2",   pmp, read_pmpcfg,  write_pmpcfg  },
5293621f35bbSAtish Patra     [CSR_PMPCFG3]    = { "pmpcfg3",   pmp, read_pmpcfg,  write_pmpcfg  },
5294621f35bbSAtish Patra     [CSR_PMPADDR0]   = { "pmpaddr0",  pmp, read_pmpaddr, write_pmpaddr },
5295621f35bbSAtish Patra     [CSR_PMPADDR1]   = { "pmpaddr1",  pmp, read_pmpaddr, write_pmpaddr },
5296621f35bbSAtish Patra     [CSR_PMPADDR2]   = { "pmpaddr2",  pmp, read_pmpaddr, write_pmpaddr },
5297621f35bbSAtish Patra     [CSR_PMPADDR3]   = { "pmpaddr3",  pmp, read_pmpaddr, write_pmpaddr },
5298621f35bbSAtish Patra     [CSR_PMPADDR4]   = { "pmpaddr4",  pmp, read_pmpaddr, write_pmpaddr },
5299621f35bbSAtish Patra     [CSR_PMPADDR5]   = { "pmpaddr5",  pmp, read_pmpaddr, write_pmpaddr },
5300621f35bbSAtish Patra     [CSR_PMPADDR6]   = { "pmpaddr6",  pmp, read_pmpaddr, write_pmpaddr },
5301621f35bbSAtish Patra     [CSR_PMPADDR7]   = { "pmpaddr7",  pmp, read_pmpaddr, write_pmpaddr },
5302621f35bbSAtish Patra     [CSR_PMPADDR8]   = { "pmpaddr8",  pmp, read_pmpaddr, write_pmpaddr },
5303621f35bbSAtish Patra     [CSR_PMPADDR9]   = { "pmpaddr9",  pmp, read_pmpaddr, write_pmpaddr },
5304621f35bbSAtish Patra     [CSR_PMPADDR10]  = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
5305621f35bbSAtish Patra     [CSR_PMPADDR11]  = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
5306621f35bbSAtish Patra     [CSR_PMPADDR12]  = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
5307621f35bbSAtish Patra     [CSR_PMPADDR13]  = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
5308621f35bbSAtish Patra     [CSR_PMPADDR14] =  { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
5309621f35bbSAtish Patra     [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
5310621f35bbSAtish Patra 
5311621f35bbSAtish Patra     /* Debug CSRs */
5312621f35bbSAtish Patra     [CSR_TSELECT]   =  { "tselect",  debug, read_tselect,  write_tselect  },
5313621f35bbSAtish Patra     [CSR_TDATA1]    =  { "tdata1",   debug, read_tdata,    write_tdata    },
5314621f35bbSAtish Patra     [CSR_TDATA2]    =  { "tdata2",   debug, read_tdata,    write_tdata    },
5315621f35bbSAtish Patra     [CSR_TDATA3]    =  { "tdata3",   debug, read_tdata,    write_tdata    },
5316621f35bbSAtish Patra     [CSR_TINFO]     =  { "tinfo",    debug, read_tinfo,    write_ignore   },
5317621f35bbSAtish Patra     [CSR_MCONTEXT]  =  { "mcontext", debug, read_mcontext, write_mcontext },
5318621f35bbSAtish Patra 
5319621f35bbSAtish Patra     /* User Pointer Masking */
5320621f35bbSAtish Patra     [CSR_UMTE]    =    { "umte",    pointer_masking, read_umte,  write_umte },
5321621f35bbSAtish Patra     [CSR_UPMMASK] =    { "upmmask", pointer_masking, read_upmmask,
5322621f35bbSAtish Patra                          write_upmmask                                      },
5323621f35bbSAtish Patra     [CSR_UPMBASE] =    { "upmbase", pointer_masking, read_upmbase,
5324621f35bbSAtish Patra                          write_upmbase                                      },
5325621f35bbSAtish Patra     /* Machine Pointer Masking */
5326621f35bbSAtish Patra     [CSR_MMTE]    =    { "mmte",    pointer_masking, read_mmte,  write_mmte },
5327621f35bbSAtish Patra     [CSR_MPMMASK] =    { "mpmmask", pointer_masking, read_mpmmask,
5328621f35bbSAtish Patra                          write_mpmmask                                      },
5329621f35bbSAtish Patra     [CSR_MPMBASE] =    { "mpmbase", pointer_masking, read_mpmbase,
5330621f35bbSAtish Patra                          write_mpmbase                                      },
5331621f35bbSAtish Patra     /* Supervisor Pointer Masking */
5332621f35bbSAtish Patra     [CSR_SMTE]    =    { "smte",    pointer_masking, read_smte,  write_smte },
5333621f35bbSAtish Patra     [CSR_SPMMASK] =    { "spmmask", pointer_masking, read_spmmask,
5334621f35bbSAtish Patra                          write_spmmask                                      },
5335621f35bbSAtish Patra     [CSR_SPMBASE] =    { "spmbase", pointer_masking, read_spmbase,
5336621f35bbSAtish Patra                          write_spmbase                                      },
5337621f35bbSAtish Patra 
5338621f35bbSAtish Patra     /* Performance Counters */
5339621f35bbSAtish Patra     [CSR_HPMCOUNTER3]    = { "hpmcounter3",    ctr,    read_hpmcounter },
5340621f35bbSAtish Patra     [CSR_HPMCOUNTER4]    = { "hpmcounter4",    ctr,    read_hpmcounter },
5341621f35bbSAtish Patra     [CSR_HPMCOUNTER5]    = { "hpmcounter5",    ctr,    read_hpmcounter },
5342621f35bbSAtish Patra     [CSR_HPMCOUNTER6]    = { "hpmcounter6",    ctr,    read_hpmcounter },
53438ceac5dcSBin Meng     [CSR_HPMCOUNTER7]    = { "hpmcounter7",    ctr,    read_hpmcounter },
5344b1675eebSAtish Patra     [CSR_HPMCOUNTER8]    = { "hpmcounter8",    ctr,    read_hpmcounter },
5345108c4f26SWeiwei Li     [CSR_HPMCOUNTER9]    = { "hpmcounter9",    ctr,    read_hpmcounter },
5346108c4f26SWeiwei Li     [CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,    read_hpmcounter },
5347b1675eebSAtish Patra     [CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,    read_hpmcounter },
5348b54a84c1SKaiwen Xue     [CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,    read_hpmcounter },
5349b54a84c1SKaiwen Xue     [CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,    read_hpmcounter },
5350b54a84c1SKaiwen Xue     [CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,    read_hpmcounter },
5351b54a84c1SKaiwen Xue     [CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,    read_hpmcounter },
5352b54a84c1SKaiwen Xue     [CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,    read_hpmcounter },
5353b54a84c1SKaiwen Xue     [CSR_HPMCOUNTER17]   = { "hpmcounter17",   ctr,    read_hpmcounter },
5354b54a84c1SKaiwen Xue     [CSR_HPMCOUNTER18]   = { "hpmcounter18",   ctr,    read_hpmcounter },
5355621f35bbSAtish Patra     [CSR_HPMCOUNTER19]   = { "hpmcounter19",   ctr,    read_hpmcounter },
5356621f35bbSAtish Patra     [CSR_HPMCOUNTER20]   = { "hpmcounter20",   ctr,    read_hpmcounter },
5357621f35bbSAtish Patra     [CSR_HPMCOUNTER21]   = { "hpmcounter21",   ctr,    read_hpmcounter },
5358621f35bbSAtish Patra     [CSR_HPMCOUNTER22]   = { "hpmcounter22",   ctr,    read_hpmcounter },
5359621f35bbSAtish Patra     [CSR_HPMCOUNTER23]   = { "hpmcounter23",   ctr,    read_hpmcounter },
5360621f35bbSAtish Patra     [CSR_HPMCOUNTER24]   = { "hpmcounter24",   ctr,    read_hpmcounter },
5361621f35bbSAtish Patra     [CSR_HPMCOUNTER25]   = { "hpmcounter25",   ctr,    read_hpmcounter },
5362621f35bbSAtish Patra     [CSR_HPMCOUNTER26]   = { "hpmcounter26",   ctr,    read_hpmcounter },
5363621f35bbSAtish Patra     [CSR_HPMCOUNTER27]   = { "hpmcounter27",   ctr,    read_hpmcounter },
5364621f35bbSAtish Patra     [CSR_HPMCOUNTER28]   = { "hpmcounter28",   ctr,    read_hpmcounter },
5365621f35bbSAtish Patra     [CSR_HPMCOUNTER29]   = { "hpmcounter29",   ctr,    read_hpmcounter },
5366621f35bbSAtish Patra     [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,    read_hpmcounter },
5367621f35bbSAtish Patra     [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,    read_hpmcounter },
5368621f35bbSAtish Patra 
5369621f35bbSAtish Patra     [CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   mctr,    read_hpmcounter,
5370621f35bbSAtish Patra                              write_mhpmcounter                         },
5371621f35bbSAtish Patra     [CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   mctr,    read_hpmcounter,
5372621f35bbSAtish Patra                              write_mhpmcounter                         },
5373621f35bbSAtish Patra     [CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   mctr,    read_hpmcounter,
5374621f35bbSAtish Patra                              write_mhpmcounter                         },
5375621f35bbSAtish Patra     [CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   mctr,    read_hpmcounter,
5376621f35bbSAtish Patra                              write_mhpmcounter                         },
5377621f35bbSAtish Patra     [CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   mctr,    read_hpmcounter,
5378621f35bbSAtish Patra                              write_mhpmcounter                         },
5379621f35bbSAtish Patra     [CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   mctr,    read_hpmcounter,
5380621f35bbSAtish Patra                              write_mhpmcounter                         },
5381621f35bbSAtish Patra     [CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   mctr,    read_hpmcounter,
5382621f35bbSAtish Patra                              write_mhpmcounter                         },
5383621f35bbSAtish Patra     [CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  mctr,    read_hpmcounter,
5384621f35bbSAtish Patra                              write_mhpmcounter                         },
5385621f35bbSAtish Patra     [CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  mctr,    read_hpmcounter,
5386621f35bbSAtish Patra                              write_mhpmcounter                         },
5387621f35bbSAtish Patra     [CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  mctr,    read_hpmcounter,
5388621f35bbSAtish Patra                              write_mhpmcounter                         },
5389621f35bbSAtish Patra     [CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  mctr,    read_hpmcounter,
5390621f35bbSAtish Patra                              write_mhpmcounter                         },
5391621f35bbSAtish Patra     [CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  mctr,    read_hpmcounter,
5392621f35bbSAtish Patra                              write_mhpmcounter                         },
5393621f35bbSAtish Patra     [CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  mctr,    read_hpmcounter,
5394621f35bbSAtish Patra                              write_mhpmcounter                         },
5395621f35bbSAtish Patra     [CSR_MHPMCOUNTER16]  = { "mhpmcounter16",  mctr,    read_hpmcounter,
5396621f35bbSAtish Patra                              write_mhpmcounter                         },
5397621f35bbSAtish Patra     [CSR_MHPMCOUNTER17]  = { "mhpmcounter17",  mctr,    read_hpmcounter,
5398621f35bbSAtish Patra                              write_mhpmcounter                         },
5399621f35bbSAtish Patra     [CSR_MHPMCOUNTER18]  = { "mhpmcounter18",  mctr,    read_hpmcounter,
5400621f35bbSAtish Patra                              write_mhpmcounter                         },
5401621f35bbSAtish Patra     [CSR_MHPMCOUNTER19]  = { "mhpmcounter19",  mctr,    read_hpmcounter,
5402621f35bbSAtish Patra                              write_mhpmcounter                         },
5403621f35bbSAtish Patra     [CSR_MHPMCOUNTER20]  = { "mhpmcounter20",  mctr,    read_hpmcounter,
5404621f35bbSAtish Patra                              write_mhpmcounter                         },
5405621f35bbSAtish Patra     [CSR_MHPMCOUNTER21]  = { "mhpmcounter21",  mctr,    read_hpmcounter,
5406621f35bbSAtish Patra                              write_mhpmcounter                         },
5407621f35bbSAtish Patra     [CSR_MHPMCOUNTER22]  = { "mhpmcounter22",  mctr,    read_hpmcounter,
5408621f35bbSAtish Patra                              write_mhpmcounter                         },
5409621f35bbSAtish Patra     [CSR_MHPMCOUNTER23]  = { "mhpmcounter23",  mctr,    read_hpmcounter,
5410621f35bbSAtish Patra                              write_mhpmcounter                         },
5411621f35bbSAtish Patra     [CSR_MHPMCOUNTER24]  = { "mhpmcounter24",  mctr,    read_hpmcounter,
5412621f35bbSAtish Patra                              write_mhpmcounter                         },
54138ceac5dcSBin Meng     [CSR_MHPMCOUNTER25]  = { "mhpmcounter25",  mctr,    read_hpmcounter,
5414b54a84c1SKaiwen Xue                              write_mhpmcounter                         },
5415b54a84c1SKaiwen Xue     [CSR_MHPMCOUNTER26]  = { "mhpmcounter26",  mctr,    read_hpmcounter,
5416b54a84c1SKaiwen Xue                              write_mhpmcounter                         },
5417b54a84c1SKaiwen Xue     [CSR_MHPMCOUNTER27]  = { "mhpmcounter27",  mctr,    read_hpmcounter,
5418b54a84c1SKaiwen Xue                              write_mhpmcounter                         },
5419b54a84c1SKaiwen Xue     [CSR_MHPMCOUNTER28]  = { "mhpmcounter28",  mctr,    read_hpmcounter,
5420b54a84c1SKaiwen Xue                              write_mhpmcounter                         },
5421be470e59SAtish Patra     [CSR_MHPMCOUNTER29]  = { "mhpmcounter29",  mctr,    read_hpmcounter,
5422f0551560SAtish Patra                              write_mhpmcounter                         },
5423f0551560SAtish Patra     [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  mctr,    read_hpmcounter,
5424be470e59SAtish Patra                              write_mhpmcounter                         },
5425f0551560SAtish Patra     [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  mctr,    read_hpmcounter,
5426f0551560SAtish Patra                              write_mhpmcounter                         },
5427be470e59SAtish Patra 
5428f0551560SAtish Patra     [CSR_MCOUNTINHIBIT]  = { "mcountinhibit",  any, read_mcountinhibit,
5429f0551560SAtish Patra                              write_mcountinhibit,
5430be470e59SAtish Patra                              .min_priv_ver = PRIV_VERSION_1_11_0       },
5431f0551560SAtish Patra 
5432f0551560SAtish Patra     [CSR_MCYCLECFG]      = { "mcyclecfg",   smcntrpmf, read_mcyclecfg,
5433be470e59SAtish Patra                              write_mcyclecfg,
5434f0551560SAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0       },
5435f0551560SAtish Patra     [CSR_MINSTRETCFG]    = { "minstretcfg", smcntrpmf, read_minstretcfg,
5436be470e59SAtish Patra                              write_minstretcfg,
5437f0551560SAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0       },
5438f0551560SAtish Patra 
5439be470e59SAtish Patra     [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_mhpmevent,
5440f0551560SAtish Patra                              write_mhpmevent                           },
5441f0551560SAtish Patra     [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_mhpmevent,
5442be470e59SAtish Patra                              write_mhpmevent                           },
5443f0551560SAtish Patra     [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_mhpmevent,
5444f0551560SAtish Patra                              write_mhpmevent                           },
5445be470e59SAtish Patra     [CSR_MHPMEVENT6]     = { "mhpmevent6",     any,    read_mhpmevent,
5446f0551560SAtish Patra                              write_mhpmevent                           },
5447f0551560SAtish Patra     [CSR_MHPMEVENT7]     = { "mhpmevent7",     any,    read_mhpmevent,
5448be470e59SAtish Patra                              write_mhpmevent                           },
5449f0551560SAtish Patra     [CSR_MHPMEVENT8]     = { "mhpmevent8",     any,    read_mhpmevent,
5450f0551560SAtish Patra                              write_mhpmevent                           },
5451be470e59SAtish Patra     [CSR_MHPMEVENT9]     = { "mhpmevent9",     any,    read_mhpmevent,
5452f0551560SAtish Patra                              write_mhpmevent                           },
5453f0551560SAtish Patra     [CSR_MHPMEVENT10]    = { "mhpmevent10",    any,    read_mhpmevent,
5454be470e59SAtish Patra                              write_mhpmevent                           },
5455f0551560SAtish Patra     [CSR_MHPMEVENT11]    = { "mhpmevent11",    any,    read_mhpmevent,
5456f0551560SAtish Patra                              write_mhpmevent                           },
5457be470e59SAtish Patra     [CSR_MHPMEVENT12]    = { "mhpmevent12",    any,    read_mhpmevent,
5458f0551560SAtish Patra                              write_mhpmevent                           },
5459f0551560SAtish Patra     [CSR_MHPMEVENT13]    = { "mhpmevent13",    any,    read_mhpmevent,
5460be470e59SAtish Patra                              write_mhpmevent                           },
5461f0551560SAtish Patra     [CSR_MHPMEVENT14]    = { "mhpmevent14",    any,    read_mhpmevent,
5462f0551560SAtish Patra                              write_mhpmevent                           },
5463be470e59SAtish Patra     [CSR_MHPMEVENT15]    = { "mhpmevent15",    any,    read_mhpmevent,
5464f0551560SAtish Patra                              write_mhpmevent                           },
5465f0551560SAtish Patra     [CSR_MHPMEVENT16]    = { "mhpmevent16",    any,    read_mhpmevent,
5466be470e59SAtish Patra                              write_mhpmevent                           },
5467f0551560SAtish Patra     [CSR_MHPMEVENT17]    = { "mhpmevent17",    any,    read_mhpmevent,
5468f0551560SAtish Patra                              write_mhpmevent                           },
5469be470e59SAtish Patra     [CSR_MHPMEVENT18]    = { "mhpmevent18",    any,    read_mhpmevent,
5470f0551560SAtish Patra                              write_mhpmevent                           },
5471f0551560SAtish Patra     [CSR_MHPMEVENT19]    = { "mhpmevent19",    any,    read_mhpmevent,
5472be470e59SAtish Patra                              write_mhpmevent                           },
5473f0551560SAtish Patra     [CSR_MHPMEVENT20]    = { "mhpmevent20",    any,    read_mhpmevent,
5474f0551560SAtish Patra                              write_mhpmevent                           },
5475be470e59SAtish Patra     [CSR_MHPMEVENT21]    = { "mhpmevent21",    any,    read_mhpmevent,
5476f0551560SAtish Patra                              write_mhpmevent                           },
5477f0551560SAtish Patra     [CSR_MHPMEVENT22]    = { "mhpmevent22",    any,    read_mhpmevent,
5478be470e59SAtish Patra                              write_mhpmevent                           },
5479f0551560SAtish Patra     [CSR_MHPMEVENT23]    = { "mhpmevent23",    any,    read_mhpmevent,
5480f0551560SAtish Patra                              write_mhpmevent                           },
5481be470e59SAtish Patra     [CSR_MHPMEVENT24]    = { "mhpmevent24",    any,    read_mhpmevent,
5482f0551560SAtish Patra                              write_mhpmevent                           },
5483f0551560SAtish Patra     [CSR_MHPMEVENT25]    = { "mhpmevent25",    any,    read_mhpmevent,
5484be470e59SAtish Patra                              write_mhpmevent                           },
5485f0551560SAtish Patra     [CSR_MHPMEVENT26]    = { "mhpmevent26",    any,    read_mhpmevent,
5486f0551560SAtish Patra                              write_mhpmevent                           },
5487be470e59SAtish Patra     [CSR_MHPMEVENT27]    = { "mhpmevent27",    any,    read_mhpmevent,
5488f0551560SAtish Patra                              write_mhpmevent                           },
5489f0551560SAtish Patra     [CSR_MHPMEVENT28]    = { "mhpmevent28",    any,    read_mhpmevent,
5490be470e59SAtish Patra                              write_mhpmevent                           },
5491f0551560SAtish Patra     [CSR_MHPMEVENT29]    = { "mhpmevent29",    any,    read_mhpmevent,
5492f0551560SAtish Patra                              write_mhpmevent                           },
5493be470e59SAtish Patra     [CSR_MHPMEVENT30]    = { "mhpmevent30",    any,    read_mhpmevent,
5494f0551560SAtish Patra                              write_mhpmevent                           },
5495f0551560SAtish Patra     [CSR_MHPMEVENT31]    = { "mhpmevent31",    any,    read_mhpmevent,
5496be470e59SAtish Patra                              write_mhpmevent                           },
5497f0551560SAtish Patra 
5498f0551560SAtish Patra     [CSR_MCYCLECFGH]     = { "mcyclecfgh",   smcntrpmf_32, read_mcyclecfgh,
5499be470e59SAtish Patra                              write_mcyclecfgh,
5500f0551560SAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5501f0551560SAtish Patra     [CSR_MINSTRETCFGH]   = { "minstretcfgh", smcntrpmf_32, read_minstretcfgh,
5502be470e59SAtish Patra                              write_minstretcfgh,
5503f0551560SAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5504f0551560SAtish Patra 
5505be470e59SAtish Patra     [CSR_MHPMEVENT3H]    = { "mhpmevent3h",    sscofpmf_32,  read_mhpmeventh,
5506f0551560SAtish Patra                              write_mhpmeventh,
5507f0551560SAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
550814664483SAtish Patra     [CSR_MHPMEVENT4H]    = { "mhpmevent4h",    sscofpmf_32,  read_mhpmeventh,
5509621f35bbSAtish Patra                              write_mhpmeventh,
5510621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5511621f35bbSAtish Patra     [CSR_MHPMEVENT5H]    = { "mhpmevent5h",    sscofpmf_32,  read_mhpmeventh,
5512621f35bbSAtish Patra                              write_mhpmeventh,
5513621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5514621f35bbSAtish Patra     [CSR_MHPMEVENT6H]    = { "mhpmevent6h",    sscofpmf_32,  read_mhpmeventh,
5515621f35bbSAtish Patra                              write_mhpmeventh,
5516621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5517621f35bbSAtish Patra     [CSR_MHPMEVENT7H]    = { "mhpmevent7h",    sscofpmf_32,  read_mhpmeventh,
5518621f35bbSAtish Patra                              write_mhpmeventh,
5519621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5520621f35bbSAtish Patra     [CSR_MHPMEVENT8H]    = { "mhpmevent8h",    sscofpmf_32,  read_mhpmeventh,
5521621f35bbSAtish Patra                              write_mhpmeventh,
5522621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5523621f35bbSAtish Patra     [CSR_MHPMEVENT9H]    = { "mhpmevent9h",    sscofpmf_32,  read_mhpmeventh,
5524621f35bbSAtish Patra                              write_mhpmeventh,
5525621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5526621f35bbSAtish Patra     [CSR_MHPMEVENT10H]   = { "mhpmevent10h",    sscofpmf_32,  read_mhpmeventh,
5527621f35bbSAtish Patra                              write_mhpmeventh,
5528621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5529621f35bbSAtish Patra     [CSR_MHPMEVENT11H]   = { "mhpmevent11h",    sscofpmf_32,  read_mhpmeventh,
5530621f35bbSAtish Patra                              write_mhpmeventh,
5531621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5532621f35bbSAtish Patra     [CSR_MHPMEVENT12H]   = { "mhpmevent12h",    sscofpmf_32,  read_mhpmeventh,
5533621f35bbSAtish Patra                              write_mhpmeventh,
5534621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5535621f35bbSAtish Patra     [CSR_MHPMEVENT13H]   = { "mhpmevent13h",    sscofpmf_32,  read_mhpmeventh,
5536621f35bbSAtish Patra                              write_mhpmeventh,
5537621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
55388ceac5dcSBin Meng     [CSR_MHPMEVENT14H]   = { "mhpmevent14h",    sscofpmf_32,  read_mhpmeventh,
5539621f35bbSAtish Patra                              write_mhpmeventh,
5540621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5541621f35bbSAtish Patra     [CSR_MHPMEVENT15H]   = { "mhpmevent15h",    sscofpmf_32,  read_mhpmeventh,
5542621f35bbSAtish Patra                              write_mhpmeventh,
5543621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5544621f35bbSAtish Patra     [CSR_MHPMEVENT16H]   = { "mhpmevent16h",    sscofpmf_32,  read_mhpmeventh,
5545621f35bbSAtish Patra                              write_mhpmeventh,
5546621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5547621f35bbSAtish Patra     [CSR_MHPMEVENT17H]   = { "mhpmevent17h",    sscofpmf_32,  read_mhpmeventh,
5548621f35bbSAtish Patra                              write_mhpmeventh,
5549621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5550621f35bbSAtish Patra     [CSR_MHPMEVENT18H]   = { "mhpmevent18h",    sscofpmf_32,  read_mhpmeventh,
5551621f35bbSAtish Patra                              write_mhpmeventh,
5552621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5553621f35bbSAtish Patra     [CSR_MHPMEVENT19H]   = { "mhpmevent19h",    sscofpmf_32,  read_mhpmeventh,
5554621f35bbSAtish Patra                              write_mhpmeventh,
5555621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5556621f35bbSAtish Patra     [CSR_MHPMEVENT20H]   = { "mhpmevent20h",    sscofpmf_32,  read_mhpmeventh,
5557621f35bbSAtish Patra                              write_mhpmeventh,
5558621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5559621f35bbSAtish Patra     [CSR_MHPMEVENT21H]   = { "mhpmevent21h",    sscofpmf_32,  read_mhpmeventh,
5560621f35bbSAtish Patra                              write_mhpmeventh,
5561621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5562621f35bbSAtish Patra     [CSR_MHPMEVENT22H]   = { "mhpmevent22h",    sscofpmf_32,  read_mhpmeventh,
5563621f35bbSAtish Patra                              write_mhpmeventh,
5564621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5565621f35bbSAtish Patra     [CSR_MHPMEVENT23H]   = { "mhpmevent23h",    sscofpmf_32,  read_mhpmeventh,
5566621f35bbSAtish Patra                              write_mhpmeventh,
5567621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5568621f35bbSAtish Patra     [CSR_MHPMEVENT24H]   = { "mhpmevent24h",    sscofpmf_32,  read_mhpmeventh,
5569621f35bbSAtish Patra                              write_mhpmeventh,
5570621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5571621f35bbSAtish Patra     [CSR_MHPMEVENT25H]   = { "mhpmevent25h",    sscofpmf_32,  read_mhpmeventh,
5572621f35bbSAtish Patra                              write_mhpmeventh,
5573621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5574621f35bbSAtish Patra     [CSR_MHPMEVENT26H]   = { "mhpmevent26h",    sscofpmf_32,  read_mhpmeventh,
5575621f35bbSAtish Patra                              write_mhpmeventh,
5576621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5577621f35bbSAtish Patra     [CSR_MHPMEVENT27H]   = { "mhpmevent27h",    sscofpmf_32,  read_mhpmeventh,
5578621f35bbSAtish Patra                              write_mhpmeventh,
5579621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5580621f35bbSAtish Patra     [CSR_MHPMEVENT28H]   = { "mhpmevent28h",    sscofpmf_32,  read_mhpmeventh,
5581621f35bbSAtish Patra                              write_mhpmeventh,
5582621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5583621f35bbSAtish Patra     [CSR_MHPMEVENT29H]   = { "mhpmevent29h",    sscofpmf_32,  read_mhpmeventh,
5584621f35bbSAtish Patra                              write_mhpmeventh,
5585621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5586621f35bbSAtish Patra     [CSR_MHPMEVENT30H]   = { "mhpmevent30h",    sscofpmf_32,  read_mhpmeventh,
5587621f35bbSAtish Patra                              write_mhpmeventh,
5588621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5589621f35bbSAtish Patra     [CSR_MHPMEVENT31H]   = { "mhpmevent31h",    sscofpmf_32,  read_mhpmeventh,
5590621f35bbSAtish Patra                              write_mhpmeventh,
5591621f35bbSAtish Patra                              .min_priv_ver = PRIV_VERSION_1_12_0        },
5592621f35bbSAtish Patra 
5593621f35bbSAtish Patra     [CSR_HPMCOUNTER3H]   = { "hpmcounter3h",   ctr32,  read_hpmcounterh },
5594621f35bbSAtish Patra     [CSR_HPMCOUNTER4H]   = { "hpmcounter4h",   ctr32,  read_hpmcounterh },
5595621f35bbSAtish Patra     [CSR_HPMCOUNTER5H]   = { "hpmcounter5h",   ctr32,  read_hpmcounterh },
5596621f35bbSAtish Patra     [CSR_HPMCOUNTER6H]   = { "hpmcounter6h",   ctr32,  read_hpmcounterh },
5597f0551560SAtish Patra     [CSR_HPMCOUNTER7H]   = { "hpmcounter7h",   ctr32,  read_hpmcounterh },
5598f0551560SAtish Patra     [CSR_HPMCOUNTER8H]   = { "hpmcounter8h",   ctr32,  read_hpmcounterh },
559914664483SAtish Patra     [CSR_HPMCOUNTER9H]   = { "hpmcounter9h",   ctr32,  read_hpmcounterh },
5600c7b95171SMichael Clark     [CSR_HPMCOUNTER10H]  = { "hpmcounter10h",  ctr32,  read_hpmcounterh },
5601c7b95171SMichael Clark     [CSR_HPMCOUNTER11H]  = { "hpmcounter11h",  ctr32,  read_hpmcounterh },
5602     [CSR_HPMCOUNTER12H]  = { "hpmcounter12h",  ctr32,  read_hpmcounterh },
5603     [CSR_HPMCOUNTER13H]  = { "hpmcounter13h",  ctr32,  read_hpmcounterh },
5604     [CSR_HPMCOUNTER14H]  = { "hpmcounter14h",  ctr32,  read_hpmcounterh },
5605     [CSR_HPMCOUNTER15H]  = { "hpmcounter15h",  ctr32,  read_hpmcounterh },
5606     [CSR_HPMCOUNTER16H]  = { "hpmcounter16h",  ctr32,  read_hpmcounterh },
5607     [CSR_HPMCOUNTER17H]  = { "hpmcounter17h",  ctr32,  read_hpmcounterh },
5608     [CSR_HPMCOUNTER18H]  = { "hpmcounter18h",  ctr32,  read_hpmcounterh },
5609     [CSR_HPMCOUNTER19H]  = { "hpmcounter19h",  ctr32,  read_hpmcounterh },
5610     [CSR_HPMCOUNTER20H]  = { "hpmcounter20h",  ctr32,  read_hpmcounterh },
5611     [CSR_HPMCOUNTER21H]  = { "hpmcounter21h",  ctr32,  read_hpmcounterh },
5612     [CSR_HPMCOUNTER22H]  = { "hpmcounter22h",  ctr32,  read_hpmcounterh },
5613     [CSR_HPMCOUNTER23H]  = { "hpmcounter23h",  ctr32,  read_hpmcounterh },
5614     [CSR_HPMCOUNTER24H]  = { "hpmcounter24h",  ctr32,  read_hpmcounterh },
5615     [CSR_HPMCOUNTER25H]  = { "hpmcounter25h",  ctr32,  read_hpmcounterh },
5616     [CSR_HPMCOUNTER26H]  = { "hpmcounter26h",  ctr32,  read_hpmcounterh },
5617     [CSR_HPMCOUNTER27H]  = { "hpmcounter27h",  ctr32,  read_hpmcounterh },
5618     [CSR_HPMCOUNTER28H]  = { "hpmcounter28h",  ctr32,  read_hpmcounterh },
5619     [CSR_HPMCOUNTER29H]  = { "hpmcounter29h",  ctr32,  read_hpmcounterh },
5620     [CSR_HPMCOUNTER30H]  = { "hpmcounter30h",  ctr32,  read_hpmcounterh },
5621     [CSR_HPMCOUNTER31H]  = { "hpmcounter31h",  ctr32,  read_hpmcounterh },
5622 
5623     [CSR_MHPMCOUNTER3H]  = { "mhpmcounter3h",  mctr32,  read_hpmcounterh,
5624                              write_mhpmcounterh                         },
5625     [CSR_MHPMCOUNTER4H]  = { "mhpmcounter4h",  mctr32,  read_hpmcounterh,
5626                              write_mhpmcounterh                         },
5627     [CSR_MHPMCOUNTER5H]  = { "mhpmcounter5h",  mctr32,  read_hpmcounterh,
5628                              write_mhpmcounterh                         },
5629     [CSR_MHPMCOUNTER6H]  = { "mhpmcounter6h",  mctr32,  read_hpmcounterh,
5630                              write_mhpmcounterh                         },
5631     [CSR_MHPMCOUNTER7H]  = { "mhpmcounter7h",  mctr32,  read_hpmcounterh,
5632                              write_mhpmcounterh                         },
5633     [CSR_MHPMCOUNTER8H]  = { "mhpmcounter8h",  mctr32,  read_hpmcounterh,
5634                              write_mhpmcounterh                         },
5635     [CSR_MHPMCOUNTER9H]  = { "mhpmcounter9h",  mctr32,  read_hpmcounterh,
5636                              write_mhpmcounterh                         },
5637     [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32,  read_hpmcounterh,
5638                              write_mhpmcounterh                         },
5639     [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32,  read_hpmcounterh,
5640                              write_mhpmcounterh                         },
5641     [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32,  read_hpmcounterh,
5642                              write_mhpmcounterh                         },
5643     [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32,  read_hpmcounterh,
5644                              write_mhpmcounterh                         },
5645     [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32,  read_hpmcounterh,
5646                              write_mhpmcounterh                         },
5647     [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32,  read_hpmcounterh,
5648                              write_mhpmcounterh                         },
5649     [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32,  read_hpmcounterh,
5650                              write_mhpmcounterh                         },
5651     [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32,  read_hpmcounterh,
5652                              write_mhpmcounterh                         },
5653     [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32,  read_hpmcounterh,
5654                              write_mhpmcounterh                         },
5655     [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32,  read_hpmcounterh,
5656                              write_mhpmcounterh                         },
5657     [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32,  read_hpmcounterh,
5658                              write_mhpmcounterh                         },
5659     [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32,  read_hpmcounterh,
5660                              write_mhpmcounterh                         },
5661     [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32,  read_hpmcounterh,
5662                              write_mhpmcounterh                         },
5663     [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32,  read_hpmcounterh,
5664                              write_mhpmcounterh                         },
5665     [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32,  read_hpmcounterh,
5666                              write_mhpmcounterh                         },
5667     [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32,  read_hpmcounterh,
5668                              write_mhpmcounterh                         },
5669     [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32,  read_hpmcounterh,
5670                              write_mhpmcounterh                         },
5671     [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32,  read_hpmcounterh,
5672                              write_mhpmcounterh                         },
5673     [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32,  read_hpmcounterh,
5674                              write_mhpmcounterh                         },
5675     [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32,  read_hpmcounterh,
5676                              write_mhpmcounterh                         },
5677     [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32,  read_hpmcounterh,
5678                              write_mhpmcounterh                         },
5679     [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32,  read_hpmcounterh,
5680                              write_mhpmcounterh                         },
5681     [CSR_SCOUNTOVF]      = { "scountovf", sscofpmf,  read_scountovf,
5682                              .min_priv_ver = PRIV_VERSION_1_12_0 },
5683 
5684 #endif /* !CONFIG_USER_ONLY */
5685 };
5686