cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

cpu.h (25498B)


      1#ifndef SPARC_CPU_H
      2#define SPARC_CPU_H
      3
      4#include "qemu/bswap.h"
      5#include "cpu-qom.h"
      6#include "exec/cpu-defs.h"
      7
      8#if !defined(TARGET_SPARC64)
      9#define TARGET_DPREGS 16
     10#else
     11#define TARGET_DPREGS 32
     12#endif
     13
     14/*#define EXCP_INTERRUPT 0x100*/
     15
     16/* Windowed register indexes.  */
     17enum {
     18    WREG_O0,
     19    WREG_O1,
     20    WREG_O2,
     21    WREG_O3,
     22    WREG_O4,
     23    WREG_O5,
     24    WREG_O6,
     25    WREG_O7,
     26
     27    WREG_L0,
     28    WREG_L1,
     29    WREG_L2,
     30    WREG_L3,
     31    WREG_L4,
     32    WREG_L5,
     33    WREG_L6,
     34    WREG_L7,
     35
     36    WREG_I0,
     37    WREG_I1,
     38    WREG_I2,
     39    WREG_I3,
     40    WREG_I4,
     41    WREG_I5,
     42    WREG_I6,
     43    WREG_I7,
     44
     45    WREG_SP = WREG_O6,
     46    WREG_FP = WREG_I6,
     47};
     48
     49/* trap definitions */
     50#ifndef TARGET_SPARC64
     51#define TT_TFAULT   0x01
     52#define TT_ILL_INSN 0x02
     53#define TT_PRIV_INSN 0x03
     54#define TT_NFPU_INSN 0x04
     55#define TT_WIN_OVF  0x05
     56#define TT_WIN_UNF  0x06
     57#define TT_UNALIGNED 0x07
     58#define TT_FP_EXCP  0x08
     59#define TT_DFAULT   0x09
     60#define TT_TOVF     0x0a
     61#define TT_EXTINT   0x10
     62#define TT_CODE_ACCESS 0x21
     63#define TT_UNIMP_FLUSH 0x25
     64#define TT_DATA_ACCESS 0x29
     65#define TT_DIV_ZERO 0x2a
     66#define TT_NCP_INSN 0x24
     67#define TT_TRAP     0x80
     68#else
     69#define TT_POWER_ON_RESET 0x01
     70#define TT_TFAULT   0x08
     71#define TT_CODE_ACCESS 0x0a
     72#define TT_ILL_INSN 0x10
     73#define TT_UNIMP_FLUSH TT_ILL_INSN
     74#define TT_PRIV_INSN 0x11
     75#define TT_NFPU_INSN 0x20
     76#define TT_FP_EXCP  0x21
     77#define TT_TOVF     0x23
     78#define TT_CLRWIN   0x24
     79#define TT_DIV_ZERO 0x28
     80#define TT_DFAULT   0x30
     81#define TT_DATA_ACCESS 0x32
     82#define TT_UNALIGNED 0x34
     83#define TT_PRIV_ACT 0x37
     84#define TT_INSN_REAL_TRANSLATION_MISS 0x3e
     85#define TT_DATA_REAL_TRANSLATION_MISS 0x3f
     86#define TT_EXTINT   0x40
     87#define TT_IVEC     0x60
     88#define TT_TMISS    0x64
     89#define TT_DMISS    0x68
     90#define TT_DPROT    0x6c
     91#define TT_SPILL    0x80
     92#define TT_FILL     0xc0
     93#define TT_WOTHER   (1 << 5)
     94#define TT_TRAP     0x100
     95#define TT_HTRAP    0x180
     96#endif
     97
     98#define PSR_NEG_SHIFT 23
     99#define PSR_NEG   (1 << PSR_NEG_SHIFT)
    100#define PSR_ZERO_SHIFT 22
    101#define PSR_ZERO  (1 << PSR_ZERO_SHIFT)
    102#define PSR_OVF_SHIFT 21
    103#define PSR_OVF   (1 << PSR_OVF_SHIFT)
    104#define PSR_CARRY_SHIFT 20
    105#define PSR_CARRY (1 << PSR_CARRY_SHIFT)
    106#define PSR_ICC   (PSR_NEG|PSR_ZERO|PSR_OVF|PSR_CARRY)
    107#if !defined(TARGET_SPARC64)
    108#define PSR_EF    (1<<12)
    109#define PSR_PIL   0xf00
    110#define PSR_S     (1<<7)
    111#define PSR_PS    (1<<6)
    112#define PSR_ET    (1<<5)
    113#define PSR_CWP   0x1f
    114#endif
    115
    116#define CC_SRC (env->cc_src)
    117#define CC_SRC2 (env->cc_src2)
    118#define CC_DST (env->cc_dst)
    119#define CC_OP  (env->cc_op)
    120
    121/* Even though lazy evaluation of CPU condition codes tends to be less
    122 * important on RISC systems where condition codes are only updated
    123 * when explicitly requested, SPARC uses it to update 32-bit and 64-bit
    124 * condition codes.
    125 */
    126enum {
    127    CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
    128    CC_OP_FLAGS,   /* all cc are back in status register */
    129    CC_OP_DIV,     /* modify N, Z and V, C = 0*/
    130    CC_OP_ADD,     /* modify all flags, CC_DST = res, CC_SRC = src1 */
    131    CC_OP_ADDX,    /* modify all flags, CC_DST = res, CC_SRC = src1 */
    132    CC_OP_TADD,    /* modify all flags, CC_DST = res, CC_SRC = src1 */
    133    CC_OP_TADDTV,  /* modify all flags except V, CC_DST = res, CC_SRC = src1 */
    134    CC_OP_SUB,     /* modify all flags, CC_DST = res, CC_SRC = src1 */
    135    CC_OP_SUBX,    /* modify all flags, CC_DST = res, CC_SRC = src1 */
    136    CC_OP_TSUB,    /* modify all flags, CC_DST = res, CC_SRC = src1 */
    137    CC_OP_TSUBTV,  /* modify all flags except V, CC_DST = res, CC_SRC = src1 */
    138    CC_OP_LOGIC,   /* modify N and Z, C = V = 0, CC_DST = res */
    139    CC_OP_NB,
    140};
    141
    142/* Trap base register */
    143#define TBR_BASE_MASK 0xfffff000
    144
    145#if defined(TARGET_SPARC64)
    146#define PS_TCT   (1<<12) /* UA2007, impl.dep. trap on control transfer */
    147#define PS_IG    (1<<11) /* v9, zero on UA2007 */
    148#define PS_MG    (1<<10) /* v9, zero on UA2007 */
    149#define PS_CLE   (1<<9) /* UA2007 */
    150#define PS_TLE   (1<<8) /* UA2007 */
    151#define PS_RMO   (1<<7)
    152#define PS_RED   (1<<5) /* v9, zero on UA2007 */
    153#define PS_PEF   (1<<4) /* enable fpu */
    154#define PS_AM    (1<<3) /* address mask */
    155#define PS_PRIV  (1<<2)
    156#define PS_IE    (1<<1)
    157#define PS_AG    (1<<0) /* v9, zero on UA2007 */
    158
    159#define FPRS_DL (1 << 0)
    160#define FPRS_DU (1 << 1)
    161#define FPRS_FEF (1 << 2)
    162
    163#define HS_PRIV  (1<<2)
    164#endif
    165
    166/* Fcc */
    167#define FSR_RD1        (1ULL << 31)
    168#define FSR_RD0        (1ULL << 30)
    169#define FSR_RD_MASK    (FSR_RD1 | FSR_RD0)
    170#define FSR_RD_NEAREST 0
    171#define FSR_RD_ZERO    FSR_RD0
    172#define FSR_RD_POS     FSR_RD1
    173#define FSR_RD_NEG     (FSR_RD1 | FSR_RD0)
    174
    175#define FSR_NVM   (1ULL << 27)
    176#define FSR_OFM   (1ULL << 26)
    177#define FSR_UFM   (1ULL << 25)
    178#define FSR_DZM   (1ULL << 24)
    179#define FSR_NXM   (1ULL << 23)
    180#define FSR_TEM_MASK (FSR_NVM | FSR_OFM | FSR_UFM | FSR_DZM | FSR_NXM)
    181
    182#define FSR_NVA   (1ULL << 9)
    183#define FSR_OFA   (1ULL << 8)
    184#define FSR_UFA   (1ULL << 7)
    185#define FSR_DZA   (1ULL << 6)
    186#define FSR_NXA   (1ULL << 5)
    187#define FSR_AEXC_MASK (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
    188
    189#define FSR_NVC   (1ULL << 4)
    190#define FSR_OFC   (1ULL << 3)
    191#define FSR_UFC   (1ULL << 2)
    192#define FSR_DZC   (1ULL << 1)
    193#define FSR_NXC   (1ULL << 0)
    194#define FSR_CEXC_MASK (FSR_NVC | FSR_OFC | FSR_UFC | FSR_DZC | FSR_NXC)
    195
    196#define FSR_FTT2   (1ULL << 16)
    197#define FSR_FTT1   (1ULL << 15)
    198#define FSR_FTT0   (1ULL << 14)
    199//gcc warns about constant overflow for ~FSR_FTT_MASK
    200//#define FSR_FTT_MASK (FSR_FTT2 | FSR_FTT1 | FSR_FTT0)
    201#ifdef TARGET_SPARC64
    202#define FSR_FTT_NMASK      0xfffffffffffe3fffULL
    203#define FSR_FTT_CEXC_NMASK 0xfffffffffffe3fe0ULL
    204#define FSR_LDFSR_OLDMASK  0x0000003f000fc000ULL
    205#define FSR_LDXFSR_MASK    0x0000003fcfc00fffULL
    206#define FSR_LDXFSR_OLDMASK 0x00000000000fc000ULL
    207#else
    208#define FSR_FTT_NMASK      0xfffe3fffULL
    209#define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL
    210#define FSR_LDFSR_OLDMASK  0x000fc000ULL
    211#endif
    212#define FSR_LDFSR_MASK     0xcfc00fffULL
    213#define FSR_FTT_IEEE_EXCP (1ULL << 14)
    214#define FSR_FTT_UNIMPFPOP (3ULL << 14)
    215#define FSR_FTT_SEQ_ERROR (4ULL << 14)
    216#define FSR_FTT_INVAL_FPR (6ULL << 14)
    217
    218#define FSR_FCC1_SHIFT 11
    219#define FSR_FCC1  (1ULL << FSR_FCC1_SHIFT)
    220#define FSR_FCC0_SHIFT 10
    221#define FSR_FCC0  (1ULL << FSR_FCC0_SHIFT)
    222
    223/* MMU */
    224#define MMU_E     (1<<0)
    225#define MMU_NF    (1<<1)
    226
    227#define PTE_ENTRYTYPE_MASK 3
    228#define PTE_ACCESS_MASK    0x1c
    229#define PTE_ACCESS_SHIFT   2
    230#define PTE_PPN_SHIFT      7
    231#define PTE_ADDR_MASK      0xffffff00
    232
    233#define PG_ACCESSED_BIT 5
    234#define PG_MODIFIED_BIT 6
    235#define PG_CACHE_BIT    7
    236
    237#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
    238#define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT)
    239#define PG_CACHE_MASK    (1 << PG_CACHE_BIT)
    240
    241/* 3 <= NWINDOWS <= 32. */
    242#define MIN_NWINDOWS 3
    243#define MAX_NWINDOWS 32
    244
    245#ifdef TARGET_SPARC64
    246typedef struct trap_state {
    247    uint64_t tpc;
    248    uint64_t tnpc;
    249    uint64_t tstate;
    250    uint32_t tt;
    251} trap_state;
    252#endif
    253#define TARGET_INSN_START_EXTRA_WORDS 1
    254
    255struct sparc_def_t {
    256    const char *name;
    257    target_ulong iu_version;
    258    uint32_t fpu_version;
    259    uint32_t mmu_version;
    260    uint32_t mmu_bm;
    261    uint32_t mmu_ctpr_mask;
    262    uint32_t mmu_cxr_mask;
    263    uint32_t mmu_sfsr_mask;
    264    uint32_t mmu_trcr_mask;
    265    uint32_t mxcc_version;
    266    uint32_t features;
    267    uint32_t nwindows;
    268    uint32_t maxtl;
    269};
    270
    271#define CPU_FEATURE_FLOAT        (1 << 0)
    272#define CPU_FEATURE_FLOAT128     (1 << 1)
    273#define CPU_FEATURE_SWAP         (1 << 2)
    274#define CPU_FEATURE_MUL          (1 << 3)
    275#define CPU_FEATURE_DIV          (1 << 4)
    276#define CPU_FEATURE_FLUSH        (1 << 5)
    277#define CPU_FEATURE_FSQRT        (1 << 6)
    278#define CPU_FEATURE_FMUL         (1 << 7)
    279#define CPU_FEATURE_VIS1         (1 << 8)
    280#define CPU_FEATURE_VIS2         (1 << 9)
    281#define CPU_FEATURE_FSMULD       (1 << 10)
    282#define CPU_FEATURE_HYPV         (1 << 11)
    283#define CPU_FEATURE_CMT          (1 << 12)
    284#define CPU_FEATURE_GL           (1 << 13)
    285#define CPU_FEATURE_TA0_SHUTDOWN (1 << 14) /* Shutdown on "ta 0x0" */
    286#define CPU_FEATURE_ASR17        (1 << 15)
    287#define CPU_FEATURE_CACHE_CTRL   (1 << 16)
    288#define CPU_FEATURE_POWERDOWN    (1 << 17)
    289#define CPU_FEATURE_CASA         (1 << 18)
    290
    291#ifndef TARGET_SPARC64
    292#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP |  \
    293                              CPU_FEATURE_MUL | CPU_FEATURE_DIV |     \
    294                              CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
    295                              CPU_FEATURE_FMUL | CPU_FEATURE_FSMULD)
    296#else
    297#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP |  \
    298                              CPU_FEATURE_MUL | CPU_FEATURE_DIV |     \
    299                              CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
    300                              CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 |   \
    301                              CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD | \
    302                              CPU_FEATURE_CASA)
    303enum {
    304    mmu_us_12, // Ultrasparc < III (64 entry TLB)
    305    mmu_us_3,  // Ultrasparc III (512 entry TLB)
    306    mmu_us_4,  // Ultrasparc IV (several TLBs, 32 and 256MB pages)
    307    mmu_sun4v, // T1, T2
    308};
    309#endif
    310
    311#define TTE_VALID_BIT       (1ULL << 63)
    312#define TTE_NFO_BIT         (1ULL << 60)
    313#define TTE_IE_BIT          (1ULL << 59)
    314#define TTE_USED_BIT        (1ULL << 41)
    315#define TTE_LOCKED_BIT      (1ULL <<  6)
    316#define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
    317#define TTE_PRIV_BIT        (1ULL <<  2)
    318#define TTE_W_OK_BIT        (1ULL <<  1)
    319#define TTE_GLOBAL_BIT      (1ULL <<  0)
    320
    321#define TTE_NFO_BIT_UA2005  (1ULL << 62)
    322#define TTE_USED_BIT_UA2005 (1ULL << 47)
    323#define TTE_LOCKED_BIT_UA2005 (1ULL <<  61)
    324#define TTE_SIDEEFFECT_BIT_UA2005 (1ULL <<  11)
    325#define TTE_PRIV_BIT_UA2005 (1ULL <<  8)
    326#define TTE_W_OK_BIT_UA2005 (1ULL <<  6)
    327
    328#define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
    329#define TTE_IS_NFO(tte)     ((tte) & TTE_NFO_BIT)
    330#define TTE_IS_IE(tte)      ((tte) & TTE_IE_BIT)
    331#define TTE_IS_USED(tte)    ((tte) & TTE_USED_BIT)
    332#define TTE_IS_LOCKED(tte)  ((tte) & TTE_LOCKED_BIT)
    333#define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT)
    334#define TTE_IS_SIDEEFFECT_UA2005(tte) ((tte) & TTE_SIDEEFFECT_BIT_UA2005)
    335#define TTE_IS_PRIV(tte)    ((tte) & TTE_PRIV_BIT)
    336#define TTE_IS_W_OK(tte)    ((tte) & TTE_W_OK_BIT)
    337
    338#define TTE_IS_NFO_UA2005(tte)     ((tte) & TTE_NFO_BIT_UA2005)
    339#define TTE_IS_USED_UA2005(tte)    ((tte) & TTE_USED_BIT_UA2005)
    340#define TTE_IS_LOCKED_UA2005(tte)  ((tte) & TTE_LOCKED_BIT_UA2005)
    341#define TTE_IS_SIDEEFFECT_UA2005(tte) ((tte) & TTE_SIDEEFFECT_BIT_UA2005)
    342#define TTE_IS_PRIV_UA2005(tte)    ((tte) & TTE_PRIV_BIT_UA2005)
    343#define TTE_IS_W_OK_UA2005(tte)    ((tte) & TTE_W_OK_BIT_UA2005)
    344
    345#define TTE_IS_GLOBAL(tte)  ((tte) & TTE_GLOBAL_BIT)
    346
    347#define TTE_SET_USED(tte)   ((tte) |= TTE_USED_BIT)
    348#define TTE_SET_UNUSED(tte) ((tte) &= ~TTE_USED_BIT)
    349
    350#define TTE_PGSIZE(tte)     (((tte) >> 61) & 3ULL)
    351#define TTE_PGSIZE_UA2005(tte)     ((tte) & 7ULL)
    352#define TTE_PA(tte)         ((tte) & 0x1ffffffe000ULL)
    353
    354/* UltraSPARC T1 specific */
    355#define TLB_UST1_IS_REAL_BIT   (1ULL << 9)  /* Real translation entry */
    356#define TLB_UST1_IS_SUN4V_BIT  (1ULL << 10) /* sun4u/sun4v TTE format switch */
    357
    358#define SFSR_NF_BIT         (1ULL << 24)   /* JPS1 NoFault */
    359#define SFSR_TM_BIT         (1ULL << 15)   /* JPS1 TLB Miss */
    360#define SFSR_FT_VA_IMMU_BIT (1ULL << 13)   /* USIIi VA out of range (IMMU) */
    361#define SFSR_FT_VA_DMMU_BIT (1ULL << 12)   /* USIIi VA out of range (DMMU) */
    362#define SFSR_FT_NFO_BIT     (1ULL << 11)   /* NFO page access */
    363#define SFSR_FT_ILL_BIT     (1ULL << 10)   /* illegal LDA/STA ASI */
    364#define SFSR_FT_ATOMIC_BIT  (1ULL <<  9)   /* atomic op on noncacheable area */
    365#define SFSR_FT_NF_E_BIT    (1ULL <<  8)   /* NF access on side effect area */
    366#define SFSR_FT_PRIV_BIT    (1ULL <<  7)   /* privilege violation */
    367#define SFSR_PR_BIT         (1ULL <<  3)   /* privilege mode */
    368#define SFSR_WRITE_BIT      (1ULL <<  2)   /* write access mode */
    369#define SFSR_OW_BIT         (1ULL <<  1)   /* status overwritten */
    370#define SFSR_VALID_BIT      (1ULL <<  0)   /* status valid */
    371
    372#define SFSR_ASI_SHIFT      16             /* 23:16 ASI value */
    373#define SFSR_ASI_MASK       (0xffULL << SFSR_ASI_SHIFT)
    374#define SFSR_CT_PRIMARY     (0ULL <<  4)   /* 5:4 context type */
    375#define SFSR_CT_SECONDARY   (1ULL <<  4)
    376#define SFSR_CT_NUCLEUS     (2ULL <<  4)
    377#define SFSR_CT_NOTRANS     (3ULL <<  4)
    378#define SFSR_CT_MASK        (3ULL <<  4)
    379
    380/* Leon3 cache control */
    381
    382/* Cache control: emulate the behavior of cache control registers but without
    383   any effect on the emulated */
    384
    385#define CACHE_STATE_MASK 0x3
    386#define CACHE_DISABLED   0x0
    387#define CACHE_FROZEN     0x1
    388#define CACHE_ENABLED    0x3
    389
    390/* Cache Control register fields */
    391
    392#define CACHE_CTRL_IF (1 <<  4)  /* Instruction Cache Freeze on Interrupt */
    393#define CACHE_CTRL_DF (1 <<  5)  /* Data Cache Freeze on Interrupt */
    394#define CACHE_CTRL_DP (1 << 14)  /* Data cache flush pending */
    395#define CACHE_CTRL_IP (1 << 15)  /* Instruction cache flush pending */
    396#define CACHE_CTRL_IB (1 << 16)  /* Instruction burst fetch */
    397#define CACHE_CTRL_FI (1 << 21)  /* Flush Instruction cache (Write only) */
    398#define CACHE_CTRL_FD (1 << 22)  /* Flush Data cache (Write only) */
    399#define CACHE_CTRL_DS (1 << 23)  /* Data cache snoop enable */
    400
    401#define CONVERT_BIT(X, SRC, DST) \
    402         (SRC > DST ? (X) / (SRC / DST) & (DST) : ((X) & SRC) * (DST / SRC))
    403
    404typedef struct SparcTLBEntry {
    405    uint64_t tag;
    406    uint64_t tte;
    407} SparcTLBEntry;
    408
    409struct CPUTimer
    410{
    411    const char *name;
    412    uint32_t    frequency;
    413    uint32_t    disabled;
    414    uint64_t    disabled_mask;
    415    uint32_t    npt;
    416    uint64_t    npt_mask;
    417    int64_t     clock_offset;
    418    QEMUTimer  *qtimer;
    419};
    420
    421typedef struct CPUTimer CPUTimer;
    422
    423typedef struct CPUSPARCState CPUSPARCState;
    424#if defined(TARGET_SPARC64)
    425typedef union {
    426   uint64_t mmuregs[16];
    427   struct {
    428    uint64_t tsb_tag_target;
    429    uint64_t mmu_primary_context;
    430    uint64_t mmu_secondary_context;
    431    uint64_t sfsr;
    432    uint64_t sfar;
    433    uint64_t tsb;
    434    uint64_t tag_access;
    435    uint64_t virtual_watchpoint;
    436    uint64_t physical_watchpoint;
    437    uint64_t sun4v_ctx_config[2];
    438    uint64_t sun4v_tsb_pointers[4];
    439   };
    440} SparcV9MMU;
    441#endif
    442struct CPUSPARCState {
    443    target_ulong gregs[8]; /* general registers */
    444    target_ulong *regwptr; /* pointer to current register window */
    445    target_ulong pc;       /* program counter */
    446    target_ulong npc;      /* next program counter */
    447    target_ulong y;        /* multiply/divide register */
    448
    449    /* emulator internal flags handling */
    450    target_ulong cc_src, cc_src2;
    451    target_ulong cc_dst;
    452    uint32_t cc_op;
    453
    454    target_ulong cond; /* conditional branch result (XXX: save it in a
    455                          temporary register when possible) */
    456
    457    uint32_t psr;      /* processor state register */
    458    target_ulong fsr;      /* FPU state register */
    459    CPU_DoubleU fpr[TARGET_DPREGS];  /* floating point registers */
    460    uint32_t cwp;      /* index of current register window (extracted
    461                          from PSR) */
    462#if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
    463    uint32_t wim;      /* window invalid mask */
    464#endif
    465    target_ulong tbr;  /* trap base register */
    466#if !defined(TARGET_SPARC64)
    467    int      psrs;     /* supervisor mode (extracted from PSR) */
    468    int      psrps;    /* previous supervisor mode */
    469    int      psret;    /* enable traps */
    470#endif
    471    uint32_t psrpil;   /* interrupt blocking level */
    472    uint32_t pil_in;   /* incoming interrupt level bitmap */
    473#if !defined(TARGET_SPARC64)
    474    int      psref;    /* enable fpu */
    475#endif
    476    int interrupt_index;
    477    /* NOTE: we allow 8 more registers to handle wrapping */
    478    target_ulong regbase[MAX_NWINDOWS * 16 + 8];
    479
    480    /* Fields up to this point are cleared by a CPU reset */
    481    struct {} end_reset_fields;
    482
    483    /* Fields from here on are preserved across CPU reset. */
    484    target_ulong version;
    485    uint32_t nwindows;
    486
    487    /* MMU regs */
    488#if defined(TARGET_SPARC64)
    489    uint64_t lsu;
    490#define DMMU_E 0x8
    491#define IMMU_E 0x4
    492    SparcV9MMU immu;
    493    SparcV9MMU dmmu;
    494    SparcTLBEntry itlb[64];
    495    SparcTLBEntry dtlb[64];
    496    uint32_t mmu_version;
    497#else
    498    uint32_t mmuregs[32];
    499    uint64_t mxccdata[4];
    500    uint64_t mxccregs[8];
    501    uint32_t mmubpctrv, mmubpctrc, mmubpctrs;
    502    uint64_t mmubpaction;
    503    uint64_t mmubpregs[4];
    504    uint64_t prom_addr;
    505#endif
    506    /* temporary float registers */
    507    float128 qt0, qt1;
    508    float_status fp_status;
    509#if defined(TARGET_SPARC64)
    510#define MAXTL_MAX 8
    511#define MAXTL_MASK (MAXTL_MAX - 1)
    512    trap_state ts[MAXTL_MAX];
    513    uint32_t xcc;               /* Extended integer condition codes */
    514    uint32_t asi;
    515    uint32_t pstate;
    516    uint32_t tl;
    517    uint32_t maxtl;
    518    uint32_t cansave, canrestore, otherwin, wstate, cleanwin;
    519    uint64_t agregs[8]; /* alternate general registers */
    520    uint64_t bgregs[8]; /* backup for normal global registers */
    521    uint64_t igregs[8]; /* interrupt general registers */
    522    uint64_t mgregs[8]; /* mmu general registers */
    523    uint64_t glregs[8 * MAXTL_MAX];
    524    uint64_t fprs;
    525    uint64_t tick_cmpr, stick_cmpr;
    526    CPUTimer *tick, *stick;
    527#define TICK_NPT_MASK        0x8000000000000000ULL
    528#define TICK_INT_DIS         0x8000000000000000ULL
    529    uint64_t gsr;
    530    uint32_t gl; // UA2005
    531    /* UA 2005 hyperprivileged registers */
    532    uint64_t hpstate, htstate[MAXTL_MAX], hintp, htba, hver, hstick_cmpr, ssr;
    533    uint64_t scratch[8];
    534    CPUTimer *hstick; // UA 2005
    535    /* Interrupt vector registers */
    536    uint64_t ivec_status;
    537    uint64_t ivec_data[3];
    538    uint32_t softint;
    539#define SOFTINT_TIMER   1
    540#define SOFTINT_STIMER  (1 << 16)
    541#define SOFTINT_INTRMASK (0xFFFE)
    542#define SOFTINT_REG_MASK (SOFTINT_STIMER|SOFTINT_INTRMASK|SOFTINT_TIMER)
    543#endif
    544    sparc_def_t def;
    545
    546    void *irq_manager;
    547    void (*qemu_irq_ack)(CPUSPARCState *env, void *irq_manager, int intno);
    548
    549    /* Leon3 cache control */
    550    uint32_t cache_control;
    551};
    552
    553/**
    554 * SPARCCPU:
    555 * @env: #CPUSPARCState
    556 *
    557 * A SPARC CPU.
    558 */
    559struct SPARCCPU {
    560    /*< private >*/
    561    CPUState parent_obj;
    562    /*< public >*/
    563
    564    CPUNegativeOffsetState neg;
    565    CPUSPARCState env;
    566};
    567
    568
    569#ifndef CONFIG_USER_ONLY
    570extern const VMStateDescription vmstate_sparc_cpu;
    571#endif
    572
    573void sparc_cpu_do_interrupt(CPUState *cpu);
    574hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
    575int sparc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
    576int sparc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
    577void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
    578                                                 MMUAccessType access_type,
    579                                                 int mmu_idx,
    580                                                 uintptr_t retaddr);
    581void cpu_raise_exception_ra(CPUSPARCState *, int, uintptr_t) QEMU_NORETURN;
    582
    583#ifndef NO_CPU_IO_DEFS
    584/* cpu_init.c */
    585void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
    586void sparc_cpu_list(void);
    587/* mmu_helper.c */
    588bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
    589                        MMUAccessType access_type, int mmu_idx,
    590                        bool probe, uintptr_t retaddr);
    591target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
    592void dump_mmu(CPUSPARCState *env);
    593
    594#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
    595int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
    596                              uint8_t *buf, int len, bool is_write);
    597#endif
    598
    599
    600/* translate.c */
    601void sparc_tcg_init(void);
    602
    603/* cpu-exec.c */
    604
    605/* win_helper.c */
    606target_ulong cpu_get_psr(CPUSPARCState *env1);
    607void cpu_put_psr(CPUSPARCState *env1, target_ulong val);
    608void cpu_put_psr_raw(CPUSPARCState *env1, target_ulong val);
    609#ifdef TARGET_SPARC64
    610void cpu_change_pstate(CPUSPARCState *env1, uint32_t new_pstate);
    611void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl);
    612#endif
    613int cpu_cwp_inc(CPUSPARCState *env1, int cwp);
    614int cpu_cwp_dec(CPUSPARCState *env1, int cwp);
    615void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
    616
    617/* sun4m.c, sun4u.c */
    618void cpu_check_irqs(CPUSPARCState *env);
    619
    620#if defined (TARGET_SPARC64)
    621
    622static inline int compare_masked(uint64_t x, uint64_t y, uint64_t mask)
    623{
    624    return (x & mask) == (y & mask);
    625}
    626
    627#define MMU_CONTEXT_BITS 13
    628#define MMU_CONTEXT_MASK ((1 << MMU_CONTEXT_BITS) - 1)
    629
    630static inline int tlb_compare_context(const SparcTLBEntry *tlb,
    631                                      uint64_t context)
    632{
    633    return compare_masked(context, tlb->tag, MMU_CONTEXT_MASK);
    634}
    635
    636#endif
    637#endif
    638
    639/* cpu-exec.c */
    640#if !defined(CONFIG_USER_ONLY)
    641void sparc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
    642                                     vaddr addr, unsigned size,
    643                                     MMUAccessType access_type,
    644                                     int mmu_idx, MemTxAttrs attrs,
    645                                     MemTxResult response, uintptr_t retaddr);
    646#if defined(TARGET_SPARC64)
    647hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
    648                                           int mmu_idx);
    649#endif
    650#endif
    651
    652#define SPARC_CPU_TYPE_SUFFIX "-" TYPE_SPARC_CPU
    653#define SPARC_CPU_TYPE_NAME(model) model SPARC_CPU_TYPE_SUFFIX
    654#define CPU_RESOLVING_TYPE TYPE_SPARC_CPU
    655
    656#define cpu_list sparc_cpu_list
    657
    658/* MMU modes definitions */
    659#if defined (TARGET_SPARC64)
    660#define MMU_USER_IDX   0
    661#define MMU_USER_SECONDARY_IDX   1
    662#define MMU_KERNEL_IDX 2
    663#define MMU_KERNEL_SECONDARY_IDX 3
    664#define MMU_NUCLEUS_IDX 4
    665#define MMU_PHYS_IDX   5
    666#else
    667#define MMU_USER_IDX   0
    668#define MMU_KERNEL_IDX 1
    669#define MMU_PHYS_IDX   2
    670#endif
    671
    672#if defined (TARGET_SPARC64)
    673static inline int cpu_has_hypervisor(CPUSPARCState *env1)
    674{
    675    return env1->def.features & CPU_FEATURE_HYPV;
    676}
    677
    678static inline int cpu_hypervisor_mode(CPUSPARCState *env1)
    679{
    680    return cpu_has_hypervisor(env1) && (env1->hpstate & HS_PRIV);
    681}
    682
    683static inline int cpu_supervisor_mode(CPUSPARCState *env1)
    684{
    685    return env1->pstate & PS_PRIV;
    686}
    687#else
    688static inline int cpu_supervisor_mode(CPUSPARCState *env1)
    689{
    690    return env1->psrs;
    691}
    692#endif
    693
    694static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
    695{
    696#if defined(CONFIG_USER_ONLY)
    697    return MMU_USER_IDX;
    698#elif !defined(TARGET_SPARC64)
    699    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
    700        return MMU_PHYS_IDX;
    701    } else {
    702        return env->psrs;
    703    }
    704#else
    705    /* IMMU or DMMU disabled.  */
    706    if (ifetch
    707        ? (env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0
    708        : (env->lsu & DMMU_E) == 0) {
    709        return MMU_PHYS_IDX;
    710    } else if (cpu_hypervisor_mode(env)) {
    711        return MMU_PHYS_IDX;
    712    } else if (env->tl > 0) {
    713        return MMU_NUCLEUS_IDX;
    714    } else if (cpu_supervisor_mode(env)) {
    715        return MMU_KERNEL_IDX;
    716    } else {
    717        return MMU_USER_IDX;
    718    }
    719#endif
    720}
    721
    722static inline int cpu_interrupts_enabled(CPUSPARCState *env1)
    723{
    724#if !defined (TARGET_SPARC64)
    725    if (env1->psret != 0)
    726        return 1;
    727#else
    728    if ((env1->pstate & PS_IE) && !cpu_hypervisor_mode(env1)) {
    729        return 1;
    730    }
    731#endif
    732
    733    return 0;
    734}
    735
    736static inline int cpu_pil_allowed(CPUSPARCState *env1, int pil)
    737{
    738#if !defined(TARGET_SPARC64)
    739    /* level 15 is non-maskable on sparc v8 */
    740    return pil == 15 || pil > env1->psrpil;
    741#else
    742    return pil > env1->psrpil;
    743#endif
    744}
    745
    746typedef CPUSPARCState CPUArchState;
    747typedef SPARCCPU ArchCPU;
    748
    749#include "exec/cpu-all.h"
    750
    751#ifdef TARGET_SPARC64
    752/* sun4u.c */
    753void cpu_tick_set_count(CPUTimer *timer, uint64_t count);
    754uint64_t cpu_tick_get_count(CPUTimer *timer);
    755void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit);
    756trap_state* cpu_tsptr(CPUSPARCState* env);
    757#endif
    758
    759#define TB_FLAG_MMU_MASK     7
    760#define TB_FLAG_FPU_ENABLED  (1 << 4)
    761#define TB_FLAG_AM_ENABLED   (1 << 5)
    762#define TB_FLAG_SUPER        (1 << 6)
    763#define TB_FLAG_HYPER        (1 << 7)
    764#define TB_FLAG_ASI_SHIFT    24
    765
    766static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
    767                                        target_ulong *cs_base, uint32_t *pflags)
    768{
    769    uint32_t flags;
    770    *pc = env->pc;
    771    *cs_base = env->npc;
    772    flags = cpu_mmu_index(env, false);
    773#ifndef CONFIG_USER_ONLY
    774    if (cpu_supervisor_mode(env)) {
    775        flags |= TB_FLAG_SUPER;
    776    }
    777#endif
    778#ifdef TARGET_SPARC64
    779#ifndef CONFIG_USER_ONLY
    780    if (cpu_hypervisor_mode(env)) {
    781        flags |= TB_FLAG_HYPER;
    782    }
    783#endif
    784    if (env->pstate & PS_AM) {
    785        flags |= TB_FLAG_AM_ENABLED;
    786    }
    787    if ((env->def.features & CPU_FEATURE_FLOAT)
    788        && (env->pstate & PS_PEF)
    789        && (env->fprs & FPRS_FEF)) {
    790        flags |= TB_FLAG_FPU_ENABLED;
    791    }
    792    flags |= env->asi << TB_FLAG_ASI_SHIFT;
    793#else
    794    if ((env->def.features & CPU_FEATURE_FLOAT) && env->psref) {
    795        flags |= TB_FLAG_FPU_ENABLED;
    796    }
    797#endif
    798    *pflags = flags;
    799}
    800
    801static inline bool tb_fpu_enabled(int tb_flags)
    802{
    803#if defined(CONFIG_USER_ONLY)
    804    return true;
    805#else
    806    return tb_flags & TB_FLAG_FPU_ENABLED;
    807#endif
    808}
    809
    810static inline bool tb_am_enabled(int tb_flags)
    811{
    812#ifndef TARGET_SPARC64
    813    return false;
    814#else
    815    return tb_flags & TB_FLAG_AM_ENABLED;
    816#endif
    817}
    818
    819#ifdef TARGET_SPARC64
    820/* win_helper.c */
    821target_ulong cpu_get_ccr(CPUSPARCState *env1);
    822void cpu_put_ccr(CPUSPARCState *env1, target_ulong val);
    823target_ulong cpu_get_cwp64(CPUSPARCState *env1);
    824void cpu_put_cwp64(CPUSPARCState *env1, int cwp);
    825
    826static inline uint64_t sparc64_tstate(CPUSPARCState *env)
    827{
    828    uint64_t tstate = (cpu_get_ccr(env) << 32) |
    829        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
    830        cpu_get_cwp64(env);
    831
    832    if (env->def.features & CPU_FEATURE_GL) {
    833        tstate |= (env->gl & 7ULL) << 40;
    834    }
    835    return tstate;
    836}
    837#endif
    838
    839#endif