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