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