xref: /openbmc/qemu/target/riscv/cpu.h (revision 1c627d726545038a6ed16fb38b2765a1c0981db5)
1dc5bd18fSMichael Clark /*
2dc5bd18fSMichael Clark  * QEMU RISC-V CPU
3dc5bd18fSMichael Clark  *
4dc5bd18fSMichael Clark  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5dc5bd18fSMichael Clark  * Copyright (c) 2017-2018 SiFive, Inc.
6dc5bd18fSMichael Clark  *
7dc5bd18fSMichael Clark  * This program is free software; you can redistribute it and/or modify it
8dc5bd18fSMichael Clark  * under the terms and conditions of the GNU General Public License,
9dc5bd18fSMichael Clark  * version 2 or later, as published by the Free Software Foundation.
10dc5bd18fSMichael Clark  *
11dc5bd18fSMichael Clark  * This program is distributed in the hope it will be useful, but WITHOUT
12dc5bd18fSMichael Clark  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13dc5bd18fSMichael Clark  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14dc5bd18fSMichael Clark  * more details.
15dc5bd18fSMichael Clark  *
16dc5bd18fSMichael Clark  * You should have received a copy of the GNU General Public License along with
17dc5bd18fSMichael Clark  * this program.  If not, see <http://www.gnu.org/licenses/>.
18dc5bd18fSMichael Clark  */
19dc5bd18fSMichael Clark 
20dc5bd18fSMichael Clark #ifndef RISCV_CPU_H
21dc5bd18fSMichael Clark #define RISCV_CPU_H
22dc5bd18fSMichael Clark 
232e5b09fdSMarkus Armbruster #include "hw/core/cpu.h"
242b7168fcSLIU Zhiwei #include "hw/registerfields.h"
2532fa1776SDaniel Henrique Barboza #include "hw/qdev-properties.h"
26dc5bd18fSMichael Clark #include "exec/cpu-defs.h"
2733a24910SAkihiko Odaki #include "exec/gdbstub.h"
2869242e7eSMarc-André Lureau #include "qemu/cpu-float.h"
29db1015e9SEduardo Habkost #include "qom/object.h"
30961738ffSFrédéric Pétrot #include "qemu/int128.h"
31e91a7227SRichard Henderson #include "cpu_bits.h"
32b902ff29SWeiwei Li #include "cpu_cfg.h"
336f23aaebSAlexandre Ghiti #include "qapi/qapi-types-common.h"
3485840bd2SDaniel Henrique Barboza #include "cpu-qom.h"
35dc5bd18fSMichael Clark 
369348028eSPhilippe Mathieu-Daudé typedef struct CPUArchState CPURISCVState;
379348028eSPhilippe Mathieu-Daudé 
3866125f93SPhilippe Mathieu-Daudé #define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
3966125f93SPhilippe Mathieu-Daudé 
4027a6e78eSPhilippe Mathieu-Daudé #if defined(TARGET_RISCV32)
4127a6e78eSPhilippe Mathieu-Daudé # define TYPE_RISCV_CPU_BASE            TYPE_RISCV_CPU_BASE32
4227a6e78eSPhilippe Mathieu-Daudé #elif defined(TARGET_RISCV64)
4327a6e78eSPhilippe Mathieu-Daudé # define TYPE_RISCV_CPU_BASE            TYPE_RISCV_CPU_BASE64
4427a6e78eSPhilippe Mathieu-Daudé #endif
4527a6e78eSPhilippe Mathieu-Daudé 
4662cf0245SAnup Patel /*
4762cf0245SAnup Patel  * RISC-V-specific extra insn start words:
4862cf0245SAnup Patel  * 1: Original instruction opcode
4962cf0245SAnup Patel  * 2: more information about instruction
5062cf0245SAnup Patel  */
5162cf0245SAnup Patel #define TARGET_INSN_START_EXTRA_WORDS 2
52dc5bd18fSMichael Clark /*
53dc5bd18fSMichael Clark  * b0: Whether a instruction always raise a store AMO or not.
54ed7e6182SDaniel Henrique Barboza  */
55efa365b7SDaniel Henrique Barboza #define RISCV_UW2_ALWAYS_STORE_AMO 1
56ed7e6182SDaniel Henrique Barboza 
57ed7e6182SDaniel Henrique Barboza #define RV(x) ((target_ulong)1 << (x - 'A'))
58dc5bd18fSMichael Clark 
5979f86934SMichael Clark /*
60dc5bd18fSMichael Clark  * Update misa_bits[], misa_ext_info_arr[] and misa_ext_cfgs[]
61dc5bd18fSMichael Clark  * when adding new MISA bits here.
62dc5bd18fSMichael Clark  */
63dc5bd18fSMichael Clark #define RVI RV('I')
64ad9e5aa2SLIU Zhiwei #define RVE RV('E') /* E and I are mutually exclusive */
65dc5bd18fSMichael Clark #define RVM RV('M')
66dc5bd18fSMichael Clark #define RVA RV('A')
67dc5bd18fSMichael Clark #define RVF RV('F')
68af1fa003SAlistair Francis #define RVD RV('D')
6953dcea58SAlexey Baturo #define RVV RV('V')
704f13abcbSDaniel Henrique Barboza #define RVC RV('C')
712317ba9fSRob Bradford #define RVS RV('S')
72dc5bd18fSMichael Clark #define RVU RV('U')
73efa365b7SDaniel Henrique Barboza #define RVH RV('H')
74ed7e6182SDaniel Henrique Barboza #define RVJ RV('J')
75ed7e6182SDaniel Henrique Barboza #define RVG RV('G')
76dc5bd18fSMichael Clark #define RVB RV('B')
77238fd586SDaniel Henrique Barboza 
78238fd586SDaniel Henrique Barboza extern const uint32_t misa_bits[];
793f361847SDaniel Henrique Barboza const char *riscv_get_misa_ext_name(uint32_t bit);
8079593ca4SDaniel Henrique Barboza const char *riscv_get_misa_ext_description(uint32_t bit);
813f361847SDaniel Henrique Barboza 
823f361847SDaniel Henrique Barboza #define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop)
833f361847SDaniel Henrique Barboza 
843f361847SDaniel Henrique Barboza typedef struct riscv_cpu_profile {
851a7d4fcbSDaniel Henrique Barboza     struct riscv_cpu_profile *parent;
8655398025SDaniel Henrique Barboza     const char *name;
873f361847SDaniel Henrique Barboza     uint32_t misa_ext;
883f361847SDaniel Henrique Barboza     bool enabled;
893f361847SDaniel Henrique Barboza     bool user_set;
903f361847SDaniel Henrique Barboza     int priv_spec;
911a7d4fcbSDaniel Henrique Barboza     int satp_mode;
923f361847SDaniel Henrique Barboza     const int32_t ext_offsets[];
933f361847SDaniel Henrique Barboza } RISCVCPUProfile;
943f361847SDaniel Henrique Barboza 
95a46d410cSAtish Patra #define RISCV_PROFILE_EXT_LIST_END -1
96fefc294bSDaniel Henrique Barboza #define RISCV_PROFILE_ATTR_UNUSED -1
97fefc294bSDaniel Henrique Barboza 
98fefc294bSDaniel Henrique Barboza extern RISCVCPUProfile *riscv_profiles[];
990c2d5f73SFea.Wang 
100a46d410cSAtish Patra /* Privileged specification version */
101a46d410cSAtish Patra #define PRIV_VER_1_10_0_STR "v1.10.0"
102a46d410cSAtish Patra #define PRIV_VER_1_11_0_STR "v1.11.0"
1033a4af26dSAtish Patra #define PRIV_VER_1_12_0_STR "v1.12.0"
1040c2d5f73SFea.Wang #define PRIV_VER_1_13_0_STR "v1.13.0"
105b9a2b98eSDaniel Henrique Barboza enum {
1060c2d5f73SFea.Wang     PRIV_VERSION_1_10_0 = 0,
107a46d410cSAtish Patra     PRIV_VERSION_1_11_0,
108dc5bd18fSMichael Clark     PRIV_VERSION_1_12_0,
1099ec6622dSFrank Chang     PRIV_VERSION_1_13_0,
11041f2b94eSDaniel Henrique Barboza 
11132931383SLIU Zhiwei     PRIV_VERSION_LATEST = PRIV_VERSION_1_13_0,
11233a9a57dSYifei Jiang };
11333a9a57dSYifei Jiang 
11433a9a57dSYifei Jiang #define VEXT_VERSION_1_00_0 0x00010000
11533a9a57dSYifei Jiang #define VEXT_VER_1_00_0_STR "v1.0"
11633a9a57dSYifei Jiang 
11733a9a57dSYifei Jiang enum {
11833a9a57dSYifei Jiang     TRANSLATE_SUCCESS,
11942967f40SLIU Zhiwei     TRANSLATE_FAIL,
12042967f40SLIU Zhiwei     TRANSLATE_PMP_FAIL,
12142967f40SLIU Zhiwei     TRANSLATE_G_STAGE_FAIL
12242967f40SLIU Zhiwei };
12342967f40SLIU Zhiwei 
12442967f40SLIU Zhiwei /* Extension context status */
12542967f40SLIU Zhiwei typedef enum {
12642967f40SLIU Zhiwei     EXT_STATUS_DISABLED = 0,
127f04f7709SFrank Chang     EXT_STATUS_INITIAL,
128f04f7709SFrank Chang     EXT_STATUS_CLEAN,
129f04f7709SFrank Chang     EXT_STATUS_DIRTY,
130f04f7709SFrank Chang } RISCVExtStatus;
131f04f7709SFrank Chang 
132f04f7709SFrank Chang typedef struct riscv_cpu_implied_exts_rule {
133f04f7709SFrank Chang #ifndef CONFIG_USER_ONLY
134f04f7709SFrank Chang     /*
135f04f7709SFrank Chang      * Bitmask indicates the rule enabled status for the harts.
136f04f7709SFrank Chang      * This enhancement is only available in system-mode QEMU,
137f04f7709SFrank Chang      * as we don't have a good way (e.g. mhartid) to distinguish
138f04f7709SFrank Chang      * the SMP cores in user-mode QEMU.
139f04f7709SFrank Chang      */
140f04f7709SFrank Chang     unsigned long *enabled;
141f04f7709SFrank Chang #endif
142f04f7709SFrank Chang     /* True if this is a MISA implied rule. */
143f04f7709SFrank Chang     bool is_misa;
144f04f7709SFrank Chang     /* ext is MISA bit if is_misa flag is true, else multi extension offset. */
145f04f7709SFrank Chang     const uint32_t ext;
146f04f7709SFrank Chang     const uint32_t implied_misa_exts;
147f04f7709SFrank Chang     const uint32_t implied_multi_exts[];
148f04f7709SFrank Chang } RISCVCPUImpliedExtsRule;
149f04f7709SFrank Chang 
150dc5bd18fSMichael Clark extern RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[];
151dc5bd18fSMichael Clark extern RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[];
152dc5bd18fSMichael Clark 
153dc5bd18fSMichael Clark #define RISCV_IMPLIED_EXTS_RULE_END -1
154bbf3d1b4SPhilippe Mathieu-Daudé 
155dc5bd18fSMichael Clark #define MMU_USER_IDX 3
15695799e36SBin Meng 
157bbf3d1b4SPhilippe Mathieu-Daudé #define MAX_RISCV_PMPS (16)
158dc5bd18fSMichael Clark 
1598a4b5257SFrank Chang #if !defined(CONFIG_USER_ONLY)
1603780e337SAtish Patra #include "pmp.h"
161621f35bbSAtish Patra #include "debug.h"
162ad9e5aa2SLIU Zhiwei #endif
16333f1beafSFrank Chang 
16433f1beafSFrank Chang #define RV_VLEN_MAX 1024
1653479a814SFrank Chang #define RV_MAX_MHPMEVENTS 32
1663479a814SFrank Chang #define RV_MAX_MHPMCOUNTERS 32
16733f1beafSFrank Chang 
16833f1beafSFrank Chang FIELD(VTYPE, VLMUL, 0, 3)
1692b7168fcSLIU Zhiwei FIELD(VTYPE, VSEW, 3, 3)
1703780e337SAtish Patra FIELD(VTYPE, VTA, 6, 1)
1713780e337SAtish Patra FIELD(VTYPE, VMA, 7, 1)
1723780e337SAtish Patra FIELD(VTYPE, VEDIV, 8, 2)
1733780e337SAtish Patra FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
1743780e337SAtish Patra 
1753780e337SAtish Patra typedef struct PMUCTRState {
1763780e337SAtish Patra     /* Current value of a counter */
1773780e337SAtish Patra     target_ulong mhpmcounter_val;
1783780e337SAtish Patra     /* Current value of a counter in RV32 */
17914664483SAtish Patra     target_ulong mhpmcounterh_val;
18014664483SAtish Patra     /* Snapshot values of counter */
1813780e337SAtish Patra     target_ulong mhpmcounter_prev;
1823780e337SAtish Patra     /* Snapshort value of a counter in RV32 */
183b2d7a7c7SAtish Patra     target_ulong mhpmcounterh_prev;
184b2d7a7c7SAtish Patra     /* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger */
185b2d7a7c7SAtish Patra     target_ulong irq_overflow_left;
186b2d7a7c7SAtish Patra } PMUCTRState;
187b2d7a7c7SAtish Patra 
188b2d7a7c7SAtish Patra typedef struct PMUFixedCtrState {
189b2d7a7c7SAtish Patra         /* Track cycle and icount for each privilege mode */
190b2d7a7c7SAtish Patra         uint64_t counter[4];
191b2d7a7c7SAtish Patra         uint64_t counter_prev[4];
1921ea4a06aSPhilippe Mathieu-Daudé         /* Track cycle and icount for each privilege mode when V = 1*/
193dc5bd18fSMichael Clark         uint64_t counter_virt[2];
1942b547084SFrédéric Pétrot         uint64_t counter_virt_prev[2];
195ad9e5aa2SLIU Zhiwei } PMUFixedCtrState;
196ad9e5aa2SLIU Zhiwei 
197ad9e5aa2SLIU Zhiwei struct CPUArchState {
198ad9e5aa2SLIU Zhiwei     target_ulong gpr[32];
199ad9e5aa2SLIU Zhiwei     target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
200ad9e5aa2SLIU Zhiwei 
201ad9e5aa2SLIU Zhiwei     /* vector coprocessor state. */
202ad9e5aa2SLIU Zhiwei     uint64_t vreg[32 * RV_VLEN_MAX / 64] QEMU_ALIGNED(16);
203d96a271aSLIU Zhiwei     target_ulong vxrm;
204ad9e5aa2SLIU Zhiwei     target_ulong vxsat;
205dc5bd18fSMichael Clark     target_ulong vl;
206dc5bd18fSMichael Clark     target_ulong vstart;
207dc5bd18fSMichael Clark     target_ulong vtype;
208dc5bd18fSMichael Clark     bool vill;
20904bc3027SPhilippe Mathieu-Daudé 
21004bc3027SPhilippe Mathieu-Daudé     target_ulong pc;
211dc5bd18fSMichael Clark     target_ulong load_res;
21204bc3027SPhilippe Mathieu-Daudé     target_ulong load_val;
213dc5bd18fSMichael Clark 
214dc5bd18fSMichael Clark     /* Floating-Point state */
21562cf0245SAnup Patel     uint64_t fpr[32]; /* assume both F and D extensions */
21648eaeb56SAlistair Francis     target_ulong frm;
21736a18664SAlistair Francis     float_status fp_status;
218dc5bd18fSMichael Clark 
219dc5bd18fSMichael Clark     target_ulong badaddr;
22032931383SLIU Zhiwei     target_ulong bins;
221e91a7227SRichard Henderson 
222e91a7227SRichard Henderson     target_ulong guest_phys_fault_addr;
223e91a7227SRichard Henderson 
224e91a7227SRichard Henderson     target_ulong priv_ver;
225e91a7227SRichard Henderson     target_ulong vext_ver;
226440544e1SLIU Zhiwei 
227dc5bd18fSMichael Clark     /* RISCVMXL, but uint32_t for vmstate migration */
228b3a5d1fbSFrédéric Pétrot     uint32_t misa_mxl;      /* current mxl */
229b3a5d1fbSFrédéric Pétrot     uint32_t misa_ext;      /* current extensions */
230b3a5d1fbSFrédéric Pétrot     uint32_t misa_ext_mask; /* max ext for this cpu */
231ce3af0bbSWeiwei Li     uint32_t xl;            /* current xlen */
232ce3af0bbSWeiwei Li 
2335836c3ecSKito Cheng     /* 128-bit helpers upper part return value */
2345836c3ecSKito Cheng     target_ulong retxh;
2355836c3ecSKito Cheng 
2365836c3ecSKito Cheng     target_ulong jvt;
237dc5bd18fSMichael Clark 
238dc5bd18fSMichael Clark     /* elp state for zicfilp extension */
239ef6bb7b6SAlistair Francis     bool      elp;
240b3c5077bSLIU Zhiwei     /* shadow stack register for zicfiss extension */
241cd032fe7SAnup Patel     target_ulong ssp;
242277b210dSAlistair Francis     /* env place holder for extra word 2 during unwind */
243dc5bd18fSMichael Clark     target_ulong excp_uw2;
244dc5bd18fSMichael Clark     /* sw check code for sw check exception */
245284d697cSYifei Jiang     target_ulong sw_check_code;
246284d697cSYifei Jiang #ifdef CONFIG_USER_ONLY
247284d697cSYifei Jiang     uint32_t elf_flags;
248284d697cSYifei Jiang #endif
249284d697cSYifei Jiang 
25085ba724fSMichael Clark     target_ulong priv;
251d028ac75SAnup Patel     /* CSRs for execution environment configuration */
25233fe584fSAlistair Francis     uint64_t menvcfg;
25333fe584fSAlistair Francis     target_ulong senvcfg;
25433fe584fSAlistair Francis 
25533fe584fSAlistair Francis #ifndef CONFIG_USER_ONLY
25633fe584fSAlistair Francis     /* This contains QEMU specific information about the virt state. */
25733fe584fSAlistair Francis     bool virt_enabled;
25833fe584fSAlistair Francis     target_ulong geilen;
25933fe584fSAlistair Francis     uint64_t resetvec;
26066e594f2SAlistair Francis 
261d028ac75SAnup Patel     target_ulong mhartid;
26285ba724fSMichael Clark     /*
263d028ac75SAnup Patel      * For RV32 this is 32-bit mstatus and 32-bit mstatush.
264d028ac75SAnup Patel      * For RV64 this is a 64-bit mstatus.
265dc5bd18fSMichael Clark      */
2661697837eSRajnesh Kanwal     uint64_t mstatus;
2671697837eSRajnesh Kanwal 
2683a4e5601SMichael Tokarev     uint64_t mip;
2691697837eSRajnesh Kanwal     /*
2701697837eSRajnesh Kanwal      * MIP contains the software writable version of SEIP ORed with the
2711697837eSRajnesh Kanwal      * external interrupt value. The MIP register is always up-to-date.
27240336d5bSRajnesh Kanwal      * To keep track of the current source, we also save booleans of the values
27340336d5bSRajnesh Kanwal      * here.
2743a4e5601SMichael Tokarev      */
27540336d5bSRajnesh Kanwal     bool external_seip;
27640336d5bSRajnesh Kanwal     bool software_seip;
27740336d5bSRajnesh Kanwal 
278dc5bd18fSMichael Clark     uint64_t miclaim;
279ac12b601SAtish Patra 
280dc5bd18fSMichael Clark     uint64_t mie;
281dc5bd18fSMichael Clark     uint64_t mideleg;
282dc5bd18fSMichael Clark 
283dc5bd18fSMichael Clark     /*
284dc5bd18fSMichael Clark      * When mideleg[i]=0 and mvien[i]=1, sie[i] is no more
285dc5bd18fSMichael Clark      * alias of mie[i] and needs to be maintained separately.
286dc5bd18fSMichael Clark      */
287dc5bd18fSMichael Clark     uint64_t sie;
288dc5bd18fSMichael Clark 
289dc5bd18fSMichael Clark     /*
290dc5bd18fSMichael Clark      * When hideleg[i]=0 and hvien[i]=1, vsie[i] is no more
29143dc93afSAnup Patel      * alias of sie[i] (mie[i]) and needs to be maintained separately.
29243dc93afSAnup Patel      */
29343dc93afSAnup Patel     uint64_t vsie;
29443dc93afSAnup Patel 
295d1ceff40SAnup Patel     target_ulong satp;   /* since: priv-1.10.0 */
296d1ceff40SAnup Patel     target_ulong stval;
297d1ceff40SAnup Patel     target_ulong medeleg;
2981697837eSRajnesh Kanwal 
2991697837eSRajnesh Kanwal     target_ulong stvec;
300d1ceff40SAnup Patel     target_ulong sepc;
301bd023ce3SAlistair Francis     target_ulong scause;
302bd023ce3SAlistair Francis 
303bd023ce3SAlistair Francis     target_ulong mtvec;
304d028ac75SAnup Patel     target_ulong mepc;
305e231ec8fSVadim Shakirov     target_ulong mcause;
306bd023ce3SAlistair Francis     target_ulong mtval;  /* since: priv-1.10.0 */
307bd023ce3SAlistair Francis 
308bd023ce3SAlistair Francis     /* Machine and Supervisor interrupt priorities */
309cd032fe7SAnup Patel     uint8_t miprio[64];
310cd032fe7SAnup Patel     uint8_t siprio[64];
311c6957248SAnup Patel 
31240336d5bSRajnesh Kanwal     /* AIA CSRs */
31340336d5bSRajnesh Kanwal     target_ulong miselect;
31440336d5bSRajnesh Kanwal     target_ulong siselect;
31540336d5bSRajnesh Kanwal     uint64_t mvien;
31640336d5bSRajnesh Kanwal     uint64_t mvip;
31740336d5bSRajnesh Kanwal 
31840336d5bSRajnesh Kanwal     /* Hypervisor CSRs */
31940336d5bSRajnesh Kanwal     target_ulong hstatus;
320bd023ce3SAlistair Francis     target_ulong hedeleg;
32143dc93afSAnup Patel     uint64_t hideleg;
3222b602398SAnup Patel     uint32_t hcounteren;
32343dc93afSAnup Patel     target_ulong htval;
32443dc93afSAnup Patel     target_ulong htinst;
3252c64ab66SFrédéric Pétrot     target_ulong hgatp;
3262c64ab66SFrédéric Pétrot     target_ulong hgeie;
3272c64ab66SFrédéric Pétrot     target_ulong hgeip;
3282c64ab66SFrédéric Pétrot     uint64_t htimedelta;
329bd023ce3SAlistair Francis     uint64_t hvien;
330284d697cSYifei Jiang 
331284d697cSYifei Jiang     /*
332284d697cSYifei Jiang      * Bits VSSIP, VSTIP and VSEIP in hvip are maintained in mip. Other bits
333284d697cSYifei Jiang      * from 0:12 are reserved. Bits 13:63 are not aliased and must be separately
334284d697cSYifei Jiang      * maintain in hvip.
335bd023ce3SAlistair Francis      */
336bd023ce3SAlistair Francis     uint64_t hvip;
337bd023ce3SAlistair Francis 
338bd023ce3SAlistair Francis     /* Hypervisor controlled virtual interrupt priorities */
339bd023ce3SAlistair Francis     target_ulong hvictl;
340bd023ce3SAlistair Francis     uint8_t hviprio[64];
341bd023ce3SAlistair Francis 
342d1ceff40SAnup Patel     /* Upper 64-bits of 128-bit CSRs */
343d1ceff40SAnup Patel     uint64_t mscratchh;
344d1ceff40SAnup Patel     uint64_t sscratchh;
345bd023ce3SAlistair Francis 
346bd023ce3SAlistair Francis     /* Virtual CSRs */
347bd023ce3SAlistair Francis     /*
34866e594f2SAlistair Francis      * For RV32 this is 32-bit vsstatus and 32-bit vsstatush.
34966e594f2SAlistair Francis      * For RV64 this is a 64-bit vsstatus.
35066e594f2SAlistair Francis      */
35166e594f2SAlistair Francis     uint64_t vsstatus;
35266e594f2SAlistair Francis     target_ulong vstvec;
35366e594f2SAlistair Francis     target_ulong vsscratch;
35466e594f2SAlistair Francis     target_ulong vsepc;
355284d697cSYifei Jiang     target_ulong vscause;
35666e594f2SAlistair Francis     target_ulong vstval;
3573b57254dSWeiwei Li     target_ulong vsatp;
3583b57254dSWeiwei Li 
3593b57254dSWeiwei Li     /* AIA VS-mode CSRs */
3603b57254dSWeiwei Li     target_ulong vsiselect;
361ec352d0cSGeorg Kotheimer 
3628e2aa21bSAnup Patel     target_ulong mtval2;
3638e2aa21bSAnup Patel     target_ulong mtinst;
3648e2aa21bSAnup Patel 
3658e2aa21bSAnup Patel     /* HS Backup CSRs */
3668e2aa21bSAnup Patel     target_ulong stvec_hs;
367ec352d0cSGeorg Kotheimer     target_ulong sscratch_hs;
368e231ec8fSVadim Shakirov     target_ulong sepc_hs;
369e231ec8fSVadim Shakirov     target_ulong scause_hs;
370dc5bd18fSMichael Clark     target_ulong stval_hs;
371e231ec8fSVadim Shakirov     target_ulong satp_hs;
372b1675eebSAtish Patra     uint64_t mstatus_hs;
3736d1e3893SKaiwen Xue 
3746d1e3893SKaiwen Xue     /*
3756d1e3893SKaiwen Xue      * Signals whether the current exception occurred with two-stage address
3766d1e3893SKaiwen Xue      * translation active.
3776d1e3893SKaiwen Xue      */
3786d1e3893SKaiwen Xue     bool two_stage_lookup;
3793780e337SAtish Patra     /*
3803780e337SAtish Patra      * Signals whether the current exception occurred while doing two-stage
381621f35bbSAtish Patra      * address translation for the VS-stage page table walk.
3823780e337SAtish Patra      */
383621f35bbSAtish Patra     bool two_stage_indirect_lookup;
384621f35bbSAtish Patra 
38514664483SAtish Patra     uint32_t scounteren;
38614664483SAtish Patra     uint32_t mcounteren;
38714664483SAtish Patra 
388b2d7a7c7SAtish Patra     uint32_t mcountinhibit;
389b2d7a7c7SAtish Patra 
390dc5bd18fSMichael Clark     /* PMU cycle & instret privilege mode filtering */
391dc5bd18fSMichael Clark     target_ulong mcyclecfg;
392dc5bd18fSMichael Clark     target_ulong mcyclecfgh;
39343888c2fSAtish Patra     target_ulong minstretcfg;
39443888c2fSAtish Patra     target_ulong minstretcfgh;
39543888c2fSAtish Patra 
3963ec0fe18SAtish Patra     /* PMU counter state */
3973ec0fe18SAtish Patra     PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
398dc5bd18fSMichael Clark 
399dc5bd18fSMichael Clark     /* PMU event selector configured values. First three are unused */
4002582a95cSHou Weiying     target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
401753e3fe2SJim Wilson 
40295799e36SBin Meng     /* PMU event selector configured values for RV32 */
40395799e36SBin Meng     target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
4049495c488SFrank Chang 
4059495c488SFrank Chang     PMUFixedCtrState pmu_fixed_ctrs[2];
4069495c488SFrank Chang 
4070c4e579aSAlvin Chang     target_ulong sscratch;
4089495c488SFrank Chang     target_ulong mscratch;
4099495c488SFrank Chang 
4105a4ae64cSLIU Zhiwei     /* Sstc CSRs */
4115a4ae64cSLIU Zhiwei     uint64_t stimecmp;
412577f0286SLIU Zhiwei 
41395799e36SBin Meng     uint64_t vstimecmp;
414c6957248SAnup Patel 
415e2f01f3cSFrank Chang     /* physical memory protection */
416e2f01f3cSFrank Chang     pmp_table_t pmp_state;
417c6957248SAnup Patel     target_ulong mseccfg;
41869077dd6SAnup Patel 
41969077dd6SAnup Patel     /* trigger module */
42069077dd6SAnup Patel     target_ulong trigger_cur;
42169077dd6SAnup Patel     target_ulong tdata1[RV_MAX_TRIGGERS];
42269077dd6SAnup Patel     target_ulong tdata2[RV_MAX_TRIGGERS];
42369077dd6SAnup Patel     target_ulong tdata3[RV_MAX_TRIGGERS];
42469077dd6SAnup Patel     target_ulong mcontext;
42569077dd6SAnup Patel     struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
42669077dd6SAnup Patel     struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
42769077dd6SAnup Patel     QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
42869077dd6SAnup Patel     int64_t last_icount;
42969077dd6SAnup Patel     bool itrigger_enabled;
43069077dd6SAnup Patel 
43169077dd6SAnup Patel     /* machine specific rdtime callback */
43269077dd6SAnup Patel     uint64_t (*rdtime_fn)(void *);
43369077dd6SAnup Patel     void *rdtime_fn_arg;
434753e3fe2SJim Wilson 
435753e3fe2SJim Wilson     /* machine specific AIA ireg read-modify-write callback */
4364bbe8033SAlexey Baturo #define AIA_MAKE_IREG(__isel, __priv, __virt, __vgein, __xlen) \
4374bbe8033SAlexey Baturo     ((((__xlen) & 0xff) << 24) | \
4384bbe8033SAlexey Baturo      (((__vgein) & 0x3f) << 20) | \
4394bbe8033SAlexey Baturo      (((__virt) & 0x1) << 18) | \
4404bbe8033SAlexey Baturo      (((__priv) & 0x3) << 16) | \
4414bbe8033SAlexey Baturo      (__isel & 0xffff))
4424bbe8033SAlexey Baturo #define AIA_IREG_ISEL(__ireg)                  ((__ireg) & 0xffff)
4434bbe8033SAlexey Baturo #define AIA_IREG_PRIV(__ireg)                  (((__ireg) >> 16) & 0x3)
4444bbe8033SAlexey Baturo #define AIA_IREG_VIRT(__ireg)                  (((__ireg) >> 18) & 0x1)
4454bbe8033SAlexey Baturo #define AIA_IREG_VGEIN(__ireg)                 (((__ireg) >> 20) & 0x3f)
4464bbe8033SAlexey Baturo #define AIA_IREG_XLEN(__ireg)                  (((__ireg) >> 24) & 0xff)
44729a9ec9bSAtish Patra     int (*aia_ireg_rmw_fn[4])(void *arg, target_ulong reg,
44842fe7499SMichael Tokarev         target_ulong *val, target_ulong new_val, target_ulong write_mask);
44929a9ec9bSAtish Patra     void *aia_ireg_rmw_fn_arg[4];
4503bee0e40SMayuresh Chitale 
4513bee0e40SMayuresh Chitale     /* True if in debugger mode.  */
4523bee0e40SMayuresh Chitale     bool debugger;
45329a9ec9bSAtish Patra 
45429a9ec9bSAtish Patra     /*
455dc5bd18fSMichael Clark      * CSRs for PointerMasking extension
45640bfa5f6SLIU Zhiwei      */
45740bfa5f6SLIU Zhiwei     target_ulong mmte;
458dc5bd18fSMichael Clark     target_ulong mpmmask;
459dc5bd18fSMichael Clark     target_ulong mpmbase;
46043888c2fSAtish Patra     target_ulong spmmask;
4613ec0fe18SAtish Patra     target_ulong spmbase;
4623ec0fe18SAtish Patra     target_ulong upmmask;
463ad40be27SYifei Jiang     target_ulong upmbase;
464ad40be27SYifei Jiang 
465ad40be27SYifei Jiang     uint64_t mstateen[SMSTATEEN_MAX_COUNT];
46627abe66fSYifei Jiang     uint64_t hstateen[SMSTATEEN_MAX_COUNT];
4679638cbdeSPhilippe Mathieu-Daudé     uint64_t sstateen[SMSTATEEN_MAX_COUNT];
46827abe66fSYifei Jiang     uint64_t henvcfg;
46927abe66fSYifei Jiang #endif
47027abe66fSYifei Jiang     target_ulong cur_pmmask;
47127abe66fSYifei Jiang     target_ulong cur_pmbase;
47227abe66fSYifei Jiang 
47327abe66fSYifei Jiang     /* Fields from here on are preserved across CPU reset. */
4749638cbdeSPhilippe Mathieu-Daudé     QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
475dc5bd18fSMichael Clark     QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
476dc5bd18fSMichael Clark     bool vstime_irq;
4776f23aaebSAlexandre Ghiti 
478466292bdSPhilipp Tomsich     hwaddr kernel_addr;
479466292bdSPhilipp Tomsich     hwaddr fdt_addr;
480466292bdSPhilipp Tomsich 
481466292bdSPhilipp Tomsich #ifdef CONFIG_KVM
482466292bdSPhilipp Tomsich     /* kvm timer */
483b36e239eSPhilippe Mathieu-Daudé     bool kvm_timer_dirty;
484466292bdSPhilipp Tomsich     uint64_t kvm_timer_time;
4853b3d7df5SRichard Henderson     uint64_t kvm_timer_compare;
486466292bdSPhilipp Tomsich     uint64_t kvm_timer_state;
487466292bdSPhilipp Tomsich     uint64_t kvm_timer_frequency;
48833a24910SAkihiko Odaki #endif /* CONFIG_KVM */
48933a24910SAkihiko Odaki };
490466292bdSPhilipp Tomsich 
491466292bdSPhilipp Tomsich /*
492466292bdSPhilipp Tomsich  * RISCVCPU:
49314664483SAtish Patra  * @env: #CPURISCVState
49414664483SAtish Patra  *
49514664483SAtish Patra  * A RISCV CPU.
49614664483SAtish Patra  */
49714664483SAtish Patra struct ArchCPU {
49814664483SAtish Patra     CPUState parent_obj;
4998c8a7cd6SHuang Tao 
500db1015e9SEduardo Habkost     CPURISCVState env;
501dc5bd18fSMichael Clark 
5029348028eSPhilippe Mathieu-Daudé     GDBFeature dyn_csr_feature;
5039348028eSPhilippe Mathieu-Daudé     GDBFeature dyn_vreg_feature;
5049348028eSPhilippe Mathieu-Daudé 
5059348028eSPhilippe Mathieu-Daudé     /* Configuration Settings */
5069348028eSPhilippe Mathieu-Daudé     RISCVCPUConfig cfg;
5079348028eSPhilippe Mathieu-Daudé 
5089348028eSPhilippe Mathieu-Daudé     QEMUTimer *pmu_timer;
5099348028eSPhilippe Mathieu-Daudé     /* A bitmask of Available programmable counters */
5109348028eSPhilippe Mathieu-Daudé     uint32_t pmu_avail_ctrs;
5119348028eSPhilippe Mathieu-Daudé     /* Mapping of events to counters */
5129348028eSPhilippe Mathieu-Daudé     GHashTable *pmu_event_ctr_map;
5139348028eSPhilippe Mathieu-Daudé     const GPtrArray *decoders;
514742cc269SAkihiko Odaki };
5159348028eSPhilippe Mathieu-Daudé 
5169348028eSPhilippe Mathieu-Daudé /**
517dc5bd18fSMichael Clark  * RISCVCPUClass:
518dc5bd18fSMichael Clark  * @parent_realize: The parent class' realize handler.
519e91a7227SRichard Henderson  * @parent_phases: The parent class' reset phase handlers.
520dc5bd18fSMichael Clark  *
521dc5bd18fSMichael Clark  * A RISCV CPU model.
522dc5bd18fSMichael Clark  */
523dc5bd18fSMichael Clark struct RISCVCPUClass {
524dc5bd18fSMichael Clark     CPUClass parent_class;
5252b547084SFrédéric Pétrot 
526dc5bd18fSMichael Clark     DeviceRealize parent_realize;
527dc5bd18fSMichael Clark     ResettablePhases parent_phases;
528c51a3f5dSYifei Jiang     uint32_t misa_mxl_max;  /* max mxl for this cpu */
52943a96588SYifei Jiang };
5301af0006aSJanosch Frank 
riscv_has_ext(CPURISCVState * env,target_ulong ext)53143a96588SYifei Jiang static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
5321af0006aSJanosch Frank {
533a010bdbeSAlex Bennée     return (env->misa_ext & ext) != 0;
534dc5bd18fSMichael Clark }
53543dc93afSAnup Patel 
53643dc93afSAnup Patel #include "cpu_user.h"
5378f42415fSAndrew Bresticker 
53843dc93afSAnup Patel extern const char * const riscv_int_regnames[];
53943dc93afSAnup Patel extern const char * const riscv_int_regnamesh[];
54043dc93afSAnup Patel extern const char * const riscv_fpr_regnames[];
541b345b480SAlistair Francis 
542cd032fe7SAnup Patel const char *riscv_cpu_get_trap_name(target_ulong cause, bool async);
543cd032fe7SAnup Patel int riscv_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
54461b4b69dSLIU Zhiwei                                int cpuid, DumpState *s);
545ef6bb7b6SAlistair Francis int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
5467f6f2ebbSRichard Henderson                                int cpuid, DumpState *s);
5478905770bSMarc-André Lureau int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
548246f8796SWeiwei Li int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
549246f8796SWeiwei Li int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero);
5508a4ca3c1SRichard Henderson uint8_t riscv_cpu_default_priority(int irq);
5518a4ca3c1SRichard Henderson uint64_t riscv_cpu_all_pending(CPURISCVState *env);
5528a4ca3c1SRichard Henderson int riscv_cpu_mirq_pending(CPURISCVState *env);
553dc5bd18fSMichael Clark int riscv_cpu_sirq_pending(CPURISCVState *env);
554afa42c21SConor Dooley int riscv_cpu_vsirq_pending(CPURISCVState *env);
555bbef9140SDaniel Henrique Barboza bool riscv_cpu_fp_enabled(CPURISCVState *env);
556dc5bd18fSMichael Clark target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
55785ba724fSMichael Clark void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
5582dd31749SPhilippe Mathieu-Daudé bool riscv_cpu_vector_enabled(CPURISCVState *env);
5591c8e491cSConor Dooley void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
560d90ebc47SPhilippe Mathieu-Daudé int riscv_env_mmu_index(CPURISCVState *env, bool ifetch);
561d90ebc47SPhilippe Mathieu-Daudé bool cpu_get_fcfien(CPURISCVState *env);
562d90ebc47SPhilippe Mathieu-Daudé bool cpu_get_bcfien(CPURISCVState *env);
563d90ebc47SPhilippe Mathieu-Daudé G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
564d90ebc47SPhilippe Mathieu-Daudé                                                MMUAccessType access_type,
5656d2d454aSPhilippe Mathieu-Daudé                                                int mmu_idx, uintptr_t retaddr);
56617b3c353SPhilippe Mathieu-Daudé bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
56766e594f2SAlistair Francis                         MMUAccessType access_type, int mmu_idx,
568d028ac75SAnup Patel                         bool probe, uintptr_t retaddr);
569bbb9fc25SWeiwei Li char *riscv_isa_string(RISCVCPU *cpu);
570bbb9fc25SWeiwei Li int riscv_cpu_max_xlen(RISCVCPUClass *mcc);
5711ebad505SRajnesh Kanwal bool riscv_cpu_option_set(const char *optname);
57285ba724fSMichael Clark 
573e2f01f3cSFrank Chang #ifndef CONFIG_USER_ONLY
574e2f01f3cSFrank Chang void riscv_cpu_do_interrupt(CPUState *cpu);
57569077dd6SAnup Patel void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename);
57669077dd6SAnup Patel void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
57769077dd6SAnup Patel                                      vaddr addr, unsigned size,
57869077dd6SAnup Patel                                      MMUAccessType access_type,
57969077dd6SAnup Patel                                      int mmu_idx, MemTxAttrs attrs,
58069077dd6SAnup Patel                                      MemTxResult response, uintptr_t retaddr);
58169077dd6SAnup Patel hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
582ce3af0bbSWeiwei Li bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
583ce3af0bbSWeiwei Li void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
5842dd31749SPhilippe Mathieu-Daudé int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts);
5852dd31749SPhilippe Mathieu-Daudé uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask,
58668c05fb5SRajnesh Kanwal                               uint64_t value);
587dc5bd18fSMichael Clark void riscv_cpu_interrupt(CPURISCVState *env);
588dc5bd18fSMichael Clark #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
5898905770bSMarc-André Lureau void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
590dc5bd18fSMichael Clark                              void *arg);
591dc5bd18fSMichael Clark void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
592fb738839SMichael Clark                                    int (*rmw_fn)(void *arg,
593fb738839SMichael Clark                                                  target_ulong reg,
594dc5bd18fSMichael Clark                                                  target_ulong *val,
5952b7168fcSLIU Zhiwei                                                  target_ulong new_val,
5962b7168fcSLIU Zhiwei                                                  target_ulong write_mask),
59761d56494SFrank Chang                                    void *rmw_fn_arg);
598ebd47648SLIU Zhiwei 
599ebd47648SLIU Zhiwei RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
600ebd47648SLIU Zhiwei #endif /* !CONFIG_USER_ONLY */
601ebd47648SLIU Zhiwei 
602ebd47648SLIU Zhiwei void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en);
603ebd47648SLIU Zhiwei 
604ebd47648SLIU Zhiwei void riscv_translate_init(void);
6050f58cbbeSRichard Henderson G_NORETURN void riscv_raise_exception(CPURISCVState *env,
60692371bd9SRichard Henderson                                       uint32_t exception, uintptr_t pc);
60725f3ddffSRichard Henderson 
6080774a7a1SAnatoly Parshintsev target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
60925f3ddffSRichard Henderson void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
61025f3ddffSRichard Henderson 
61125f3ddffSRichard Henderson #include "exec/cpu-all.h"
61225f3ddffSRichard Henderson 
6132c9d7471SLIU Zhiwei FIELD(TB_FLAGS, MEM_IDX, 0, 3)
61425f3ddffSRichard Henderson FIELD(TB_FLAGS, FS, 3, 2)
615f1966390SLIU Zhiwei /* Vector flags */
61625f3ddffSRichard Henderson FIELD(TB_FLAGS, VS, 5, 2)
6170f58cbbeSRichard Henderson FIELD(TB_FLAGS, LMUL, 7, 3)
6183a610f54SWeiwei Li FIELD(TB_FLAGS, SEW, 10, 3)
6192b7168fcSLIU Zhiwei FIELD(TB_FLAGS, VL_EQ_VLMAX, 13, 1)
620db23e5d9SRichard Henderson FIELD(TB_FLAGS, VILL, 14, 1)
621db23e5d9SRichard Henderson FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1)
622db23e5d9SRichard Henderson /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
623db23e5d9SRichard Henderson FIELD(TB_FLAGS, XL, 16, 2)
624db23e5d9SRichard Henderson /* If PointerMasking should be applied */
625db23e5d9SRichard Henderson FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1)
626db23e5d9SRichard Henderson FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1)
627db23e5d9SRichard Henderson FIELD(TB_FLAGS, VTA, 20, 1)
6282b602398SAnup Patel FIELD(TB_FLAGS, VMA, 21, 1)
62951ae0cabSAlistair Francis /* Native debug itrigger */
630d4ea7117SDaniel Henrique Barboza FIELD(TB_FLAGS, ITRIGGER, 22, 1)
631d4ea7117SDaniel Henrique Barboza /* Virtual mode enabled */
632d4ea7117SDaniel Henrique Barboza FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
633d4ea7117SDaniel Henrique Barboza FIELD(TB_FLAGS, PRIV, 24, 2)
634d4ea7117SDaniel Henrique Barboza FIELD(TB_FLAGS, AXL, 26, 2)
6353a610f54SWeiwei Li /* zicfilp needs a TB flag to track indirect branches */
6363a610f54SWeiwei Li FIELD(TB_FLAGS, FCFI_ENABLED, 28, 1)
6373a610f54SWeiwei Li FIELD(TB_FLAGS, FCFI_LP_EXPECTED, 29, 1)
6383a610f54SWeiwei Li /* zicfiss needs a TB flag so that correct TB is located based on tb flags */
6393a610f54SWeiwei Li FIELD(TB_FLAGS, BCFI_ENABLED, 30, 1)
6403a610f54SWeiwei Li 
6413a610f54SWeiwei Li #ifdef TARGET_RISCV32
6423a610f54SWeiwei Li #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
6433a610f54SWeiwei Li #else
6443a610f54SWeiwei Li static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
6453a610f54SWeiwei Li {
6463a610f54SWeiwei Li     return env->misa_mxl;
647440544e1SLIU Zhiwei }
648440544e1SLIU Zhiwei #endif
649440544e1SLIU Zhiwei #define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env)))
650440544e1SLIU Zhiwei 
riscv_cpu_cfg(CPURISCVState * env)651440544e1SLIU Zhiwei static inline const RISCVCPUConfig *riscv_cpu_cfg(CPURISCVState *env)
652440544e1SLIU Zhiwei {
653440544e1SLIU Zhiwei     return &env_archcpu(env)->cfg;
654440544e1SLIU Zhiwei }
655440544e1SLIU Zhiwei 
6563a610f54SWeiwei Li #if !defined(CONFIG_USER_ONLY)
cpu_address_mode(CPURISCVState * env)657440544e1SLIU Zhiwei static inline int cpu_address_mode(CPURISCVState *env)
658440544e1SLIU Zhiwei {
659440544e1SLIU Zhiwei     int mode = env->priv;
660440544e1SLIU Zhiwei 
661440544e1SLIU Zhiwei     if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
66244b8f74bSWeiwei Li         mode = get_field(env->mstatus, MSTATUS_MPP);
663440544e1SLIU Zhiwei     }
664440544e1SLIU Zhiwei     return mode;
665440544e1SLIU Zhiwei }
666440544e1SLIU Zhiwei 
cpu_get_xl(CPURISCVState * env,target_ulong mode)667440544e1SLIU Zhiwei static inline RISCVMXL cpu_get_xl(CPURISCVState *env, target_ulong mode)
668440544e1SLIU Zhiwei {
669440544e1SLIU Zhiwei     RISCVMXL xl = env->misa_mxl;
670440544e1SLIU Zhiwei     /*
6713a610f54SWeiwei Li      * When emulating a 32-bit-only cpu, use RV32.
6723a610f54SWeiwei Li      * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
6733a610f54SWeiwei Li      * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
6743a610f54SWeiwei Li      * back to RV64 for lower privs.
6753a610f54SWeiwei Li      */
6763a610f54SWeiwei Li     if (xl != MXL_RV32) {
6773a610f54SWeiwei Li         switch (mode) {
6783a610f54SWeiwei Li         case PRV_M:
6793a610f54SWeiwei Li             break;
6803a610f54SWeiwei Li         case PRV_U:
6813a610f54SWeiwei Li             xl = get_field(env->mstatus, MSTATUS64_UXL);
6823a610f54SWeiwei Li             break;
6833a610f54SWeiwei Li         default: /* PRV_S */
6843a610f54SWeiwei Li             xl = get_field(env->mstatus, MSTATUS64_SXL);
6853a610f54SWeiwei Li             break;
6863a610f54SWeiwei Li         }
6873a610f54SWeiwei Li     }
6883a610f54SWeiwei Li     return xl;
6893a610f54SWeiwei Li }
6903a610f54SWeiwei Li #endif
6913a610f54SWeiwei Li 
6923a610f54SWeiwei Li #if defined(TARGET_RISCV32)
6933a610f54SWeiwei Li #define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
6943a610f54SWeiwei Li #else
cpu_recompute_xl(CPURISCVState * env)6953a610f54SWeiwei Li static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
6963a610f54SWeiwei Li {
6973a610f54SWeiwei Li #if !defined(CONFIG_USER_ONLY)
6983a610f54SWeiwei Li     return cpu_get_xl(env, env->priv);
69931961cfeSLIU Zhiwei #else
70031961cfeSLIU Zhiwei     return env->misa_mxl;
70131961cfeSLIU Zhiwei #endif
70231961cfeSLIU Zhiwei }
70331961cfeSLIU Zhiwei #endif
70405e6ca5eSGuo Ren 
70505e6ca5eSGuo Ren #if defined(TARGET_RISCV32)
70605e6ca5eSGuo Ren #define cpu_address_xl(env)  ((void)(env), MXL_RV32)
70705e6ca5eSGuo Ren #else
cpu_address_xl(CPURISCVState * env)70805e6ca5eSGuo Ren static inline RISCVMXL cpu_address_xl(CPURISCVState *env)
70905e6ca5eSGuo Ren {
71005e6ca5eSGuo Ren #ifdef CONFIG_USER_ONLY
71105e6ca5eSGuo Ren     return env->xl;
712*1c627d72STANG Tiancheng #else
71305e6ca5eSGuo Ren     int mode = cpu_address_mode(env);
714*1c627d72STANG Tiancheng 
71505e6ca5eSGuo Ren     return cpu_get_xl(env, mode);
716*1c627d72STANG Tiancheng #endif
71705e6ca5eSGuo Ren }
71805e6ca5eSGuo Ren #endif
71905e6ca5eSGuo Ren 
riscv_cpu_xlen(CPURISCVState * env)7202b7168fcSLIU Zhiwei static inline int riscv_cpu_xlen(CPURISCVState *env)
721a689a82bSFrank Chang {
722a689a82bSFrank Chang     return 16 << env->xl;
723a689a82bSFrank Chang }
724a689a82bSFrank Chang 
725a689a82bSFrank Chang #ifdef TARGET_RISCV32
726a689a82bSFrank Chang #define riscv_cpu_sxl(env)  ((void)(env), MXL_RV32)
727a689a82bSFrank Chang #else
riscv_cpu_sxl(CPURISCVState * env)728a689a82bSFrank Chang static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
729a689a82bSFrank Chang {
730a689a82bSFrank Chang #ifdef CONFIG_USER_ONLY
731a689a82bSFrank Chang     return env->misa_mxl;
732a689a82bSFrank Chang #else
733a689a82bSFrank Chang     if (env->misa_mxl != MXL_RV32) {
734a689a82bSFrank Chang         return get_field(env->mstatus, MSTATUS64_SXL);
735a689a82bSFrank Chang     }
736a689a82bSFrank Chang #endif
7372b7168fcSLIU Zhiwei     return MXL_RV32;
738cd21576dSDaniel Henrique Barboza }
739cd21576dSDaniel Henrique Barboza #endif
740dc5bd18fSMichael Clark 
741cd21576dSDaniel Henrique Barboza /*
74224a6aeecSDaniel Henrique Barboza  * Encode LMUL to lmul as follows:
74324a6aeecSDaniel Henrique Barboza  *     LMUL    vlmul    lmul
74424a6aeecSDaniel Henrique Barboza  *      1       000       0
74524a6aeecSDaniel Henrique Barboza  *      2       001       1
74624a6aeecSDaniel Henrique Barboza  *      4       010       2
74724a6aeecSDaniel Henrique Barboza  *      8       011       3
74824a6aeecSDaniel Henrique Barboza  *      -       100       -
7492b7168fcSLIU Zhiwei  *     1/8      101      -3
7502b7168fcSLIU Zhiwei  *     1/4      110      -2
751bb5de525SAnton Johansson  *     1/2      111      -1
752bb5de525SAnton Johansson  *
753dc5bd18fSMichael Clark  * then, we can calculate VLMAX = vlen >> (vsew + 3 - lmul)
75440bfa5f6SLIU Zhiwei  * e.g. vlen = 256 bits, SEW = 16, LMUL = 1/8
755e7acc1cbSDaniel Henrique Barboza  *      => VLMAX = vlen >> (1 + 3 - (-3))
75640bfa5f6SLIU Zhiwei  *               = 256 >> 7
75738c83e8dSYu-Ming Chang  *               = 2
75838c83e8dSYu-Ming Chang  */
vext_get_vlmax(uint32_t vlenb,uint32_t vsew,int8_t lmul)759533c91e8SAlistair Francis static inline uint32_t vext_get_vlmax(uint32_t vlenb, uint32_t vsew,
760533c91e8SAlistair Francis                                       int8_t lmul)
761c7b95171SMichael Clark {
762533c91e8SAlistair Francis     uint32_t vlen = vlenb << 3;
763533c91e8SAlistair Francis 
764533c91e8SAlistair Francis     /*
765533c91e8SAlistair Francis      * We need to use 'vlen' instead of 'vlenb' to
766c7b95171SMichael Clark      * preserve the '+ 3' in the formula. Otherwise
767fb738839SMichael Clark      * we risk a negative shift if vsew < lmul.
768fb738839SMichael Clark      */
769c7b95171SMichael Clark     return vlen >> (vsew + 3 - lmul);
770c7b95171SMichael Clark }
771c7b95171SMichael Clark 
772c7b95171SMichael Clark void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
773fb738839SMichael Clark                           uint64_t *cs_base, uint32_t *pflags);
774c7b95171SMichael Clark 
775c7b95171SMichael Clark void riscv_cpu_update_mask(CPURISCVState *env);
776c7b95171SMichael Clark bool riscv_cpu_is_32bit(RISCVCPU *cpu);
777c7b95171SMichael Clark 
778c7b95171SMichael Clark RISCVException riscv_csrr(CPURISCVState *env, int csrno,
779c7b95171SMichael Clark                           target_ulong *ret_value);
7800e62f92eSAlistair Francis RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
7810e62f92eSAlistair Francis                            target_ulong *ret_value,
782605def6eSAlistair Francis                            target_ulong new_value, target_ulong write_mask);
783c7b95171SMichael Clark RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
784605def6eSAlistair Francis                                  target_ulong *ret_value,
785c7b95171SMichael Clark                                  target_ulong new_value,
786605def6eSAlistair Francis                                  target_ulong write_mask);
787605def6eSAlistair Francis 
riscv_csr_write(CPURISCVState * env,int csrno,target_ulong val)788605def6eSAlistair Francis static inline void riscv_csr_write(CPURISCVState *env, int csrno,
789605def6eSAlistair Francis                                    target_ulong val)
790c7b95171SMichael Clark {
79138c83e8dSYu-Ming Chang     riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
79238c83e8dSYu-Ming Chang }
793961738ffSFrédéric Pétrot 
riscv_csr_read(CPURISCVState * env,int csrno)794961738ffSFrédéric Pétrot static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
795961738ffSFrédéric Pétrot {
796961738ffSFrédéric Pétrot     target_ulong val = 0;
797457c360fSFrédéric Pétrot     riscv_csrrw(env, csrno, &val, 0, 0);
798457c360fSFrédéric Pétrot     return val;
799457c360fSFrédéric Pétrot }
800457c360fSFrédéric Pétrot 
801457c360fSFrédéric Pétrot typedef RISCVException (*riscv_csr_predicate_fn)(CPURISCVState *env,
802c7b95171SMichael Clark                                                  int csrno);
8038ceac5dcSBin Meng typedef RISCVException (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
804a88365c1SMichael Clark                                             target_ulong *ret_value);
805c7b95171SMichael Clark typedef RISCVException (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
806c7b95171SMichael Clark                                              target_ulong new_value);
807c7b95171SMichael Clark typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
808457c360fSFrédéric Pétrot                                           target_ulong *ret_value,
809457c360fSFrédéric Pétrot                                           target_ulong new_value,
810a4b2fa43SAtish Patra                                           target_ulong write_mask);
811a4b2fa43SAtish Patra 
812c7b95171SMichael Clark RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
813c7b95171SMichael Clark                                Int128 *ret_value);
81456118ee8SBin Meng RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
81556118ee8SBin Meng                                 Int128 *ret_value,
81656118ee8SBin Meng                                 Int128 new_value, Int128 write_mask);
81756118ee8SBin Meng 
81856118ee8SBin Meng typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
8193b57254dSWeiwei Li                                                Int128 *ret_value);
82014664483SAtish Patra typedef RISCVException (*riscv_csr_write128_fn)(CPURISCVState *env, int csrno,
82114664483SAtish Patra                                              Int128 new_value);
82214664483SAtish Patra 
82314664483SAtish Patra typedef struct {
82414664483SAtish Patra     const char *name;
82514664483SAtish Patra     riscv_csr_predicate_fn predicate;
82614664483SAtish Patra     riscv_csr_read_fn read;
82714664483SAtish Patra     riscv_csr_write_fn write;
82814664483SAtish Patra     riscv_csr_op_fn op;
82914664483SAtish Patra     riscv_csr_read128_fn read128;
83014664483SAtish Patra     riscv_csr_write128_fn write128;
83114664483SAtish Patra     /* The default priv spec version should be PRIV_VERSION_1_10_0 (i.e 0) */
83236c1118dSDaniel Henrique Barboza     uint32_t min_priv_ver;
83336c1118dSDaniel Henrique Barboza } riscv_csr_operations;
83436c1118dSDaniel Henrique Barboza 
835742cc269SAkihiko Odaki /* CSR function table constants */
836b62b86a1SDaniel Henrique Barboza enum {
83736c1118dSDaniel Henrique Barboza     CSR_TABLE_SIZE = 0x1000
83832fa1776SDaniel Henrique Barboza };
83932fa1776SDaniel Henrique Barboza 
84032fa1776SDaniel Henrique Barboza /*
84132fa1776SDaniel Henrique Barboza  * The event id are encoded based on the encoding specified in the
84232fa1776SDaniel Henrique Barboza  * SBI specification v0.3
84332fa1776SDaniel Henrique Barboza  */
84432fa1776SDaniel Henrique Barboza 
84532fa1776SDaniel Henrique Barboza enum riscv_pmu_event_idx {
84632fa1776SDaniel Henrique Barboza     RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
8475fe2800bSDaniel Henrique Barboza     RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
8488043effdSDaniel Henrique Barboza     RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
84932fa1776SDaniel Henrique Barboza     RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
8507935e2c4SDaniel Henrique Barboza     RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
8517935e2c4SDaniel Henrique Barboza };
8527935e2c4SDaniel Henrique Barboza 
8537935e2c4SDaniel Henrique Barboza /* used by tcg/tcg-cpu.c*/
8547935e2c4SDaniel Henrique Barboza void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en);
8557935e2c4SDaniel Henrique Barboza bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset);
856b933720bSDaniel Henrique Barboza void riscv_cpu_set_misa_ext(CPURISCVState *env, uint32_t ext);
8577935e2c4SDaniel Henrique Barboza bool riscv_cpu_is_vendor(Object *cpu_obj);
858a13a6082SDaniel Henrique Barboza 
8597d0c302cSDaniel Henrique Barboza typedef struct RISCVCPUMultiExtConfig {
860ef58fad0SDaniel Henrique Barboza     const char *name;
86132fa1776SDaniel Henrique Barboza     uint32_t offset;
86256118ee8SBin Meng     bool enabled;
8636f03770dSBin Meng } RISCVCPUMultiExtConfig;
86456118ee8SBin Meng 
8656f23aaebSAlexandre Ghiti extern const RISCVCPUMultiExtConfig riscv_cpu_extensions[];
8666f23aaebSAlexandre Ghiti extern const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[];
867c7b95171SMichael Clark extern const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[];
868c7b95171SMichael Clark extern const RISCVCPUMultiExtConfig riscv_cpu_named_features[];
869dc5bd18fSMichael Clark extern const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[];
8705371f5cdSJim Wilson 
8715371f5cdSJim Wilson typedef struct isa_ext_data {
87286997772SAndrew Jones     const char *name;
87386997772SAndrew Jones     int min_version;
87486997772SAndrew Jones     int ext_enable_offset;
8756f23aaebSAlexandre Ghiti } RISCVIsaExtData;
8766f23aaebSAlexandre Ghiti extern const RISCVIsaExtData isa_edata_arr[];
8776f23aaebSAlexandre Ghiti char *riscv_cpu_get_name(RISCVCPU *cpu);
878fd53ee26SChristoph Müllner 
879fd53ee26SChristoph Müllner void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
880fd53ee26SChristoph Müllner void riscv_add_satp_mode_properties(Object *obj);
881a1a8e776SJim Shu bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu);
882dc5bd18fSMichael Clark 
883 /* CSR function table */
884 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
885 
886 extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
887 
888 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
889 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
890 
891 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
892 
893 target_ulong riscv_new_csr_seed(target_ulong new_value,
894                                 target_ulong write_mask);
895 
896 uint8_t satp_mode_max_from_map(uint32_t map);
897 const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
898 
899 /* Implemented in th_csr.c */
900 void th_register_custom_csrs(RISCVCPU *cpu);
901 
902 const char *priv_spec_to_str(int priv_version);
903 #endif /* RISCV_CPU_H */
904