xref: /openbmc/qemu/target/riscv/cpu.h (revision 29a9ec9b)
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 
31 #define TCG_GUEST_DEFAULT_MO 0
32 
33 #define TYPE_RISCV_CPU "riscv-cpu"
34 
35 #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
36 #define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
37 #define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
38 
39 #define TYPE_RISCV_CPU_ANY              RISCV_CPU_TYPE_NAME("any")
40 #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
41 #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
42 #define TYPE_RISCV_CPU_BASE128          RISCV_CPU_TYPE_NAME("x-rv128")
43 #define TYPE_RISCV_CPU_IBEX             RISCV_CPU_TYPE_NAME("lowrisc-ibex")
44 #define TYPE_RISCV_CPU_SHAKTI_C         RISCV_CPU_TYPE_NAME("shakti-c")
45 #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
46 #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")
47 #define TYPE_RISCV_CPU_SIFIVE_E51       RISCV_CPU_TYPE_NAME("sifive-e51")
48 #define TYPE_RISCV_CPU_SIFIVE_U34       RISCV_CPU_TYPE_NAME("sifive-u34")
49 #define TYPE_RISCV_CPU_SIFIVE_U54       RISCV_CPU_TYPE_NAME("sifive-u54")
50 #define TYPE_RISCV_CPU_HOST             RISCV_CPU_TYPE_NAME("host")
51 
52 #if defined(TARGET_RISCV32)
53 # define TYPE_RISCV_CPU_BASE            TYPE_RISCV_CPU_BASE32
54 #elif defined(TARGET_RISCV64)
55 # define TYPE_RISCV_CPU_BASE            TYPE_RISCV_CPU_BASE64
56 #endif
57 
58 #define RV(x) ((target_ulong)1 << (x - 'A'))
59 
60 #define RVI RV('I')
61 #define RVE RV('E') /* E and I are mutually exclusive */
62 #define RVM RV('M')
63 #define RVA RV('A')
64 #define RVF RV('F')
65 #define RVD RV('D')
66 #define RVV RV('V')
67 #define RVC RV('C')
68 #define RVS RV('S')
69 #define RVU RV('U')
70 #define RVH RV('H')
71 #define RVJ RV('J')
72 
73 /* S extension denotes that Supervisor mode exists, however it is possible
74    to have a core that support S mode but does not have an MMU and there
75    is currently no bit in misa to indicate whether an MMU exists or not
76    so a cpu features bitfield is required, likewise for optional PMP support */
77 enum {
78     RISCV_FEATURE_MMU,
79     RISCV_FEATURE_PMP,
80     RISCV_FEATURE_EPMP,
81     RISCV_FEATURE_MISA,
82     RISCV_FEATURE_AIA
83 };
84 
85 /* Privileged specification version */
86 enum {
87     PRIV_VERSION_1_10_0 = 0,
88     PRIV_VERSION_1_11_0,
89     PRIV_VERSION_1_12_0,
90 };
91 
92 #define VEXT_VERSION_1_00_0 0x00010000
93 
94 enum {
95     TRANSLATE_SUCCESS,
96     TRANSLATE_FAIL,
97     TRANSLATE_PMP_FAIL,
98     TRANSLATE_G_STAGE_FAIL
99 };
100 
101 #define MMU_USER_IDX 3
102 
103 #define MAX_RISCV_PMPS (16)
104 
105 typedef struct CPUArchState CPURISCVState;
106 
107 #if !defined(CONFIG_USER_ONLY)
108 #include "pmp.h"
109 #endif
110 
111 #define RV_VLEN_MAX 1024
112 
113 FIELD(VTYPE, VLMUL, 0, 3)
114 FIELD(VTYPE, VSEW, 3, 3)
115 FIELD(VTYPE, VTA, 6, 1)
116 FIELD(VTYPE, VMA, 7, 1)
117 FIELD(VTYPE, VEDIV, 8, 2)
118 FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
119 
120 struct CPUArchState {
121     target_ulong gpr[32];
122     target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
123     uint64_t fpr[32]; /* assume both F and D extensions */
124 
125     /* vector coprocessor state. */
126     uint64_t vreg[32 * RV_VLEN_MAX / 64] QEMU_ALIGNED(16);
127     target_ulong vxrm;
128     target_ulong vxsat;
129     target_ulong vl;
130     target_ulong vstart;
131     target_ulong vtype;
132     bool vill;
133 
134     target_ulong pc;
135     target_ulong load_res;
136     target_ulong load_val;
137 
138     target_ulong frm;
139 
140     target_ulong badaddr;
141     uint32_t bins;
142 
143     target_ulong guest_phys_fault_addr;
144 
145     target_ulong priv_ver;
146     target_ulong bext_ver;
147     target_ulong vext_ver;
148 
149     /* RISCVMXL, but uint32_t for vmstate migration */
150     uint32_t misa_mxl;      /* current mxl */
151     uint32_t misa_mxl_max;  /* max mxl for this cpu */
152     uint32_t misa_ext;      /* current extensions */
153     uint32_t misa_ext_mask; /* max ext for this cpu */
154     uint32_t xl;            /* current xlen */
155 
156     /* 128-bit helpers upper part return value */
157     target_ulong retxh;
158 
159     uint32_t features;
160 
161 #ifdef CONFIG_USER_ONLY
162     uint32_t elf_flags;
163 #endif
164 
165 #ifndef CONFIG_USER_ONLY
166     target_ulong priv;
167     /* This contains QEMU specific information about the virt state. */
168     target_ulong virt;
169     target_ulong geilen;
170     target_ulong resetvec;
171 
172     target_ulong mhartid;
173     /*
174      * For RV32 this is 32-bit mstatus and 32-bit mstatush.
175      * For RV64 this is a 64-bit mstatus.
176      */
177     uint64_t mstatus;
178 
179     uint64_t mip;
180 
181     uint64_t miclaim;
182 
183     uint64_t mie;
184     uint64_t mideleg;
185 
186     target_ulong satp;   /* since: priv-1.10.0 */
187     target_ulong stval;
188     target_ulong medeleg;
189 
190     target_ulong stvec;
191     target_ulong sepc;
192     target_ulong scause;
193 
194     target_ulong mtvec;
195     target_ulong mepc;
196     target_ulong mcause;
197     target_ulong mtval;  /* since: priv-1.10.0 */
198 
199     /* Machine and Supervisor interrupt priorities */
200     uint8_t miprio[64];
201     uint8_t siprio[64];
202 
203     /* AIA CSRs */
204     target_ulong miselect;
205     target_ulong siselect;
206 
207     /* Hypervisor CSRs */
208     target_ulong hstatus;
209     target_ulong hedeleg;
210     uint64_t hideleg;
211     target_ulong hcounteren;
212     target_ulong htval;
213     target_ulong htinst;
214     target_ulong hgatp;
215     target_ulong hgeie;
216     target_ulong hgeip;
217     uint64_t htimedelta;
218 
219     /* Hypervisor controlled virtual interrupt priorities */
220     target_ulong hvictl;
221     uint8_t hviprio[64];
222 
223     /* Upper 64-bits of 128-bit CSRs */
224     uint64_t mscratchh;
225     uint64_t sscratchh;
226 
227     /* Virtual CSRs */
228     /*
229      * For RV32 this is 32-bit vsstatus and 32-bit vsstatush.
230      * For RV64 this is a 64-bit vsstatus.
231      */
232     uint64_t vsstatus;
233     target_ulong vstvec;
234     target_ulong vsscratch;
235     target_ulong vsepc;
236     target_ulong vscause;
237     target_ulong vstval;
238     target_ulong vsatp;
239 
240     /* AIA VS-mode CSRs */
241     target_ulong vsiselect;
242 
243     target_ulong mtval2;
244     target_ulong mtinst;
245 
246     /* HS Backup CSRs */
247     target_ulong stvec_hs;
248     target_ulong sscratch_hs;
249     target_ulong sepc_hs;
250     target_ulong scause_hs;
251     target_ulong stval_hs;
252     target_ulong satp_hs;
253     uint64_t mstatus_hs;
254 
255     /* Signals whether the current exception occurred with two-stage address
256        translation active. */
257     bool two_stage_lookup;
258 
259     target_ulong scounteren;
260     target_ulong mcounteren;
261 
262     target_ulong sscratch;
263     target_ulong mscratch;
264 
265     /* temporary htif regs */
266     uint64_t mfromhost;
267     uint64_t mtohost;
268     uint64_t timecmp;
269 
270     /* physical memory protection */
271     pmp_table_t pmp_state;
272     target_ulong mseccfg;
273 
274     /* machine specific rdtime callback */
275     uint64_t (*rdtime_fn)(uint32_t);
276     uint32_t rdtime_fn_arg;
277 
278     /* machine specific AIA ireg read-modify-write callback */
279 #define AIA_MAKE_IREG(__isel, __priv, __virt, __vgein, __xlen) \
280     ((((__xlen) & 0xff) << 24) | \
281      (((__vgein) & 0x3f) << 20) | \
282      (((__virt) & 0x1) << 18) | \
283      (((__priv) & 0x3) << 16) | \
284      (__isel & 0xffff))
285 #define AIA_IREG_ISEL(__ireg)                  ((__ireg) & 0xffff)
286 #define AIA_IREG_PRIV(__ireg)                  (((__ireg) >> 16) & 0x3)
287 #define AIA_IREG_VIRT(__ireg)                  (((__ireg) >> 18) & 0x1)
288 #define AIA_IREG_VGEIN(__ireg)                 (((__ireg) >> 20) & 0x3f)
289 #define AIA_IREG_XLEN(__ireg)                  (((__ireg) >> 24) & 0xff)
290     int (*aia_ireg_rmw_fn[4])(void *arg, target_ulong reg,
291         target_ulong *val, target_ulong new_val, target_ulong write_mask);
292     void *aia_ireg_rmw_fn_arg[4];
293 
294     /* True if in debugger mode.  */
295     bool debugger;
296 
297     /*
298      * CSRs for PointerMasking extension
299      */
300     target_ulong mmte;
301     target_ulong mpmmask;
302     target_ulong mpmbase;
303     target_ulong spmmask;
304     target_ulong spmbase;
305     target_ulong upmmask;
306     target_ulong upmbase;
307 
308     /* CSRs for execution enviornment configuration */
309     uint64_t menvcfg;
310     target_ulong senvcfg;
311     uint64_t henvcfg;
312 #endif
313     target_ulong cur_pmmask;
314     target_ulong cur_pmbase;
315 
316     float_status fp_status;
317 
318     /* Fields from here on are preserved across CPU reset. */
319     QEMUTimer *timer; /* Internal timer */
320 
321     hwaddr kernel_addr;
322     hwaddr fdt_addr;
323 
324     /* kvm timer */
325     bool kvm_timer_dirty;
326     uint64_t kvm_timer_time;
327     uint64_t kvm_timer_compare;
328     uint64_t kvm_timer_state;
329     uint64_t kvm_timer_frequency;
330 };
331 
332 OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
333 
334 /**
335  * RISCVCPUClass:
336  * @parent_realize: The parent class' realize handler.
337  * @parent_reset: The parent class' reset handler.
338  *
339  * A RISCV CPU model.
340  */
341 struct RISCVCPUClass {
342     /*< private >*/
343     CPUClass parent_class;
344     /*< public >*/
345     DeviceRealize parent_realize;
346     DeviceReset parent_reset;
347 };
348 
349 struct RISCVCPUConfig {
350     bool ext_i;
351     bool ext_e;
352     bool ext_g;
353     bool ext_m;
354     bool ext_a;
355     bool ext_f;
356     bool ext_d;
357     bool ext_c;
358     bool ext_s;
359     bool ext_u;
360     bool ext_h;
361     bool ext_j;
362     bool ext_v;
363     bool ext_zba;
364     bool ext_zbb;
365     bool ext_zbc;
366     bool ext_zbs;
367     bool ext_counters;
368     bool ext_ifencei;
369     bool ext_icsr;
370     bool ext_svinval;
371     bool ext_svnapot;
372     bool ext_svpbmt;
373     bool ext_zdinx;
374     bool ext_zfh;
375     bool ext_zfhmin;
376     bool ext_zfinx;
377     bool ext_zhinx;
378     bool ext_zhinxmin;
379     bool ext_zve32f;
380     bool ext_zve64f;
381 
382     /* Vendor-specific custom extensions */
383     bool ext_XVentanaCondOps;
384 
385     char *priv_spec;
386     char *user_spec;
387     char *bext_spec;
388     char *vext_spec;
389     uint16_t vlen;
390     uint16_t elen;
391     bool mmu;
392     bool pmp;
393     bool epmp;
394     bool aia;
395     uint64_t resetvec;
396 };
397 
398 typedef struct RISCVCPUConfig RISCVCPUConfig;
399 
400 /**
401  * RISCVCPU:
402  * @env: #CPURISCVState
403  *
404  * A RISCV CPU.
405  */
406 struct ArchCPU {
407     /*< private >*/
408     CPUState parent_obj;
409     /*< public >*/
410     CPUNegativeOffsetState neg;
411     CPURISCVState env;
412 
413     char *dyn_csr_xml;
414     char *dyn_vreg_xml;
415 
416     /* Configuration Settings */
417     RISCVCPUConfig cfg;
418 };
419 
420 static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
421 {
422     return (env->misa_ext & ext) != 0;
423 }
424 
425 static inline bool riscv_feature(CPURISCVState *env, int feature)
426 {
427     return env->features & (1ULL << feature);
428 }
429 
430 static inline void riscv_set_feature(CPURISCVState *env, int feature)
431 {
432     env->features |= (1ULL << feature);
433 }
434 
435 #include "cpu_user.h"
436 
437 extern const char * const riscv_int_regnames[];
438 extern const char * const riscv_int_regnamesh[];
439 extern const char * const riscv_fpr_regnames[];
440 
441 const char *riscv_cpu_get_trap_name(target_ulong cause, bool async);
442 void riscv_cpu_do_interrupt(CPUState *cpu);
443 int riscv_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
444                                int cpuid, void *opaque);
445 int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
446                                int cpuid, void *opaque);
447 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
448 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
449 int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero);
450 uint8_t riscv_cpu_default_priority(int irq);
451 int riscv_cpu_mirq_pending(CPURISCVState *env);
452 int riscv_cpu_sirq_pending(CPURISCVState *env);
453 int riscv_cpu_vsirq_pending(CPURISCVState *env);
454 bool riscv_cpu_fp_enabled(CPURISCVState *env);
455 target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
456 void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
457 bool riscv_cpu_vector_enabled(CPURISCVState *env);
458 bool riscv_cpu_virt_enabled(CPURISCVState *env);
459 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
460 bool riscv_cpu_two_stage_lookup(int mmu_idx);
461 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
462 hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
463 G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
464                                                MMUAccessType access_type, int mmu_idx,
465                                                uintptr_t retaddr);
466 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
467                         MMUAccessType access_type, int mmu_idx,
468                         bool probe, uintptr_t retaddr);
469 void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
470                                      vaddr addr, unsigned size,
471                                      MMUAccessType access_type,
472                                      int mmu_idx, MemTxAttrs attrs,
473                                      MemTxResult response, uintptr_t retaddr);
474 char *riscv_isa_string(RISCVCPU *cpu);
475 void riscv_cpu_list(void);
476 
477 #define cpu_list riscv_cpu_list
478 #define cpu_mmu_index riscv_cpu_mmu_index
479 
480 #ifndef CONFIG_USER_ONLY
481 bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
482 void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
483 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts);
484 uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value);
485 #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
486 void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t),
487                              uint32_t arg);
488 void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
489                                    int (*rmw_fn)(void *arg,
490                                                  target_ulong reg,
491                                                  target_ulong *val,
492                                                  target_ulong new_val,
493                                                  target_ulong write_mask),
494                                    void *rmw_fn_arg);
495 #endif
496 void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
497 
498 void riscv_translate_init(void);
499 G_NORETURN void riscv_raise_exception(CPURISCVState *env,
500                                       uint32_t exception, uintptr_t pc);
501 
502 target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
503 void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
504 
505 #define TB_FLAGS_PRIV_MMU_MASK                3
506 #define TB_FLAGS_PRIV_HYP_ACCESS_MASK   (1 << 2)
507 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
508 #define TB_FLAGS_MSTATUS_VS MSTATUS_VS
509 
510 #include "exec/cpu-all.h"
511 
512 FIELD(TB_FLAGS, MEM_IDX, 0, 3)
513 FIELD(TB_FLAGS, LMUL, 3, 3)
514 FIELD(TB_FLAGS, SEW, 6, 3)
515 /* Skip MSTATUS_VS (0x600) bits */
516 FIELD(TB_FLAGS, VL_EQ_VLMAX, 11, 1)
517 FIELD(TB_FLAGS, VILL, 12, 1)
518 /* Skip MSTATUS_FS (0x6000) bits */
519 /* Is a Hypervisor instruction load/store allowed? */
520 FIELD(TB_FLAGS, HLSX, 15, 1)
521 FIELD(TB_FLAGS, MSTATUS_HS_FS, 16, 2)
522 FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2)
523 /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
524 FIELD(TB_FLAGS, XL, 20, 2)
525 /* If PointerMasking should be applied */
526 FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
527 FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
528 
529 #ifdef TARGET_RISCV32
530 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
531 #else
532 static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
533 {
534     return env->misa_mxl;
535 }
536 #endif
537 #define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env)))
538 
539 #if defined(TARGET_RISCV32)
540 #define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
541 #else
542 static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
543 {
544     RISCVMXL xl = env->misa_mxl;
545 #if !defined(CONFIG_USER_ONLY)
546     /*
547      * When emulating a 32-bit-only cpu, use RV32.
548      * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
549      * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
550      * back to RV64 for lower privs.
551      */
552     if (xl != MXL_RV32) {
553         switch (env->priv) {
554         case PRV_M:
555             break;
556         case PRV_U:
557             xl = get_field(env->mstatus, MSTATUS64_UXL);
558             break;
559         default: /* PRV_S | PRV_H */
560             xl = get_field(env->mstatus, MSTATUS64_SXL);
561             break;
562         }
563     }
564 #endif
565     return xl;
566 }
567 #endif
568 
569 static inline int riscv_cpu_xlen(CPURISCVState *env)
570 {
571     return 16 << env->xl;
572 }
573 
574 #ifdef TARGET_RISCV32
575 #define riscv_cpu_sxl(env)  ((void)(env), MXL_RV32)
576 #else
577 static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
578 {
579 #ifdef CONFIG_USER_ONLY
580     return env->misa_mxl;
581 #else
582     return get_field(env->mstatus, MSTATUS64_SXL);
583 #endif
584 }
585 #endif
586 
587 /*
588  * Encode LMUL to lmul as follows:
589  *     LMUL    vlmul    lmul
590  *      1       000       0
591  *      2       001       1
592  *      4       010       2
593  *      8       011       3
594  *      -       100       -
595  *     1/8      101      -3
596  *     1/4      110      -2
597  *     1/2      111      -1
598  *
599  * then, we can calculate VLMAX = vlen >> (vsew + 3 - lmul)
600  * e.g. vlen = 256 bits, SEW = 16, LMUL = 1/8
601  *      => VLMAX = vlen >> (1 + 3 - (-3))
602  *               = 256 >> 7
603  *               = 2
604  */
605 static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
606 {
607     uint8_t sew = FIELD_EX64(vtype, VTYPE, VSEW);
608     int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
609     return cpu->cfg.vlen >> (sew + 3 - lmul);
610 }
611 
612 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
613                           target_ulong *cs_base, uint32_t *pflags);
614 
615 void riscv_cpu_update_mask(CPURISCVState *env);
616 
617 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
618                            target_ulong *ret_value,
619                            target_ulong new_value, target_ulong write_mask);
620 RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
621                                  target_ulong *ret_value,
622                                  target_ulong new_value,
623                                  target_ulong write_mask);
624 
625 static inline void riscv_csr_write(CPURISCVState *env, int csrno,
626                                    target_ulong val)
627 {
628     riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
629 }
630 
631 static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
632 {
633     target_ulong val = 0;
634     riscv_csrrw(env, csrno, &val, 0, 0);
635     return val;
636 }
637 
638 typedef RISCVException (*riscv_csr_predicate_fn)(CPURISCVState *env,
639                                                  int csrno);
640 typedef RISCVException (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
641                                             target_ulong *ret_value);
642 typedef RISCVException (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
643                                              target_ulong new_value);
644 typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
645                                           target_ulong *ret_value,
646                                           target_ulong new_value,
647                                           target_ulong write_mask);
648 
649 RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
650                                 Int128 *ret_value,
651                                 Int128 new_value, Int128 write_mask);
652 
653 typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
654                                                Int128 *ret_value);
655 typedef RISCVException (*riscv_csr_write128_fn)(CPURISCVState *env, int csrno,
656                                              Int128 new_value);
657 
658 typedef struct {
659     const char *name;
660     riscv_csr_predicate_fn predicate;
661     riscv_csr_read_fn read;
662     riscv_csr_write_fn write;
663     riscv_csr_op_fn op;
664     riscv_csr_read128_fn read128;
665     riscv_csr_write128_fn write128;
666     /* The default priv spec version should be PRIV_VERSION_1_10_0 (i.e 0) */
667     uint32_t min_priv_ver;
668 } riscv_csr_operations;
669 
670 /* CSR function table constants */
671 enum {
672     CSR_TABLE_SIZE = 0x1000
673 };
674 
675 /* CSR function table */
676 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
677 
678 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
679 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
680 
681 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
682 
683 #endif /* RISCV_CPU_H */
684