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