xref: /qemu/target/loongarch/cpu.h (revision f78b49ae8dd900f90d8e650c09d6bc4b489ea11c)
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 
11228021f0SSong Gao #include "exec/cpu-defs.h"
12228021f0SSong Gao #include "fpu/softfloat-types.h"
13228021f0SSong Gao #include "hw/registerfields.h"
14dd615fa4SXiaojuan Yang #include "qemu/timer.h"
15f84a2aacSXiaojuan Yang #include "exec/memory.h"
16f84a2aacSXiaojuan Yang #include "hw/sysbus.h"
17b4bda200SRui Wang #include "cpu-csr.h"
18f84a2aacSXiaojuan Yang 
19f84a2aacSXiaojuan Yang #define IOCSRF_TEMP             0
20f84a2aacSXiaojuan Yang #define IOCSRF_NODECNT          1
21f84a2aacSXiaojuan Yang #define IOCSRF_MSI              2
22f84a2aacSXiaojuan Yang #define IOCSRF_EXTIOI           3
23f84a2aacSXiaojuan Yang #define IOCSRF_CSRIPI           4
24f84a2aacSXiaojuan Yang #define IOCSRF_FREQCSR          5
25f84a2aacSXiaojuan Yang #define IOCSRF_FREQSCALE        6
26f84a2aacSXiaojuan Yang #define IOCSRF_DVFSV1           7
27f84a2aacSXiaojuan Yang #define IOCSRF_GMOD             9
28f84a2aacSXiaojuan Yang #define IOCSRF_VM               11
29f84a2aacSXiaojuan Yang 
30f84a2aacSXiaojuan Yang #define FEATURE_REG             0x8
31f84a2aacSXiaojuan Yang #define VENDOR_REG              0x10
32f84a2aacSXiaojuan Yang #define CPUNAME_REG             0x20
33f84a2aacSXiaojuan Yang #define MISC_FUNC_REG           0x420
34f84a2aacSXiaojuan Yang #define IOCSRM_EXTIOI_EN        48
35f84a2aacSXiaojuan Yang 
36f84a2aacSXiaojuan Yang #define IOCSR_MEM_SIZE          0x428
37228021f0SSong Gao 
38228021f0SSong Gao #define TCG_GUEST_DEFAULT_MO (0)
39228021f0SSong Gao 
40228021f0SSong Gao #define FCSR0_M1    0x1f         /* FCSR1 mask, Enables */
41228021f0SSong Gao #define FCSR0_M2    0x1f1f0000   /* FCSR2 mask, Cause and Flags */
42228021f0SSong Gao #define FCSR0_M3    0x300        /* FCSR3 mask, Round Mode */
43228021f0SSong Gao #define FCSR0_RM    8            /* Round Mode bit num on fcsr0 */
44228021f0SSong Gao 
45228021f0SSong Gao FIELD(FCSR0, ENABLES, 0, 5)
46228021f0SSong Gao FIELD(FCSR0, RM, 8, 2)
47228021f0SSong Gao FIELD(FCSR0, FLAGS, 16, 5)
48228021f0SSong Gao FIELD(FCSR0, CAUSE, 24, 5)
49228021f0SSong Gao 
50228021f0SSong Gao #define GET_FP_CAUSE(REG)      FIELD_EX32(REG, FCSR0, CAUSE)
5100952d93SQi Hu #define SET_FP_CAUSE(REG, V) \
5200952d93SQi Hu     do { \
5300952d93SQi Hu         (REG) = FIELD_DP32(REG, FCSR0, CAUSE, V); \
5400952d93SQi Hu     } while (0)
5500952d93SQi Hu 
56228021f0SSong Gao #define GET_FP_ENABLES(REG)    FIELD_EX32(REG, FCSR0, ENABLES)
5700952d93SQi Hu #define SET_FP_ENABLES(REG, V) \
5800952d93SQi Hu     do { \
5900952d93SQi Hu         (REG) = FIELD_DP32(REG, FCSR0, ENABLES, V); \
6000952d93SQi Hu     } while (0)
6100952d93SQi Hu 
62228021f0SSong Gao #define GET_FP_FLAGS(REG)      FIELD_EX32(REG, FCSR0, FLAGS)
6300952d93SQi Hu #define SET_FP_FLAGS(REG, V) \
6400952d93SQi Hu     do { \
6500952d93SQi Hu         (REG) = FIELD_DP32(REG, FCSR0, FLAGS, V); \
6600952d93SQi Hu     } while (0)
6700952d93SQi Hu 
68228021f0SSong Gao #define UPDATE_FP_FLAGS(REG, V) \
69228021f0SSong Gao     do { \
70228021f0SSong Gao         (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \
71228021f0SSong Gao     } while (0)
72228021f0SSong Gao 
73228021f0SSong Gao #define FP_INEXACT        1
74228021f0SSong Gao #define FP_UNDERFLOW      2
75228021f0SSong Gao #define FP_OVERFLOW       4
76228021f0SSong Gao #define FP_DIV0           8
77228021f0SSong Gao #define FP_INVALID        16
78228021f0SSong Gao 
79a6b129c8SSong Gao #define EXCODE(code, subcode) ( ((subcode) << 6) | (code) )
80a6b129c8SSong Gao #define EXCODE_MCODE(code)    ( (code) & 0x3f )
81a6b129c8SSong Gao #define EXCODE_SUBCODE(code)  ( (code) >> 6 )
82a6b129c8SSong Gao 
83228021f0SSong Gao #define  EXCCODE_EXTERNAL_INT        64   /* plus external interrupt number */
84a6b129c8SSong Gao #define  EXCCODE_INT                 EXCODE(0, 0)
85a6b129c8SSong Gao #define  EXCCODE_PIL                 EXCODE(1, 0)
86a6b129c8SSong Gao #define  EXCCODE_PIS                 EXCODE(2, 0)
87a6b129c8SSong Gao #define  EXCCODE_PIF                 EXCODE(3, 0)
88a6b129c8SSong Gao #define  EXCCODE_PME                 EXCODE(4, 0)
89a6b129c8SSong Gao #define  EXCCODE_PNR                 EXCODE(5, 0)
90a6b129c8SSong Gao #define  EXCCODE_PNX                 EXCODE(6, 0)
91a6b129c8SSong Gao #define  EXCCODE_PPI                 EXCODE(7, 0)
92a6b129c8SSong Gao #define  EXCCODE_ADEF                EXCODE(8, 0) /* Different exception subcode */
93a6b129c8SSong Gao #define  EXCCODE_ADEM                EXCODE(8, 1)
94a6b129c8SSong Gao #define  EXCCODE_ALE                 EXCODE(9, 0)
95a6b129c8SSong Gao #define  EXCCODE_BCE                 EXCODE(10, 0)
96a6b129c8SSong Gao #define  EXCCODE_SYS                 EXCODE(11, 0)
97a6b129c8SSong Gao #define  EXCCODE_BRK                 EXCODE(12, 0)
98a6b129c8SSong Gao #define  EXCCODE_INE                 EXCODE(13, 0)
99a6b129c8SSong Gao #define  EXCCODE_IPE                 EXCODE(14, 0)
100a6b129c8SSong Gao #define  EXCCODE_FPD                 EXCODE(15, 0)
101a6b129c8SSong Gao #define  EXCCODE_SXD                 EXCODE(16, 0)
102a6b129c8SSong Gao #define  EXCCODE_ASXD                EXCODE(17, 0)
103a6b129c8SSong Gao #define  EXCCODE_FPE                 EXCODE(18, 0) /* Different exception subcode */
104a6b129c8SSong Gao #define  EXCCODE_VFPE                EXCODE(18, 1)
105a6b129c8SSong Gao #define  EXCCODE_WPEF                EXCODE(19, 0) /* Different exception subcode */
106a6b129c8SSong Gao #define  EXCCODE_WPEM                EXCODE(19, 1)
107a6b129c8SSong Gao #define  EXCCODE_BTD                 EXCODE(20, 0)
108a6b129c8SSong Gao #define  EXCCODE_BTE                 EXCODE(21, 0)
109a6b129c8SSong Gao #define  EXCCODE_DBP                 EXCODE(26, 0) /* Reserved subcode used for debug */
110228021f0SSong Gao 
111228021f0SSong Gao /* cpucfg[0] bits */
112228021f0SSong Gao FIELD(CPUCFG0, PRID, 0, 32)
113228021f0SSong Gao 
114228021f0SSong Gao /* cpucfg[1] bits */
115228021f0SSong Gao FIELD(CPUCFG1, ARCH, 0, 2)
116228021f0SSong Gao FIELD(CPUCFG1, PGMMU, 2, 1)
117228021f0SSong Gao FIELD(CPUCFG1, IOCSR, 3, 1)
118228021f0SSong Gao FIELD(CPUCFG1, PALEN, 4, 8)
119228021f0SSong Gao FIELD(CPUCFG1, VALEN, 12, 8)
120228021f0SSong Gao FIELD(CPUCFG1, UAL, 20, 1)
121228021f0SSong Gao FIELD(CPUCFG1, RI, 21, 1)
122228021f0SSong Gao FIELD(CPUCFG1, EP, 22, 1)
123228021f0SSong Gao FIELD(CPUCFG1, RPLV, 23, 1)
124228021f0SSong Gao FIELD(CPUCFG1, HP, 24, 1)
125228021f0SSong Gao FIELD(CPUCFG1, IOCSR_BRD, 25, 1)
126228021f0SSong Gao FIELD(CPUCFG1, MSG_INT, 26, 1)
127228021f0SSong Gao 
128228021f0SSong Gao /* cpucfg[2] bits */
129228021f0SSong Gao FIELD(CPUCFG2, FP, 0, 1)
130228021f0SSong Gao FIELD(CPUCFG2, FP_SP, 1, 1)
131228021f0SSong Gao FIELD(CPUCFG2, FP_DP, 2, 1)
132228021f0SSong Gao FIELD(CPUCFG2, FP_VER, 3, 3)
133228021f0SSong Gao FIELD(CPUCFG2, LSX, 6, 1)
134228021f0SSong Gao FIELD(CPUCFG2, LASX, 7, 1)
135228021f0SSong Gao FIELD(CPUCFG2, COMPLEX, 8, 1)
136228021f0SSong Gao FIELD(CPUCFG2, CRYPTO, 9, 1)
137228021f0SSong Gao FIELD(CPUCFG2, LVZ, 10, 1)
138228021f0SSong Gao FIELD(CPUCFG2, LVZ_VER, 11, 3)
139228021f0SSong Gao FIELD(CPUCFG2, LLFTP, 14, 1)
140228021f0SSong Gao FIELD(CPUCFG2, LLFTP_VER, 15, 3)
141228021f0SSong Gao FIELD(CPUCFG2, LBT_X86, 18, 1)
142228021f0SSong Gao FIELD(CPUCFG2, LBT_ARM, 19, 1)
143228021f0SSong Gao FIELD(CPUCFG2, LBT_MIPS, 20, 1)
144228021f0SSong Gao FIELD(CPUCFG2, LSPW, 21, 1)
145228021f0SSong Gao FIELD(CPUCFG2, LAM, 22, 1)
146228021f0SSong Gao 
147228021f0SSong Gao /* cpucfg[3] bits */
148228021f0SSong Gao FIELD(CPUCFG3, CCDMA, 0, 1)
149228021f0SSong Gao FIELD(CPUCFG3, SFB, 1, 1)
150228021f0SSong Gao FIELD(CPUCFG3, UCACC, 2, 1)
151228021f0SSong Gao FIELD(CPUCFG3, LLEXC, 3, 1)
152228021f0SSong Gao FIELD(CPUCFG3, SCDLY, 4, 1)
153228021f0SSong Gao FIELD(CPUCFG3, LLDBAR, 5, 1)
154228021f0SSong Gao FIELD(CPUCFG3, ITLBHMC, 6, 1)
155228021f0SSong Gao FIELD(CPUCFG3, ICHMC, 7, 1)
156228021f0SSong Gao FIELD(CPUCFG3, SPW_LVL, 8, 3)
157228021f0SSong Gao FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
158228021f0SSong Gao FIELD(CPUCFG3, RVA, 12, 1)
159228021f0SSong Gao FIELD(CPUCFG3, RVAMAX, 13, 4)
160228021f0SSong Gao 
161228021f0SSong Gao /* cpucfg[4] bits */
162228021f0SSong Gao FIELD(CPUCFG4, CC_FREQ, 0, 32)
163228021f0SSong Gao 
164228021f0SSong Gao /* cpucfg[5] bits */
165228021f0SSong Gao FIELD(CPUCFG5, CC_MUL, 0, 16)
166228021f0SSong Gao FIELD(CPUCFG5, CC_DIV, 16, 16)
167228021f0SSong Gao 
168228021f0SSong Gao /* cpucfg[6] bits */
169228021f0SSong Gao FIELD(CPUCFG6, PMP, 0, 1)
170228021f0SSong Gao FIELD(CPUCFG6, PMVER, 1, 3)
171228021f0SSong Gao FIELD(CPUCFG6, PMNUM, 4, 4)
172228021f0SSong Gao FIELD(CPUCFG6, PMBITS, 8, 6)
173228021f0SSong Gao FIELD(CPUCFG6, UPM, 14, 1)
174228021f0SSong Gao 
175228021f0SSong Gao /* cpucfg[16] bits */
176228021f0SSong Gao FIELD(CPUCFG16, L1_IUPRE, 0, 1)
177228021f0SSong Gao FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
178228021f0SSong Gao FIELD(CPUCFG16, L1_DPRE, 2, 1)
179228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRE, 3, 1)
180228021f0SSong Gao FIELD(CPUCFG16, L2_IUUNIFY, 4, 1)
181228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRIV, 5, 1)
182228021f0SSong Gao FIELD(CPUCFG16, L2_IUINCL, 6, 1)
183228021f0SSong Gao FIELD(CPUCFG16, L2_DPRE, 7, 1)
184228021f0SSong Gao FIELD(CPUCFG16, L2_DPRIV, 8, 1)
185228021f0SSong Gao FIELD(CPUCFG16, L2_DINCL, 9, 1)
186228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRE, 10, 1)
187228021f0SSong Gao FIELD(CPUCFG16, L3_IUUNIFY, 11, 1)
188228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRIV, 12, 1)
189228021f0SSong Gao FIELD(CPUCFG16, L3_IUINCL, 13, 1)
190228021f0SSong Gao FIELD(CPUCFG16, L3_DPRE, 14, 1)
191228021f0SSong Gao FIELD(CPUCFG16, L3_DPRIV, 15, 1)
192228021f0SSong Gao FIELD(CPUCFG16, L3_DINCL, 16, 1)
193228021f0SSong Gao 
194228021f0SSong Gao /* cpucfg[17] bits */
195228021f0SSong Gao FIELD(CPUCFG17, L1IU_WAYS, 0, 16)
196228021f0SSong Gao FIELD(CPUCFG17, L1IU_SETS, 16, 8)
197228021f0SSong Gao FIELD(CPUCFG17, L1IU_SIZE, 24, 7)
198228021f0SSong Gao 
199228021f0SSong Gao /* cpucfg[18] bits */
200228021f0SSong Gao FIELD(CPUCFG18, L1D_WAYS, 0, 16)
201228021f0SSong Gao FIELD(CPUCFG18, L1D_SETS, 16, 8)
202228021f0SSong Gao FIELD(CPUCFG18, L1D_SIZE, 24, 7)
203228021f0SSong Gao 
204228021f0SSong Gao /* cpucfg[19] bits */
205228021f0SSong Gao FIELD(CPUCFG19, L2IU_WAYS, 0, 16)
206228021f0SSong Gao FIELD(CPUCFG19, L2IU_SETS, 16, 8)
207228021f0SSong Gao FIELD(CPUCFG19, L2IU_SIZE, 24, 7)
208228021f0SSong Gao 
209228021f0SSong Gao /* cpucfg[20] bits */
210228021f0SSong Gao FIELD(CPUCFG20, L3IU_WAYS, 0, 16)
211228021f0SSong Gao FIELD(CPUCFG20, L3IU_SETS, 16, 8)
212228021f0SSong Gao FIELD(CPUCFG20, L3IU_SIZE, 24, 7)
213228021f0SSong Gao 
214398cecb9SXiaojuan Yang /*CSR_CRMD */
215398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PLV, 0, 2)
216398cecb9SXiaojuan Yang FIELD(CSR_CRMD, IE, 2, 1)
217398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DA, 3, 1)
218398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PG, 4, 1)
219398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATF, 5, 2)
220398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATM, 7, 2)
221398cecb9SXiaojuan Yang FIELD(CSR_CRMD, WE, 9, 1)
222398cecb9SXiaojuan Yang 
223228021f0SSong Gao extern const char * const regnames[32];
224228021f0SSong Gao extern const char * const fregnames[32];
225228021f0SSong Gao 
226f757a2cdSXiaojuan Yang #define N_IRQS      13
227dd615fa4SXiaojuan Yang #define IRQ_TIMER   11
228dd615fa4SXiaojuan Yang #define IRQ_IPI     12
229f757a2cdSXiaojuan Yang 
2307e1c521eSXiaojuan Yang #define LOONGARCH_STLB         2048 /* 2048 STLB */
2317e1c521eSXiaojuan Yang #define LOONGARCH_MTLB         64   /* 64 MTLB */
2327e1c521eSXiaojuan Yang #define LOONGARCH_TLB_MAX      (LOONGARCH_STLB + LOONGARCH_MTLB)
2337e1c521eSXiaojuan Yang 
2347e1c521eSXiaojuan Yang /*
2357e1c521eSXiaojuan Yang  * define the ASID PS E VPPN field of TLB
2367e1c521eSXiaojuan Yang  */
2377e1c521eSXiaojuan Yang FIELD(TLB_MISC, E, 0, 1)
2387e1c521eSXiaojuan Yang FIELD(TLB_MISC, ASID, 1, 10)
2397e1c521eSXiaojuan Yang FIELD(TLB_MISC, VPPN, 13, 35)
2407e1c521eSXiaojuan Yang FIELD(TLB_MISC, PS, 48, 6)
2417e1c521eSXiaojuan Yang 
2427e1c521eSXiaojuan Yang struct LoongArchTLB {
2437e1c521eSXiaojuan Yang     uint64_t tlb_misc;
2447e1c521eSXiaojuan Yang     /* Fields corresponding to CSR_TLBELO0/1 */
2457e1c521eSXiaojuan Yang     uint64_t tlb_entry0;
2467e1c521eSXiaojuan Yang     uint64_t tlb_entry1;
2477e1c521eSXiaojuan Yang };
2487e1c521eSXiaojuan Yang typedef struct LoongArchTLB LoongArchTLB;
2497e1c521eSXiaojuan Yang 
250228021f0SSong Gao typedef struct CPUArchState {
251228021f0SSong Gao     uint64_t gpr[32];
252228021f0SSong Gao     uint64_t pc;
253228021f0SSong Gao 
254228021f0SSong Gao     uint64_t fpr[32];
255228021f0SSong Gao     float_status fp_status;
256228021f0SSong Gao     bool cf[8];
257228021f0SSong Gao 
258228021f0SSong Gao     uint32_t fcsr0;
259228021f0SSong Gao     uint32_t fcsr0_mask;
260228021f0SSong Gao 
261228021f0SSong Gao     uint32_t cpucfg[21];
262228021f0SSong Gao 
263228021f0SSong Gao     uint64_t lladdr; /* LL virtual address compared against SC */
264228021f0SSong Gao     uint64_t llval;
265228021f0SSong Gao 
266398cecb9SXiaojuan Yang     /* LoongArch CSRs */
267398cecb9SXiaojuan Yang     uint64_t CSR_CRMD;
268398cecb9SXiaojuan Yang     uint64_t CSR_PRMD;
269398cecb9SXiaojuan Yang     uint64_t CSR_EUEN;
270398cecb9SXiaojuan Yang     uint64_t CSR_MISC;
271398cecb9SXiaojuan Yang     uint64_t CSR_ECFG;
272398cecb9SXiaojuan Yang     uint64_t CSR_ESTAT;
273398cecb9SXiaojuan Yang     uint64_t CSR_ERA;
274398cecb9SXiaojuan Yang     uint64_t CSR_BADV;
275398cecb9SXiaojuan Yang     uint64_t CSR_BADI;
276398cecb9SXiaojuan Yang     uint64_t CSR_EENTRY;
277398cecb9SXiaojuan Yang     uint64_t CSR_TLBIDX;
278398cecb9SXiaojuan Yang     uint64_t CSR_TLBEHI;
279398cecb9SXiaojuan Yang     uint64_t CSR_TLBELO0;
280398cecb9SXiaojuan Yang     uint64_t CSR_TLBELO1;
281398cecb9SXiaojuan Yang     uint64_t CSR_ASID;
282398cecb9SXiaojuan Yang     uint64_t CSR_PGDL;
283398cecb9SXiaojuan Yang     uint64_t CSR_PGDH;
284398cecb9SXiaojuan Yang     uint64_t CSR_PGD;
285398cecb9SXiaojuan Yang     uint64_t CSR_PWCL;
286398cecb9SXiaojuan Yang     uint64_t CSR_PWCH;
287398cecb9SXiaojuan Yang     uint64_t CSR_STLBPS;
288398cecb9SXiaojuan Yang     uint64_t CSR_RVACFG;
289398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG1;
290398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG2;
291398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG3;
292398cecb9SXiaojuan Yang     uint64_t CSR_SAVE[16];
293398cecb9SXiaojuan Yang     uint64_t CSR_TID;
294398cecb9SXiaojuan Yang     uint64_t CSR_TCFG;
295398cecb9SXiaojuan Yang     uint64_t CSR_TVAL;
296398cecb9SXiaojuan Yang     uint64_t CSR_CNTC;
297398cecb9SXiaojuan Yang     uint64_t CSR_TICLR;
298398cecb9SXiaojuan Yang     uint64_t CSR_LLBCTL;
299398cecb9SXiaojuan Yang     uint64_t CSR_IMPCTL1;
300398cecb9SXiaojuan Yang     uint64_t CSR_IMPCTL2;
301398cecb9SXiaojuan Yang     uint64_t CSR_TLBRENTRY;
302398cecb9SXiaojuan Yang     uint64_t CSR_TLBRBADV;
303398cecb9SXiaojuan Yang     uint64_t CSR_TLBRERA;
304398cecb9SXiaojuan Yang     uint64_t CSR_TLBRSAVE;
305398cecb9SXiaojuan Yang     uint64_t CSR_TLBRELO0;
306398cecb9SXiaojuan Yang     uint64_t CSR_TLBRELO1;
307398cecb9SXiaojuan Yang     uint64_t CSR_TLBREHI;
308398cecb9SXiaojuan Yang     uint64_t CSR_TLBRPRMD;
309398cecb9SXiaojuan Yang     uint64_t CSR_MERRCTL;
310398cecb9SXiaojuan Yang     uint64_t CSR_MERRINFO1;
311398cecb9SXiaojuan Yang     uint64_t CSR_MERRINFO2;
312398cecb9SXiaojuan Yang     uint64_t CSR_MERRENTRY;
313398cecb9SXiaojuan Yang     uint64_t CSR_MERRERA;
314398cecb9SXiaojuan Yang     uint64_t CSR_MERRSAVE;
315398cecb9SXiaojuan Yang     uint64_t CSR_CTAG;
316398cecb9SXiaojuan Yang     uint64_t CSR_DMW[4];
317398cecb9SXiaojuan Yang     uint64_t CSR_DBG;
318398cecb9SXiaojuan Yang     uint64_t CSR_DERA;
319398cecb9SXiaojuan Yang     uint64_t CSR_DSAVE;
3207e1c521eSXiaojuan Yang 
3210093b9a5SSong Gao #ifndef CONFIG_USER_ONLY
3227e1c521eSXiaojuan Yang     LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
323f84a2aacSXiaojuan Yang 
324f84a2aacSXiaojuan Yang     AddressSpace address_space_iocsr;
325f84a2aacSXiaojuan Yang     MemoryRegion system_iocsr;
326f84a2aacSXiaojuan Yang     MemoryRegion iocsr_mem;
3276a6f26f4SXiaojuan Yang     bool load_elf;
3286a6f26f4SXiaojuan Yang     uint64_t elf_address;
3290093b9a5SSong Gao #endif
330228021f0SSong Gao } CPULoongArchState;
331228021f0SSong Gao 
332228021f0SSong Gao /**
333228021f0SSong Gao  * LoongArchCPU:
334228021f0SSong Gao  * @env: #CPULoongArchState
335228021f0SSong Gao  *
336228021f0SSong Gao  * A LoongArch CPU.
337228021f0SSong Gao  */
338228021f0SSong Gao struct ArchCPU {
339228021f0SSong Gao     /*< private >*/
340228021f0SSong Gao     CPUState parent_obj;
341228021f0SSong Gao     /*< public >*/
342228021f0SSong Gao 
343228021f0SSong Gao     CPUNegativeOffsetState neg;
344228021f0SSong Gao     CPULoongArchState env;
345dd615fa4SXiaojuan Yang     QEMUTimer timer;
346fda3f15bSXiaojuan Yang 
347fda3f15bSXiaojuan Yang     /* 'compatible' string for this CPU for Linux device trees */
348fda3f15bSXiaojuan Yang     const char *dtb_compatible;
349228021f0SSong Gao };
350228021f0SSong Gao 
351228021f0SSong Gao #define TYPE_LOONGARCH_CPU "loongarch-cpu"
352228021f0SSong Gao 
353228021f0SSong Gao OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass,
354228021f0SSong Gao                         LOONGARCH_CPU)
355228021f0SSong Gao 
356228021f0SSong Gao /**
357228021f0SSong Gao  * LoongArchCPUClass:
358228021f0SSong Gao  * @parent_realize: The parent class' realize handler.
359*f78b49aeSPeter Maydell  * @parent_phases: The parent class' reset phase handlers.
360228021f0SSong Gao  *
361228021f0SSong Gao  * A LoongArch CPU model.
362228021f0SSong Gao  */
363228021f0SSong Gao struct LoongArchCPUClass {
364228021f0SSong Gao     /*< private >*/
365228021f0SSong Gao     CPUClass parent_class;
366228021f0SSong Gao     /*< public >*/
367228021f0SSong Gao 
368228021f0SSong Gao     DeviceRealize parent_realize;
369*f78b49aeSPeter Maydell     ResettablePhases parent_phases;
370228021f0SSong Gao };
371228021f0SSong Gao 
3727e1c521eSXiaojuan Yang /*
3737e1c521eSXiaojuan Yang  * LoongArch CPUs has 4 privilege levels.
3747e1c521eSXiaojuan Yang  * 0 for kernel mode, 3 for user mode.
3757e1c521eSXiaojuan Yang  * Define an extra index for DA(direct addressing) mode.
3767e1c521eSXiaojuan Yang  */
377c8885b88SRui Wang #define MMU_PLV_KERNEL   0
378c8885b88SRui Wang #define MMU_PLV_USER     3
379c8885b88SRui Wang #define MMU_IDX_KERNEL   MMU_PLV_KERNEL
380c8885b88SRui Wang #define MMU_IDX_USER     MMU_PLV_USER
381c8885b88SRui Wang #define MMU_IDX_DA       4
3827e1c521eSXiaojuan Yang 
3837e1c521eSXiaojuan Yang static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
3847e1c521eSXiaojuan Yang {
3850093b9a5SSong Gao #ifdef CONFIG_USER_ONLY
386c8885b88SRui Wang     return MMU_IDX_USER;
3870093b9a5SSong Gao #else
388c8885b88SRui Wang     if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) {
3897e1c521eSXiaojuan Yang         return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
390c8885b88SRui Wang     }
391c8885b88SRui Wang     return MMU_IDX_DA;
3920093b9a5SSong Gao #endif
3937e1c521eSXiaojuan Yang }
3947e1c521eSXiaojuan Yang 
395b4bda200SRui Wang /*
396b4bda200SRui Wang  * LoongArch CPUs hardware flags.
397b4bda200SRui Wang  */
398b4bda200SRui Wang #define HW_FLAGS_PLV_MASK   R_CSR_CRMD_PLV_MASK  /* 0x03 */
399b4bda200SRui Wang #define HW_FLAGS_CRMD_PG    R_CSR_CRMD_PG_MASK   /* 0x10 */
4002419978cSRui Wang #define HW_FLAGS_EUEN_FPE   0x04
401b4bda200SRui Wang 
4027e1c521eSXiaojuan Yang static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
4037e1c521eSXiaojuan Yang                                         target_ulong *pc,
4047e1c521eSXiaojuan Yang                                         target_ulong *cs_base,
4057e1c521eSXiaojuan Yang                                         uint32_t *flags)
4067e1c521eSXiaojuan Yang {
4077e1c521eSXiaojuan Yang     *pc = env->pc;
4087e1c521eSXiaojuan Yang     *cs_base = 0;
409b4bda200SRui Wang     *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
4102419978cSRui Wang     *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
4117e1c521eSXiaojuan Yang }
4127e1c521eSXiaojuan Yang 
413228021f0SSong Gao void loongarch_cpu_list(void);
414228021f0SSong Gao 
415228021f0SSong Gao #define cpu_list loongarch_cpu_list
416228021f0SSong Gao 
417228021f0SSong Gao #include "exec/cpu-all.h"
418228021f0SSong Gao 
419228021f0SSong Gao #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
420228021f0SSong Gao #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
421228021f0SSong Gao #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
422228021f0SSong Gao 
423228021f0SSong Gao #endif /* LOONGARCH_CPU_H */
424