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