1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 "fpu/softfloat-types.h"
27#include "qom/object.h"
28
29#define TCG_GUEST_DEFAULT_MO 0
30
31#define TYPE_RISCV_CPU "riscv-cpu"
32
33#define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
34#define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
35#define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
36
37#define TYPE_RISCV_CPU_ANY RISCV_CPU_TYPE_NAME("any")
38#define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
39#define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
40#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
41#define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
42#define TYPE_RISCV_CPU_SIFIVE_E34 RISCV_CPU_TYPE_NAME("sifive-e34")
43#define TYPE_RISCV_CPU_SIFIVE_E51 RISCV_CPU_TYPE_NAME("sifive-e51")
44#define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34")
45#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
46
47#if defined(TARGET_RISCV32)
48# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE32
49#elif defined(TARGET_RISCV64)
50# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE64
51#endif
52
53#define RV32 ((target_ulong)1 << (TARGET_LONG_BITS - 2))
54#define RV64 ((target_ulong)2 << (TARGET_LONG_BITS - 2))
55
56#if defined(TARGET_RISCV32)
57#define RVXLEN RV32
58#elif defined(TARGET_RISCV64)
59#define RVXLEN RV64
60#endif
61
62#define RV(x) ((target_ulong)1 << (x - 'A'))
63
64#define RVI RV('I')
65#define RVE RV('E')
66#define RVM RV('M')
67#define RVA RV('A')
68#define RVF RV('F')
69#define RVD RV('D')
70#define RVV RV('V')
71#define RVC RV('C')
72#define RVS RV('S')
73#define RVU RV('U')
74#define RVH RV('H')
75
76
77
78
79
80enum {
81 RISCV_FEATURE_MMU,
82 RISCV_FEATURE_PMP,
83 RISCV_FEATURE_MISA
84};
85
86#define PRIV_VERSION_1_10_0 0x00011000
87#define PRIV_VERSION_1_11_0 0x00011100
88
89#define VEXT_VERSION_0_07_1 0x00000701
90
91enum {
92 TRANSLATE_SUCCESS,
93 TRANSLATE_FAIL,
94 TRANSLATE_PMP_FAIL,
95 TRANSLATE_G_STAGE_FAIL
96};
97
98#define MMU_USER_IDX 3
99
100#define MAX_RISCV_PMPS (16)
101
102typedef struct CPURISCVState CPURISCVState;
103
104#include "pmp.h"
105
106#define RV_VLEN_MAX 256
107
108FIELD(VTYPE, VLMUL, 0, 2)
109FIELD(VTYPE, VSEW, 2, 3)
110FIELD(VTYPE, VEDIV, 5, 2)
111FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
112FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
113
114struct CPURISCVState {
115 target_ulong gpr[32];
116 uint64_t fpr[32];
117
118
119 uint64_t vreg[32 * RV_VLEN_MAX / 64] QEMU_ALIGNED(16);
120 target_ulong vxrm;
121 target_ulong vxsat;
122 target_ulong vl;
123 target_ulong vstart;
124 target_ulong vtype;
125
126 target_ulong pc;
127 target_ulong load_res;
128 target_ulong load_val;
129
130 target_ulong frm;
131
132 target_ulong badaddr;
133 target_ulong guest_phys_fault_addr;
134
135 target_ulong priv_ver;
136 target_ulong vext_ver;
137 target_ulong misa;
138 target_ulong misa_mask;
139
140 uint32_t features;
141
142#ifdef CONFIG_USER_ONLY
143 uint32_t elf_flags;
144#endif
145
146#ifndef CONFIG_USER_ONLY
147 target_ulong priv;
148
149 target_ulong virt;
150 target_ulong resetvec;
151
152 target_ulong mhartid;
153
154
155
156
157 uint64_t mstatus;
158
159 target_ulong mip;
160
161 uint32_t miclaim;
162
163 target_ulong mie;
164 target_ulong mideleg;
165
166 target_ulong sptbr;
167 target_ulong satp;
168 target_ulong sbadaddr;
169 target_ulong mbadaddr;
170 target_ulong medeleg;
171
172 target_ulong stvec;
173 target_ulong sepc;
174 target_ulong scause;
175
176 target_ulong mtvec;
177 target_ulong mepc;
178 target_ulong mcause;
179 target_ulong mtval;
180
181
182 target_ulong hstatus;
183 target_ulong hedeleg;
184 target_ulong hideleg;
185 target_ulong hcounteren;
186 target_ulong htval;
187 target_ulong htinst;
188 target_ulong hgatp;
189 uint64_t htimedelta;
190
191
192
193
194
195
196 uint64_t vsstatus;
197 target_ulong vstvec;
198 target_ulong vsscratch;
199 target_ulong vsepc;
200 target_ulong vscause;
201 target_ulong vstval;
202 target_ulong vsatp;
203
204 target_ulong mtval2;
205 target_ulong mtinst;
206
207
208 target_ulong stvec_hs;
209 target_ulong sscratch_hs;
210 target_ulong sepc_hs;
211 target_ulong scause_hs;
212 target_ulong stval_hs;
213 target_ulong satp_hs;
214 uint64_t mstatus_hs;
215
216
217
218 bool two_stage_lookup;
219
220 target_ulong scounteren;
221 target_ulong mcounteren;
222
223 target_ulong sscratch;
224 target_ulong mscratch;
225
226
227 uint64_t mfromhost;
228 uint64_t mtohost;
229 uint64_t timecmp;
230
231
232 pmp_table_t pmp_state;
233
234
235 uint64_t (*rdtime_fn)(uint32_t);
236 uint32_t rdtime_fn_arg;
237
238
239 bool debugger;
240#endif
241
242 float_status fp_status;
243
244
245 QEMUTimer *timer;
246};
247
248OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
249 RISCV_CPU)
250
251
252
253
254
255
256
257
258struct RISCVCPUClass {
259
260 CPUClass parent_class;
261
262 DeviceRealize parent_realize;
263 DeviceReset parent_reset;
264};
265
266
267
268
269
270
271
272struct RISCVCPU {
273
274 CPUState parent_obj;
275
276 CPUNegativeOffsetState neg;
277 CPURISCVState env;
278
279 char *dyn_csr_xml;
280
281
282 struct {
283 bool ext_i;
284 bool ext_e;
285 bool ext_g;
286 bool ext_m;
287 bool ext_a;
288 bool ext_f;
289 bool ext_d;
290 bool ext_c;
291 bool ext_s;
292 bool ext_u;
293 bool ext_h;
294 bool ext_v;
295 bool ext_counters;
296 bool ext_ifencei;
297 bool ext_icsr;
298
299 char *priv_spec;
300 char *user_spec;
301 char *vext_spec;
302 uint16_t vlen;
303 uint16_t elen;
304 bool mmu;
305 bool pmp;
306 uint64_t resetvec;
307 } cfg;
308};
309
310static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
311{
312 return (env->misa & ext) != 0;
313}
314
315static inline bool riscv_feature(CPURISCVState *env, int feature)
316{
317 return env->features & (1ULL << feature);
318}
319
320#include "cpu_user.h"
321#include "cpu_bits.h"
322
323extern const char * const riscv_int_regnames[];
324extern const char * const riscv_fpr_regnames[];
325extern const char * const riscv_excp_names[];
326extern const char * const riscv_intr_names[];
327
328const char *riscv_cpu_get_trap_name(target_ulong cause, bool async);
329void riscv_cpu_do_interrupt(CPUState *cpu);
330int riscv_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
331 int cpuid, void *opaque);
332int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
333 int cpuid, void *opaque);
334int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
335int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
336bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
337bool riscv_cpu_fp_enabled(CPURISCVState *env);
338bool riscv_cpu_virt_enabled(CPURISCVState *env);
339void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
340bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
341void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
342bool riscv_cpu_two_stage_lookup(int mmu_idx);
343int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
344hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
345void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
346 MMUAccessType access_type, int mmu_idx,
347 uintptr_t retaddr);
348bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
349 MMUAccessType access_type, int mmu_idx,
350 bool probe, uintptr_t retaddr);
351void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
352 vaddr addr, unsigned size,
353 MMUAccessType access_type,
354 int mmu_idx, MemTxAttrs attrs,
355 MemTxResult response, uintptr_t retaddr);
356char *riscv_isa_string(RISCVCPU *cpu);
357void riscv_cpu_list(void);
358
359#define cpu_signal_handler riscv_cpu_signal_handler
360#define cpu_list riscv_cpu_list
361#define cpu_mmu_index riscv_cpu_mmu_index
362
363#ifndef CONFIG_USER_ONLY
364void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
365int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts);
366uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
367#define BOOL_TO_MASK(x) (-!!(x))
368void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t),
369 uint32_t arg);
370#endif
371void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
372
373void riscv_translate_init(void);
374int riscv_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
375void QEMU_NORETURN riscv_raise_exception(CPURISCVState *env,
376 uint32_t exception, uintptr_t pc);
377
378target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
379void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
380
381#define TB_FLAGS_MMU_MASK 7
382#define TB_FLAGS_PRIV_MMU_MASK 3
383#define TB_FLAGS_PRIV_HYP_ACCESS_MASK (1 << 2)
384#define TB_FLAGS_MSTATUS_FS MSTATUS_FS
385
386typedef CPURISCVState CPUArchState;
387typedef RISCVCPU ArchCPU;
388#include "exec/cpu-all.h"
389
390FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1)
391FIELD(TB_FLAGS, LMUL, 3, 2)
392FIELD(TB_FLAGS, SEW, 5, 3)
393FIELD(TB_FLAGS, VILL, 8, 1)
394
395FIELD(TB_FLAGS, HLSX, 9, 1)
396
397bool riscv_cpu_is_32bit(CPURISCVState *env);
398
399
400
401
402
403
404
405
406static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
407{
408 uint8_t sew, lmul;
409
410 sew = FIELD_EX64(vtype, VTYPE, VSEW);
411 lmul = FIELD_EX64(vtype, VTYPE, VLMUL);
412 return cpu->cfg.vlen >> (sew + 3 - lmul);
413}
414
415static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
416 target_ulong *cs_base, uint32_t *pflags)
417{
418 uint32_t flags = 0;
419
420 *pc = env->pc;
421 *cs_base = 0;
422
423 if (riscv_has_ext(env, RVV)) {
424 uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
425 bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
426 flags = FIELD_DP32(flags, TB_FLAGS, VILL,
427 FIELD_EX64(env->vtype, VTYPE, VILL));
428 flags = FIELD_DP32(flags, TB_FLAGS, SEW,
429 FIELD_EX64(env->vtype, VTYPE, VSEW));
430 flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
431 FIELD_EX64(env->vtype, VTYPE, VLMUL));
432 flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
433 } else {
434 flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
435 }
436
437#ifdef CONFIG_USER_ONLY
438 flags |= TB_FLAGS_MSTATUS_FS;
439#else
440 flags |= cpu_mmu_index(env, 0);
441 if (riscv_cpu_fp_enabled(env)) {
442 flags |= env->mstatus & MSTATUS_FS;
443 }
444
445 if (riscv_has_ext(env, RVH)) {
446 if (env->priv == PRV_M ||
447 (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
448 (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
449 get_field(env->hstatus, HSTATUS_HU))) {
450 flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1);
451 }
452 }
453#endif
454
455 *pflags = flags;
456}
457
458int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
459 target_ulong new_value, target_ulong write_mask);
460int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
461 target_ulong new_value, target_ulong write_mask);
462
463static inline void riscv_csr_write(CPURISCVState *env, int csrno,
464 target_ulong val)
465{
466 riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
467}
468
469static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
470{
471 target_ulong val = 0;
472 riscv_csrrw(env, csrno, &val, 0, 0);
473 return val;
474}
475
476typedef int (*riscv_csr_predicate_fn)(CPURISCVState *env, int csrno);
477typedef int (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
478 target_ulong *ret_value);
479typedef int (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
480 target_ulong new_value);
481typedef int (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
482 target_ulong *ret_value, target_ulong new_value, target_ulong write_mask);
483
484typedef struct {
485 const char *name;
486 riscv_csr_predicate_fn predicate;
487 riscv_csr_read_fn read;
488 riscv_csr_write_fn write;
489 riscv_csr_op_fn op;
490} riscv_csr_operations;
491
492
493enum {
494 CSR_TABLE_SIZE = 0x1000
495};
496
497
498extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
499
500void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
501void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
502
503void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
504
505#endif
506