xref: /qemu/target/loongarch/cpu.h (revision ca61e750)
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     uint64_t badaddr;
250 
251     /* LoongArch CSRs */
252     uint64_t CSR_CRMD;
253     uint64_t CSR_PRMD;
254     uint64_t CSR_EUEN;
255     uint64_t CSR_MISC;
256     uint64_t CSR_ECFG;
257     uint64_t CSR_ESTAT;
258     uint64_t CSR_ERA;
259     uint64_t CSR_BADV;
260     uint64_t CSR_BADI;
261     uint64_t CSR_EENTRY;
262     uint64_t CSR_TLBIDX;
263     uint64_t CSR_TLBEHI;
264     uint64_t CSR_TLBELO0;
265     uint64_t CSR_TLBELO1;
266     uint64_t CSR_ASID;
267     uint64_t CSR_PGDL;
268     uint64_t CSR_PGDH;
269     uint64_t CSR_PGD;
270     uint64_t CSR_PWCL;
271     uint64_t CSR_PWCH;
272     uint64_t CSR_STLBPS;
273     uint64_t CSR_RVACFG;
274     uint64_t CSR_PRCFG1;
275     uint64_t CSR_PRCFG2;
276     uint64_t CSR_PRCFG3;
277     uint64_t CSR_SAVE[16];
278     uint64_t CSR_TID;
279     uint64_t CSR_TCFG;
280     uint64_t CSR_TVAL;
281     uint64_t CSR_CNTC;
282     uint64_t CSR_TICLR;
283     uint64_t CSR_LLBCTL;
284     uint64_t CSR_IMPCTL1;
285     uint64_t CSR_IMPCTL2;
286     uint64_t CSR_TLBRENTRY;
287     uint64_t CSR_TLBRBADV;
288     uint64_t CSR_TLBRERA;
289     uint64_t CSR_TLBRSAVE;
290     uint64_t CSR_TLBRELO0;
291     uint64_t CSR_TLBRELO1;
292     uint64_t CSR_TLBREHI;
293     uint64_t CSR_TLBRPRMD;
294     uint64_t CSR_MERRCTL;
295     uint64_t CSR_MERRINFO1;
296     uint64_t CSR_MERRINFO2;
297     uint64_t CSR_MERRENTRY;
298     uint64_t CSR_MERRERA;
299     uint64_t CSR_MERRSAVE;
300     uint64_t CSR_CTAG;
301     uint64_t CSR_DMW[4];
302     uint64_t CSR_DBG;
303     uint64_t CSR_DERA;
304     uint64_t CSR_DSAVE;
305 
306     LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
307 
308     AddressSpace address_space_iocsr;
309     MemoryRegion system_iocsr;
310     MemoryRegion iocsr_mem;
311     bool load_elf;
312     uint64_t elf_address;
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 
331 #define TYPE_LOONGARCH_CPU "loongarch-cpu"
332 
333 OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass,
334                         LOONGARCH_CPU)
335 
336 /**
337  * LoongArchCPUClass:
338  * @parent_realize: The parent class' realize handler.
339  * @parent_reset: The parent class' reset handler.
340  *
341  * A LoongArch CPU model.
342  */
343 struct LoongArchCPUClass {
344     /*< private >*/
345     CPUClass parent_class;
346     /*< public >*/
347 
348     DeviceRealize parent_realize;
349     DeviceReset parent_reset;
350 };
351 
352 /*
353  * LoongArch CPUs has 4 privilege levels.
354  * 0 for kernel mode, 3 for user mode.
355  * Define an extra index for DA(direct addressing) mode.
356  */
357 #define MMU_KERNEL_IDX   0
358 #define MMU_USER_IDX     3
359 #define MMU_DA_IDX       4
360 
361 static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
362 {
363     uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
364 
365     if (!pg) {
366         return MMU_DA_IDX;
367     }
368     return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
369 }
370 
371 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
372                                         target_ulong *pc,
373                                         target_ulong *cs_base,
374                                         uint32_t *flags)
375 {
376     *pc = env->pc;
377     *cs_base = 0;
378     *flags = cpu_mmu_index(env, false);
379 }
380 
381 void loongarch_cpu_list(void);
382 
383 #define cpu_list loongarch_cpu_list
384 
385 #include "exec/cpu-all.h"
386 
387 #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
388 #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
389 #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
390 
391 #endif /* LOONGARCH_CPU_H */
392