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