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