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