1228021f0SSong Gao /* SPDX-License-Identifier: GPL-2.0-or-later */ 2228021f0SSong Gao /* 3228021f0SSong Gao * QEMU LoongArch CPU 4228021f0SSong Gao * 5228021f0SSong Gao * Copyright (c) 2021 Loongson Technology Corporation Limited 6228021f0SSong Gao */ 7228021f0SSong Gao 8228021f0SSong Gao #ifndef LOONGARCH_CPU_H 9228021f0SSong Gao #define LOONGARCH_CPU_H 10228021f0SSong Gao 1116f5396cSSong Gao #include "qemu/int128.h" 12228021f0SSong Gao #include "exec/cpu-defs.h" 13228021f0SSong Gao #include "fpu/softfloat-types.h" 14228021f0SSong Gao #include "hw/registerfields.h" 15dd615fa4SXiaojuan Yang #include "qemu/timer.h" 168f15d617SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY 17f84a2aacSXiaojuan Yang #include "exec/memory.h" 188f15d617SPhilippe Mathieu-Daudé #endif 19b4bda200SRui Wang #include "cpu-csr.h" 20f84a2aacSXiaojuan Yang 21f84a2aacSXiaojuan Yang #define IOCSRF_TEMP 0 22f84a2aacSXiaojuan Yang #define IOCSRF_NODECNT 1 23f84a2aacSXiaojuan Yang #define IOCSRF_MSI 2 24f84a2aacSXiaojuan Yang #define IOCSRF_EXTIOI 3 25f84a2aacSXiaojuan Yang #define IOCSRF_CSRIPI 4 26f84a2aacSXiaojuan Yang #define IOCSRF_FREQCSR 5 27f84a2aacSXiaojuan Yang #define IOCSRF_FREQSCALE 6 28f84a2aacSXiaojuan Yang #define IOCSRF_DVFSV1 7 29f84a2aacSXiaojuan Yang #define IOCSRF_GMOD 9 30f84a2aacSXiaojuan Yang #define IOCSRF_VM 11 31f84a2aacSXiaojuan Yang 32c77432d0SSong Gao #define VERSION_REG 0x0 33f84a2aacSXiaojuan Yang #define FEATURE_REG 0x8 34f84a2aacSXiaojuan Yang #define VENDOR_REG 0x10 35f84a2aacSXiaojuan Yang #define CPUNAME_REG 0x20 36f84a2aacSXiaojuan Yang #define MISC_FUNC_REG 0x420 37f84a2aacSXiaojuan Yang #define IOCSRM_EXTIOI_EN 48 38f84a2aacSXiaojuan Yang 39f84a2aacSXiaojuan Yang #define IOCSR_MEM_SIZE 0x428 40228021f0SSong Gao 41228021f0SSong Gao #define TCG_GUEST_DEFAULT_MO (0) 42228021f0SSong Gao 43228021f0SSong Gao #define FCSR0_M1 0x1f /* FCSR1 mask, Enables */ 44228021f0SSong Gao #define FCSR0_M2 0x1f1f0000 /* FCSR2 mask, Cause and Flags */ 45228021f0SSong Gao #define FCSR0_M3 0x300 /* FCSR3 mask, Round Mode */ 46228021f0SSong Gao #define FCSR0_RM 8 /* Round Mode bit num on fcsr0 */ 47228021f0SSong Gao 48228021f0SSong Gao FIELD(FCSR0, ENABLES, 0, 5) 49228021f0SSong Gao FIELD(FCSR0, RM, 8, 2) 50228021f0SSong Gao FIELD(FCSR0, FLAGS, 16, 5) 51228021f0SSong Gao FIELD(FCSR0, CAUSE, 24, 5) 52228021f0SSong Gao 53228021f0SSong Gao #define GET_FP_CAUSE(REG) FIELD_EX32(REG, FCSR0, CAUSE) 5400952d93SQi Hu #define SET_FP_CAUSE(REG, V) \ 5500952d93SQi Hu do { \ 5600952d93SQi Hu (REG) = FIELD_DP32(REG, FCSR0, CAUSE, V); \ 5700952d93SQi Hu } while (0) 58*aca67472SSong Gao #define UPDATE_FP_CAUSE(REG, V) \ 59*aca67472SSong Gao do { \ 60*aca67472SSong Gao (REG) |= FIELD_DP32(0, FCSR0, CAUSE, V); \ 61*aca67472SSong Gao } while (0) 6200952d93SQi Hu 63228021f0SSong Gao #define GET_FP_ENABLES(REG) FIELD_EX32(REG, FCSR0, ENABLES) 6400952d93SQi Hu #define SET_FP_ENABLES(REG, V) \ 6500952d93SQi Hu do { \ 6600952d93SQi Hu (REG) = FIELD_DP32(REG, FCSR0, ENABLES, V); \ 6700952d93SQi Hu } while (0) 6800952d93SQi Hu 69228021f0SSong Gao #define GET_FP_FLAGS(REG) FIELD_EX32(REG, FCSR0, FLAGS) 7000952d93SQi Hu #define SET_FP_FLAGS(REG, V) \ 7100952d93SQi Hu do { \ 7200952d93SQi Hu (REG) = FIELD_DP32(REG, FCSR0, FLAGS, V); \ 7300952d93SQi Hu } while (0) 7400952d93SQi Hu 75228021f0SSong Gao #define UPDATE_FP_FLAGS(REG, V) \ 76228021f0SSong Gao do { \ 77228021f0SSong Gao (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \ 78228021f0SSong Gao } while (0) 79228021f0SSong Gao 80228021f0SSong Gao #define FP_INEXACT 1 81228021f0SSong Gao #define FP_UNDERFLOW 2 82228021f0SSong Gao #define FP_OVERFLOW 4 83228021f0SSong Gao #define FP_DIV0 8 84228021f0SSong Gao #define FP_INVALID 16 85228021f0SSong Gao 86a6b129c8SSong Gao #define EXCODE(code, subcode) ( ((subcode) << 6) | (code) ) 87a6b129c8SSong Gao #define EXCODE_MCODE(code) ( (code) & 0x3f ) 88a6b129c8SSong Gao #define EXCODE_SUBCODE(code) ( (code) >> 6 ) 89a6b129c8SSong Gao 90228021f0SSong Gao #define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */ 91a6b129c8SSong Gao #define EXCCODE_INT EXCODE(0, 0) 92a6b129c8SSong Gao #define EXCCODE_PIL EXCODE(1, 0) 93a6b129c8SSong Gao #define EXCCODE_PIS EXCODE(2, 0) 94a6b129c8SSong Gao #define EXCCODE_PIF EXCODE(3, 0) 95a6b129c8SSong Gao #define EXCCODE_PME EXCODE(4, 0) 96a6b129c8SSong Gao #define EXCCODE_PNR EXCODE(5, 0) 97a6b129c8SSong Gao #define EXCCODE_PNX EXCODE(6, 0) 98a6b129c8SSong Gao #define EXCCODE_PPI EXCODE(7, 0) 99a6b129c8SSong Gao #define EXCCODE_ADEF EXCODE(8, 0) /* Different exception subcode */ 100a6b129c8SSong Gao #define EXCCODE_ADEM EXCODE(8, 1) 101a6b129c8SSong Gao #define EXCCODE_ALE EXCODE(9, 0) 102a6b129c8SSong Gao #define EXCCODE_BCE EXCODE(10, 0) 103a6b129c8SSong Gao #define EXCCODE_SYS EXCODE(11, 0) 104a6b129c8SSong Gao #define EXCCODE_BRK EXCODE(12, 0) 105a6b129c8SSong Gao #define EXCCODE_INE EXCODE(13, 0) 106a6b129c8SSong Gao #define EXCCODE_IPE EXCODE(14, 0) 107a6b129c8SSong Gao #define EXCCODE_FPD EXCODE(15, 0) 108a6b129c8SSong Gao #define EXCCODE_SXD EXCODE(16, 0) 109a6b129c8SSong Gao #define EXCCODE_ASXD EXCODE(17, 0) 110a6b129c8SSong Gao #define EXCCODE_FPE EXCODE(18, 0) /* Different exception subcode */ 111a6b129c8SSong Gao #define EXCCODE_VFPE EXCODE(18, 1) 112a6b129c8SSong Gao #define EXCCODE_WPEF EXCODE(19, 0) /* Different exception subcode */ 113a6b129c8SSong Gao #define EXCCODE_WPEM EXCODE(19, 1) 114a6b129c8SSong Gao #define EXCCODE_BTD EXCODE(20, 0) 115a6b129c8SSong Gao #define EXCCODE_BTE EXCODE(21, 0) 116a6b129c8SSong Gao #define EXCCODE_DBP EXCODE(26, 0) /* Reserved subcode used for debug */ 117228021f0SSong Gao 118228021f0SSong Gao /* cpucfg[0] bits */ 119228021f0SSong Gao FIELD(CPUCFG0, PRID, 0, 32) 120228021f0SSong Gao 121228021f0SSong Gao /* cpucfg[1] bits */ 122228021f0SSong Gao FIELD(CPUCFG1, ARCH, 0, 2) 123228021f0SSong Gao FIELD(CPUCFG1, PGMMU, 2, 1) 124228021f0SSong Gao FIELD(CPUCFG1, IOCSR, 3, 1) 125228021f0SSong Gao FIELD(CPUCFG1, PALEN, 4, 8) 126228021f0SSong Gao FIELD(CPUCFG1, VALEN, 12, 8) 127228021f0SSong Gao FIELD(CPUCFG1, UAL, 20, 1) 128228021f0SSong Gao FIELD(CPUCFG1, RI, 21, 1) 129228021f0SSong Gao FIELD(CPUCFG1, EP, 22, 1) 130228021f0SSong Gao FIELD(CPUCFG1, RPLV, 23, 1) 131228021f0SSong Gao FIELD(CPUCFG1, HP, 24, 1) 132228021f0SSong Gao FIELD(CPUCFG1, IOCSR_BRD, 25, 1) 133228021f0SSong Gao FIELD(CPUCFG1, MSG_INT, 26, 1) 134228021f0SSong Gao 135228021f0SSong Gao /* cpucfg[2] bits */ 136228021f0SSong Gao FIELD(CPUCFG2, FP, 0, 1) 137228021f0SSong Gao FIELD(CPUCFG2, FP_SP, 1, 1) 138228021f0SSong Gao FIELD(CPUCFG2, FP_DP, 2, 1) 139228021f0SSong Gao FIELD(CPUCFG2, FP_VER, 3, 3) 140228021f0SSong Gao FIELD(CPUCFG2, LSX, 6, 1) 141228021f0SSong Gao FIELD(CPUCFG2, LASX, 7, 1) 142228021f0SSong Gao FIELD(CPUCFG2, COMPLEX, 8, 1) 143228021f0SSong Gao FIELD(CPUCFG2, CRYPTO, 9, 1) 144228021f0SSong Gao FIELD(CPUCFG2, LVZ, 10, 1) 145228021f0SSong Gao FIELD(CPUCFG2, LVZ_VER, 11, 3) 146228021f0SSong Gao FIELD(CPUCFG2, LLFTP, 14, 1) 147228021f0SSong Gao FIELD(CPUCFG2, LLFTP_VER, 15, 3) 148228021f0SSong Gao FIELD(CPUCFG2, LBT_X86, 18, 1) 149228021f0SSong Gao FIELD(CPUCFG2, LBT_ARM, 19, 1) 150228021f0SSong Gao FIELD(CPUCFG2, LBT_MIPS, 20, 1) 151228021f0SSong Gao FIELD(CPUCFG2, LSPW, 21, 1) 152228021f0SSong Gao FIELD(CPUCFG2, LAM, 22, 1) 153228021f0SSong Gao 154228021f0SSong Gao /* cpucfg[3] bits */ 155228021f0SSong Gao FIELD(CPUCFG3, CCDMA, 0, 1) 156228021f0SSong Gao FIELD(CPUCFG3, SFB, 1, 1) 157228021f0SSong Gao FIELD(CPUCFG3, UCACC, 2, 1) 158228021f0SSong Gao FIELD(CPUCFG3, LLEXC, 3, 1) 159228021f0SSong Gao FIELD(CPUCFG3, SCDLY, 4, 1) 160228021f0SSong Gao FIELD(CPUCFG3, LLDBAR, 5, 1) 161228021f0SSong Gao FIELD(CPUCFG3, ITLBHMC, 6, 1) 162228021f0SSong Gao FIELD(CPUCFG3, ICHMC, 7, 1) 163228021f0SSong Gao FIELD(CPUCFG3, SPW_LVL, 8, 3) 164228021f0SSong Gao FIELD(CPUCFG3, SPW_HP_HF, 11, 1) 165228021f0SSong Gao FIELD(CPUCFG3, RVA, 12, 1) 166228021f0SSong Gao FIELD(CPUCFG3, RVAMAX, 13, 4) 167228021f0SSong Gao 168228021f0SSong Gao /* cpucfg[4] bits */ 169228021f0SSong Gao FIELD(CPUCFG4, CC_FREQ, 0, 32) 170228021f0SSong Gao 171228021f0SSong Gao /* cpucfg[5] bits */ 172228021f0SSong Gao FIELD(CPUCFG5, CC_MUL, 0, 16) 173228021f0SSong Gao FIELD(CPUCFG5, CC_DIV, 16, 16) 174228021f0SSong Gao 175228021f0SSong Gao /* cpucfg[6] bits */ 176228021f0SSong Gao FIELD(CPUCFG6, PMP, 0, 1) 177228021f0SSong Gao FIELD(CPUCFG6, PMVER, 1, 3) 178228021f0SSong Gao FIELD(CPUCFG6, PMNUM, 4, 4) 179228021f0SSong Gao FIELD(CPUCFG6, PMBITS, 8, 6) 180228021f0SSong Gao FIELD(CPUCFG6, UPM, 14, 1) 181228021f0SSong Gao 182228021f0SSong Gao /* cpucfg[16] bits */ 183228021f0SSong Gao FIELD(CPUCFG16, L1_IUPRE, 0, 1) 184228021f0SSong Gao FIELD(CPUCFG16, L1_IUUNIFY, 1, 1) 185228021f0SSong Gao FIELD(CPUCFG16, L1_DPRE, 2, 1) 186228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRE, 3, 1) 187228021f0SSong Gao FIELD(CPUCFG16, L2_IUUNIFY, 4, 1) 188228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRIV, 5, 1) 189228021f0SSong Gao FIELD(CPUCFG16, L2_IUINCL, 6, 1) 190228021f0SSong Gao FIELD(CPUCFG16, L2_DPRE, 7, 1) 191228021f0SSong Gao FIELD(CPUCFG16, L2_DPRIV, 8, 1) 192228021f0SSong Gao FIELD(CPUCFG16, L2_DINCL, 9, 1) 193228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRE, 10, 1) 194228021f0SSong Gao FIELD(CPUCFG16, L3_IUUNIFY, 11, 1) 195228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRIV, 12, 1) 196228021f0SSong Gao FIELD(CPUCFG16, L3_IUINCL, 13, 1) 197228021f0SSong Gao FIELD(CPUCFG16, L3_DPRE, 14, 1) 198228021f0SSong Gao FIELD(CPUCFG16, L3_DPRIV, 15, 1) 199228021f0SSong Gao FIELD(CPUCFG16, L3_DINCL, 16, 1) 200228021f0SSong Gao 201228021f0SSong Gao /* cpucfg[17] bits */ 202228021f0SSong Gao FIELD(CPUCFG17, L1IU_WAYS, 0, 16) 203228021f0SSong Gao FIELD(CPUCFG17, L1IU_SETS, 16, 8) 204228021f0SSong Gao FIELD(CPUCFG17, L1IU_SIZE, 24, 7) 205228021f0SSong Gao 206228021f0SSong Gao /* cpucfg[18] bits */ 207228021f0SSong Gao FIELD(CPUCFG18, L1D_WAYS, 0, 16) 208228021f0SSong Gao FIELD(CPUCFG18, L1D_SETS, 16, 8) 209228021f0SSong Gao FIELD(CPUCFG18, L1D_SIZE, 24, 7) 210228021f0SSong Gao 211228021f0SSong Gao /* cpucfg[19] bits */ 212228021f0SSong Gao FIELD(CPUCFG19, L2IU_WAYS, 0, 16) 213228021f0SSong Gao FIELD(CPUCFG19, L2IU_SETS, 16, 8) 214228021f0SSong Gao FIELD(CPUCFG19, L2IU_SIZE, 24, 7) 215228021f0SSong Gao 216228021f0SSong Gao /* cpucfg[20] bits */ 217228021f0SSong Gao FIELD(CPUCFG20, L3IU_WAYS, 0, 16) 218228021f0SSong Gao FIELD(CPUCFG20, L3IU_SETS, 16, 8) 219228021f0SSong Gao FIELD(CPUCFG20, L3IU_SIZE, 24, 7) 220228021f0SSong Gao 221398cecb9SXiaojuan Yang /*CSR_CRMD */ 222398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PLV, 0, 2) 223398cecb9SXiaojuan Yang FIELD(CSR_CRMD, IE, 2, 1) 224398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DA, 3, 1) 225398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PG, 4, 1) 226398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATF, 5, 2) 227398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATM, 7, 2) 228398cecb9SXiaojuan Yang FIELD(CSR_CRMD, WE, 9, 1) 229398cecb9SXiaojuan Yang 230228021f0SSong Gao extern const char * const regnames[32]; 231228021f0SSong Gao extern const char * const fregnames[32]; 232228021f0SSong Gao 233f757a2cdSXiaojuan Yang #define N_IRQS 13 234dd615fa4SXiaojuan Yang #define IRQ_TIMER 11 235dd615fa4SXiaojuan Yang #define IRQ_IPI 12 236f757a2cdSXiaojuan Yang 2377e1c521eSXiaojuan Yang #define LOONGARCH_STLB 2048 /* 2048 STLB */ 2387e1c521eSXiaojuan Yang #define LOONGARCH_MTLB 64 /* 64 MTLB */ 2397e1c521eSXiaojuan Yang #define LOONGARCH_TLB_MAX (LOONGARCH_STLB + LOONGARCH_MTLB) 2407e1c521eSXiaojuan Yang 2417e1c521eSXiaojuan Yang /* 2427e1c521eSXiaojuan Yang * define the ASID PS E VPPN field of TLB 2437e1c521eSXiaojuan Yang */ 2447e1c521eSXiaojuan Yang FIELD(TLB_MISC, E, 0, 1) 2457e1c521eSXiaojuan Yang FIELD(TLB_MISC, ASID, 1, 10) 2467e1c521eSXiaojuan Yang FIELD(TLB_MISC, VPPN, 13, 35) 2477e1c521eSXiaojuan Yang FIELD(TLB_MISC, PS, 48, 6) 2487e1c521eSXiaojuan Yang 24916f5396cSSong Gao #define LSX_LEN (128) 25016f5396cSSong Gao typedef union VReg { 25116f5396cSSong Gao int8_t B[LSX_LEN / 8]; 25216f5396cSSong Gao int16_t H[LSX_LEN / 16]; 25316f5396cSSong Gao int32_t W[LSX_LEN / 32]; 25416f5396cSSong Gao int64_t D[LSX_LEN / 64]; 25516f5396cSSong Gao uint8_t UB[LSX_LEN / 8]; 25616f5396cSSong Gao uint16_t UH[LSX_LEN / 16]; 25716f5396cSSong Gao uint32_t UW[LSX_LEN / 32]; 25816f5396cSSong Gao uint64_t UD[LSX_LEN / 64]; 25916f5396cSSong Gao Int128 Q[LSX_LEN / 128]; 26016f5396cSSong Gao }VReg; 26116f5396cSSong Gao 26216f5396cSSong Gao typedef union fpr_t fpr_t; 26316f5396cSSong Gao union fpr_t { 26416f5396cSSong Gao VReg vreg; 26516f5396cSSong Gao }; 26616f5396cSSong Gao 2677e1c521eSXiaojuan Yang struct LoongArchTLB { 2687e1c521eSXiaojuan Yang uint64_t tlb_misc; 2697e1c521eSXiaojuan Yang /* Fields corresponding to CSR_TLBELO0/1 */ 2707e1c521eSXiaojuan Yang uint64_t tlb_entry0; 2717e1c521eSXiaojuan Yang uint64_t tlb_entry1; 2727e1c521eSXiaojuan Yang }; 2737e1c521eSXiaojuan Yang typedef struct LoongArchTLB LoongArchTLB; 2747e1c521eSXiaojuan Yang 275228021f0SSong Gao typedef struct CPUArchState { 276228021f0SSong Gao uint64_t gpr[32]; 277228021f0SSong Gao uint64_t pc; 278228021f0SSong Gao 27916f5396cSSong Gao fpr_t fpr[32]; 280228021f0SSong Gao float_status fp_status; 281228021f0SSong Gao bool cf[8]; 282228021f0SSong Gao 283228021f0SSong Gao uint32_t fcsr0; 284228021f0SSong Gao uint32_t fcsr0_mask; 285228021f0SSong Gao 286228021f0SSong Gao uint32_t cpucfg[21]; 287228021f0SSong Gao 288228021f0SSong Gao uint64_t lladdr; /* LL virtual address compared against SC */ 289228021f0SSong Gao uint64_t llval; 290228021f0SSong Gao 291398cecb9SXiaojuan Yang /* LoongArch CSRs */ 292398cecb9SXiaojuan Yang uint64_t CSR_CRMD; 293398cecb9SXiaojuan Yang uint64_t CSR_PRMD; 294398cecb9SXiaojuan Yang uint64_t CSR_EUEN; 295398cecb9SXiaojuan Yang uint64_t CSR_MISC; 296398cecb9SXiaojuan Yang uint64_t CSR_ECFG; 297398cecb9SXiaojuan Yang uint64_t CSR_ESTAT; 298398cecb9SXiaojuan Yang uint64_t CSR_ERA; 299398cecb9SXiaojuan Yang uint64_t CSR_BADV; 300398cecb9SXiaojuan Yang uint64_t CSR_BADI; 301398cecb9SXiaojuan Yang uint64_t CSR_EENTRY; 302398cecb9SXiaojuan Yang uint64_t CSR_TLBIDX; 303398cecb9SXiaojuan Yang uint64_t CSR_TLBEHI; 304398cecb9SXiaojuan Yang uint64_t CSR_TLBELO0; 305398cecb9SXiaojuan Yang uint64_t CSR_TLBELO1; 306398cecb9SXiaojuan Yang uint64_t CSR_ASID; 307398cecb9SXiaojuan Yang uint64_t CSR_PGDL; 308398cecb9SXiaojuan Yang uint64_t CSR_PGDH; 309398cecb9SXiaojuan Yang uint64_t CSR_PGD; 310398cecb9SXiaojuan Yang uint64_t CSR_PWCL; 311398cecb9SXiaojuan Yang uint64_t CSR_PWCH; 312398cecb9SXiaojuan Yang uint64_t CSR_STLBPS; 313398cecb9SXiaojuan Yang uint64_t CSR_RVACFG; 314398cecb9SXiaojuan Yang uint64_t CSR_PRCFG1; 315398cecb9SXiaojuan Yang uint64_t CSR_PRCFG2; 316398cecb9SXiaojuan Yang uint64_t CSR_PRCFG3; 317398cecb9SXiaojuan Yang uint64_t CSR_SAVE[16]; 318398cecb9SXiaojuan Yang uint64_t CSR_TID; 319398cecb9SXiaojuan Yang uint64_t CSR_TCFG; 320398cecb9SXiaojuan Yang uint64_t CSR_TVAL; 321398cecb9SXiaojuan Yang uint64_t CSR_CNTC; 322398cecb9SXiaojuan Yang uint64_t CSR_TICLR; 323398cecb9SXiaojuan Yang uint64_t CSR_LLBCTL; 324398cecb9SXiaojuan Yang uint64_t CSR_IMPCTL1; 325398cecb9SXiaojuan Yang uint64_t CSR_IMPCTL2; 326398cecb9SXiaojuan Yang uint64_t CSR_TLBRENTRY; 327398cecb9SXiaojuan Yang uint64_t CSR_TLBRBADV; 328398cecb9SXiaojuan Yang uint64_t CSR_TLBRERA; 329398cecb9SXiaojuan Yang uint64_t CSR_TLBRSAVE; 330398cecb9SXiaojuan Yang uint64_t CSR_TLBRELO0; 331398cecb9SXiaojuan Yang uint64_t CSR_TLBRELO1; 332398cecb9SXiaojuan Yang uint64_t CSR_TLBREHI; 333398cecb9SXiaojuan Yang uint64_t CSR_TLBRPRMD; 334398cecb9SXiaojuan Yang uint64_t CSR_MERRCTL; 335398cecb9SXiaojuan Yang uint64_t CSR_MERRINFO1; 336398cecb9SXiaojuan Yang uint64_t CSR_MERRINFO2; 337398cecb9SXiaojuan Yang uint64_t CSR_MERRENTRY; 338398cecb9SXiaojuan Yang uint64_t CSR_MERRERA; 339398cecb9SXiaojuan Yang uint64_t CSR_MERRSAVE; 340398cecb9SXiaojuan Yang uint64_t CSR_CTAG; 341398cecb9SXiaojuan Yang uint64_t CSR_DMW[4]; 342398cecb9SXiaojuan Yang uint64_t CSR_DBG; 343398cecb9SXiaojuan Yang uint64_t CSR_DERA; 344398cecb9SXiaojuan Yang uint64_t CSR_DSAVE; 3457e1c521eSXiaojuan Yang 3460093b9a5SSong Gao #ifndef CONFIG_USER_ONLY 3477e1c521eSXiaojuan Yang LoongArchTLB tlb[LOONGARCH_TLB_MAX]; 348f84a2aacSXiaojuan Yang 349f84a2aacSXiaojuan Yang AddressSpace address_space_iocsr; 350f84a2aacSXiaojuan Yang MemoryRegion system_iocsr; 351f84a2aacSXiaojuan Yang MemoryRegion iocsr_mem; 3526a6f26f4SXiaojuan Yang bool load_elf; 3536a6f26f4SXiaojuan Yang uint64_t elf_address; 3540093b9a5SSong Gao #endif 355228021f0SSong Gao } CPULoongArchState; 356228021f0SSong Gao 357228021f0SSong Gao /** 358228021f0SSong Gao * LoongArchCPU: 359228021f0SSong Gao * @env: #CPULoongArchState 360228021f0SSong Gao * 361228021f0SSong Gao * A LoongArch CPU. 362228021f0SSong Gao */ 363228021f0SSong Gao struct ArchCPU { 364228021f0SSong Gao /*< private >*/ 365228021f0SSong Gao CPUState parent_obj; 366228021f0SSong Gao /*< public >*/ 367228021f0SSong Gao 368228021f0SSong Gao CPUNegativeOffsetState neg; 369228021f0SSong Gao CPULoongArchState env; 370dd615fa4SXiaojuan Yang QEMUTimer timer; 371fda3f15bSXiaojuan Yang 372fda3f15bSXiaojuan Yang /* 'compatible' string for this CPU for Linux device trees */ 373fda3f15bSXiaojuan Yang const char *dtb_compatible; 374228021f0SSong Gao }; 375228021f0SSong Gao 376228021f0SSong Gao #define TYPE_LOONGARCH_CPU "loongarch-cpu" 377228021f0SSong Gao 378228021f0SSong Gao OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass, 379228021f0SSong Gao LOONGARCH_CPU) 380228021f0SSong Gao 381228021f0SSong Gao /** 382228021f0SSong Gao * LoongArchCPUClass: 383228021f0SSong Gao * @parent_realize: The parent class' realize handler. 384f78b49aeSPeter Maydell * @parent_phases: The parent class' reset phase handlers. 385228021f0SSong Gao * 386228021f0SSong Gao * A LoongArch CPU model. 387228021f0SSong Gao */ 388228021f0SSong Gao struct LoongArchCPUClass { 389228021f0SSong Gao /*< private >*/ 390228021f0SSong Gao CPUClass parent_class; 391228021f0SSong Gao /*< public >*/ 392228021f0SSong Gao 393228021f0SSong Gao DeviceRealize parent_realize; 394f78b49aeSPeter Maydell ResettablePhases parent_phases; 395228021f0SSong Gao }; 396228021f0SSong Gao 3977e1c521eSXiaojuan Yang /* 3987e1c521eSXiaojuan Yang * LoongArch CPUs has 4 privilege levels. 3997e1c521eSXiaojuan Yang * 0 for kernel mode, 3 for user mode. 4007e1c521eSXiaojuan Yang * Define an extra index for DA(direct addressing) mode. 4017e1c521eSXiaojuan Yang */ 402c8885b88SRui Wang #define MMU_PLV_KERNEL 0 403c8885b88SRui Wang #define MMU_PLV_USER 3 404c8885b88SRui Wang #define MMU_IDX_KERNEL MMU_PLV_KERNEL 405c8885b88SRui Wang #define MMU_IDX_USER MMU_PLV_USER 406c8885b88SRui Wang #define MMU_IDX_DA 4 4077e1c521eSXiaojuan Yang 4087e1c521eSXiaojuan Yang static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch) 4097e1c521eSXiaojuan Yang { 4100093b9a5SSong Gao #ifdef CONFIG_USER_ONLY 411c8885b88SRui Wang return MMU_IDX_USER; 4120093b9a5SSong Gao #else 413c8885b88SRui Wang if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) { 4147e1c521eSXiaojuan Yang return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); 415c8885b88SRui Wang } 416c8885b88SRui Wang return MMU_IDX_DA; 4170093b9a5SSong Gao #endif 4187e1c521eSXiaojuan Yang } 4197e1c521eSXiaojuan Yang 420b4bda200SRui Wang /* 421b4bda200SRui Wang * LoongArch CPUs hardware flags. 422b4bda200SRui Wang */ 423b4bda200SRui Wang #define HW_FLAGS_PLV_MASK R_CSR_CRMD_PLV_MASK /* 0x03 */ 424b4bda200SRui Wang #define HW_FLAGS_CRMD_PG R_CSR_CRMD_PG_MASK /* 0x10 */ 4252419978cSRui Wang #define HW_FLAGS_EUEN_FPE 0x04 426a3f3db5cSSong Gao #define HW_FLAGS_EUEN_SXE 0x08 427b4bda200SRui Wang 4287e1c521eSXiaojuan Yang static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, 4297e1c521eSXiaojuan Yang target_ulong *pc, 4307e1c521eSXiaojuan Yang target_ulong *cs_base, 4317e1c521eSXiaojuan Yang uint32_t *flags) 4327e1c521eSXiaojuan Yang { 4337e1c521eSXiaojuan Yang *pc = env->pc; 4347e1c521eSXiaojuan Yang *cs_base = 0; 435b4bda200SRui Wang *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); 4362419978cSRui Wang *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; 437a3f3db5cSSong Gao *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE; 4387e1c521eSXiaojuan Yang } 4397e1c521eSXiaojuan Yang 440228021f0SSong Gao void loongarch_cpu_list(void); 441228021f0SSong Gao 442228021f0SSong Gao #define cpu_list loongarch_cpu_list 443228021f0SSong Gao 444228021f0SSong Gao #include "exec/cpu-all.h" 445228021f0SSong Gao 446228021f0SSong Gao #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU 447228021f0SSong Gao #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX 448228021f0SSong Gao #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU 449228021f0SSong Gao 450228021f0SSong Gao #endif /* LOONGARCH_CPU_H */ 451