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