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