]> git.proxmox.com Git - mirror_qemu.git/blob - target/loongarch/cpu.h
b983ce241c590d6f85318892791c2bcd2f4d3ffd
[mirror_qemu.git] / target / loongarch / cpu.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * QEMU LoongArch CPU
4 *
5 * Copyright (c) 2021 Loongson Technology Corporation Limited
6 */
7
8 #ifndef LOONGARCH_CPU_H
9 #define LOONGARCH_CPU_H
10
11 #include "exec/cpu-defs.h"
12 #include "fpu/softfloat-types.h"
13 #include "hw/registerfields.h"
14
15 #define TCG_GUEST_DEFAULT_MO (0)
16
17 #define FCSR0_M1 0x1f /* FCSR1 mask, Enables */
18 #define FCSR0_M2 0x1f1f0000 /* FCSR2 mask, Cause and Flags */
19 #define FCSR0_M3 0x300 /* FCSR3 mask, Round Mode */
20 #define FCSR0_RM 8 /* Round Mode bit num on fcsr0 */
21
22 FIELD(FCSR0, ENABLES, 0, 5)
23 FIELD(FCSR0, RM, 8, 2)
24 FIELD(FCSR0, FLAGS, 16, 5)
25 FIELD(FCSR0, CAUSE, 24, 5)
26
27 #define GET_FP_CAUSE(REG) FIELD_EX32(REG, FCSR0, CAUSE)
28 #define SET_FP_CAUSE(REG, V) FIELD_DP32(REG, FCSR0, CAUSE, V)
29 #define GET_FP_ENABLES(REG) FIELD_EX32(REG, FCSR0, ENABLES)
30 #define SET_FP_ENABLES(REG, V) FIELD_DP32(REG, FCSR0, ENABLES, V)
31 #define GET_FP_FLAGS(REG) FIELD_EX32(REG, FCSR0, FLAGS)
32 #define SET_FP_FLAGS(REG, V) FIELD_DP32(REG, FCSR0, FLAGS, V)
33 #define UPDATE_FP_FLAGS(REG, V) \
34 do { \
35 (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \
36 } while (0)
37
38 #define FP_INEXACT 1
39 #define FP_UNDERFLOW 2
40 #define FP_OVERFLOW 4
41 #define FP_DIV0 8
42 #define FP_INVALID 16
43
44 #define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */
45 #define EXCCODE_INT 0
46 #define EXCCODE_PIL 1
47 #define EXCCODE_PIS 2
48 #define EXCCODE_PIF 3
49 #define EXCCODE_PME 4
50 #define EXCCODE_PNR 5
51 #define EXCCODE_PNX 6
52 #define EXCCODE_PPI 7
53 #define EXCCODE_ADEF 8 /* Different exception subcode */
54 #define EXCCODE_ADEM 8
55 #define EXCCODE_ALE 9
56 #define EXCCODE_BCE 10
57 #define EXCCODE_SYS 11
58 #define EXCCODE_BRK 12
59 #define EXCCODE_INE 13
60 #define EXCCODE_IPE 14
61 #define EXCCODE_FPD 15
62 #define EXCCODE_SXD 16
63 #define EXCCODE_ASXD 17
64 #define EXCCODE_FPE 18 /* Different exception subcode */
65 #define EXCCODE_VFPE 18
66 #define EXCCODE_WPEF 19 /* Different exception subcode */
67 #define EXCCODE_WPEM 19
68 #define EXCCODE_BTD 20
69 #define EXCCODE_BTE 21
70 #define EXCCODE_DBP 26 /* Reserved subcode used for debug */
71
72 /* cpucfg[0] bits */
73 FIELD(CPUCFG0, PRID, 0, 32)
74
75 /* cpucfg[1] bits */
76 FIELD(CPUCFG1, ARCH, 0, 2)
77 FIELD(CPUCFG1, PGMMU, 2, 1)
78 FIELD(CPUCFG1, IOCSR, 3, 1)
79 FIELD(CPUCFG1, PALEN, 4, 8)
80 FIELD(CPUCFG1, VALEN, 12, 8)
81 FIELD(CPUCFG1, UAL, 20, 1)
82 FIELD(CPUCFG1, RI, 21, 1)
83 FIELD(CPUCFG1, EP, 22, 1)
84 FIELD(CPUCFG1, RPLV, 23, 1)
85 FIELD(CPUCFG1, HP, 24, 1)
86 FIELD(CPUCFG1, IOCSR_BRD, 25, 1)
87 FIELD(CPUCFG1, MSG_INT, 26, 1)
88
89 /* cpucfg[2] bits */
90 FIELD(CPUCFG2, FP, 0, 1)
91 FIELD(CPUCFG2, FP_SP, 1, 1)
92 FIELD(CPUCFG2, FP_DP, 2, 1)
93 FIELD(CPUCFG2, FP_VER, 3, 3)
94 FIELD(CPUCFG2, LSX, 6, 1)
95 FIELD(CPUCFG2, LASX, 7, 1)
96 FIELD(CPUCFG2, COMPLEX, 8, 1)
97 FIELD(CPUCFG2, CRYPTO, 9, 1)
98 FIELD(CPUCFG2, LVZ, 10, 1)
99 FIELD(CPUCFG2, LVZ_VER, 11, 3)
100 FIELD(CPUCFG2, LLFTP, 14, 1)
101 FIELD(CPUCFG2, LLFTP_VER, 15, 3)
102 FIELD(CPUCFG2, LBT_X86, 18, 1)
103 FIELD(CPUCFG2, LBT_ARM, 19, 1)
104 FIELD(CPUCFG2, LBT_MIPS, 20, 1)
105 FIELD(CPUCFG2, LSPW, 21, 1)
106 FIELD(CPUCFG2, LAM, 22, 1)
107
108 /* cpucfg[3] bits */
109 FIELD(CPUCFG3, CCDMA, 0, 1)
110 FIELD(CPUCFG3, SFB, 1, 1)
111 FIELD(CPUCFG3, UCACC, 2, 1)
112 FIELD(CPUCFG3, LLEXC, 3, 1)
113 FIELD(CPUCFG3, SCDLY, 4, 1)
114 FIELD(CPUCFG3, LLDBAR, 5, 1)
115 FIELD(CPUCFG3, ITLBHMC, 6, 1)
116 FIELD(CPUCFG3, ICHMC, 7, 1)
117 FIELD(CPUCFG3, SPW_LVL, 8, 3)
118 FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
119 FIELD(CPUCFG3, RVA, 12, 1)
120 FIELD(CPUCFG3, RVAMAX, 13, 4)
121
122 /* cpucfg[4] bits */
123 FIELD(CPUCFG4, CC_FREQ, 0, 32)
124
125 /* cpucfg[5] bits */
126 FIELD(CPUCFG5, CC_MUL, 0, 16)
127 FIELD(CPUCFG5, CC_DIV, 16, 16)
128
129 /* cpucfg[6] bits */
130 FIELD(CPUCFG6, PMP, 0, 1)
131 FIELD(CPUCFG6, PMVER, 1, 3)
132 FIELD(CPUCFG6, PMNUM, 4, 4)
133 FIELD(CPUCFG6, PMBITS, 8, 6)
134 FIELD(CPUCFG6, UPM, 14, 1)
135
136 /* cpucfg[16] bits */
137 FIELD(CPUCFG16, L1_IUPRE, 0, 1)
138 FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
139 FIELD(CPUCFG16, L1_DPRE, 2, 1)
140 FIELD(CPUCFG16, L2_IUPRE, 3, 1)
141 FIELD(CPUCFG16, L2_IUUNIFY, 4, 1)
142 FIELD(CPUCFG16, L2_IUPRIV, 5, 1)
143 FIELD(CPUCFG16, L2_IUINCL, 6, 1)
144 FIELD(CPUCFG16, L2_DPRE, 7, 1)
145 FIELD(CPUCFG16, L2_DPRIV, 8, 1)
146 FIELD(CPUCFG16, L2_DINCL, 9, 1)
147 FIELD(CPUCFG16, L3_IUPRE, 10, 1)
148 FIELD(CPUCFG16, L3_IUUNIFY, 11, 1)
149 FIELD(CPUCFG16, L3_IUPRIV, 12, 1)
150 FIELD(CPUCFG16, L3_IUINCL, 13, 1)
151 FIELD(CPUCFG16, L3_DPRE, 14, 1)
152 FIELD(CPUCFG16, L3_DPRIV, 15, 1)
153 FIELD(CPUCFG16, L3_DINCL, 16, 1)
154
155 /* cpucfg[17] bits */
156 FIELD(CPUCFG17, L1IU_WAYS, 0, 16)
157 FIELD(CPUCFG17, L1IU_SETS, 16, 8)
158 FIELD(CPUCFG17, L1IU_SIZE, 24, 7)
159
160 /* cpucfg[18] bits */
161 FIELD(CPUCFG18, L1D_WAYS, 0, 16)
162 FIELD(CPUCFG18, L1D_SETS, 16, 8)
163 FIELD(CPUCFG18, L1D_SIZE, 24, 7)
164
165 /* cpucfg[19] bits */
166 FIELD(CPUCFG19, L2IU_WAYS, 0, 16)
167 FIELD(CPUCFG19, L2IU_SETS, 16, 8)
168 FIELD(CPUCFG19, L2IU_SIZE, 24, 7)
169
170 /* cpucfg[20] bits */
171 FIELD(CPUCFG20, L3IU_WAYS, 0, 16)
172 FIELD(CPUCFG20, L3IU_SETS, 16, 8)
173 FIELD(CPUCFG20, L3IU_SIZE, 24, 7)
174
175 /*CSR_CRMD */
176 FIELD(CSR_CRMD, PLV, 0, 2)
177 FIELD(CSR_CRMD, IE, 2, 1)
178 FIELD(CSR_CRMD, DA, 3, 1)
179 FIELD(CSR_CRMD, PG, 4, 1)
180 FIELD(CSR_CRMD, DATF, 5, 2)
181 FIELD(CSR_CRMD, DATM, 7, 2)
182 FIELD(CSR_CRMD, WE, 9, 1)
183
184 extern const char * const regnames[32];
185 extern const char * const fregnames[32];
186
187 #define N_IRQS 13
188
189 #define LOONGARCH_STLB 2048 /* 2048 STLB */
190 #define LOONGARCH_MTLB 64 /* 64 MTLB */
191 #define LOONGARCH_TLB_MAX (LOONGARCH_STLB + LOONGARCH_MTLB)
192
193 /*
194 * define the ASID PS E VPPN field of TLB
195 */
196 FIELD(TLB_MISC, E, 0, 1)
197 FIELD(TLB_MISC, ASID, 1, 10)
198 FIELD(TLB_MISC, VPPN, 13, 35)
199 FIELD(TLB_MISC, PS, 48, 6)
200
201 struct LoongArchTLB {
202 uint64_t tlb_misc;
203 /* Fields corresponding to CSR_TLBELO0/1 */
204 uint64_t tlb_entry0;
205 uint64_t tlb_entry1;
206 };
207 typedef struct LoongArchTLB LoongArchTLB;
208
209 typedef struct CPUArchState {
210 uint64_t gpr[32];
211 uint64_t pc;
212
213 uint64_t fpr[32];
214 float_status fp_status;
215 bool cf[8];
216
217 uint32_t fcsr0;
218 uint32_t fcsr0_mask;
219
220 uint32_t cpucfg[21];
221
222 uint64_t lladdr; /* LL virtual address compared against SC */
223 uint64_t llval;
224
225 uint64_t badaddr;
226
227 /* LoongArch CSRs */
228 uint64_t CSR_CRMD;
229 uint64_t CSR_PRMD;
230 uint64_t CSR_EUEN;
231 uint64_t CSR_MISC;
232 uint64_t CSR_ECFG;
233 uint64_t CSR_ESTAT;
234 uint64_t CSR_ERA;
235 uint64_t CSR_BADV;
236 uint64_t CSR_BADI;
237 uint64_t CSR_EENTRY;
238 uint64_t CSR_TLBIDX;
239 uint64_t CSR_TLBEHI;
240 uint64_t CSR_TLBELO0;
241 uint64_t CSR_TLBELO1;
242 uint64_t CSR_ASID;
243 uint64_t CSR_PGDL;
244 uint64_t CSR_PGDH;
245 uint64_t CSR_PGD;
246 uint64_t CSR_PWCL;
247 uint64_t CSR_PWCH;
248 uint64_t CSR_STLBPS;
249 uint64_t CSR_RVACFG;
250 uint64_t CSR_PRCFG1;
251 uint64_t CSR_PRCFG2;
252 uint64_t CSR_PRCFG3;
253 uint64_t CSR_SAVE[16];
254 uint64_t CSR_TID;
255 uint64_t CSR_TCFG;
256 uint64_t CSR_TVAL;
257 uint64_t CSR_CNTC;
258 uint64_t CSR_TICLR;
259 uint64_t CSR_LLBCTL;
260 uint64_t CSR_IMPCTL1;
261 uint64_t CSR_IMPCTL2;
262 uint64_t CSR_TLBRENTRY;
263 uint64_t CSR_TLBRBADV;
264 uint64_t CSR_TLBRERA;
265 uint64_t CSR_TLBRSAVE;
266 uint64_t CSR_TLBRELO0;
267 uint64_t CSR_TLBRELO1;
268 uint64_t CSR_TLBREHI;
269 uint64_t CSR_TLBRPRMD;
270 uint64_t CSR_MERRCTL;
271 uint64_t CSR_MERRINFO1;
272 uint64_t CSR_MERRINFO2;
273 uint64_t CSR_MERRENTRY;
274 uint64_t CSR_MERRERA;
275 uint64_t CSR_MERRSAVE;
276 uint64_t CSR_CTAG;
277 uint64_t CSR_DMW[4];
278 uint64_t CSR_DBG;
279 uint64_t CSR_DERA;
280 uint64_t CSR_DSAVE;
281
282 LoongArchTLB tlb[LOONGARCH_TLB_MAX];
283 } CPULoongArchState;
284
285 /**
286 * LoongArchCPU:
287 * @env: #CPULoongArchState
288 *
289 * A LoongArch CPU.
290 */
291 struct ArchCPU {
292 /*< private >*/
293 CPUState parent_obj;
294 /*< public >*/
295
296 CPUNegativeOffsetState neg;
297 CPULoongArchState env;
298 };
299
300 #define TYPE_LOONGARCH_CPU "loongarch-cpu"
301
302 OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass,
303 LOONGARCH_CPU)
304
305 /**
306 * LoongArchCPUClass:
307 * @parent_realize: The parent class' realize handler.
308 * @parent_reset: The parent class' reset handler.
309 *
310 * A LoongArch CPU model.
311 */
312 struct LoongArchCPUClass {
313 /*< private >*/
314 CPUClass parent_class;
315 /*< public >*/
316
317 DeviceRealize parent_realize;
318 DeviceReset parent_reset;
319 };
320
321 /*
322 * LoongArch CPUs has 4 privilege levels.
323 * 0 for kernel mode, 3 for user mode.
324 * Define an extra index for DA(direct addressing) mode.
325 */
326 #define MMU_KERNEL_IDX 0
327 #define MMU_USER_IDX 3
328 #define MMU_DA_IDX 4
329
330 static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
331 {
332 uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
333
334 if (!pg) {
335 return MMU_DA_IDX;
336 }
337 return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
338 }
339
340 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
341 target_ulong *pc,
342 target_ulong *cs_base,
343 uint32_t *flags)
344 {
345 *pc = env->pc;
346 *cs_base = 0;
347 *flags = cpu_mmu_index(env, false);
348 }
349
350 void loongarch_cpu_list(void);
351
352 #define cpu_list loongarch_cpu_list
353
354 #include "exec/cpu-all.h"
355
356 #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
357 #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
358 #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
359
360 #endif /* LOONGARCH_CPU_H */