]> git.proxmox.com Git - mirror_qemu.git/blame - target/riscv/cpu.h
Merge tag 'pull-target-arm-20240111' of https://git.linaro.org/people/pmaydell/qemu...
[mirror_qemu.git] / target / riscv / cpu.h
CommitLineData
dc5bd18f
MC
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
2e5b09fd 23#include "hw/core/cpu.h"
2b7168fc 24#include "hw/registerfields.h"
32fa1776 25#include "hw/qdev-properties.h"
dc5bd18f 26#include "exec/cpu-defs.h"
69242e7e 27#include "qemu/cpu-float.h"
db1015e9 28#include "qom/object.h"
961738ff 29#include "qemu/int128.h"
e91a7227 30#include "cpu_bits.h"
b902ff29 31#include "cpu_cfg.h"
6f23aaeb 32#include "qapi/qapi-types-common.h"
85840bd2 33#include "cpu-qom.h"
dc5bd18f 34
9348028e
PMD
35typedef struct CPUArchState CPURISCVState;
36
66125f93
PMD
37#define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
38
27a6e78e
PMD
39#if defined(TARGET_RISCV32)
40# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE32
41#elif defined(TARGET_RISCV64)
42# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE64
43#endif
44
74433bf0
RH
45#define TCG_GUEST_DEFAULT_MO 0
46
62cf0245
AP
47/*
48 * RISC-V-specific extra insn start words:
49 * 1: Original instruction opcode
50 */
51#define TARGET_INSN_START_EXTRA_WORDS 1
52
dc5bd18f
MC
53#define RV(x) ((target_ulong)1 << (x - 'A'))
54
ed7e6182 55/*
efa365b7 56 * Update misa_bits[], misa_ext_info_arr[] and misa_ext_cfgs[]
ed7e6182
DHB
57 * when adding new MISA bits here.
58 */
dc5bd18f 59#define RVI RV('I')
79f86934 60#define RVE RV('E') /* E and I are mutually exclusive */
dc5bd18f
MC
61#define RVM RV('M')
62#define RVA RV('A')
63#define RVF RV('F')
64#define RVD RV('D')
ad9e5aa2 65#define RVV RV('V')
dc5bd18f
MC
66#define RVC RV('C')
67#define RVS RV('S')
68#define RVU RV('U')
af1fa003 69#define RVH RV('H')
53dcea58 70#define RVJ RV('J')
4f13abcb 71#define RVG RV('G')
dc5bd18f 72
efa365b7 73extern const uint32_t misa_bits[];
ed7e6182
DHB
74const char *riscv_get_misa_ext_name(uint32_t bit);
75const char *riscv_get_misa_ext_description(uint32_t bit);
dc5bd18f 76
238fd586
DHB
77#define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop)
78
3f361847 79typedef struct riscv_cpu_profile {
79593ca4 80 struct riscv_cpu_profile *parent;
3f361847
DHB
81 const char *name;
82 uint32_t misa_ext;
83 bool enabled;
84 bool user_set;
1a7d4fcb 85 int priv_spec;
55398025 86 int satp_mode;
3f361847
DHB
87 const int32_t ext_offsets[];
88} RISCVCPUProfile;
89
90#define RISCV_PROFILE_EXT_LIST_END -1
1a7d4fcb 91#define RISCV_PROFILE_ATTR_UNUSED -1
3f361847
DHB
92
93extern RISCVCPUProfile *riscv_profiles[];
94
a46d410c
AP
95/* Privileged specification version */
96enum {
97 PRIV_VERSION_1_10_0 = 0,
98 PRIV_VERSION_1_11_0,
3a4af26d 99 PRIV_VERSION_1_12_0,
b9a2b98e
DHB
100
101 PRIV_VERSION_LATEST = PRIV_VERSION_1_12_0,
a46d410c 102};
dc5bd18f 103
9ec6622d 104#define VEXT_VERSION_1_00_0 0x00010000
32931383 105
33a9a57d
YJ
106enum {
107 TRANSLATE_SUCCESS,
108 TRANSLATE_FAIL,
109 TRANSLATE_PMP_FAIL,
110 TRANSLATE_G_STAGE_FAIL
111};
112
42967f40
LZ
113/* Extension context status */
114typedef enum {
115 EXT_STATUS_DISABLED = 0,
116 EXT_STATUS_INITIAL,
117 EXT_STATUS_CLEAN,
118 EXT_STATUS_DIRTY,
119} RISCVExtStatus;
120
dc5bd18f
MC
121#define MMU_USER_IDX 3
122
123#define MAX_RISCV_PMPS (16)
124
bbf3d1b4 125#if !defined(CONFIG_USER_ONLY)
dc5bd18f 126#include "pmp.h"
95799e36 127#include "debug.h"
bbf3d1b4 128#endif
dc5bd18f 129
8a4b5257 130#define RV_VLEN_MAX 1024
3780e337 131#define RV_MAX_MHPMEVENTS 32
621f35bb 132#define RV_MAX_MHPMCOUNTERS 32
ad9e5aa2 133
33f1beaf
FC
134FIELD(VTYPE, VLMUL, 0, 3)
135FIELD(VTYPE, VSEW, 3, 3)
3479a814
FC
136FIELD(VTYPE, VTA, 6, 1)
137FIELD(VTYPE, VMA, 7, 1)
33f1beaf
FC
138FIELD(VTYPE, VEDIV, 8, 2)
139FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
2b7168fc 140
3780e337
AP
141typedef struct PMUCTRState {
142 /* Current value of a counter */
143 target_ulong mhpmcounter_val;
3b57254d 144 /* Current value of a counter in RV32 */
3780e337
AP
145 target_ulong mhpmcounterh_val;
146 /* Snapshot values of counter */
147 target_ulong mhpmcounter_prev;
148 /* Snapshort value of a counter in RV32 */
149 target_ulong mhpmcounterh_prev;
150 bool started;
14664483
AP
151 /* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger */
152 target_ulong irq_overflow_left;
3780e337
AP
153} PMUCTRState;
154
1ea4a06a 155struct CPUArchState {
dc5bd18f 156 target_ulong gpr[32];
2b547084 157 target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
ad9e5aa2
LZ
158
159 /* vector coprocessor state. */
160 uint64_t vreg[32 * RV_VLEN_MAX / 64] QEMU_ALIGNED(16);
161 target_ulong vxrm;
162 target_ulong vxsat;
163 target_ulong vl;
164 target_ulong vstart;
165 target_ulong vtype;
d96a271a 166 bool vill;
ad9e5aa2 167
dc5bd18f
MC
168 target_ulong pc;
169 target_ulong load_res;
170 target_ulong load_val;
171
04bc3027
PMD
172 /* Floating-Point state */
173 uint64_t fpr[32]; /* assume both F and D extensions */
dc5bd18f 174 target_ulong frm;
04bc3027 175 float_status fp_status;
dc5bd18f
MC
176
177 target_ulong badaddr;
62cf0245 178 target_ulong bins;
48eaeb56 179
36a18664 180 target_ulong guest_phys_fault_addr;
dc5bd18f 181
dc5bd18f 182 target_ulong priv_ver;
d2c1a177 183 target_ulong bext_ver;
32931383 184 target_ulong vext_ver;
e91a7227
RH
185
186 /* RISCVMXL, but uint32_t for vmstate migration */
187 uint32_t misa_mxl; /* current mxl */
188 uint32_t misa_mxl_max; /* max mxl for this cpu */
189 uint32_t misa_ext; /* current extensions */
190 uint32_t misa_ext_mask; /* max ext for this cpu */
440544e1 191 uint32_t xl; /* current xlen */
dc5bd18f 192
b3a5d1fb
FP
193 /* 128-bit helpers upper part return value */
194 target_ulong retxh;
195
ce3af0bb
WL
196 target_ulong jvt;
197
5836c3ec
KC
198#ifdef CONFIG_USER_ONLY
199 uint32_t elf_flags;
200#endif
201
dc5bd18f
MC
202#ifndef CONFIG_USER_ONLY
203 target_ulong priv;
ef6bb7b6 204 /* This contains QEMU specific information about the virt state. */
b3c5077b 205 bool virt_enabled;
cd032fe7 206 target_ulong geilen;
277b210d 207 uint64_t resetvec;
dc5bd18f
MC
208
209 target_ulong mhartid;
284d697c
YJ
210 /*
211 * For RV32 this is 32-bit mstatus and 32-bit mstatush.
212 * For RV64 this is a 64-bit mstatus.
213 */
214 uint64_t mstatus;
85ba724f 215
d028ac75 216 uint64_t mip;
33fe584f
AF
217 /*
218 * MIP contains the software writable version of SEIP ORed with the
219 * external interrupt value. The MIP register is always up-to-date.
220 * To keep track of the current source, we also save booleans of the values
221 * here.
222 */
223 bool external_seip;
224 bool software_seip;
66e594f2 225
d028ac75 226 uint64_t miclaim;
85ba724f 227
d028ac75
AP
228 uint64_t mie;
229 uint64_t mideleg;
dc5bd18f 230
1697837e
RK
231 /*
232 * When mideleg[i]=0 and mvien[i]=1, sie[i] is no more
3a4e5601 233 * alias of mie[i] and needs to be maintained separately.
1697837e
RK
234 */
235 uint64_t sie;
236
40336d5b
RK
237 /*
238 * When hideleg[i]=0 and hvien[i]=1, vsie[i] is no more
3a4e5601 239 * alias of sie[i] (mie[i]) and needs to be maintained separately.
40336d5b
RK
240 */
241 uint64_t vsie;
242
dc5bd18f 243 target_ulong satp; /* since: priv-1.10.0 */
ac12b601 244 target_ulong stval;
dc5bd18f
MC
245 target_ulong medeleg;
246
247 target_ulong stvec;
248 target_ulong sepc;
249 target_ulong scause;
250
251 target_ulong mtvec;
252 target_ulong mepc;
253 target_ulong mcause;
254 target_ulong mtval; /* since: priv-1.10.0 */
255
43dc93af
AP
256 /* Machine and Supervisor interrupt priorities */
257 uint8_t miprio[64];
258 uint8_t siprio[64];
259
d1ceff40
AP
260 /* AIA CSRs */
261 target_ulong miselect;
262 target_ulong siselect;
1697837e
RK
263 uint64_t mvien;
264 uint64_t mvip;
d1ceff40 265
bd023ce3
AF
266 /* Hypervisor CSRs */
267 target_ulong hstatus;
268 target_ulong hedeleg;
d028ac75 269 uint64_t hideleg;
bd023ce3
AF
270 target_ulong hcounteren;
271 target_ulong htval;
272 target_ulong htinst;
273 target_ulong hgatp;
cd032fe7
AP
274 target_ulong hgeie;
275 target_ulong hgeip;
c6957248 276 uint64_t htimedelta;
40336d5b
RK
277 uint64_t hvien;
278
279 /*
280 * Bits VSSIP, VSTIP and VSEIP in hvip are maintained in mip. Other bits
281 * from 0:12 are reserved. Bits 13:63 are not aliased and must be separately
282 * maintain in hvip.
283 */
284 uint64_t hvip;
bd023ce3 285
43dc93af 286 /* Hypervisor controlled virtual interrupt priorities */
2b602398 287 target_ulong hvictl;
43dc93af
AP
288 uint8_t hviprio[64];
289
2c64ab66
FP
290 /* Upper 64-bits of 128-bit CSRs */
291 uint64_t mscratchh;
292 uint64_t sscratchh;
293
bd023ce3 294 /* Virtual CSRs */
284d697c
YJ
295 /*
296 * For RV32 this is 32-bit vsstatus and 32-bit vsstatush.
297 * For RV64 this is a 64-bit vsstatus.
298 */
299 uint64_t vsstatus;
bd023ce3
AF
300 target_ulong vstvec;
301 target_ulong vsscratch;
302 target_ulong vsepc;
303 target_ulong vscause;
304 target_ulong vstval;
305 target_ulong vsatp;
306
d1ceff40
AP
307 /* AIA VS-mode CSRs */
308 target_ulong vsiselect;
309
bd023ce3
AF
310 target_ulong mtval2;
311 target_ulong mtinst;
312
66e594f2
AF
313 /* HS Backup CSRs */
314 target_ulong stvec_hs;
315 target_ulong sscratch_hs;
316 target_ulong sepc_hs;
317 target_ulong scause_hs;
318 target_ulong stval_hs;
319 target_ulong satp_hs;
284d697c 320 uint64_t mstatus_hs;
66e594f2 321
3b57254d
WL
322 /*
323 * Signals whether the current exception occurred with two-stage address
324 * translation active.
325 */
ec352d0c 326 bool two_stage_lookup;
8e2aa21b
AP
327 /*
328 * Signals whether the current exception occurred while doing two-stage
329 * address translation for the VS-stage page table walk.
330 */
331 bool two_stage_indirect_lookup;
ec352d0c 332
8c59f5c1
MC
333 target_ulong scounteren;
334 target_ulong mcounteren;
dc5bd18f 335
b1675eeb
AP
336 target_ulong mcountinhibit;
337
3780e337
AP
338 /* PMU counter state */
339 PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
621f35bb 340
3b57254d 341 /* PMU event selector configured values. First three are unused */
621f35bb
AP
342 target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
343
3b57254d 344 /* PMU event selector configured values for RV32 */
14664483
AP
345 target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
346
dc5bd18f
MC
347 target_ulong sscratch;
348 target_ulong mscratch;
349
43888c2f
AP
350 /* Sstc CSRs */
351 uint64_t stimecmp;
352
3ec0fe18
AP
353 uint64_t vstimecmp;
354
dc5bd18f
MC
355 /* physical memory protection */
356 pmp_table_t pmp_state;
2582a95c 357 target_ulong mseccfg;
753e3fe2 358
95799e36
BM
359 /* trigger module */
360 target_ulong trigger_cur;
9495c488
FC
361 target_ulong tdata1[RV_MAX_TRIGGERS];
362 target_ulong tdata2[RV_MAX_TRIGGERS];
363 target_ulong tdata3[RV_MAX_TRIGGERS];
364 struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
365 struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
5a4ae64c
LZ
366 QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
367 int64_t last_icount;
577f0286 368 bool itrigger_enabled;
95799e36 369
c6957248 370 /* machine specific rdtime callback */
e2f01f3c
FC
371 uint64_t (*rdtime_fn)(void *);
372 void *rdtime_fn_arg;
c6957248 373
69077dd6
AP
374 /* machine specific AIA ireg read-modify-write callback */
375#define AIA_MAKE_IREG(__isel, __priv, __virt, __vgein, __xlen) \
376 ((((__xlen) & 0xff) << 24) | \
377 (((__vgein) & 0x3f) << 20) | \
378 (((__virt) & 0x1) << 18) | \
379 (((__priv) & 0x3) << 16) | \
380 (__isel & 0xffff))
381#define AIA_IREG_ISEL(__ireg) ((__ireg) & 0xffff)
382#define AIA_IREG_PRIV(__ireg) (((__ireg) >> 16) & 0x3)
383#define AIA_IREG_VIRT(__ireg) (((__ireg) >> 18) & 0x1)
384#define AIA_IREG_VGEIN(__ireg) (((__ireg) >> 20) & 0x3f)
385#define AIA_IREG_XLEN(__ireg) (((__ireg) >> 24) & 0xff)
386 int (*aia_ireg_rmw_fn[4])(void *arg, target_ulong reg,
387 target_ulong *val, target_ulong new_val, target_ulong write_mask);
388 void *aia_ireg_rmw_fn_arg[4];
389
753e3fe2
JW
390 /* True if in debugger mode. */
391 bool debugger;
4bbe8033
AB
392
393 /*
394 * CSRs for PointerMasking extension
395 */
396 target_ulong mmte;
397 target_ulong mpmmask;
398 target_ulong mpmbase;
399 target_ulong spmmask;
400 target_ulong spmbase;
401 target_ulong upmmask;
402 target_ulong upmbase;
29a9ec9b 403
42fe7499 404 /* CSRs for execution environment configuration */
29a9ec9b 405 uint64_t menvcfg;
3bee0e40
MC
406 uint64_t mstateen[SMSTATEEN_MAX_COUNT];
407 uint64_t hstateen[SMSTATEEN_MAX_COUNT];
408 uint64_t sstateen[SMSTATEEN_MAX_COUNT];
29a9ec9b
AP
409 target_ulong senvcfg;
410 uint64_t henvcfg;
dc5bd18f 411#endif
40bfa5f6
LZ
412 target_ulong cur_pmmask;
413 target_ulong cur_pmbase;
dc5bd18f 414
dc5bd18f 415 /* Fields from here on are preserved across CPU reset. */
43888c2f 416 QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
3ec0fe18
AP
417 QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
418 bool vstime_irq;
ad40be27
YJ
419
420 hwaddr kernel_addr;
421 hwaddr fdt_addr;
27abe66f 422
9638cbde 423#ifdef CONFIG_KVM
27abe66f
YJ
424 /* kvm timer */
425 bool kvm_timer_dirty;
426 uint64_t kvm_timer_time;
427 uint64_t kvm_timer_compare;
428 uint64_t kvm_timer_state;
429 uint64_t kvm_timer_frequency;
9638cbde 430#endif /* CONFIG_KVM */
dc5bd18f
MC
431};
432
3b57254d 433/*
dc5bd18f
MC
434 * RISCVCPU:
435 * @env: #CPURISCVState
436 *
437 * A RISCV CPU.
438 */
b36e239e 439struct ArchCPU {
dc5bd18f 440 CPUState parent_obj;
3b3d7df5 441
dc5bd18f 442 CPURISCVState env;
c4e95030 443
b93777e1 444 char *dyn_csr_xml;
719d3561 445 char *dyn_vreg_xml;
b93777e1 446
c4e95030 447 /* Configuration Settings */
466292bd 448 RISCVCPUConfig cfg;
14664483
AP
449
450 QEMUTimer *pmu_timer;
451 /* A bitmask of Available programmable counters */
452 uint32_t pmu_avail_ctrs;
453 /* Mapping of events to counters */
454 GHashTable *pmu_event_ctr_map;
db1015e9 455};
dc5bd18f 456
9348028e
PMD
457/**
458 * RISCVCPUClass:
459 * @parent_realize: The parent class' realize handler.
460 * @parent_phases: The parent class' reset phase handlers.
461 *
462 * A RISCV CPU model.
463 */
464struct RISCVCPUClass {
465 CPUClass parent_class;
466
467 DeviceRealize parent_realize;
468 ResettablePhases parent_phases;
469};
470
dc5bd18f
MC
471static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
472{
e91a7227 473 return (env->misa_ext & ext) != 0;
dc5bd18f
MC
474}
475
dc5bd18f 476#include "cpu_user.h"
dc5bd18f
MC
477
478extern const char * const riscv_int_regnames[];
2b547084 479extern const char * const riscv_int_regnamesh[];
dc5bd18f 480extern const char * const riscv_fpr_regnames[];
dc5bd18f 481
c51a3f5d 482const char *riscv_cpu_get_trap_name(target_ulong cause, bool async);
dc5bd18f 483void riscv_cpu_do_interrupt(CPUState *cpu);
43a96588 484int riscv_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
1af0006a 485 int cpuid, DumpState *s);
43a96588 486int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
1af0006a 487 int cpuid, DumpState *s);
a010bdbe 488int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
dc5bd18f 489int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
43dc93af
AP
490int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero);
491uint8_t riscv_cpu_default_priority(int irq);
8f42415f 492uint64_t riscv_cpu_all_pending(CPURISCVState *env);
43dc93af
AP
493int riscv_cpu_mirq_pending(CPURISCVState *env);
494int riscv_cpu_sirq_pending(CPURISCVState *env);
495int riscv_cpu_vsirq_pending(CPURISCVState *env);
b345b480 496bool riscv_cpu_fp_enabled(CPURISCVState *env);
cd032fe7
AP
497target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
498void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
61b4b69d 499bool riscv_cpu_vector_enabled(CPURISCVState *env);
ef6bb7b6 500void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
dc5bd18f 501int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
8905770b 502G_NORETURN void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
246f8796
WL
503 MMUAccessType access_type,
504 int mmu_idx, uintptr_t retaddr);
8a4ca3c1
RH
505bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
506 MMUAccessType access_type, int mmu_idx,
507 bool probe, uintptr_t retaddr);
dc5bd18f 508char *riscv_isa_string(RISCVCPU *cpu);
dc5bd18f 509
dc5bd18f
MC
510#define cpu_mmu_index riscv_cpu_mmu_index
511
85ba724f 512#ifndef CONFIG_USER_ONLY
d90ebc47
PMD
513void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
514 vaddr addr, unsigned size,
515 MMUAccessType access_type,
516 int mmu_idx, MemTxAttrs attrs,
517 MemTxResult response, uintptr_t retaddr);
6d2d454a 518hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
17b3c353 519bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
66e594f2 520void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
d028ac75 521int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts);
bbb9fc25
WL
522uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask,
523 uint64_t value);
1ebad505 524void riscv_cpu_interrupt(CPURISCVState *env);
85ba724f 525#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
e2f01f3c
FC
526void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
527 void *arg);
69077dd6
AP
528void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
529 int (*rmw_fn)(void *arg,
530 target_ulong reg,
531 target_ulong *val,
532 target_ulong new_val,
533 target_ulong write_mask),
534 void *rmw_fn_arg);
ce3af0bb
WL
535
536RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
85ba724f 537#endif
fb738839 538void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
dc5bd18f
MC
539
540void riscv_translate_init(void);
8905770b
MAL
541G_NORETURN void riscv_raise_exception(CPURISCVState *env,
542 uint32_t exception, uintptr_t pc);
dc5bd18f 543
fb738839
MC
544target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
545void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
dc5bd18f 546
2b7168fc
LZ
547#include "exec/cpu-all.h"
548
61d56494 549FIELD(TB_FLAGS, MEM_IDX, 0, 3)
ebd47648
LZ
550FIELD(TB_FLAGS, FS, 3, 2)
551/* Vector flags */
552FIELD(TB_FLAGS, VS, 5, 2)
553FIELD(TB_FLAGS, LMUL, 7, 3)
554FIELD(TB_FLAGS, SEW, 10, 3)
555FIELD(TB_FLAGS, VL_EQ_VLMAX, 13, 1)
556FIELD(TB_FLAGS, VILL, 14, 1)
0f58cbbe 557FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1)
92371bd9 558/* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
25f3ddff 559FIELD(TB_FLAGS, XL, 16, 2)
0774a7a1 560/* If PointerMasking should be applied */
25f3ddff
RH
561FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1)
562FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1)
563FIELD(TB_FLAGS, VTA, 20, 1)
564FIELD(TB_FLAGS, VMA, 21, 1)
2c9d7471 565/* Native debug itrigger */
25f3ddff 566FIELD(TB_FLAGS, ITRIGGER, 22, 1)
f1966390 567/* Virtual mode enabled */
25f3ddff 568FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
0f58cbbe 569FIELD(TB_FLAGS, PRIV, 24, 2)
3a610f54 570FIELD(TB_FLAGS, AXL, 26, 2)
2b7168fc 571
db23e5d9
RH
572#ifdef TARGET_RISCV32
573#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
574#else
575static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
576{
577 return env->misa_mxl;
578}
579#endif
2b602398 580#define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env)))
51ae0cab 581
d4ea7117
DHB
582static inline const RISCVCPUConfig *riscv_cpu_cfg(CPURISCVState *env)
583{
584 return &env_archcpu(env)->cfg;
585}
586
3a610f54
WL
587#if !defined(CONFIG_USER_ONLY)
588static inline int cpu_address_mode(CPURISCVState *env)
589{
590 int mode = env->priv;
591
592 if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
593 mode = get_field(env->mstatus, MSTATUS_MPP);
594 }
595 return mode;
596}
597
598static inline RISCVMXL cpu_get_xl(CPURISCVState *env, target_ulong mode)
440544e1
LZ
599{
600 RISCVMXL xl = env->misa_mxl;
440544e1
LZ
601 /*
602 * When emulating a 32-bit-only cpu, use RV32.
603 * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
604 * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
605 * back to RV64 for lower privs.
606 */
607 if (xl != MXL_RV32) {
3a610f54 608 switch (mode) {
440544e1
LZ
609 case PRV_M:
610 break;
611 case PRV_U:
612 xl = get_field(env->mstatus, MSTATUS64_UXL);
613 break;
44b8f74b 614 default: /* PRV_S */
440544e1
LZ
615 xl = get_field(env->mstatus, MSTATUS64_SXL);
616 break;
617 }
618 }
440544e1
LZ
619 return xl;
620}
621#endif
622
3a610f54
WL
623#if defined(TARGET_RISCV32)
624#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
625#else
626static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
627{
628#if !defined(CONFIG_USER_ONLY)
629 return cpu_get_xl(env, env->priv);
630#else
631 return env->misa_mxl;
632#endif
633}
634#endif
635
636#if defined(TARGET_RISCV32)
637#define cpu_address_xl(env) ((void)(env), MXL_RV32)
638#else
639static inline RISCVMXL cpu_address_xl(CPURISCVState *env)
640{
641#ifdef CONFIG_USER_ONLY
642 return env->xl;
643#else
644 int mode = cpu_address_mode(env);
645
646 return cpu_get_xl(env, mode);
647#endif
648}
649#endif
650
31961cfe
LZ
651static inline int riscv_cpu_xlen(CPURISCVState *env)
652{
653 return 16 << env->xl;
654}
655
05e6ca5e
GR
656#ifdef TARGET_RISCV32
657#define riscv_cpu_sxl(env) ((void)(env), MXL_RV32)
658#else
659static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
660{
661#ifdef CONFIG_USER_ONLY
662 return env->misa_mxl;
663#else
664 return get_field(env->mstatus, MSTATUS64_SXL);
665#endif
666}
667#endif
668
2b7168fc 669/*
a689a82b
FC
670 * Encode LMUL to lmul as follows:
671 * LMUL vlmul lmul
672 * 1 000 0
673 * 2 001 1
674 * 4 010 2
675 * 8 011 3
676 * - 100 -
677 * 1/8 101 -3
678 * 1/4 110 -2
679 * 1/2 111 -1
680 *
681 * then, we can calculate VLMAX = vlen >> (vsew + 3 - lmul)
682 * e.g. vlen = 256 bits, SEW = 16, LMUL = 1/8
683 * => VLMAX = vlen >> (1 + 3 - (-3))
684 * = 256 >> 7
685 * = 2
2b7168fc
LZ
686 */
687static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
688{
a689a82b
FC
689 uint8_t sew = FIELD_EX64(vtype, VTYPE, VSEW);
690 int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
2b7168fc
LZ
691 return cpu->cfg.vlen >> (sew + 3 - lmul);
692}
693
bb5de525
AJ
694void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
695 uint64_t *cs_base, uint32_t *pflags);
dc5bd18f 696
40bfa5f6 697void riscv_cpu_update_mask(CPURISCVState *env);
e7acc1cb 698bool riscv_cpu_is_32bit(RISCVCPU *cpu);
40bfa5f6 699
533c91e8
AF
700RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
701 target_ulong *ret_value,
702 target_ulong new_value, target_ulong write_mask);
703RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
704 target_ulong *ret_value,
705 target_ulong new_value,
706 target_ulong write_mask);
c7b95171 707
fb738839
MC
708static inline void riscv_csr_write(CPURISCVState *env, int csrno,
709 target_ulong val)
c7b95171
MC
710{
711 riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
712}
713
fb738839 714static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
c7b95171
MC
715{
716 target_ulong val = 0;
717 riscv_csrrw(env, csrno, &val, 0, 0);
718 return val;
719}
720
0e62f92e
AF
721typedef RISCVException (*riscv_csr_predicate_fn)(CPURISCVState *env,
722 int csrno);
605def6e
AF
723typedef RISCVException (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
724 target_ulong *ret_value);
725typedef RISCVException (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
726 target_ulong new_value);
727typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
728 target_ulong *ret_value,
729 target_ulong new_value,
730 target_ulong write_mask);
c7b95171 731
961738ff
FP
732RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
733 Int128 *ret_value,
734 Int128 new_value, Int128 write_mask);
735
457c360f
FP
736typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
737 Int128 *ret_value);
738typedef RISCVException (*riscv_csr_write128_fn)(CPURISCVState *env, int csrno,
739 Int128 new_value);
740
c7b95171 741typedef struct {
8ceac5dc 742 const char *name;
a88365c1 743 riscv_csr_predicate_fn predicate;
c7b95171
MC
744 riscv_csr_read_fn read;
745 riscv_csr_write_fn write;
746 riscv_csr_op_fn op;
457c360f
FP
747 riscv_csr_read128_fn read128;
748 riscv_csr_write128_fn write128;
a4b2fa43
AP
749 /* The default priv spec version should be PRIV_VERSION_1_10_0 (i.e 0) */
750 uint32_t min_priv_ver;
c7b95171
MC
751} riscv_csr_operations;
752
56118ee8
BM
753/* CSR function table constants */
754enum {
755 CSR_TABLE_SIZE = 0x1000
756};
757
3b57254d 758/*
14664483
AP
759 * The event id are encoded based on the encoding specified in the
760 * SBI specification v0.3
761 */
762
763enum riscv_pmu_event_idx {
764 RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
765 RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
766 RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
767 RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
768 RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
769};
770
36c1118d
DHB
771/* used by tcg/tcg-cpu.c*/
772void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en);
36c1118d 773bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset);
f51d03b0 774void riscv_cpu_set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext);
36c1118d 775
32fa1776
DHB
776typedef struct RISCVCPUMultiExtConfig {
777 const char *name;
778 uint32_t offset;
779 bool enabled;
780} RISCVCPUMultiExtConfig;
781
782extern const RISCVCPUMultiExtConfig riscv_cpu_extensions[];
783extern const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[];
784extern const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[];
5fe2800b 785extern const RISCVCPUMultiExtConfig riscv_cpu_named_features[];
8043effd 786extern const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[];
32fa1776
DHB
787extern Property riscv_cpu_options[];
788
7935e2c4
DHB
789typedef struct isa_ext_data {
790 const char *name;
791 int min_version;
792 int ext_enable_offset;
793} RISCVIsaExtData;
794extern const RISCVIsaExtData isa_edata_arr[];
b933720b 795char *riscv_cpu_get_name(RISCVCPU *cpu);
7935e2c4 796
a13a6082 797void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
7d0c302c 798void riscv_add_satp_mode_properties(Object *obj);
ef58fad0 799bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu);
32fa1776 800
56118ee8 801/* CSR function table */
6f03770d 802extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
56118ee8 803
6f23aaeb
AG
804extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
805
c7b95171
MC
806void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
807void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
dc5bd18f 808
5371f5cd
JW
809void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
810
6f23aaeb
AG
811uint8_t satp_mode_max_from_map(uint32_t map);
812const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
813
dc5bd18f 814#endif /* RISCV_CPU_H */