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