]> git.proxmox.com Git - mirror_qemu.git/blame - target/riscv/csr.c
target/riscv: Implement AIA CSRs for 64 local interrupts on RV32
[mirror_qemu.git] / target / riscv / csr.c
CommitLineData
c7b95171
MC
1/*
2 * RISC-V Control and Status Registers.
3 *
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2017-2018 SiFive, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2 or later, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "qemu/osdep.h"
21#include "qemu/log.h"
22#include "cpu.h"
23#include "qemu/main-loop.h"
24#include "exec/exec-all.h"
25
c7b95171
MC
26/* CSR function table public API */
27void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
28{
29 *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
30}
31
32void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
33{
34 csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
35}
36
a88365c1 37/* Predicates */
0e62f92e 38static RISCVException fs(CPURISCVState *env, int csrno)
a88365c1
MC
39{
40#if !defined(CONFIG_USER_ONLY)
b345b480 41 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
0e62f92e 42 return RISCV_EXCP_ILLEGAL_INST;
a88365c1
MC
43 }
44#endif
0e62f92e 45 return RISCV_EXCP_NONE;
a88365c1
MC
46}
47
0e62f92e 48static RISCVException vs(CPURISCVState *env, int csrno)
8e3a1f18 49{
b4a99d40
FC
50 CPUState *cs = env_cpu(env);
51 RISCVCPU *cpu = RISCV_CPU(cs);
52
53 if (env->misa_ext & RVV ||
32e579b8 54 cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
6bc3dfa9
FC
55#if !defined(CONFIG_USER_ONLY)
56 if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
57 return RISCV_EXCP_ILLEGAL_INST;
58 }
59#endif
0e62f92e 60 return RISCV_EXCP_NONE;
8e3a1f18 61 }
0e62f92e 62 return RISCV_EXCP_ILLEGAL_INST;
8e3a1f18
LZ
63}
64
0e62f92e 65static RISCVException ctr(CPURISCVState *env, int csrno)
a88365c1
MC
66{
67#if !defined(CONFIG_USER_ONLY)
0a13a5b8
AF
68 CPUState *cs = env_cpu(env);
69 RISCVCPU *cpu = RISCV_CPU(cs);
0a13a5b8
AF
70
71 if (!cpu->cfg.ext_counters) {
72 /* The Counters extensions is not enabled */
0e62f92e 73 return RISCV_EXCP_ILLEGAL_INST;
0a13a5b8 74 }
e39a8320
AF
75
76 if (riscv_cpu_virt_enabled(env)) {
77 switch (csrno) {
78 case CSR_CYCLE:
db70794e
BM
79 if (!get_field(env->hcounteren, COUNTEREN_CY) &&
80 get_field(env->mcounteren, COUNTEREN_CY)) {
0e62f92e 81 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
e39a8320
AF
82 }
83 break;
84 case CSR_TIME:
db70794e
BM
85 if (!get_field(env->hcounteren, COUNTEREN_TM) &&
86 get_field(env->mcounteren, COUNTEREN_TM)) {
0e62f92e 87 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
e39a8320
AF
88 }
89 break;
90 case CSR_INSTRET:
db70794e
BM
91 if (!get_field(env->hcounteren, COUNTEREN_IR) &&
92 get_field(env->mcounteren, COUNTEREN_IR)) {
0e62f92e 93 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
e39a8320
AF
94 }
95 break;
96 case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
97 if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
98 get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
0e62f92e 99 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
e39a8320
AF
100 }
101 break;
8987cdc4 102 }
db23e5d9 103 if (riscv_cpu_mxl(env) == MXL_RV32) {
8987cdc4
AF
104 switch (csrno) {
105 case CSR_CYCLEH:
db70794e
BM
106 if (!get_field(env->hcounteren, COUNTEREN_CY) &&
107 get_field(env->mcounteren, COUNTEREN_CY)) {
0e62f92e 108 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
8987cdc4
AF
109 }
110 break;
111 case CSR_TIMEH:
db70794e
BM
112 if (!get_field(env->hcounteren, COUNTEREN_TM) &&
113 get_field(env->mcounteren, COUNTEREN_TM)) {
0e62f92e 114 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
8987cdc4
AF
115 }
116 break;
117 case CSR_INSTRETH:
db70794e
BM
118 if (!get_field(env->hcounteren, COUNTEREN_IR) &&
119 get_field(env->mcounteren, COUNTEREN_IR)) {
0e62f92e 120 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
8987cdc4
AF
121 }
122 break;
123 case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
124 if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
125 get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
0e62f92e 126 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
8987cdc4
AF
127 }
128 break;
e39a8320 129 }
e39a8320
AF
130 }
131 }
a88365c1 132#endif
0e62f92e 133 return RISCV_EXCP_NONE;
a88365c1
MC
134}
135
0e62f92e 136static RISCVException ctr32(CPURISCVState *env, int csrno)
8987cdc4 137{
db23e5d9 138 if (riscv_cpu_mxl(env) != MXL_RV32) {
0e62f92e 139 return RISCV_EXCP_ILLEGAL_INST;
8987cdc4
AF
140 }
141
142 return ctr(env, csrno);
143}
144
a88365c1 145#if !defined(CONFIG_USER_ONLY)
0e62f92e 146static RISCVException any(CPURISCVState *env, int csrno)
a88365c1 147{
0e62f92e 148 return RISCV_EXCP_NONE;
a88365c1
MC
149}
150
0e62f92e 151static RISCVException any32(CPURISCVState *env, int csrno)
8987cdc4 152{
db23e5d9 153 if (riscv_cpu_mxl(env) != MXL_RV32) {
0e62f92e 154 return RISCV_EXCP_ILLEGAL_INST;
8987cdc4
AF
155 }
156
157 return any(env, csrno);
158
159}
160
d028ac75
AP
161static int aia_any32(CPURISCVState *env, int csrno)
162{
163 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
164 return RISCV_EXCP_ILLEGAL_INST;
165 }
166
167 return any32(env, csrno);
168}
169
0e62f92e 170static RISCVException smode(CPURISCVState *env, int csrno)
a88365c1 171{
0e62f92e
AF
172 if (riscv_has_ext(env, RVS)) {
173 return RISCV_EXCP_NONE;
174 }
175
176 return RISCV_EXCP_ILLEGAL_INST;
a88365c1
MC
177}
178
d028ac75
AP
179static int smode32(CPURISCVState *env, int csrno)
180{
181 if (riscv_cpu_mxl(env) != MXL_RV32) {
182 return RISCV_EXCP_ILLEGAL_INST;
183 }
184
185 return smode(env, csrno);
186}
187
188static int aia_smode32(CPURISCVState *env, int csrno)
189{
190 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
191 return RISCV_EXCP_ILLEGAL_INST;
192 }
193
194 return smode32(env, csrno);
195}
196
0e62f92e 197static RISCVException hmode(CPURISCVState *env, int csrno)
ff2cc129
AF
198{
199 if (riscv_has_ext(env, RVS) &&
200 riscv_has_ext(env, RVH)) {
201 /* Hypervisor extension is supported */
202 if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
203 env->priv == PRV_M) {
0e62f92e 204 return RISCV_EXCP_NONE;
e39a8320 205 } else {
0e62f92e 206 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
ff2cc129
AF
207 }
208 }
209
0e62f92e 210 return RISCV_EXCP_ILLEGAL_INST;
ff2cc129
AF
211}
212
0e62f92e 213static RISCVException hmode32(CPURISCVState *env, int csrno)
8987cdc4 214{
db23e5d9 215 if (riscv_cpu_mxl(env) != MXL_RV32) {
dceecac8 216 if (!riscv_cpu_virt_enabled(env)) {
d6f20dac
AF
217 return RISCV_EXCP_ILLEGAL_INST;
218 } else {
219 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
220 }
8987cdc4
AF
221 }
222
223 return hmode(env, csrno);
224
225}
226
4bbe8033
AB
227/* Checks if PointerMasking registers could be accessed */
228static RISCVException pointer_masking(CPURISCVState *env, int csrno)
229{
230 /* Check if j-ext is present */
231 if (riscv_has_ext(env, RVJ)) {
232 return RISCV_EXCP_NONE;
233 }
234 return RISCV_EXCP_ILLEGAL_INST;
235}
236
d028ac75
AP
237static int aia_hmode32(CPURISCVState *env, int csrno)
238{
239 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
240 return RISCV_EXCP_ILLEGAL_INST;
241 }
242
243 return hmode32(env, csrno);
244}
245
0e62f92e 246static RISCVException pmp(CPURISCVState *env, int csrno)
a88365c1 247{
0e62f92e
AF
248 if (riscv_feature(env, RISCV_FEATURE_PMP)) {
249 return RISCV_EXCP_NONE;
250 }
251
252 return RISCV_EXCP_ILLEGAL_INST;
a88365c1 253}
2582a95c
HW
254
255static RISCVException epmp(CPURISCVState *env, int csrno)
256{
257 if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
258 return RISCV_EXCP_NONE;
259 }
260
261 return RISCV_EXCP_ILLEGAL_INST;
262}
a88365c1
MC
263#endif
264
c7b95171 265/* User Floating-Point CSRs */
605def6e
AF
266static RISCVException read_fflags(CPURISCVState *env, int csrno,
267 target_ulong *val)
c7b95171 268{
fb738839 269 *val = riscv_cpu_get_fflags(env);
605def6e 270 return RISCV_EXCP_NONE;
c7b95171
MC
271}
272
605def6e
AF
273static RISCVException write_fflags(CPURISCVState *env, int csrno,
274 target_ulong val)
c7b95171
MC
275{
276#if !defined(CONFIG_USER_ONLY)
c7b95171
MC
277 env->mstatus |= MSTATUS_FS;
278#endif
fb738839 279 riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
605def6e 280 return RISCV_EXCP_NONE;
c7b95171
MC
281}
282
605def6e
AF
283static RISCVException read_frm(CPURISCVState *env, int csrno,
284 target_ulong *val)
c7b95171 285{
c7b95171 286 *val = env->frm;
605def6e 287 return RISCV_EXCP_NONE;
c7b95171
MC
288}
289
605def6e
AF
290static RISCVException write_frm(CPURISCVState *env, int csrno,
291 target_ulong val)
c7b95171
MC
292{
293#if !defined(CONFIG_USER_ONLY)
c7b95171
MC
294 env->mstatus |= MSTATUS_FS;
295#endif
296 env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
605def6e 297 return RISCV_EXCP_NONE;
c7b95171
MC
298}
299
605def6e
AF
300static RISCVException read_fcsr(CPURISCVState *env, int csrno,
301 target_ulong *val)
c7b95171 302{
fb738839 303 *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
c7b95171 304 | (env->frm << FSR_RD_SHIFT);
605def6e 305 return RISCV_EXCP_NONE;
c7b95171
MC
306}
307
605def6e
AF
308static RISCVException write_fcsr(CPURISCVState *env, int csrno,
309 target_ulong val)
c7b95171
MC
310{
311#if !defined(CONFIG_USER_ONLY)
c7b95171
MC
312 env->mstatus |= MSTATUS_FS;
313#endif
314 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
fb738839 315 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
605def6e 316 return RISCV_EXCP_NONE;
c7b95171
MC
317}
318
605def6e
AF
319static RISCVException read_vtype(CPURISCVState *env, int csrno,
320 target_ulong *val)
8e3a1f18 321{
d96a271a
LZ
322 uint64_t vill;
323 switch (env->xl) {
324 case MXL_RV32:
325 vill = (uint32_t)env->vill << 31;
326 break;
327 case MXL_RV64:
328 vill = (uint64_t)env->vill << 63;
329 break;
330 default:
331 g_assert_not_reached();
332 }
333 *val = (target_ulong)vill | env->vtype;
605def6e 334 return RISCV_EXCP_NONE;
8e3a1f18
LZ
335}
336
605def6e
AF
337static RISCVException read_vl(CPURISCVState *env, int csrno,
338 target_ulong *val)
8e3a1f18
LZ
339{
340 *val = env->vl;
605def6e 341 return RISCV_EXCP_NONE;
8e3a1f18
LZ
342}
343
2e565054
GH
344static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
345{
346 *val = env_archcpu(env)->cfg.vlen >> 3;
347 return RISCV_EXCP_NONE;
348}
349
605def6e
AF
350static RISCVException read_vxrm(CPURISCVState *env, int csrno,
351 target_ulong *val)
8e3a1f18
LZ
352{
353 *val = env->vxrm;
605def6e 354 return RISCV_EXCP_NONE;
8e3a1f18
LZ
355}
356
605def6e
AF
357static RISCVException write_vxrm(CPURISCVState *env, int csrno,
358 target_ulong val)
8e3a1f18 359{
61b4b69d
LZ
360#if !defined(CONFIG_USER_ONLY)
361 env->mstatus |= MSTATUS_VS;
362#endif
8e3a1f18 363 env->vxrm = val;
605def6e 364 return RISCV_EXCP_NONE;
8e3a1f18
LZ
365}
366
605def6e
AF
367static RISCVException read_vxsat(CPURISCVState *env, int csrno,
368 target_ulong *val)
8e3a1f18
LZ
369{
370 *val = env->vxsat;
605def6e 371 return RISCV_EXCP_NONE;
8e3a1f18
LZ
372}
373
605def6e
AF
374static RISCVException write_vxsat(CPURISCVState *env, int csrno,
375 target_ulong val)
8e3a1f18 376{
61b4b69d
LZ
377#if !defined(CONFIG_USER_ONLY)
378 env->mstatus |= MSTATUS_VS;
379#endif
8e3a1f18 380 env->vxsat = val;
605def6e 381 return RISCV_EXCP_NONE;
8e3a1f18
LZ
382}
383
605def6e
AF
384static RISCVException read_vstart(CPURISCVState *env, int csrno,
385 target_ulong *val)
8e3a1f18
LZ
386{
387 *val = env->vstart;
605def6e 388 return RISCV_EXCP_NONE;
8e3a1f18
LZ
389}
390
605def6e
AF
391static RISCVException write_vstart(CPURISCVState *env, int csrno,
392 target_ulong val)
8e3a1f18 393{
61b4b69d
LZ
394#if !defined(CONFIG_USER_ONLY)
395 env->mstatus |= MSTATUS_VS;
396#endif
f714361e
FC
397 /*
398 * The vstart CSR is defined to have only enough writable bits
399 * to hold the largest element index, i.e. lg2(VLEN) bits.
400 */
401 env->vstart = val & ~(~0ULL << ctzl(env_archcpu(env)->cfg.vlen));
605def6e 402 return RISCV_EXCP_NONE;
8e3a1f18
LZ
403}
404
4594fa5a
LZ
405static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
406{
407 *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
408 return RISCV_EXCP_NONE;
409}
410
411static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
412{
413#if !defined(CONFIG_USER_ONLY)
414 env->mstatus |= MSTATUS_VS;
415#endif
416 env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
417 env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
418 return RISCV_EXCP_NONE;
419}
420
c7b95171 421/* User Timers and Counters */
605def6e
AF
422static RISCVException read_instret(CPURISCVState *env, int csrno,
423 target_ulong *val)
c7b95171 424{
c7b95171 425#if !defined(CONFIG_USER_ONLY)
740b1759 426 if (icount_enabled()) {
8191d368 427 *val = icount_get();
c7b95171
MC
428 } else {
429 *val = cpu_get_host_ticks();
430 }
431#else
432 *val = cpu_get_host_ticks();
433#endif
605def6e 434 return RISCV_EXCP_NONE;
c7b95171
MC
435}
436
605def6e
AF
437static RISCVException read_instreth(CPURISCVState *env, int csrno,
438 target_ulong *val)
c7b95171 439{
c7b95171 440#if !defined(CONFIG_USER_ONLY)
740b1759 441 if (icount_enabled()) {
8191d368 442 *val = icount_get() >> 32;
c7b95171
MC
443 } else {
444 *val = cpu_get_host_ticks() >> 32;
445 }
446#else
447 *val = cpu_get_host_ticks() >> 32;
448#endif
605def6e 449 return RISCV_EXCP_NONE;
c7b95171 450}
c7b95171
MC
451
452#if defined(CONFIG_USER_ONLY)
605def6e
AF
453static RISCVException read_time(CPURISCVState *env, int csrno,
454 target_ulong *val)
c7b95171
MC
455{
456 *val = cpu_get_host_ticks();
605def6e 457 return RISCV_EXCP_NONE;
c7b95171
MC
458}
459
605def6e
AF
460static RISCVException read_timeh(CPURISCVState *env, int csrno,
461 target_ulong *val)
c7b95171
MC
462{
463 *val = cpu_get_host_ticks() >> 32;
605def6e 464 return RISCV_EXCP_NONE;
c7b95171 465}
c7b95171
MC
466
467#else /* CONFIG_USER_ONLY */
468
605def6e
AF
469static RISCVException read_time(CPURISCVState *env, int csrno,
470 target_ulong *val)
c6957248
AP
471{
472 uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
473
474 if (!env->rdtime_fn) {
605def6e 475 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
476 }
477
a47ef6e9 478 *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
605def6e 479 return RISCV_EXCP_NONE;
c6957248
AP
480}
481
605def6e
AF
482static RISCVException read_timeh(CPURISCVState *env, int csrno,
483 target_ulong *val)
c6957248
AP
484{
485 uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
486
487 if (!env->rdtime_fn) {
605def6e 488 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
489 }
490
a47ef6e9 491 *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
605def6e 492 return RISCV_EXCP_NONE;
c6957248 493}
c6957248 494
c7b95171
MC
495/* Machine constants */
496
d028ac75
AP
497#define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
498#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP))
499#define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
500#define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
c7b95171 501
d028ac75 502static const uint64_t delegable_ints = S_MODE_INTERRUPTS |
d0e53ce3 503 VS_MODE_INTERRUPTS;
d028ac75
AP
504static const uint64_t vs_delegable_ints = VS_MODE_INTERRUPTS;
505static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
881df35d 506 HS_MODE_INTERRUPTS;
bc083a51
JM
507#define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
508 (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
509 (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
510 (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
511 (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
512 (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
513 (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
514 (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
515 (1ULL << (RISCV_EXCP_U_ECALL)) | \
516 (1ULL << (RISCV_EXCP_S_ECALL)) | \
517 (1ULL << (RISCV_EXCP_VS_ECALL)) | \
518 (1ULL << (RISCV_EXCP_M_ECALL)) | \
519 (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
520 (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
521 (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
522 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
523 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
524 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
525 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
526static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
527 ~((1ULL << (RISCV_EXCP_S_ECALL)) |
528 (1ULL << (RISCV_EXCP_VS_ECALL)) |
529 (1ULL << (RISCV_EXCP_M_ECALL)) |
530 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
531 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
532 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
533 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
c7b95171
MC
534static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
535 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
f310df58 536 SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
087b051a 537static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
e89b631c
GK
538static const target_ulong hip_writable_mask = MIP_VSSIP;
539static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
8747c9ee 540static const target_ulong vsip_writable_mask = MIP_VSSIP;
c7b95171 541
8987cdc4 542static const char valid_vm_1_10_32[16] = {
c7b95171
MC
543 [VM_1_10_MBARE] = 1,
544 [VM_1_10_SV32] = 1
545};
8987cdc4
AF
546
547static const char valid_vm_1_10_64[16] = {
c7b95171
MC
548 [VM_1_10_MBARE] = 1,
549 [VM_1_10_SV39] = 1,
550 [VM_1_10_SV48] = 1,
551 [VM_1_10_SV57] = 1
552};
c7b95171
MC
553
554/* Machine Information Registers */
605def6e
AF
555static RISCVException read_zero(CPURISCVState *env, int csrno,
556 target_ulong *val)
c7b95171 557{
605def6e
AF
558 *val = 0;
559 return RISCV_EXCP_NONE;
c7b95171
MC
560}
561
605def6e
AF
562static RISCVException read_mhartid(CPURISCVState *env, int csrno,
563 target_ulong *val)
c7b95171
MC
564{
565 *val = env->mhartid;
605def6e 566 return RISCV_EXCP_NONE;
c7b95171
MC
567}
568
569/* Machine Trap Setup */
b550f894
RH
570
571/* We do not store SD explicitly, only compute it on demand. */
572static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
573{
574 if ((status & MSTATUS_FS) == MSTATUS_FS ||
c36b2f1a 575 (status & MSTATUS_VS) == MSTATUS_VS ||
b550f894
RH
576 (status & MSTATUS_XS) == MSTATUS_XS) {
577 switch (xl) {
578 case MXL_RV32:
579 return status | MSTATUS32_SD;
580 case MXL_RV64:
581 return status | MSTATUS64_SD;
457c360f
FP
582 case MXL_RV128:
583 return MSTATUSH128_SD;
b550f894
RH
584 default:
585 g_assert_not_reached();
586 }
587 }
588 return status;
589}
590
605def6e
AF
591static RISCVException read_mstatus(CPURISCVState *env, int csrno,
592 target_ulong *val)
c7b95171 593{
b550f894 594 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
605def6e 595 return RISCV_EXCP_NONE;
c7b95171
MC
596}
597
598static int validate_vm(CPURISCVState *env, target_ulong vm)
599{
db23e5d9 600 if (riscv_cpu_mxl(env) == MXL_RV32) {
8987cdc4
AF
601 return valid_vm_1_10_32[vm & 0xf];
602 } else {
603 return valid_vm_1_10_64[vm & 0xf];
604 }
c7b95171
MC
605}
606
605def6e
AF
607static RISCVException write_mstatus(CPURISCVState *env, int csrno,
608 target_ulong val)
c7b95171 609{
284d697c
YJ
610 uint64_t mstatus = env->mstatus;
611 uint64_t mask = 0;
f310df58 612 RISCVMXL xl = riscv_cpu_mxl(env);
c7b95171
MC
613
614 /* flush tlb on mstatus fields that affect VM */
1a9540d1
AF
615 if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
616 MSTATUS_MPRV | MSTATUS_SUM)) {
617 tlb_flush(env_cpu(env));
c7b95171 618 }
1a9540d1
AF
619 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
620 MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
621 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
61b4b69d 622 MSTATUS_TW | MSTATUS_VS;
8987cdc4 623
f297245f 624 if (xl != MXL_RV32 || env->debugger) {
8987cdc4
AF
625 /*
626 * RV32: MPV and GVA are not in mstatus. The current plan is to
627 * add them to mstatush. For now, we just don't support it.
628 */
629 mask |= MSTATUS_MPV | MSTATUS_GVA;
f310df58
LZ
630 if ((val & MSTATUS64_UXL) != 0) {
631 mask |= MSTATUS64_UXL;
632 }
8987cdc4 633 }
c7b95171
MC
634
635 mstatus = (mstatus & ~mask) | (val & mask);
636
457c360f 637 if (xl > MXL_RV32) {
f310df58 638 /* SXL field is for now read only */
457c360f 639 mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
4fd7455b 640 }
c7b95171 641 env->mstatus = mstatus;
440544e1 642 env->xl = cpu_recompute_xl(env);
c7b95171 643
605def6e 644 return RISCV_EXCP_NONE;
c7b95171
MC
645}
646
605def6e
AF
647static RISCVException read_mstatush(CPURISCVState *env, int csrno,
648 target_ulong *val)
551fa7e8 649{
284d697c 650 *val = env->mstatus >> 32;
605def6e 651 return RISCV_EXCP_NONE;
551fa7e8
AF
652}
653
605def6e
AF
654static RISCVException write_mstatush(CPURISCVState *env, int csrno,
655 target_ulong val)
551fa7e8 656{
284d697c
YJ
657 uint64_t valh = (uint64_t)val << 32;
658 uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
659
660 if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
551fa7e8
AF
661 tlb_flush(env_cpu(env));
662 }
663
284d697c 664 env->mstatus = (env->mstatus & ~mask) | (valh & mask);
551fa7e8 665
605def6e 666 return RISCV_EXCP_NONE;
551fa7e8 667}
551fa7e8 668
457c360f
FP
669static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
670 Int128 *val)
671{
672 *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, env->mstatus));
673 return RISCV_EXCP_NONE;
674}
675
676static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
677 Int128 *val)
678{
679 *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
680 return RISCV_EXCP_NONE;
681}
682
605def6e
AF
683static RISCVException read_misa(CPURISCVState *env, int csrno,
684 target_ulong *val)
c7b95171 685{
e91a7227
RH
686 target_ulong misa;
687
688 switch (env->misa_mxl) {
689 case MXL_RV32:
690 misa = (target_ulong)MXL_RV32 << 30;
691 break;
692#ifdef TARGET_RISCV64
693 case MXL_RV64:
694 misa = (target_ulong)MXL_RV64 << 62;
695 break;
696#endif
697 default:
698 g_assert_not_reached();
699 }
700
701 *val = misa | env->misa_ext;
605def6e 702 return RISCV_EXCP_NONE;
c7b95171
MC
703}
704
605def6e
AF
705static RISCVException write_misa(CPURISCVState *env, int csrno,
706 target_ulong val)
f18637cd
MC
707{
708 if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
709 /* drop write to misa */
605def6e 710 return RISCV_EXCP_NONE;
f18637cd
MC
711 }
712
713 /* 'I' or 'E' must be present */
714 if (!(val & (RVI | RVE))) {
715 /* It is not, drop write to misa */
605def6e 716 return RISCV_EXCP_NONE;
f18637cd
MC
717 }
718
719 /* 'E' excludes all other extensions */
720 if (val & RVE) {
721 /* when we support 'E' we can do "val = RVE;" however
722 * for now we just drop writes if 'E' is present.
723 */
605def6e 724 return RISCV_EXCP_NONE;
f18637cd
MC
725 }
726
e91a7227
RH
727 /*
728 * misa.MXL writes are not supported by QEMU.
729 * Drop writes to those bits.
730 */
731
f18637cd 732 /* Mask extensions that are not supported by this hart */
e91a7227 733 val &= env->misa_ext_mask;
f18637cd
MC
734
735 /* Mask extensions that are not supported by QEMU */
7b07a37c 736 val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
f18637cd
MC
737
738 /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
739 if ((val & RVD) && !(val & RVF)) {
740 val &= ~RVD;
741 }
742
743 /* Suppress 'C' if next instruction is not aligned
744 * TODO: this should check next_pc
745 */
746 if ((val & RVC) && (GETPC() & ~3) != 0) {
747 val &= ~RVC;
748 }
749
e91a7227
RH
750 /* If nothing changed, do nothing. */
751 if (val == env->misa_ext) {
752 return RISCV_EXCP_NONE;
4fd7455b 753 }
f18637cd
MC
754
755 /* flush translation cache */
e91a7227
RH
756 tb_flush(env_cpu(env));
757 env->misa_ext = val;
440544e1 758 env->xl = riscv_cpu_mxl(env);
605def6e 759 return RISCV_EXCP_NONE;
f18637cd
MC
760}
761
605def6e
AF
762static RISCVException read_medeleg(CPURISCVState *env, int csrno,
763 target_ulong *val)
c7b95171
MC
764{
765 *val = env->medeleg;
605def6e 766 return RISCV_EXCP_NONE;
c7b95171
MC
767}
768
605def6e
AF
769static RISCVException write_medeleg(CPURISCVState *env, int csrno,
770 target_ulong val)
c7b95171 771{
bc083a51 772 env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
605def6e 773 return RISCV_EXCP_NONE;
c7b95171
MC
774}
775
d028ac75
AP
776static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
777 uint64_t *ret_val,
778 uint64_t new_val, uint64_t wr_mask)
c7b95171 779{
d028ac75
AP
780 uint64_t mask = wr_mask & delegable_ints;
781
782 if (ret_val) {
783 *ret_val = env->mideleg;
784 }
785
786 env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
c7b95171 787
713d8363 788 if (riscv_has_ext(env, RVH)) {
881df35d 789 env->mideleg |= HS_MODE_INTERRUPTS;
713d8363 790 }
d028ac75 791
605def6e 792 return RISCV_EXCP_NONE;
c7b95171
MC
793}
794
d028ac75
AP
795static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
796 target_ulong *ret_val,
797 target_ulong new_val, target_ulong wr_mask)
c7b95171 798{
d028ac75
AP
799 uint64_t rval;
800 RISCVException ret;
801
802 ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
803 if (ret_val) {
804 *ret_val = rval;
805 }
806
807 return ret;
c7b95171
MC
808}
809
d028ac75
AP
810static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
811 target_ulong *ret_val,
812 target_ulong new_val,
813 target_ulong wr_mask)
c7b95171 814{
d028ac75
AP
815 uint64_t rval;
816 RISCVException ret;
817
818 ret = rmw_mideleg64(env, csrno, &rval,
819 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
820 if (ret_val) {
821 *ret_val = rval >> 32;
822 }
823
824 return ret;
825}
826
827static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
828 uint64_t *ret_val,
829 uint64_t new_val, uint64_t wr_mask)
830{
831 uint64_t mask = wr_mask & all_ints;
832
833 if (ret_val) {
834 *ret_val = env->mie;
835 }
836
837 env->mie = (env->mie & ~mask) | (new_val & mask);
838
881df35d 839 if (!riscv_has_ext(env, RVH)) {
d028ac75 840 env->mie &= ~((uint64_t)MIP_SGEIP);
881df35d 841 }
d028ac75 842
605def6e 843 return RISCV_EXCP_NONE;
c7b95171
MC
844}
845
d028ac75
AP
846static RISCVException rmw_mie(CPURISCVState *env, int csrno,
847 target_ulong *ret_val,
848 target_ulong new_val, target_ulong wr_mask)
849{
850 uint64_t rval;
851 RISCVException ret;
852
853 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
854 if (ret_val) {
855 *ret_val = rval;
856 }
857
858 return ret;
859}
860
861static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
862 target_ulong *ret_val,
863 target_ulong new_val, target_ulong wr_mask)
864{
865 uint64_t rval;
866 RISCVException ret;
867
868 ret = rmw_mie64(env, csrno, &rval,
869 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
870 if (ret_val) {
871 *ret_val = rval >> 32;
872 }
873
874 return ret;
875}
876
605def6e
AF
877static RISCVException read_mtvec(CPURISCVState *env, int csrno,
878 target_ulong *val)
c7b95171
MC
879{
880 *val = env->mtvec;
605def6e 881 return RISCV_EXCP_NONE;
c7b95171
MC
882}
883
605def6e
AF
884static RISCVException write_mtvec(CPURISCVState *env, int csrno,
885 target_ulong val)
c7b95171
MC
886{
887 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
acbbb94e
MC
888 if ((val & 3) < 2) {
889 env->mtvec = val;
c7b95171 890 } else {
acbbb94e 891 qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
c7b95171 892 }
605def6e 893 return RISCV_EXCP_NONE;
c7b95171
MC
894}
895
605def6e
AF
896static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
897 target_ulong *val)
c7b95171 898{
c7b95171 899 *val = env->mcounteren;
605def6e 900 return RISCV_EXCP_NONE;
c7b95171
MC
901}
902
605def6e
AF
903static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
904 target_ulong val)
c7b95171 905{
c7b95171 906 env->mcounteren = val;
605def6e 907 return RISCV_EXCP_NONE;
c7b95171
MC
908}
909
c7b95171 910/* Machine Trap Handling */
457c360f
FP
911static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
912 Int128 *val)
913{
914 *val = int128_make128(env->mscratch, env->mscratchh);
915 return RISCV_EXCP_NONE;
916}
917
918static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
919 Int128 val)
920{
921 env->mscratch = int128_getlo(val);
922 env->mscratchh = int128_gethi(val);
923 return RISCV_EXCP_NONE;
924}
925
605def6e
AF
926static RISCVException read_mscratch(CPURISCVState *env, int csrno,
927 target_ulong *val)
c7b95171
MC
928{
929 *val = env->mscratch;
605def6e 930 return RISCV_EXCP_NONE;
c7b95171
MC
931}
932
605def6e
AF
933static RISCVException write_mscratch(CPURISCVState *env, int csrno,
934 target_ulong val)
c7b95171
MC
935{
936 env->mscratch = val;
605def6e 937 return RISCV_EXCP_NONE;
c7b95171
MC
938}
939
605def6e
AF
940static RISCVException read_mepc(CPURISCVState *env, int csrno,
941 target_ulong *val)
c7b95171
MC
942{
943 *val = env->mepc;
605def6e 944 return RISCV_EXCP_NONE;
c7b95171
MC
945}
946
605def6e
AF
947static RISCVException write_mepc(CPURISCVState *env, int csrno,
948 target_ulong val)
c7b95171
MC
949{
950 env->mepc = val;
605def6e 951 return RISCV_EXCP_NONE;
c7b95171
MC
952}
953
605def6e
AF
954static RISCVException read_mcause(CPURISCVState *env, int csrno,
955 target_ulong *val)
c7b95171
MC
956{
957 *val = env->mcause;
605def6e 958 return RISCV_EXCP_NONE;
c7b95171
MC
959}
960
605def6e
AF
961static RISCVException write_mcause(CPURISCVState *env, int csrno,
962 target_ulong val)
c7b95171
MC
963{
964 env->mcause = val;
605def6e 965 return RISCV_EXCP_NONE;
c7b95171
MC
966}
967
605def6e
AF
968static RISCVException read_mtval(CPURISCVState *env, int csrno,
969 target_ulong *val)
c7b95171 970{
ac12b601 971 *val = env->mtval;
605def6e 972 return RISCV_EXCP_NONE;
c7b95171
MC
973}
974
605def6e
AF
975static RISCVException write_mtval(CPURISCVState *env, int csrno,
976 target_ulong val)
c7b95171 977{
ac12b601 978 env->mtval = val;
605def6e 979 return RISCV_EXCP_NONE;
c7b95171
MC
980}
981
d028ac75
AP
982static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
983 uint64_t *ret_val,
984 uint64_t new_val, uint64_t wr_mask)
c7b95171 985{
3109cd98 986 RISCVCPU *cpu = env_archcpu(env);
e3e7039c 987 /* Allow software control of delegable interrupts not claimed by hardware */
d028ac75
AP
988 uint64_t old_mip, mask = wr_mask & delegable_ints & ~env->miclaim;
989 uint32_t gin;
71877e29 990
71877e29 991 if (mask) {
d028ac75 992 old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
71877e29 993 } else {
7ec5d303 994 old_mip = env->mip;
71877e29 995 }
c7b95171 996
cd032fe7
AP
997 if (csrno != CSR_HVIP) {
998 gin = get_field(env->hstatus, HSTATUS_VGEIN);
999 old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
1000 }
1001
d028ac75
AP
1002 if (ret_val) {
1003 *ret_val = old_mip;
71877e29 1004 }
c7b95171 1005
605def6e 1006 return RISCV_EXCP_NONE;
c7b95171
MC
1007}
1008
d028ac75
AP
1009static RISCVException rmw_mip(CPURISCVState *env, int csrno,
1010 target_ulong *ret_val,
1011 target_ulong new_val, target_ulong wr_mask)
1012{
1013 uint64_t rval;
1014 RISCVException ret;
1015
1016 ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
1017 if (ret_val) {
1018 *ret_val = rval;
1019 }
1020
1021 return ret;
1022}
1023
1024static RISCVException rmw_miph(CPURISCVState *env, int csrno,
1025 target_ulong *ret_val,
1026 target_ulong new_val, target_ulong wr_mask)
1027{
1028 uint64_t rval;
1029 RISCVException ret;
1030
1031 ret = rmw_mip64(env, csrno, &rval,
1032 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1033 if (ret_val) {
1034 *ret_val = rval >> 32;
1035 }
1036
1037 return ret;
1038}
1039
c7b95171 1040/* Supervisor Trap Setup */
457c360f
FP
1041static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
1042 Int128 *val)
1043{
1044 uint64_t mask = sstatus_v1_10_mask;
1045 uint64_t sstatus = env->mstatus & mask;
f297245f 1046 if (env->xl != MXL_RV32 || env->debugger) {
f310df58
LZ
1047 mask |= SSTATUS64_UXL;
1048 }
457c360f
FP
1049
1050 *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
1051 return RISCV_EXCP_NONE;
1052}
1053
605def6e
AF
1054static RISCVException read_sstatus(CPURISCVState *env, int csrno,
1055 target_ulong *val)
c7b95171 1056{
1a9540d1 1057 target_ulong mask = (sstatus_v1_10_mask);
f297245f 1058 if (env->xl != MXL_RV32 || env->debugger) {
f310df58
LZ
1059 mask |= SSTATUS64_UXL;
1060 }
b550f894
RH
1061 /* TODO: Use SXL not MXL. */
1062 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
605def6e 1063 return RISCV_EXCP_NONE;
c7b95171
MC
1064}
1065
605def6e
AF
1066static RISCVException write_sstatus(CPURISCVState *env, int csrno,
1067 target_ulong val)
c7b95171 1068{
1a9540d1 1069 target_ulong mask = (sstatus_v1_10_mask);
f310df58 1070
f297245f 1071 if (env->xl != MXL_RV32 || env->debugger) {
f310df58
LZ
1072 if ((val & SSTATUS64_UXL) != 0) {
1073 mask |= SSTATUS64_UXL;
1074 }
1075 }
c7b95171
MC
1076 target_ulong newval = (env->mstatus & ~mask) | (val & mask);
1077 return write_mstatus(env, CSR_MSTATUS, newval);
1078}
1079
d028ac75
AP
1080static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
1081 uint64_t *ret_val,
1082 uint64_t new_val, uint64_t wr_mask)
9d5451e0 1083{
d028ac75
AP
1084 RISCVException ret;
1085 uint64_t rval, vsbits, mask = env->hideleg & VS_MODE_INTERRUPTS;
1086
1087 /* Bring VS-level bits to correct position */
1088 vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
1089 new_val &= ~(VS_MODE_INTERRUPTS >> 1);
1090 new_val |= vsbits << 1;
1091 vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
1092 wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
1093 wr_mask |= vsbits << 1;
1094
1095 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask);
1096 if (ret_val) {
1097 rval &= mask;
1098 vsbits = rval & VS_MODE_INTERRUPTS;
1099 rval &= ~VS_MODE_INTERRUPTS;
1100 *ret_val = rval | (vsbits >> 1);
1101 }
1102
1103 return ret;
9d5451e0
GK
1104}
1105
d028ac75
AP
1106static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
1107 target_ulong *ret_val,
1108 target_ulong new_val, target_ulong wr_mask)
c7b95171 1109{
d028ac75
AP
1110 uint64_t rval;
1111 RISCVException ret;
1112
1113 ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
1114 if (ret_val) {
1115 *ret_val = rval;
d0e53ce3 1116 }
d028ac75
AP
1117
1118 return ret;
c7b95171
MC
1119}
1120
d028ac75
AP
1121static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
1122 target_ulong *ret_val,
1123 target_ulong new_val, target_ulong wr_mask)
c7b95171 1124{
d028ac75
AP
1125 uint64_t rval;
1126 RISCVException ret;
1127
1128 ret = rmw_vsie64(env, csrno, &rval,
1129 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1130 if (ret_val) {
1131 *ret_val = rval >> 32;
1132 }
1133
1134 return ret;
9d5451e0 1135}
d0e53ce3 1136
d028ac75
AP
1137static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
1138 uint64_t *ret_val,
1139 uint64_t new_val, uint64_t wr_mask)
9d5451e0 1140{
d028ac75
AP
1141 RISCVException ret;
1142 uint64_t mask = env->mideleg & S_MODE_INTERRUPTS;
1143
d0e53ce3 1144 if (riscv_cpu_virt_enabled(env)) {
d028ac75 1145 ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
d0e53ce3 1146 } else {
d028ac75 1147 ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask);
d0e53ce3
AF
1148 }
1149
d028ac75
AP
1150 if (ret_val) {
1151 *ret_val &= mask;
1152 }
1153
1154 return ret;
1155}
1156
1157static RISCVException rmw_sie(CPURISCVState *env, int csrno,
1158 target_ulong *ret_val,
1159 target_ulong new_val, target_ulong wr_mask)
1160{
1161 uint64_t rval;
1162 RISCVException ret;
1163
1164 ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
1165 if (ret_val) {
1166 *ret_val = rval;
1167 }
1168
1169 return ret;
1170}
1171
1172static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
1173 target_ulong *ret_val,
1174 target_ulong new_val, target_ulong wr_mask)
1175{
1176 uint64_t rval;
1177 RISCVException ret;
1178
1179 ret = rmw_sie64(env, csrno, &rval,
1180 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1181 if (ret_val) {
1182 *ret_val = rval >> 32;
1183 }
1184
1185 return ret;
c7b95171
MC
1186}
1187
605def6e
AF
1188static RISCVException read_stvec(CPURISCVState *env, int csrno,
1189 target_ulong *val)
c7b95171
MC
1190{
1191 *val = env->stvec;
605def6e 1192 return RISCV_EXCP_NONE;
c7b95171
MC
1193}
1194
605def6e
AF
1195static RISCVException write_stvec(CPURISCVState *env, int csrno,
1196 target_ulong val)
c7b95171
MC
1197{
1198 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
acbbb94e
MC
1199 if ((val & 3) < 2) {
1200 env->stvec = val;
c7b95171 1201 } else {
acbbb94e 1202 qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
c7b95171 1203 }
605def6e 1204 return RISCV_EXCP_NONE;
c7b95171
MC
1205}
1206
605def6e
AF
1207static RISCVException read_scounteren(CPURISCVState *env, int csrno,
1208 target_ulong *val)
c7b95171 1209{
c7b95171 1210 *val = env->scounteren;
605def6e 1211 return RISCV_EXCP_NONE;
c7b95171
MC
1212}
1213
605def6e
AF
1214static RISCVException write_scounteren(CPURISCVState *env, int csrno,
1215 target_ulong val)
c7b95171 1216{
c7b95171 1217 env->scounteren = val;
605def6e 1218 return RISCV_EXCP_NONE;
c7b95171
MC
1219}
1220
1221/* Supervisor Trap Handling */
457c360f
FP
1222static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
1223 Int128 *val)
1224{
1225 *val = int128_make128(env->sscratch, env->sscratchh);
1226 return RISCV_EXCP_NONE;
1227}
1228
1229static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
1230 Int128 val)
1231{
1232 env->sscratch = int128_getlo(val);
1233 env->sscratchh = int128_gethi(val);
1234 return RISCV_EXCP_NONE;
1235}
1236
605def6e
AF
1237static RISCVException read_sscratch(CPURISCVState *env, int csrno,
1238 target_ulong *val)
c7b95171
MC
1239{
1240 *val = env->sscratch;
605def6e 1241 return RISCV_EXCP_NONE;
c7b95171
MC
1242}
1243
605def6e
AF
1244static RISCVException write_sscratch(CPURISCVState *env, int csrno,
1245 target_ulong val)
c7b95171
MC
1246{
1247 env->sscratch = val;
605def6e 1248 return RISCV_EXCP_NONE;
c7b95171
MC
1249}
1250
605def6e
AF
1251static RISCVException read_sepc(CPURISCVState *env, int csrno,
1252 target_ulong *val)
c7b95171
MC
1253{
1254 *val = env->sepc;
605def6e 1255 return RISCV_EXCP_NONE;
c7b95171
MC
1256}
1257
605def6e
AF
1258static RISCVException write_sepc(CPURISCVState *env, int csrno,
1259 target_ulong val)
c7b95171
MC
1260{
1261 env->sepc = val;
605def6e 1262 return RISCV_EXCP_NONE;
c7b95171
MC
1263}
1264
605def6e
AF
1265static RISCVException read_scause(CPURISCVState *env, int csrno,
1266 target_ulong *val)
c7b95171
MC
1267{
1268 *val = env->scause;
605def6e 1269 return RISCV_EXCP_NONE;
c7b95171
MC
1270}
1271
605def6e
AF
1272static RISCVException write_scause(CPURISCVState *env, int csrno,
1273 target_ulong val)
c7b95171
MC
1274{
1275 env->scause = val;
605def6e 1276 return RISCV_EXCP_NONE;
c7b95171
MC
1277}
1278
605def6e
AF
1279static RISCVException read_stval(CPURISCVState *env, int csrno,
1280 target_ulong *val)
c7b95171 1281{
ac12b601 1282 *val = env->stval;
605def6e 1283 return RISCV_EXCP_NONE;
c7b95171
MC
1284}
1285
605def6e
AF
1286static RISCVException write_stval(CPURISCVState *env, int csrno,
1287 target_ulong val)
c7b95171 1288{
ac12b601 1289 env->stval = val;
605def6e 1290 return RISCV_EXCP_NONE;
c7b95171
MC
1291}
1292
d028ac75
AP
1293static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
1294 uint64_t *ret_val,
1295 uint64_t new_val, uint64_t wr_mask)
1296{
1297 RISCVException ret;
1298 uint64_t rval, vsbits, mask = env->hideleg & vsip_writable_mask;
1299
1300 /* Bring VS-level bits to correct position */
1301 vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
1302 new_val &= ~(VS_MODE_INTERRUPTS >> 1);
1303 new_val |= vsbits << 1;
1304 vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
1305 wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
1306 wr_mask |= vsbits << 1;
1307
1308 ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask & mask);
1309 if (ret_val) {
1310 rval &= mask;
1311 vsbits = rval & VS_MODE_INTERRUPTS;
1312 rval &= ~VS_MODE_INTERRUPTS;
1313 *ret_val = rval | (vsbits >> 1);
1314 }
1315
1316 return ret;
1317}
1318
605def6e 1319static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
d028ac75
AP
1320 target_ulong *ret_val,
1321 target_ulong new_val, target_ulong wr_mask)
9d5451e0 1322{
d028ac75
AP
1323 uint64_t rval;
1324 RISCVException ret;
33979526 1325
d028ac75
AP
1326 ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
1327 if (ret_val) {
1328 *ret_val = rval;
33979526 1329 }
d028ac75 1330
9d5451e0
GK
1331 return ret;
1332}
1333
d028ac75
AP
1334static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
1335 target_ulong *ret_val,
1336 target_ulong new_val, target_ulong wr_mask)
c7b95171 1337{
d028ac75
AP
1338 uint64_t rval;
1339 RISCVException ret;
1340
1341 ret = rmw_vsip64(env, csrno, &rval,
1342 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1343 if (ret_val) {
1344 *ret_val = rval >> 32;
1345 }
1346
1347 return ret;
1348}
1349
1350static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
1351 uint64_t *ret_val,
1352 uint64_t new_val, uint64_t wr_mask)
1353{
1354 RISCVException ret;
1355 uint64_t mask = env->mideleg & sip_writable_mask;
a2e9f57d
AF
1356
1357 if (riscv_cpu_virt_enabled(env)) {
d028ac75 1358 ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
a2e9f57d 1359 } else {
d028ac75 1360 ret = rmw_mip64(env, csrno, ret_val, new_val, wr_mask & mask);
a2e9f57d
AF
1361 }
1362
d028ac75
AP
1363 if (ret_val) {
1364 *ret_val &= env->mideleg & S_MODE_INTERRUPTS;
1365 }
1366
1367 return ret;
1368}
1369
1370static RISCVException rmw_sip(CPURISCVState *env, int csrno,
1371 target_ulong *ret_val,
1372 target_ulong new_val, target_ulong wr_mask)
1373{
1374 uint64_t rval;
1375 RISCVException ret;
1376
1377 ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
1378 if (ret_val) {
1379 *ret_val = rval;
33979526 1380 }
d028ac75
AP
1381
1382 return ret;
1383}
1384
1385static RISCVException rmw_siph(CPURISCVState *env, int csrno,
1386 target_ulong *ret_val,
1387 target_ulong new_val, target_ulong wr_mask)
1388{
1389 uint64_t rval;
1390 RISCVException ret;
1391
1392 ret = rmw_sip64(env, csrno, &rval,
1393 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1394 if (ret_val) {
1395 *ret_val = rval >> 32;
1396 }
1397
087b051a 1398 return ret;
c7b95171
MC
1399}
1400
1401/* Supervisor Protection and Translation */
605def6e
AF
1402static RISCVException read_satp(CPURISCVState *env, int csrno,
1403 target_ulong *val)
c7b95171
MC
1404{
1405 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
1406 *val = 0;
605def6e 1407 return RISCV_EXCP_NONE;
1a9540d1
AF
1408 }
1409
1410 if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
605def6e 1411 return RISCV_EXCP_ILLEGAL_INST;
c7b95171 1412 } else {
1a9540d1 1413 *val = env->satp;
c7b95171 1414 }
1a9540d1 1415
605def6e 1416 return RISCV_EXCP_NONE;
c7b95171
MC
1417}
1418
605def6e
AF
1419static RISCVException write_satp(CPURISCVState *env, int csrno,
1420 target_ulong val)
c7b95171 1421{
15732b8e 1422 target_ulong vm, mask, asid;
419ddf00 1423
c7b95171 1424 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
605def6e 1425 return RISCV_EXCP_NONE;
c7b95171 1426 }
419ddf00 1427
db23e5d9 1428 if (riscv_cpu_mxl(env) == MXL_RV32) {
419ddf00
AF
1429 vm = validate_vm(env, get_field(val, SATP32_MODE));
1430 mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
1431 asid = (val ^ env->satp) & SATP32_ASID;
1432 } else {
1433 vm = validate_vm(env, get_field(val, SATP64_MODE));
1434 mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
1435 asid = (val ^ env->satp) & SATP64_ASID;
1436 }
1437
1438 if (vm && mask) {
7f2b5ff1 1439 if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
605def6e 1440 return RISCV_EXCP_ILLEGAL_INST;
7f2b5ff1 1441 } else {
419ddf00 1442 if (asid) {
3109cd98 1443 tlb_flush(env_cpu(env));
1e0d985f 1444 }
7f2b5ff1
MC
1445 env->satp = val;
1446 }
c7b95171 1447 }
605def6e 1448 return RISCV_EXCP_NONE;
c7b95171
MC
1449}
1450
ff2cc129 1451/* Hypervisor Extensions */
605def6e
AF
1452static RISCVException read_hstatus(CPURISCVState *env, int csrno,
1453 target_ulong *val)
ff2cc129
AF
1454{
1455 *val = env->hstatus;
db23e5d9 1456 if (riscv_cpu_mxl(env) != MXL_RV32) {
8987cdc4
AF
1457 /* We only support 64-bit VSXL */
1458 *val = set_field(*val, HSTATUS_VSXL, 2);
1459 }
30f663b1
AF
1460 /* We only support little endian */
1461 *val = set_field(*val, HSTATUS_VSBE, 0);
605def6e 1462 return RISCV_EXCP_NONE;
ff2cc129
AF
1463}
1464
605def6e
AF
1465static RISCVException write_hstatus(CPURISCVState *env, int csrno,
1466 target_ulong val)
ff2cc129
AF
1467{
1468 env->hstatus = val;
db23e5d9 1469 if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
f8dc878e
AF
1470 qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
1471 }
30f663b1
AF
1472 if (get_field(val, HSTATUS_VSBE) != 0) {
1473 qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
1474 }
605def6e 1475 return RISCV_EXCP_NONE;
ff2cc129
AF
1476}
1477
605def6e
AF
1478static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
1479 target_ulong *val)
ff2cc129
AF
1480{
1481 *val = env->hedeleg;
605def6e 1482 return RISCV_EXCP_NONE;
ff2cc129
AF
1483}
1484
605def6e
AF
1485static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
1486 target_ulong val)
ff2cc129 1487{
bc083a51 1488 env->hedeleg = val & vs_delegable_excps;
605def6e 1489 return RISCV_EXCP_NONE;
ff2cc129
AF
1490}
1491
d028ac75
AP
1492static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
1493 uint64_t *ret_val,
1494 uint64_t new_val, uint64_t wr_mask)
ff2cc129 1495{
d028ac75
AP
1496 uint64_t mask = wr_mask & vs_delegable_ints;
1497
1498 if (ret_val) {
1499 *ret_val = env->hideleg & vs_delegable_ints;
1500 }
1501
1502 env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
605def6e 1503 return RISCV_EXCP_NONE;
ff2cc129
AF
1504}
1505
d028ac75
AP
1506static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
1507 target_ulong *ret_val,
1508 target_ulong new_val, target_ulong wr_mask)
ff2cc129 1509{
d028ac75
AP
1510 uint64_t rval;
1511 RISCVException ret;
1512
1513 ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
1514 if (ret_val) {
1515 *ret_val = rval;
1516 }
1517
1518 return ret;
1519}
1520
1521static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
1522 target_ulong *ret_val,
1523 target_ulong new_val, target_ulong wr_mask)
1524{
1525 uint64_t rval;
1526 RISCVException ret;
1527
1528 ret = rmw_hideleg64(env, csrno, &rval,
1529 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1530 if (ret_val) {
1531 *ret_val = rval >> 32;
1532 }
1533
1534 return ret;
1535}
1536
1537static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
1538 uint64_t *ret_val,
1539 uint64_t new_val, uint64_t wr_mask)
1540{
1541 RISCVException ret;
1542
1543 ret = rmw_mip64(env, csrno, ret_val, new_val,
1544 wr_mask & hvip_writable_mask);
1545 if (ret_val) {
1546 *ret_val &= VS_MODE_INTERRUPTS;
1547 }
1548
1549 return ret;
ff2cc129
AF
1550}
1551
605def6e 1552static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
d028ac75
AP
1553 target_ulong *ret_val,
1554 target_ulong new_val, target_ulong wr_mask)
83028098 1555{
d028ac75
AP
1556 uint64_t rval;
1557 RISCVException ret;
83028098 1558
d028ac75
AP
1559 ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
1560 if (ret_val) {
1561 *ret_val = rval;
1562 }
1563
1564 return ret;
1565}
1566
1567static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
1568 target_ulong *ret_val,
1569 target_ulong new_val, target_ulong wr_mask)
1570{
1571 uint64_t rval;
1572 RISCVException ret;
1573
1574 ret = rmw_hvip64(env, csrno, &rval,
1575 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1576 if (ret_val) {
1577 *ret_val = rval >> 32;
33979526 1578 }
d028ac75 1579
83028098
AF
1580 return ret;
1581}
1582
605def6e
AF
1583static RISCVException rmw_hip(CPURISCVState *env, int csrno,
1584 target_ulong *ret_value,
1585 target_ulong new_value, target_ulong write_mask)
ff2cc129 1586{
cd032fe7 1587 int ret = rmw_mip(env, csrno, ret_value, new_value,
ff2cc129
AF
1588 write_mask & hip_writable_mask);
1589
33979526 1590 if (ret_value) {
881df35d 1591 *ret_value &= HS_MODE_INTERRUPTS;
33979526 1592 }
ff2cc129
AF
1593 return ret;
1594}
1595
d028ac75
AP
1596static RISCVException rmw_hie(CPURISCVState *env, int csrno,
1597 target_ulong *ret_val,
1598 target_ulong new_val, target_ulong wr_mask)
ff2cc129 1599{
d028ac75
AP
1600 uint64_t rval;
1601 RISCVException ret;
ff2cc129 1602
d028ac75
AP
1603 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
1604 if (ret_val) {
1605 *ret_val = rval & HS_MODE_INTERRUPTS;
1606 }
1607
1608 return ret;
ff2cc129
AF
1609}
1610
605def6e
AF
1611static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
1612 target_ulong *val)
ff2cc129
AF
1613{
1614 *val = env->hcounteren;
605def6e 1615 return RISCV_EXCP_NONE;
ff2cc129
AF
1616}
1617
605def6e
AF
1618static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
1619 target_ulong val)
ff2cc129
AF
1620{
1621 env->hcounteren = val;
605def6e 1622 return RISCV_EXCP_NONE;
ff2cc129
AF
1623}
1624
cd032fe7
AP
1625static RISCVException read_hgeie(CPURISCVState *env, int csrno,
1626 target_ulong *val)
83028098 1627{
377cbb4b 1628 if (val) {
cd032fe7 1629 *val = env->hgeie;
377cbb4b 1630 }
605def6e 1631 return RISCV_EXCP_NONE;
83028098
AF
1632}
1633
cd032fe7
AP
1634static RISCVException write_hgeie(CPURISCVState *env, int csrno,
1635 target_ulong val)
1636{
1637 /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
1638 val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
1639 env->hgeie = val;
1640 /* Update mip.SGEIP bit */
1641 riscv_cpu_update_mip(env_archcpu(env), MIP_SGEIP,
1642 BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
1643 return RISCV_EXCP_NONE;
1644}
1645
605def6e
AF
1646static RISCVException read_htval(CPURISCVState *env, int csrno,
1647 target_ulong *val)
ff2cc129
AF
1648{
1649 *val = env->htval;
605def6e 1650 return RISCV_EXCP_NONE;
ff2cc129
AF
1651}
1652
605def6e
AF
1653static RISCVException write_htval(CPURISCVState *env, int csrno,
1654 target_ulong val)
ff2cc129
AF
1655{
1656 env->htval = val;
605def6e 1657 return RISCV_EXCP_NONE;
ff2cc129
AF
1658}
1659
605def6e
AF
1660static RISCVException read_htinst(CPURISCVState *env, int csrno,
1661 target_ulong *val)
ff2cc129
AF
1662{
1663 *val = env->htinst;
605def6e 1664 return RISCV_EXCP_NONE;
ff2cc129
AF
1665}
1666
605def6e
AF
1667static RISCVException write_htinst(CPURISCVState *env, int csrno,
1668 target_ulong val)
ff2cc129 1669{
605def6e 1670 return RISCV_EXCP_NONE;
ff2cc129
AF
1671}
1672
cd032fe7
AP
1673static RISCVException read_hgeip(CPURISCVState *env, int csrno,
1674 target_ulong *val)
83028098 1675{
377cbb4b 1676 if (val) {
cd032fe7 1677 *val = env->hgeip;
377cbb4b 1678 }
605def6e 1679 return RISCV_EXCP_NONE;
83028098
AF
1680}
1681
605def6e
AF
1682static RISCVException read_hgatp(CPURISCVState *env, int csrno,
1683 target_ulong *val)
ff2cc129
AF
1684{
1685 *val = env->hgatp;
605def6e 1686 return RISCV_EXCP_NONE;
ff2cc129
AF
1687}
1688
605def6e
AF
1689static RISCVException write_hgatp(CPURISCVState *env, int csrno,
1690 target_ulong val)
ff2cc129
AF
1691{
1692 env->hgatp = val;
605def6e 1693 return RISCV_EXCP_NONE;
ff2cc129
AF
1694}
1695
605def6e
AF
1696static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
1697 target_ulong *val)
c6957248
AP
1698{
1699 if (!env->rdtime_fn) {
605def6e 1700 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
1701 }
1702
c6957248 1703 *val = env->htimedelta;
605def6e 1704 return RISCV_EXCP_NONE;
c6957248
AP
1705}
1706
605def6e
AF
1707static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
1708 target_ulong val)
c6957248
AP
1709{
1710 if (!env->rdtime_fn) {
605def6e 1711 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
1712 }
1713
db23e5d9 1714 if (riscv_cpu_mxl(env) == MXL_RV32) {
8987cdc4
AF
1715 env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
1716 } else {
1717 env->htimedelta = val;
1718 }
605def6e 1719 return RISCV_EXCP_NONE;
c6957248
AP
1720}
1721
605def6e
AF
1722static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
1723 target_ulong *val)
c6957248
AP
1724{
1725 if (!env->rdtime_fn) {
605def6e 1726 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
1727 }
1728
1729 *val = env->htimedelta >> 32;
605def6e 1730 return RISCV_EXCP_NONE;
c6957248
AP
1731}
1732
605def6e
AF
1733static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
1734 target_ulong val)
c6957248
AP
1735{
1736 if (!env->rdtime_fn) {
605def6e 1737 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
1738 }
1739
1740 env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
605def6e 1741 return RISCV_EXCP_NONE;
c6957248 1742}
c6957248 1743
8747c9ee 1744/* Virtual CSR Registers */
605def6e
AF
1745static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
1746 target_ulong *val)
8747c9ee
AF
1747{
1748 *val = env->vsstatus;
605def6e 1749 return RISCV_EXCP_NONE;
8747c9ee
AF
1750}
1751
605def6e
AF
1752static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
1753 target_ulong val)
8747c9ee 1754{
284d697c 1755 uint64_t mask = (target_ulong)-1;
f310df58
LZ
1756 if ((val & VSSTATUS64_UXL) == 0) {
1757 mask &= ~VSSTATUS64_UXL;
1758 }
284d697c 1759 env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
605def6e 1760 return RISCV_EXCP_NONE;
8747c9ee
AF
1761}
1762
8747c9ee
AF
1763static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
1764{
1765 *val = env->vstvec;
605def6e 1766 return RISCV_EXCP_NONE;
8747c9ee
AF
1767}
1768
605def6e
AF
1769static RISCVException write_vstvec(CPURISCVState *env, int csrno,
1770 target_ulong val)
8747c9ee
AF
1771{
1772 env->vstvec = val;
605def6e 1773 return RISCV_EXCP_NONE;
8747c9ee
AF
1774}
1775
605def6e
AF
1776static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
1777 target_ulong *val)
8747c9ee
AF
1778{
1779 *val = env->vsscratch;
605def6e 1780 return RISCV_EXCP_NONE;
8747c9ee
AF
1781}
1782
605def6e
AF
1783static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
1784 target_ulong val)
8747c9ee
AF
1785{
1786 env->vsscratch = val;
605def6e 1787 return RISCV_EXCP_NONE;
8747c9ee
AF
1788}
1789
605def6e
AF
1790static RISCVException read_vsepc(CPURISCVState *env, int csrno,
1791 target_ulong *val)
8747c9ee
AF
1792{
1793 *val = env->vsepc;
605def6e 1794 return RISCV_EXCP_NONE;
8747c9ee
AF
1795}
1796
605def6e
AF
1797static RISCVException write_vsepc(CPURISCVState *env, int csrno,
1798 target_ulong val)
8747c9ee
AF
1799{
1800 env->vsepc = val;
605def6e 1801 return RISCV_EXCP_NONE;
8747c9ee
AF
1802}
1803
605def6e
AF
1804static RISCVException read_vscause(CPURISCVState *env, int csrno,
1805 target_ulong *val)
8747c9ee
AF
1806{
1807 *val = env->vscause;
605def6e 1808 return RISCV_EXCP_NONE;
8747c9ee
AF
1809}
1810
605def6e
AF
1811static RISCVException write_vscause(CPURISCVState *env, int csrno,
1812 target_ulong val)
8747c9ee
AF
1813{
1814 env->vscause = val;
605def6e 1815 return RISCV_EXCP_NONE;
8747c9ee
AF
1816}
1817
605def6e
AF
1818static RISCVException read_vstval(CPURISCVState *env, int csrno,
1819 target_ulong *val)
8747c9ee
AF
1820{
1821 *val = env->vstval;
605def6e 1822 return RISCV_EXCP_NONE;
8747c9ee
AF
1823}
1824
605def6e
AF
1825static RISCVException write_vstval(CPURISCVState *env, int csrno,
1826 target_ulong val)
8747c9ee
AF
1827{
1828 env->vstval = val;
605def6e 1829 return RISCV_EXCP_NONE;
8747c9ee
AF
1830}
1831
605def6e
AF
1832static RISCVException read_vsatp(CPURISCVState *env, int csrno,
1833 target_ulong *val)
8747c9ee
AF
1834{
1835 *val = env->vsatp;
605def6e 1836 return RISCV_EXCP_NONE;
8747c9ee
AF
1837}
1838
605def6e
AF
1839static RISCVException write_vsatp(CPURISCVState *env, int csrno,
1840 target_ulong val)
8747c9ee
AF
1841{
1842 env->vsatp = val;
605def6e 1843 return RISCV_EXCP_NONE;
8747c9ee
AF
1844}
1845
605def6e
AF
1846static RISCVException read_mtval2(CPURISCVState *env, int csrno,
1847 target_ulong *val)
34cfb5f6
AF
1848{
1849 *val = env->mtval2;
605def6e 1850 return RISCV_EXCP_NONE;
34cfb5f6
AF
1851}
1852
605def6e
AF
1853static RISCVException write_mtval2(CPURISCVState *env, int csrno,
1854 target_ulong val)
34cfb5f6
AF
1855{
1856 env->mtval2 = val;
605def6e 1857 return RISCV_EXCP_NONE;
34cfb5f6
AF
1858}
1859
605def6e
AF
1860static RISCVException read_mtinst(CPURISCVState *env, int csrno,
1861 target_ulong *val)
34cfb5f6
AF
1862{
1863 *val = env->mtinst;
605def6e 1864 return RISCV_EXCP_NONE;
34cfb5f6
AF
1865}
1866
605def6e
AF
1867static RISCVException write_mtinst(CPURISCVState *env, int csrno,
1868 target_ulong val)
34cfb5f6
AF
1869{
1870 env->mtinst = val;
605def6e 1871 return RISCV_EXCP_NONE;
34cfb5f6
AF
1872}
1873
c7b95171 1874/* Physical Memory Protection */
2582a95c
HW
1875static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
1876 target_ulong *val)
1877{
1878 *val = mseccfg_csr_read(env);
1879 return RISCV_EXCP_NONE;
1880}
1881
1882static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
1883 target_ulong val)
1884{
1885 mseccfg_csr_write(env, val);
1886 return RISCV_EXCP_NONE;
1887}
1888
79f26b3b
LZ
1889static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
1890{
1891 /* TODO: RV128 restriction check */
1892 if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
1893 return false;
1894 }
1895 return true;
1896}
1897
605def6e
AF
1898static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
1899 target_ulong *val)
c7b95171 1900{
79f26b3b
LZ
1901 uint32_t reg_index = csrno - CSR_PMPCFG0;
1902
1903 if (!check_pmp_reg_index(env, reg_index)) {
1904 return RISCV_EXCP_ILLEGAL_INST;
1905 }
c7b95171 1906 *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
605def6e 1907 return RISCV_EXCP_NONE;
c7b95171
MC
1908}
1909
605def6e
AF
1910static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
1911 target_ulong val)
c7b95171 1912{
79f26b3b
LZ
1913 uint32_t reg_index = csrno - CSR_PMPCFG0;
1914
1915 if (!check_pmp_reg_index(env, reg_index)) {
1916 return RISCV_EXCP_ILLEGAL_INST;
1917 }
c7b95171 1918 pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
605def6e 1919 return RISCV_EXCP_NONE;
c7b95171
MC
1920}
1921
605def6e
AF
1922static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
1923 target_ulong *val)
c7b95171
MC
1924{
1925 *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
605def6e 1926 return RISCV_EXCP_NONE;
c7b95171
MC
1927}
1928
605def6e
AF
1929static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
1930 target_ulong val)
c7b95171
MC
1931{
1932 pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
605def6e 1933 return RISCV_EXCP_NONE;
c7b95171
MC
1934}
1935
4bbe8033
AB
1936/*
1937 * Functions to access Pointer Masking feature registers
1938 * We have to check if current priv lvl could modify
1939 * csr in given mode
1940 */
1941static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
1942{
1943 int csr_priv = get_field(csrno, 0x300);
1944 int pm_current;
1945
47bdec82
LZ
1946 if (env->debugger) {
1947 return false;
1948 }
4bbe8033
AB
1949 /*
1950 * If priv lvls differ that means we're accessing csr from higher priv lvl,
1951 * so allow the access
1952 */
1953 if (env->priv != csr_priv) {
1954 return false;
1955 }
1956 switch (env->priv) {
1957 case PRV_M:
1958 pm_current = get_field(env->mmte, M_PM_CURRENT);
1959 break;
1960 case PRV_S:
1961 pm_current = get_field(env->mmte, S_PM_CURRENT);
1962 break;
1963 case PRV_U:
1964 pm_current = get_field(env->mmte, U_PM_CURRENT);
1965 break;
1966 default:
1967 g_assert_not_reached();
1968 }
1969 /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
1970 return !pm_current;
1971}
1972
1973static RISCVException read_mmte(CPURISCVState *env, int csrno,
1974 target_ulong *val)
1975{
1976 *val = env->mmte & MMTE_MASK;
1977 return RISCV_EXCP_NONE;
1978}
1979
1980static RISCVException write_mmte(CPURISCVState *env, int csrno,
1981 target_ulong val)
1982{
1983 uint64_t mstatus;
1984 target_ulong wpri_val = val & MMTE_MASK;
1985
1986 if (val != wpri_val) {
1987 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
1988 "MMTE: WPRI violation written 0x", val,
1989 "vs expected 0x", wpri_val);
1990 }
1991 /* for machine mode pm.current is hardwired to 1 */
1992 wpri_val |= MMTE_M_PM_CURRENT;
1993
1994 /* hardwiring pm.instruction bit to 0, since it's not supported yet */
1995 wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
1996 env->mmte = wpri_val | PM_EXT_DIRTY;
40bfa5f6 1997 riscv_cpu_update_mask(env);
4bbe8033
AB
1998
1999 /* Set XS and SD bits, since PM CSRs are dirty */
2000 mstatus = env->mstatus | MSTATUS_XS;
2001 write_mstatus(env, csrno, mstatus);
2002 return RISCV_EXCP_NONE;
2003}
2004
2005static RISCVException read_smte(CPURISCVState *env, int csrno,
2006 target_ulong *val)
2007{
2008 *val = env->mmte & SMTE_MASK;
2009 return RISCV_EXCP_NONE;
2010}
2011
2012static RISCVException write_smte(CPURISCVState *env, int csrno,
2013 target_ulong val)
2014{
2015 target_ulong wpri_val = val & SMTE_MASK;
2016
2017 if (val != wpri_val) {
2018 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2019 "SMTE: WPRI violation written 0x", val,
2020 "vs expected 0x", wpri_val);
2021 }
2022
2023 /* if pm.current==0 we can't modify current PM CSRs */
2024 if (check_pm_current_disabled(env, csrno)) {
2025 return RISCV_EXCP_NONE;
2026 }
2027
2028 wpri_val |= (env->mmte & ~SMTE_MASK);
2029 write_mmte(env, csrno, wpri_val);
2030 return RISCV_EXCP_NONE;
2031}
2032
2033static RISCVException read_umte(CPURISCVState *env, int csrno,
2034 target_ulong *val)
2035{
2036 *val = env->mmte & UMTE_MASK;
2037 return RISCV_EXCP_NONE;
2038}
2039
2040static RISCVException write_umte(CPURISCVState *env, int csrno,
2041 target_ulong val)
2042{
2043 target_ulong wpri_val = val & UMTE_MASK;
2044
2045 if (val != wpri_val) {
2046 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2047 "UMTE: WPRI violation written 0x", val,
2048 "vs expected 0x", wpri_val);
2049 }
2050
2051 if (check_pm_current_disabled(env, csrno)) {
2052 return RISCV_EXCP_NONE;
2053 }
2054
2055 wpri_val |= (env->mmte & ~UMTE_MASK);
2056 write_mmte(env, csrno, wpri_val);
2057 return RISCV_EXCP_NONE;
2058}
2059
2060static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
2061 target_ulong *val)
2062{
2063 *val = env->mpmmask;
2064 return RISCV_EXCP_NONE;
2065}
2066
2067static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
2068 target_ulong val)
2069{
2070 uint64_t mstatus;
2071
2072 env->mpmmask = val;
40bfa5f6
LZ
2073 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
2074 env->cur_pmmask = val;
2075 }
4bbe8033
AB
2076 env->mmte |= PM_EXT_DIRTY;
2077
2078 /* Set XS and SD bits, since PM CSRs are dirty */
2079 mstatus = env->mstatus | MSTATUS_XS;
2080 write_mstatus(env, csrno, mstatus);
2081 return RISCV_EXCP_NONE;
2082}
2083
2084static RISCVException read_spmmask(CPURISCVState *env, int csrno,
2085 target_ulong *val)
2086{
2087 *val = env->spmmask;
2088 return RISCV_EXCP_NONE;
2089}
2090
2091static RISCVException write_spmmask(CPURISCVState *env, int csrno,
2092 target_ulong val)
2093{
2094 uint64_t mstatus;
2095
2096 /* if pm.current==0 we can't modify current PM CSRs */
2097 if (check_pm_current_disabled(env, csrno)) {
2098 return RISCV_EXCP_NONE;
2099 }
2100 env->spmmask = val;
40bfa5f6
LZ
2101 if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
2102 env->cur_pmmask = val;
2103 }
4bbe8033
AB
2104 env->mmte |= PM_EXT_DIRTY;
2105
2106 /* Set XS and SD bits, since PM CSRs are dirty */
2107 mstatus = env->mstatus | MSTATUS_XS;
2108 write_mstatus(env, csrno, mstatus);
2109 return RISCV_EXCP_NONE;
2110}
2111
2112static RISCVException read_upmmask(CPURISCVState *env, int csrno,
2113 target_ulong *val)
2114{
2115 *val = env->upmmask;
2116 return RISCV_EXCP_NONE;
2117}
2118
2119static RISCVException write_upmmask(CPURISCVState *env, int csrno,
2120 target_ulong val)
2121{
2122 uint64_t mstatus;
2123
2124 /* if pm.current==0 we can't modify current PM CSRs */
2125 if (check_pm_current_disabled(env, csrno)) {
2126 return RISCV_EXCP_NONE;
2127 }
2128 env->upmmask = val;
40bfa5f6
LZ
2129 if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
2130 env->cur_pmmask = val;
2131 }
4bbe8033
AB
2132 env->mmte |= PM_EXT_DIRTY;
2133
2134 /* Set XS and SD bits, since PM CSRs are dirty */
2135 mstatus = env->mstatus | MSTATUS_XS;
2136 write_mstatus(env, csrno, mstatus);
2137 return RISCV_EXCP_NONE;
2138}
2139
2140static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
2141 target_ulong *val)
2142{
2143 *val = env->mpmbase;
2144 return RISCV_EXCP_NONE;
2145}
2146
2147static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
2148 target_ulong val)
2149{
2150 uint64_t mstatus;
2151
2152 env->mpmbase = val;
40bfa5f6
LZ
2153 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
2154 env->cur_pmbase = val;
2155 }
4bbe8033
AB
2156 env->mmte |= PM_EXT_DIRTY;
2157
2158 /* Set XS and SD bits, since PM CSRs are dirty */
2159 mstatus = env->mstatus | MSTATUS_XS;
2160 write_mstatus(env, csrno, mstatus);
2161 return RISCV_EXCP_NONE;
2162}
2163
2164static RISCVException read_spmbase(CPURISCVState *env, int csrno,
2165 target_ulong *val)
2166{
2167 *val = env->spmbase;
2168 return RISCV_EXCP_NONE;
2169}
2170
2171static RISCVException write_spmbase(CPURISCVState *env, int csrno,
2172 target_ulong val)
2173{
2174 uint64_t mstatus;
2175
2176 /* if pm.current==0 we can't modify current PM CSRs */
2177 if (check_pm_current_disabled(env, csrno)) {
2178 return RISCV_EXCP_NONE;
2179 }
2180 env->spmbase = val;
40bfa5f6
LZ
2181 if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
2182 env->cur_pmbase = val;
2183 }
4bbe8033
AB
2184 env->mmte |= PM_EXT_DIRTY;
2185
2186 /* Set XS and SD bits, since PM CSRs are dirty */
2187 mstatus = env->mstatus | MSTATUS_XS;
2188 write_mstatus(env, csrno, mstatus);
2189 return RISCV_EXCP_NONE;
2190}
2191
2192static RISCVException read_upmbase(CPURISCVState *env, int csrno,
2193 target_ulong *val)
2194{
2195 *val = env->upmbase;
2196 return RISCV_EXCP_NONE;
2197}
2198
2199static RISCVException write_upmbase(CPURISCVState *env, int csrno,
2200 target_ulong val)
2201{
2202 uint64_t mstatus;
2203
2204 /* if pm.current==0 we can't modify current PM CSRs */
2205 if (check_pm_current_disabled(env, csrno)) {
2206 return RISCV_EXCP_NONE;
2207 }
2208 env->upmbase = val;
40bfa5f6
LZ
2209 if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
2210 env->cur_pmbase = val;
2211 }
4bbe8033
AB
2212 env->mmte |= PM_EXT_DIRTY;
2213
2214 /* Set XS and SD bits, since PM CSRs are dirty */
2215 mstatus = env->mstatus | MSTATUS_XS;
2216 write_mstatus(env, csrno, mstatus);
2217 return RISCV_EXCP_NONE;
2218}
2219
c7b95171
MC
2220#endif
2221
2222/*
2223 * riscv_csrrw - read and/or update control and status register
2224 *
2225 * csrr <-> riscv_csrrw(env, csrno, ret_value, 0, 0);
2226 * csrrw <-> riscv_csrrw(env, csrno, ret_value, value, -1);
2227 * csrrs <-> riscv_csrrw(env, csrno, ret_value, -1, value);
2228 * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value);
2229 */
2230
457c360f
FP
2231static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
2232 int csrno,
2233 bool write_mask,
2234 RISCVCPU *cpu)
c7b95171 2235{
65e728a2 2236 /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
457c360f 2237 int read_only = get_field(csrno, 0xC00) == 3;
c7b95171 2238#if !defined(CONFIG_USER_ONLY)
0a42f4c4 2239 int effective_priv = env->priv;
0a42f4c4
AF
2240
2241 if (riscv_has_ext(env, RVH) &&
2242 env->priv == PRV_S &&
2243 !riscv_cpu_virt_enabled(env)) {
2244 /*
2245 * We are in S mode without virtualisation, therefore we are in HS Mode.
2246 * Add 1 to the effective privledge level to allow us to access the
2247 * Hypervisor CSRs.
2248 */
2249 effective_priv++;
e6e03dcf 2250 }
0a42f4c4 2251
42109837 2252 if (!env->debugger && (effective_priv < get_field(csrno, 0x300))) {
533c91e8 2253 return RISCV_EXCP_ILLEGAL_INST;
c7b95171
MC
2254 }
2255#endif
42109837
LZ
2256 if (write_mask && read_only) {
2257 return RISCV_EXCP_ILLEGAL_INST;
2258 }
c7b95171 2259
591bddea
PD
2260 /* ensure the CSR extension is enabled. */
2261 if (!cpu->cfg.ext_icsr) {
533c91e8 2262 return RISCV_EXCP_ILLEGAL_INST;
591bddea
PD
2263 }
2264
a88365c1 2265 /* check predicate */
e39a8320 2266 if (!csr_ops[csrno].predicate) {
533c91e8 2267 return RISCV_EXCP_ILLEGAL_INST;
a88365c1 2268 }
457c360f
FP
2269
2270 return csr_ops[csrno].predicate(env, csrno);
2271}
2272
2273static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
2274 target_ulong *ret_value,
2275 target_ulong new_value,
2276 target_ulong write_mask)
2277{
2278 RISCVException ret;
2279 target_ulong old_value;
a88365c1 2280
c7b95171
MC
2281 /* execute combined read/write operation if it exists */
2282 if (csr_ops[csrno].op) {
533c91e8 2283 return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
c7b95171
MC
2284 }
2285
2286 /* if no accessor exists then return failure */
2287 if (!csr_ops[csrno].read) {
533c91e8 2288 return RISCV_EXCP_ILLEGAL_INST;
c7b95171 2289 }
c7b95171
MC
2290 /* read old value */
2291 ret = csr_ops[csrno].read(env, csrno, &old_value);
605def6e 2292 if (ret != RISCV_EXCP_NONE) {
533c91e8 2293 return ret;
c7b95171
MC
2294 }
2295
2296 /* write value if writable and write mask set, otherwise drop writes */
2297 if (write_mask) {
2298 new_value = (old_value & ~write_mask) | (new_value & write_mask);
2299 if (csr_ops[csrno].write) {
2300 ret = csr_ops[csrno].write(env, csrno, new_value);
605def6e 2301 if (ret != RISCV_EXCP_NONE) {
533c91e8 2302 return ret;
c7b95171
MC
2303 }
2304 }
2305 }
2306
2307 /* return old value */
2308 if (ret_value) {
2309 *ret_value = old_value;
2310 }
2311
533c91e8 2312 return RISCV_EXCP_NONE;
c7b95171
MC
2313}
2314
457c360f
FP
2315RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
2316 target_ulong *ret_value,
2317 target_ulong new_value, target_ulong write_mask)
2318{
2319 RISCVCPU *cpu = env_archcpu(env);
2320
2321 RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu);
2322 if (ret != RISCV_EXCP_NONE) {
2323 return ret;
2324 }
2325
2326 return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
2327}
2328
2329static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
2330 Int128 *ret_value,
2331 Int128 new_value,
2332 Int128 write_mask)
961738ff 2333{
457c360f
FP
2334 RISCVException ret;
2335 Int128 old_value;
2336
2337 /* read old value */
2338 ret = csr_ops[csrno].read128(env, csrno, &old_value);
2339 if (ret != RISCV_EXCP_NONE) {
2340 return ret;
2341 }
2342
2343 /* write value if writable and write mask set, otherwise drop writes */
2344 if (int128_nz(write_mask)) {
2345 new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
2346 int128_and(new_value, write_mask));
2347 if (csr_ops[csrno].write128) {
2348 ret = csr_ops[csrno].write128(env, csrno, new_value);
2349 if (ret != RISCV_EXCP_NONE) {
2350 return ret;
2351 }
2352 } else if (csr_ops[csrno].write) {
2353 /* avoids having to write wrappers for all registers */
2354 ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
2355 if (ret != RISCV_EXCP_NONE) {
2356 return ret;
2357 }
2358 }
2359 }
961738ff 2360
457c360f 2361 /* return old value */
961738ff 2362 if (ret_value) {
457c360f
FP
2363 *ret_value = old_value;
2364 }
2365
2366 return RISCV_EXCP_NONE;
2367}
2368
2369RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
2370 Int128 *ret_value,
2371 Int128 new_value, Int128 write_mask)
2372{
2373 RISCVException ret;
2374 RISCVCPU *cpu = env_archcpu(env);
2375
2376 ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu);
2377 if (ret != RISCV_EXCP_NONE) {
2378 return ret;
961738ff
FP
2379 }
2380
457c360f
FP
2381 if (csr_ops[csrno].read128) {
2382 return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
2383 }
2384
2385 /*
2386 * Fall back to 64-bit version for now, if the 128-bit alternative isn't
2387 * at all defined.
2388 * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
2389 * significant), for those, this fallback is correctly handling the accesses
2390 */
2391 target_ulong old_value;
2392 ret = riscv_csrrw_do64(env, csrno, &old_value,
2393 int128_getlo(new_value),
2394 int128_getlo(write_mask));
2395 if (ret == RISCV_EXCP_NONE && ret_value) {
2396 *ret_value = int128_make64(old_value);
2397 }
961738ff
FP
2398 return ret;
2399}
2400
753e3fe2
JW
2401/*
2402 * Debugger support. If not in user mode, set env->debugger before the
2403 * riscv_csrrw call and clear it after the call.
2404 */
533c91e8
AF
2405RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
2406 target_ulong *ret_value,
2407 target_ulong new_value,
2408 target_ulong write_mask)
753e3fe2 2409{
533c91e8 2410 RISCVException ret;
753e3fe2
JW
2411#if !defined(CONFIG_USER_ONLY)
2412 env->debugger = true;
2413#endif
2414 ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
2415#if !defined(CONFIG_USER_ONLY)
2416 env->debugger = false;
2417#endif
2418 return ret;
2419}
2420
c7b95171 2421/* Control and Status Register function table */
56118ee8 2422riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
c7b95171 2423 /* User Floating-Point CSRs */
8ceac5dc
BM
2424 [CSR_FFLAGS] = { "fflags", fs, read_fflags, write_fflags },
2425 [CSR_FRM] = { "frm", fs, read_frm, write_frm },
2426 [CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr },
8e3a1f18 2427 /* Vector CSRs */
8ceac5dc
BM
2428 [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart },
2429 [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat },
2430 [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm },
4594fa5a 2431 [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr },
8ceac5dc
BM
2432 [CSR_VL] = { "vl", vs, read_vl },
2433 [CSR_VTYPE] = { "vtype", vs, read_vtype },
2e565054 2434 [CSR_VLENB] = { "vlenb", vs, read_vlenb },
c7b95171 2435 /* User Timers and Counters */
8ceac5dc
BM
2436 [CSR_CYCLE] = { "cycle", ctr, read_instret },
2437 [CSR_INSTRET] = { "instret", ctr, read_instret },
2438 [CSR_CYCLEH] = { "cycleh", ctr32, read_instreth },
2439 [CSR_INSTRETH] = { "instreth", ctr32, read_instreth },
2440
2441 /*
2442 * In privileged mode, the monitor will have to emulate TIME CSRs only if
2443 * rdtime callback is not provided by machine/platform emulation.
2444 */
2445 [CSR_TIME] = { "time", ctr, read_time },
2446 [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
c7b95171
MC
2447
2448#if !defined(CONFIG_USER_ONLY)
2449 /* Machine Timers and Counters */
8ceac5dc
BM
2450 [CSR_MCYCLE] = { "mcycle", any, read_instret },
2451 [CSR_MINSTRET] = { "minstret", any, read_instret },
2452 [CSR_MCYCLEH] = { "mcycleh", any32, read_instreth },
2453 [CSR_MINSTRETH] = { "minstreth", any32, read_instreth },
c7b95171
MC
2454
2455 /* Machine Information Registers */
8ceac5dc
BM
2456 [CSR_MVENDORID] = { "mvendorid", any, read_zero },
2457 [CSR_MARCHID] = { "marchid", any, read_zero },
2458 [CSR_MIMPID] = { "mimpid", any, read_zero },
2459 [CSR_MHARTID] = { "mhartid", any, read_mhartid },
c7b95171
MC
2460
2461 /* Machine Trap Setup */
457c360f
FP
2462 [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL,
2463 read_mstatus_i128 },
2464 [CSR_MISA] = { "misa", any, read_misa, write_misa, NULL,
2465 read_misa_i128 },
d028ac75 2466 [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg },
8ceac5dc 2467 [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
d028ac75 2468 [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
8ceac5dc
BM
2469 [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
2470 [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, write_mcounteren },
c7b95171 2471
8ceac5dc 2472 [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush },
551fa7e8 2473
c7b95171 2474 /* Machine Trap Handling */
457c360f
FP
2475 [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch, NULL,
2476 read_mscratch_i128, write_mscratch_i128 },
8ceac5dc
BM
2477 [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc },
2478 [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause },
ac12b601 2479 [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval },
8ceac5dc 2480 [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip },
c7b95171 2481
d028ac75
AP
2482 /* Machine-Level High-Half CSRs (AIA) */
2483 [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
2484 [CSR_MIEH] = { "mieh", aia_any32, NULL, NULL, rmw_mieh },
2485 [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
2486
c7b95171 2487 /* Supervisor Trap Setup */
457c360f
FP
2488 [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
2489 read_sstatus_i128 },
d028ac75 2490 [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie },
8ceac5dc
BM
2491 [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
2492 [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren },
c7b95171
MC
2493
2494 /* Supervisor Trap Handling */
457c360f
FP
2495 [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, NULL,
2496 read_sscratch_i128, write_sscratch_i128 },
8ceac5dc
BM
2497 [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc },
2498 [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
ac12b601 2499 [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
8ceac5dc 2500 [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
c7b95171
MC
2501
2502 /* Supervisor Protection and Translation */
8ceac5dc
BM
2503 [CSR_SATP] = { "satp", smode, read_satp, write_satp },
2504
d028ac75
AP
2505 /* Supervisor-Level High-Half CSRs (AIA) */
2506 [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh },
2507 [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph },
2508
8ceac5dc
BM
2509 [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus },
2510 [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg },
d028ac75 2511 [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg },
8ceac5dc
BM
2512 [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip },
2513 [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip },
d028ac75 2514 [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie },
8ceac5dc 2515 [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren },
cd032fe7 2516 [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie },
8ceac5dc
BM
2517 [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval },
2518 [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst },
cd032fe7 2519 [CSR_HGEIP] = { "hgeip", hmode, read_hgeip, NULL },
8ceac5dc
BM
2520 [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp },
2521 [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta },
2522 [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah },
2523
2524 [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus },
2525 [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip },
d028ac75 2526 [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie },
8ceac5dc
BM
2527 [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec },
2528 [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch },
2529 [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc },
2530 [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause },
2531 [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval },
2532 [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp },
2533
2534 [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2 },
2535 [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst },
34cfb5f6 2536
d028ac75
AP
2537 /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
2538 [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh },
2539 [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph },
2540 [CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh },
2541 [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph },
2542
c7b95171 2543 /* Physical Memory Protection */
2582a95c 2544 [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg },
8ceac5dc
BM
2545 [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
2546 [CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
2547 [CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
2548 [CSR_PMPCFG3] = { "pmpcfg3", pmp, read_pmpcfg, write_pmpcfg },
2549 [CSR_PMPADDR0] = { "pmpaddr0", pmp, read_pmpaddr, write_pmpaddr },
2550 [CSR_PMPADDR1] = { "pmpaddr1", pmp, read_pmpaddr, write_pmpaddr },
2551 [CSR_PMPADDR2] = { "pmpaddr2", pmp, read_pmpaddr, write_pmpaddr },
2552 [CSR_PMPADDR3] = { "pmpaddr3", pmp, read_pmpaddr, write_pmpaddr },
2553 [CSR_PMPADDR4] = { "pmpaddr4", pmp, read_pmpaddr, write_pmpaddr },
2554 [CSR_PMPADDR5] = { "pmpaddr5", pmp, read_pmpaddr, write_pmpaddr },
2555 [CSR_PMPADDR6] = { "pmpaddr6", pmp, read_pmpaddr, write_pmpaddr },
2556 [CSR_PMPADDR7] = { "pmpaddr7", pmp, read_pmpaddr, write_pmpaddr },
2557 [CSR_PMPADDR8] = { "pmpaddr8", pmp, read_pmpaddr, write_pmpaddr },
2558 [CSR_PMPADDR9] = { "pmpaddr9", pmp, read_pmpaddr, write_pmpaddr },
2559 [CSR_PMPADDR10] = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
2560 [CSR_PMPADDR11] = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
2561 [CSR_PMPADDR12] = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
2562 [CSR_PMPADDR13] = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
2563 [CSR_PMPADDR14] = { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
2564 [CSR_PMPADDR15] = { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
c7b95171 2565
4bbe8033
AB
2566 /* User Pointer Masking */
2567 [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
2568 [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask, write_upmmask },
2569 [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase, write_upmbase },
2570 /* Machine Pointer Masking */
2571 [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
2572 [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask, write_mpmmask },
2573 [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase, write_mpmbase },
2574 /* Supervisor Pointer Masking */
2575 [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
2576 [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask, write_spmmask },
2577 [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase, write_spmbase },
2578
c7b95171 2579 /* Performance Counters */
8ceac5dc
BM
2580 [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_zero },
2581 [CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_zero },
2582 [CSR_HPMCOUNTER5] = { "hpmcounter5", ctr, read_zero },
2583 [CSR_HPMCOUNTER6] = { "hpmcounter6", ctr, read_zero },
2584 [CSR_HPMCOUNTER7] = { "hpmcounter7", ctr, read_zero },
2585 [CSR_HPMCOUNTER8] = { "hpmcounter8", ctr, read_zero },
2586 [CSR_HPMCOUNTER9] = { "hpmcounter9", ctr, read_zero },
2587 [CSR_HPMCOUNTER10] = { "hpmcounter10", ctr, read_zero },
2588 [CSR_HPMCOUNTER11] = { "hpmcounter11", ctr, read_zero },
2589 [CSR_HPMCOUNTER12] = { "hpmcounter12", ctr, read_zero },
2590 [CSR_HPMCOUNTER13] = { "hpmcounter13", ctr, read_zero },
2591 [CSR_HPMCOUNTER14] = { "hpmcounter14", ctr, read_zero },
2592 [CSR_HPMCOUNTER15] = { "hpmcounter15", ctr, read_zero },
2593 [CSR_HPMCOUNTER16] = { "hpmcounter16", ctr, read_zero },
2594 [CSR_HPMCOUNTER17] = { "hpmcounter17", ctr, read_zero },
2595 [CSR_HPMCOUNTER18] = { "hpmcounter18", ctr, read_zero },
2596 [CSR_HPMCOUNTER19] = { "hpmcounter19", ctr, read_zero },
2597 [CSR_HPMCOUNTER20] = { "hpmcounter20", ctr, read_zero },
2598 [CSR_HPMCOUNTER21] = { "hpmcounter21", ctr, read_zero },
2599 [CSR_HPMCOUNTER22] = { "hpmcounter22", ctr, read_zero },
2600 [CSR_HPMCOUNTER23] = { "hpmcounter23", ctr, read_zero },
2601 [CSR_HPMCOUNTER24] = { "hpmcounter24", ctr, read_zero },
2602 [CSR_HPMCOUNTER25] = { "hpmcounter25", ctr, read_zero },
2603 [CSR_HPMCOUNTER26] = { "hpmcounter26", ctr, read_zero },
2604 [CSR_HPMCOUNTER27] = { "hpmcounter27", ctr, read_zero },
2605 [CSR_HPMCOUNTER28] = { "hpmcounter28", ctr, read_zero },
2606 [CSR_HPMCOUNTER29] = { "hpmcounter29", ctr, read_zero },
2607 [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_zero },
2608 [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_zero },
2609
2610 [CSR_MHPMCOUNTER3] = { "mhpmcounter3", any, read_zero },
2611 [CSR_MHPMCOUNTER4] = { "mhpmcounter4", any, read_zero },
2612 [CSR_MHPMCOUNTER5] = { "mhpmcounter5", any, read_zero },
2613 [CSR_MHPMCOUNTER6] = { "mhpmcounter6", any, read_zero },
2614 [CSR_MHPMCOUNTER7] = { "mhpmcounter7", any, read_zero },
2615 [CSR_MHPMCOUNTER8] = { "mhpmcounter8", any, read_zero },
2616 [CSR_MHPMCOUNTER9] = { "mhpmcounter9", any, read_zero },
2617 [CSR_MHPMCOUNTER10] = { "mhpmcounter10", any, read_zero },
2618 [CSR_MHPMCOUNTER11] = { "mhpmcounter11", any, read_zero },
2619 [CSR_MHPMCOUNTER12] = { "mhpmcounter12", any, read_zero },
2620 [CSR_MHPMCOUNTER13] = { "mhpmcounter13", any, read_zero },
2621 [CSR_MHPMCOUNTER14] = { "mhpmcounter14", any, read_zero },
2622 [CSR_MHPMCOUNTER15] = { "mhpmcounter15", any, read_zero },
2623 [CSR_MHPMCOUNTER16] = { "mhpmcounter16", any, read_zero },
2624 [CSR_MHPMCOUNTER17] = { "mhpmcounter17", any, read_zero },
2625 [CSR_MHPMCOUNTER18] = { "mhpmcounter18", any, read_zero },
2626 [CSR_MHPMCOUNTER19] = { "mhpmcounter19", any, read_zero },
2627 [CSR_MHPMCOUNTER20] = { "mhpmcounter20", any, read_zero },
2628 [CSR_MHPMCOUNTER21] = { "mhpmcounter21", any, read_zero },
2629 [CSR_MHPMCOUNTER22] = { "mhpmcounter22", any, read_zero },
2630 [CSR_MHPMCOUNTER23] = { "mhpmcounter23", any, read_zero },
2631 [CSR_MHPMCOUNTER24] = { "mhpmcounter24", any, read_zero },
2632 [CSR_MHPMCOUNTER25] = { "mhpmcounter25", any, read_zero },
2633 [CSR_MHPMCOUNTER26] = { "mhpmcounter26", any, read_zero },
2634 [CSR_MHPMCOUNTER27] = { "mhpmcounter27", any, read_zero },
2635 [CSR_MHPMCOUNTER28] = { "mhpmcounter28", any, read_zero },
2636 [CSR_MHPMCOUNTER29] = { "mhpmcounter29", any, read_zero },
2637 [CSR_MHPMCOUNTER30] = { "mhpmcounter30", any, read_zero },
2638 [CSR_MHPMCOUNTER31] = { "mhpmcounter31", any, read_zero },
2639
2640 [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_zero },
2641 [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_zero },
2642 [CSR_MHPMEVENT5] = { "mhpmevent5", any, read_zero },
2643 [CSR_MHPMEVENT6] = { "mhpmevent6", any, read_zero },
2644 [CSR_MHPMEVENT7] = { "mhpmevent7", any, read_zero },
2645 [CSR_MHPMEVENT8] = { "mhpmevent8", any, read_zero },
2646 [CSR_MHPMEVENT9] = { "mhpmevent9", any, read_zero },
2647 [CSR_MHPMEVENT10] = { "mhpmevent10", any, read_zero },
2648 [CSR_MHPMEVENT11] = { "mhpmevent11", any, read_zero },
2649 [CSR_MHPMEVENT12] = { "mhpmevent12", any, read_zero },
2650 [CSR_MHPMEVENT13] = { "mhpmevent13", any, read_zero },
2651 [CSR_MHPMEVENT14] = { "mhpmevent14", any, read_zero },
2652 [CSR_MHPMEVENT15] = { "mhpmevent15", any, read_zero },
2653 [CSR_MHPMEVENT16] = { "mhpmevent16", any, read_zero },
2654 [CSR_MHPMEVENT17] = { "mhpmevent17", any, read_zero },
2655 [CSR_MHPMEVENT18] = { "mhpmevent18", any, read_zero },
2656 [CSR_MHPMEVENT19] = { "mhpmevent19", any, read_zero },
2657 [CSR_MHPMEVENT20] = { "mhpmevent20", any, read_zero },
2658 [CSR_MHPMEVENT21] = { "mhpmevent21", any, read_zero },
2659 [CSR_MHPMEVENT22] = { "mhpmevent22", any, read_zero },
2660 [CSR_MHPMEVENT23] = { "mhpmevent23", any, read_zero },
2661 [CSR_MHPMEVENT24] = { "mhpmevent24", any, read_zero },
2662 [CSR_MHPMEVENT25] = { "mhpmevent25", any, read_zero },
2663 [CSR_MHPMEVENT26] = { "mhpmevent26", any, read_zero },
2664 [CSR_MHPMEVENT27] = { "mhpmevent27", any, read_zero },
2665 [CSR_MHPMEVENT28] = { "mhpmevent28", any, read_zero },
2666 [CSR_MHPMEVENT29] = { "mhpmevent29", any, read_zero },
2667 [CSR_MHPMEVENT30] = { "mhpmevent30", any, read_zero },
2668 [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_zero },
2669
2670 [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_zero },
2671 [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_zero },
2672 [CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_zero },
2673 [CSR_HPMCOUNTER6H] = { "hpmcounter6h", ctr32, read_zero },
2674 [CSR_HPMCOUNTER7H] = { "hpmcounter7h", ctr32, read_zero },
2675 [CSR_HPMCOUNTER8H] = { "hpmcounter8h", ctr32, read_zero },
2676 [CSR_HPMCOUNTER9H] = { "hpmcounter9h", ctr32, read_zero },
2677 [CSR_HPMCOUNTER10H] = { "hpmcounter10h", ctr32, read_zero },
2678 [CSR_HPMCOUNTER11H] = { "hpmcounter11h", ctr32, read_zero },
2679 [CSR_HPMCOUNTER12H] = { "hpmcounter12h", ctr32, read_zero },
2680 [CSR_HPMCOUNTER13H] = { "hpmcounter13h", ctr32, read_zero },
2681 [CSR_HPMCOUNTER14H] = { "hpmcounter14h", ctr32, read_zero },
2682 [CSR_HPMCOUNTER15H] = { "hpmcounter15h", ctr32, read_zero },
2683 [CSR_HPMCOUNTER16H] = { "hpmcounter16h", ctr32, read_zero },
2684 [CSR_HPMCOUNTER17H] = { "hpmcounter17h", ctr32, read_zero },
2685 [CSR_HPMCOUNTER18H] = { "hpmcounter18h", ctr32, read_zero },
2686 [CSR_HPMCOUNTER19H] = { "hpmcounter19h", ctr32, read_zero },
2687 [CSR_HPMCOUNTER20H] = { "hpmcounter20h", ctr32, read_zero },
2688 [CSR_HPMCOUNTER21H] = { "hpmcounter21h", ctr32, read_zero },
2689 [CSR_HPMCOUNTER22H] = { "hpmcounter22h", ctr32, read_zero },
2690 [CSR_HPMCOUNTER23H] = { "hpmcounter23h", ctr32, read_zero },
2691 [CSR_HPMCOUNTER24H] = { "hpmcounter24h", ctr32, read_zero },
2692 [CSR_HPMCOUNTER25H] = { "hpmcounter25h", ctr32, read_zero },
2693 [CSR_HPMCOUNTER26H] = { "hpmcounter26h", ctr32, read_zero },
2694 [CSR_HPMCOUNTER27H] = { "hpmcounter27h", ctr32, read_zero },
2695 [CSR_HPMCOUNTER28H] = { "hpmcounter28h", ctr32, read_zero },
2696 [CSR_HPMCOUNTER29H] = { "hpmcounter29h", ctr32, read_zero },
2697 [CSR_HPMCOUNTER30H] = { "hpmcounter30h", ctr32, read_zero },
2698 [CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_zero },
2699
2700 [CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", any32, read_zero },
2701 [CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", any32, read_zero },
2702 [CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", any32, read_zero },
2703 [CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", any32, read_zero },
2704 [CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", any32, read_zero },
2705 [CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", any32, read_zero },
2706 [CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", any32, read_zero },
2707 [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32, read_zero },
2708 [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32, read_zero },
2709 [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32, read_zero },
2710 [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32, read_zero },
2711 [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32, read_zero },
2712 [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32, read_zero },
2713 [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32, read_zero },
2714 [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32, read_zero },
2715 [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32, read_zero },
2716 [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32, read_zero },
2717 [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32, read_zero },
2718 [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32, read_zero },
2719 [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32, read_zero },
2720 [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32, read_zero },
2721 [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32, read_zero },
2722 [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32, read_zero },
2723 [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32, read_zero },
2724 [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32, read_zero },
2725 [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32, read_zero },
2726 [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32, read_zero },
2727 [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32, read_zero },
2728 [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32, read_zero },
c7b95171
MC
2729#endif /* !CONFIG_USER_ONLY */
2730};