xref: /qemu/target/loongarch/cpu.h (revision d97c3b06de5bdd885f0ee3d8153326acd3db480e)
1228021f0SSong Gao /* SPDX-License-Identifier: GPL-2.0-or-later */
2228021f0SSong Gao /*
3228021f0SSong Gao  * QEMU LoongArch CPU
4228021f0SSong Gao  *
5228021f0SSong Gao  * Copyright (c) 2021 Loongson Technology Corporation Limited
6228021f0SSong Gao  */
7228021f0SSong Gao 
8228021f0SSong Gao #ifndef LOONGARCH_CPU_H
9228021f0SSong Gao #define LOONGARCH_CPU_H
10228021f0SSong Gao 
1116f5396cSSong Gao #include "qemu/int128.h"
12*d97c3b06SPierrick Bouvier #include "exec/cpu-common.h"
13228021f0SSong Gao #include "exec/cpu-defs.h"
1422a7c2f2SPierrick Bouvier #include "exec/cpu-interrupt.h"
15228021f0SSong Gao #include "fpu/softfloat-types.h"
16228021f0SSong Gao #include "hw/registerfields.h"
17dd615fa4SXiaojuan Yang #include "qemu/timer.h"
188f15d617SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY
198be545baSRichard Henderson #include "system/memory.h"
208f15d617SPhilippe Mathieu-Daudé #endif
21b4bda200SRui Wang #include "cpu-csr.h"
22edcea147SPhilippe Mathieu-Daudé #include "cpu-qom.h"
23f84a2aacSXiaojuan Yang 
24f84a2aacSXiaojuan Yang #define IOCSRF_TEMP             0
25f84a2aacSXiaojuan Yang #define IOCSRF_NODECNT          1
26f84a2aacSXiaojuan Yang #define IOCSRF_MSI              2
27f84a2aacSXiaojuan Yang #define IOCSRF_EXTIOI           3
28f84a2aacSXiaojuan Yang #define IOCSRF_CSRIPI           4
29f84a2aacSXiaojuan Yang #define IOCSRF_FREQCSR          5
30f84a2aacSXiaojuan Yang #define IOCSRF_FREQSCALE        6
31f84a2aacSXiaojuan Yang #define IOCSRF_DVFSV1           7
32f84a2aacSXiaojuan Yang #define IOCSRF_GMOD             9
33f84a2aacSXiaojuan Yang #define IOCSRF_VM               11
34f84a2aacSXiaojuan Yang 
35c77432d0SSong Gao #define VERSION_REG             0x0
36f84a2aacSXiaojuan Yang #define FEATURE_REG             0x8
37f84a2aacSXiaojuan Yang #define VENDOR_REG              0x10
38f84a2aacSXiaojuan Yang #define CPUNAME_REG             0x20
39f84a2aacSXiaojuan Yang #define MISC_FUNC_REG           0x420
40f84a2aacSXiaojuan Yang #define IOCSRM_EXTIOI_EN        48
412b284fa9SSong Gao #define IOCSRM_EXTIOI_INT_ENCODE 49
42f84a2aacSXiaojuan Yang 
43f84a2aacSXiaojuan Yang #define IOCSR_MEM_SIZE          0x428
44228021f0SSong Gao 
45228021f0SSong Gao #define FCSR0_M1    0x1f         /* FCSR1 mask, Enables */
46228021f0SSong Gao #define FCSR0_M2    0x1f1f0000   /* FCSR2 mask, Cause and Flags */
47228021f0SSong Gao #define FCSR0_M3    0x300        /* FCSR3 mask, Round Mode */
48228021f0SSong Gao #define FCSR0_RM    8            /* Round Mode bit num on fcsr0 */
49228021f0SSong Gao 
50228021f0SSong Gao FIELD(FCSR0, ENABLES, 0, 5)
51228021f0SSong Gao FIELD(FCSR0, RM, 8, 2)
52228021f0SSong Gao FIELD(FCSR0, FLAGS, 16, 5)
53228021f0SSong Gao FIELD(FCSR0, CAUSE, 24, 5)
54228021f0SSong Gao 
55228021f0SSong Gao #define GET_FP_CAUSE(REG)      FIELD_EX32(REG, FCSR0, CAUSE)
5600952d93SQi Hu #define SET_FP_CAUSE(REG, V) \
5700952d93SQi Hu     do { \
5800952d93SQi Hu         (REG) = FIELD_DP32(REG, FCSR0, CAUSE, V); \
5900952d93SQi Hu     } while (0)
60aca67472SSong Gao #define UPDATE_FP_CAUSE(REG, V) \
61aca67472SSong Gao     do { \
62aca67472SSong Gao         (REG) |= FIELD_DP32(0, FCSR0, CAUSE, V); \
63aca67472SSong Gao     } while (0)
6400952d93SQi Hu 
65228021f0SSong Gao #define GET_FP_ENABLES(REG)    FIELD_EX32(REG, FCSR0, ENABLES)
6600952d93SQi Hu #define SET_FP_ENABLES(REG, V) \
6700952d93SQi Hu     do { \
6800952d93SQi Hu         (REG) = FIELD_DP32(REG, FCSR0, ENABLES, V); \
6900952d93SQi Hu     } while (0)
7000952d93SQi Hu 
71228021f0SSong Gao #define GET_FP_FLAGS(REG)      FIELD_EX32(REG, FCSR0, FLAGS)
7200952d93SQi Hu #define SET_FP_FLAGS(REG, V) \
7300952d93SQi Hu     do { \
7400952d93SQi Hu         (REG) = FIELD_DP32(REG, FCSR0, FLAGS, V); \
7500952d93SQi Hu     } while (0)
7600952d93SQi Hu 
77228021f0SSong Gao #define UPDATE_FP_FLAGS(REG, V) \
78228021f0SSong Gao     do { \
79228021f0SSong Gao         (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \
80228021f0SSong Gao     } while (0)
81228021f0SSong Gao 
82228021f0SSong Gao #define FP_INEXACT        1
83228021f0SSong Gao #define FP_UNDERFLOW      2
84228021f0SSong Gao #define FP_OVERFLOW       4
85228021f0SSong Gao #define FP_DIV0           8
86228021f0SSong Gao #define FP_INVALID        16
87228021f0SSong Gao 
88a6b129c8SSong Gao #define EXCODE(code, subcode) ( ((subcode) << 6) | (code) )
89a6b129c8SSong Gao #define EXCODE_MCODE(code)    ( (code) & 0x3f )
90a6b129c8SSong Gao #define EXCODE_SUBCODE(code)  ( (code) >> 6 )
91a6b129c8SSong Gao 
92228021f0SSong Gao #define  EXCCODE_EXTERNAL_INT        64   /* plus external interrupt number */
93a6b129c8SSong Gao #define  EXCCODE_INT                 EXCODE(0, 0)
94a6b129c8SSong Gao #define  EXCCODE_PIL                 EXCODE(1, 0)
95a6b129c8SSong Gao #define  EXCCODE_PIS                 EXCODE(2, 0)
96a6b129c8SSong Gao #define  EXCCODE_PIF                 EXCODE(3, 0)
97a6b129c8SSong Gao #define  EXCCODE_PME                 EXCODE(4, 0)
98a6b129c8SSong Gao #define  EXCCODE_PNR                 EXCODE(5, 0)
99a6b129c8SSong Gao #define  EXCCODE_PNX                 EXCODE(6, 0)
100a6b129c8SSong Gao #define  EXCCODE_PPI                 EXCODE(7, 0)
101a6b129c8SSong Gao #define  EXCCODE_ADEF                EXCODE(8, 0) /* Different exception subcode */
102a6b129c8SSong Gao #define  EXCCODE_ADEM                EXCODE(8, 1)
103a6b129c8SSong Gao #define  EXCCODE_ALE                 EXCODE(9, 0)
104a6b129c8SSong Gao #define  EXCCODE_BCE                 EXCODE(10, 0)
105a6b129c8SSong Gao #define  EXCCODE_SYS                 EXCODE(11, 0)
106a6b129c8SSong Gao #define  EXCCODE_BRK                 EXCODE(12, 0)
107a6b129c8SSong Gao #define  EXCCODE_INE                 EXCODE(13, 0)
108a6b129c8SSong Gao #define  EXCCODE_IPE                 EXCODE(14, 0)
109a6b129c8SSong Gao #define  EXCCODE_FPD                 EXCODE(15, 0)
110a6b129c8SSong Gao #define  EXCCODE_SXD                 EXCODE(16, 0)
111a6b129c8SSong Gao #define  EXCCODE_ASXD                EXCODE(17, 0)
112a6b129c8SSong Gao #define  EXCCODE_FPE                 EXCODE(18, 0) /* Different exception subcode */
113a6b129c8SSong Gao #define  EXCCODE_VFPE                EXCODE(18, 1)
114a6b129c8SSong Gao #define  EXCCODE_WPEF                EXCODE(19, 0) /* Different exception subcode */
115a6b129c8SSong Gao #define  EXCCODE_WPEM                EXCODE(19, 1)
116a6b129c8SSong Gao #define  EXCCODE_BTD                 EXCODE(20, 0)
117a6b129c8SSong Gao #define  EXCCODE_BTE                 EXCODE(21, 0)
118a6b129c8SSong Gao #define  EXCCODE_DBP                 EXCODE(26, 0) /* Reserved subcode used for debug */
119228021f0SSong Gao 
120228021f0SSong Gao /* cpucfg[0] bits */
121228021f0SSong Gao FIELD(CPUCFG0, PRID, 0, 32)
122228021f0SSong Gao 
123228021f0SSong Gao /* cpucfg[1] bits */
124228021f0SSong Gao FIELD(CPUCFG1, ARCH, 0, 2)
125228021f0SSong Gao FIELD(CPUCFG1, PGMMU, 2, 1)
126228021f0SSong Gao FIELD(CPUCFG1, IOCSR, 3, 1)
127228021f0SSong Gao FIELD(CPUCFG1, PALEN, 4, 8)
128228021f0SSong Gao FIELD(CPUCFG1, VALEN, 12, 8)
129228021f0SSong Gao FIELD(CPUCFG1, UAL, 20, 1)
130228021f0SSong Gao FIELD(CPUCFG1, RI, 21, 1)
131228021f0SSong Gao FIELD(CPUCFG1, EP, 22, 1)
132228021f0SSong Gao FIELD(CPUCFG1, RPLV, 23, 1)
133228021f0SSong Gao FIELD(CPUCFG1, HP, 24, 1)
134228021f0SSong Gao FIELD(CPUCFG1, IOCSR_BRD, 25, 1)
135228021f0SSong Gao FIELD(CPUCFG1, MSG_INT, 26, 1)
136228021f0SSong Gao 
13719f82a4aSJiajie Chen /* cpucfg[1].arch */
13819f82a4aSJiajie Chen #define CPUCFG1_ARCH_LA32R       0
13919f82a4aSJiajie Chen #define CPUCFG1_ARCH_LA32        1
14019f82a4aSJiajie Chen #define CPUCFG1_ARCH_LA64        2
14119f82a4aSJiajie Chen 
142228021f0SSong Gao /* cpucfg[2] bits */
143228021f0SSong Gao FIELD(CPUCFG2, FP, 0, 1)
144228021f0SSong Gao FIELD(CPUCFG2, FP_SP, 1, 1)
145228021f0SSong Gao FIELD(CPUCFG2, FP_DP, 2, 1)
146228021f0SSong Gao FIELD(CPUCFG2, FP_VER, 3, 3)
147228021f0SSong Gao FIELD(CPUCFG2, LSX, 6, 1)
148228021f0SSong Gao FIELD(CPUCFG2, LASX, 7, 1)
149228021f0SSong Gao FIELD(CPUCFG2, COMPLEX, 8, 1)
150228021f0SSong Gao FIELD(CPUCFG2, CRYPTO, 9, 1)
151228021f0SSong Gao FIELD(CPUCFG2, LVZ, 10, 1)
152228021f0SSong Gao FIELD(CPUCFG2, LVZ_VER, 11, 3)
153228021f0SSong Gao FIELD(CPUCFG2, LLFTP, 14, 1)
154228021f0SSong Gao FIELD(CPUCFG2, LLFTP_VER, 15, 3)
155228021f0SSong Gao FIELD(CPUCFG2, LBT_X86, 18, 1)
156228021f0SSong Gao FIELD(CPUCFG2, LBT_ARM, 19, 1)
157228021f0SSong Gao FIELD(CPUCFG2, LBT_MIPS, 20, 1)
158c23a53d8SBibo Mao FIELD(CPUCFG2, LBT_ALL, 18, 3)
159228021f0SSong Gao FIELD(CPUCFG2, LSPW, 21, 1)
160228021f0SSong Gao FIELD(CPUCFG2, LAM, 22, 1)
161228021f0SSong Gao 
162228021f0SSong Gao /* cpucfg[3] bits */
163228021f0SSong Gao FIELD(CPUCFG3, CCDMA, 0, 1)
164228021f0SSong Gao FIELD(CPUCFG3, SFB, 1, 1)
165228021f0SSong Gao FIELD(CPUCFG3, UCACC, 2, 1)
166228021f0SSong Gao FIELD(CPUCFG3, LLEXC, 3, 1)
167228021f0SSong Gao FIELD(CPUCFG3, SCDLY, 4, 1)
168228021f0SSong Gao FIELD(CPUCFG3, LLDBAR, 5, 1)
169228021f0SSong Gao FIELD(CPUCFG3, ITLBHMC, 6, 1)
170228021f0SSong Gao FIELD(CPUCFG3, ICHMC, 7, 1)
171228021f0SSong Gao FIELD(CPUCFG3, SPW_LVL, 8, 3)
172228021f0SSong Gao FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
173228021f0SSong Gao FIELD(CPUCFG3, RVA, 12, 1)
174228021f0SSong Gao FIELD(CPUCFG3, RVAMAX, 13, 4)
175228021f0SSong Gao 
176228021f0SSong Gao /* cpucfg[4] bits */
177228021f0SSong Gao FIELD(CPUCFG4, CC_FREQ, 0, 32)
178228021f0SSong Gao 
179228021f0SSong Gao /* cpucfg[5] bits */
180228021f0SSong Gao FIELD(CPUCFG5, CC_MUL, 0, 16)
181228021f0SSong Gao FIELD(CPUCFG5, CC_DIV, 16, 16)
182228021f0SSong Gao 
183228021f0SSong Gao /* cpucfg[6] bits */
184228021f0SSong Gao FIELD(CPUCFG6, PMP, 0, 1)
185228021f0SSong Gao FIELD(CPUCFG6, PMVER, 1, 3)
186228021f0SSong Gao FIELD(CPUCFG6, PMNUM, 4, 4)
187228021f0SSong Gao FIELD(CPUCFG6, PMBITS, 8, 6)
188228021f0SSong Gao FIELD(CPUCFG6, UPM, 14, 1)
189228021f0SSong Gao 
190228021f0SSong Gao /* cpucfg[16] bits */
191228021f0SSong Gao FIELD(CPUCFG16, L1_IUPRE, 0, 1)
192228021f0SSong Gao FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
193228021f0SSong Gao FIELD(CPUCFG16, L1_DPRE, 2, 1)
194228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRE, 3, 1)
195228021f0SSong Gao FIELD(CPUCFG16, L2_IUUNIFY, 4, 1)
196228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRIV, 5, 1)
197228021f0SSong Gao FIELD(CPUCFG16, L2_IUINCL, 6, 1)
198228021f0SSong Gao FIELD(CPUCFG16, L2_DPRE, 7, 1)
199228021f0SSong Gao FIELD(CPUCFG16, L2_DPRIV, 8, 1)
200228021f0SSong Gao FIELD(CPUCFG16, L2_DINCL, 9, 1)
201228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRE, 10, 1)
202228021f0SSong Gao FIELD(CPUCFG16, L3_IUUNIFY, 11, 1)
203228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRIV, 12, 1)
204228021f0SSong Gao FIELD(CPUCFG16, L3_IUINCL, 13, 1)
205228021f0SSong Gao FIELD(CPUCFG16, L3_DPRE, 14, 1)
206228021f0SSong Gao FIELD(CPUCFG16, L3_DPRIV, 15, 1)
207228021f0SSong Gao FIELD(CPUCFG16, L3_DINCL, 16, 1)
208228021f0SSong Gao 
209228021f0SSong Gao /* cpucfg[17] bits */
210228021f0SSong Gao FIELD(CPUCFG17, L1IU_WAYS, 0, 16)
211228021f0SSong Gao FIELD(CPUCFG17, L1IU_SETS, 16, 8)
212228021f0SSong Gao FIELD(CPUCFG17, L1IU_SIZE, 24, 7)
213228021f0SSong Gao 
214228021f0SSong Gao /* cpucfg[18] bits */
215228021f0SSong Gao FIELD(CPUCFG18, L1D_WAYS, 0, 16)
216228021f0SSong Gao FIELD(CPUCFG18, L1D_SETS, 16, 8)
217228021f0SSong Gao FIELD(CPUCFG18, L1D_SIZE, 24, 7)
218228021f0SSong Gao 
219228021f0SSong Gao /* cpucfg[19] bits */
220228021f0SSong Gao FIELD(CPUCFG19, L2IU_WAYS, 0, 16)
221228021f0SSong Gao FIELD(CPUCFG19, L2IU_SETS, 16, 8)
222228021f0SSong Gao FIELD(CPUCFG19, L2IU_SIZE, 24, 7)
223228021f0SSong Gao 
224228021f0SSong Gao /* cpucfg[20] bits */
225228021f0SSong Gao FIELD(CPUCFG20, L3IU_WAYS, 0, 16)
226228021f0SSong Gao FIELD(CPUCFG20, L3IU_SETS, 16, 8)
227228021f0SSong Gao FIELD(CPUCFG20, L3IU_SIZE, 24, 7)
228228021f0SSong Gao 
229398cecb9SXiaojuan Yang /*CSR_CRMD */
230398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PLV, 0, 2)
231398cecb9SXiaojuan Yang FIELD(CSR_CRMD, IE, 2, 1)
232398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DA, 3, 1)
233398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PG, 4, 1)
234398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATF, 5, 2)
235398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATM, 7, 2)
236398cecb9SXiaojuan Yang FIELD(CSR_CRMD, WE, 9, 1)
237398cecb9SXiaojuan Yang 
238228021f0SSong Gao extern const char * const regnames[32];
239228021f0SSong Gao extern const char * const fregnames[32];
240228021f0SSong Gao 
241f757a2cdSXiaojuan Yang #define N_IRQS      13
242dd615fa4SXiaojuan Yang #define IRQ_TIMER   11
243dd615fa4SXiaojuan Yang #define IRQ_IPI     12
244f757a2cdSXiaojuan Yang 
2457e1c521eSXiaojuan Yang #define LOONGARCH_STLB         2048 /* 2048 STLB */
2467e1c521eSXiaojuan Yang #define LOONGARCH_MTLB         64   /* 64 MTLB */
2477e1c521eSXiaojuan Yang #define LOONGARCH_TLB_MAX      (LOONGARCH_STLB + LOONGARCH_MTLB)
2487e1c521eSXiaojuan Yang 
2497e1c521eSXiaojuan Yang /*
2507e1c521eSXiaojuan Yang  * define the ASID PS E VPPN field of TLB
2517e1c521eSXiaojuan Yang  */
2527e1c521eSXiaojuan Yang FIELD(TLB_MISC, E, 0, 1)
2537e1c521eSXiaojuan Yang FIELD(TLB_MISC, ASID, 1, 10)
2547e1c521eSXiaojuan Yang FIELD(TLB_MISC, VPPN, 13, 35)
2557e1c521eSXiaojuan Yang FIELD(TLB_MISC, PS, 48, 6)
2567e1c521eSXiaojuan Yang 
25716f5396cSSong Gao #define LSX_LEN    (128)
258008a3b16SSong Gao #define LASX_LEN   (256)
259008a3b16SSong Gao 
26016f5396cSSong Gao typedef union VReg {
261008a3b16SSong Gao     int8_t   B[LASX_LEN / 8];
262008a3b16SSong Gao     int16_t  H[LASX_LEN / 16];
263008a3b16SSong Gao     int32_t  W[LASX_LEN / 32];
264008a3b16SSong Gao     int64_t  D[LASX_LEN / 64];
265008a3b16SSong Gao     uint8_t  UB[LASX_LEN / 8];
266008a3b16SSong Gao     uint16_t UH[LASX_LEN / 16];
267008a3b16SSong Gao     uint32_t UW[LASX_LEN / 32];
268008a3b16SSong Gao     uint64_t UD[LASX_LEN / 64];
269008a3b16SSong Gao     Int128   Q[LASX_LEN / 128];
27016f5396cSSong Gao } VReg;
27116f5396cSSong Gao 
27216f5396cSSong Gao typedef union fpr_t fpr_t;
27316f5396cSSong Gao union fpr_t {
27416f5396cSSong Gao     VReg  vreg;
27516f5396cSSong Gao };
27616f5396cSSong Gao 
2776f703a48SBibo Mao #ifdef CONFIG_TCG
2787e1c521eSXiaojuan Yang struct LoongArchTLB {
2797e1c521eSXiaojuan Yang     uint64_t tlb_misc;
2807e1c521eSXiaojuan Yang     /* Fields corresponding to CSR_TLBELO0/1 */
2817e1c521eSXiaojuan Yang     uint64_t tlb_entry0;
2827e1c521eSXiaojuan Yang     uint64_t tlb_entry1;
2837e1c521eSXiaojuan Yang };
2847e1c521eSXiaojuan Yang typedef struct LoongArchTLB LoongArchTLB;
2856f703a48SBibo Mao #endif
2867e1c521eSXiaojuan Yang 
287c23a53d8SBibo Mao enum loongarch_features {
288936c3f4dSBibo Mao     LOONGARCH_FEATURE_LSX,
2895e360dabSBibo Mao     LOONGARCH_FEATURE_LASX,
290c23a53d8SBibo Mao     LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
2916edd2a9bSBibo Mao     LOONGARCH_FEATURE_PMU,
292620d9bd0SBibo Mao     LOONGARCH_FEATURE_PV_IPI,
293954cc5c3SBibo Mao     LOONGARCH_FEATURE_STEALTIME,
294c23a53d8SBibo Mao };
295c23a53d8SBibo Mao 
296a45df286SBibo Mao typedef struct  LoongArchBT {
297a45df286SBibo Mao     /* scratch registers */
298a45df286SBibo Mao     uint64_t scr0;
299a45df286SBibo Mao     uint64_t scr1;
300a45df286SBibo Mao     uint64_t scr2;
301a45df286SBibo Mao     uint64_t scr3;
302a45df286SBibo Mao     /* loongarch eflags */
303a45df286SBibo Mao     uint32_t eflags;
304a45df286SBibo Mao     uint32_t ftop;
305a45df286SBibo Mao } lbt_t;
306a45df286SBibo Mao 
307228021f0SSong Gao typedef struct CPUArchState {
308228021f0SSong Gao     uint64_t gpr[32];
309228021f0SSong Gao     uint64_t pc;
310228021f0SSong Gao 
31116f5396cSSong Gao     fpr_t fpr[32];
312228021f0SSong Gao     bool cf[8];
313228021f0SSong Gao     uint32_t fcsr0;
314a45df286SBibo Mao     lbt_t  lbt;
315228021f0SSong Gao 
316228021f0SSong Gao     uint32_t cpucfg[21];
317620d9bd0SBibo Mao     uint32_t pv_features;
318228021f0SSong Gao 
319398cecb9SXiaojuan Yang     /* LoongArch CSRs */
320398cecb9SXiaojuan Yang     uint64_t CSR_CRMD;
321398cecb9SXiaojuan Yang     uint64_t CSR_PRMD;
322398cecb9SXiaojuan Yang     uint64_t CSR_EUEN;
323398cecb9SXiaojuan Yang     uint64_t CSR_MISC;
324398cecb9SXiaojuan Yang     uint64_t CSR_ECFG;
325398cecb9SXiaojuan Yang     uint64_t CSR_ESTAT;
326398cecb9SXiaojuan Yang     uint64_t CSR_ERA;
327398cecb9SXiaojuan Yang     uint64_t CSR_BADV;
328398cecb9SXiaojuan Yang     uint64_t CSR_BADI;
329398cecb9SXiaojuan Yang     uint64_t CSR_EENTRY;
330398cecb9SXiaojuan Yang     uint64_t CSR_TLBIDX;
331398cecb9SXiaojuan Yang     uint64_t CSR_TLBEHI;
332398cecb9SXiaojuan Yang     uint64_t CSR_TLBELO0;
333398cecb9SXiaojuan Yang     uint64_t CSR_TLBELO1;
334398cecb9SXiaojuan Yang     uint64_t CSR_ASID;
335398cecb9SXiaojuan Yang     uint64_t CSR_PGDL;
336398cecb9SXiaojuan Yang     uint64_t CSR_PGDH;
337398cecb9SXiaojuan Yang     uint64_t CSR_PGD;
338398cecb9SXiaojuan Yang     uint64_t CSR_PWCL;
339398cecb9SXiaojuan Yang     uint64_t CSR_PWCH;
340398cecb9SXiaojuan Yang     uint64_t CSR_STLBPS;
341398cecb9SXiaojuan Yang     uint64_t CSR_RVACFG;
34262784656STianrui Zhao     uint64_t CSR_CPUID;
343398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG1;
344398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG2;
345398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG3;
346398cecb9SXiaojuan Yang     uint64_t CSR_SAVE[16];
347398cecb9SXiaojuan Yang     uint64_t CSR_TID;
348398cecb9SXiaojuan Yang     uint64_t CSR_TCFG;
349398cecb9SXiaojuan Yang     uint64_t CSR_TVAL;
350398cecb9SXiaojuan Yang     uint64_t CSR_CNTC;
351398cecb9SXiaojuan Yang     uint64_t CSR_TICLR;
352398cecb9SXiaojuan Yang     uint64_t CSR_LLBCTL;
353398cecb9SXiaojuan Yang     uint64_t CSR_IMPCTL1;
354398cecb9SXiaojuan Yang     uint64_t CSR_IMPCTL2;
355398cecb9SXiaojuan Yang     uint64_t CSR_TLBRENTRY;
356398cecb9SXiaojuan Yang     uint64_t CSR_TLBRBADV;
357398cecb9SXiaojuan Yang     uint64_t CSR_TLBRERA;
358398cecb9SXiaojuan Yang     uint64_t CSR_TLBRSAVE;
359398cecb9SXiaojuan Yang     uint64_t CSR_TLBRELO0;
360398cecb9SXiaojuan Yang     uint64_t CSR_TLBRELO1;
361398cecb9SXiaojuan Yang     uint64_t CSR_TLBREHI;
362398cecb9SXiaojuan Yang     uint64_t CSR_TLBRPRMD;
363398cecb9SXiaojuan Yang     uint64_t CSR_MERRCTL;
364398cecb9SXiaojuan Yang     uint64_t CSR_MERRINFO1;
365398cecb9SXiaojuan Yang     uint64_t CSR_MERRINFO2;
366398cecb9SXiaojuan Yang     uint64_t CSR_MERRENTRY;
367398cecb9SXiaojuan Yang     uint64_t CSR_MERRERA;
368398cecb9SXiaojuan Yang     uint64_t CSR_MERRSAVE;
369398cecb9SXiaojuan Yang     uint64_t CSR_CTAG;
370398cecb9SXiaojuan Yang     uint64_t CSR_DMW[4];
371398cecb9SXiaojuan Yang     uint64_t CSR_DBG;
372398cecb9SXiaojuan Yang     uint64_t CSR_DERA;
373398cecb9SXiaojuan Yang     uint64_t CSR_DSAVE;
37447b54e15SBibo Mao     struct {
37547b54e15SBibo Mao         uint64_t guest_addr;
37647b54e15SBibo Mao     } stealtime;
3777e1c521eSXiaojuan Yang 
3786f703a48SBibo Mao #ifdef CONFIG_TCG
3796f703a48SBibo Mao     float_status fp_status;
3806f703a48SBibo Mao     uint32_t fcsr0_mask;
3816f703a48SBibo Mao     uint64_t lladdr; /* LL virtual address compared against SC */
3826f703a48SBibo Mao     uint64_t llval;
3836f703a48SBibo Mao #endif
3840093b9a5SSong Gao #ifndef CONFIG_USER_ONLY
3856f703a48SBibo Mao #ifdef CONFIG_TCG
3867e1c521eSXiaojuan Yang     LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
3876f703a48SBibo Mao #endif
388f84a2aacSXiaojuan Yang 
3895e90b8dbSBibo Mao     AddressSpace *address_space_iocsr;
3906a6f26f4SXiaojuan Yang     bool load_elf;
3916a6f26f4SXiaojuan Yang     uint64_t elf_address;
392f8447436STianrui Zhao     uint32_t mp_state;
39358ee60d2SSong Gao 
39458ee60d2SSong Gao     struct loongarch_boot_info *boot_info;
3950093b9a5SSong Gao #endif
396228021f0SSong Gao } CPULoongArchState;
397228021f0SSong Gao 
3988ccf28c2SBibo Mao typedef struct LoongArchCPUTopo {
3998ccf28c2SBibo Mao     int32_t socket_id;  /* socket-id of this VCPU */
4008ccf28c2SBibo Mao     int32_t core_id;    /* core-id of this VCPU */
4018ccf28c2SBibo Mao     int32_t thread_id;  /* thread-id of this VCPU */
4028ccf28c2SBibo Mao } LoongArchCPUTopo;
4038ccf28c2SBibo Mao 
404228021f0SSong Gao /**
405228021f0SSong Gao  * LoongArchCPU:
406228021f0SSong Gao  * @env: #CPULoongArchState
407228021f0SSong Gao  *
408228021f0SSong Gao  * A LoongArch CPU.
409228021f0SSong Gao  */
410228021f0SSong Gao struct ArchCPU {
411228021f0SSong Gao     CPUState parent_obj;
412228021f0SSong Gao 
413228021f0SSong Gao     CPULoongArchState env;
414dd615fa4SXiaojuan Yang     QEMUTimer timer;
41514f21f67SBibo Mao     uint32_t  phy_id;
416c23a53d8SBibo Mao     OnOffAuto lbt;
4176edd2a9bSBibo Mao     OnOffAuto pmu;
418936c3f4dSBibo Mao     OnOffAuto lsx;
4195e360dabSBibo Mao     OnOffAuto lasx;
4205b0502c5SBibo Mao     OnOffAuto kvm_pv_ipi;
421610babceSBibo Mao     OnOffAuto kvm_steal_time;
422d32fde20SBibo Mao     int32_t socket_id;  /* socket-id of this CPU */
423d32fde20SBibo Mao     int32_t core_id;    /* core-id of this CPU */
424d32fde20SBibo Mao     int32_t thread_id;  /* thread-id of this CPU */
425d32fde20SBibo Mao     int32_t node_id;    /* NUMA node of this CPU */
426fda3f15bSXiaojuan Yang 
427fda3f15bSXiaojuan Yang     /* 'compatible' string for this CPU for Linux device trees */
428fda3f15bSXiaojuan Yang     const char *dtb_compatible;
429d11681c9STianrui Zhao     /* used by KVM_REG_LOONGARCH_COUNTER ioctl to access guest time counters */
430d11681c9STianrui Zhao     uint64_t kvm_state_counter;
4310c346576SXianglai Li     VMChangeStateEntry *vmsentry;
432228021f0SSong Gao };
433228021f0SSong Gao 
434228021f0SSong Gao /**
435228021f0SSong Gao  * LoongArchCPUClass:
436228021f0SSong Gao  * @parent_realize: The parent class' realize handler.
437f78b49aeSPeter Maydell  * @parent_phases: The parent class' reset phase handlers.
438228021f0SSong Gao  *
439228021f0SSong Gao  * A LoongArch CPU model.
440228021f0SSong Gao  */
441228021f0SSong Gao struct LoongArchCPUClass {
442228021f0SSong Gao     CPUClass parent_class;
443228021f0SSong Gao 
444228021f0SSong Gao     DeviceRealize parent_realize;
4457bf633c5SBibo Mao     DeviceUnrealize parent_unrealize;
446f78b49aeSPeter Maydell     ResettablePhases parent_phases;
447228021f0SSong Gao };
448228021f0SSong Gao 
4497e1c521eSXiaojuan Yang /*
4507e1c521eSXiaojuan Yang  * LoongArch CPUs has 4 privilege levels.
4517e1c521eSXiaojuan Yang  * 0 for kernel mode, 3 for user mode.
4527e1c521eSXiaojuan Yang  * Define an extra index for DA(direct addressing) mode.
4537e1c521eSXiaojuan Yang  */
454c8885b88SRui Wang #define MMU_PLV_KERNEL   0
455c8885b88SRui Wang #define MMU_PLV_USER     3
4563f262d25SRichard Henderson #define MMU_KERNEL_IDX   MMU_PLV_KERNEL
4573f262d25SRichard Henderson #define MMU_USER_IDX     MMU_PLV_USER
4583f262d25SRichard Henderson #define MMU_DA_IDX       4
4597e1c521eSXiaojuan Yang 
46019f82a4aSJiajie Chen static inline bool is_la64(CPULoongArchState *env)
46119f82a4aSJiajie Chen {
46219f82a4aSJiajie Chen     return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64;
46319f82a4aSJiajie Chen }
46419f82a4aSJiajie Chen 
46539665820SJiajie Chen static inline bool is_va32(CPULoongArchState *env)
46639665820SJiajie Chen {
46739665820SJiajie Chen     /* VA32 if !LA64 or VA32L[1-3] */
46839665820SJiajie Chen     bool va32 = !is_la64(env);
46939665820SJiajie Chen     uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
47039665820SJiajie Chen     if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) {
47139665820SJiajie Chen         va32 = true;
47239665820SJiajie Chen     }
47339665820SJiajie Chen     return va32;
47439665820SJiajie Chen }
47539665820SJiajie Chen 
4762f6478ffSJiajie Chen static inline void set_pc(CPULoongArchState *env, uint64_t value)
4772f6478ffSJiajie Chen {
4787033c0e6SJiajie Chen     if (is_va32(env)) {
4797033c0e6SJiajie Chen         env->pc = (uint32_t)value;
4807033c0e6SJiajie Chen     } else {
4812f6478ffSJiajie Chen         env->pc = value;
4822f6478ffSJiajie Chen     }
4837033c0e6SJiajie Chen }
4842f6478ffSJiajie Chen 
485b4bda200SRui Wang /*
486b4bda200SRui Wang  * LoongArch CPUs hardware flags.
487b4bda200SRui Wang  */
488b4bda200SRui Wang #define HW_FLAGS_PLV_MASK   R_CSR_CRMD_PLV_MASK  /* 0x03 */
4892419978cSRui Wang #define HW_FLAGS_EUEN_FPE   0x04
490a3f3db5cSSong Gao #define HW_FLAGS_EUEN_SXE   0x08
49132f4916cSJiajie Chen #define HW_FLAGS_CRMD_PG    R_CSR_CRMD_PG_MASK   /* 0x10 */
49239665820SJiajie Chen #define HW_FLAGS_VA32       0x20
49332f4916cSJiajie Chen #define HW_FLAGS_EUEN_ASXE  0x40
494b4bda200SRui Wang 
495bb5de525SAnton Johansson static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
496bb5de525SAnton Johansson                                         uint64_t *cs_base, uint32_t *flags)
4977e1c521eSXiaojuan Yang {
4987e1c521eSXiaojuan Yang     *pc = env->pc;
4997e1c521eSXiaojuan Yang     *cs_base = 0;
500b4bda200SRui Wang     *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
5012419978cSRui Wang     *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
502a3f3db5cSSong Gao     *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE;
503b8f1bdf3SSong Gao     *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE;
50439665820SJiajie Chen     *flags |= is_va32(env) * HW_FLAGS_VA32;
5057e1c521eSXiaojuan Yang }
5067e1c521eSXiaojuan Yang 
507228021f0SSong Gao #include "exec/cpu-all.h"
508228021f0SSong Gao 
509228021f0SSong Gao #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
510228021f0SSong Gao 
511464136ceSSong Gao void loongarch_cpu_post_init(Object *obj);
512464136ceSSong Gao 
5133406b001SBibo Mao #ifdef CONFIG_KVM
5143406b001SBibo Mao void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu);
5153406b001SBibo Mao #else
5163406b001SBibo Mao static inline void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
5173406b001SBibo Mao {
5183406b001SBibo Mao }
5193406b001SBibo Mao #endif
5203406b001SBibo Mao 
521228021f0SSong Gao #endif /* LOONGARCH_CPU_H */
522