xref: /qemu/target/loongarch/cpu.h (revision a3f3db5cda7bf6edf0fc0c94c3aa450eb79a2185)
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"
20f84a2aacSXiaojuan Yang 
21f84a2aacSXiaojuan Yang #define IOCSRF_TEMP             0
22f84a2aacSXiaojuan Yang #define IOCSRF_NODECNT          1
23f84a2aacSXiaojuan Yang #define IOCSRF_MSI              2
24f84a2aacSXiaojuan Yang #define IOCSRF_EXTIOI           3
25f84a2aacSXiaojuan Yang #define IOCSRF_CSRIPI           4
26f84a2aacSXiaojuan Yang #define IOCSRF_FREQCSR          5
27f84a2aacSXiaojuan Yang #define IOCSRF_FREQSCALE        6
28f84a2aacSXiaojuan Yang #define IOCSRF_DVFSV1           7
29f84a2aacSXiaojuan Yang #define IOCSRF_GMOD             9
30f84a2aacSXiaojuan Yang #define IOCSRF_VM               11
31f84a2aacSXiaojuan Yang 
32c77432d0SSong Gao #define VERSION_REG             0x0
33f84a2aacSXiaojuan Yang #define FEATURE_REG             0x8
34f84a2aacSXiaojuan Yang #define VENDOR_REG              0x10
35f84a2aacSXiaojuan Yang #define CPUNAME_REG             0x20
36f84a2aacSXiaojuan Yang #define MISC_FUNC_REG           0x420
37f84a2aacSXiaojuan Yang #define IOCSRM_EXTIOI_EN        48
38f84a2aacSXiaojuan Yang 
39f84a2aacSXiaojuan Yang #define IOCSR_MEM_SIZE          0x428
40228021f0SSong Gao 
41228021f0SSong Gao #define TCG_GUEST_DEFAULT_MO (0)
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)
5800952d93SQi Hu 
59228021f0SSong Gao #define GET_FP_ENABLES(REG)    FIELD_EX32(REG, FCSR0, ENABLES)
6000952d93SQi Hu #define SET_FP_ENABLES(REG, V) \
6100952d93SQi Hu     do { \
6200952d93SQi Hu         (REG) = FIELD_DP32(REG, FCSR0, ENABLES, V); \
6300952d93SQi Hu     } while (0)
6400952d93SQi Hu 
65228021f0SSong Gao #define GET_FP_FLAGS(REG)      FIELD_EX32(REG, FCSR0, FLAGS)
6600952d93SQi Hu #define SET_FP_FLAGS(REG, V) \
6700952d93SQi Hu     do { \
6800952d93SQi Hu         (REG) = FIELD_DP32(REG, FCSR0, FLAGS, V); \
6900952d93SQi Hu     } while (0)
7000952d93SQi Hu 
71228021f0SSong Gao #define UPDATE_FP_FLAGS(REG, V) \
72228021f0SSong Gao     do { \
73228021f0SSong Gao         (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \
74228021f0SSong Gao     } while (0)
75228021f0SSong Gao 
76228021f0SSong Gao #define FP_INEXACT        1
77228021f0SSong Gao #define FP_UNDERFLOW      2
78228021f0SSong Gao #define FP_OVERFLOW       4
79228021f0SSong Gao #define FP_DIV0           8
80228021f0SSong Gao #define FP_INVALID        16
81228021f0SSong Gao 
82a6b129c8SSong Gao #define EXCODE(code, subcode) ( ((subcode) << 6) | (code) )
83a6b129c8SSong Gao #define EXCODE_MCODE(code)    ( (code) & 0x3f )
84a6b129c8SSong Gao #define EXCODE_SUBCODE(code)  ( (code) >> 6 )
85a6b129c8SSong Gao 
86228021f0SSong Gao #define  EXCCODE_EXTERNAL_INT        64   /* plus external interrupt number */
87a6b129c8SSong Gao #define  EXCCODE_INT                 EXCODE(0, 0)
88a6b129c8SSong Gao #define  EXCCODE_PIL                 EXCODE(1, 0)
89a6b129c8SSong Gao #define  EXCCODE_PIS                 EXCODE(2, 0)
90a6b129c8SSong Gao #define  EXCCODE_PIF                 EXCODE(3, 0)
91a6b129c8SSong Gao #define  EXCCODE_PME                 EXCODE(4, 0)
92a6b129c8SSong Gao #define  EXCCODE_PNR                 EXCODE(5, 0)
93a6b129c8SSong Gao #define  EXCCODE_PNX                 EXCODE(6, 0)
94a6b129c8SSong Gao #define  EXCCODE_PPI                 EXCODE(7, 0)
95a6b129c8SSong Gao #define  EXCCODE_ADEF                EXCODE(8, 0) /* Different exception subcode */
96a6b129c8SSong Gao #define  EXCCODE_ADEM                EXCODE(8, 1)
97a6b129c8SSong Gao #define  EXCCODE_ALE                 EXCODE(9, 0)
98a6b129c8SSong Gao #define  EXCCODE_BCE                 EXCODE(10, 0)
99a6b129c8SSong Gao #define  EXCCODE_SYS                 EXCODE(11, 0)
100a6b129c8SSong Gao #define  EXCCODE_BRK                 EXCODE(12, 0)
101a6b129c8SSong Gao #define  EXCCODE_INE                 EXCODE(13, 0)
102a6b129c8SSong Gao #define  EXCCODE_IPE                 EXCODE(14, 0)
103a6b129c8SSong Gao #define  EXCCODE_FPD                 EXCODE(15, 0)
104a6b129c8SSong Gao #define  EXCCODE_SXD                 EXCODE(16, 0)
105a6b129c8SSong Gao #define  EXCCODE_ASXD                EXCODE(17, 0)
106a6b129c8SSong Gao #define  EXCCODE_FPE                 EXCODE(18, 0) /* Different exception subcode */
107a6b129c8SSong Gao #define  EXCCODE_VFPE                EXCODE(18, 1)
108a6b129c8SSong Gao #define  EXCCODE_WPEF                EXCODE(19, 0) /* Different exception subcode */
109a6b129c8SSong Gao #define  EXCCODE_WPEM                EXCODE(19, 1)
110a6b129c8SSong Gao #define  EXCCODE_BTD                 EXCODE(20, 0)
111a6b129c8SSong Gao #define  EXCCODE_BTE                 EXCODE(21, 0)
112a6b129c8SSong Gao #define  EXCCODE_DBP                 EXCODE(26, 0) /* Reserved subcode used for debug */
113228021f0SSong Gao 
114228021f0SSong Gao /* cpucfg[0] bits */
115228021f0SSong Gao FIELD(CPUCFG0, PRID, 0, 32)
116228021f0SSong Gao 
117228021f0SSong Gao /* cpucfg[1] bits */
118228021f0SSong Gao FIELD(CPUCFG1, ARCH, 0, 2)
119228021f0SSong Gao FIELD(CPUCFG1, PGMMU, 2, 1)
120228021f0SSong Gao FIELD(CPUCFG1, IOCSR, 3, 1)
121228021f0SSong Gao FIELD(CPUCFG1, PALEN, 4, 8)
122228021f0SSong Gao FIELD(CPUCFG1, VALEN, 12, 8)
123228021f0SSong Gao FIELD(CPUCFG1, UAL, 20, 1)
124228021f0SSong Gao FIELD(CPUCFG1, RI, 21, 1)
125228021f0SSong Gao FIELD(CPUCFG1, EP, 22, 1)
126228021f0SSong Gao FIELD(CPUCFG1, RPLV, 23, 1)
127228021f0SSong Gao FIELD(CPUCFG1, HP, 24, 1)
128228021f0SSong Gao FIELD(CPUCFG1, IOCSR_BRD, 25, 1)
129228021f0SSong Gao FIELD(CPUCFG1, MSG_INT, 26, 1)
130228021f0SSong Gao 
131228021f0SSong Gao /* cpucfg[2] bits */
132228021f0SSong Gao FIELD(CPUCFG2, FP, 0, 1)
133228021f0SSong Gao FIELD(CPUCFG2, FP_SP, 1, 1)
134228021f0SSong Gao FIELD(CPUCFG2, FP_DP, 2, 1)
135228021f0SSong Gao FIELD(CPUCFG2, FP_VER, 3, 3)
136228021f0SSong Gao FIELD(CPUCFG2, LSX, 6, 1)
137228021f0SSong Gao FIELD(CPUCFG2, LASX, 7, 1)
138228021f0SSong Gao FIELD(CPUCFG2, COMPLEX, 8, 1)
139228021f0SSong Gao FIELD(CPUCFG2, CRYPTO, 9, 1)
140228021f0SSong Gao FIELD(CPUCFG2, LVZ, 10, 1)
141228021f0SSong Gao FIELD(CPUCFG2, LVZ_VER, 11, 3)
142228021f0SSong Gao FIELD(CPUCFG2, LLFTP, 14, 1)
143228021f0SSong Gao FIELD(CPUCFG2, LLFTP_VER, 15, 3)
144228021f0SSong Gao FIELD(CPUCFG2, LBT_X86, 18, 1)
145228021f0SSong Gao FIELD(CPUCFG2, LBT_ARM, 19, 1)
146228021f0SSong Gao FIELD(CPUCFG2, LBT_MIPS, 20, 1)
147228021f0SSong Gao FIELD(CPUCFG2, LSPW, 21, 1)
148228021f0SSong Gao FIELD(CPUCFG2, LAM, 22, 1)
149228021f0SSong Gao 
150228021f0SSong Gao /* cpucfg[3] bits */
151228021f0SSong Gao FIELD(CPUCFG3, CCDMA, 0, 1)
152228021f0SSong Gao FIELD(CPUCFG3, SFB, 1, 1)
153228021f0SSong Gao FIELD(CPUCFG3, UCACC, 2, 1)
154228021f0SSong Gao FIELD(CPUCFG3, LLEXC, 3, 1)
155228021f0SSong Gao FIELD(CPUCFG3, SCDLY, 4, 1)
156228021f0SSong Gao FIELD(CPUCFG3, LLDBAR, 5, 1)
157228021f0SSong Gao FIELD(CPUCFG3, ITLBHMC, 6, 1)
158228021f0SSong Gao FIELD(CPUCFG3, ICHMC, 7, 1)
159228021f0SSong Gao FIELD(CPUCFG3, SPW_LVL, 8, 3)
160228021f0SSong Gao FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
161228021f0SSong Gao FIELD(CPUCFG3, RVA, 12, 1)
162228021f0SSong Gao FIELD(CPUCFG3, RVAMAX, 13, 4)
163228021f0SSong Gao 
164228021f0SSong Gao /* cpucfg[4] bits */
165228021f0SSong Gao FIELD(CPUCFG4, CC_FREQ, 0, 32)
166228021f0SSong Gao 
167228021f0SSong Gao /* cpucfg[5] bits */
168228021f0SSong Gao FIELD(CPUCFG5, CC_MUL, 0, 16)
169228021f0SSong Gao FIELD(CPUCFG5, CC_DIV, 16, 16)
170228021f0SSong Gao 
171228021f0SSong Gao /* cpucfg[6] bits */
172228021f0SSong Gao FIELD(CPUCFG6, PMP, 0, 1)
173228021f0SSong Gao FIELD(CPUCFG6, PMVER, 1, 3)
174228021f0SSong Gao FIELD(CPUCFG6, PMNUM, 4, 4)
175228021f0SSong Gao FIELD(CPUCFG6, PMBITS, 8, 6)
176228021f0SSong Gao FIELD(CPUCFG6, UPM, 14, 1)
177228021f0SSong Gao 
178228021f0SSong Gao /* cpucfg[16] bits */
179228021f0SSong Gao FIELD(CPUCFG16, L1_IUPRE, 0, 1)
180228021f0SSong Gao FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
181228021f0SSong Gao FIELD(CPUCFG16, L1_DPRE, 2, 1)
182228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRE, 3, 1)
183228021f0SSong Gao FIELD(CPUCFG16, L2_IUUNIFY, 4, 1)
184228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRIV, 5, 1)
185228021f0SSong Gao FIELD(CPUCFG16, L2_IUINCL, 6, 1)
186228021f0SSong Gao FIELD(CPUCFG16, L2_DPRE, 7, 1)
187228021f0SSong Gao FIELD(CPUCFG16, L2_DPRIV, 8, 1)
188228021f0SSong Gao FIELD(CPUCFG16, L2_DINCL, 9, 1)
189228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRE, 10, 1)
190228021f0SSong Gao FIELD(CPUCFG16, L3_IUUNIFY, 11, 1)
191228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRIV, 12, 1)
192228021f0SSong Gao FIELD(CPUCFG16, L3_IUINCL, 13, 1)
193228021f0SSong Gao FIELD(CPUCFG16, L3_DPRE, 14, 1)
194228021f0SSong Gao FIELD(CPUCFG16, L3_DPRIV, 15, 1)
195228021f0SSong Gao FIELD(CPUCFG16, L3_DINCL, 16, 1)
196228021f0SSong Gao 
197228021f0SSong Gao /* cpucfg[17] bits */
198228021f0SSong Gao FIELD(CPUCFG17, L1IU_WAYS, 0, 16)
199228021f0SSong Gao FIELD(CPUCFG17, L1IU_SETS, 16, 8)
200228021f0SSong Gao FIELD(CPUCFG17, L1IU_SIZE, 24, 7)
201228021f0SSong Gao 
202228021f0SSong Gao /* cpucfg[18] bits */
203228021f0SSong Gao FIELD(CPUCFG18, L1D_WAYS, 0, 16)
204228021f0SSong Gao FIELD(CPUCFG18, L1D_SETS, 16, 8)
205228021f0SSong Gao FIELD(CPUCFG18, L1D_SIZE, 24, 7)
206228021f0SSong Gao 
207228021f0SSong Gao /* cpucfg[19] bits */
208228021f0SSong Gao FIELD(CPUCFG19, L2IU_WAYS, 0, 16)
209228021f0SSong Gao FIELD(CPUCFG19, L2IU_SETS, 16, 8)
210228021f0SSong Gao FIELD(CPUCFG19, L2IU_SIZE, 24, 7)
211228021f0SSong Gao 
212228021f0SSong Gao /* cpucfg[20] bits */
213228021f0SSong Gao FIELD(CPUCFG20, L3IU_WAYS, 0, 16)
214228021f0SSong Gao FIELD(CPUCFG20, L3IU_SETS, 16, 8)
215228021f0SSong Gao FIELD(CPUCFG20, L3IU_SIZE, 24, 7)
216228021f0SSong Gao 
217398cecb9SXiaojuan Yang /*CSR_CRMD */
218398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PLV, 0, 2)
219398cecb9SXiaojuan Yang FIELD(CSR_CRMD, IE, 2, 1)
220398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DA, 3, 1)
221398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PG, 4, 1)
222398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATF, 5, 2)
223398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATM, 7, 2)
224398cecb9SXiaojuan Yang FIELD(CSR_CRMD, WE, 9, 1)
225398cecb9SXiaojuan Yang 
226228021f0SSong Gao extern const char * const regnames[32];
227228021f0SSong Gao extern const char * const fregnames[32];
228228021f0SSong Gao 
229f757a2cdSXiaojuan Yang #define N_IRQS      13
230dd615fa4SXiaojuan Yang #define IRQ_TIMER   11
231dd615fa4SXiaojuan Yang #define IRQ_IPI     12
232f757a2cdSXiaojuan Yang 
2337e1c521eSXiaojuan Yang #define LOONGARCH_STLB         2048 /* 2048 STLB */
2347e1c521eSXiaojuan Yang #define LOONGARCH_MTLB         64   /* 64 MTLB */
2357e1c521eSXiaojuan Yang #define LOONGARCH_TLB_MAX      (LOONGARCH_STLB + LOONGARCH_MTLB)
2367e1c521eSXiaojuan Yang 
2377e1c521eSXiaojuan Yang /*
2387e1c521eSXiaojuan Yang  * define the ASID PS E VPPN field of TLB
2397e1c521eSXiaojuan Yang  */
2407e1c521eSXiaojuan Yang FIELD(TLB_MISC, E, 0, 1)
2417e1c521eSXiaojuan Yang FIELD(TLB_MISC, ASID, 1, 10)
2427e1c521eSXiaojuan Yang FIELD(TLB_MISC, VPPN, 13, 35)
2437e1c521eSXiaojuan Yang FIELD(TLB_MISC, PS, 48, 6)
2447e1c521eSXiaojuan Yang 
24516f5396cSSong Gao #define LSX_LEN   (128)
24616f5396cSSong Gao typedef union VReg {
24716f5396cSSong Gao     int8_t   B[LSX_LEN / 8];
24816f5396cSSong Gao     int16_t  H[LSX_LEN / 16];
24916f5396cSSong Gao     int32_t  W[LSX_LEN / 32];
25016f5396cSSong Gao     int64_t  D[LSX_LEN / 64];
25116f5396cSSong Gao     uint8_t  UB[LSX_LEN / 8];
25216f5396cSSong Gao     uint16_t UH[LSX_LEN / 16];
25316f5396cSSong Gao     uint32_t UW[LSX_LEN / 32];
25416f5396cSSong Gao     uint64_t UD[LSX_LEN / 64];
25516f5396cSSong Gao     Int128   Q[LSX_LEN / 128];
25616f5396cSSong Gao }VReg;
25716f5396cSSong Gao 
25816f5396cSSong Gao typedef union fpr_t fpr_t;
25916f5396cSSong Gao union fpr_t {
26016f5396cSSong Gao     VReg  vreg;
26116f5396cSSong Gao };
26216f5396cSSong Gao 
2637e1c521eSXiaojuan Yang struct LoongArchTLB {
2647e1c521eSXiaojuan Yang     uint64_t tlb_misc;
2657e1c521eSXiaojuan Yang     /* Fields corresponding to CSR_TLBELO0/1 */
2667e1c521eSXiaojuan Yang     uint64_t tlb_entry0;
2677e1c521eSXiaojuan Yang     uint64_t tlb_entry1;
2687e1c521eSXiaojuan Yang };
2697e1c521eSXiaojuan Yang typedef struct LoongArchTLB LoongArchTLB;
2707e1c521eSXiaojuan Yang 
271228021f0SSong Gao typedef struct CPUArchState {
272228021f0SSong Gao     uint64_t gpr[32];
273228021f0SSong Gao     uint64_t pc;
274228021f0SSong Gao 
27516f5396cSSong Gao     fpr_t fpr[32];
276228021f0SSong Gao     float_status fp_status;
277228021f0SSong Gao     bool cf[8];
278228021f0SSong Gao 
279228021f0SSong Gao     uint32_t fcsr0;
280228021f0SSong Gao     uint32_t fcsr0_mask;
281228021f0SSong Gao 
282228021f0SSong Gao     uint32_t cpucfg[21];
283228021f0SSong Gao 
284228021f0SSong Gao     uint64_t lladdr; /* LL virtual address compared against SC */
285228021f0SSong Gao     uint64_t llval;
286228021f0SSong Gao 
287398cecb9SXiaojuan Yang     /* LoongArch CSRs */
288398cecb9SXiaojuan Yang     uint64_t CSR_CRMD;
289398cecb9SXiaojuan Yang     uint64_t CSR_PRMD;
290398cecb9SXiaojuan Yang     uint64_t CSR_EUEN;
291398cecb9SXiaojuan Yang     uint64_t CSR_MISC;
292398cecb9SXiaojuan Yang     uint64_t CSR_ECFG;
293398cecb9SXiaojuan Yang     uint64_t CSR_ESTAT;
294398cecb9SXiaojuan Yang     uint64_t CSR_ERA;
295398cecb9SXiaojuan Yang     uint64_t CSR_BADV;
296398cecb9SXiaojuan Yang     uint64_t CSR_BADI;
297398cecb9SXiaojuan Yang     uint64_t CSR_EENTRY;
298398cecb9SXiaojuan Yang     uint64_t CSR_TLBIDX;
299398cecb9SXiaojuan Yang     uint64_t CSR_TLBEHI;
300398cecb9SXiaojuan Yang     uint64_t CSR_TLBELO0;
301398cecb9SXiaojuan Yang     uint64_t CSR_TLBELO1;
302398cecb9SXiaojuan Yang     uint64_t CSR_ASID;
303398cecb9SXiaojuan Yang     uint64_t CSR_PGDL;
304398cecb9SXiaojuan Yang     uint64_t CSR_PGDH;
305398cecb9SXiaojuan Yang     uint64_t CSR_PGD;
306398cecb9SXiaojuan Yang     uint64_t CSR_PWCL;
307398cecb9SXiaojuan Yang     uint64_t CSR_PWCH;
308398cecb9SXiaojuan Yang     uint64_t CSR_STLBPS;
309398cecb9SXiaojuan Yang     uint64_t CSR_RVACFG;
310398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG1;
311398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG2;
312398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG3;
313398cecb9SXiaojuan Yang     uint64_t CSR_SAVE[16];
314398cecb9SXiaojuan Yang     uint64_t CSR_TID;
315398cecb9SXiaojuan Yang     uint64_t CSR_TCFG;
316398cecb9SXiaojuan Yang     uint64_t CSR_TVAL;
317398cecb9SXiaojuan Yang     uint64_t CSR_CNTC;
318398cecb9SXiaojuan Yang     uint64_t CSR_TICLR;
319398cecb9SXiaojuan Yang     uint64_t CSR_LLBCTL;
320398cecb9SXiaojuan Yang     uint64_t CSR_IMPCTL1;
321398cecb9SXiaojuan Yang     uint64_t CSR_IMPCTL2;
322398cecb9SXiaojuan Yang     uint64_t CSR_TLBRENTRY;
323398cecb9SXiaojuan Yang     uint64_t CSR_TLBRBADV;
324398cecb9SXiaojuan Yang     uint64_t CSR_TLBRERA;
325398cecb9SXiaojuan Yang     uint64_t CSR_TLBRSAVE;
326398cecb9SXiaojuan Yang     uint64_t CSR_TLBRELO0;
327398cecb9SXiaojuan Yang     uint64_t CSR_TLBRELO1;
328398cecb9SXiaojuan Yang     uint64_t CSR_TLBREHI;
329398cecb9SXiaojuan Yang     uint64_t CSR_TLBRPRMD;
330398cecb9SXiaojuan Yang     uint64_t CSR_MERRCTL;
331398cecb9SXiaojuan Yang     uint64_t CSR_MERRINFO1;
332398cecb9SXiaojuan Yang     uint64_t CSR_MERRINFO2;
333398cecb9SXiaojuan Yang     uint64_t CSR_MERRENTRY;
334398cecb9SXiaojuan Yang     uint64_t CSR_MERRERA;
335398cecb9SXiaojuan Yang     uint64_t CSR_MERRSAVE;
336398cecb9SXiaojuan Yang     uint64_t CSR_CTAG;
337398cecb9SXiaojuan Yang     uint64_t CSR_DMW[4];
338398cecb9SXiaojuan Yang     uint64_t CSR_DBG;
339398cecb9SXiaojuan Yang     uint64_t CSR_DERA;
340398cecb9SXiaojuan Yang     uint64_t CSR_DSAVE;
3417e1c521eSXiaojuan Yang 
3420093b9a5SSong Gao #ifndef CONFIG_USER_ONLY
3437e1c521eSXiaojuan Yang     LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
344f84a2aacSXiaojuan Yang 
345f84a2aacSXiaojuan Yang     AddressSpace address_space_iocsr;
346f84a2aacSXiaojuan Yang     MemoryRegion system_iocsr;
347f84a2aacSXiaojuan Yang     MemoryRegion iocsr_mem;
3486a6f26f4SXiaojuan Yang     bool load_elf;
3496a6f26f4SXiaojuan Yang     uint64_t elf_address;
3500093b9a5SSong Gao #endif
351228021f0SSong Gao } CPULoongArchState;
352228021f0SSong Gao 
353228021f0SSong Gao /**
354228021f0SSong Gao  * LoongArchCPU:
355228021f0SSong Gao  * @env: #CPULoongArchState
356228021f0SSong Gao  *
357228021f0SSong Gao  * A LoongArch CPU.
358228021f0SSong Gao  */
359228021f0SSong Gao struct ArchCPU {
360228021f0SSong Gao     /*< private >*/
361228021f0SSong Gao     CPUState parent_obj;
362228021f0SSong Gao     /*< public >*/
363228021f0SSong Gao 
364228021f0SSong Gao     CPUNegativeOffsetState neg;
365228021f0SSong Gao     CPULoongArchState env;
366dd615fa4SXiaojuan Yang     QEMUTimer timer;
367fda3f15bSXiaojuan Yang 
368fda3f15bSXiaojuan Yang     /* 'compatible' string for this CPU for Linux device trees */
369fda3f15bSXiaojuan Yang     const char *dtb_compatible;
370228021f0SSong Gao };
371228021f0SSong Gao 
372228021f0SSong Gao #define TYPE_LOONGARCH_CPU "loongarch-cpu"
373228021f0SSong Gao 
374228021f0SSong Gao OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass,
375228021f0SSong Gao                         LOONGARCH_CPU)
376228021f0SSong Gao 
377228021f0SSong Gao /**
378228021f0SSong Gao  * LoongArchCPUClass:
379228021f0SSong Gao  * @parent_realize: The parent class' realize handler.
380f78b49aeSPeter Maydell  * @parent_phases: The parent class' reset phase handlers.
381228021f0SSong Gao  *
382228021f0SSong Gao  * A LoongArch CPU model.
383228021f0SSong Gao  */
384228021f0SSong Gao struct LoongArchCPUClass {
385228021f0SSong Gao     /*< private >*/
386228021f0SSong Gao     CPUClass parent_class;
387228021f0SSong Gao     /*< public >*/
388228021f0SSong Gao 
389228021f0SSong Gao     DeviceRealize parent_realize;
390f78b49aeSPeter Maydell     ResettablePhases parent_phases;
391228021f0SSong Gao };
392228021f0SSong Gao 
3937e1c521eSXiaojuan Yang /*
3947e1c521eSXiaojuan Yang  * LoongArch CPUs has 4 privilege levels.
3957e1c521eSXiaojuan Yang  * 0 for kernel mode, 3 for user mode.
3967e1c521eSXiaojuan Yang  * Define an extra index for DA(direct addressing) mode.
3977e1c521eSXiaojuan Yang  */
398c8885b88SRui Wang #define MMU_PLV_KERNEL   0
399c8885b88SRui Wang #define MMU_PLV_USER     3
400c8885b88SRui Wang #define MMU_IDX_KERNEL   MMU_PLV_KERNEL
401c8885b88SRui Wang #define MMU_IDX_USER     MMU_PLV_USER
402c8885b88SRui Wang #define MMU_IDX_DA       4
4037e1c521eSXiaojuan Yang 
4047e1c521eSXiaojuan Yang static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
4057e1c521eSXiaojuan Yang {
4060093b9a5SSong Gao #ifdef CONFIG_USER_ONLY
407c8885b88SRui Wang     return MMU_IDX_USER;
4080093b9a5SSong Gao #else
409c8885b88SRui Wang     if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) {
4107e1c521eSXiaojuan Yang         return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
411c8885b88SRui Wang     }
412c8885b88SRui Wang     return MMU_IDX_DA;
4130093b9a5SSong Gao #endif
4147e1c521eSXiaojuan Yang }
4157e1c521eSXiaojuan Yang 
416b4bda200SRui Wang /*
417b4bda200SRui Wang  * LoongArch CPUs hardware flags.
418b4bda200SRui Wang  */
419b4bda200SRui Wang #define HW_FLAGS_PLV_MASK   R_CSR_CRMD_PLV_MASK  /* 0x03 */
420b4bda200SRui Wang #define HW_FLAGS_CRMD_PG    R_CSR_CRMD_PG_MASK   /* 0x10 */
4212419978cSRui Wang #define HW_FLAGS_EUEN_FPE   0x04
422*a3f3db5cSSong Gao #define HW_FLAGS_EUEN_SXE   0x08
423b4bda200SRui Wang 
4247e1c521eSXiaojuan Yang static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
4257e1c521eSXiaojuan Yang                                         target_ulong *pc,
4267e1c521eSXiaojuan Yang                                         target_ulong *cs_base,
4277e1c521eSXiaojuan Yang                                         uint32_t *flags)
4287e1c521eSXiaojuan Yang {
4297e1c521eSXiaojuan Yang     *pc = env->pc;
4307e1c521eSXiaojuan Yang     *cs_base = 0;
431b4bda200SRui Wang     *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
4322419978cSRui Wang     *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
433*a3f3db5cSSong Gao     *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE;
4347e1c521eSXiaojuan Yang }
4357e1c521eSXiaojuan Yang 
436228021f0SSong Gao void loongarch_cpu_list(void);
437228021f0SSong Gao 
438228021f0SSong Gao #define cpu_list loongarch_cpu_list
439228021f0SSong Gao 
440228021f0SSong Gao #include "exec/cpu-all.h"
441228021f0SSong Gao 
442228021f0SSong Gao #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
443228021f0SSong Gao #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
444228021f0SSong Gao #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
445228021f0SSong Gao 
446228021f0SSong Gao #endif /* LOONGARCH_CPU_H */
447