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