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