]> git.proxmox.com Git - mirror_qemu.git/blame - target/riscv/csr.c
target/riscv: rvk: add support for zksed/zksh extension
[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"
b8012ecf 22#include "qemu/timer.h"
c7b95171
MC
23#include "cpu.h"
24#include "qemu/main-loop.h"
25#include "exec/exec-all.h"
03ff4f8d 26#include "sysemu/cpu-timers.h"
c7b95171 27
c7b95171
MC
28/* CSR function table public API */
29void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
30{
31 *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
32}
33
34void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
35{
36 csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
37}
38
a88365c1 39/* Predicates */
0e62f92e 40static RISCVException fs(CPURISCVState *env, int csrno)
a88365c1
MC
41{
42#if !defined(CONFIG_USER_ONLY)
c163b3ba
WL
43 if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
44 !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
0e62f92e 45 return RISCV_EXCP_ILLEGAL_INST;
a88365c1
MC
46 }
47#endif
0e62f92e 48 return RISCV_EXCP_NONE;
a88365c1
MC
49}
50
0e62f92e 51static RISCVException vs(CPURISCVState *env, int csrno)
8e3a1f18 52{
b4a99d40
FC
53 CPUState *cs = env_cpu(env);
54 RISCVCPU *cpu = RISCV_CPU(cs);
55
56 if (env->misa_ext & RVV ||
32e579b8 57 cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
6bc3dfa9
FC
58#if !defined(CONFIG_USER_ONLY)
59 if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
60 return RISCV_EXCP_ILLEGAL_INST;
61 }
62#endif
0e62f92e 63 return RISCV_EXCP_NONE;
8e3a1f18 64 }
0e62f92e 65 return RISCV_EXCP_ILLEGAL_INST;
8e3a1f18
LZ
66}
67
0e62f92e 68static RISCVException ctr(CPURISCVState *env, int csrno)
a88365c1
MC
69{
70#if !defined(CONFIG_USER_ONLY)
0a13a5b8
AF
71 CPUState *cs = env_cpu(env);
72 RISCVCPU *cpu = RISCV_CPU(cs);
0a13a5b8
AF
73
74 if (!cpu->cfg.ext_counters) {
75 /* The Counters extensions is not enabled */
0e62f92e 76 return RISCV_EXCP_ILLEGAL_INST;
0a13a5b8 77 }
e39a8320
AF
78
79 if (riscv_cpu_virt_enabled(env)) {
80 switch (csrno) {
81 case CSR_CYCLE:
db70794e
BM
82 if (!get_field(env->hcounteren, COUNTEREN_CY) &&
83 get_field(env->mcounteren, COUNTEREN_CY)) {
0e62f92e 84 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
e39a8320
AF
85 }
86 break;
87 case CSR_TIME:
db70794e
BM
88 if (!get_field(env->hcounteren, COUNTEREN_TM) &&
89 get_field(env->mcounteren, COUNTEREN_TM)) {
0e62f92e 90 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
e39a8320
AF
91 }
92 break;
93 case CSR_INSTRET:
db70794e
BM
94 if (!get_field(env->hcounteren, COUNTEREN_IR) &&
95 get_field(env->mcounteren, COUNTEREN_IR)) {
0e62f92e 96 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
e39a8320
AF
97 }
98 break;
99 case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
100 if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
101 get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
0e62f92e 102 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
e39a8320
AF
103 }
104 break;
8987cdc4 105 }
db23e5d9 106 if (riscv_cpu_mxl(env) == MXL_RV32) {
8987cdc4
AF
107 switch (csrno) {
108 case CSR_CYCLEH:
db70794e
BM
109 if (!get_field(env->hcounteren, COUNTEREN_CY) &&
110 get_field(env->mcounteren, COUNTEREN_CY)) {
0e62f92e 111 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
8987cdc4
AF
112 }
113 break;
114 case CSR_TIMEH:
db70794e
BM
115 if (!get_field(env->hcounteren, COUNTEREN_TM) &&
116 get_field(env->mcounteren, COUNTEREN_TM)) {
0e62f92e 117 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
8987cdc4
AF
118 }
119 break;
120 case CSR_INSTRETH:
db70794e
BM
121 if (!get_field(env->hcounteren, COUNTEREN_IR) &&
122 get_field(env->mcounteren, COUNTEREN_IR)) {
0e62f92e 123 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
8987cdc4
AF
124 }
125 break;
126 case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
127 if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
128 get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
0e62f92e 129 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
8987cdc4
AF
130 }
131 break;
e39a8320 132 }
e39a8320
AF
133 }
134 }
a88365c1 135#endif
0e62f92e 136 return RISCV_EXCP_NONE;
a88365c1
MC
137}
138
0e62f92e 139static RISCVException ctr32(CPURISCVState *env, int csrno)
8987cdc4 140{
db23e5d9 141 if (riscv_cpu_mxl(env) != MXL_RV32) {
0e62f92e 142 return RISCV_EXCP_ILLEGAL_INST;
8987cdc4
AF
143 }
144
145 return ctr(env, csrno);
146}
147
a88365c1 148#if !defined(CONFIG_USER_ONLY)
0e62f92e 149static RISCVException any(CPURISCVState *env, int csrno)
a88365c1 150{
0e62f92e 151 return RISCV_EXCP_NONE;
a88365c1
MC
152}
153
0e62f92e 154static RISCVException any32(CPURISCVState *env, int csrno)
8987cdc4 155{
db23e5d9 156 if (riscv_cpu_mxl(env) != MXL_RV32) {
0e62f92e 157 return RISCV_EXCP_ILLEGAL_INST;
8987cdc4
AF
158 }
159
160 return any(env, csrno);
161
162}
163
d0237b4d
AP
164static int aia_any(CPURISCVState *env, int csrno)
165{
166 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
167 return RISCV_EXCP_ILLEGAL_INST;
168 }
169
170 return any(env, csrno);
171}
172
d028ac75
AP
173static int aia_any32(CPURISCVState *env, int csrno)
174{
175 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
176 return RISCV_EXCP_ILLEGAL_INST;
177 }
178
179 return any32(env, csrno);
180}
181
0e62f92e 182static RISCVException smode(CPURISCVState *env, int csrno)
a88365c1 183{
0e62f92e
AF
184 if (riscv_has_ext(env, RVS)) {
185 return RISCV_EXCP_NONE;
186 }
187
188 return RISCV_EXCP_ILLEGAL_INST;
a88365c1
MC
189}
190
d028ac75
AP
191static int smode32(CPURISCVState *env, int csrno)
192{
193 if (riscv_cpu_mxl(env) != MXL_RV32) {
194 return RISCV_EXCP_ILLEGAL_INST;
195 }
196
197 return smode(env, csrno);
198}
199
c7de92b4
AP
200static int aia_smode(CPURISCVState *env, int csrno)
201{
202 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
203 return RISCV_EXCP_ILLEGAL_INST;
204 }
205
206 return smode(env, csrno);
207}
208
d028ac75
AP
209static int aia_smode32(CPURISCVState *env, int csrno)
210{
211 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
212 return RISCV_EXCP_ILLEGAL_INST;
213 }
214
215 return smode32(env, csrno);
216}
217
0e62f92e 218static RISCVException hmode(CPURISCVState *env, int csrno)
ff2cc129
AF
219{
220 if (riscv_has_ext(env, RVS) &&
221 riscv_has_ext(env, RVH)) {
222 /* Hypervisor extension is supported */
223 if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
224 env->priv == PRV_M) {
0e62f92e 225 return RISCV_EXCP_NONE;
e39a8320 226 } else {
0e62f92e 227 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
ff2cc129
AF
228 }
229 }
230
0e62f92e 231 return RISCV_EXCP_ILLEGAL_INST;
ff2cc129
AF
232}
233
0e62f92e 234static RISCVException hmode32(CPURISCVState *env, int csrno)
8987cdc4 235{
db23e5d9 236 if (riscv_cpu_mxl(env) != MXL_RV32) {
dceecac8 237 if (!riscv_cpu_virt_enabled(env)) {
d6f20dac
AF
238 return RISCV_EXCP_ILLEGAL_INST;
239 } else {
240 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
241 }
8987cdc4
AF
242 }
243
244 return hmode(env, csrno);
245
246}
247
4bbe8033
AB
248/* Checks if PointerMasking registers could be accessed */
249static RISCVException pointer_masking(CPURISCVState *env, int csrno)
250{
251 /* Check if j-ext is present */
252 if (riscv_has_ext(env, RVJ)) {
253 return RISCV_EXCP_NONE;
254 }
255 return RISCV_EXCP_ILLEGAL_INST;
256}
257
2b602398
AP
258static int aia_hmode(CPURISCVState *env, int csrno)
259{
260 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
261 return RISCV_EXCP_ILLEGAL_INST;
262 }
263
264 return hmode(env, csrno);
265}
266
d028ac75
AP
267static int aia_hmode32(CPURISCVState *env, int csrno)
268{
269 if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
270 return RISCV_EXCP_ILLEGAL_INST;
271 }
272
273 return hmode32(env, csrno);
274}
275
0e62f92e 276static RISCVException pmp(CPURISCVState *env, int csrno)
a88365c1 277{
0e62f92e
AF
278 if (riscv_feature(env, RISCV_FEATURE_PMP)) {
279 return RISCV_EXCP_NONE;
280 }
281
282 return RISCV_EXCP_ILLEGAL_INST;
a88365c1 283}
2582a95c
HW
284
285static RISCVException epmp(CPURISCVState *env, int csrno)
286{
287 if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
288 return RISCV_EXCP_NONE;
289 }
290
291 return RISCV_EXCP_ILLEGAL_INST;
292}
b6092544
BM
293
294static RISCVException debug(CPURISCVState *env, int csrno)
295{
296 if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
297 return RISCV_EXCP_NONE;
298 }
299
300 return RISCV_EXCP_ILLEGAL_INST;
301}
a88365c1
MC
302#endif
303
c7b95171 304/* User Floating-Point CSRs */
605def6e
AF
305static RISCVException read_fflags(CPURISCVState *env, int csrno,
306 target_ulong *val)
c7b95171 307{
fb738839 308 *val = riscv_cpu_get_fflags(env);
605def6e 309 return RISCV_EXCP_NONE;
c7b95171
MC
310}
311
605def6e
AF
312static RISCVException write_fflags(CPURISCVState *env, int csrno,
313 target_ulong val)
c7b95171
MC
314{
315#if !defined(CONFIG_USER_ONLY)
c163b3ba
WL
316 if (riscv_has_ext(env, RVF)) {
317 env->mstatus |= MSTATUS_FS;
318 }
c7b95171 319#endif
fb738839 320 riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
605def6e 321 return RISCV_EXCP_NONE;
c7b95171
MC
322}
323
605def6e
AF
324static RISCVException read_frm(CPURISCVState *env, int csrno,
325 target_ulong *val)
c7b95171 326{
c7b95171 327 *val = env->frm;
605def6e 328 return RISCV_EXCP_NONE;
c7b95171
MC
329}
330
605def6e
AF
331static RISCVException write_frm(CPURISCVState *env, int csrno,
332 target_ulong val)
c7b95171
MC
333{
334#if !defined(CONFIG_USER_ONLY)
c163b3ba
WL
335 if (riscv_has_ext(env, RVF)) {
336 env->mstatus |= MSTATUS_FS;
337 }
c7b95171
MC
338#endif
339 env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
605def6e 340 return RISCV_EXCP_NONE;
c7b95171
MC
341}
342
605def6e
AF
343static RISCVException read_fcsr(CPURISCVState *env, int csrno,
344 target_ulong *val)
c7b95171 345{
fb738839 346 *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
c7b95171 347 | (env->frm << FSR_RD_SHIFT);
605def6e 348 return RISCV_EXCP_NONE;
c7b95171
MC
349}
350
605def6e
AF
351static RISCVException write_fcsr(CPURISCVState *env, int csrno,
352 target_ulong val)
c7b95171
MC
353{
354#if !defined(CONFIG_USER_ONLY)
c163b3ba
WL
355 if (riscv_has_ext(env, RVF)) {
356 env->mstatus |= MSTATUS_FS;
357 }
c7b95171
MC
358#endif
359 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
fb738839 360 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
605def6e 361 return RISCV_EXCP_NONE;
c7b95171
MC
362}
363
605def6e
AF
364static RISCVException read_vtype(CPURISCVState *env, int csrno,
365 target_ulong *val)
8e3a1f18 366{
d96a271a
LZ
367 uint64_t vill;
368 switch (env->xl) {
369 case MXL_RV32:
370 vill = (uint32_t)env->vill << 31;
371 break;
372 case MXL_RV64:
373 vill = (uint64_t)env->vill << 63;
374 break;
375 default:
376 g_assert_not_reached();
377 }
378 *val = (target_ulong)vill | env->vtype;
605def6e 379 return RISCV_EXCP_NONE;
8e3a1f18
LZ
380}
381
605def6e
AF
382static RISCVException read_vl(CPURISCVState *env, int csrno,
383 target_ulong *val)
8e3a1f18
LZ
384{
385 *val = env->vl;
605def6e 386 return RISCV_EXCP_NONE;
8e3a1f18
LZ
387}
388
2e565054
GH
389static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
390{
391 *val = env_archcpu(env)->cfg.vlen >> 3;
392 return RISCV_EXCP_NONE;
393}
394
605def6e
AF
395static RISCVException read_vxrm(CPURISCVState *env, int csrno,
396 target_ulong *val)
8e3a1f18
LZ
397{
398 *val = env->vxrm;
605def6e 399 return RISCV_EXCP_NONE;
8e3a1f18
LZ
400}
401
605def6e
AF
402static RISCVException write_vxrm(CPURISCVState *env, int csrno,
403 target_ulong val)
8e3a1f18 404{
61b4b69d
LZ
405#if !defined(CONFIG_USER_ONLY)
406 env->mstatus |= MSTATUS_VS;
407#endif
8e3a1f18 408 env->vxrm = val;
605def6e 409 return RISCV_EXCP_NONE;
8e3a1f18
LZ
410}
411
605def6e
AF
412static RISCVException read_vxsat(CPURISCVState *env, int csrno,
413 target_ulong *val)
8e3a1f18
LZ
414{
415 *val = env->vxsat;
605def6e 416 return RISCV_EXCP_NONE;
8e3a1f18
LZ
417}
418
605def6e
AF
419static RISCVException write_vxsat(CPURISCVState *env, int csrno,
420 target_ulong val)
8e3a1f18 421{
61b4b69d
LZ
422#if !defined(CONFIG_USER_ONLY)
423 env->mstatus |= MSTATUS_VS;
424#endif
8e3a1f18 425 env->vxsat = val;
605def6e 426 return RISCV_EXCP_NONE;
8e3a1f18
LZ
427}
428
605def6e
AF
429static RISCVException read_vstart(CPURISCVState *env, int csrno,
430 target_ulong *val)
8e3a1f18
LZ
431{
432 *val = env->vstart;
605def6e 433 return RISCV_EXCP_NONE;
8e3a1f18
LZ
434}
435
605def6e
AF
436static RISCVException write_vstart(CPURISCVState *env, int csrno,
437 target_ulong val)
8e3a1f18 438{
61b4b69d
LZ
439#if !defined(CONFIG_USER_ONLY)
440 env->mstatus |= MSTATUS_VS;
441#endif
f714361e
FC
442 /*
443 * The vstart CSR is defined to have only enough writable bits
444 * to hold the largest element index, i.e. lg2(VLEN) bits.
445 */
446 env->vstart = val & ~(~0ULL << ctzl(env_archcpu(env)->cfg.vlen));
605def6e 447 return RISCV_EXCP_NONE;
8e3a1f18
LZ
448}
449
4594fa5a
LZ
450static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
451{
452 *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
453 return RISCV_EXCP_NONE;
454}
455
456static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
457{
458#if !defined(CONFIG_USER_ONLY)
459 env->mstatus |= MSTATUS_VS;
460#endif
461 env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
462 env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
463 return RISCV_EXCP_NONE;
464}
465
c7b95171 466/* User Timers and Counters */
605def6e
AF
467static RISCVException read_instret(CPURISCVState *env, int csrno,
468 target_ulong *val)
c7b95171 469{
c7b95171 470#if !defined(CONFIG_USER_ONLY)
740b1759 471 if (icount_enabled()) {
8191d368 472 *val = icount_get();
c7b95171
MC
473 } else {
474 *val = cpu_get_host_ticks();
475 }
476#else
477 *val = cpu_get_host_ticks();
478#endif
605def6e 479 return RISCV_EXCP_NONE;
c7b95171
MC
480}
481
605def6e
AF
482static RISCVException read_instreth(CPURISCVState *env, int csrno,
483 target_ulong *val)
c7b95171 484{
c7b95171 485#if !defined(CONFIG_USER_ONLY)
740b1759 486 if (icount_enabled()) {
8191d368 487 *val = icount_get() >> 32;
c7b95171
MC
488 } else {
489 *val = cpu_get_host_ticks() >> 32;
490 }
491#else
492 *val = cpu_get_host_ticks() >> 32;
493#endif
605def6e 494 return RISCV_EXCP_NONE;
c7b95171 495}
c7b95171
MC
496
497#if defined(CONFIG_USER_ONLY)
605def6e
AF
498static RISCVException read_time(CPURISCVState *env, int csrno,
499 target_ulong *val)
c7b95171
MC
500{
501 *val = cpu_get_host_ticks();
605def6e 502 return RISCV_EXCP_NONE;
c7b95171
MC
503}
504
605def6e
AF
505static RISCVException read_timeh(CPURISCVState *env, int csrno,
506 target_ulong *val)
c7b95171
MC
507{
508 *val = cpu_get_host_ticks() >> 32;
605def6e 509 return RISCV_EXCP_NONE;
c7b95171 510}
c7b95171
MC
511
512#else /* CONFIG_USER_ONLY */
513
605def6e
AF
514static RISCVException read_time(CPURISCVState *env, int csrno,
515 target_ulong *val)
c6957248
AP
516{
517 uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
518
519 if (!env->rdtime_fn) {
605def6e 520 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
521 }
522
a47ef6e9 523 *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
605def6e 524 return RISCV_EXCP_NONE;
c6957248
AP
525}
526
605def6e
AF
527static RISCVException read_timeh(CPURISCVState *env, int csrno,
528 target_ulong *val)
c6957248
AP
529{
530 uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
531
532 if (!env->rdtime_fn) {
605def6e 533 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
534 }
535
a47ef6e9 536 *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
605def6e 537 return RISCV_EXCP_NONE;
c6957248 538}
c6957248 539
c7b95171
MC
540/* Machine constants */
541
d028ac75
AP
542#define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
543#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP))
544#define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
545#define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
c7b95171 546
c7de92b4
AP
547#define VSTOPI_NUM_SRCS 5
548
d028ac75 549static const uint64_t delegable_ints = S_MODE_INTERRUPTS |
d0e53ce3 550 VS_MODE_INTERRUPTS;
d028ac75
AP
551static const uint64_t vs_delegable_ints = VS_MODE_INTERRUPTS;
552static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
881df35d 553 HS_MODE_INTERRUPTS;
bc083a51
JM
554#define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
555 (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
556 (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
557 (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
558 (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
559 (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
560 (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
561 (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
562 (1ULL << (RISCV_EXCP_U_ECALL)) | \
563 (1ULL << (RISCV_EXCP_S_ECALL)) | \
564 (1ULL << (RISCV_EXCP_VS_ECALL)) | \
565 (1ULL << (RISCV_EXCP_M_ECALL)) | \
566 (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
567 (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
568 (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
569 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
570 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
571 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
572 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
573static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
574 ~((1ULL << (RISCV_EXCP_S_ECALL)) |
575 (1ULL << (RISCV_EXCP_VS_ECALL)) |
576 (1ULL << (RISCV_EXCP_M_ECALL)) |
577 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
578 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
579 (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
580 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
c7b95171
MC
581static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
582 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
f310df58 583 SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
087b051a 584static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
e89b631c
GK
585static const target_ulong hip_writable_mask = MIP_VSSIP;
586static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
8747c9ee 587static const target_ulong vsip_writable_mask = MIP_VSSIP;
c7b95171 588
8987cdc4 589static const char valid_vm_1_10_32[16] = {
c7b95171
MC
590 [VM_1_10_MBARE] = 1,
591 [VM_1_10_SV32] = 1
592};
8987cdc4
AF
593
594static const char valid_vm_1_10_64[16] = {
c7b95171
MC
595 [VM_1_10_MBARE] = 1,
596 [VM_1_10_SV39] = 1,
597 [VM_1_10_SV48] = 1,
598 [VM_1_10_SV57] = 1
599};
c7b95171
MC
600
601/* Machine Information Registers */
605def6e
AF
602static RISCVException read_zero(CPURISCVState *env, int csrno,
603 target_ulong *val)
c7b95171 604{
605def6e
AF
605 *val = 0;
606 return RISCV_EXCP_NONE;
c7b95171
MC
607}
608
d0237b4d
AP
609static RISCVException write_ignore(CPURISCVState *env, int csrno,
610 target_ulong val)
611{
612 return RISCV_EXCP_NONE;
613}
614
9951ba94
FC
615static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
616 target_ulong *val)
617{
618 CPUState *cs = env_cpu(env);
619 RISCVCPU *cpu = RISCV_CPU(cs);
620
621 *val = cpu->cfg.mvendorid;
622 return RISCV_EXCP_NONE;
623}
624
625static RISCVException read_marchid(CPURISCVState *env, int csrno,
626 target_ulong *val)
627{
628 CPUState *cs = env_cpu(env);
629 RISCVCPU *cpu = RISCV_CPU(cs);
630
631 *val = cpu->cfg.marchid;
632 return RISCV_EXCP_NONE;
633}
634
635static RISCVException read_mipid(CPURISCVState *env, int csrno,
636 target_ulong *val)
637{
638 CPUState *cs = env_cpu(env);
639 RISCVCPU *cpu = RISCV_CPU(cs);
640
641 *val = cpu->cfg.mipid;
642 return RISCV_EXCP_NONE;
643}
644
605def6e
AF
645static RISCVException read_mhartid(CPURISCVState *env, int csrno,
646 target_ulong *val)
c7b95171
MC
647{
648 *val = env->mhartid;
605def6e 649 return RISCV_EXCP_NONE;
c7b95171
MC
650}
651
652/* Machine Trap Setup */
b550f894
RH
653
654/* We do not store SD explicitly, only compute it on demand. */
655static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
656{
657 if ((status & MSTATUS_FS) == MSTATUS_FS ||
c36b2f1a 658 (status & MSTATUS_VS) == MSTATUS_VS ||
b550f894
RH
659 (status & MSTATUS_XS) == MSTATUS_XS) {
660 switch (xl) {
661 case MXL_RV32:
662 return status | MSTATUS32_SD;
663 case MXL_RV64:
664 return status | MSTATUS64_SD;
457c360f
FP
665 case MXL_RV128:
666 return MSTATUSH128_SD;
b550f894
RH
667 default:
668 g_assert_not_reached();
669 }
670 }
671 return status;
672}
673
605def6e
AF
674static RISCVException read_mstatus(CPURISCVState *env, int csrno,
675 target_ulong *val)
c7b95171 676{
b550f894 677 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
605def6e 678 return RISCV_EXCP_NONE;
c7b95171
MC
679}
680
681static int validate_vm(CPURISCVState *env, target_ulong vm)
682{
db23e5d9 683 if (riscv_cpu_mxl(env) == MXL_RV32) {
8987cdc4
AF
684 return valid_vm_1_10_32[vm & 0xf];
685 } else {
686 return valid_vm_1_10_64[vm & 0xf];
687 }
c7b95171
MC
688}
689
605def6e
AF
690static RISCVException write_mstatus(CPURISCVState *env, int csrno,
691 target_ulong val)
c7b95171 692{
284d697c
YJ
693 uint64_t mstatus = env->mstatus;
694 uint64_t mask = 0;
f310df58 695 RISCVMXL xl = riscv_cpu_mxl(env);
c7b95171
MC
696
697 /* flush tlb on mstatus fields that affect VM */
1a9540d1
AF
698 if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
699 MSTATUS_MPRV | MSTATUS_SUM)) {
700 tlb_flush(env_cpu(env));
c7b95171 701 }
1a9540d1 702 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
c163b3ba 703 MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
1a9540d1 704 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
61b4b69d 705 MSTATUS_TW | MSTATUS_VS;
8987cdc4 706
c163b3ba
WL
707 if (riscv_has_ext(env, RVF)) {
708 mask |= MSTATUS_FS;
709 }
710
f297245f 711 if (xl != MXL_RV32 || env->debugger) {
8987cdc4
AF
712 /*
713 * RV32: MPV and GVA are not in mstatus. The current plan is to
714 * add them to mstatush. For now, we just don't support it.
715 */
716 mask |= MSTATUS_MPV | MSTATUS_GVA;
f310df58
LZ
717 if ((val & MSTATUS64_UXL) != 0) {
718 mask |= MSTATUS64_UXL;
719 }
8987cdc4 720 }
c7b95171
MC
721
722 mstatus = (mstatus & ~mask) | (val & mask);
723
457c360f 724 if (xl > MXL_RV32) {
f310df58 725 /* SXL field is for now read only */
457c360f 726 mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
4fd7455b 727 }
c7b95171 728 env->mstatus = mstatus;
440544e1 729 env->xl = cpu_recompute_xl(env);
c7b95171 730
605def6e 731 return RISCV_EXCP_NONE;
c7b95171
MC
732}
733
605def6e
AF
734static RISCVException read_mstatush(CPURISCVState *env, int csrno,
735 target_ulong *val)
551fa7e8 736{
284d697c 737 *val = env->mstatus >> 32;
605def6e 738 return RISCV_EXCP_NONE;
551fa7e8
AF
739}
740
605def6e
AF
741static RISCVException write_mstatush(CPURISCVState *env, int csrno,
742 target_ulong val)
551fa7e8 743{
284d697c
YJ
744 uint64_t valh = (uint64_t)val << 32;
745 uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
746
747 if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
551fa7e8
AF
748 tlb_flush(env_cpu(env));
749 }
750
284d697c 751 env->mstatus = (env->mstatus & ~mask) | (valh & mask);
551fa7e8 752
605def6e 753 return RISCV_EXCP_NONE;
551fa7e8 754}
551fa7e8 755
457c360f
FP
756static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
757 Int128 *val)
758{
759 *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, env->mstatus));
760 return RISCV_EXCP_NONE;
761}
762
763static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
764 Int128 *val)
765{
766 *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
767 return RISCV_EXCP_NONE;
768}
769
605def6e
AF
770static RISCVException read_misa(CPURISCVState *env, int csrno,
771 target_ulong *val)
c7b95171 772{
e91a7227
RH
773 target_ulong misa;
774
775 switch (env->misa_mxl) {
776 case MXL_RV32:
777 misa = (target_ulong)MXL_RV32 << 30;
778 break;
779#ifdef TARGET_RISCV64
780 case MXL_RV64:
781 misa = (target_ulong)MXL_RV64 << 62;
782 break;
783#endif
784 default:
785 g_assert_not_reached();
786 }
787
788 *val = misa | env->misa_ext;
605def6e 789 return RISCV_EXCP_NONE;
c7b95171
MC
790}
791
605def6e
AF
792static RISCVException write_misa(CPURISCVState *env, int csrno,
793 target_ulong val)
f18637cd
MC
794{
795 if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
796 /* drop write to misa */
605def6e 797 return RISCV_EXCP_NONE;
f18637cd
MC
798 }
799
800 /* 'I' or 'E' must be present */
801 if (!(val & (RVI | RVE))) {
802 /* It is not, drop write to misa */
605def6e 803 return RISCV_EXCP_NONE;
f18637cd
MC
804 }
805
806 /* 'E' excludes all other extensions */
807 if (val & RVE) {
808 /* when we support 'E' we can do "val = RVE;" however
809 * for now we just drop writes if 'E' is present.
810 */
605def6e 811 return RISCV_EXCP_NONE;
f18637cd
MC
812 }
813
e91a7227
RH
814 /*
815 * misa.MXL writes are not supported by QEMU.
816 * Drop writes to those bits.
817 */
818
f18637cd 819 /* Mask extensions that are not supported by this hart */
e91a7227 820 val &= env->misa_ext_mask;
f18637cd
MC
821
822 /* Mask extensions that are not supported by QEMU */
7b07a37c 823 val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
f18637cd
MC
824
825 /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
826 if ((val & RVD) && !(val & RVF)) {
827 val &= ~RVD;
828 }
829
830 /* Suppress 'C' if next instruction is not aligned
831 * TODO: this should check next_pc
832 */
833 if ((val & RVC) && (GETPC() & ~3) != 0) {
834 val &= ~RVC;
835 }
836
e91a7227
RH
837 /* If nothing changed, do nothing. */
838 if (val == env->misa_ext) {
839 return RISCV_EXCP_NONE;
4fd7455b 840 }
f18637cd 841
c163b3ba
WL
842 if (!(val & RVF)) {
843 env->mstatus &= ~MSTATUS_FS;
844 }
845
f18637cd 846 /* flush translation cache */
e91a7227
RH
847 tb_flush(env_cpu(env));
848 env->misa_ext = val;
440544e1 849 env->xl = riscv_cpu_mxl(env);
605def6e 850 return RISCV_EXCP_NONE;
f18637cd
MC
851}
852
605def6e
AF
853static RISCVException read_medeleg(CPURISCVState *env, int csrno,
854 target_ulong *val)
c7b95171
MC
855{
856 *val = env->medeleg;
605def6e 857 return RISCV_EXCP_NONE;
c7b95171
MC
858}
859
605def6e
AF
860static RISCVException write_medeleg(CPURISCVState *env, int csrno,
861 target_ulong val)
c7b95171 862{
bc083a51 863 env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
605def6e 864 return RISCV_EXCP_NONE;
c7b95171
MC
865}
866
d028ac75
AP
867static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
868 uint64_t *ret_val,
869 uint64_t new_val, uint64_t wr_mask)
c7b95171 870{
d028ac75
AP
871 uint64_t mask = wr_mask & delegable_ints;
872
873 if (ret_val) {
874 *ret_val = env->mideleg;
875 }
876
877 env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
c7b95171 878
713d8363 879 if (riscv_has_ext(env, RVH)) {
881df35d 880 env->mideleg |= HS_MODE_INTERRUPTS;
713d8363 881 }
d028ac75 882
605def6e 883 return RISCV_EXCP_NONE;
c7b95171
MC
884}
885
d028ac75
AP
886static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
887 target_ulong *ret_val,
888 target_ulong new_val, target_ulong wr_mask)
c7b95171 889{
d028ac75
AP
890 uint64_t rval;
891 RISCVException ret;
892
893 ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
894 if (ret_val) {
895 *ret_val = rval;
896 }
897
898 return ret;
c7b95171
MC
899}
900
d028ac75
AP
901static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
902 target_ulong *ret_val,
903 target_ulong new_val,
904 target_ulong wr_mask)
c7b95171 905{
d028ac75
AP
906 uint64_t rval;
907 RISCVException ret;
908
909 ret = rmw_mideleg64(env, csrno, &rval,
910 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
911 if (ret_val) {
912 *ret_val = rval >> 32;
913 }
914
915 return ret;
916}
917
918static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
919 uint64_t *ret_val,
920 uint64_t new_val, uint64_t wr_mask)
921{
922 uint64_t mask = wr_mask & all_ints;
923
924 if (ret_val) {
925 *ret_val = env->mie;
926 }
927
928 env->mie = (env->mie & ~mask) | (new_val & mask);
929
881df35d 930 if (!riscv_has_ext(env, RVH)) {
d028ac75 931 env->mie &= ~((uint64_t)MIP_SGEIP);
881df35d 932 }
d028ac75 933
605def6e 934 return RISCV_EXCP_NONE;
c7b95171
MC
935}
936
d028ac75
AP
937static RISCVException rmw_mie(CPURISCVState *env, int csrno,
938 target_ulong *ret_val,
939 target_ulong new_val, target_ulong wr_mask)
940{
941 uint64_t rval;
942 RISCVException ret;
943
944 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
945 if (ret_val) {
946 *ret_val = rval;
947 }
948
949 return ret;
950}
951
952static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
953 target_ulong *ret_val,
954 target_ulong new_val, target_ulong wr_mask)
955{
956 uint64_t rval;
957 RISCVException ret;
958
959 ret = rmw_mie64(env, csrno, &rval,
960 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
961 if (ret_val) {
962 *ret_val = rval >> 32;
963 }
964
965 return ret;
966}
967
c7de92b4
AP
968static int read_mtopi(CPURISCVState *env, int csrno, target_ulong *val)
969{
970 int irq;
971 uint8_t iprio;
972
973 irq = riscv_cpu_mirq_pending(env);
974 if (irq <= 0 || irq > 63) {
975 *val = 0;
976 } else {
977 iprio = env->miprio[irq];
978 if (!iprio) {
979 if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) {
980 iprio = IPRIO_MMAXIPRIO;
981 }
982 }
983 *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
984 *val |= iprio;
985 }
986
987 return RISCV_EXCP_NONE;
988}
989
d1ceff40
AP
990static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
991{
992 if (!riscv_cpu_virt_enabled(env)) {
993 return csrno;
994 }
995
996 switch (csrno) {
997 case CSR_SISELECT:
998 return CSR_VSISELECT;
999 case CSR_SIREG:
1000 return CSR_VSIREG;
ac4b0302
AP
1001 case CSR_SSETEIPNUM:
1002 return CSR_VSSETEIPNUM;
1003 case CSR_SCLREIPNUM:
1004 return CSR_VSCLREIPNUM;
1005 case CSR_SSETEIENUM:
1006 return CSR_VSSETEIENUM;
1007 case CSR_SCLREIENUM:
1008 return CSR_VSCLREIENUM;
1009 case CSR_STOPEI:
1010 return CSR_VSTOPEI;
d1ceff40
AP
1011 default:
1012 return csrno;
1013 };
1014}
1015
1016static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
1017 target_ulong new_val, target_ulong wr_mask)
1018{
1019 target_ulong *iselect;
1020
1021 /* Translate CSR number for VS-mode */
1022 csrno = aia_xlate_vs_csrno(env, csrno);
1023
1024 /* Find the iselect CSR based on CSR number */
1025 switch (csrno) {
1026 case CSR_MISELECT:
1027 iselect = &env->miselect;
1028 break;
1029 case CSR_SISELECT:
1030 iselect = &env->siselect;
1031 break;
1032 case CSR_VSISELECT:
1033 iselect = &env->vsiselect;
1034 break;
1035 default:
1036 return RISCV_EXCP_ILLEGAL_INST;
1037 };
1038
1039 if (val) {
1040 *val = *iselect;
1041 }
1042
1043 wr_mask &= ISELECT_MASK;
1044 if (wr_mask) {
1045 *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
1046 }
1047
1048 return RISCV_EXCP_NONE;
1049}
1050
1051static int rmw_iprio(target_ulong xlen,
1052 target_ulong iselect, uint8_t *iprio,
1053 target_ulong *val, target_ulong new_val,
1054 target_ulong wr_mask, int ext_irq_no)
1055{
1056 int i, firq, nirqs;
1057 target_ulong old_val;
1058
1059 if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
1060 return -EINVAL;
1061 }
1062 if (xlen != 32 && iselect & 0x1) {
1063 return -EINVAL;
1064 }
1065
1066 nirqs = 4 * (xlen / 32);
1067 firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
1068
1069 old_val = 0;
1070 for (i = 0; i < nirqs; i++) {
1071 old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i);
1072 }
1073
1074 if (val) {
1075 *val = old_val;
1076 }
1077
1078 if (wr_mask) {
1079 new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
1080 for (i = 0; i < nirqs; i++) {
1081 /*
1082 * M-level and S-level external IRQ priority always read-only
1083 * zero. This means default priority order is always preferred
1084 * for M-level and S-level external IRQs.
1085 */
1086 if ((firq + i) == ext_irq_no) {
1087 continue;
1088 }
1089 iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
1090 }
1091 }
1092
1093 return 0;
1094}
1095
1096static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
1097 target_ulong new_val, target_ulong wr_mask)
1098{
1099 bool virt;
1100 uint8_t *iprio;
1101 int ret = -EINVAL;
1102 target_ulong priv, isel, vgein;
1103
1104 /* Translate CSR number for VS-mode */
1105 csrno = aia_xlate_vs_csrno(env, csrno);
1106
1107 /* Decode register details from CSR number */
1108 virt = false;
1109 switch (csrno) {
1110 case CSR_MIREG:
1111 iprio = env->miprio;
1112 isel = env->miselect;
1113 priv = PRV_M;
1114 break;
1115 case CSR_SIREG:
1116 iprio = env->siprio;
1117 isel = env->siselect;
1118 priv = PRV_S;
1119 break;
1120 case CSR_VSIREG:
1121 iprio = env->hviprio;
1122 isel = env->vsiselect;
1123 priv = PRV_S;
1124 virt = true;
1125 break;
1126 default:
1127 goto done;
1128 };
1129
1130 /* Find the selected guest interrupt file */
1131 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1132
1133 if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
1134 /* Local interrupt priority registers not available for VS-mode */
1135 if (!virt) {
1136 ret = rmw_iprio(riscv_cpu_mxl_bits(env),
1137 isel, iprio, val, new_val, wr_mask,
1138 (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
1139 }
1140 } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) {
1141 /* IMSIC registers only available when machine implements it. */
1142 if (env->aia_ireg_rmw_fn[priv]) {
1143 /* Selected guest interrupt file should not be zero */
1144 if (virt && (!vgein || env->geilen < vgein)) {
1145 goto done;
1146 }
1147 /* Call machine specific IMSIC register emulation */
1148 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1149 AIA_MAKE_IREG(isel, priv, virt, vgein,
1150 riscv_cpu_mxl_bits(env)),
1151 val, new_val, wr_mask);
1152 }
1153 }
1154
1155done:
1156 if (ret) {
1157 return (riscv_cpu_virt_enabled(env) && virt) ?
1158 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1159 }
1160 return RISCV_EXCP_NONE;
1161}
1162
ac4b0302
AP
1163static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong *val,
1164 target_ulong new_val, target_ulong wr_mask)
1165{
1166 int ret = -EINVAL;
1167 bool set, pend, virt;
1168 target_ulong priv, isel, vgein, xlen, nval, wmask;
1169
1170 /* Translate CSR number for VS-mode */
1171 csrno = aia_xlate_vs_csrno(env, csrno);
1172
1173 /* Decode register details from CSR number */
1174 virt = set = pend = false;
1175 switch (csrno) {
1176 case CSR_MSETEIPNUM:
1177 priv = PRV_M;
1178 set = true;
1179 pend = true;
1180 break;
1181 case CSR_MCLREIPNUM:
1182 priv = PRV_M;
1183 pend = true;
1184 break;
1185 case CSR_MSETEIENUM:
1186 priv = PRV_M;
1187 set = true;
1188 break;
1189 case CSR_MCLREIENUM:
1190 priv = PRV_M;
1191 break;
1192 case CSR_SSETEIPNUM:
1193 priv = PRV_S;
1194 set = true;
1195 pend = true;
1196 break;
1197 case CSR_SCLREIPNUM:
1198 priv = PRV_S;
1199 pend = true;
1200 break;
1201 case CSR_SSETEIENUM:
1202 priv = PRV_S;
1203 set = true;
1204 break;
1205 case CSR_SCLREIENUM:
1206 priv = PRV_S;
1207 break;
1208 case CSR_VSSETEIPNUM:
1209 priv = PRV_S;
1210 virt = true;
1211 set = true;
1212 pend = true;
1213 break;
1214 case CSR_VSCLREIPNUM:
1215 priv = PRV_S;
1216 virt = true;
1217 pend = true;
1218 break;
1219 case CSR_VSSETEIENUM:
1220 priv = PRV_S;
1221 virt = true;
1222 set = true;
1223 break;
1224 case CSR_VSCLREIENUM:
1225 priv = PRV_S;
1226 virt = true;
1227 break;
1228 default:
1229 goto done;
1230 };
1231
1232 /* IMSIC CSRs only available when machine implements IMSIC. */
1233 if (!env->aia_ireg_rmw_fn[priv]) {
1234 goto done;
1235 }
1236
1237 /* Find the selected guest interrupt file */
1238 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1239
1240 /* Selected guest interrupt file should be valid */
1241 if (virt && (!vgein || env->geilen < vgein)) {
1242 goto done;
1243 }
1244
1245 /* Set/Clear CSRs always read zero */
1246 if (val) {
1247 *val = 0;
1248 }
1249
1250 if (wr_mask) {
1251 /* Get interrupt number */
1252 new_val &= wr_mask;
1253
1254 /* Find target interrupt pending/enable register */
1255 xlen = riscv_cpu_mxl_bits(env);
1256 isel = (new_val / xlen);
1257 isel *= (xlen / IMSIC_EIPx_BITS);
1258 isel += (pend) ? ISELECT_IMSIC_EIP0 : ISELECT_IMSIC_EIE0;
1259
1260 /* Find the interrupt bit to be set/clear */
1261 wmask = ((target_ulong)1) << (new_val % xlen);
1262 nval = (set) ? wmask : 0;
1263
1264 /* Call machine specific IMSIC register emulation */
1265 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1266 AIA_MAKE_IREG(isel, priv, virt,
1267 vgein, xlen),
1268 NULL, nval, wmask);
1269 } else {
1270 ret = 0;
1271 }
1272
1273done:
1274 if (ret) {
1275 return (riscv_cpu_virt_enabled(env) && virt) ?
1276 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1277 }
1278 return RISCV_EXCP_NONE;
1279}
1280
1281static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
1282 target_ulong new_val, target_ulong wr_mask)
1283{
1284 bool virt;
1285 int ret = -EINVAL;
1286 target_ulong priv, vgein;
1287
1288 /* Translate CSR number for VS-mode */
1289 csrno = aia_xlate_vs_csrno(env, csrno);
1290
1291 /* Decode register details from CSR number */
1292 virt = false;
1293 switch (csrno) {
1294 case CSR_MTOPEI:
1295 priv = PRV_M;
1296 break;
1297 case CSR_STOPEI:
1298 priv = PRV_S;
1299 break;
1300 case CSR_VSTOPEI:
1301 priv = PRV_S;
1302 virt = true;
1303 break;
1304 default:
1305 goto done;
1306 };
1307
1308 /* IMSIC CSRs only available when machine implements IMSIC. */
1309 if (!env->aia_ireg_rmw_fn[priv]) {
1310 goto done;
1311 }
1312
1313 /* Find the selected guest interrupt file */
1314 vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1315
1316 /* Selected guest interrupt file should be valid */
1317 if (virt && (!vgein || env->geilen < vgein)) {
1318 goto done;
1319 }
1320
1321 /* Call machine specific IMSIC register emulation for TOPEI */
1322 ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1323 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein,
1324 riscv_cpu_mxl_bits(env)),
1325 val, new_val, wr_mask);
1326
1327done:
1328 if (ret) {
1329 return (riscv_cpu_virt_enabled(env) && virt) ?
1330 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1331 }
1332 return RISCV_EXCP_NONE;
1333}
1334
605def6e
AF
1335static RISCVException read_mtvec(CPURISCVState *env, int csrno,
1336 target_ulong *val)
c7b95171
MC
1337{
1338 *val = env->mtvec;
605def6e 1339 return RISCV_EXCP_NONE;
c7b95171
MC
1340}
1341
605def6e
AF
1342static RISCVException write_mtvec(CPURISCVState *env, int csrno,
1343 target_ulong val)
c7b95171
MC
1344{
1345 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
acbbb94e
MC
1346 if ((val & 3) < 2) {
1347 env->mtvec = val;
c7b95171 1348 } else {
acbbb94e 1349 qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
c7b95171 1350 }
605def6e 1351 return RISCV_EXCP_NONE;
c7b95171
MC
1352}
1353
605def6e
AF
1354static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
1355 target_ulong *val)
c7b95171 1356{
c7b95171 1357 *val = env->mcounteren;
605def6e 1358 return RISCV_EXCP_NONE;
c7b95171
MC
1359}
1360
605def6e
AF
1361static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
1362 target_ulong val)
c7b95171 1363{
c7b95171 1364 env->mcounteren = val;
605def6e 1365 return RISCV_EXCP_NONE;
c7b95171
MC
1366}
1367
c7b95171 1368/* Machine Trap Handling */
457c360f
FP
1369static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
1370 Int128 *val)
1371{
1372 *val = int128_make128(env->mscratch, env->mscratchh);
1373 return RISCV_EXCP_NONE;
1374}
1375
1376static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
1377 Int128 val)
1378{
1379 env->mscratch = int128_getlo(val);
1380 env->mscratchh = int128_gethi(val);
1381 return RISCV_EXCP_NONE;
1382}
1383
605def6e
AF
1384static RISCVException read_mscratch(CPURISCVState *env, int csrno,
1385 target_ulong *val)
c7b95171
MC
1386{
1387 *val = env->mscratch;
605def6e 1388 return RISCV_EXCP_NONE;
c7b95171
MC
1389}
1390
605def6e
AF
1391static RISCVException write_mscratch(CPURISCVState *env, int csrno,
1392 target_ulong val)
c7b95171
MC
1393{
1394 env->mscratch = val;
605def6e 1395 return RISCV_EXCP_NONE;
c7b95171
MC
1396}
1397
605def6e
AF
1398static RISCVException read_mepc(CPURISCVState *env, int csrno,
1399 target_ulong *val)
c7b95171
MC
1400{
1401 *val = env->mepc;
605def6e 1402 return RISCV_EXCP_NONE;
c7b95171
MC
1403}
1404
605def6e
AF
1405static RISCVException write_mepc(CPURISCVState *env, int csrno,
1406 target_ulong val)
c7b95171
MC
1407{
1408 env->mepc = val;
605def6e 1409 return RISCV_EXCP_NONE;
c7b95171
MC
1410}
1411
605def6e
AF
1412static RISCVException read_mcause(CPURISCVState *env, int csrno,
1413 target_ulong *val)
c7b95171
MC
1414{
1415 *val = env->mcause;
605def6e 1416 return RISCV_EXCP_NONE;
c7b95171
MC
1417}
1418
605def6e
AF
1419static RISCVException write_mcause(CPURISCVState *env, int csrno,
1420 target_ulong val)
c7b95171
MC
1421{
1422 env->mcause = val;
605def6e 1423 return RISCV_EXCP_NONE;
c7b95171
MC
1424}
1425
605def6e
AF
1426static RISCVException read_mtval(CPURISCVState *env, int csrno,
1427 target_ulong *val)
c7b95171 1428{
ac12b601 1429 *val = env->mtval;
605def6e 1430 return RISCV_EXCP_NONE;
c7b95171
MC
1431}
1432
605def6e
AF
1433static RISCVException write_mtval(CPURISCVState *env, int csrno,
1434 target_ulong val)
c7b95171 1435{
ac12b601 1436 env->mtval = val;
605def6e 1437 return RISCV_EXCP_NONE;
c7b95171
MC
1438}
1439
29a9ec9b
AP
1440/* Execution environment configuration setup */
1441static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
1442 target_ulong *val)
1443{
1444 *val = env->menvcfg;
1445 return RISCV_EXCP_NONE;
1446}
1447
1448static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
1449 target_ulong val)
1450{
1451 uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
1452
1453 if (riscv_cpu_mxl(env) == MXL_RV64) {
1454 mask |= MENVCFG_PBMTE | MENVCFG_STCE;
1455 }
1456 env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
1457
1458 return RISCV_EXCP_NONE;
1459}
1460
1461static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
1462 target_ulong *val)
1463{
1464 *val = env->menvcfg >> 32;
1465 return RISCV_EXCP_NONE;
1466}
1467
1468static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
1469 target_ulong val)
1470{
1471 uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE;
1472 uint64_t valh = (uint64_t)val << 32;
1473
1474 env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
1475
1476 return RISCV_EXCP_NONE;
1477}
1478
1479static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
1480 target_ulong *val)
1481{
1482 *val = env->senvcfg;
1483 return RISCV_EXCP_NONE;
1484}
1485
1486static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
1487 target_ulong val)
1488{
1489 uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
1490
1491 env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
1492
1493 return RISCV_EXCP_NONE;
1494}
1495
1496static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
1497 target_ulong *val)
1498{
1499 *val = env->henvcfg;
1500 return RISCV_EXCP_NONE;
1501}
1502
1503static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
1504 target_ulong val)
1505{
1506 uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
1507
1508 if (riscv_cpu_mxl(env) == MXL_RV64) {
1509 mask |= HENVCFG_PBMTE | HENVCFG_STCE;
1510 }
1511
1512 env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
1513
1514 return RISCV_EXCP_NONE;
1515}
1516
1517static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
1518 target_ulong *val)
1519{
1520 *val = env->henvcfg >> 32;
1521 return RISCV_EXCP_NONE;
1522}
1523
1524static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
1525 target_ulong val)
1526{
1527 uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
1528 uint64_t valh = (uint64_t)val << 32;
1529
1530 env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
1531
1532 return RISCV_EXCP_NONE;
1533}
1534
d028ac75
AP
1535static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
1536 uint64_t *ret_val,
1537 uint64_t new_val, uint64_t wr_mask)
c7b95171 1538{
3109cd98 1539 RISCVCPU *cpu = env_archcpu(env);
33fe584f 1540 uint64_t old_mip, mask = wr_mask & delegable_ints;
d028ac75 1541 uint32_t gin;
71877e29 1542
33fe584f
AF
1543 if (mask & MIP_SEIP) {
1544 env->software_seip = new_val & MIP_SEIP;
1545 new_val |= env->external_seip * MIP_SEIP;
1546 }
1547
71877e29 1548 if (mask) {
d028ac75 1549 old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
71877e29 1550 } else {
7ec5d303 1551 old_mip = env->mip;
71877e29 1552 }
c7b95171 1553
cd032fe7
AP
1554 if (csrno != CSR_HVIP) {
1555 gin = get_field(env->hstatus, HSTATUS_VGEIN);
1556 old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
1557 }
1558
d028ac75
AP
1559 if (ret_val) {
1560 *ret_val = old_mip;
71877e29 1561 }
c7b95171 1562
605def6e 1563 return RISCV_EXCP_NONE;
c7b95171
MC
1564}
1565
d028ac75
AP
1566static RISCVException rmw_mip(CPURISCVState *env, int csrno,
1567 target_ulong *ret_val,
1568 target_ulong new_val, target_ulong wr_mask)
1569{
1570 uint64_t rval;
1571 RISCVException ret;
1572
1573 ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
1574 if (ret_val) {
1575 *ret_val = rval;
1576 }
1577
1578 return ret;
1579}
1580
1581static RISCVException rmw_miph(CPURISCVState *env, int csrno,
1582 target_ulong *ret_val,
1583 target_ulong new_val, target_ulong wr_mask)
1584{
1585 uint64_t rval;
1586 RISCVException ret;
1587
1588 ret = rmw_mip64(env, csrno, &rval,
1589 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1590 if (ret_val) {
1591 *ret_val = rval >> 32;
1592 }
1593
1594 return ret;
1595}
1596
c7b95171 1597/* Supervisor Trap Setup */
457c360f
FP
1598static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
1599 Int128 *val)
1600{
1601 uint64_t mask = sstatus_v1_10_mask;
1602 uint64_t sstatus = env->mstatus & mask;
f297245f 1603 if (env->xl != MXL_RV32 || env->debugger) {
f310df58
LZ
1604 mask |= SSTATUS64_UXL;
1605 }
457c360f
FP
1606
1607 *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
1608 return RISCV_EXCP_NONE;
1609}
1610
605def6e
AF
1611static RISCVException read_sstatus(CPURISCVState *env, int csrno,
1612 target_ulong *val)
c7b95171 1613{
1a9540d1 1614 target_ulong mask = (sstatus_v1_10_mask);
f297245f 1615 if (env->xl != MXL_RV32 || env->debugger) {
f310df58
LZ
1616 mask |= SSTATUS64_UXL;
1617 }
b550f894
RH
1618 /* TODO: Use SXL not MXL. */
1619 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
605def6e 1620 return RISCV_EXCP_NONE;
c7b95171
MC
1621}
1622
605def6e
AF
1623static RISCVException write_sstatus(CPURISCVState *env, int csrno,
1624 target_ulong val)
c7b95171 1625{
1a9540d1 1626 target_ulong mask = (sstatus_v1_10_mask);
f310df58 1627
f297245f 1628 if (env->xl != MXL_RV32 || env->debugger) {
f310df58
LZ
1629 if ((val & SSTATUS64_UXL) != 0) {
1630 mask |= SSTATUS64_UXL;
1631 }
1632 }
c7b95171
MC
1633 target_ulong newval = (env->mstatus & ~mask) | (val & mask);
1634 return write_mstatus(env, CSR_MSTATUS, newval);
1635}
1636
d028ac75
AP
1637static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
1638 uint64_t *ret_val,
1639 uint64_t new_val, uint64_t wr_mask)
9d5451e0 1640{
d028ac75
AP
1641 RISCVException ret;
1642 uint64_t rval, vsbits, mask = env->hideleg & VS_MODE_INTERRUPTS;
1643
1644 /* Bring VS-level bits to correct position */
1645 vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
1646 new_val &= ~(VS_MODE_INTERRUPTS >> 1);
1647 new_val |= vsbits << 1;
1648 vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
1649 wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
1650 wr_mask |= vsbits << 1;
1651
1652 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask);
1653 if (ret_val) {
1654 rval &= mask;
1655 vsbits = rval & VS_MODE_INTERRUPTS;
1656 rval &= ~VS_MODE_INTERRUPTS;
1657 *ret_val = rval | (vsbits >> 1);
1658 }
1659
1660 return ret;
9d5451e0
GK
1661}
1662
d028ac75
AP
1663static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
1664 target_ulong *ret_val,
1665 target_ulong new_val, target_ulong wr_mask)
c7b95171 1666{
d028ac75
AP
1667 uint64_t rval;
1668 RISCVException ret;
1669
1670 ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
1671 if (ret_val) {
1672 *ret_val = rval;
d0e53ce3 1673 }
d028ac75
AP
1674
1675 return ret;
c7b95171
MC
1676}
1677
d028ac75
AP
1678static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
1679 target_ulong *ret_val,
1680 target_ulong new_val, target_ulong wr_mask)
c7b95171 1681{
d028ac75
AP
1682 uint64_t rval;
1683 RISCVException ret;
1684
1685 ret = rmw_vsie64(env, csrno, &rval,
1686 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1687 if (ret_val) {
1688 *ret_val = rval >> 32;
1689 }
1690
1691 return ret;
9d5451e0 1692}
d0e53ce3 1693
d028ac75
AP
1694static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
1695 uint64_t *ret_val,
1696 uint64_t new_val, uint64_t wr_mask)
9d5451e0 1697{
d028ac75
AP
1698 RISCVException ret;
1699 uint64_t mask = env->mideleg & S_MODE_INTERRUPTS;
1700
d0e53ce3 1701 if (riscv_cpu_virt_enabled(env)) {
2b602398
AP
1702 if (env->hvictl & HVICTL_VTI) {
1703 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1704 }
d028ac75 1705 ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
d0e53ce3 1706 } else {
d028ac75 1707 ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask);
d0e53ce3
AF
1708 }
1709
d028ac75
AP
1710 if (ret_val) {
1711 *ret_val &= mask;
1712 }
1713
1714 return ret;
1715}
1716
1717static RISCVException rmw_sie(CPURISCVState *env, int csrno,
1718 target_ulong *ret_val,
1719 target_ulong new_val, target_ulong wr_mask)
1720{
1721 uint64_t rval;
1722 RISCVException ret;
1723
1724 ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
2b602398 1725 if (ret == RISCV_EXCP_NONE && ret_val) {
d028ac75
AP
1726 *ret_val = rval;
1727 }
1728
1729 return ret;
1730}
1731
1732static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
1733 target_ulong *ret_val,
1734 target_ulong new_val, target_ulong wr_mask)
1735{
1736 uint64_t rval;
1737 RISCVException ret;
1738
1739 ret = rmw_sie64(env, csrno, &rval,
1740 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1741 if (ret_val) {
1742 *ret_val = rval >> 32;
1743 }
1744
1745 return ret;
c7b95171
MC
1746}
1747
605def6e
AF
1748static RISCVException read_stvec(CPURISCVState *env, int csrno,
1749 target_ulong *val)
c7b95171
MC
1750{
1751 *val = env->stvec;
605def6e 1752 return RISCV_EXCP_NONE;
c7b95171
MC
1753}
1754
605def6e
AF
1755static RISCVException write_stvec(CPURISCVState *env, int csrno,
1756 target_ulong val)
c7b95171
MC
1757{
1758 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
acbbb94e
MC
1759 if ((val & 3) < 2) {
1760 env->stvec = val;
c7b95171 1761 } else {
acbbb94e 1762 qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
c7b95171 1763 }
605def6e 1764 return RISCV_EXCP_NONE;
c7b95171
MC
1765}
1766
605def6e
AF
1767static RISCVException read_scounteren(CPURISCVState *env, int csrno,
1768 target_ulong *val)
c7b95171 1769{
c7b95171 1770 *val = env->scounteren;
605def6e 1771 return RISCV_EXCP_NONE;
c7b95171
MC
1772}
1773
605def6e
AF
1774static RISCVException write_scounteren(CPURISCVState *env, int csrno,
1775 target_ulong val)
c7b95171 1776{
c7b95171 1777 env->scounteren = val;
605def6e 1778 return RISCV_EXCP_NONE;
c7b95171
MC
1779}
1780
1781/* Supervisor Trap Handling */
457c360f
FP
1782static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
1783 Int128 *val)
1784{
1785 *val = int128_make128(env->sscratch, env->sscratchh);
1786 return RISCV_EXCP_NONE;
1787}
1788
1789static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
1790 Int128 val)
1791{
1792 env->sscratch = int128_getlo(val);
1793 env->sscratchh = int128_gethi(val);
1794 return RISCV_EXCP_NONE;
1795}
1796
605def6e
AF
1797static RISCVException read_sscratch(CPURISCVState *env, int csrno,
1798 target_ulong *val)
c7b95171
MC
1799{
1800 *val = env->sscratch;
605def6e 1801 return RISCV_EXCP_NONE;
c7b95171
MC
1802}
1803
605def6e
AF
1804static RISCVException write_sscratch(CPURISCVState *env, int csrno,
1805 target_ulong val)
c7b95171
MC
1806{
1807 env->sscratch = val;
605def6e 1808 return RISCV_EXCP_NONE;
c7b95171
MC
1809}
1810
605def6e
AF
1811static RISCVException read_sepc(CPURISCVState *env, int csrno,
1812 target_ulong *val)
c7b95171
MC
1813{
1814 *val = env->sepc;
605def6e 1815 return RISCV_EXCP_NONE;
c7b95171
MC
1816}
1817
605def6e
AF
1818static RISCVException write_sepc(CPURISCVState *env, int csrno,
1819 target_ulong val)
c7b95171
MC
1820{
1821 env->sepc = val;
605def6e 1822 return RISCV_EXCP_NONE;
c7b95171
MC
1823}
1824
605def6e
AF
1825static RISCVException read_scause(CPURISCVState *env, int csrno,
1826 target_ulong *val)
c7b95171
MC
1827{
1828 *val = env->scause;
605def6e 1829 return RISCV_EXCP_NONE;
c7b95171
MC
1830}
1831
605def6e
AF
1832static RISCVException write_scause(CPURISCVState *env, int csrno,
1833 target_ulong val)
c7b95171
MC
1834{
1835 env->scause = val;
605def6e 1836 return RISCV_EXCP_NONE;
c7b95171
MC
1837}
1838
605def6e
AF
1839static RISCVException read_stval(CPURISCVState *env, int csrno,
1840 target_ulong *val)
c7b95171 1841{
ac12b601 1842 *val = env->stval;
605def6e 1843 return RISCV_EXCP_NONE;
c7b95171
MC
1844}
1845
605def6e
AF
1846static RISCVException write_stval(CPURISCVState *env, int csrno,
1847 target_ulong val)
c7b95171 1848{
ac12b601 1849 env->stval = val;
605def6e 1850 return RISCV_EXCP_NONE;
c7b95171
MC
1851}
1852
d028ac75
AP
1853static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
1854 uint64_t *ret_val,
1855 uint64_t new_val, uint64_t wr_mask)
1856{
1857 RISCVException ret;
1858 uint64_t rval, vsbits, mask = env->hideleg & vsip_writable_mask;
1859
1860 /* Bring VS-level bits to correct position */
1861 vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
1862 new_val &= ~(VS_MODE_INTERRUPTS >> 1);
1863 new_val |= vsbits << 1;
1864 vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
1865 wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
1866 wr_mask |= vsbits << 1;
1867
1868 ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask & mask);
1869 if (ret_val) {
1870 rval &= mask;
1871 vsbits = rval & VS_MODE_INTERRUPTS;
1872 rval &= ~VS_MODE_INTERRUPTS;
1873 *ret_val = rval | (vsbits >> 1);
1874 }
1875
1876 return ret;
1877}
1878
605def6e 1879static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
d028ac75
AP
1880 target_ulong *ret_val,
1881 target_ulong new_val, target_ulong wr_mask)
9d5451e0 1882{
d028ac75
AP
1883 uint64_t rval;
1884 RISCVException ret;
33979526 1885
d028ac75
AP
1886 ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
1887 if (ret_val) {
1888 *ret_val = rval;
33979526 1889 }
d028ac75 1890
9d5451e0
GK
1891 return ret;
1892}
1893
d028ac75
AP
1894static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
1895 target_ulong *ret_val,
1896 target_ulong new_val, target_ulong wr_mask)
c7b95171 1897{
d028ac75
AP
1898 uint64_t rval;
1899 RISCVException ret;
1900
1901 ret = rmw_vsip64(env, csrno, &rval,
1902 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1903 if (ret_val) {
1904 *ret_val = rval >> 32;
1905 }
1906
1907 return ret;
1908}
1909
1910static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
1911 uint64_t *ret_val,
1912 uint64_t new_val, uint64_t wr_mask)
1913{
1914 RISCVException ret;
1915 uint64_t mask = env->mideleg & sip_writable_mask;
a2e9f57d
AF
1916
1917 if (riscv_cpu_virt_enabled(env)) {
2b602398
AP
1918 if (env->hvictl & HVICTL_VTI) {
1919 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1920 }
d028ac75 1921 ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
a2e9f57d 1922 } else {
d028ac75 1923 ret = rmw_mip64(env, csrno, ret_val, new_val, wr_mask & mask);
a2e9f57d
AF
1924 }
1925
d028ac75
AP
1926 if (ret_val) {
1927 *ret_val &= env->mideleg & S_MODE_INTERRUPTS;
1928 }
1929
1930 return ret;
1931}
1932
1933static RISCVException rmw_sip(CPURISCVState *env, int csrno,
1934 target_ulong *ret_val,
1935 target_ulong new_val, target_ulong wr_mask)
1936{
1937 uint64_t rval;
1938 RISCVException ret;
1939
1940 ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
1941 if (ret_val) {
1942 *ret_val = rval;
33979526 1943 }
d028ac75
AP
1944
1945 return ret;
1946}
1947
1948static RISCVException rmw_siph(CPURISCVState *env, int csrno,
1949 target_ulong *ret_val,
1950 target_ulong new_val, target_ulong wr_mask)
1951{
1952 uint64_t rval;
1953 RISCVException ret;
1954
1955 ret = rmw_sip64(env, csrno, &rval,
1956 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1957 if (ret_val) {
1958 *ret_val = rval >> 32;
1959 }
1960
087b051a 1961 return ret;
c7b95171
MC
1962}
1963
1964/* Supervisor Protection and Translation */
605def6e
AF
1965static RISCVException read_satp(CPURISCVState *env, int csrno,
1966 target_ulong *val)
c7b95171
MC
1967{
1968 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
1969 *val = 0;
605def6e 1970 return RISCV_EXCP_NONE;
1a9540d1
AF
1971 }
1972
1973 if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
605def6e 1974 return RISCV_EXCP_ILLEGAL_INST;
c7b95171 1975 } else {
1a9540d1 1976 *val = env->satp;
c7b95171 1977 }
1a9540d1 1978
605def6e 1979 return RISCV_EXCP_NONE;
c7b95171
MC
1980}
1981
605def6e
AF
1982static RISCVException write_satp(CPURISCVState *env, int csrno,
1983 target_ulong val)
c7b95171 1984{
5242ef88 1985 target_ulong vm, mask;
419ddf00 1986
c7b95171 1987 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
605def6e 1988 return RISCV_EXCP_NONE;
c7b95171 1989 }
419ddf00 1990
db23e5d9 1991 if (riscv_cpu_mxl(env) == MXL_RV32) {
419ddf00
AF
1992 vm = validate_vm(env, get_field(val, SATP32_MODE));
1993 mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
419ddf00
AF
1994 } else {
1995 vm = validate_vm(env, get_field(val, SATP64_MODE));
1996 mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
419ddf00
AF
1997 }
1998
1999 if (vm && mask) {
7f2b5ff1 2000 if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
605def6e 2001 return RISCV_EXCP_ILLEGAL_INST;
7f2b5ff1 2002 } else {
5242ef88
PD
2003 /*
2004 * The ISA defines SATP.MODE=Bare as "no translation", but we still
2005 * pass these through QEMU's TLB emulation as it improves
2006 * performance. Flushing the TLB on SATP writes with paging
2007 * enabled avoids leaking those invalid cached mappings.
2008 */
2009 tlb_flush(env_cpu(env));
7f2b5ff1
MC
2010 env->satp = val;
2011 }
c7b95171 2012 }
605def6e 2013 return RISCV_EXCP_NONE;
c7b95171
MC
2014}
2015
c7de92b4
AP
2016static int read_vstopi(CPURISCVState *env, int csrno, target_ulong *val)
2017{
2018 int irq, ret;
2019 target_ulong topei;
2020 uint64_t vseip, vsgein;
2021 uint32_t iid, iprio, hviid, hviprio, gein;
2022 uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS];
2023
2024 gein = get_field(env->hstatus, HSTATUS_VGEIN);
2025 hviid = get_field(env->hvictl, HVICTL_IID);
2026 hviprio = get_field(env->hvictl, HVICTL_IPRIO);
2027
2028 if (gein) {
2029 vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
2030 vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP;
2031 if (gein <= env->geilen && vseip) {
2032 siid[scount] = IRQ_S_EXT;
2033 siprio[scount] = IPRIO_MMAXIPRIO + 1;
2034 if (env->aia_ireg_rmw_fn[PRV_S]) {
2035 /*
2036 * Call machine specific IMSIC register emulation for
2037 * reading TOPEI.
2038 */
2039 ret = env->aia_ireg_rmw_fn[PRV_S](
2040 env->aia_ireg_rmw_fn_arg[PRV_S],
2041 AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein,
2042 riscv_cpu_mxl_bits(env)),
2043 &topei, 0, 0);
2044 if (!ret && topei) {
2045 siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK;
2046 }
2047 }
2048 scount++;
2049 }
2050 } else {
2051 if (hviid == IRQ_S_EXT && hviprio) {
2052 siid[scount] = IRQ_S_EXT;
2053 siprio[scount] = hviprio;
2054 scount++;
2055 }
2056 }
2057
2058 if (env->hvictl & HVICTL_VTI) {
2059 if (hviid != IRQ_S_EXT) {
2060 siid[scount] = hviid;
2061 siprio[scount] = hviprio;
2062 scount++;
2063 }
2064 } else {
2065 irq = riscv_cpu_vsirq_pending(env);
2066 if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) {
2067 siid[scount] = irq;
2068 siprio[scount] = env->hviprio[irq];
2069 scount++;
2070 }
2071 }
2072
2073 iid = 0;
2074 iprio = UINT_MAX;
2075 for (s = 0; s < scount; s++) {
2076 if (siprio[s] < iprio) {
2077 iid = siid[s];
2078 iprio = siprio[s];
2079 }
2080 }
2081
2082 if (iid) {
2083 if (env->hvictl & HVICTL_IPRIOM) {
2084 if (iprio > IPRIO_MMAXIPRIO) {
2085 iprio = IPRIO_MMAXIPRIO;
2086 }
2087 if (!iprio) {
2088 if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) {
2089 iprio = IPRIO_MMAXIPRIO;
2090 }
2091 }
2092 } else {
2093 iprio = 1;
2094 }
2095 } else {
2096 iprio = 0;
2097 }
2098
2099 *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2100 *val |= iprio;
2101 return RISCV_EXCP_NONE;
2102}
2103
2104static int read_stopi(CPURISCVState *env, int csrno, target_ulong *val)
2105{
2106 int irq;
2107 uint8_t iprio;
2108
2109 if (riscv_cpu_virt_enabled(env)) {
2110 return read_vstopi(env, CSR_VSTOPI, val);
2111 }
2112
2113 irq = riscv_cpu_sirq_pending(env);
2114 if (irq <= 0 || irq > 63) {
2115 *val = 0;
2116 } else {
2117 iprio = env->siprio[irq];
2118 if (!iprio) {
2119 if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) {
2120 iprio = IPRIO_MMAXIPRIO;
2121 }
2122 }
2123 *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2124 *val |= iprio;
2125 }
2126
2127 return RISCV_EXCP_NONE;
2128}
2129
ff2cc129 2130/* Hypervisor Extensions */
605def6e
AF
2131static RISCVException read_hstatus(CPURISCVState *env, int csrno,
2132 target_ulong *val)
ff2cc129
AF
2133{
2134 *val = env->hstatus;
db23e5d9 2135 if (riscv_cpu_mxl(env) != MXL_RV32) {
8987cdc4
AF
2136 /* We only support 64-bit VSXL */
2137 *val = set_field(*val, HSTATUS_VSXL, 2);
2138 }
30f663b1
AF
2139 /* We only support little endian */
2140 *val = set_field(*val, HSTATUS_VSBE, 0);
605def6e 2141 return RISCV_EXCP_NONE;
ff2cc129
AF
2142}
2143
605def6e
AF
2144static RISCVException write_hstatus(CPURISCVState *env, int csrno,
2145 target_ulong val)
ff2cc129
AF
2146{
2147 env->hstatus = val;
db23e5d9 2148 if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
f8dc878e
AF
2149 qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
2150 }
30f663b1
AF
2151 if (get_field(val, HSTATUS_VSBE) != 0) {
2152 qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
2153 }
605def6e 2154 return RISCV_EXCP_NONE;
ff2cc129
AF
2155}
2156
605def6e
AF
2157static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
2158 target_ulong *val)
ff2cc129
AF
2159{
2160 *val = env->hedeleg;
605def6e 2161 return RISCV_EXCP_NONE;
ff2cc129
AF
2162}
2163
605def6e
AF
2164static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
2165 target_ulong val)
ff2cc129 2166{
bc083a51 2167 env->hedeleg = val & vs_delegable_excps;
605def6e 2168 return RISCV_EXCP_NONE;
ff2cc129
AF
2169}
2170
d028ac75
AP
2171static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
2172 uint64_t *ret_val,
2173 uint64_t new_val, uint64_t wr_mask)
ff2cc129 2174{
d028ac75
AP
2175 uint64_t mask = wr_mask & vs_delegable_ints;
2176
2177 if (ret_val) {
2178 *ret_val = env->hideleg & vs_delegable_ints;
2179 }
2180
2181 env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
605def6e 2182 return RISCV_EXCP_NONE;
ff2cc129
AF
2183}
2184
d028ac75
AP
2185static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
2186 target_ulong *ret_val,
2187 target_ulong new_val, target_ulong wr_mask)
ff2cc129 2188{
d028ac75
AP
2189 uint64_t rval;
2190 RISCVException ret;
2191
2192 ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
2193 if (ret_val) {
2194 *ret_val = rval;
2195 }
2196
2197 return ret;
2198}
2199
2200static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
2201 target_ulong *ret_val,
2202 target_ulong new_val, target_ulong wr_mask)
2203{
2204 uint64_t rval;
2205 RISCVException ret;
2206
2207 ret = rmw_hideleg64(env, csrno, &rval,
2208 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2209 if (ret_val) {
2210 *ret_val = rval >> 32;
2211 }
2212
2213 return ret;
2214}
2215
2216static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
2217 uint64_t *ret_val,
2218 uint64_t new_val, uint64_t wr_mask)
2219{
2220 RISCVException ret;
2221
2222 ret = rmw_mip64(env, csrno, ret_val, new_val,
2223 wr_mask & hvip_writable_mask);
2224 if (ret_val) {
2225 *ret_val &= VS_MODE_INTERRUPTS;
2226 }
2227
2228 return ret;
ff2cc129
AF
2229}
2230
605def6e 2231static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
d028ac75
AP
2232 target_ulong *ret_val,
2233 target_ulong new_val, target_ulong wr_mask)
83028098 2234{
d028ac75
AP
2235 uint64_t rval;
2236 RISCVException ret;
83028098 2237
d028ac75
AP
2238 ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
2239 if (ret_val) {
2240 *ret_val = rval;
2241 }
2242
2243 return ret;
2244}
2245
2246static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
2247 target_ulong *ret_val,
2248 target_ulong new_val, target_ulong wr_mask)
2249{
2250 uint64_t rval;
2251 RISCVException ret;
2252
2253 ret = rmw_hvip64(env, csrno, &rval,
2254 ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2255 if (ret_val) {
2256 *ret_val = rval >> 32;
33979526 2257 }
d028ac75 2258
83028098
AF
2259 return ret;
2260}
2261
605def6e
AF
2262static RISCVException rmw_hip(CPURISCVState *env, int csrno,
2263 target_ulong *ret_value,
2264 target_ulong new_value, target_ulong write_mask)
ff2cc129 2265{
cd032fe7 2266 int ret = rmw_mip(env, csrno, ret_value, new_value,
ff2cc129
AF
2267 write_mask & hip_writable_mask);
2268
33979526 2269 if (ret_value) {
881df35d 2270 *ret_value &= HS_MODE_INTERRUPTS;
33979526 2271 }
ff2cc129
AF
2272 return ret;
2273}
2274
d028ac75
AP
2275static RISCVException rmw_hie(CPURISCVState *env, int csrno,
2276 target_ulong *ret_val,
2277 target_ulong new_val, target_ulong wr_mask)
ff2cc129 2278{
d028ac75
AP
2279 uint64_t rval;
2280 RISCVException ret;
ff2cc129 2281
d028ac75
AP
2282 ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
2283 if (ret_val) {
2284 *ret_val = rval & HS_MODE_INTERRUPTS;
2285 }
2286
2287 return ret;
ff2cc129
AF
2288}
2289
605def6e
AF
2290static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
2291 target_ulong *val)
ff2cc129
AF
2292{
2293 *val = env->hcounteren;
605def6e 2294 return RISCV_EXCP_NONE;
ff2cc129
AF
2295}
2296
605def6e
AF
2297static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
2298 target_ulong val)
ff2cc129
AF
2299{
2300 env->hcounteren = val;
605def6e 2301 return RISCV_EXCP_NONE;
ff2cc129
AF
2302}
2303
cd032fe7
AP
2304static RISCVException read_hgeie(CPURISCVState *env, int csrno,
2305 target_ulong *val)
83028098 2306{
377cbb4b 2307 if (val) {
cd032fe7 2308 *val = env->hgeie;
377cbb4b 2309 }
605def6e 2310 return RISCV_EXCP_NONE;
83028098
AF
2311}
2312
cd032fe7
AP
2313static RISCVException write_hgeie(CPURISCVState *env, int csrno,
2314 target_ulong val)
2315{
2316 /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
2317 val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
2318 env->hgeie = val;
2319 /* Update mip.SGEIP bit */
2320 riscv_cpu_update_mip(env_archcpu(env), MIP_SGEIP,
2321 BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
2322 return RISCV_EXCP_NONE;
2323}
2324
605def6e
AF
2325static RISCVException read_htval(CPURISCVState *env, int csrno,
2326 target_ulong *val)
ff2cc129
AF
2327{
2328 *val = env->htval;
605def6e 2329 return RISCV_EXCP_NONE;
ff2cc129
AF
2330}
2331
605def6e
AF
2332static RISCVException write_htval(CPURISCVState *env, int csrno,
2333 target_ulong val)
ff2cc129
AF
2334{
2335 env->htval = val;
605def6e 2336 return RISCV_EXCP_NONE;
ff2cc129
AF
2337}
2338
605def6e
AF
2339static RISCVException read_htinst(CPURISCVState *env, int csrno,
2340 target_ulong *val)
ff2cc129
AF
2341{
2342 *val = env->htinst;
605def6e 2343 return RISCV_EXCP_NONE;
ff2cc129
AF
2344}
2345
605def6e
AF
2346static RISCVException write_htinst(CPURISCVState *env, int csrno,
2347 target_ulong val)
ff2cc129 2348{
605def6e 2349 return RISCV_EXCP_NONE;
ff2cc129
AF
2350}
2351
cd032fe7
AP
2352static RISCVException read_hgeip(CPURISCVState *env, int csrno,
2353 target_ulong *val)
83028098 2354{
377cbb4b 2355 if (val) {
cd032fe7 2356 *val = env->hgeip;
377cbb4b 2357 }
605def6e 2358 return RISCV_EXCP_NONE;
83028098
AF
2359}
2360
605def6e
AF
2361static RISCVException read_hgatp(CPURISCVState *env, int csrno,
2362 target_ulong *val)
ff2cc129
AF
2363{
2364 *val = env->hgatp;
605def6e 2365 return RISCV_EXCP_NONE;
ff2cc129
AF
2366}
2367
605def6e
AF
2368static RISCVException write_hgatp(CPURISCVState *env, int csrno,
2369 target_ulong val)
ff2cc129
AF
2370{
2371 env->hgatp = val;
605def6e 2372 return RISCV_EXCP_NONE;
ff2cc129
AF
2373}
2374
605def6e
AF
2375static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
2376 target_ulong *val)
c6957248
AP
2377{
2378 if (!env->rdtime_fn) {
605def6e 2379 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
2380 }
2381
c6957248 2382 *val = env->htimedelta;
605def6e 2383 return RISCV_EXCP_NONE;
c6957248
AP
2384}
2385
605def6e
AF
2386static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
2387 target_ulong val)
c6957248
AP
2388{
2389 if (!env->rdtime_fn) {
605def6e 2390 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
2391 }
2392
db23e5d9 2393 if (riscv_cpu_mxl(env) == MXL_RV32) {
8987cdc4
AF
2394 env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
2395 } else {
2396 env->htimedelta = val;
2397 }
605def6e 2398 return RISCV_EXCP_NONE;
c6957248
AP
2399}
2400
605def6e
AF
2401static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
2402 target_ulong *val)
c6957248
AP
2403{
2404 if (!env->rdtime_fn) {
605def6e 2405 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
2406 }
2407
2408 *val = env->htimedelta >> 32;
605def6e 2409 return RISCV_EXCP_NONE;
c6957248
AP
2410}
2411
605def6e
AF
2412static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
2413 target_ulong val)
c6957248
AP
2414{
2415 if (!env->rdtime_fn) {
605def6e 2416 return RISCV_EXCP_ILLEGAL_INST;
c6957248
AP
2417 }
2418
2419 env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
605def6e 2420 return RISCV_EXCP_NONE;
c6957248 2421}
c6957248 2422
2b602398
AP
2423static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val)
2424{
2425 *val = env->hvictl;
2426 return RISCV_EXCP_NONE;
2427}
2428
2429static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val)
2430{
2431 env->hvictl = val & HVICTL_VALID_MASK;
2432 return RISCV_EXCP_NONE;
2433}
2434
2435static int read_hvipriox(CPURISCVState *env, int first_index,
2436 uint8_t *iprio, target_ulong *val)
2437{
2438 int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
2439
2440 /* First index has to be a multiple of number of irqs per register */
2441 if (first_index % num_irqs) {
2442 return (riscv_cpu_virt_enabled(env)) ?
2443 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2444 }
2445
2446 /* Fill-up return value */
2447 *val = 0;
2448 for (i = 0; i < num_irqs; i++) {
2449 if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
2450 continue;
2451 }
2452 if (rdzero) {
2453 continue;
2454 }
2455 *val |= ((target_ulong)iprio[irq]) << (i * 8);
2456 }
2457
2458 return RISCV_EXCP_NONE;
2459}
2460
2461static int write_hvipriox(CPURISCVState *env, int first_index,
2462 uint8_t *iprio, target_ulong val)
2463{
2464 int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
2465
2466 /* First index has to be a multiple of number of irqs per register */
2467 if (first_index % num_irqs) {
2468 return (riscv_cpu_virt_enabled(env)) ?
2469 RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2470 }
2471
2472 /* Fill-up priority arrary */
2473 for (i = 0; i < num_irqs; i++) {
2474 if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
2475 continue;
2476 }
2477 if (rdzero) {
2478 iprio[irq] = 0;
2479 } else {
2480 iprio[irq] = (val >> (i * 8)) & 0xff;
2481 }
2482 }
2483
2484 return RISCV_EXCP_NONE;
2485}
2486
2487static int read_hviprio1(CPURISCVState *env, int csrno, target_ulong *val)
2488{
2489 return read_hvipriox(env, 0, env->hviprio, val);
2490}
2491
2492static int write_hviprio1(CPURISCVState *env, int csrno, target_ulong val)
2493{
2494 return write_hvipriox(env, 0, env->hviprio, val);
2495}
2496
2497static int read_hviprio1h(CPURISCVState *env, int csrno, target_ulong *val)
2498{
2499 return read_hvipriox(env, 4, env->hviprio, val);
2500}
2501
2502static int write_hviprio1h(CPURISCVState *env, int csrno, target_ulong val)
2503{
2504 return write_hvipriox(env, 4, env->hviprio, val);
2505}
2506
2507static int read_hviprio2(CPURISCVState *env, int csrno, target_ulong *val)
2508{
2509 return read_hvipriox(env, 8, env->hviprio, val);
2510}
2511
2512static int write_hviprio2(CPURISCVState *env, int csrno, target_ulong val)
2513{
2514 return write_hvipriox(env, 8, env->hviprio, val);
2515}
2516
2517static int read_hviprio2h(CPURISCVState *env, int csrno, target_ulong *val)
2518{
2519 return read_hvipriox(env, 12, env->hviprio, val);
2520}
2521
2522static int write_hviprio2h(CPURISCVState *env, int csrno, target_ulong val)
2523{
2524 return write_hvipriox(env, 12, env->hviprio, val);
2525}
2526
8747c9ee 2527/* Virtual CSR Registers */
605def6e
AF
2528static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
2529 target_ulong *val)
8747c9ee
AF
2530{
2531 *val = env->vsstatus;
605def6e 2532 return RISCV_EXCP_NONE;
8747c9ee
AF
2533}
2534
605def6e
AF
2535static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
2536 target_ulong val)
8747c9ee 2537{
284d697c 2538 uint64_t mask = (target_ulong)-1;
f310df58
LZ
2539 if ((val & VSSTATUS64_UXL) == 0) {
2540 mask &= ~VSSTATUS64_UXL;
2541 }
284d697c 2542 env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
605def6e 2543 return RISCV_EXCP_NONE;
8747c9ee
AF
2544}
2545
8747c9ee
AF
2546static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
2547{
2548 *val = env->vstvec;
605def6e 2549 return RISCV_EXCP_NONE;
8747c9ee
AF
2550}
2551
605def6e
AF
2552static RISCVException write_vstvec(CPURISCVState *env, int csrno,
2553 target_ulong val)
8747c9ee
AF
2554{
2555 env->vstvec = val;
605def6e 2556 return RISCV_EXCP_NONE;
8747c9ee
AF
2557}
2558
605def6e
AF
2559static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
2560 target_ulong *val)
8747c9ee
AF
2561{
2562 *val = env->vsscratch;
605def6e 2563 return RISCV_EXCP_NONE;
8747c9ee
AF
2564}
2565
605def6e
AF
2566static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
2567 target_ulong val)
8747c9ee
AF
2568{
2569 env->vsscratch = val;
605def6e 2570 return RISCV_EXCP_NONE;
8747c9ee
AF
2571}
2572
605def6e
AF
2573static RISCVException read_vsepc(CPURISCVState *env, int csrno,
2574 target_ulong *val)
8747c9ee
AF
2575{
2576 *val = env->vsepc;
605def6e 2577 return RISCV_EXCP_NONE;
8747c9ee
AF
2578}
2579
605def6e
AF
2580static RISCVException write_vsepc(CPURISCVState *env, int csrno,
2581 target_ulong val)
8747c9ee
AF
2582{
2583 env->vsepc = val;
605def6e 2584 return RISCV_EXCP_NONE;
8747c9ee
AF
2585}
2586
605def6e
AF
2587static RISCVException read_vscause(CPURISCVState *env, int csrno,
2588 target_ulong *val)
8747c9ee
AF
2589{
2590 *val = env->vscause;
605def6e 2591 return RISCV_EXCP_NONE;
8747c9ee
AF
2592}
2593
605def6e
AF
2594static RISCVException write_vscause(CPURISCVState *env, int csrno,
2595 target_ulong val)
8747c9ee
AF
2596{
2597 env->vscause = val;
605def6e 2598 return RISCV_EXCP_NONE;
8747c9ee
AF
2599}
2600
605def6e
AF
2601static RISCVException read_vstval(CPURISCVState *env, int csrno,
2602 target_ulong *val)
8747c9ee
AF
2603{
2604 *val = env->vstval;
605def6e 2605 return RISCV_EXCP_NONE;
8747c9ee
AF
2606}
2607
605def6e
AF
2608static RISCVException write_vstval(CPURISCVState *env, int csrno,
2609 target_ulong val)
8747c9ee
AF
2610{
2611 env->vstval = val;
605def6e 2612 return RISCV_EXCP_NONE;
8747c9ee
AF
2613}
2614
605def6e
AF
2615static RISCVException read_vsatp(CPURISCVState *env, int csrno,
2616 target_ulong *val)
8747c9ee
AF
2617{
2618 *val = env->vsatp;
605def6e 2619 return RISCV_EXCP_NONE;
8747c9ee
AF
2620}
2621
605def6e
AF
2622static RISCVException write_vsatp(CPURISCVState *env, int csrno,
2623 target_ulong val)
8747c9ee
AF
2624{
2625 env->vsatp = val;
605def6e 2626 return RISCV_EXCP_NONE;
8747c9ee
AF
2627}
2628
605def6e
AF
2629static RISCVException read_mtval2(CPURISCVState *env, int csrno,
2630 target_ulong *val)
34cfb5f6
AF
2631{
2632 *val = env->mtval2;
605def6e 2633 return RISCV_EXCP_NONE;
34cfb5f6
AF
2634}
2635
605def6e
AF
2636static RISCVException write_mtval2(CPURISCVState *env, int csrno,
2637 target_ulong val)
34cfb5f6
AF
2638{
2639 env->mtval2 = val;
605def6e 2640 return RISCV_EXCP_NONE;
34cfb5f6
AF
2641}
2642
605def6e
AF
2643static RISCVException read_mtinst(CPURISCVState *env, int csrno,
2644 target_ulong *val)
34cfb5f6
AF
2645{
2646 *val = env->mtinst;
605def6e 2647 return RISCV_EXCP_NONE;
34cfb5f6
AF
2648}
2649
605def6e
AF
2650static RISCVException write_mtinst(CPURISCVState *env, int csrno,
2651 target_ulong val)
34cfb5f6
AF
2652{
2653 env->mtinst = val;
605def6e 2654 return RISCV_EXCP_NONE;
34cfb5f6
AF
2655}
2656
c7b95171 2657/* Physical Memory Protection */
2582a95c
HW
2658static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
2659 target_ulong *val)
2660{
2661 *val = mseccfg_csr_read(env);
2662 return RISCV_EXCP_NONE;
2663}
2664
2665static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
2666 target_ulong val)
2667{
2668 mseccfg_csr_write(env, val);
2669 return RISCV_EXCP_NONE;
2670}
2671
79f26b3b
LZ
2672static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
2673{
2674 /* TODO: RV128 restriction check */
2675 if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
2676 return false;
2677 }
2678 return true;
2679}
2680
605def6e
AF
2681static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
2682 target_ulong *val)
c7b95171 2683{
79f26b3b
LZ
2684 uint32_t reg_index = csrno - CSR_PMPCFG0;
2685
2686 if (!check_pmp_reg_index(env, reg_index)) {
2687 return RISCV_EXCP_ILLEGAL_INST;
2688 }
c7b95171 2689 *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
605def6e 2690 return RISCV_EXCP_NONE;
c7b95171
MC
2691}
2692
605def6e
AF
2693static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
2694 target_ulong val)
c7b95171 2695{
79f26b3b
LZ
2696 uint32_t reg_index = csrno - CSR_PMPCFG0;
2697
2698 if (!check_pmp_reg_index(env, reg_index)) {
2699 return RISCV_EXCP_ILLEGAL_INST;
2700 }
c7b95171 2701 pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
605def6e 2702 return RISCV_EXCP_NONE;
c7b95171
MC
2703}
2704
605def6e
AF
2705static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
2706 target_ulong *val)
c7b95171
MC
2707{
2708 *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
605def6e 2709 return RISCV_EXCP_NONE;
c7b95171
MC
2710}
2711
605def6e
AF
2712static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
2713 target_ulong val)
c7b95171
MC
2714{
2715 pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
605def6e 2716 return RISCV_EXCP_NONE;
c7b95171
MC
2717}
2718
b6092544
BM
2719static RISCVException read_tselect(CPURISCVState *env, int csrno,
2720 target_ulong *val)
2721{
2722 *val = tselect_csr_read(env);
2723 return RISCV_EXCP_NONE;
2724}
2725
2726static RISCVException write_tselect(CPURISCVState *env, int csrno,
2727 target_ulong val)
2728{
2729 tselect_csr_write(env, val);
2730 return RISCV_EXCP_NONE;
2731}
2732
2733static RISCVException read_tdata(CPURISCVState *env, int csrno,
2734 target_ulong *val)
2735{
2736 /* return 0 in tdata1 to end the trigger enumeration */
2737 if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
2738 *val = 0;
2739 return RISCV_EXCP_NONE;
2740 }
2741
2742 if (!tdata_available(env, csrno - CSR_TDATA1)) {
2743 return RISCV_EXCP_ILLEGAL_INST;
2744 }
2745
2746 *val = tdata_csr_read(env, csrno - CSR_TDATA1);
2747 return RISCV_EXCP_NONE;
2748}
2749
2750static RISCVException write_tdata(CPURISCVState *env, int csrno,
2751 target_ulong val)
2752{
2753 if (!tdata_available(env, csrno - CSR_TDATA1)) {
2754 return RISCV_EXCP_ILLEGAL_INST;
2755 }
2756
2757 tdata_csr_write(env, csrno - CSR_TDATA1, val);
2758 return RISCV_EXCP_NONE;
2759}
2760
4bbe8033
AB
2761/*
2762 * Functions to access Pointer Masking feature registers
2763 * We have to check if current priv lvl could modify
2764 * csr in given mode
2765 */
2766static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
2767{
2768 int csr_priv = get_field(csrno, 0x300);
2769 int pm_current;
2770
47bdec82
LZ
2771 if (env->debugger) {
2772 return false;
2773 }
4bbe8033
AB
2774 /*
2775 * If priv lvls differ that means we're accessing csr from higher priv lvl,
2776 * so allow the access
2777 */
2778 if (env->priv != csr_priv) {
2779 return false;
2780 }
2781 switch (env->priv) {
2782 case PRV_M:
2783 pm_current = get_field(env->mmte, M_PM_CURRENT);
2784 break;
2785 case PRV_S:
2786 pm_current = get_field(env->mmte, S_PM_CURRENT);
2787 break;
2788 case PRV_U:
2789 pm_current = get_field(env->mmte, U_PM_CURRENT);
2790 break;
2791 default:
2792 g_assert_not_reached();
2793 }
2794 /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
2795 return !pm_current;
2796}
2797
2798static RISCVException read_mmte(CPURISCVState *env, int csrno,
2799 target_ulong *val)
2800{
2801 *val = env->mmte & MMTE_MASK;
2802 return RISCV_EXCP_NONE;
2803}
2804
2805static RISCVException write_mmte(CPURISCVState *env, int csrno,
2806 target_ulong val)
2807{
2808 uint64_t mstatus;
2809 target_ulong wpri_val = val & MMTE_MASK;
2810
2811 if (val != wpri_val) {
2812 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2813 "MMTE: WPRI violation written 0x", val,
2814 "vs expected 0x", wpri_val);
2815 }
2816 /* for machine mode pm.current is hardwired to 1 */
2817 wpri_val |= MMTE_M_PM_CURRENT;
2818
2819 /* hardwiring pm.instruction bit to 0, since it's not supported yet */
2820 wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
2821 env->mmte = wpri_val | PM_EXT_DIRTY;
40bfa5f6 2822 riscv_cpu_update_mask(env);
4bbe8033
AB
2823
2824 /* Set XS and SD bits, since PM CSRs are dirty */
2825 mstatus = env->mstatus | MSTATUS_XS;
2826 write_mstatus(env, csrno, mstatus);
2827 return RISCV_EXCP_NONE;
2828}
2829
2830static RISCVException read_smte(CPURISCVState *env, int csrno,
2831 target_ulong *val)
2832{
2833 *val = env->mmte & SMTE_MASK;
2834 return RISCV_EXCP_NONE;
2835}
2836
2837static RISCVException write_smte(CPURISCVState *env, int csrno,
2838 target_ulong val)
2839{
2840 target_ulong wpri_val = val & SMTE_MASK;
2841
2842 if (val != wpri_val) {
2843 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2844 "SMTE: WPRI violation written 0x", val,
2845 "vs expected 0x", wpri_val);
2846 }
2847
2848 /* if pm.current==0 we can't modify current PM CSRs */
2849 if (check_pm_current_disabled(env, csrno)) {
2850 return RISCV_EXCP_NONE;
2851 }
2852
2853 wpri_val |= (env->mmte & ~SMTE_MASK);
2854 write_mmte(env, csrno, wpri_val);
2855 return RISCV_EXCP_NONE;
2856}
2857
2858static RISCVException read_umte(CPURISCVState *env, int csrno,
2859 target_ulong *val)
2860{
2861 *val = env->mmte & UMTE_MASK;
2862 return RISCV_EXCP_NONE;
2863}
2864
2865static RISCVException write_umte(CPURISCVState *env, int csrno,
2866 target_ulong val)
2867{
2868 target_ulong wpri_val = val & UMTE_MASK;
2869
2870 if (val != wpri_val) {
2871 qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2872 "UMTE: WPRI violation written 0x", val,
2873 "vs expected 0x", wpri_val);
2874 }
2875
2876 if (check_pm_current_disabled(env, csrno)) {
2877 return RISCV_EXCP_NONE;
2878 }
2879
2880 wpri_val |= (env->mmte & ~UMTE_MASK);
2881 write_mmte(env, csrno, wpri_val);
2882 return RISCV_EXCP_NONE;
2883}
2884
2885static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
2886 target_ulong *val)
2887{
2888 *val = env->mpmmask;
2889 return RISCV_EXCP_NONE;
2890}
2891
2892static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
2893 target_ulong val)
2894{
2895 uint64_t mstatus;
2896
2897 env->mpmmask = val;
40bfa5f6
LZ
2898 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
2899 env->cur_pmmask = val;
2900 }
4bbe8033
AB
2901 env->mmte |= PM_EXT_DIRTY;
2902
2903 /* Set XS and SD bits, since PM CSRs are dirty */
2904 mstatus = env->mstatus | MSTATUS_XS;
2905 write_mstatus(env, csrno, mstatus);
2906 return RISCV_EXCP_NONE;
2907}
2908
2909static RISCVException read_spmmask(CPURISCVState *env, int csrno,
2910 target_ulong *val)
2911{
2912 *val = env->spmmask;
2913 return RISCV_EXCP_NONE;
2914}
2915
2916static RISCVException write_spmmask(CPURISCVState *env, int csrno,
2917 target_ulong val)
2918{
2919 uint64_t mstatus;
2920
2921 /* if pm.current==0 we can't modify current PM CSRs */
2922 if (check_pm_current_disabled(env, csrno)) {
2923 return RISCV_EXCP_NONE;
2924 }
2925 env->spmmask = val;
40bfa5f6
LZ
2926 if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
2927 env->cur_pmmask = val;
2928 }
4bbe8033
AB
2929 env->mmte |= PM_EXT_DIRTY;
2930
2931 /* Set XS and SD bits, since PM CSRs are dirty */
2932 mstatus = env->mstatus | MSTATUS_XS;
2933 write_mstatus(env, csrno, mstatus);
2934 return RISCV_EXCP_NONE;
2935}
2936
2937static RISCVException read_upmmask(CPURISCVState *env, int csrno,
2938 target_ulong *val)
2939{
2940 *val = env->upmmask;
2941 return RISCV_EXCP_NONE;
2942}
2943
2944static RISCVException write_upmmask(CPURISCVState *env, int csrno,
2945 target_ulong val)
2946{
2947 uint64_t mstatus;
2948
2949 /* if pm.current==0 we can't modify current PM CSRs */
2950 if (check_pm_current_disabled(env, csrno)) {
2951 return RISCV_EXCP_NONE;
2952 }
2953 env->upmmask = val;
40bfa5f6
LZ
2954 if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
2955 env->cur_pmmask = val;
2956 }
4bbe8033
AB
2957 env->mmte |= PM_EXT_DIRTY;
2958
2959 /* Set XS and SD bits, since PM CSRs are dirty */
2960 mstatus = env->mstatus | MSTATUS_XS;
2961 write_mstatus(env, csrno, mstatus);
2962 return RISCV_EXCP_NONE;
2963}
2964
2965static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
2966 target_ulong *val)
2967{
2968 *val = env->mpmbase;
2969 return RISCV_EXCP_NONE;
2970}
2971
2972static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
2973 target_ulong val)
2974{
2975 uint64_t mstatus;
2976
2977 env->mpmbase = val;
40bfa5f6
LZ
2978 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
2979 env->cur_pmbase = val;
2980 }
4bbe8033
AB
2981 env->mmte |= PM_EXT_DIRTY;
2982
2983 /* Set XS and SD bits, since PM CSRs are dirty */
2984 mstatus = env->mstatus | MSTATUS_XS;
2985 write_mstatus(env, csrno, mstatus);
2986 return RISCV_EXCP_NONE;
2987}
2988
2989static RISCVException read_spmbase(CPURISCVState *env, int csrno,
2990 target_ulong *val)
2991{
2992 *val = env->spmbase;
2993 return RISCV_EXCP_NONE;
2994}
2995
2996static RISCVException write_spmbase(CPURISCVState *env, int csrno,
2997 target_ulong val)
2998{
2999 uint64_t mstatus;
3000
3001 /* if pm.current==0 we can't modify current PM CSRs */
3002 if (check_pm_current_disabled(env, csrno)) {
3003 return RISCV_EXCP_NONE;
3004 }
3005 env->spmbase = val;
40bfa5f6
LZ
3006 if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
3007 env->cur_pmbase = val;
3008 }
4bbe8033
AB
3009 env->mmte |= PM_EXT_DIRTY;
3010
3011 /* Set XS and SD bits, since PM CSRs are dirty */
3012 mstatus = env->mstatus | MSTATUS_XS;
3013 write_mstatus(env, csrno, mstatus);
3014 return RISCV_EXCP_NONE;
3015}
3016
3017static RISCVException read_upmbase(CPURISCVState *env, int csrno,
3018 target_ulong *val)
3019{
3020 *val = env->upmbase;
3021 return RISCV_EXCP_NONE;
3022}
3023
3024static RISCVException write_upmbase(CPURISCVState *env, int csrno,
3025 target_ulong val)
3026{
3027 uint64_t mstatus;
3028
3029 /* if pm.current==0 we can't modify current PM CSRs */
3030 if (check_pm_current_disabled(env, csrno)) {
3031 return RISCV_EXCP_NONE;
3032 }
3033 env->upmbase = val;
40bfa5f6
LZ
3034 if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
3035 env->cur_pmbase = val;
3036 }
4bbe8033
AB
3037 env->mmte |= PM_EXT_DIRTY;
3038
3039 /* Set XS and SD bits, since PM CSRs are dirty */
3040 mstatus = env->mstatus | MSTATUS_XS;
3041 write_mstatus(env, csrno, mstatus);
3042 return RISCV_EXCP_NONE;
3043}
3044
c7b95171
MC
3045#endif
3046
3047/*
3048 * riscv_csrrw - read and/or update control and status register
3049 *
3050 * csrr <-> riscv_csrrw(env, csrno, ret_value, 0, 0);
3051 * csrrw <-> riscv_csrrw(env, csrno, ret_value, value, -1);
3052 * csrrs <-> riscv_csrrw(env, csrno, ret_value, -1, value);
3053 * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value);
3054 */
3055
457c360f
FP
3056static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
3057 int csrno,
3058 bool write_mask,
3059 RISCVCPU *cpu)
c7b95171 3060{
65e728a2 3061 /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
457c360f 3062 int read_only = get_field(csrno, 0xC00) == 3;
7100fe6c 3063 int csr_min_priv = csr_ops[csrno].min_priv_ver;
c7b95171 3064#if !defined(CONFIG_USER_ONLY)
0a42f4c4 3065 int effective_priv = env->priv;
0a42f4c4
AF
3066
3067 if (riscv_has_ext(env, RVH) &&
3068 env->priv == PRV_S &&
3069 !riscv_cpu_virt_enabled(env)) {
3070 /*
3071 * We are in S mode without virtualisation, therefore we are in HS Mode.
3072 * Add 1 to the effective privledge level to allow us to access the
3073 * Hypervisor CSRs.
3074 */
3075 effective_priv++;
e6e03dcf 3076 }
0a42f4c4 3077
42109837 3078 if (!env->debugger && (effective_priv < get_field(csrno, 0x300))) {
533c91e8 3079 return RISCV_EXCP_ILLEGAL_INST;
c7b95171
MC
3080 }
3081#endif
42109837
LZ
3082 if (write_mask && read_only) {
3083 return RISCV_EXCP_ILLEGAL_INST;
3084 }
c7b95171 3085
591bddea
PD
3086 /* ensure the CSR extension is enabled. */
3087 if (!cpu->cfg.ext_icsr) {
533c91e8 3088 return RISCV_EXCP_ILLEGAL_INST;
591bddea
PD
3089 }
3090
a88365c1 3091 /* check predicate */
e39a8320 3092 if (!csr_ops[csrno].predicate) {
533c91e8 3093 return RISCV_EXCP_ILLEGAL_INST;
a88365c1 3094 }
457c360f 3095
7100fe6c
AP
3096 if (env->priv_ver < csr_min_priv) {
3097 return RISCV_EXCP_ILLEGAL_INST;
3098 }
3099
457c360f
FP
3100 return csr_ops[csrno].predicate(env, csrno);
3101}
3102
3103static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
3104 target_ulong *ret_value,
3105 target_ulong new_value,
3106 target_ulong write_mask)
3107{
3108 RISCVException ret;
3109 target_ulong old_value;
a88365c1 3110
c7b95171
MC
3111 /* execute combined read/write operation if it exists */
3112 if (csr_ops[csrno].op) {
533c91e8 3113 return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
c7b95171
MC
3114 }
3115
3116 /* if no accessor exists then return failure */
3117 if (!csr_ops[csrno].read) {
533c91e8 3118 return RISCV_EXCP_ILLEGAL_INST;
c7b95171 3119 }
c7b95171
MC
3120 /* read old value */
3121 ret = csr_ops[csrno].read(env, csrno, &old_value);
605def6e 3122 if (ret != RISCV_EXCP_NONE) {
533c91e8 3123 return ret;
c7b95171
MC
3124 }
3125
3126 /* write value if writable and write mask set, otherwise drop writes */
3127 if (write_mask) {
3128 new_value = (old_value & ~write_mask) | (new_value & write_mask);
3129 if (csr_ops[csrno].write) {
3130 ret = csr_ops[csrno].write(env, csrno, new_value);
605def6e 3131 if (ret != RISCV_EXCP_NONE) {
533c91e8 3132 return ret;
c7b95171
MC
3133 }
3134 }
3135 }
3136
3137 /* return old value */
3138 if (ret_value) {
3139 *ret_value = old_value;
3140 }
3141
533c91e8 3142 return RISCV_EXCP_NONE;
c7b95171
MC
3143}
3144
457c360f
FP
3145RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
3146 target_ulong *ret_value,
3147 target_ulong new_value, target_ulong write_mask)
3148{
3149 RISCVCPU *cpu = env_archcpu(env);
3150
3151 RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu);
3152 if (ret != RISCV_EXCP_NONE) {
3153 return ret;
3154 }
3155
3156 return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
3157}
3158
3159static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
3160 Int128 *ret_value,
3161 Int128 new_value,
3162 Int128 write_mask)
961738ff 3163{
457c360f
FP
3164 RISCVException ret;
3165 Int128 old_value;
3166
3167 /* read old value */
3168 ret = csr_ops[csrno].read128(env, csrno, &old_value);
3169 if (ret != RISCV_EXCP_NONE) {
3170 return ret;
3171 }
3172
3173 /* write value if writable and write mask set, otherwise drop writes */
3174 if (int128_nz(write_mask)) {
3175 new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
3176 int128_and(new_value, write_mask));
3177 if (csr_ops[csrno].write128) {
3178 ret = csr_ops[csrno].write128(env, csrno, new_value);
3179 if (ret != RISCV_EXCP_NONE) {
3180 return ret;
3181 }
3182 } else if (csr_ops[csrno].write) {
3183 /* avoids having to write wrappers for all registers */
3184 ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
3185 if (ret != RISCV_EXCP_NONE) {
3186 return ret;
3187 }
3188 }
3189 }
961738ff 3190
457c360f 3191 /* return old value */
961738ff 3192 if (ret_value) {
457c360f
FP
3193 *ret_value = old_value;
3194 }
3195
3196 return RISCV_EXCP_NONE;
3197}
3198
3199RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
3200 Int128 *ret_value,
3201 Int128 new_value, Int128 write_mask)
3202{
3203 RISCVException ret;
3204 RISCVCPU *cpu = env_archcpu(env);
3205
3206 ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu);
3207 if (ret != RISCV_EXCP_NONE) {
3208 return ret;
961738ff
FP
3209 }
3210
457c360f
FP
3211 if (csr_ops[csrno].read128) {
3212 return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
3213 }
3214
3215 /*
3216 * Fall back to 64-bit version for now, if the 128-bit alternative isn't
3217 * at all defined.
3218 * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
3219 * significant), for those, this fallback is correctly handling the accesses
3220 */
3221 target_ulong old_value;
3222 ret = riscv_csrrw_do64(env, csrno, &old_value,
3223 int128_getlo(new_value),
3224 int128_getlo(write_mask));
3225 if (ret == RISCV_EXCP_NONE && ret_value) {
3226 *ret_value = int128_make64(old_value);
3227 }
961738ff
FP
3228 return ret;
3229}
3230
753e3fe2
JW
3231/*
3232 * Debugger support. If not in user mode, set env->debugger before the
3233 * riscv_csrrw call and clear it after the call.
3234 */
533c91e8
AF
3235RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
3236 target_ulong *ret_value,
3237 target_ulong new_value,
3238 target_ulong write_mask)
753e3fe2 3239{
533c91e8 3240 RISCVException ret;
753e3fe2
JW
3241#if !defined(CONFIG_USER_ONLY)
3242 env->debugger = true;
3243#endif
3244 ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
3245#if !defined(CONFIG_USER_ONLY)
3246 env->debugger = false;
3247#endif
3248 return ret;
3249}
3250
c7b95171 3251/* Control and Status Register function table */
56118ee8 3252riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
c7b95171 3253 /* User Floating-Point CSRs */
8ceac5dc
BM
3254 [CSR_FFLAGS] = { "fflags", fs, read_fflags, write_fflags },
3255 [CSR_FRM] = { "frm", fs, read_frm, write_frm },
3256 [CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr },
8e3a1f18 3257 /* Vector CSRs */
a4b2fa43
AP
3258 [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart,
3259 .min_priv_ver = PRIV_VERSION_1_12_0 },
3260 [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat,
3261 .min_priv_ver = PRIV_VERSION_1_12_0 },
3262 [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm,
3263 .min_priv_ver = PRIV_VERSION_1_12_0 },
3264 [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr,
3265 .min_priv_ver = PRIV_VERSION_1_12_0 },
3266 [CSR_VL] = { "vl", vs, read_vl,
3267 .min_priv_ver = PRIV_VERSION_1_12_0 },
3268 [CSR_VTYPE] = { "vtype", vs, read_vtype,
3269 .min_priv_ver = PRIV_VERSION_1_12_0 },
3270 [CSR_VLENB] = { "vlenb", vs, read_vlenb,
3271 .min_priv_ver = PRIV_VERSION_1_12_0 },
c7b95171 3272 /* User Timers and Counters */
8ceac5dc
BM
3273 [CSR_CYCLE] = { "cycle", ctr, read_instret },
3274 [CSR_INSTRET] = { "instret", ctr, read_instret },
3275 [CSR_CYCLEH] = { "cycleh", ctr32, read_instreth },
3276 [CSR_INSTRETH] = { "instreth", ctr32, read_instreth },
3277
3278 /*
3279 * In privileged mode, the monitor will have to emulate TIME CSRs only if
3280 * rdtime callback is not provided by machine/platform emulation.
3281 */
3282 [CSR_TIME] = { "time", ctr, read_time },
3283 [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
c7b95171
MC
3284
3285#if !defined(CONFIG_USER_ONLY)
3286 /* Machine Timers and Counters */
8ceac5dc
BM
3287 [CSR_MCYCLE] = { "mcycle", any, read_instret },
3288 [CSR_MINSTRET] = { "minstret", any, read_instret },
3289 [CSR_MCYCLEH] = { "mcycleh", any32, read_instreth },
3290 [CSR_MINSTRETH] = { "minstreth", any32, read_instreth },
c7b95171
MC
3291
3292 /* Machine Information Registers */
9951ba94
FC
3293 [CSR_MVENDORID] = { "mvendorid", any, read_mvendorid },
3294 [CSR_MARCHID] = { "marchid", any, read_marchid },
3295 [CSR_MIMPID] = { "mimpid", any, read_mipid },
3296 [CSR_MHARTID] = { "mhartid", any, read_mhartid },
c7b95171 3297
3e6a417c
AP
3298 [CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero,
3299 .min_priv_ver = PRIV_VERSION_1_12_0 },
c7b95171 3300 /* Machine Trap Setup */
457c360f
FP
3301 [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL,
3302 read_mstatus_i128 },
3303 [CSR_MISA] = { "misa", any, read_misa, write_misa, NULL,
3304 read_misa_i128 },
d028ac75 3305 [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg },
8ceac5dc 3306 [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
d028ac75 3307 [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
8ceac5dc
BM
3308 [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
3309 [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, write_mcounteren },
c7b95171 3310
8ceac5dc 3311 [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush },
551fa7e8 3312
c7b95171 3313 /* Machine Trap Handling */
457c360f
FP
3314 [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch, NULL,
3315 read_mscratch_i128, write_mscratch_i128 },
8ceac5dc
BM
3316 [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc },
3317 [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause },
ac12b601 3318 [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval },
8ceac5dc 3319 [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip },
c7b95171 3320
d1ceff40
AP
3321 /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
3322 [CSR_MISELECT] = { "miselect", aia_any, NULL, NULL, rmw_xiselect },
3323 [CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg },
3324
c7de92b4
AP
3325 /* Machine-Level Interrupts (AIA) */
3326 [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
3327
ac4b0302
AP
3328 /* Machine-Level IMSIC Interface (AIA) */
3329 [CSR_MSETEIPNUM] = { "mseteipnum", aia_any, NULL, NULL, rmw_xsetclreinum },
3330 [CSR_MCLREIPNUM] = { "mclreipnum", aia_any, NULL, NULL, rmw_xsetclreinum },
3331 [CSR_MSETEIENUM] = { "mseteienum", aia_any, NULL, NULL, rmw_xsetclreinum },
3332 [CSR_MCLREIENUM] = { "mclreienum", aia_any, NULL, NULL, rmw_xsetclreinum },
3333 [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
3334
d0237b4d
AP
3335 /* Virtual Interrupts for Supervisor Level (AIA) */
3336 [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore },
3337 [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore },
3338
d028ac75
AP
3339 /* Machine-Level High-Half CSRs (AIA) */
3340 [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
3341 [CSR_MIEH] = { "mieh", aia_any32, NULL, NULL, rmw_mieh },
d0237b4d
AP
3342 [CSR_MVIENH] = { "mvienh", aia_any32, read_zero, write_ignore },
3343 [CSR_MVIPH] = { "mviph", aia_any32, read_zero, write_ignore },
d028ac75
AP
3344 [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
3345
29a9ec9b
AP
3346 /* Execution environment configuration */
3347 [CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg,
3348 .min_priv_ver = PRIV_VERSION_1_12_0 },
3349 [CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh,
3350 .min_priv_ver = PRIV_VERSION_1_12_0 },
3351 [CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
3352 .min_priv_ver = PRIV_VERSION_1_12_0 },
3353 [CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg,
3354 .min_priv_ver = PRIV_VERSION_1_12_0 },
3355 [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
3356 .min_priv_ver = PRIV_VERSION_1_12_0 },
3357
c7b95171 3358 /* Supervisor Trap Setup */
457c360f
FP
3359 [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
3360 read_sstatus_i128 },
d028ac75 3361 [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie },
8ceac5dc
BM
3362 [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
3363 [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren },
c7b95171
MC
3364
3365 /* Supervisor Trap Handling */
457c360f
FP
3366 [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, NULL,
3367 read_sscratch_i128, write_sscratch_i128 },
8ceac5dc
BM
3368 [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc },
3369 [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
ac12b601 3370 [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
8ceac5dc 3371 [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
c7b95171
MC
3372
3373 /* Supervisor Protection and Translation */
8ceac5dc
BM
3374 [CSR_SATP] = { "satp", smode, read_satp, write_satp },
3375
d1ceff40
AP
3376 /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
3377 [CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect },
3378 [CSR_SIREG] = { "sireg", aia_smode, NULL, NULL, rmw_xireg },
3379
c7de92b4
AP
3380 /* Supervisor-Level Interrupts (AIA) */
3381 [CSR_STOPI] = { "stopi", aia_smode, read_stopi },
3382
ac4b0302
AP
3383 /* Supervisor-Level IMSIC Interface (AIA) */
3384 [CSR_SSETEIPNUM] = { "sseteipnum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3385 [CSR_SCLREIPNUM] = { "sclreipnum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3386 [CSR_SSETEIENUM] = { "sseteienum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3387 [CSR_SCLREIENUM] = { "sclreienum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3388 [CSR_STOPEI] = { "stopei", aia_smode, NULL, NULL, rmw_xtopei },
3389
d028ac75
AP
3390 /* Supervisor-Level High-Half CSRs (AIA) */
3391 [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh },
3392 [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph },
3393
a4b2fa43
AP
3394 [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus,
3395 .min_priv_ver = PRIV_VERSION_1_12_0 },
3396 [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg,
3397 .min_priv_ver = PRIV_VERSION_1_12_0 },
3398 [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg,
3399 .min_priv_ver = PRIV_VERSION_1_12_0 },
3400 [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip,
3401 .min_priv_ver = PRIV_VERSION_1_12_0 },
3402 [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip,
3403 .min_priv_ver = PRIV_VERSION_1_12_0 },
3404 [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie,
3405 .min_priv_ver = PRIV_VERSION_1_12_0 },
3406 [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren,
3407 .min_priv_ver = PRIV_VERSION_1_12_0 },
3408 [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie,
3409 .min_priv_ver = PRIV_VERSION_1_12_0 },
3410 [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval,
3411 .min_priv_ver = PRIV_VERSION_1_12_0 },
3412 [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst,
3413 .min_priv_ver = PRIV_VERSION_1_12_0 },
3414 [CSR_HGEIP] = { "hgeip", hmode, read_hgeip,
3415 .min_priv_ver = PRIV_VERSION_1_12_0 },
3416 [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp,
3417 .min_priv_ver = PRIV_VERSION_1_12_0 },
3418 [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta,
3419 .min_priv_ver = PRIV_VERSION_1_12_0 },
3420 [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah,
3421 .min_priv_ver = PRIV_VERSION_1_12_0 },
3422
3423 [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus,
3424 .min_priv_ver = PRIV_VERSION_1_12_0 },
3425 [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip,
3426 .min_priv_ver = PRIV_VERSION_1_12_0 },
3427 [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie ,
3428 .min_priv_ver = PRIV_VERSION_1_12_0 },
3429 [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec,
3430 .min_priv_ver = PRIV_VERSION_1_12_0 },
3431 [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch,
3432 .min_priv_ver = PRIV_VERSION_1_12_0 },
3433 [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc,
3434 .min_priv_ver = PRIV_VERSION_1_12_0 },
3435 [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause,
3436 .min_priv_ver = PRIV_VERSION_1_12_0 },
3437 [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval,
3438 .min_priv_ver = PRIV_VERSION_1_12_0 },
3439 [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
3440 .min_priv_ver = PRIV_VERSION_1_12_0 },
3441
3442 [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
3443 .min_priv_ver = PRIV_VERSION_1_12_0 },
3444 [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
3445 .min_priv_ver = PRIV_VERSION_1_12_0 },
34cfb5f6 3446
2b602398 3447 /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
d0237b4d 3448 [CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore },
2b602398
AP
3449 [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl, write_hvictl },
3450 [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, write_hviprio1 },
3451 [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, write_hviprio2 },
3452
d1ceff40
AP
3453 /*
3454 * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
3455 */
3456 [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL, rmw_xiselect },
3457 [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
3458
c7de92b4
AP
3459 /* VS-Level Interrupts (H-extension with AIA) */
3460 [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi },
3461
ac4b0302
AP
3462 /* VS-Level IMSIC Interface (H-extension with AIA) */
3463 [CSR_VSSETEIPNUM] = { "vsseteipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3464 [CSR_VSCLREIPNUM] = { "vsclreipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3465 [CSR_VSSETEIENUM] = { "vsseteienum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3466 [CSR_VSCLREIENUM] = { "vsclreienum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3467 [CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei },
3468
d028ac75
AP
3469 /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
3470 [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh },
d0237b4d 3471 [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero, write_ignore },
d028ac75 3472 [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph },
2b602398
AP
3473 [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h, write_hviprio1h },
3474 [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h, write_hviprio2h },
d028ac75
AP
3475 [CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh },
3476 [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph },
3477
c7b95171 3478 /* Physical Memory Protection */
a4b2fa43
AP
3479 [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg,
3480 .min_priv_ver = PRIV_VERSION_1_12_0 },
8ceac5dc
BM
3481 [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
3482 [CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
3483 [CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
3484 [CSR_PMPCFG3] = { "pmpcfg3", pmp, read_pmpcfg, write_pmpcfg },
3485 [CSR_PMPADDR0] = { "pmpaddr0", pmp, read_pmpaddr, write_pmpaddr },
3486 [CSR_PMPADDR1] = { "pmpaddr1", pmp, read_pmpaddr, write_pmpaddr },
3487 [CSR_PMPADDR2] = { "pmpaddr2", pmp, read_pmpaddr, write_pmpaddr },
3488 [CSR_PMPADDR3] = { "pmpaddr3", pmp, read_pmpaddr, write_pmpaddr },
3489 [CSR_PMPADDR4] = { "pmpaddr4", pmp, read_pmpaddr, write_pmpaddr },
3490 [CSR_PMPADDR5] = { "pmpaddr5", pmp, read_pmpaddr, write_pmpaddr },
3491 [CSR_PMPADDR6] = { "pmpaddr6", pmp, read_pmpaddr, write_pmpaddr },
3492 [CSR_PMPADDR7] = { "pmpaddr7", pmp, read_pmpaddr, write_pmpaddr },
3493 [CSR_PMPADDR8] = { "pmpaddr8", pmp, read_pmpaddr, write_pmpaddr },
3494 [CSR_PMPADDR9] = { "pmpaddr9", pmp, read_pmpaddr, write_pmpaddr },
3495 [CSR_PMPADDR10] = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
3496 [CSR_PMPADDR11] = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
3497 [CSR_PMPADDR12] = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
3498 [CSR_PMPADDR13] = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
3499 [CSR_PMPADDR14] = { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
3500 [CSR_PMPADDR15] = { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
c7b95171 3501
b6092544
BM
3502 /* Debug CSRs */
3503 [CSR_TSELECT] = { "tselect", debug, read_tselect, write_tselect },
3504 [CSR_TDATA1] = { "tdata1", debug, read_tdata, write_tdata },
3505 [CSR_TDATA2] = { "tdata2", debug, read_tdata, write_tdata },
3506 [CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata },
3507
4bbe8033
AB
3508 /* User Pointer Masking */
3509 [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
3510 [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask, write_upmmask },
3511 [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase, write_upmbase },
3512 /* Machine Pointer Masking */
3513 [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
3514 [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask, write_mpmmask },
3515 [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase, write_mpmbase },
3516 /* Supervisor Pointer Masking */
3517 [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
3518 [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask, write_spmmask },
3519 [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase, write_spmbase },
3520
c7b95171 3521 /* Performance Counters */
8ceac5dc
BM
3522 [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_zero },
3523 [CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_zero },
3524 [CSR_HPMCOUNTER5] = { "hpmcounter5", ctr, read_zero },
3525 [CSR_HPMCOUNTER6] = { "hpmcounter6", ctr, read_zero },
3526 [CSR_HPMCOUNTER7] = { "hpmcounter7", ctr, read_zero },
3527 [CSR_HPMCOUNTER8] = { "hpmcounter8", ctr, read_zero },
3528 [CSR_HPMCOUNTER9] = { "hpmcounter9", ctr, read_zero },
3529 [CSR_HPMCOUNTER10] = { "hpmcounter10", ctr, read_zero },
3530 [CSR_HPMCOUNTER11] = { "hpmcounter11", ctr, read_zero },
3531 [CSR_HPMCOUNTER12] = { "hpmcounter12", ctr, read_zero },
3532 [CSR_HPMCOUNTER13] = { "hpmcounter13", ctr, read_zero },
3533 [CSR_HPMCOUNTER14] = { "hpmcounter14", ctr, read_zero },
3534 [CSR_HPMCOUNTER15] = { "hpmcounter15", ctr, read_zero },
3535 [CSR_HPMCOUNTER16] = { "hpmcounter16", ctr, read_zero },
3536 [CSR_HPMCOUNTER17] = { "hpmcounter17", ctr, read_zero },
3537 [CSR_HPMCOUNTER18] = { "hpmcounter18", ctr, read_zero },
3538 [CSR_HPMCOUNTER19] = { "hpmcounter19", ctr, read_zero },
3539 [CSR_HPMCOUNTER20] = { "hpmcounter20", ctr, read_zero },
3540 [CSR_HPMCOUNTER21] = { "hpmcounter21", ctr, read_zero },
3541 [CSR_HPMCOUNTER22] = { "hpmcounter22", ctr, read_zero },
3542 [CSR_HPMCOUNTER23] = { "hpmcounter23", ctr, read_zero },
3543 [CSR_HPMCOUNTER24] = { "hpmcounter24", ctr, read_zero },
3544 [CSR_HPMCOUNTER25] = { "hpmcounter25", ctr, read_zero },
3545 [CSR_HPMCOUNTER26] = { "hpmcounter26", ctr, read_zero },
3546 [CSR_HPMCOUNTER27] = { "hpmcounter27", ctr, read_zero },
3547 [CSR_HPMCOUNTER28] = { "hpmcounter28", ctr, read_zero },
3548 [CSR_HPMCOUNTER29] = { "hpmcounter29", ctr, read_zero },
3549 [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_zero },
3550 [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_zero },
3551
3552 [CSR_MHPMCOUNTER3] = { "mhpmcounter3", any, read_zero },
3553 [CSR_MHPMCOUNTER4] = { "mhpmcounter4", any, read_zero },
3554 [CSR_MHPMCOUNTER5] = { "mhpmcounter5", any, read_zero },
3555 [CSR_MHPMCOUNTER6] = { "mhpmcounter6", any, read_zero },
3556 [CSR_MHPMCOUNTER7] = { "mhpmcounter7", any, read_zero },
3557 [CSR_MHPMCOUNTER8] = { "mhpmcounter8", any, read_zero },
3558 [CSR_MHPMCOUNTER9] = { "mhpmcounter9", any, read_zero },
3559 [CSR_MHPMCOUNTER10] = { "mhpmcounter10", any, read_zero },
3560 [CSR_MHPMCOUNTER11] = { "mhpmcounter11", any, read_zero },
3561 [CSR_MHPMCOUNTER12] = { "mhpmcounter12", any, read_zero },
3562 [CSR_MHPMCOUNTER13] = { "mhpmcounter13", any, read_zero },
3563 [CSR_MHPMCOUNTER14] = { "mhpmcounter14", any, read_zero },
3564 [CSR_MHPMCOUNTER15] = { "mhpmcounter15", any, read_zero },
3565 [CSR_MHPMCOUNTER16] = { "mhpmcounter16", any, read_zero },
3566 [CSR_MHPMCOUNTER17] = { "mhpmcounter17", any, read_zero },
3567 [CSR_MHPMCOUNTER18] = { "mhpmcounter18", any, read_zero },
3568 [CSR_MHPMCOUNTER19] = { "mhpmcounter19", any, read_zero },
3569 [CSR_MHPMCOUNTER20] = { "mhpmcounter20", any, read_zero },
3570 [CSR_MHPMCOUNTER21] = { "mhpmcounter21", any, read_zero },
3571 [CSR_MHPMCOUNTER22] = { "mhpmcounter22", any, read_zero },
3572 [CSR_MHPMCOUNTER23] = { "mhpmcounter23", any, read_zero },
3573 [CSR_MHPMCOUNTER24] = { "mhpmcounter24", any, read_zero },
3574 [CSR_MHPMCOUNTER25] = { "mhpmcounter25", any, read_zero },
3575 [CSR_MHPMCOUNTER26] = { "mhpmcounter26", any, read_zero },
3576 [CSR_MHPMCOUNTER27] = { "mhpmcounter27", any, read_zero },
3577 [CSR_MHPMCOUNTER28] = { "mhpmcounter28", any, read_zero },
3578 [CSR_MHPMCOUNTER29] = { "mhpmcounter29", any, read_zero },
3579 [CSR_MHPMCOUNTER30] = { "mhpmcounter30", any, read_zero },
3580 [CSR_MHPMCOUNTER31] = { "mhpmcounter31", any, read_zero },
3581
3582 [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_zero },
3583 [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_zero },
3584 [CSR_MHPMEVENT5] = { "mhpmevent5", any, read_zero },
3585 [CSR_MHPMEVENT6] = { "mhpmevent6", any, read_zero },
3586 [CSR_MHPMEVENT7] = { "mhpmevent7", any, read_zero },
3587 [CSR_MHPMEVENT8] = { "mhpmevent8", any, read_zero },
3588 [CSR_MHPMEVENT9] = { "mhpmevent9", any, read_zero },
3589 [CSR_MHPMEVENT10] = { "mhpmevent10", any, read_zero },
3590 [CSR_MHPMEVENT11] = { "mhpmevent11", any, read_zero },
3591 [CSR_MHPMEVENT12] = { "mhpmevent12", any, read_zero },
3592 [CSR_MHPMEVENT13] = { "mhpmevent13", any, read_zero },
3593 [CSR_MHPMEVENT14] = { "mhpmevent14", any, read_zero },
3594 [CSR_MHPMEVENT15] = { "mhpmevent15", any, read_zero },
3595 [CSR_MHPMEVENT16] = { "mhpmevent16", any, read_zero },
3596 [CSR_MHPMEVENT17] = { "mhpmevent17", any, read_zero },
3597 [CSR_MHPMEVENT18] = { "mhpmevent18", any, read_zero },
3598 [CSR_MHPMEVENT19] = { "mhpmevent19", any, read_zero },
3599 [CSR_MHPMEVENT20] = { "mhpmevent20", any, read_zero },
3600 [CSR_MHPMEVENT21] = { "mhpmevent21", any, read_zero },
3601 [CSR_MHPMEVENT22] = { "mhpmevent22", any, read_zero },
3602 [CSR_MHPMEVENT23] = { "mhpmevent23", any, read_zero },
3603 [CSR_MHPMEVENT24] = { "mhpmevent24", any, read_zero },
3604 [CSR_MHPMEVENT25] = { "mhpmevent25", any, read_zero },
3605 [CSR_MHPMEVENT26] = { "mhpmevent26", any, read_zero },
3606 [CSR_MHPMEVENT27] = { "mhpmevent27", any, read_zero },
3607 [CSR_MHPMEVENT28] = { "mhpmevent28", any, read_zero },
3608 [CSR_MHPMEVENT29] = { "mhpmevent29", any, read_zero },
3609 [CSR_MHPMEVENT30] = { "mhpmevent30", any, read_zero },
3610 [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_zero },
3611
3612 [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_zero },
3613 [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_zero },
3614 [CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_zero },
3615 [CSR_HPMCOUNTER6H] = { "hpmcounter6h", ctr32, read_zero },
3616 [CSR_HPMCOUNTER7H] = { "hpmcounter7h", ctr32, read_zero },
3617 [CSR_HPMCOUNTER8H] = { "hpmcounter8h", ctr32, read_zero },
3618 [CSR_HPMCOUNTER9H] = { "hpmcounter9h", ctr32, read_zero },
3619 [CSR_HPMCOUNTER10H] = { "hpmcounter10h", ctr32, read_zero },
3620 [CSR_HPMCOUNTER11H] = { "hpmcounter11h", ctr32, read_zero },
3621 [CSR_HPMCOUNTER12H] = { "hpmcounter12h", ctr32, read_zero },
3622 [CSR_HPMCOUNTER13H] = { "hpmcounter13h", ctr32, read_zero },
3623 [CSR_HPMCOUNTER14H] = { "hpmcounter14h", ctr32, read_zero },
3624 [CSR_HPMCOUNTER15H] = { "hpmcounter15h", ctr32, read_zero },
3625 [CSR_HPMCOUNTER16H] = { "hpmcounter16h", ctr32, read_zero },
3626 [CSR_HPMCOUNTER17H] = { "hpmcounter17h", ctr32, read_zero },
3627 [CSR_HPMCOUNTER18H] = { "hpmcounter18h", ctr32, read_zero },
3628 [CSR_HPMCOUNTER19H] = { "hpmcounter19h", ctr32, read_zero },
3629 [CSR_HPMCOUNTER20H] = { "hpmcounter20h", ctr32, read_zero },
3630 [CSR_HPMCOUNTER21H] = { "hpmcounter21h", ctr32, read_zero },
3631 [CSR_HPMCOUNTER22H] = { "hpmcounter22h", ctr32, read_zero },
3632 [CSR_HPMCOUNTER23H] = { "hpmcounter23h", ctr32, read_zero },
3633 [CSR_HPMCOUNTER24H] = { "hpmcounter24h", ctr32, read_zero },
3634 [CSR_HPMCOUNTER25H] = { "hpmcounter25h", ctr32, read_zero },
3635 [CSR_HPMCOUNTER26H] = { "hpmcounter26h", ctr32, read_zero },
3636 [CSR_HPMCOUNTER27H] = { "hpmcounter27h", ctr32, read_zero },
3637 [CSR_HPMCOUNTER28H] = { "hpmcounter28h", ctr32, read_zero },
3638 [CSR_HPMCOUNTER29H] = { "hpmcounter29h", ctr32, read_zero },
3639 [CSR_HPMCOUNTER30H] = { "hpmcounter30h", ctr32, read_zero },
3640 [CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_zero },
3641
3642 [CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", any32, read_zero },
3643 [CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", any32, read_zero },
3644 [CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", any32, read_zero },
3645 [CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", any32, read_zero },
3646 [CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", any32, read_zero },
3647 [CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", any32, read_zero },
3648 [CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", any32, read_zero },
3649 [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32, read_zero },
3650 [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32, read_zero },
3651 [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32, read_zero },
3652 [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32, read_zero },
3653 [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32, read_zero },
3654 [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32, read_zero },
3655 [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32, read_zero },
3656 [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32, read_zero },
3657 [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32, read_zero },
3658 [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32, read_zero },
3659 [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32, read_zero },
3660 [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32, read_zero },
3661 [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32, read_zero },
3662 [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32, read_zero },
3663 [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32, read_zero },
3664 [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32, read_zero },
3665 [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32, read_zero },
3666 [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32, read_zero },
3667 [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32, read_zero },
3668 [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32, read_zero },
3669 [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32, read_zero },
3670 [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32, read_zero },
c7b95171
MC
3671#endif /* !CONFIG_USER_ONLY */
3672};