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"
12228021f0SSong Gao #include "exec/cpu-defs.h"
13228021f0SSong Gao #include "fpu/softfloat-types.h"
14228021f0SSong Gao #include "hw/registerfields.h"
15dd615fa4SXiaojuan Yang #include "qemu/timer.h"
168f15d617SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY
17f84a2aacSXiaojuan Yang #include "exec/memory.h"
188f15d617SPhilippe Mathieu-Daudé #endif
19b4bda200SRui Wang #include "cpu-csr.h"
20edcea147SPhilippe Mathieu-Daudé #include "cpu-qom.h"
21f84a2aacSXiaojuan Yang
22f84a2aacSXiaojuan Yang #define IOCSRF_TEMP 0
23f84a2aacSXiaojuan Yang #define IOCSRF_NODECNT 1
24f84a2aacSXiaojuan Yang #define IOCSRF_MSI 2
25f84a2aacSXiaojuan Yang #define IOCSRF_EXTIOI 3
26f84a2aacSXiaojuan Yang #define IOCSRF_CSRIPI 4
27f84a2aacSXiaojuan Yang #define IOCSRF_FREQCSR 5
28f84a2aacSXiaojuan Yang #define IOCSRF_FREQSCALE 6
29f84a2aacSXiaojuan Yang #define IOCSRF_DVFSV1 7
30f84a2aacSXiaojuan Yang #define IOCSRF_GMOD 9
31f84a2aacSXiaojuan Yang #define IOCSRF_VM 11
32f84a2aacSXiaojuan Yang
33c77432d0SSong Gao #define VERSION_REG 0x0
34f84a2aacSXiaojuan Yang #define FEATURE_REG 0x8
35f84a2aacSXiaojuan Yang #define VENDOR_REG 0x10
36f84a2aacSXiaojuan Yang #define CPUNAME_REG 0x20
37f84a2aacSXiaojuan Yang #define MISC_FUNC_REG 0x420
38f84a2aacSXiaojuan Yang #define IOCSRM_EXTIOI_EN 48
392b284fa9SSong Gao #define IOCSRM_EXTIOI_INT_ENCODE 49
40f84a2aacSXiaojuan Yang
41f84a2aacSXiaojuan Yang #define IOCSR_MEM_SIZE 0x428
42228021f0SSong Gao
43228021f0SSong Gao #define FCSR0_M1 0x1f /* FCSR1 mask, Enables */
44228021f0SSong Gao #define FCSR0_M2 0x1f1f0000 /* FCSR2 mask, Cause and Flags */
45228021f0SSong Gao #define FCSR0_M3 0x300 /* FCSR3 mask, Round Mode */
46228021f0SSong Gao #define FCSR0_RM 8 /* Round Mode bit num on fcsr0 */
47228021f0SSong Gao
48228021f0SSong Gao FIELD(FCSR0, ENABLES, 0, 5)
49228021f0SSong Gao FIELD(FCSR0, RM, 8, 2)
50228021f0SSong Gao FIELD(FCSR0, FLAGS, 16, 5)
51228021f0SSong Gao FIELD(FCSR0, CAUSE, 24, 5)
52228021f0SSong Gao
53228021f0SSong Gao #define GET_FP_CAUSE(REG) FIELD_EX32(REG, FCSR0, CAUSE)
5400952d93SQi Hu #define SET_FP_CAUSE(REG, V) \
5500952d93SQi Hu do { \
5600952d93SQi Hu (REG) = FIELD_DP32(REG, FCSR0, CAUSE, V); \
5700952d93SQi Hu } while (0)
58aca67472SSong Gao #define UPDATE_FP_CAUSE(REG, V) \
59aca67472SSong Gao do { \
60aca67472SSong Gao (REG) |= FIELD_DP32(0, FCSR0, CAUSE, V); \
61aca67472SSong Gao } while (0)
6200952d93SQi Hu
63228021f0SSong Gao #define GET_FP_ENABLES(REG) FIELD_EX32(REG, FCSR0, ENABLES)
6400952d93SQi Hu #define SET_FP_ENABLES(REG, V) \
6500952d93SQi Hu do { \
6600952d93SQi Hu (REG) = FIELD_DP32(REG, FCSR0, ENABLES, V); \
6700952d93SQi Hu } while (0)
6800952d93SQi Hu
69228021f0SSong Gao #define GET_FP_FLAGS(REG) FIELD_EX32(REG, FCSR0, FLAGS)
7000952d93SQi Hu #define SET_FP_FLAGS(REG, V) \
7100952d93SQi Hu do { \
7200952d93SQi Hu (REG) = FIELD_DP32(REG, FCSR0, FLAGS, V); \
7300952d93SQi Hu } while (0)
7400952d93SQi Hu
75228021f0SSong Gao #define UPDATE_FP_FLAGS(REG, V) \
76228021f0SSong Gao do { \
77228021f0SSong Gao (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \
78228021f0SSong Gao } while (0)
79228021f0SSong Gao
80228021f0SSong Gao #define FP_INEXACT 1
81228021f0SSong Gao #define FP_UNDERFLOW 2
82228021f0SSong Gao #define FP_OVERFLOW 4
83228021f0SSong Gao #define FP_DIV0 8
84228021f0SSong Gao #define FP_INVALID 16
85228021f0SSong Gao
86a6b129c8SSong Gao #define EXCODE(code, subcode) ( ((subcode) << 6) | (code) )
87a6b129c8SSong Gao #define EXCODE_MCODE(code) ( (code) & 0x3f )
88a6b129c8SSong Gao #define EXCODE_SUBCODE(code) ( (code) >> 6 )
89a6b129c8SSong Gao
90228021f0SSong Gao #define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */
91a6b129c8SSong Gao #define EXCCODE_INT EXCODE(0, 0)
92a6b129c8SSong Gao #define EXCCODE_PIL EXCODE(1, 0)
93a6b129c8SSong Gao #define EXCCODE_PIS EXCODE(2, 0)
94a6b129c8SSong Gao #define EXCCODE_PIF EXCODE(3, 0)
95a6b129c8SSong Gao #define EXCCODE_PME EXCODE(4, 0)
96a6b129c8SSong Gao #define EXCCODE_PNR EXCODE(5, 0)
97a6b129c8SSong Gao #define EXCCODE_PNX EXCODE(6, 0)
98a6b129c8SSong Gao #define EXCCODE_PPI EXCODE(7, 0)
99a6b129c8SSong Gao #define EXCCODE_ADEF EXCODE(8, 0) /* Different exception subcode */
100a6b129c8SSong Gao #define EXCCODE_ADEM EXCODE(8, 1)
101a6b129c8SSong Gao #define EXCCODE_ALE EXCODE(9, 0)
102a6b129c8SSong Gao #define EXCCODE_BCE EXCODE(10, 0)
103a6b129c8SSong Gao #define EXCCODE_SYS EXCODE(11, 0)
104a6b129c8SSong Gao #define EXCCODE_BRK EXCODE(12, 0)
105a6b129c8SSong Gao #define EXCCODE_INE EXCODE(13, 0)
106a6b129c8SSong Gao #define EXCCODE_IPE EXCODE(14, 0)
107a6b129c8SSong Gao #define EXCCODE_FPD EXCODE(15, 0)
108a6b129c8SSong Gao #define EXCCODE_SXD EXCODE(16, 0)
109a6b129c8SSong Gao #define EXCCODE_ASXD EXCODE(17, 0)
110a6b129c8SSong Gao #define EXCCODE_FPE EXCODE(18, 0) /* Different exception subcode */
111a6b129c8SSong Gao #define EXCCODE_VFPE EXCODE(18, 1)
112a6b129c8SSong Gao #define EXCCODE_WPEF EXCODE(19, 0) /* Different exception subcode */
113a6b129c8SSong Gao #define EXCCODE_WPEM EXCODE(19, 1)
114a6b129c8SSong Gao #define EXCCODE_BTD EXCODE(20, 0)
115a6b129c8SSong Gao #define EXCCODE_BTE EXCODE(21, 0)
116a6b129c8SSong Gao #define EXCCODE_DBP EXCODE(26, 0) /* Reserved subcode used for debug */
117228021f0SSong Gao
118228021f0SSong Gao /* cpucfg[0] bits */
119228021f0SSong Gao FIELD(CPUCFG0, PRID, 0, 32)
120228021f0SSong Gao
121228021f0SSong Gao /* cpucfg[1] bits */
122228021f0SSong Gao FIELD(CPUCFG1, ARCH, 0, 2)
123228021f0SSong Gao FIELD(CPUCFG1, PGMMU, 2, 1)
124228021f0SSong Gao FIELD(CPUCFG1, IOCSR, 3, 1)
125228021f0SSong Gao FIELD(CPUCFG1, PALEN, 4, 8)
126228021f0SSong Gao FIELD(CPUCFG1, VALEN, 12, 8)
127228021f0SSong Gao FIELD(CPUCFG1, UAL, 20, 1)
128228021f0SSong Gao FIELD(CPUCFG1, RI, 21, 1)
129228021f0SSong Gao FIELD(CPUCFG1, EP, 22, 1)
130228021f0SSong Gao FIELD(CPUCFG1, RPLV, 23, 1)
131228021f0SSong Gao FIELD(CPUCFG1, HP, 24, 1)
132228021f0SSong Gao FIELD(CPUCFG1, IOCSR_BRD, 25, 1)
133228021f0SSong Gao FIELD(CPUCFG1, MSG_INT, 26, 1)
134228021f0SSong Gao
13519f82a4aSJiajie Chen /* cpucfg[1].arch */
13619f82a4aSJiajie Chen #define CPUCFG1_ARCH_LA32R 0
13719f82a4aSJiajie Chen #define CPUCFG1_ARCH_LA32 1
13819f82a4aSJiajie Chen #define CPUCFG1_ARCH_LA64 2
13919f82a4aSJiajie Chen
140228021f0SSong Gao /* cpucfg[2] bits */
141228021f0SSong Gao FIELD(CPUCFG2, FP, 0, 1)
142228021f0SSong Gao FIELD(CPUCFG2, FP_SP, 1, 1)
143228021f0SSong Gao FIELD(CPUCFG2, FP_DP, 2, 1)
144228021f0SSong Gao FIELD(CPUCFG2, FP_VER, 3, 3)
145228021f0SSong Gao FIELD(CPUCFG2, LSX, 6, 1)
146228021f0SSong Gao FIELD(CPUCFG2, LASX, 7, 1)
147228021f0SSong Gao FIELD(CPUCFG2, COMPLEX, 8, 1)
148228021f0SSong Gao FIELD(CPUCFG2, CRYPTO, 9, 1)
149228021f0SSong Gao FIELD(CPUCFG2, LVZ, 10, 1)
150228021f0SSong Gao FIELD(CPUCFG2, LVZ_VER, 11, 3)
151228021f0SSong Gao FIELD(CPUCFG2, LLFTP, 14, 1)
152228021f0SSong Gao FIELD(CPUCFG2, LLFTP_VER, 15, 3)
153228021f0SSong Gao FIELD(CPUCFG2, LBT_X86, 18, 1)
154228021f0SSong Gao FIELD(CPUCFG2, LBT_ARM, 19, 1)
155228021f0SSong Gao FIELD(CPUCFG2, LBT_MIPS, 20, 1)
156c23a53d8SBibo Mao FIELD(CPUCFG2, LBT_ALL, 18, 3)
157228021f0SSong Gao FIELD(CPUCFG2, LSPW, 21, 1)
158228021f0SSong Gao FIELD(CPUCFG2, LAM, 22, 1)
159228021f0SSong Gao
160228021f0SSong Gao /* cpucfg[3] bits */
161228021f0SSong Gao FIELD(CPUCFG3, CCDMA, 0, 1)
162228021f0SSong Gao FIELD(CPUCFG3, SFB, 1, 1)
163228021f0SSong Gao FIELD(CPUCFG3, UCACC, 2, 1)
164228021f0SSong Gao FIELD(CPUCFG3, LLEXC, 3, 1)
165228021f0SSong Gao FIELD(CPUCFG3, SCDLY, 4, 1)
166228021f0SSong Gao FIELD(CPUCFG3, LLDBAR, 5, 1)
167228021f0SSong Gao FIELD(CPUCFG3, ITLBHMC, 6, 1)
168228021f0SSong Gao FIELD(CPUCFG3, ICHMC, 7, 1)
169228021f0SSong Gao FIELD(CPUCFG3, SPW_LVL, 8, 3)
170228021f0SSong Gao FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
171228021f0SSong Gao FIELD(CPUCFG3, RVA, 12, 1)
172228021f0SSong Gao FIELD(CPUCFG3, RVAMAX, 13, 4)
173228021f0SSong Gao
174228021f0SSong Gao /* cpucfg[4] bits */
175228021f0SSong Gao FIELD(CPUCFG4, CC_FREQ, 0, 32)
176228021f0SSong Gao
177228021f0SSong Gao /* cpucfg[5] bits */
178228021f0SSong Gao FIELD(CPUCFG5, CC_MUL, 0, 16)
179228021f0SSong Gao FIELD(CPUCFG5, CC_DIV, 16, 16)
180228021f0SSong Gao
181228021f0SSong Gao /* cpucfg[6] bits */
182228021f0SSong Gao FIELD(CPUCFG6, PMP, 0, 1)
183228021f0SSong Gao FIELD(CPUCFG6, PMVER, 1, 3)
184228021f0SSong Gao FIELD(CPUCFG6, PMNUM, 4, 4)
185228021f0SSong Gao FIELD(CPUCFG6, PMBITS, 8, 6)
186228021f0SSong Gao FIELD(CPUCFG6, UPM, 14, 1)
187228021f0SSong Gao
188228021f0SSong Gao /* cpucfg[16] bits */
189228021f0SSong Gao FIELD(CPUCFG16, L1_IUPRE, 0, 1)
190228021f0SSong Gao FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
191228021f0SSong Gao FIELD(CPUCFG16, L1_DPRE, 2, 1)
192228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRE, 3, 1)
193228021f0SSong Gao FIELD(CPUCFG16, L2_IUUNIFY, 4, 1)
194228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRIV, 5, 1)
195228021f0SSong Gao FIELD(CPUCFG16, L2_IUINCL, 6, 1)
196228021f0SSong Gao FIELD(CPUCFG16, L2_DPRE, 7, 1)
197228021f0SSong Gao FIELD(CPUCFG16, L2_DPRIV, 8, 1)
198228021f0SSong Gao FIELD(CPUCFG16, L2_DINCL, 9, 1)
199228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRE, 10, 1)
200228021f0SSong Gao FIELD(CPUCFG16, L3_IUUNIFY, 11, 1)
201228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRIV, 12, 1)
202228021f0SSong Gao FIELD(CPUCFG16, L3_IUINCL, 13, 1)
203228021f0SSong Gao FIELD(CPUCFG16, L3_DPRE, 14, 1)
204228021f0SSong Gao FIELD(CPUCFG16, L3_DPRIV, 15, 1)
205228021f0SSong Gao FIELD(CPUCFG16, L3_DINCL, 16, 1)
206228021f0SSong Gao
207228021f0SSong Gao /* cpucfg[17] bits */
208228021f0SSong Gao FIELD(CPUCFG17, L1IU_WAYS, 0, 16)
209228021f0SSong Gao FIELD(CPUCFG17, L1IU_SETS, 16, 8)
210228021f0SSong Gao FIELD(CPUCFG17, L1IU_SIZE, 24, 7)
211228021f0SSong Gao
212228021f0SSong Gao /* cpucfg[18] bits */
213228021f0SSong Gao FIELD(CPUCFG18, L1D_WAYS, 0, 16)
214228021f0SSong Gao FIELD(CPUCFG18, L1D_SETS, 16, 8)
215228021f0SSong Gao FIELD(CPUCFG18, L1D_SIZE, 24, 7)
216228021f0SSong Gao
217228021f0SSong Gao /* cpucfg[19] bits */
218228021f0SSong Gao FIELD(CPUCFG19, L2IU_WAYS, 0, 16)
219228021f0SSong Gao FIELD(CPUCFG19, L2IU_SETS, 16, 8)
220228021f0SSong Gao FIELD(CPUCFG19, L2IU_SIZE, 24, 7)
221228021f0SSong Gao
222228021f0SSong Gao /* cpucfg[20] bits */
223228021f0SSong Gao FIELD(CPUCFG20, L3IU_WAYS, 0, 16)
224228021f0SSong Gao FIELD(CPUCFG20, L3IU_SETS, 16, 8)
225228021f0SSong Gao FIELD(CPUCFG20, L3IU_SIZE, 24, 7)
226228021f0SSong Gao
227398cecb9SXiaojuan Yang /*CSR_CRMD */
228398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PLV, 0, 2)
229398cecb9SXiaojuan Yang FIELD(CSR_CRMD, IE, 2, 1)
230398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DA, 3, 1)
231398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PG, 4, 1)
232398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATF, 5, 2)
233398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATM, 7, 2)
234398cecb9SXiaojuan Yang FIELD(CSR_CRMD, WE, 9, 1)
235398cecb9SXiaojuan Yang
236228021f0SSong Gao extern const char * const regnames[32];
237228021f0SSong Gao extern const char * const fregnames[32];
238228021f0SSong Gao
239f757a2cdSXiaojuan Yang #define N_IRQS 13
240dd615fa4SXiaojuan Yang #define IRQ_TIMER 11
241dd615fa4SXiaojuan Yang #define IRQ_IPI 12
242f757a2cdSXiaojuan Yang
2437e1c521eSXiaojuan Yang #define LOONGARCH_STLB 2048 /* 2048 STLB */
2447e1c521eSXiaojuan Yang #define LOONGARCH_MTLB 64 /* 64 MTLB */
2457e1c521eSXiaojuan Yang #define LOONGARCH_TLB_MAX (LOONGARCH_STLB + LOONGARCH_MTLB)
2467e1c521eSXiaojuan Yang
2477e1c521eSXiaojuan Yang /*
2487e1c521eSXiaojuan Yang * define the ASID PS E VPPN field of TLB
2497e1c521eSXiaojuan Yang */
2507e1c521eSXiaojuan Yang FIELD(TLB_MISC, E, 0, 1)
2517e1c521eSXiaojuan Yang FIELD(TLB_MISC, ASID, 1, 10)
2527e1c521eSXiaojuan Yang FIELD(TLB_MISC, VPPN, 13, 35)
2537e1c521eSXiaojuan Yang FIELD(TLB_MISC, PS, 48, 6)
2547e1c521eSXiaojuan Yang
25516f5396cSSong Gao #define LSX_LEN (128)
256008a3b16SSong Gao #define LASX_LEN (256)
257008a3b16SSong Gao
25816f5396cSSong Gao typedef union VReg {
259008a3b16SSong Gao int8_t B[LASX_LEN / 8];
260008a3b16SSong Gao int16_t H[LASX_LEN / 16];
261008a3b16SSong Gao int32_t W[LASX_LEN / 32];
262008a3b16SSong Gao int64_t D[LASX_LEN / 64];
263008a3b16SSong Gao uint8_t UB[LASX_LEN / 8];
264008a3b16SSong Gao uint16_t UH[LASX_LEN / 16];
265008a3b16SSong Gao uint32_t UW[LASX_LEN / 32];
266008a3b16SSong Gao uint64_t UD[LASX_LEN / 64];
267008a3b16SSong Gao Int128 Q[LASX_LEN / 128];
26816f5396cSSong Gao } VReg;
26916f5396cSSong Gao
27016f5396cSSong Gao typedef union fpr_t fpr_t;
27116f5396cSSong Gao union fpr_t {
27216f5396cSSong Gao VReg vreg;
27316f5396cSSong Gao };
27416f5396cSSong Gao
2756f703a48SBibo Mao #ifdef CONFIG_TCG
2767e1c521eSXiaojuan Yang struct LoongArchTLB {
2777e1c521eSXiaojuan Yang uint64_t tlb_misc;
2787e1c521eSXiaojuan Yang /* Fields corresponding to CSR_TLBELO0/1 */
2797e1c521eSXiaojuan Yang uint64_t tlb_entry0;
2807e1c521eSXiaojuan Yang uint64_t tlb_entry1;
2817e1c521eSXiaojuan Yang };
2827e1c521eSXiaojuan Yang typedef struct LoongArchTLB LoongArchTLB;
2836f703a48SBibo Mao #endif
2847e1c521eSXiaojuan Yang
285c23a53d8SBibo Mao enum loongarch_features {
286c23a53d8SBibo Mao LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
2876edd2a9bSBibo Mao LOONGARCH_FEATURE_PMU,
288c23a53d8SBibo Mao };
289c23a53d8SBibo Mao
290a45df286SBibo Mao typedef struct LoongArchBT {
291a45df286SBibo Mao /* scratch registers */
292a45df286SBibo Mao uint64_t scr0;
293a45df286SBibo Mao uint64_t scr1;
294a45df286SBibo Mao uint64_t scr2;
295a45df286SBibo Mao uint64_t scr3;
296a45df286SBibo Mao /* loongarch eflags */
297a45df286SBibo Mao uint32_t eflags;
298a45df286SBibo Mao uint32_t ftop;
299a45df286SBibo Mao } lbt_t;
300a45df286SBibo Mao
301228021f0SSong Gao typedef struct CPUArchState {
302228021f0SSong Gao uint64_t gpr[32];
303228021f0SSong Gao uint64_t pc;
304228021f0SSong Gao
30516f5396cSSong Gao fpr_t fpr[32];
306228021f0SSong Gao bool cf[8];
307228021f0SSong Gao uint32_t fcsr0;
308a45df286SBibo Mao lbt_t lbt;
309228021f0SSong Gao
310228021f0SSong Gao uint32_t cpucfg[21];
311228021f0SSong Gao
312398cecb9SXiaojuan Yang /* LoongArch CSRs */
313398cecb9SXiaojuan Yang uint64_t CSR_CRMD;
314398cecb9SXiaojuan Yang uint64_t CSR_PRMD;
315398cecb9SXiaojuan Yang uint64_t CSR_EUEN;
316398cecb9SXiaojuan Yang uint64_t CSR_MISC;
317398cecb9SXiaojuan Yang uint64_t CSR_ECFG;
318398cecb9SXiaojuan Yang uint64_t CSR_ESTAT;
319398cecb9SXiaojuan Yang uint64_t CSR_ERA;
320398cecb9SXiaojuan Yang uint64_t CSR_BADV;
321398cecb9SXiaojuan Yang uint64_t CSR_BADI;
322398cecb9SXiaojuan Yang uint64_t CSR_EENTRY;
323398cecb9SXiaojuan Yang uint64_t CSR_TLBIDX;
324398cecb9SXiaojuan Yang uint64_t CSR_TLBEHI;
325398cecb9SXiaojuan Yang uint64_t CSR_TLBELO0;
326398cecb9SXiaojuan Yang uint64_t CSR_TLBELO1;
327398cecb9SXiaojuan Yang uint64_t CSR_ASID;
328398cecb9SXiaojuan Yang uint64_t CSR_PGDL;
329398cecb9SXiaojuan Yang uint64_t CSR_PGDH;
330398cecb9SXiaojuan Yang uint64_t CSR_PGD;
331398cecb9SXiaojuan Yang uint64_t CSR_PWCL;
332398cecb9SXiaojuan Yang uint64_t CSR_PWCH;
333398cecb9SXiaojuan Yang uint64_t CSR_STLBPS;
334398cecb9SXiaojuan Yang uint64_t CSR_RVACFG;
33562784656STianrui Zhao uint64_t CSR_CPUID;
336398cecb9SXiaojuan Yang uint64_t CSR_PRCFG1;
337398cecb9SXiaojuan Yang uint64_t CSR_PRCFG2;
338398cecb9SXiaojuan Yang uint64_t CSR_PRCFG3;
339398cecb9SXiaojuan Yang uint64_t CSR_SAVE[16];
340398cecb9SXiaojuan Yang uint64_t CSR_TID;
341398cecb9SXiaojuan Yang uint64_t CSR_TCFG;
342398cecb9SXiaojuan Yang uint64_t CSR_TVAL;
343398cecb9SXiaojuan Yang uint64_t CSR_CNTC;
344398cecb9SXiaojuan Yang uint64_t CSR_TICLR;
345398cecb9SXiaojuan Yang uint64_t CSR_LLBCTL;
346398cecb9SXiaojuan Yang uint64_t CSR_IMPCTL1;
347398cecb9SXiaojuan Yang uint64_t CSR_IMPCTL2;
348398cecb9SXiaojuan Yang uint64_t CSR_TLBRENTRY;
349398cecb9SXiaojuan Yang uint64_t CSR_TLBRBADV;
350398cecb9SXiaojuan Yang uint64_t CSR_TLBRERA;
351398cecb9SXiaojuan Yang uint64_t CSR_TLBRSAVE;
352398cecb9SXiaojuan Yang uint64_t CSR_TLBRELO0;
353398cecb9SXiaojuan Yang uint64_t CSR_TLBRELO1;
354398cecb9SXiaojuan Yang uint64_t CSR_TLBREHI;
355398cecb9SXiaojuan Yang uint64_t CSR_TLBRPRMD;
356398cecb9SXiaojuan Yang uint64_t CSR_MERRCTL;
357398cecb9SXiaojuan Yang uint64_t CSR_MERRINFO1;
358398cecb9SXiaojuan Yang uint64_t CSR_MERRINFO2;
359398cecb9SXiaojuan Yang uint64_t CSR_MERRENTRY;
360398cecb9SXiaojuan Yang uint64_t CSR_MERRERA;
361398cecb9SXiaojuan Yang uint64_t CSR_MERRSAVE;
362398cecb9SXiaojuan Yang uint64_t CSR_CTAG;
363398cecb9SXiaojuan Yang uint64_t CSR_DMW[4];
364398cecb9SXiaojuan Yang uint64_t CSR_DBG;
365398cecb9SXiaojuan Yang uint64_t CSR_DERA;
366398cecb9SXiaojuan Yang uint64_t CSR_DSAVE;
367*47b54e15SBibo Mao struct {
368*47b54e15SBibo Mao uint64_t guest_addr;
369*47b54e15SBibo Mao } stealtime;
3707e1c521eSXiaojuan Yang
3716f703a48SBibo Mao #ifdef CONFIG_TCG
3726f703a48SBibo Mao float_status fp_status;
3736f703a48SBibo Mao uint32_t fcsr0_mask;
3746f703a48SBibo Mao uint64_t lladdr; /* LL virtual address compared against SC */
3756f703a48SBibo Mao uint64_t llval;
3766f703a48SBibo Mao #endif
3770093b9a5SSong Gao #ifndef CONFIG_USER_ONLY
3786f703a48SBibo Mao #ifdef CONFIG_TCG
3797e1c521eSXiaojuan Yang LoongArchTLB tlb[LOONGARCH_TLB_MAX];
3806f703a48SBibo Mao #endif
381f84a2aacSXiaojuan Yang
3825e90b8dbSBibo Mao AddressSpace *address_space_iocsr;
3836a6f26f4SXiaojuan Yang bool load_elf;
3846a6f26f4SXiaojuan Yang uint64_t elf_address;
385f8447436STianrui Zhao uint32_t mp_state;
386758a7475STianrui Zhao /* Store ipistate to access from this struct */
387758a7475STianrui Zhao DeviceState *ipistate;
38858ee60d2SSong Gao
38958ee60d2SSong Gao struct loongarch_boot_info *boot_info;
3900093b9a5SSong Gao #endif
391228021f0SSong Gao } CPULoongArchState;
392228021f0SSong Gao
393228021f0SSong Gao /**
394228021f0SSong Gao * LoongArchCPU:
395228021f0SSong Gao * @env: #CPULoongArchState
396228021f0SSong Gao *
397228021f0SSong Gao * A LoongArch CPU.
398228021f0SSong Gao */
399228021f0SSong Gao struct ArchCPU {
400228021f0SSong Gao CPUState parent_obj;
401228021f0SSong Gao
402228021f0SSong Gao CPULoongArchState env;
403dd615fa4SXiaojuan Yang QEMUTimer timer;
40414f21f67SBibo Mao uint32_t phy_id;
405c23a53d8SBibo Mao OnOffAuto lbt;
4066edd2a9bSBibo Mao OnOffAuto pmu;
407fda3f15bSXiaojuan Yang
408fda3f15bSXiaojuan Yang /* 'compatible' string for this CPU for Linux device trees */
409fda3f15bSXiaojuan Yang const char *dtb_compatible;
410d11681c9STianrui Zhao /* used by KVM_REG_LOONGARCH_COUNTER ioctl to access guest time counters */
411d11681c9STianrui Zhao uint64_t kvm_state_counter;
412228021f0SSong Gao };
413228021f0SSong Gao
414228021f0SSong Gao /**
415228021f0SSong Gao * LoongArchCPUClass:
416228021f0SSong Gao * @parent_realize: The parent class' realize handler.
417f78b49aeSPeter Maydell * @parent_phases: The parent class' reset phase handlers.
418228021f0SSong Gao *
419228021f0SSong Gao * A LoongArch CPU model.
420228021f0SSong Gao */
421228021f0SSong Gao struct LoongArchCPUClass {
422228021f0SSong Gao CPUClass parent_class;
423228021f0SSong Gao
424228021f0SSong Gao DeviceRealize parent_realize;
425f78b49aeSPeter Maydell ResettablePhases parent_phases;
426228021f0SSong Gao };
427228021f0SSong Gao
4287e1c521eSXiaojuan Yang /*
4297e1c521eSXiaojuan Yang * LoongArch CPUs has 4 privilege levels.
4307e1c521eSXiaojuan Yang * 0 for kernel mode, 3 for user mode.
4317e1c521eSXiaojuan Yang * Define an extra index for DA(direct addressing) mode.
4327e1c521eSXiaojuan Yang */
433c8885b88SRui Wang #define MMU_PLV_KERNEL 0
434c8885b88SRui Wang #define MMU_PLV_USER 3
4353f262d25SRichard Henderson #define MMU_KERNEL_IDX MMU_PLV_KERNEL
4363f262d25SRichard Henderson #define MMU_USER_IDX MMU_PLV_USER
4373f262d25SRichard Henderson #define MMU_DA_IDX 4
4387e1c521eSXiaojuan Yang
is_la64(CPULoongArchState * env)43919f82a4aSJiajie Chen static inline bool is_la64(CPULoongArchState *env)
44019f82a4aSJiajie Chen {
44119f82a4aSJiajie Chen return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64;
44219f82a4aSJiajie Chen }
44319f82a4aSJiajie Chen
is_va32(CPULoongArchState * env)44439665820SJiajie Chen static inline bool is_va32(CPULoongArchState *env)
44539665820SJiajie Chen {
44639665820SJiajie Chen /* VA32 if !LA64 or VA32L[1-3] */
44739665820SJiajie Chen bool va32 = !is_la64(env);
44839665820SJiajie Chen uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
44939665820SJiajie Chen if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) {
45039665820SJiajie Chen va32 = true;
45139665820SJiajie Chen }
45239665820SJiajie Chen return va32;
45339665820SJiajie Chen }
45439665820SJiajie Chen
set_pc(CPULoongArchState * env,uint64_t value)4552f6478ffSJiajie Chen static inline void set_pc(CPULoongArchState *env, uint64_t value)
4562f6478ffSJiajie Chen {
4577033c0e6SJiajie Chen if (is_va32(env)) {
4587033c0e6SJiajie Chen env->pc = (uint32_t)value;
4597033c0e6SJiajie Chen } else {
4602f6478ffSJiajie Chen env->pc = value;
4612f6478ffSJiajie Chen }
4627033c0e6SJiajie Chen }
4632f6478ffSJiajie Chen
464b4bda200SRui Wang /*
465b4bda200SRui Wang * LoongArch CPUs hardware flags.
466b4bda200SRui Wang */
467b4bda200SRui Wang #define HW_FLAGS_PLV_MASK R_CSR_CRMD_PLV_MASK /* 0x03 */
4682419978cSRui Wang #define HW_FLAGS_EUEN_FPE 0x04
469a3f3db5cSSong Gao #define HW_FLAGS_EUEN_SXE 0x08
47032f4916cSJiajie Chen #define HW_FLAGS_CRMD_PG R_CSR_CRMD_PG_MASK /* 0x10 */
47139665820SJiajie Chen #define HW_FLAGS_VA32 0x20
47232f4916cSJiajie Chen #define HW_FLAGS_EUEN_ASXE 0x40
473b4bda200SRui Wang
cpu_get_tb_cpu_state(CPULoongArchState * env,vaddr * pc,uint64_t * cs_base,uint32_t * flags)474bb5de525SAnton Johansson static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
475bb5de525SAnton Johansson uint64_t *cs_base, uint32_t *flags)
4767e1c521eSXiaojuan Yang {
4777e1c521eSXiaojuan Yang *pc = env->pc;
4787e1c521eSXiaojuan Yang *cs_base = 0;
479b4bda200SRui Wang *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
4802419978cSRui Wang *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
481a3f3db5cSSong Gao *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE;
482b8f1bdf3SSong Gao *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE;
48339665820SJiajie Chen *flags |= is_va32(env) * HW_FLAGS_VA32;
4847e1c521eSXiaojuan Yang }
4857e1c521eSXiaojuan Yang
486228021f0SSong Gao #include "exec/cpu-all.h"
487228021f0SSong Gao
488228021f0SSong Gao #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
489228021f0SSong Gao
490464136ceSSong Gao void loongarch_cpu_post_init(Object *obj);
491464136ceSSong Gao
492228021f0SSong Gao #endif /* LOONGARCH_CPU_H */
493