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