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