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