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 11228021f0SSong Gao #include "exec/cpu-defs.h" 12228021f0SSong Gao #include "fpu/softfloat-types.h" 13228021f0SSong Gao #include "hw/registerfields.h" 14dd615fa4SXiaojuan Yang #include "qemu/timer.h" 15*f84a2aacSXiaojuan Yang #include "exec/memory.h" 16*f84a2aacSXiaojuan Yang #include "hw/sysbus.h" 17*f84a2aacSXiaojuan Yang 18*f84a2aacSXiaojuan Yang #define IOCSRF_TEMP 0 19*f84a2aacSXiaojuan Yang #define IOCSRF_NODECNT 1 20*f84a2aacSXiaojuan Yang #define IOCSRF_MSI 2 21*f84a2aacSXiaojuan Yang #define IOCSRF_EXTIOI 3 22*f84a2aacSXiaojuan Yang #define IOCSRF_CSRIPI 4 23*f84a2aacSXiaojuan Yang #define IOCSRF_FREQCSR 5 24*f84a2aacSXiaojuan Yang #define IOCSRF_FREQSCALE 6 25*f84a2aacSXiaojuan Yang #define IOCSRF_DVFSV1 7 26*f84a2aacSXiaojuan Yang #define IOCSRF_GMOD 9 27*f84a2aacSXiaojuan Yang #define IOCSRF_VM 11 28*f84a2aacSXiaojuan Yang 29*f84a2aacSXiaojuan Yang #define FEATURE_REG 0x8 30*f84a2aacSXiaojuan Yang #define VENDOR_REG 0x10 31*f84a2aacSXiaojuan Yang #define CPUNAME_REG 0x20 32*f84a2aacSXiaojuan Yang #define MISC_FUNC_REG 0x420 33*f84a2aacSXiaojuan Yang #define IOCSRM_EXTIOI_EN 48 34*f84a2aacSXiaojuan Yang 35*f84a2aacSXiaojuan Yang #define IOCSR_MEM_SIZE 0x428 36228021f0SSong Gao 37228021f0SSong Gao #define TCG_GUEST_DEFAULT_MO (0) 38228021f0SSong Gao 39228021f0SSong Gao #define FCSR0_M1 0x1f /* FCSR1 mask, Enables */ 40228021f0SSong Gao #define FCSR0_M2 0x1f1f0000 /* FCSR2 mask, Cause and Flags */ 41228021f0SSong Gao #define FCSR0_M3 0x300 /* FCSR3 mask, Round Mode */ 42228021f0SSong Gao #define FCSR0_RM 8 /* Round Mode bit num on fcsr0 */ 43228021f0SSong Gao 44228021f0SSong Gao FIELD(FCSR0, ENABLES, 0, 5) 45228021f0SSong Gao FIELD(FCSR0, RM, 8, 2) 46228021f0SSong Gao FIELD(FCSR0, FLAGS, 16, 5) 47228021f0SSong Gao FIELD(FCSR0, CAUSE, 24, 5) 48228021f0SSong Gao 49228021f0SSong Gao #define GET_FP_CAUSE(REG) FIELD_EX32(REG, FCSR0, CAUSE) 50228021f0SSong Gao #define SET_FP_CAUSE(REG, V) FIELD_DP32(REG, FCSR0, CAUSE, V) 51228021f0SSong Gao #define GET_FP_ENABLES(REG) FIELD_EX32(REG, FCSR0, ENABLES) 52228021f0SSong Gao #define SET_FP_ENABLES(REG, V) FIELD_DP32(REG, FCSR0, ENABLES, V) 53228021f0SSong Gao #define GET_FP_FLAGS(REG) FIELD_EX32(REG, FCSR0, FLAGS) 54228021f0SSong Gao #define SET_FP_FLAGS(REG, V) FIELD_DP32(REG, FCSR0, FLAGS, V) 55228021f0SSong Gao #define UPDATE_FP_FLAGS(REG, V) \ 56228021f0SSong Gao do { \ 57228021f0SSong Gao (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \ 58228021f0SSong Gao } while (0) 59228021f0SSong Gao 60228021f0SSong Gao #define FP_INEXACT 1 61228021f0SSong Gao #define FP_UNDERFLOW 2 62228021f0SSong Gao #define FP_OVERFLOW 4 63228021f0SSong Gao #define FP_DIV0 8 64228021f0SSong Gao #define FP_INVALID 16 65228021f0SSong Gao 66228021f0SSong Gao #define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */ 67228021f0SSong Gao #define EXCCODE_INT 0 68228021f0SSong Gao #define EXCCODE_PIL 1 69228021f0SSong Gao #define EXCCODE_PIS 2 70228021f0SSong Gao #define EXCCODE_PIF 3 71228021f0SSong Gao #define EXCCODE_PME 4 72228021f0SSong Gao #define EXCCODE_PNR 5 73228021f0SSong Gao #define EXCCODE_PNX 6 74228021f0SSong Gao #define EXCCODE_PPI 7 75228021f0SSong Gao #define EXCCODE_ADEF 8 /* Different exception subcode */ 76228021f0SSong Gao #define EXCCODE_ADEM 8 77228021f0SSong Gao #define EXCCODE_ALE 9 78228021f0SSong Gao #define EXCCODE_BCE 10 79228021f0SSong Gao #define EXCCODE_SYS 11 80228021f0SSong Gao #define EXCCODE_BRK 12 81228021f0SSong Gao #define EXCCODE_INE 13 82228021f0SSong Gao #define EXCCODE_IPE 14 83228021f0SSong Gao #define EXCCODE_FPD 15 84228021f0SSong Gao #define EXCCODE_SXD 16 85228021f0SSong Gao #define EXCCODE_ASXD 17 86228021f0SSong Gao #define EXCCODE_FPE 18 /* Different exception subcode */ 87228021f0SSong Gao #define EXCCODE_VFPE 18 88228021f0SSong Gao #define EXCCODE_WPEF 19 /* Different exception subcode */ 89228021f0SSong Gao #define EXCCODE_WPEM 19 90228021f0SSong Gao #define EXCCODE_BTD 20 91228021f0SSong Gao #define EXCCODE_BTE 21 92228021f0SSong Gao #define EXCCODE_DBP 26 /* Reserved subcode used for debug */ 93228021f0SSong Gao 94228021f0SSong Gao /* cpucfg[0] bits */ 95228021f0SSong Gao FIELD(CPUCFG0, PRID, 0, 32) 96228021f0SSong Gao 97228021f0SSong Gao /* cpucfg[1] bits */ 98228021f0SSong Gao FIELD(CPUCFG1, ARCH, 0, 2) 99228021f0SSong Gao FIELD(CPUCFG1, PGMMU, 2, 1) 100228021f0SSong Gao FIELD(CPUCFG1, IOCSR, 3, 1) 101228021f0SSong Gao FIELD(CPUCFG1, PALEN, 4, 8) 102228021f0SSong Gao FIELD(CPUCFG1, VALEN, 12, 8) 103228021f0SSong Gao FIELD(CPUCFG1, UAL, 20, 1) 104228021f0SSong Gao FIELD(CPUCFG1, RI, 21, 1) 105228021f0SSong Gao FIELD(CPUCFG1, EP, 22, 1) 106228021f0SSong Gao FIELD(CPUCFG1, RPLV, 23, 1) 107228021f0SSong Gao FIELD(CPUCFG1, HP, 24, 1) 108228021f0SSong Gao FIELD(CPUCFG1, IOCSR_BRD, 25, 1) 109228021f0SSong Gao FIELD(CPUCFG1, MSG_INT, 26, 1) 110228021f0SSong Gao 111228021f0SSong Gao /* cpucfg[2] bits */ 112228021f0SSong Gao FIELD(CPUCFG2, FP, 0, 1) 113228021f0SSong Gao FIELD(CPUCFG2, FP_SP, 1, 1) 114228021f0SSong Gao FIELD(CPUCFG2, FP_DP, 2, 1) 115228021f0SSong Gao FIELD(CPUCFG2, FP_VER, 3, 3) 116228021f0SSong Gao FIELD(CPUCFG2, LSX, 6, 1) 117228021f0SSong Gao FIELD(CPUCFG2, LASX, 7, 1) 118228021f0SSong Gao FIELD(CPUCFG2, COMPLEX, 8, 1) 119228021f0SSong Gao FIELD(CPUCFG2, CRYPTO, 9, 1) 120228021f0SSong Gao FIELD(CPUCFG2, LVZ, 10, 1) 121228021f0SSong Gao FIELD(CPUCFG2, LVZ_VER, 11, 3) 122228021f0SSong Gao FIELD(CPUCFG2, LLFTP, 14, 1) 123228021f0SSong Gao FIELD(CPUCFG2, LLFTP_VER, 15, 3) 124228021f0SSong Gao FIELD(CPUCFG2, LBT_X86, 18, 1) 125228021f0SSong Gao FIELD(CPUCFG2, LBT_ARM, 19, 1) 126228021f0SSong Gao FIELD(CPUCFG2, LBT_MIPS, 20, 1) 127228021f0SSong Gao FIELD(CPUCFG2, LSPW, 21, 1) 128228021f0SSong Gao FIELD(CPUCFG2, LAM, 22, 1) 129228021f0SSong Gao 130228021f0SSong Gao /* cpucfg[3] bits */ 131228021f0SSong Gao FIELD(CPUCFG3, CCDMA, 0, 1) 132228021f0SSong Gao FIELD(CPUCFG3, SFB, 1, 1) 133228021f0SSong Gao FIELD(CPUCFG3, UCACC, 2, 1) 134228021f0SSong Gao FIELD(CPUCFG3, LLEXC, 3, 1) 135228021f0SSong Gao FIELD(CPUCFG3, SCDLY, 4, 1) 136228021f0SSong Gao FIELD(CPUCFG3, LLDBAR, 5, 1) 137228021f0SSong Gao FIELD(CPUCFG3, ITLBHMC, 6, 1) 138228021f0SSong Gao FIELD(CPUCFG3, ICHMC, 7, 1) 139228021f0SSong Gao FIELD(CPUCFG3, SPW_LVL, 8, 3) 140228021f0SSong Gao FIELD(CPUCFG3, SPW_HP_HF, 11, 1) 141228021f0SSong Gao FIELD(CPUCFG3, RVA, 12, 1) 142228021f0SSong Gao FIELD(CPUCFG3, RVAMAX, 13, 4) 143228021f0SSong Gao 144228021f0SSong Gao /* cpucfg[4] bits */ 145228021f0SSong Gao FIELD(CPUCFG4, CC_FREQ, 0, 32) 146228021f0SSong Gao 147228021f0SSong Gao /* cpucfg[5] bits */ 148228021f0SSong Gao FIELD(CPUCFG5, CC_MUL, 0, 16) 149228021f0SSong Gao FIELD(CPUCFG5, CC_DIV, 16, 16) 150228021f0SSong Gao 151228021f0SSong Gao /* cpucfg[6] bits */ 152228021f0SSong Gao FIELD(CPUCFG6, PMP, 0, 1) 153228021f0SSong Gao FIELD(CPUCFG6, PMVER, 1, 3) 154228021f0SSong Gao FIELD(CPUCFG6, PMNUM, 4, 4) 155228021f0SSong Gao FIELD(CPUCFG6, PMBITS, 8, 6) 156228021f0SSong Gao FIELD(CPUCFG6, UPM, 14, 1) 157228021f0SSong Gao 158228021f0SSong Gao /* cpucfg[16] bits */ 159228021f0SSong Gao FIELD(CPUCFG16, L1_IUPRE, 0, 1) 160228021f0SSong Gao FIELD(CPUCFG16, L1_IUUNIFY, 1, 1) 161228021f0SSong Gao FIELD(CPUCFG16, L1_DPRE, 2, 1) 162228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRE, 3, 1) 163228021f0SSong Gao FIELD(CPUCFG16, L2_IUUNIFY, 4, 1) 164228021f0SSong Gao FIELD(CPUCFG16, L2_IUPRIV, 5, 1) 165228021f0SSong Gao FIELD(CPUCFG16, L2_IUINCL, 6, 1) 166228021f0SSong Gao FIELD(CPUCFG16, L2_DPRE, 7, 1) 167228021f0SSong Gao FIELD(CPUCFG16, L2_DPRIV, 8, 1) 168228021f0SSong Gao FIELD(CPUCFG16, L2_DINCL, 9, 1) 169228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRE, 10, 1) 170228021f0SSong Gao FIELD(CPUCFG16, L3_IUUNIFY, 11, 1) 171228021f0SSong Gao FIELD(CPUCFG16, L3_IUPRIV, 12, 1) 172228021f0SSong Gao FIELD(CPUCFG16, L3_IUINCL, 13, 1) 173228021f0SSong Gao FIELD(CPUCFG16, L3_DPRE, 14, 1) 174228021f0SSong Gao FIELD(CPUCFG16, L3_DPRIV, 15, 1) 175228021f0SSong Gao FIELD(CPUCFG16, L3_DINCL, 16, 1) 176228021f0SSong Gao 177228021f0SSong Gao /* cpucfg[17] bits */ 178228021f0SSong Gao FIELD(CPUCFG17, L1IU_WAYS, 0, 16) 179228021f0SSong Gao FIELD(CPUCFG17, L1IU_SETS, 16, 8) 180228021f0SSong Gao FIELD(CPUCFG17, L1IU_SIZE, 24, 7) 181228021f0SSong Gao 182228021f0SSong Gao /* cpucfg[18] bits */ 183228021f0SSong Gao FIELD(CPUCFG18, L1D_WAYS, 0, 16) 184228021f0SSong Gao FIELD(CPUCFG18, L1D_SETS, 16, 8) 185228021f0SSong Gao FIELD(CPUCFG18, L1D_SIZE, 24, 7) 186228021f0SSong Gao 187228021f0SSong Gao /* cpucfg[19] bits */ 188228021f0SSong Gao FIELD(CPUCFG19, L2IU_WAYS, 0, 16) 189228021f0SSong Gao FIELD(CPUCFG19, L2IU_SETS, 16, 8) 190228021f0SSong Gao FIELD(CPUCFG19, L2IU_SIZE, 24, 7) 191228021f0SSong Gao 192228021f0SSong Gao /* cpucfg[20] bits */ 193228021f0SSong Gao FIELD(CPUCFG20, L3IU_WAYS, 0, 16) 194228021f0SSong Gao FIELD(CPUCFG20, L3IU_SETS, 16, 8) 195228021f0SSong Gao FIELD(CPUCFG20, L3IU_SIZE, 24, 7) 196228021f0SSong Gao 197398cecb9SXiaojuan Yang /*CSR_CRMD */ 198398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PLV, 0, 2) 199398cecb9SXiaojuan Yang FIELD(CSR_CRMD, IE, 2, 1) 200398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DA, 3, 1) 201398cecb9SXiaojuan Yang FIELD(CSR_CRMD, PG, 4, 1) 202398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATF, 5, 2) 203398cecb9SXiaojuan Yang FIELD(CSR_CRMD, DATM, 7, 2) 204398cecb9SXiaojuan Yang FIELD(CSR_CRMD, WE, 9, 1) 205398cecb9SXiaojuan Yang 206228021f0SSong Gao extern const char * const regnames[32]; 207228021f0SSong Gao extern const char * const fregnames[32]; 208228021f0SSong Gao 209f757a2cdSXiaojuan Yang #define N_IRQS 13 210dd615fa4SXiaojuan Yang #define IRQ_TIMER 11 211dd615fa4SXiaojuan Yang #define IRQ_IPI 12 212f757a2cdSXiaojuan Yang 2137e1c521eSXiaojuan Yang #define LOONGARCH_STLB 2048 /* 2048 STLB */ 2147e1c521eSXiaojuan Yang #define LOONGARCH_MTLB 64 /* 64 MTLB */ 2157e1c521eSXiaojuan Yang #define LOONGARCH_TLB_MAX (LOONGARCH_STLB + LOONGARCH_MTLB) 2167e1c521eSXiaojuan Yang 2177e1c521eSXiaojuan Yang /* 2187e1c521eSXiaojuan Yang * define the ASID PS E VPPN field of TLB 2197e1c521eSXiaojuan Yang */ 2207e1c521eSXiaojuan Yang FIELD(TLB_MISC, E, 0, 1) 2217e1c521eSXiaojuan Yang FIELD(TLB_MISC, ASID, 1, 10) 2227e1c521eSXiaojuan Yang FIELD(TLB_MISC, VPPN, 13, 35) 2237e1c521eSXiaojuan Yang FIELD(TLB_MISC, PS, 48, 6) 2247e1c521eSXiaojuan Yang 2257e1c521eSXiaojuan Yang struct LoongArchTLB { 2267e1c521eSXiaojuan Yang uint64_t tlb_misc; 2277e1c521eSXiaojuan Yang /* Fields corresponding to CSR_TLBELO0/1 */ 2287e1c521eSXiaojuan Yang uint64_t tlb_entry0; 2297e1c521eSXiaojuan Yang uint64_t tlb_entry1; 2307e1c521eSXiaojuan Yang }; 2317e1c521eSXiaojuan Yang typedef struct LoongArchTLB LoongArchTLB; 2327e1c521eSXiaojuan Yang 233228021f0SSong Gao typedef struct CPUArchState { 234228021f0SSong Gao uint64_t gpr[32]; 235228021f0SSong Gao uint64_t pc; 236228021f0SSong Gao 237228021f0SSong Gao uint64_t fpr[32]; 238228021f0SSong Gao float_status fp_status; 239228021f0SSong Gao bool cf[8]; 240228021f0SSong Gao 241228021f0SSong Gao uint32_t fcsr0; 242228021f0SSong Gao uint32_t fcsr0_mask; 243228021f0SSong Gao 244228021f0SSong Gao uint32_t cpucfg[21]; 245228021f0SSong Gao 246228021f0SSong Gao uint64_t lladdr; /* LL virtual address compared against SC */ 247228021f0SSong Gao uint64_t llval; 248228021f0SSong Gao 249228021f0SSong Gao uint64_t badaddr; 250398cecb9SXiaojuan Yang 251398cecb9SXiaojuan Yang /* LoongArch CSRs */ 252398cecb9SXiaojuan Yang uint64_t CSR_CRMD; 253398cecb9SXiaojuan Yang uint64_t CSR_PRMD; 254398cecb9SXiaojuan Yang uint64_t CSR_EUEN; 255398cecb9SXiaojuan Yang uint64_t CSR_MISC; 256398cecb9SXiaojuan Yang uint64_t CSR_ECFG; 257398cecb9SXiaojuan Yang uint64_t CSR_ESTAT; 258398cecb9SXiaojuan Yang uint64_t CSR_ERA; 259398cecb9SXiaojuan Yang uint64_t CSR_BADV; 260398cecb9SXiaojuan Yang uint64_t CSR_BADI; 261398cecb9SXiaojuan Yang uint64_t CSR_EENTRY; 262398cecb9SXiaojuan Yang uint64_t CSR_TLBIDX; 263398cecb9SXiaojuan Yang uint64_t CSR_TLBEHI; 264398cecb9SXiaojuan Yang uint64_t CSR_TLBELO0; 265398cecb9SXiaojuan Yang uint64_t CSR_TLBELO1; 266398cecb9SXiaojuan Yang uint64_t CSR_ASID; 267398cecb9SXiaojuan Yang uint64_t CSR_PGDL; 268398cecb9SXiaojuan Yang uint64_t CSR_PGDH; 269398cecb9SXiaojuan Yang uint64_t CSR_PGD; 270398cecb9SXiaojuan Yang uint64_t CSR_PWCL; 271398cecb9SXiaojuan Yang uint64_t CSR_PWCH; 272398cecb9SXiaojuan Yang uint64_t CSR_STLBPS; 273398cecb9SXiaojuan Yang uint64_t CSR_RVACFG; 274398cecb9SXiaojuan Yang uint64_t CSR_PRCFG1; 275398cecb9SXiaojuan Yang uint64_t CSR_PRCFG2; 276398cecb9SXiaojuan Yang uint64_t CSR_PRCFG3; 277398cecb9SXiaojuan Yang uint64_t CSR_SAVE[16]; 278398cecb9SXiaojuan Yang uint64_t CSR_TID; 279398cecb9SXiaojuan Yang uint64_t CSR_TCFG; 280398cecb9SXiaojuan Yang uint64_t CSR_TVAL; 281398cecb9SXiaojuan Yang uint64_t CSR_CNTC; 282398cecb9SXiaojuan Yang uint64_t CSR_TICLR; 283398cecb9SXiaojuan Yang uint64_t CSR_LLBCTL; 284398cecb9SXiaojuan Yang uint64_t CSR_IMPCTL1; 285398cecb9SXiaojuan Yang uint64_t CSR_IMPCTL2; 286398cecb9SXiaojuan Yang uint64_t CSR_TLBRENTRY; 287398cecb9SXiaojuan Yang uint64_t CSR_TLBRBADV; 288398cecb9SXiaojuan Yang uint64_t CSR_TLBRERA; 289398cecb9SXiaojuan Yang uint64_t CSR_TLBRSAVE; 290398cecb9SXiaojuan Yang uint64_t CSR_TLBRELO0; 291398cecb9SXiaojuan Yang uint64_t CSR_TLBRELO1; 292398cecb9SXiaojuan Yang uint64_t CSR_TLBREHI; 293398cecb9SXiaojuan Yang uint64_t CSR_TLBRPRMD; 294398cecb9SXiaojuan Yang uint64_t CSR_MERRCTL; 295398cecb9SXiaojuan Yang uint64_t CSR_MERRINFO1; 296398cecb9SXiaojuan Yang uint64_t CSR_MERRINFO2; 297398cecb9SXiaojuan Yang uint64_t CSR_MERRENTRY; 298398cecb9SXiaojuan Yang uint64_t CSR_MERRERA; 299398cecb9SXiaojuan Yang uint64_t CSR_MERRSAVE; 300398cecb9SXiaojuan Yang uint64_t CSR_CTAG; 301398cecb9SXiaojuan Yang uint64_t CSR_DMW[4]; 302398cecb9SXiaojuan Yang uint64_t CSR_DBG; 303398cecb9SXiaojuan Yang uint64_t CSR_DERA; 304398cecb9SXiaojuan Yang uint64_t CSR_DSAVE; 3057e1c521eSXiaojuan Yang 3067e1c521eSXiaojuan Yang LoongArchTLB tlb[LOONGARCH_TLB_MAX]; 307*f84a2aacSXiaojuan Yang 308*f84a2aacSXiaojuan Yang AddressSpace address_space_iocsr; 309*f84a2aacSXiaojuan Yang MemoryRegion system_iocsr; 310*f84a2aacSXiaojuan Yang MemoryRegion iocsr_mem; 311228021f0SSong Gao } CPULoongArchState; 312228021f0SSong Gao 313228021f0SSong Gao /** 314228021f0SSong Gao * LoongArchCPU: 315228021f0SSong Gao * @env: #CPULoongArchState 316228021f0SSong Gao * 317228021f0SSong Gao * A LoongArch CPU. 318228021f0SSong Gao */ 319228021f0SSong Gao struct ArchCPU { 320228021f0SSong Gao /*< private >*/ 321228021f0SSong Gao CPUState parent_obj; 322228021f0SSong Gao /*< public >*/ 323228021f0SSong Gao 324228021f0SSong Gao CPUNegativeOffsetState neg; 325228021f0SSong Gao CPULoongArchState env; 326dd615fa4SXiaojuan Yang QEMUTimer timer; 327228021f0SSong Gao }; 328228021f0SSong Gao 329228021f0SSong Gao #define TYPE_LOONGARCH_CPU "loongarch-cpu" 330228021f0SSong Gao 331228021f0SSong Gao OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass, 332228021f0SSong Gao LOONGARCH_CPU) 333228021f0SSong Gao 334228021f0SSong Gao /** 335228021f0SSong Gao * LoongArchCPUClass: 336228021f0SSong Gao * @parent_realize: The parent class' realize handler. 337228021f0SSong Gao * @parent_reset: The parent class' reset handler. 338228021f0SSong Gao * 339228021f0SSong Gao * A LoongArch CPU model. 340228021f0SSong Gao */ 341228021f0SSong Gao struct LoongArchCPUClass { 342228021f0SSong Gao /*< private >*/ 343228021f0SSong Gao CPUClass parent_class; 344228021f0SSong Gao /*< public >*/ 345228021f0SSong Gao 346228021f0SSong Gao DeviceRealize parent_realize; 347228021f0SSong Gao DeviceReset parent_reset; 348228021f0SSong Gao }; 349228021f0SSong Gao 3507e1c521eSXiaojuan Yang /* 3517e1c521eSXiaojuan Yang * LoongArch CPUs has 4 privilege levels. 3527e1c521eSXiaojuan Yang * 0 for kernel mode, 3 for user mode. 3537e1c521eSXiaojuan Yang * Define an extra index for DA(direct addressing) mode. 3547e1c521eSXiaojuan Yang */ 3557e1c521eSXiaojuan Yang #define MMU_KERNEL_IDX 0 3567e1c521eSXiaojuan Yang #define MMU_USER_IDX 3 3577e1c521eSXiaojuan Yang #define MMU_DA_IDX 4 3587e1c521eSXiaojuan Yang 3597e1c521eSXiaojuan Yang static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch) 3607e1c521eSXiaojuan Yang { 3617e1c521eSXiaojuan Yang uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG); 3627e1c521eSXiaojuan Yang 3637e1c521eSXiaojuan Yang if (!pg) { 3647e1c521eSXiaojuan Yang return MMU_DA_IDX; 3657e1c521eSXiaojuan Yang } 3667e1c521eSXiaojuan Yang return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); 3677e1c521eSXiaojuan Yang } 3687e1c521eSXiaojuan Yang 3697e1c521eSXiaojuan Yang static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, 3707e1c521eSXiaojuan Yang target_ulong *pc, 3717e1c521eSXiaojuan Yang target_ulong *cs_base, 3727e1c521eSXiaojuan Yang uint32_t *flags) 3737e1c521eSXiaojuan Yang { 3747e1c521eSXiaojuan Yang *pc = env->pc; 3757e1c521eSXiaojuan Yang *cs_base = 0; 3767e1c521eSXiaojuan Yang *flags = cpu_mmu_index(env, false); 3777e1c521eSXiaojuan Yang } 3787e1c521eSXiaojuan Yang 379228021f0SSong Gao void loongarch_cpu_list(void); 380228021f0SSong Gao 381228021f0SSong Gao #define cpu_list loongarch_cpu_list 382228021f0SSong Gao 383228021f0SSong Gao #include "exec/cpu-all.h" 384228021f0SSong Gao 385228021f0SSong Gao #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU 386228021f0SSong Gao #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX 387228021f0SSong Gao #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU 388228021f0SSong Gao 389228021f0SSong Gao #endif /* LOONGARCH_CPU_H */ 390