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