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