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