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