]> git.proxmox.com Git - mirror_qemu.git/blame - target/loongarch/cpu.h
target/riscv: Clear CSR values at reset and sync MPSTATE with host
[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
008a3b16
SG
254#define LSX_LEN (128)
255#define LASX_LEN (256)
256
16f5396c 257typedef union VReg {
008a3b16
SG
258 int8_t B[LASX_LEN / 8];
259 int16_t H[LASX_LEN / 16];
260 int32_t W[LASX_LEN / 32];
261 int64_t D[LASX_LEN / 64];
262 uint8_t UB[LASX_LEN / 8];
263 uint16_t UH[LASX_LEN / 16];
264 uint32_t UW[LASX_LEN / 32];
265 uint64_t UD[LASX_LEN / 64];
266 Int128 Q[LASX_LEN / 128];
267} VReg;
16f5396c
SG
268
269typedef union fpr_t fpr_t;
270union fpr_t {
271 VReg vreg;
272};
273
7e1c521e
XY
274struct LoongArchTLB {
275 uint64_t tlb_misc;
276 /* Fields corresponding to CSR_TLBELO0/1 */
277 uint64_t tlb_entry0;
278 uint64_t tlb_entry1;
279};
280typedef struct LoongArchTLB LoongArchTLB;
281
228021f0
SG
282typedef struct CPUArchState {
283 uint64_t gpr[32];
284 uint64_t pc;
285
16f5396c 286 fpr_t fpr[32];
228021f0
SG
287 float_status fp_status;
288 bool cf[8];
289
290 uint32_t fcsr0;
291 uint32_t fcsr0_mask;
292
293 uint32_t cpucfg[21];
294
295 uint64_t lladdr; /* LL virtual address compared against SC */
296 uint64_t llval;
297
398cecb9
XY
298 /* LoongArch CSRs */
299 uint64_t CSR_CRMD;
300 uint64_t CSR_PRMD;
301 uint64_t CSR_EUEN;
302 uint64_t CSR_MISC;
303 uint64_t CSR_ECFG;
304 uint64_t CSR_ESTAT;
305 uint64_t CSR_ERA;
306 uint64_t CSR_BADV;
307 uint64_t CSR_BADI;
308 uint64_t CSR_EENTRY;
309 uint64_t CSR_TLBIDX;
310 uint64_t CSR_TLBEHI;
311 uint64_t CSR_TLBELO0;
312 uint64_t CSR_TLBELO1;
313 uint64_t CSR_ASID;
314 uint64_t CSR_PGDL;
315 uint64_t CSR_PGDH;
316 uint64_t CSR_PGD;
317 uint64_t CSR_PWCL;
318 uint64_t CSR_PWCH;
319 uint64_t CSR_STLBPS;
320 uint64_t CSR_RVACFG;
321 uint64_t CSR_PRCFG1;
322 uint64_t CSR_PRCFG2;
323 uint64_t CSR_PRCFG3;
324 uint64_t CSR_SAVE[16];
325 uint64_t CSR_TID;
326 uint64_t CSR_TCFG;
327 uint64_t CSR_TVAL;
328 uint64_t CSR_CNTC;
329 uint64_t CSR_TICLR;
330 uint64_t CSR_LLBCTL;
331 uint64_t CSR_IMPCTL1;
332 uint64_t CSR_IMPCTL2;
333 uint64_t CSR_TLBRENTRY;
334 uint64_t CSR_TLBRBADV;
335 uint64_t CSR_TLBRERA;
336 uint64_t CSR_TLBRSAVE;
337 uint64_t CSR_TLBRELO0;
338 uint64_t CSR_TLBRELO1;
339 uint64_t CSR_TLBREHI;
340 uint64_t CSR_TLBRPRMD;
341 uint64_t CSR_MERRCTL;
342 uint64_t CSR_MERRINFO1;
343 uint64_t CSR_MERRINFO2;
344 uint64_t CSR_MERRENTRY;
345 uint64_t CSR_MERRERA;
346 uint64_t CSR_MERRSAVE;
347 uint64_t CSR_CTAG;
348 uint64_t CSR_DMW[4];
349 uint64_t CSR_DBG;
350 uint64_t CSR_DERA;
351 uint64_t CSR_DSAVE;
c34ad459 352 uint64_t CSR_CPUID;
7e1c521e 353
0093b9a5 354#ifndef CONFIG_USER_ONLY
7e1c521e 355 LoongArchTLB tlb[LOONGARCH_TLB_MAX];
f84a2aac
XY
356
357 AddressSpace address_space_iocsr;
358 MemoryRegion system_iocsr;
359 MemoryRegion iocsr_mem;
6a6f26f4
XY
360 bool load_elf;
361 uint64_t elf_address;
758a7475
TZ
362 /* Store ipistate to access from this struct */
363 DeviceState *ipistate;
0093b9a5 364#endif
228021f0
SG
365} CPULoongArchState;
366
367/**
368 * LoongArchCPU:
369 * @env: #CPULoongArchState
370 *
371 * A LoongArch CPU.
372 */
373struct ArchCPU {
374 /*< private >*/
375 CPUState parent_obj;
376 /*< public >*/
377
228021f0 378 CPULoongArchState env;
dd615fa4 379 QEMUTimer timer;
14f21f67 380 uint32_t phy_id;
fda3f15b
XY
381
382 /* 'compatible' string for this CPU for Linux device trees */
383 const char *dtb_compatible;
228021f0
SG
384};
385
386#define TYPE_LOONGARCH_CPU "loongarch-cpu"
6cbba3e9 387#define TYPE_LOONGARCH32_CPU "loongarch32-cpu"
146f2354 388#define TYPE_LOONGARCH64_CPU "loongarch64-cpu"
228021f0
SG
389
390OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass,
391 LOONGARCH_CPU)
392
393/**
394 * LoongArchCPUClass:
395 * @parent_realize: The parent class' realize handler.
f78b49ae 396 * @parent_phases: The parent class' reset phase handlers.
228021f0
SG
397 *
398 * A LoongArch CPU model.
399 */
400struct LoongArchCPUClass {
401 /*< private >*/
402 CPUClass parent_class;
403 /*< public >*/
404
405 DeviceRealize parent_realize;
f78b49ae 406 ResettablePhases parent_phases;
228021f0
SG
407};
408
7e1c521e
XY
409/*
410 * LoongArch CPUs has 4 privilege levels.
411 * 0 for kernel mode, 3 for user mode.
412 * Define an extra index for DA(direct addressing) mode.
413 */
c8885b88
RW
414#define MMU_PLV_KERNEL 0
415#define MMU_PLV_USER 3
416#define MMU_IDX_KERNEL MMU_PLV_KERNEL
417#define MMU_IDX_USER MMU_PLV_USER
418#define MMU_IDX_DA 4
7e1c521e
XY
419
420static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
421{
0093b9a5 422#ifdef CONFIG_USER_ONLY
c8885b88 423 return MMU_IDX_USER;
0093b9a5 424#else
c8885b88
RW
425 if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) {
426 return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
7e1c521e 427 }
c8885b88 428 return MMU_IDX_DA;
0093b9a5 429#endif
7e1c521e
XY
430}
431
19f82a4a
JC
432static inline bool is_la64(CPULoongArchState *env)
433{
434 return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64;
435}
436
39665820
JC
437static inline bool is_va32(CPULoongArchState *env)
438{
439 /* VA32 if !LA64 or VA32L[1-3] */
440 bool va32 = !is_la64(env);
441 uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
442 if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) {
443 va32 = true;
444 }
445 return va32;
446}
447
2f6478ff
JC
448static inline void set_pc(CPULoongArchState *env, uint64_t value)
449{
7033c0e6
JC
450 if (is_va32(env)) {
451 env->pc = (uint32_t)value;
452 } else {
453 env->pc = value;
454 }
2f6478ff
JC
455}
456
b4bda200
RW
457/*
458 * LoongArch CPUs hardware flags.
459 */
460#define HW_FLAGS_PLV_MASK R_CSR_CRMD_PLV_MASK /* 0x03 */
461#define HW_FLAGS_CRMD_PG R_CSR_CRMD_PG_MASK /* 0x10 */
2419978c 462#define HW_FLAGS_EUEN_FPE 0x04
a3f3db5c 463#define HW_FLAGS_EUEN_SXE 0x08
b8f1bdf3 464#define HW_FLAGS_EUEN_ASXE 0x10
39665820 465#define HW_FLAGS_VA32 0x20
b4bda200 466
bb5de525
AJ
467static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
468 uint64_t *cs_base, uint32_t *flags)
7e1c521e
XY
469{
470 *pc = env->pc;
471 *cs_base = 0;
b4bda200 472 *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
2419978c 473 *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
a3f3db5c 474 *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE;
b8f1bdf3 475 *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE;
39665820 476 *flags |= is_va32(env) * HW_FLAGS_VA32;
7e1c521e
XY
477}
478
228021f0
SG
479void loongarch_cpu_list(void);
480
481#define cpu_list loongarch_cpu_list
482
483#include "exec/cpu-all.h"
484
485#define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
486#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
487#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
488
489#endif /* LOONGARCH_CPU_H */