xref: /openbmc/qemu/target/riscv/cpu.h (revision 243705aa)
1 /*
2  * QEMU RISC-V CPU
3  *
4  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5  * Copyright (c) 2017-2018 SiFive, Inc.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms and conditions of the GNU General Public License,
9  * version 2 or later, as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef RISCV_CPU_H
21 #define RISCV_CPU_H
22 
23 #include "hw/core/cpu.h"
24 #include "hw/registerfields.h"
25 #include "exec/cpu-defs.h"
26 #include "qemu/cpu-float.h"
27 #include "qom/object.h"
28 #include "qemu/int128.h"
29 #include "cpu_bits.h"
30 #include "cpu_cfg.h"
31 #include "qapi/qapi-types-common.h"
32 #include "cpu-qom.h"
33 
34 #define TCG_GUEST_DEFAULT_MO 0
35 
36 /*
37  * RISC-V-specific extra insn start words:
38  * 1: Original instruction opcode
39  */
40 #define TARGET_INSN_START_EXTRA_WORDS 1
41 
42 #define RV(x) ((target_ulong)1 << (x - 'A'))
43 
44 /* Consider updating misa_ext_cfgs[] when adding new MISA bits here */
45 #define RVI RV('I')
46 #define RVE RV('E') /* E and I are mutually exclusive */
47 #define RVM RV('M')
48 #define RVA RV('A')
49 #define RVF RV('F')
50 #define RVD RV('D')
51 #define RVV RV('V')
52 #define RVC RV('C')
53 #define RVS RV('S')
54 #define RVU RV('U')
55 #define RVH RV('H')
56 #define RVJ RV('J')
57 #define RVG RV('G')
58 
59 
60 /* Privileged specification version */
61 enum {
62     PRIV_VERSION_1_10_0 = 0,
63     PRIV_VERSION_1_11_0,
64     PRIV_VERSION_1_12_0,
65 
66     PRIV_VERSION_LATEST = PRIV_VERSION_1_12_0,
67 };
68 
69 #define VEXT_VERSION_1_00_0 0x00010000
70 
71 enum {
72     TRANSLATE_SUCCESS,
73     TRANSLATE_FAIL,
74     TRANSLATE_PMP_FAIL,
75     TRANSLATE_G_STAGE_FAIL
76 };
77 
78 /* Extension context status */
79 typedef enum {
80     EXT_STATUS_DISABLED = 0,
81     EXT_STATUS_INITIAL,
82     EXT_STATUS_CLEAN,
83     EXT_STATUS_DIRTY,
84 } RISCVExtStatus;
85 
86 #define MMU_USER_IDX 3
87 
88 #define MAX_RISCV_PMPS (16)
89 
90 #if !defined(CONFIG_USER_ONLY)
91 #include "pmp.h"
92 #include "debug.h"
93 #endif
94 
95 #define RV_VLEN_MAX 1024
96 #define RV_MAX_MHPMEVENTS 32
97 #define RV_MAX_MHPMCOUNTERS 32
98 
99 FIELD(VTYPE, VLMUL, 0, 3)
100 FIELD(VTYPE, VSEW, 3, 3)
101 FIELD(VTYPE, VTA, 6, 1)
102 FIELD(VTYPE, VMA, 7, 1)
103 FIELD(VTYPE, VEDIV, 8, 2)
104 FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
105 
106 typedef struct PMUCTRState {
107     /* Current value of a counter */
108     target_ulong mhpmcounter_val;
109     /* Current value of a counter in RV32 */
110     target_ulong mhpmcounterh_val;
111     /* Snapshot values of counter */
112     target_ulong mhpmcounter_prev;
113     /* Snapshort value of a counter in RV32 */
114     target_ulong mhpmcounterh_prev;
115     bool started;
116     /* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger */
117     target_ulong irq_overflow_left;
118 } PMUCTRState;
119 
120 struct CPUArchState {
121     target_ulong gpr[32];
122     target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
123 
124     /* vector coprocessor state. */
125     uint64_t vreg[32 * RV_VLEN_MAX / 64] QEMU_ALIGNED(16);
126     target_ulong vxrm;
127     target_ulong vxsat;
128     target_ulong vl;
129     target_ulong vstart;
130     target_ulong vtype;
131     bool vill;
132 
133     target_ulong pc;
134     target_ulong load_res;
135     target_ulong load_val;
136 
137     /* Floating-Point state */
138     uint64_t fpr[32]; /* assume both F and D extensions */
139     target_ulong frm;
140     float_status fp_status;
141 
142     target_ulong badaddr;
143     target_ulong bins;
144 
145     target_ulong guest_phys_fault_addr;
146 
147     target_ulong priv_ver;
148     target_ulong bext_ver;
149     target_ulong vext_ver;
150 
151     /* RISCVMXL, but uint32_t for vmstate migration */
152     uint32_t misa_mxl;      /* current mxl */
153     uint32_t misa_mxl_max;  /* max mxl for this cpu */
154     uint32_t misa_ext;      /* current extensions */
155     uint32_t misa_ext_mask; /* max ext for this cpu */
156     uint32_t xl;            /* current xlen */
157 
158     /* 128-bit helpers upper part return value */
159     target_ulong retxh;
160 
161     target_ulong jvt;
162 
163 #ifdef CONFIG_USER_ONLY
164     uint32_t elf_flags;
165 #endif
166 
167 #ifndef CONFIG_USER_ONLY
168     target_ulong priv;
169     /* This contains QEMU specific information about the virt state. */
170     bool virt_enabled;
171     target_ulong geilen;
172     uint64_t resetvec;
173 
174     target_ulong mhartid;
175     /*
176      * For RV32 this is 32-bit mstatus and 32-bit mstatush.
177      * For RV64 this is a 64-bit mstatus.
178      */
179     uint64_t mstatus;
180 
181     uint64_t mip;
182     /*
183      * MIP contains the software writable version of SEIP ORed with the
184      * external interrupt value. The MIP register is always up-to-date.
185      * To keep track of the current source, we also save booleans of the values
186      * here.
187      */
188     bool external_seip;
189     bool software_seip;
190 
191     uint64_t miclaim;
192 
193     uint64_t mie;
194     uint64_t mideleg;
195 
196     target_ulong satp;   /* since: priv-1.10.0 */
197     target_ulong stval;
198     target_ulong medeleg;
199 
200     target_ulong stvec;
201     target_ulong sepc;
202     target_ulong scause;
203 
204     target_ulong mtvec;
205     target_ulong mepc;
206     target_ulong mcause;
207     target_ulong mtval;  /* since: priv-1.10.0 */
208 
209     /* Machine and Supervisor interrupt priorities */
210     uint8_t miprio[64];
211     uint8_t siprio[64];
212 
213     /* AIA CSRs */
214     target_ulong miselect;
215     target_ulong siselect;
216 
217     /* Hypervisor CSRs */
218     target_ulong hstatus;
219     target_ulong hedeleg;
220     uint64_t hideleg;
221     target_ulong hcounteren;
222     target_ulong htval;
223     target_ulong htinst;
224     target_ulong hgatp;
225     target_ulong hgeie;
226     target_ulong hgeip;
227     uint64_t htimedelta;
228 
229     /* Hypervisor controlled virtual interrupt priorities */
230     target_ulong hvictl;
231     uint8_t hviprio[64];
232 
233     /* Upper 64-bits of 128-bit CSRs */
234     uint64_t mscratchh;
235     uint64_t sscratchh;
236 
237     /* Virtual CSRs */
238     /*
239      * For RV32 this is 32-bit vsstatus and 32-bit vsstatush.
240      * For RV64 this is a 64-bit vsstatus.
241      */
242     uint64_t vsstatus;
243     target_ulong vstvec;
244     target_ulong vsscratch;
245     target_ulong vsepc;
246     target_ulong vscause;
247     target_ulong vstval;
248     target_ulong vsatp;
249 
250     /* AIA VS-mode CSRs */
251     target_ulong vsiselect;
252 
253     target_ulong mtval2;
254     target_ulong mtinst;
255 
256     /* HS Backup CSRs */
257     target_ulong stvec_hs;
258     target_ulong sscratch_hs;
259     target_ulong sepc_hs;
260     target_ulong scause_hs;
261     target_ulong stval_hs;
262     target_ulong satp_hs;
263     uint64_t mstatus_hs;
264 
265     /*
266      * Signals whether the current exception occurred with two-stage address
267      * translation active.
268      */
269     bool two_stage_lookup;
270     /*
271      * Signals whether the current exception occurred while doing two-stage
272      * address translation for the VS-stage page table walk.
273      */
274     bool two_stage_indirect_lookup;
275 
276     target_ulong scounteren;
277     target_ulong mcounteren;
278 
279     target_ulong mcountinhibit;
280 
281     /* PMU counter state */
282     PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
283 
284     /* PMU event selector configured values. First three are unused */
285     target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
286 
287     /* PMU event selector configured values for RV32 */
288     target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
289 
290     target_ulong sscratch;
291     target_ulong mscratch;
292 
293     /* Sstc CSRs */
294     uint64_t stimecmp;
295 
296     uint64_t vstimecmp;
297 
298     /* physical memory protection */
299     pmp_table_t pmp_state;
300     target_ulong mseccfg;
301 
302     /* trigger module */
303     target_ulong trigger_cur;
304     target_ulong tdata1[RV_MAX_TRIGGERS];
305     target_ulong tdata2[RV_MAX_TRIGGERS];
306     target_ulong tdata3[RV_MAX_TRIGGERS];
307     struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
308     struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
309     QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
310     int64_t last_icount;
311     bool itrigger_enabled;
312 
313     /* machine specific rdtime callback */
314     uint64_t (*rdtime_fn)(void *);
315     void *rdtime_fn_arg;
316 
317     /* machine specific AIA ireg read-modify-write callback */
318 #define AIA_MAKE_IREG(__isel, __priv, __virt, __vgein, __xlen) \
319     ((((__xlen) & 0xff) << 24) | \
320      (((__vgein) & 0x3f) << 20) | \
321      (((__virt) & 0x1) << 18) | \
322      (((__priv) & 0x3) << 16) | \
323      (__isel & 0xffff))
324 #define AIA_IREG_ISEL(__ireg)                  ((__ireg) & 0xffff)
325 #define AIA_IREG_PRIV(__ireg)                  (((__ireg) >> 16) & 0x3)
326 #define AIA_IREG_VIRT(__ireg)                  (((__ireg) >> 18) & 0x1)
327 #define AIA_IREG_VGEIN(__ireg)                 (((__ireg) >> 20) & 0x3f)
328 #define AIA_IREG_XLEN(__ireg)                  (((__ireg) >> 24) & 0xff)
329     int (*aia_ireg_rmw_fn[4])(void *arg, target_ulong reg,
330         target_ulong *val, target_ulong new_val, target_ulong write_mask);
331     void *aia_ireg_rmw_fn_arg[4];
332 
333     /* True if in debugger mode.  */
334     bool debugger;
335 
336     /*
337      * CSRs for PointerMasking extension
338      */
339     target_ulong mmte;
340     target_ulong mpmmask;
341     target_ulong mpmbase;
342     target_ulong spmmask;
343     target_ulong spmbase;
344     target_ulong upmmask;
345     target_ulong upmbase;
346 
347     /* CSRs for execution enviornment configuration */
348     uint64_t menvcfg;
349     uint64_t mstateen[SMSTATEEN_MAX_COUNT];
350     uint64_t hstateen[SMSTATEEN_MAX_COUNT];
351     uint64_t sstateen[SMSTATEEN_MAX_COUNT];
352     target_ulong senvcfg;
353     uint64_t henvcfg;
354 #endif
355     target_ulong cur_pmmask;
356     target_ulong cur_pmbase;
357 
358     /* Fields from here on are preserved across CPU reset. */
359     QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
360     QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
361     bool vstime_irq;
362 
363     hwaddr kernel_addr;
364     hwaddr fdt_addr;
365 
366     /* kvm timer */
367     bool kvm_timer_dirty;
368     uint64_t kvm_timer_time;
369     uint64_t kvm_timer_compare;
370     uint64_t kvm_timer_state;
371     uint64_t kvm_timer_frequency;
372 };
373 
374 /*
375  * RISCVCPU:
376  * @env: #CPURISCVState
377  *
378  * A RISCV CPU.
379  */
380 struct ArchCPU {
381     /* < private > */
382     CPUState parent_obj;
383     /* < public > */
384     CPUNegativeOffsetState neg;
385     CPURISCVState env;
386 
387     char *dyn_csr_xml;
388     char *dyn_vreg_xml;
389 
390     /* Configuration Settings */
391     RISCVCPUConfig cfg;
392 
393     QEMUTimer *pmu_timer;
394     /* A bitmask of Available programmable counters */
395     uint32_t pmu_avail_ctrs;
396     /* Mapping of events to counters */
397     GHashTable *pmu_event_ctr_map;
398 };
399 
400 static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
401 {
402     return (env->misa_ext & ext) != 0;
403 }
404 
405 #include "cpu_user.h"
406 
407 extern const char * const riscv_int_regnames[];
408 extern const char * const riscv_int_regnamesh[];
409 extern const char * const riscv_fpr_regnames[];
410 
411 const char *riscv_cpu_get_trap_name(target_ulong cause, bool async);
412 void riscv_cpu_do_interrupt(CPUState *cpu);
413 int riscv_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
414                                int cpuid, DumpState *s);
415 int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
416                                int cpuid, DumpState *s);
417 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
418 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
419 int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero);
420 uint8_t riscv_cpu_default_priority(int irq);
421 uint64_t riscv_cpu_all_pending(CPURISCVState *env);
422 int riscv_cpu_mirq_pending(CPURISCVState *env);
423 int riscv_cpu_sirq_pending(CPURISCVState *env);
424 int riscv_cpu_vsirq_pending(CPURISCVState *env);
425 bool riscv_cpu_fp_enabled(CPURISCVState *env);
426 target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
427 void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
428 bool riscv_cpu_vector_enabled(CPURISCVState *env);
429 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
430 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
431 G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
432                                                MMUAccessType access_type,
433                                                int mmu_idx, uintptr_t retaddr);
434 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
435                         MMUAccessType access_type, int mmu_idx,
436                         bool probe, uintptr_t retaddr);
437 char *riscv_isa_string(RISCVCPU *cpu);
438 void riscv_cpu_list(void);
439 void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
440 
441 #define cpu_list riscv_cpu_list
442 #define cpu_mmu_index riscv_cpu_mmu_index
443 
444 #ifndef CONFIG_USER_ONLY
445 void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
446                                      vaddr addr, unsigned size,
447                                      MMUAccessType access_type,
448                                      int mmu_idx, MemTxAttrs attrs,
449                                      MemTxResult response, uintptr_t retaddr);
450 hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
451 bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
452 void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
453 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts);
454 uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask,
455                               uint64_t value);
456 #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
457 void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
458                              void *arg);
459 void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
460                                    int (*rmw_fn)(void *arg,
461                                                  target_ulong reg,
462                                                  target_ulong *val,
463                                                  target_ulong new_val,
464                                                  target_ulong write_mask),
465                                    void *rmw_fn_arg);
466 
467 RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
468 #endif
469 void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
470 
471 void riscv_translate_init(void);
472 G_NORETURN void riscv_raise_exception(CPURISCVState *env,
473                                       uint32_t exception, uintptr_t pc);
474 
475 target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
476 void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
477 
478 #include "exec/cpu-all.h"
479 
480 FIELD(TB_FLAGS, MEM_IDX, 0, 3)
481 FIELD(TB_FLAGS, FS, 3, 2)
482 /* Vector flags */
483 FIELD(TB_FLAGS, VS, 5, 2)
484 FIELD(TB_FLAGS, LMUL, 7, 3)
485 FIELD(TB_FLAGS, SEW, 10, 3)
486 FIELD(TB_FLAGS, VL_EQ_VLMAX, 13, 1)
487 FIELD(TB_FLAGS, VILL, 14, 1)
488 FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1)
489 /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
490 FIELD(TB_FLAGS, XL, 16, 2)
491 /* If PointerMasking should be applied */
492 FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1)
493 FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1)
494 FIELD(TB_FLAGS, VTA, 20, 1)
495 FIELD(TB_FLAGS, VMA, 21, 1)
496 /* Native debug itrigger */
497 FIELD(TB_FLAGS, ITRIGGER, 22, 1)
498 /* Virtual mode enabled */
499 FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
500 FIELD(TB_FLAGS, PRIV, 24, 2)
501 
502 #ifdef TARGET_RISCV32
503 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
504 #else
505 static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
506 {
507     return env->misa_mxl;
508 }
509 #endif
510 #define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env)))
511 
512 static inline const RISCVCPUConfig *riscv_cpu_cfg(CPURISCVState *env)
513 {
514     return &env_archcpu(env)->cfg;
515 }
516 
517 #if defined(TARGET_RISCV32)
518 #define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
519 #else
520 static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
521 {
522     RISCVMXL xl = env->misa_mxl;
523 #if !defined(CONFIG_USER_ONLY)
524     /*
525      * When emulating a 32-bit-only cpu, use RV32.
526      * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
527      * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
528      * back to RV64 for lower privs.
529      */
530     if (xl != MXL_RV32) {
531         switch (env->priv) {
532         case PRV_M:
533             break;
534         case PRV_U:
535             xl = get_field(env->mstatus, MSTATUS64_UXL);
536             break;
537         default: /* PRV_S */
538             xl = get_field(env->mstatus, MSTATUS64_SXL);
539             break;
540         }
541     }
542 #endif
543     return xl;
544 }
545 #endif
546 
547 static inline int riscv_cpu_xlen(CPURISCVState *env)
548 {
549     return 16 << env->xl;
550 }
551 
552 #ifdef TARGET_RISCV32
553 #define riscv_cpu_sxl(env)  ((void)(env), MXL_RV32)
554 #else
555 static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
556 {
557 #ifdef CONFIG_USER_ONLY
558     return env->misa_mxl;
559 #else
560     return get_field(env->mstatus, MSTATUS64_SXL);
561 #endif
562 }
563 #endif
564 
565 /*
566  * Encode LMUL to lmul as follows:
567  *     LMUL    vlmul    lmul
568  *      1       000       0
569  *      2       001       1
570  *      4       010       2
571  *      8       011       3
572  *      -       100       -
573  *     1/8      101      -3
574  *     1/4      110      -2
575  *     1/2      111      -1
576  *
577  * then, we can calculate VLMAX = vlen >> (vsew + 3 - lmul)
578  * e.g. vlen = 256 bits, SEW = 16, LMUL = 1/8
579  *      => VLMAX = vlen >> (1 + 3 - (-3))
580  *               = 256 >> 7
581  *               = 2
582  */
583 static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
584 {
585     uint8_t sew = FIELD_EX64(vtype, VTYPE, VSEW);
586     int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
587     return cpu->cfg.vlen >> (sew + 3 - lmul);
588 }
589 
590 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
591                           target_ulong *cs_base, uint32_t *pflags);
592 
593 void riscv_cpu_update_mask(CPURISCVState *env);
594 
595 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
596                            target_ulong *ret_value,
597                            target_ulong new_value, target_ulong write_mask);
598 RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
599                                  target_ulong *ret_value,
600                                  target_ulong new_value,
601                                  target_ulong write_mask);
602 
603 static inline void riscv_csr_write(CPURISCVState *env, int csrno,
604                                    target_ulong val)
605 {
606     riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
607 }
608 
609 static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
610 {
611     target_ulong val = 0;
612     riscv_csrrw(env, csrno, &val, 0, 0);
613     return val;
614 }
615 
616 typedef RISCVException (*riscv_csr_predicate_fn)(CPURISCVState *env,
617                                                  int csrno);
618 typedef RISCVException (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
619                                             target_ulong *ret_value);
620 typedef RISCVException (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
621                                              target_ulong new_value);
622 typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
623                                           target_ulong *ret_value,
624                                           target_ulong new_value,
625                                           target_ulong write_mask);
626 
627 RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
628                                 Int128 *ret_value,
629                                 Int128 new_value, Int128 write_mask);
630 
631 typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
632                                                Int128 *ret_value);
633 typedef RISCVException (*riscv_csr_write128_fn)(CPURISCVState *env, int csrno,
634                                              Int128 new_value);
635 
636 typedef struct {
637     const char *name;
638     riscv_csr_predicate_fn predicate;
639     riscv_csr_read_fn read;
640     riscv_csr_write_fn write;
641     riscv_csr_op_fn op;
642     riscv_csr_read128_fn read128;
643     riscv_csr_write128_fn write128;
644     /* The default priv spec version should be PRIV_VERSION_1_10_0 (i.e 0) */
645     uint32_t min_priv_ver;
646 } riscv_csr_operations;
647 
648 /* CSR function table constants */
649 enum {
650     CSR_TABLE_SIZE = 0x1000
651 };
652 
653 /*
654  * The event id are encoded based on the encoding specified in the
655  * SBI specification v0.3
656  */
657 
658 enum riscv_pmu_event_idx {
659     RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
660     RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
661     RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
662     RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
663     RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
664 };
665 
666 /* CSR function table */
667 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
668 
669 extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
670 
671 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
672 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
673 
674 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
675 
676 uint8_t satp_mode_max_from_map(uint32_t map);
677 const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
678 
679 #endif /* RISCV_CPU_H */
680