xref: /qemu/target/loongarch/cpu.h (revision f84a2aacf5d1679b1d1cceabb6006e02864232f3)
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"
15*f84a2aacSXiaojuan Yang #include "exec/memory.h"
16*f84a2aacSXiaojuan Yang #include "hw/sysbus.h"
17*f84a2aacSXiaojuan Yang 
18*f84a2aacSXiaojuan Yang #define IOCSRF_TEMP             0
19*f84a2aacSXiaojuan Yang #define IOCSRF_NODECNT          1
20*f84a2aacSXiaojuan Yang #define IOCSRF_MSI              2
21*f84a2aacSXiaojuan Yang #define IOCSRF_EXTIOI           3
22*f84a2aacSXiaojuan Yang #define IOCSRF_CSRIPI           4
23*f84a2aacSXiaojuan Yang #define IOCSRF_FREQCSR          5
24*f84a2aacSXiaojuan Yang #define IOCSRF_FREQSCALE        6
25*f84a2aacSXiaojuan Yang #define IOCSRF_DVFSV1           7
26*f84a2aacSXiaojuan Yang #define IOCSRF_GMOD             9
27*f84a2aacSXiaojuan Yang #define IOCSRF_VM               11
28*f84a2aacSXiaojuan Yang 
29*f84a2aacSXiaojuan Yang #define FEATURE_REG             0x8
30*f84a2aacSXiaojuan Yang #define VENDOR_REG              0x10
31*f84a2aacSXiaojuan Yang #define CPUNAME_REG             0x20
32*f84a2aacSXiaojuan Yang #define MISC_FUNC_REG           0x420
33*f84a2aacSXiaojuan Yang #define IOCSRM_EXTIOI_EN        48
34*f84a2aacSXiaojuan Yang 
35*f84a2aacSXiaojuan Yang #define IOCSR_MEM_SIZE          0x428
36228021f0SSong Gao 
37228021f0SSong Gao #define TCG_GUEST_DEFAULT_MO (0)
38228021f0SSong Gao 
39228021f0SSong Gao #define FCSR0_M1    0x1f         /* FCSR1 mask, Enables */
40228021f0SSong Gao #define FCSR0_M2    0x1f1f0000   /* FCSR2 mask, Cause and Flags */
41228021f0SSong Gao #define FCSR0_M3    0x300        /* FCSR3 mask, Round Mode */
42228021f0SSong Gao #define FCSR0_RM    8            /* Round Mode bit num on fcsr0 */
43228021f0SSong Gao 
44228021f0SSong Gao FIELD(FCSR0, ENABLES, 0, 5)
45228021f0SSong Gao FIELD(FCSR0, RM, 8, 2)
46228021f0SSong Gao FIELD(FCSR0, FLAGS, 16, 5)
47228021f0SSong Gao FIELD(FCSR0, CAUSE, 24, 5)
48228021f0SSong Gao 
49228021f0SSong Gao #define GET_FP_CAUSE(REG)      FIELD_EX32(REG, FCSR0, CAUSE)
50228021f0SSong Gao #define SET_FP_CAUSE(REG, V)   FIELD_DP32(REG, FCSR0, CAUSE, V)
51228021f0SSong Gao #define GET_FP_ENABLES(REG)    FIELD_EX32(REG, FCSR0, ENABLES)
52228021f0SSong Gao #define SET_FP_ENABLES(REG, V) FIELD_DP32(REG, FCSR0, ENABLES, V)
53228021f0SSong Gao #define GET_FP_FLAGS(REG)      FIELD_EX32(REG, FCSR0, FLAGS)
54228021f0SSong Gao #define SET_FP_FLAGS(REG, V)   FIELD_DP32(REG, FCSR0, FLAGS, V)
55228021f0SSong Gao #define UPDATE_FP_FLAGS(REG, V) \
56228021f0SSong Gao     do { \
57228021f0SSong Gao         (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \
58228021f0SSong Gao     } while (0)
59228021f0SSong Gao 
60228021f0SSong Gao #define FP_INEXACT        1
61228021f0SSong Gao #define FP_UNDERFLOW      2
62228021f0SSong Gao #define FP_OVERFLOW       4
63228021f0SSong Gao #define FP_DIV0           8
64228021f0SSong Gao #define FP_INVALID        16
65228021f0SSong Gao 
66228021f0SSong Gao #define  EXCCODE_EXTERNAL_INT   64   /* plus external interrupt number */
67228021f0SSong Gao #define  EXCCODE_INT                 0
68228021f0SSong Gao #define  EXCCODE_PIL                 1
69228021f0SSong Gao #define  EXCCODE_PIS                 2
70228021f0SSong Gao #define  EXCCODE_PIF                 3
71228021f0SSong Gao #define  EXCCODE_PME                 4
72228021f0SSong Gao #define  EXCCODE_PNR                 5
73228021f0SSong Gao #define  EXCCODE_PNX                 6
74228021f0SSong Gao #define  EXCCODE_PPI                 7
75228021f0SSong Gao #define  EXCCODE_ADEF                8 /* Different exception subcode */
76228021f0SSong Gao #define  EXCCODE_ADEM                8
77228021f0SSong Gao #define  EXCCODE_ALE                 9
78228021f0SSong Gao #define  EXCCODE_BCE                 10
79228021f0SSong Gao #define  EXCCODE_SYS                 11
80228021f0SSong Gao #define  EXCCODE_BRK                 12
81228021f0SSong Gao #define  EXCCODE_INE                 13
82228021f0SSong Gao #define  EXCCODE_IPE                 14
83228021f0SSong Gao #define  EXCCODE_FPD                 15
84228021f0SSong Gao #define  EXCCODE_SXD                 16
85228021f0SSong Gao #define  EXCCODE_ASXD                17
86228021f0SSong Gao #define  EXCCODE_FPE                 18 /* Different exception subcode */
87228021f0SSong Gao #define  EXCCODE_VFPE                18
88228021f0SSong Gao #define  EXCCODE_WPEF                19 /* Different exception subcode */
89228021f0SSong Gao #define  EXCCODE_WPEM                19
90228021f0SSong Gao #define  EXCCODE_BTD                 20
91228021f0SSong Gao #define  EXCCODE_BTE                 21
92228021f0SSong Gao #define  EXCCODE_DBP                 26 /* Reserved subcode used for debug */
93228021f0SSong Gao 
94228021f0SSong Gao /* cpucfg[0] bits */
95228021f0SSong Gao FIELD(CPUCFG0, PRID, 0, 32)
96228021f0SSong Gao 
97228021f0SSong Gao /* cpucfg[1] bits */
98228021f0SSong Gao FIELD(CPUCFG1, ARCH, 0, 2)
99228021f0SSong Gao FIELD(CPUCFG1, PGMMU, 2, 1)
100228021f0SSong Gao FIELD(CPUCFG1, IOCSR, 3, 1)
101228021f0SSong Gao FIELD(CPUCFG1, PALEN, 4, 8)
102228021f0SSong Gao FIELD(CPUCFG1, VALEN, 12, 8)
103228021f0SSong Gao FIELD(CPUCFG1, UAL, 20, 1)
104228021f0SSong Gao FIELD(CPUCFG1, RI, 21, 1)
105228021f0SSong Gao FIELD(CPUCFG1, EP, 22, 1)
106228021f0SSong Gao FIELD(CPUCFG1, RPLV, 23, 1)
107228021f0SSong Gao FIELD(CPUCFG1, HP, 24, 1)
108228021f0SSong Gao FIELD(CPUCFG1, IOCSR_BRD, 25, 1)
109228021f0SSong Gao FIELD(CPUCFG1, MSG_INT, 26, 1)
110228021f0SSong Gao 
111228021f0SSong Gao /* cpucfg[2] bits */
112228021f0SSong Gao FIELD(CPUCFG2, FP, 0, 1)
113228021f0SSong Gao FIELD(CPUCFG2, FP_SP, 1, 1)
114228021f0SSong Gao FIELD(CPUCFG2, FP_DP, 2, 1)
115228021f0SSong Gao FIELD(CPUCFG2, FP_VER, 3, 3)
116228021f0SSong Gao FIELD(CPUCFG2, LSX, 6, 1)
117228021f0SSong Gao FIELD(CPUCFG2, LASX, 7, 1)
118228021f0SSong Gao FIELD(CPUCFG2, COMPLEX, 8, 1)
119228021f0SSong Gao FIELD(CPUCFG2, CRYPTO, 9, 1)
120228021f0SSong Gao FIELD(CPUCFG2, LVZ, 10, 1)
121228021f0SSong Gao FIELD(CPUCFG2, LVZ_VER, 11, 3)
122228021f0SSong Gao FIELD(CPUCFG2, LLFTP, 14, 1)
123228021f0SSong Gao FIELD(CPUCFG2, LLFTP_VER, 15, 3)
124228021f0SSong Gao FIELD(CPUCFG2, LBT_X86, 18, 1)
125228021f0SSong Gao FIELD(CPUCFG2, LBT_ARM, 19, 1)
126228021f0SSong Gao FIELD(CPUCFG2, LBT_MIPS, 20, 1)
127228021f0SSong Gao FIELD(CPUCFG2, LSPW, 21, 1)
128228021f0SSong Gao FIELD(CPUCFG2, LAM, 22, 1)
129228021f0SSong Gao 
130228021f0SSong Gao /* cpucfg[3] bits */
131228021f0SSong Gao FIELD(CPUCFG3, CCDMA, 0, 1)
132228021f0SSong Gao FIELD(CPUCFG3, SFB, 1, 1)
133228021f0SSong Gao FIELD(CPUCFG3, UCACC, 2, 1)
134228021f0SSong Gao FIELD(CPUCFG3, LLEXC, 3, 1)
135228021f0SSong Gao FIELD(CPUCFG3, SCDLY, 4, 1)
136228021f0SSong Gao FIELD(CPUCFG3, LLDBAR, 5, 1)
137228021f0SSong Gao FIELD(CPUCFG3, ITLBHMC, 6, 1)
138228021f0SSong Gao FIELD(CPUCFG3, ICHMC, 7, 1)
139228021f0SSong Gao FIELD(CPUCFG3, SPW_LVL, 8, 3)
140228021f0SSong Gao FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
141228021f0SSong Gao FIELD(CPUCFG3, RVA, 12, 1)
142228021f0SSong Gao FIELD(CPUCFG3, RVAMAX, 13, 4)
143228021f0SSong Gao 
144228021f0SSong Gao /* cpucfg[4] bits */
145228021f0SSong Gao FIELD(CPUCFG4, CC_FREQ, 0, 32)
146228021f0SSong Gao 
147228021f0SSong Gao /* cpucfg[5] bits */
148228021f0SSong Gao FIELD(CPUCFG5, CC_MUL, 0, 16)
149228021f0SSong Gao FIELD(CPUCFG5, CC_DIV, 16, 16)
150228021f0SSong Gao 
151228021f0SSong Gao /* cpucfg[6] bits */
152228021f0SSong Gao FIELD(CPUCFG6, PMP, 0, 1)
153228021f0SSong Gao FIELD(CPUCFG6, PMVER, 1, 3)
154228021f0SSong Gao FIELD(CPUCFG6, PMNUM, 4, 4)
155228021f0SSong Gao FIELD(CPUCFG6, PMBITS, 8, 6)
156228021f0SSong Gao FIELD(CPUCFG6, UPM, 14, 1)
157228021f0SSong Gao 
158228021f0SSong Gao /* cpucfg[16] bits */
159228021f0SSong Gao FIELD(CPUCFG16, L1_IUPRE, 0, 1)
160228021f0SSong Gao FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
161228021f0SSong Gao FIELD(CPUCFG16, L1_DPRE, 2, 1)
162228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRE, 3, 1)
163228021f0SSong Gao FIELD(CPUCFG16, L2_IUUNIFY, 4, 1)
164228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRIV, 5, 1)
165228021f0SSong Gao FIELD(CPUCFG16, L2_IUINCL, 6, 1)
166228021f0SSong Gao FIELD(CPUCFG16, L2_DPRE, 7, 1)
167228021f0SSong Gao FIELD(CPUCFG16, L2_DPRIV, 8, 1)
168228021f0SSong Gao FIELD(CPUCFG16, L2_DINCL, 9, 1)
169228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRE, 10, 1)
170228021f0SSong Gao FIELD(CPUCFG16, L3_IUUNIFY, 11, 1)
171228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRIV, 12, 1)
172228021f0SSong Gao FIELD(CPUCFG16, L3_IUINCL, 13, 1)
173228021f0SSong Gao FIELD(CPUCFG16, L3_DPRE, 14, 1)
174228021f0SSong Gao FIELD(CPUCFG16, L3_DPRIV, 15, 1)
175228021f0SSong Gao FIELD(CPUCFG16, L3_DINCL, 16, 1)
176228021f0SSong Gao 
177228021f0SSong Gao /* cpucfg[17] bits */
178228021f0SSong Gao FIELD(CPUCFG17, L1IU_WAYS, 0, 16)
179228021f0SSong Gao FIELD(CPUCFG17, L1IU_SETS, 16, 8)
180228021f0SSong Gao FIELD(CPUCFG17, L1IU_SIZE, 24, 7)
181228021f0SSong Gao 
182228021f0SSong Gao /* cpucfg[18] bits */
183228021f0SSong Gao FIELD(CPUCFG18, L1D_WAYS, 0, 16)
184228021f0SSong Gao FIELD(CPUCFG18, L1D_SETS, 16, 8)
185228021f0SSong Gao FIELD(CPUCFG18, L1D_SIZE, 24, 7)
186228021f0SSong Gao 
187228021f0SSong Gao /* cpucfg[19] bits */
188228021f0SSong Gao FIELD(CPUCFG19, L2IU_WAYS, 0, 16)
189228021f0SSong Gao FIELD(CPUCFG19, L2IU_SETS, 16, 8)
190228021f0SSong Gao FIELD(CPUCFG19, L2IU_SIZE, 24, 7)
191228021f0SSong Gao 
192228021f0SSong Gao /* cpucfg[20] bits */
193228021f0SSong Gao FIELD(CPUCFG20, L3IU_WAYS, 0, 16)
194228021f0SSong Gao FIELD(CPUCFG20, L3IU_SETS, 16, 8)
195228021f0SSong Gao FIELD(CPUCFG20, L3IU_SIZE, 24, 7)
196228021f0SSong Gao 
197398cecb9SXiaojuan Yang /*CSR_CRMD */
198398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PLV, 0, 2)
199398cecb9SXiaojuan Yang FIELD(CSR_CRMD, IE, 2, 1)
200398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DA, 3, 1)
201398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PG, 4, 1)
202398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATF, 5, 2)
203398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATM, 7, 2)
204398cecb9SXiaojuan Yang FIELD(CSR_CRMD, WE, 9, 1)
205398cecb9SXiaojuan Yang 
206228021f0SSong Gao extern const char * const regnames[32];
207228021f0SSong Gao extern const char * const fregnames[32];
208228021f0SSong Gao 
209f757a2cdSXiaojuan Yang #define N_IRQS      13
210dd615fa4SXiaojuan Yang #define IRQ_TIMER   11
211dd615fa4SXiaojuan Yang #define IRQ_IPI     12
212f757a2cdSXiaojuan Yang 
2137e1c521eSXiaojuan Yang #define LOONGARCH_STLB         2048 /* 2048 STLB */
2147e1c521eSXiaojuan Yang #define LOONGARCH_MTLB         64   /* 64 MTLB */
2157e1c521eSXiaojuan Yang #define LOONGARCH_TLB_MAX      (LOONGARCH_STLB + LOONGARCH_MTLB)
2167e1c521eSXiaojuan Yang 
2177e1c521eSXiaojuan Yang /*
2187e1c521eSXiaojuan Yang  * define the ASID PS E VPPN field of TLB
2197e1c521eSXiaojuan Yang  */
2207e1c521eSXiaojuan Yang FIELD(TLB_MISC, E, 0, 1)
2217e1c521eSXiaojuan Yang FIELD(TLB_MISC, ASID, 1, 10)
2227e1c521eSXiaojuan Yang FIELD(TLB_MISC, VPPN, 13, 35)
2237e1c521eSXiaojuan Yang FIELD(TLB_MISC, PS, 48, 6)
2247e1c521eSXiaojuan Yang 
2257e1c521eSXiaojuan Yang struct LoongArchTLB {
2267e1c521eSXiaojuan Yang     uint64_t tlb_misc;
2277e1c521eSXiaojuan Yang     /* Fields corresponding to CSR_TLBELO0/1 */
2287e1c521eSXiaojuan Yang     uint64_t tlb_entry0;
2297e1c521eSXiaojuan Yang     uint64_t tlb_entry1;
2307e1c521eSXiaojuan Yang };
2317e1c521eSXiaojuan Yang typedef struct LoongArchTLB LoongArchTLB;
2327e1c521eSXiaojuan Yang 
233228021f0SSong Gao typedef struct CPUArchState {
234228021f0SSong Gao     uint64_t gpr[32];
235228021f0SSong Gao     uint64_t pc;
236228021f0SSong Gao 
237228021f0SSong Gao     uint64_t fpr[32];
238228021f0SSong Gao     float_status fp_status;
239228021f0SSong Gao     bool cf[8];
240228021f0SSong Gao 
241228021f0SSong Gao     uint32_t fcsr0;
242228021f0SSong Gao     uint32_t fcsr0_mask;
243228021f0SSong Gao 
244228021f0SSong Gao     uint32_t cpucfg[21];
245228021f0SSong Gao 
246228021f0SSong Gao     uint64_t lladdr; /* LL virtual address compared against SC */
247228021f0SSong Gao     uint64_t llval;
248228021f0SSong Gao 
249228021f0SSong Gao     uint64_t badaddr;
250398cecb9SXiaojuan Yang 
251398cecb9SXiaojuan Yang     /* LoongArch CSRs */
252398cecb9SXiaojuan Yang     uint64_t CSR_CRMD;
253398cecb9SXiaojuan Yang     uint64_t CSR_PRMD;
254398cecb9SXiaojuan Yang     uint64_t CSR_EUEN;
255398cecb9SXiaojuan Yang     uint64_t CSR_MISC;
256398cecb9SXiaojuan Yang     uint64_t CSR_ECFG;
257398cecb9SXiaojuan Yang     uint64_t CSR_ESTAT;
258398cecb9SXiaojuan Yang     uint64_t CSR_ERA;
259398cecb9SXiaojuan Yang     uint64_t CSR_BADV;
260398cecb9SXiaojuan Yang     uint64_t CSR_BADI;
261398cecb9SXiaojuan Yang     uint64_t CSR_EENTRY;
262398cecb9SXiaojuan Yang     uint64_t CSR_TLBIDX;
263398cecb9SXiaojuan Yang     uint64_t CSR_TLBEHI;
264398cecb9SXiaojuan Yang     uint64_t CSR_TLBELO0;
265398cecb9SXiaojuan Yang     uint64_t CSR_TLBELO1;
266398cecb9SXiaojuan Yang     uint64_t CSR_ASID;
267398cecb9SXiaojuan Yang     uint64_t CSR_PGDL;
268398cecb9SXiaojuan Yang     uint64_t CSR_PGDH;
269398cecb9SXiaojuan Yang     uint64_t CSR_PGD;
270398cecb9SXiaojuan Yang     uint64_t CSR_PWCL;
271398cecb9SXiaojuan Yang     uint64_t CSR_PWCH;
272398cecb9SXiaojuan Yang     uint64_t CSR_STLBPS;
273398cecb9SXiaojuan Yang     uint64_t CSR_RVACFG;
274398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG1;
275398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG2;
276398cecb9SXiaojuan Yang     uint64_t CSR_PRCFG3;
277398cecb9SXiaojuan Yang     uint64_t CSR_SAVE[16];
278398cecb9SXiaojuan Yang     uint64_t CSR_TID;
279398cecb9SXiaojuan Yang     uint64_t CSR_TCFG;
280398cecb9SXiaojuan Yang     uint64_t CSR_TVAL;
281398cecb9SXiaojuan Yang     uint64_t CSR_CNTC;
282398cecb9SXiaojuan Yang     uint64_t CSR_TICLR;
283398cecb9SXiaojuan Yang     uint64_t CSR_LLBCTL;
284398cecb9SXiaojuan Yang     uint64_t CSR_IMPCTL1;
285398cecb9SXiaojuan Yang     uint64_t CSR_IMPCTL2;
286398cecb9SXiaojuan Yang     uint64_t CSR_TLBRENTRY;
287398cecb9SXiaojuan Yang     uint64_t CSR_TLBRBADV;
288398cecb9SXiaojuan Yang     uint64_t CSR_TLBRERA;
289398cecb9SXiaojuan Yang     uint64_t CSR_TLBRSAVE;
290398cecb9SXiaojuan Yang     uint64_t CSR_TLBRELO0;
291398cecb9SXiaojuan Yang     uint64_t CSR_TLBRELO1;
292398cecb9SXiaojuan Yang     uint64_t CSR_TLBREHI;
293398cecb9SXiaojuan Yang     uint64_t CSR_TLBRPRMD;
294398cecb9SXiaojuan Yang     uint64_t CSR_MERRCTL;
295398cecb9SXiaojuan Yang     uint64_t CSR_MERRINFO1;
296398cecb9SXiaojuan Yang     uint64_t CSR_MERRINFO2;
297398cecb9SXiaojuan Yang     uint64_t CSR_MERRENTRY;
298398cecb9SXiaojuan Yang     uint64_t CSR_MERRERA;
299398cecb9SXiaojuan Yang     uint64_t CSR_MERRSAVE;
300398cecb9SXiaojuan Yang     uint64_t CSR_CTAG;
301398cecb9SXiaojuan Yang     uint64_t CSR_DMW[4];
302398cecb9SXiaojuan Yang     uint64_t CSR_DBG;
303398cecb9SXiaojuan Yang     uint64_t CSR_DERA;
304398cecb9SXiaojuan Yang     uint64_t CSR_DSAVE;
3057e1c521eSXiaojuan Yang 
3067e1c521eSXiaojuan Yang     LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
307*f84a2aacSXiaojuan Yang 
308*f84a2aacSXiaojuan Yang     AddressSpace address_space_iocsr;
309*f84a2aacSXiaojuan Yang     MemoryRegion system_iocsr;
310*f84a2aacSXiaojuan Yang     MemoryRegion iocsr_mem;
311228021f0SSong Gao } CPULoongArchState;
312228021f0SSong Gao 
313228021f0SSong Gao /**
314228021f0SSong Gao  * LoongArchCPU:
315228021f0SSong Gao  * @env: #CPULoongArchState
316228021f0SSong Gao  *
317228021f0SSong Gao  * A LoongArch CPU.
318228021f0SSong Gao  */
319228021f0SSong Gao struct ArchCPU {
320228021f0SSong Gao     /*< private >*/
321228021f0SSong Gao     CPUState parent_obj;
322228021f0SSong Gao     /*< public >*/
323228021f0SSong Gao 
324228021f0SSong Gao     CPUNegativeOffsetState neg;
325228021f0SSong Gao     CPULoongArchState env;
326dd615fa4SXiaojuan Yang     QEMUTimer timer;
327228021f0SSong Gao };
328228021f0SSong Gao 
329228021f0SSong Gao #define TYPE_LOONGARCH_CPU "loongarch-cpu"
330228021f0SSong Gao 
331228021f0SSong Gao OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass,
332228021f0SSong Gao                         LOONGARCH_CPU)
333228021f0SSong Gao 
334228021f0SSong Gao /**
335228021f0SSong Gao  * LoongArchCPUClass:
336228021f0SSong Gao  * @parent_realize: The parent class' realize handler.
337228021f0SSong Gao  * @parent_reset: The parent class' reset handler.
338228021f0SSong Gao  *
339228021f0SSong Gao  * A LoongArch CPU model.
340228021f0SSong Gao  */
341228021f0SSong Gao struct LoongArchCPUClass {
342228021f0SSong Gao     /*< private >*/
343228021f0SSong Gao     CPUClass parent_class;
344228021f0SSong Gao     /*< public >*/
345228021f0SSong Gao 
346228021f0SSong Gao     DeviceRealize parent_realize;
347228021f0SSong Gao     DeviceReset parent_reset;
348228021f0SSong Gao };
349228021f0SSong Gao 
3507e1c521eSXiaojuan Yang /*
3517e1c521eSXiaojuan Yang  * LoongArch CPUs has 4 privilege levels.
3527e1c521eSXiaojuan Yang  * 0 for kernel mode, 3 for user mode.
3537e1c521eSXiaojuan Yang  * Define an extra index for DA(direct addressing) mode.
3547e1c521eSXiaojuan Yang  */
3557e1c521eSXiaojuan Yang #define MMU_KERNEL_IDX   0
3567e1c521eSXiaojuan Yang #define MMU_USER_IDX     3
3577e1c521eSXiaojuan Yang #define MMU_DA_IDX       4
3587e1c521eSXiaojuan Yang 
3597e1c521eSXiaojuan Yang static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
3607e1c521eSXiaojuan Yang {
3617e1c521eSXiaojuan Yang     uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
3627e1c521eSXiaojuan Yang 
3637e1c521eSXiaojuan Yang     if (!pg) {
3647e1c521eSXiaojuan Yang         return MMU_DA_IDX;
3657e1c521eSXiaojuan Yang     }
3667e1c521eSXiaojuan Yang     return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
3677e1c521eSXiaojuan Yang }
3687e1c521eSXiaojuan Yang 
3697e1c521eSXiaojuan Yang static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
3707e1c521eSXiaojuan Yang                                         target_ulong *pc,
3717e1c521eSXiaojuan Yang                                         target_ulong *cs_base,
3727e1c521eSXiaojuan Yang                                         uint32_t *flags)
3737e1c521eSXiaojuan Yang {
3747e1c521eSXiaojuan Yang     *pc = env->pc;
3757e1c521eSXiaojuan Yang     *cs_base = 0;
3767e1c521eSXiaojuan Yang     *flags = cpu_mmu_index(env, false);
3777e1c521eSXiaojuan Yang }
3787e1c521eSXiaojuan Yang 
379228021f0SSong Gao void loongarch_cpu_list(void);
380228021f0SSong Gao 
381228021f0SSong Gao #define cpu_list loongarch_cpu_list
382228021f0SSong Gao 
383228021f0SSong Gao #include "exec/cpu-all.h"
384228021f0SSong Gao 
385228021f0SSong Gao #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
386228021f0SSong Gao #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
387228021f0SSong Gao #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
388228021f0SSong Gao 
389228021f0SSong Gao #endif /* LOONGARCH_CPU_H */
390