cpu.h 24.4 KB
Newer Older
1 2
#ifndef SPARC_CPU_H
#define SPARC_CPU_H
3

4
#include "qemu-common.h"
5
#include "qemu/bswap.h"
6
#include "cpu-qom.h"
7
#include "exec/cpu-defs.h"
8

9 10
#define ALIGNED_ONLY

11
#if !defined(TARGET_SPARC64)
12
#define TARGET_DPREGS 16
13
#else
14
#define TARGET_DPREGS 32
15
#endif
B
bellard 已提交
16

17 18
/*#define EXCP_INTERRUPT 0x100*/

19
/* trap definitions */
B
bellard 已提交
20
#ifndef TARGET_SPARC64
B
bellard 已提交
21
#define TT_TFAULT   0x01
22
#define TT_ILL_INSN 0x02
23
#define TT_PRIV_INSN 0x03
B
bellard 已提交
24
#define TT_NFPU_INSN 0x04
25
#define TT_WIN_OVF  0x05
26
#define TT_WIN_UNF  0x06
27
#define TT_UNALIGNED 0x07
28
#define TT_FP_EXCP  0x08
B
bellard 已提交
29
#define TT_DFAULT   0x09
30
#define TT_TOVF     0x0a
B
bellard 已提交
31
#define TT_EXTINT   0x10
32
#define TT_CODE_ACCESS 0x21
B
blueswir1 已提交
33
#define TT_UNIMP_FLUSH 0x25
34
#define TT_DATA_ACCESS 0x29
35
#define TT_DIV_ZERO 0x2a
36
#define TT_NCP_INSN 0x24
37
#define TT_TRAP     0x80
B
bellard 已提交
38
#else
39
#define TT_POWER_ON_RESET 0x01
B
bellard 已提交
40
#define TT_TFAULT   0x08
41
#define TT_CODE_ACCESS 0x0a
B
bellard 已提交
42
#define TT_ILL_INSN 0x10
B
blueswir1 已提交
43
#define TT_UNIMP_FLUSH TT_ILL_INSN
B
bellard 已提交
44 45 46
#define TT_PRIV_INSN 0x11
#define TT_NFPU_INSN 0x20
#define TT_FP_EXCP  0x21
47
#define TT_TOVF     0x23
B
bellard 已提交
48 49 50
#define TT_CLRWIN   0x24
#define TT_DIV_ZERO 0x28
#define TT_DFAULT   0x30
51
#define TT_DATA_ACCESS 0x32
52
#define TT_UNALIGNED 0x34
B
bellard 已提交
53
#define TT_PRIV_ACT 0x37
54 55
#define TT_INSN_REAL_TRANSLATION_MISS 0x3e
#define TT_DATA_REAL_TRANSLATION_MISS 0x3f
B
bellard 已提交
56
#define TT_EXTINT   0x40
B
blueswir1 已提交
57
#define TT_IVEC     0x60
B
blueswir1 已提交
58 59
#define TT_TMISS    0x64
#define TT_DMISS    0x68
B
blueswir1 已提交
60
#define TT_DPROT    0x6c
B
bellard 已提交
61 62
#define TT_SPILL    0x80
#define TT_FILL     0xc0
I
Igor V. Kovalenko 已提交
63
#define TT_WOTHER   (1 << 5)
B
bellard 已提交
64
#define TT_TRAP     0x100
65
#define TT_HTRAP    0x180
B
bellard 已提交
66
#endif
67

B
blueswir1 已提交
68 69 70 71 72 73 74 75
#define PSR_NEG_SHIFT 23
#define PSR_NEG   (1 << PSR_NEG_SHIFT)
#define PSR_ZERO_SHIFT 22
#define PSR_ZERO  (1 << PSR_ZERO_SHIFT)
#define PSR_OVF_SHIFT 21
#define PSR_OVF   (1 << PSR_OVF_SHIFT)
#define PSR_CARRY_SHIFT 20
#define PSR_CARRY (1 << PSR_CARRY_SHIFT)
76
#define PSR_ICC   (PSR_NEG|PSR_ZERO|PSR_OVF|PSR_CARRY)
77
#if !defined(TARGET_SPARC64)
B
bellard 已提交
78 79
#define PSR_EF    (1<<12)
#define PSR_PIL   0xf00
80 81 82 83
#define PSR_S     (1<<7)
#define PSR_PS    (1<<6)
#define PSR_ET    (1<<5)
#define PSR_CWP   0x1f
84
#endif
85

86 87 88 89 90
#define CC_SRC (env->cc_src)
#define CC_SRC2 (env->cc_src2)
#define CC_DST (env->cc_dst)
#define CC_OP  (env->cc_op)

91 92 93 94 95
/* Even though lazy evaluation of CPU condition codes tends to be less
 * important on RISC systems where condition codes are only updated
 * when explicitly requested, SPARC uses it to update 32-bit and 64-bit
 * condition codes.
 */
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
enum {
    CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
    CC_OP_FLAGS,   /* all cc are back in status register */
    CC_OP_DIV,     /* modify N, Z and V, C = 0*/
    CC_OP_ADD,     /* modify all flags, CC_DST = res, CC_SRC = src1 */
    CC_OP_ADDX,    /* modify all flags, CC_DST = res, CC_SRC = src1 */
    CC_OP_TADD,    /* modify all flags, CC_DST = res, CC_SRC = src1 */
    CC_OP_TADDTV,  /* modify all flags except V, CC_DST = res, CC_SRC = src1 */
    CC_OP_SUB,     /* modify all flags, CC_DST = res, CC_SRC = src1 */
    CC_OP_SUBX,    /* modify all flags, CC_DST = res, CC_SRC = src1 */
    CC_OP_TSUB,    /* modify all flags, CC_DST = res, CC_SRC = src1 */
    CC_OP_TSUBTV,  /* modify all flags except V, CC_DST = res, CC_SRC = src1 */
    CC_OP_LOGIC,   /* modify N and Z, C = V = 0, CC_DST = res */
    CC_OP_NB,
};

112 113 114
/* Trap base register */
#define TBR_BASE_MASK 0xfffff000

B
bellard 已提交
115
#if defined(TARGET_SPARC64)
116 117 118 119 120
#define PS_TCT   (1<<12) /* UA2007, impl.dep. trap on control transfer */
#define PS_IG    (1<<11) /* v9, zero on UA2007 */
#define PS_MG    (1<<10) /* v9, zero on UA2007 */
#define PS_CLE   (1<<9) /* UA2007 */
#define PS_TLE   (1<<8) /* UA2007 */
121
#define PS_RMO   (1<<7)
122 123 124
#define PS_RED   (1<<5) /* v9, zero on UA2007 */
#define PS_PEF   (1<<4) /* enable fpu */
#define PS_AM    (1<<3) /* address mask */
B
bellard 已提交
125 126
#define PS_PRIV  (1<<2)
#define PS_IE    (1<<1)
127
#define PS_AG    (1<<0) /* v9, zero on UA2007 */
B
bellard 已提交
128 129

#define FPRS_FEF (1<<2)
B
blueswir1 已提交
130 131

#define HS_PRIV  (1<<2)
B
bellard 已提交
132 133
#endif

134
/* Fcc */
135 136
#define FSR_RD1        (1ULL << 31)
#define FSR_RD0        (1ULL << 30)
137 138 139 140 141 142
#define FSR_RD_MASK    (FSR_RD1 | FSR_RD0)
#define FSR_RD_NEAREST 0
#define FSR_RD_ZERO    FSR_RD0
#define FSR_RD_POS     FSR_RD1
#define FSR_RD_NEG     (FSR_RD1 | FSR_RD0)

143 144 145 146 147
#define FSR_NVM   (1ULL << 27)
#define FSR_OFM   (1ULL << 26)
#define FSR_UFM   (1ULL << 25)
#define FSR_DZM   (1ULL << 24)
#define FSR_NXM   (1ULL << 23)
148 149
#define FSR_TEM_MASK (FSR_NVM | FSR_OFM | FSR_UFM | FSR_DZM | FSR_NXM)

150 151 152 153 154
#define FSR_NVA   (1ULL << 9)
#define FSR_OFA   (1ULL << 8)
#define FSR_UFA   (1ULL << 7)
#define FSR_DZA   (1ULL << 6)
#define FSR_NXA   (1ULL << 5)
155 156
#define FSR_AEXC_MASK (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)

157 158 159 160 161
#define FSR_NVC   (1ULL << 4)
#define FSR_OFC   (1ULL << 3)
#define FSR_UFC   (1ULL << 2)
#define FSR_DZC   (1ULL << 1)
#define FSR_NXC   (1ULL << 0)
162 163
#define FSR_CEXC_MASK (FSR_NVC | FSR_OFC | FSR_UFC | FSR_DZC | FSR_NXC)

164 165 166
#define FSR_FTT2   (1ULL << 16)
#define FSR_FTT1   (1ULL << 15)
#define FSR_FTT0   (1ULL << 14)
167 168 169 170 171
//gcc warns about constant overflow for ~FSR_FTT_MASK
//#define FSR_FTT_MASK (FSR_FTT2 | FSR_FTT1 | FSR_FTT0)
#ifdef TARGET_SPARC64
#define FSR_FTT_NMASK      0xfffffffffffe3fffULL
#define FSR_FTT_CEXC_NMASK 0xfffffffffffe3fe0ULL
172 173 174
#define FSR_LDFSR_OLDMASK  0x0000003f000fc000ULL
#define FSR_LDXFSR_MASK    0x0000003fcfc00fffULL
#define FSR_LDXFSR_OLDMASK 0x00000000000fc000ULL
175 176 177
#else
#define FSR_FTT_NMASK      0xfffe3fffULL
#define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL
178
#define FSR_LDFSR_OLDMASK  0x000fc000ULL
179
#endif
180
#define FSR_LDFSR_MASK     0xcfc00fffULL
181 182 183 184
#define FSR_FTT_IEEE_EXCP (1ULL << 14)
#define FSR_FTT_UNIMPFPOP (3ULL << 14)
#define FSR_FTT_SEQ_ERROR (4ULL << 14)
#define FSR_FTT_INVAL_FPR (6ULL << 14)
185

B
blueswir1 已提交
186
#define FSR_FCC1_SHIFT 11
187
#define FSR_FCC1  (1ULL << FSR_FCC1_SHIFT)
B
blueswir1 已提交
188
#define FSR_FCC0_SHIFT 10
189
#define FSR_FCC0  (1ULL << FSR_FCC0_SHIFT)
190 191

/* MMU */
B
blueswir1 已提交
192 193
#define MMU_E     (1<<0)
#define MMU_NF    (1<<1)
194 195 196 197

#define PTE_ENTRYTYPE_MASK 3
#define PTE_ACCESS_MASK    0x1c
#define PTE_ACCESS_SHIFT   2
B
bellard 已提交
198
#define PTE_PPN_SHIFT      7
199 200
#define PTE_ADDR_MASK      0xffffff00

B
blueswir1 已提交
201 202
#define PG_ACCESSED_BIT 5
#define PG_MODIFIED_BIT 6
203 204 205 206 207 208
#define PG_CACHE_BIT    7

#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
#define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT)
#define PG_CACHE_MASK    (1 << PG_CACHE_BIT)

209 210 211
/* 3 <= NWINDOWS <= 32. */
#define MIN_NWINDOWS 3
#define MAX_NWINDOWS 32
212

213
#ifdef TARGET_SPARC64
214 215 216 217 218 219
typedef struct trap_state {
    uint64_t tpc;
    uint64_t tnpc;
    uint64_t tstate;
    uint32_t tt;
} trap_state;
B
blueswir1 已提交
220
#endif
221
#define TARGET_INSN_START_EXTRA_WORDS 1
222

223
struct sparc_def_t {
224 225 226 227 228 229 230 231 232
    const char *name;
    target_ulong iu_version;
    uint32_t fpu_version;
    uint32_t mmu_version;
    uint32_t mmu_bm;
    uint32_t mmu_ctpr_mask;
    uint32_t mmu_cxr_mask;
    uint32_t mmu_sfsr_mask;
    uint32_t mmu_trcr_mask;
233
    uint32_t mxcc_version;
234 235 236
    uint32_t features;
    uint32_t nwindows;
    uint32_t maxtl;
237
};
238

F
Fabien Chouteau 已提交
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
#define CPU_FEATURE_FLOAT        (1 << 0)
#define CPU_FEATURE_FLOAT128     (1 << 1)
#define CPU_FEATURE_SWAP         (1 << 2)
#define CPU_FEATURE_MUL          (1 << 3)
#define CPU_FEATURE_DIV          (1 << 4)
#define CPU_FEATURE_FLUSH        (1 << 5)
#define CPU_FEATURE_FSQRT        (1 << 6)
#define CPU_FEATURE_FMUL         (1 << 7)
#define CPU_FEATURE_VIS1         (1 << 8)
#define CPU_FEATURE_VIS2         (1 << 9)
#define CPU_FEATURE_FSMULD       (1 << 10)
#define CPU_FEATURE_HYPV         (1 << 11)
#define CPU_FEATURE_CMT          (1 << 12)
#define CPU_FEATURE_GL           (1 << 13)
#define CPU_FEATURE_TA0_SHUTDOWN (1 << 14) /* Shutdown on "ta 0x0" */
254
#define CPU_FEATURE_ASR17        (1 << 15)
F
Fabien Chouteau 已提交
255
#define CPU_FEATURE_CACHE_CTRL   (1 << 16)
256
#define CPU_FEATURE_POWERDOWN    (1 << 17)
257
#define CPU_FEATURE_CASA         (1 << 18)
F
Fabien Chouteau 已提交
258

259 260 261 262 263 264 265 266 267 268
#ifndef TARGET_SPARC64
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP |  \
                              CPU_FEATURE_MUL | CPU_FEATURE_DIV |     \
                              CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
                              CPU_FEATURE_FMUL | CPU_FEATURE_FSMULD)
#else
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP |  \
                              CPU_FEATURE_MUL | CPU_FEATURE_DIV |     \
                              CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
                              CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 |   \
269 270
                              CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD | \
                              CPU_FEATURE_CASA)
271 272 273 274 275 276 277 278
enum {
    mmu_us_12, // Ultrasparc < III (64 entry TLB)
    mmu_us_3,  // Ultrasparc III (512 entry TLB)
    mmu_us_4,  // Ultrasparc IV (several TLBs, 32 and 256MB pages)
    mmu_sun4v, // T1, T2
};
#endif

279
#define TTE_VALID_BIT       (1ULL << 63)
280
#define TTE_NFO_BIT         (1ULL << 60)
281 282
#define TTE_USED_BIT        (1ULL << 41)
#define TTE_LOCKED_BIT      (1ULL <<  6)
283
#define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
T
Tsuneo Saito 已提交
284 285
#define TTE_PRIV_BIT        (1ULL <<  2)
#define TTE_W_OK_BIT        (1ULL <<  1)
286
#define TTE_GLOBAL_BIT      (1ULL <<  0)
287

288 289 290 291 292 293 294
#define TTE_NFO_BIT_UA2005  (1ULL << 62)
#define TTE_USED_BIT_UA2005 (1ULL << 47)
#define TTE_LOCKED_BIT_UA2005 (1ULL <<  61)
#define TTE_SIDEEFFECT_BIT_UA2005 (1ULL <<  11)
#define TTE_PRIV_BIT_UA2005 (1ULL <<  8)
#define TTE_W_OK_BIT_UA2005 (1ULL <<  6)

295
#define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
296
#define TTE_IS_NFO(tte)     ((tte) & TTE_NFO_BIT)
297 298
#define TTE_IS_USED(tte)    ((tte) & TTE_USED_BIT)
#define TTE_IS_LOCKED(tte)  ((tte) & TTE_LOCKED_BIT)
299
#define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT)
300
#define TTE_IS_SIDEEFFECT_UA2005(tte) ((tte) & TTE_SIDEEFFECT_BIT_UA2005)
T
Tsuneo Saito 已提交
301 302
#define TTE_IS_PRIV(tte)    ((tte) & TTE_PRIV_BIT)
#define TTE_IS_W_OK(tte)    ((tte) & TTE_W_OK_BIT)
303 304 305 306 307 308 309 310

#define TTE_IS_NFO_UA2005(tte)     ((tte) & TTE_NFO_BIT_UA2005)
#define TTE_IS_USED_UA2005(tte)    ((tte) & TTE_USED_BIT_UA2005)
#define TTE_IS_LOCKED_UA2005(tte)  ((tte) & TTE_LOCKED_BIT_UA2005)
#define TTE_IS_SIDEEFFECT_UA2005(tte) ((tte) & TTE_SIDEEFFECT_BIT_UA2005)
#define TTE_IS_PRIV_UA2005(tte)    ((tte) & TTE_PRIV_BIT_UA2005)
#define TTE_IS_W_OK_UA2005(tte)    ((tte) & TTE_W_OK_BIT_UA2005)

311
#define TTE_IS_GLOBAL(tte)  ((tte) & TTE_GLOBAL_BIT)
312 313 314 315

#define TTE_SET_USED(tte)   ((tte) |= TTE_USED_BIT)
#define TTE_SET_UNUSED(tte) ((tte) &= ~TTE_USED_BIT)

T
Tsuneo Saito 已提交
316
#define TTE_PGSIZE(tte)     (((tte) >> 61) & 3ULL)
317
#define TTE_PGSIZE_UA2005(tte)     ((tte) & 7ULL)
T
Tsuneo Saito 已提交
318 319
#define TTE_PA(tte)         ((tte) & 0x1ffffffe000ULL)

320 321 322 323
/* UltraSPARC T1 specific */
#define TLB_UST1_IS_REAL_BIT   (1ULL << 9)  /* Real translation entry */
#define TLB_UST1_IS_SUN4V_BIT  (1ULL << 10) /* sun4u/sun4v TTE format switch */

T
Tsuneo Saito 已提交
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
#define SFSR_NF_BIT         (1ULL << 24)   /* JPS1 NoFault */
#define SFSR_TM_BIT         (1ULL << 15)   /* JPS1 TLB Miss */
#define SFSR_FT_VA_IMMU_BIT (1ULL << 13)   /* USIIi VA out of range (IMMU) */
#define SFSR_FT_VA_DMMU_BIT (1ULL << 12)   /* USIIi VA out of range (DMMU) */
#define SFSR_FT_NFO_BIT     (1ULL << 11)   /* NFO page access */
#define SFSR_FT_ILL_BIT     (1ULL << 10)   /* illegal LDA/STA ASI */
#define SFSR_FT_ATOMIC_BIT  (1ULL <<  9)   /* atomic op on noncacheable area */
#define SFSR_FT_NF_E_BIT    (1ULL <<  8)   /* NF access on side effect area */
#define SFSR_FT_PRIV_BIT    (1ULL <<  7)   /* privilege violation */
#define SFSR_PR_BIT         (1ULL <<  3)   /* privilege mode */
#define SFSR_WRITE_BIT      (1ULL <<  2)   /* write access mode */
#define SFSR_OW_BIT         (1ULL <<  1)   /* status overwritten */
#define SFSR_VALID_BIT      (1ULL <<  0)   /* status valid */

#define SFSR_ASI_SHIFT      16             /* 23:16 ASI value */
#define SFSR_ASI_MASK       (0xffULL << SFSR_ASI_SHIFT)
#define SFSR_CT_PRIMARY     (0ULL <<  4)   /* 5:4 context type */
#define SFSR_CT_SECONDARY   (1ULL <<  4)
#define SFSR_CT_NUCLEUS     (2ULL <<  4)
#define SFSR_CT_NOTRANS     (3ULL <<  4)
#define SFSR_CT_MASK        (3ULL <<  4)

346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
/* Leon3 cache control */

/* Cache control: emulate the behavior of cache control registers but without
   any effect on the emulated */

#define CACHE_STATE_MASK 0x3
#define CACHE_DISABLED   0x0
#define CACHE_FROZEN     0x1
#define CACHE_ENABLED    0x3

/* Cache Control register fields */

#define CACHE_CTRL_IF (1 <<  4)  /* Instruction Cache Freeze on Interrupt */
#define CACHE_CTRL_DF (1 <<  5)  /* Data Cache Freeze on Interrupt */
#define CACHE_CTRL_DP (1 << 14)  /* Data cache flush pending */
#define CACHE_CTRL_IP (1 << 15)  /* Instruction cache flush pending */
#define CACHE_CTRL_IB (1 << 16)  /* Instruction burst fetch */
#define CACHE_CTRL_FI (1 << 21)  /* Flush Instruction cache (Write only) */
#define CACHE_CTRL_FD (1 << 22)  /* Flush Data cache (Write only) */
#define CACHE_CTRL_DS (1 << 23)  /* Data cache snoop enable */

367 368 369
#define CONVERT_BIT(X, SRC, DST) \
         (SRC > DST ? (X) / (SRC / DST) & (DST) : ((X) & SRC) * (DST / SRC))

370 371 372 373 374
typedef struct SparcTLBEntry {
    uint64_t tag;
    uint64_t tte;
} SparcTLBEntry;

375 376 377 378 379 380
struct CPUTimer
{
    const char *name;
    uint32_t    frequency;
    uint32_t    disabled;
    uint64_t    disabled_mask;
381 382
    uint32_t    npt;
    uint64_t    npt_mask;
383
    int64_t     clock_offset;
384
    QEMUTimer  *qtimer;
385 386 387 388
};

typedef struct CPUTimer CPUTimer;

389
typedef struct CPUSPARCState CPUSPARCState;
390 391 392 393 394 395 396 397 398 399 400 401 402
#if defined(TARGET_SPARC64)
typedef union {
   uint64_t mmuregs[16];
   struct {
    uint64_t tsb_tag_target;
    uint64_t mmu_primary_context;
    uint64_t mmu_secondary_context;
    uint64_t sfsr;
    uint64_t sfar;
    uint64_t tsb;
    uint64_t tag_access;
    uint64_t virtual_watchpoint;
    uint64_t physical_watchpoint;
403 404
    uint64_t sun4v_ctx_config[2];
    uint64_t sun4v_tsb_pointers[4];
405 406 407
   };
} SparcV9MMU;
#endif
408
struct CPUSPARCState {
409 410 411 412 413
    target_ulong gregs[8]; /* general registers */
    target_ulong *regwptr; /* pointer to current register window */
    target_ulong pc;       /* program counter */
    target_ulong npc;      /* next program counter */
    target_ulong y;        /* multiply/divide register */
414 415

    /* emulator internal flags handling */
B
blueswir1 已提交
416
    target_ulong cc_src, cc_src2;
417
    target_ulong cc_dst;
418
    uint32_t cc_op;
419

B
bellard 已提交
420 421 422
    target_ulong cond; /* conditional branch result (XXX: save it in a
                          temporary register when possible) */

423
    uint32_t psr;      /* processor state register */
B
bellard 已提交
424
    target_ulong fsr;      /* FPU state register */
425
    CPU_DoubleU fpr[TARGET_DPREGS];  /* floating point registers */
426 427
    uint32_t cwp;      /* index of current register window (extracted
                          from PSR) */
428
#if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
429
    uint32_t wim;      /* window invalid mask */
430
#endif
B
bellard 已提交
431
    target_ulong tbr;  /* trap base register */
432
#if !defined(TARGET_SPARC64)
433 434 435
    int      psrs;     /* supervisor mode (extracted from PSR) */
    int      psrps;    /* previous supervisor mode */
    int      psret;    /* enable traps */
436
#endif
B
blueswir1 已提交
437 438
    uint32_t psrpil;   /* interrupt blocking level */
    uint32_t pil_in;   /* incoming interrupt level bitmap */
439
#if !defined(TARGET_SPARC64)
B
bellard 已提交
440
    int      psref;    /* enable fpu */
441
#endif
442 443
    int interrupt_index;
    /* NOTE: we allow 8 more registers to handle wrapping */
444
    target_ulong regbase[MAX_NWINDOWS * 16 + 8];
B
bellard 已提交
445

446 447 448
    /* Fields up to this point are cleared by a CPU reset */
    struct {} end_reset_fields;

449 450
    CPU_COMMON

451
    /* Fields from here on are preserved across CPU reset. */
B
Blue Swirl 已提交
452 453 454
    target_ulong version;
    uint32_t nwindows;

455
    /* MMU regs */
B
bellard 已提交
456 457 458 459
#if defined(TARGET_SPARC64)
    uint64_t lsu;
#define DMMU_E 0x8
#define IMMU_E 0x4
460 461
    SparcV9MMU immu;
    SparcV9MMU dmmu;
462 463
    SparcTLBEntry itlb[64];
    SparcTLBEntry dtlb[64];
464
    uint32_t mmu_version;
B
bellard 已提交
465
#else
B
blueswir1 已提交
466
    uint32_t mmuregs[32];
467 468
    uint64_t mxccdata[4];
    uint64_t mxccregs[8];
469 470
    uint32_t mmubpctrv, mmubpctrc, mmubpctrs;
    uint64_t mmubpaction;
471
    uint64_t mmubpregs[4];
472
    uint64_t prom_addr;
B
bellard 已提交
473
#endif
474
    /* temporary float registers */
B
blueswir1 已提交
475
    float128 qt0, qt1;
B
bellard 已提交
476
    float_status fp_status;
477
#if defined(TARGET_SPARC64)
478 479 480
#define MAXTL_MAX 8
#define MAXTL_MASK (MAXTL_MAX - 1)
    trap_state ts[MAXTL_MAX];
B
blueswir1 已提交
481
    uint32_t xcc;               /* Extended integer condition codes */
B
bellard 已提交
482 483 484
    uint32_t asi;
    uint32_t pstate;
    uint32_t tl;
485
    uint32_t maxtl;
B
bellard 已提交
486
    uint32_t cansave, canrestore, otherwin, wstate, cleanwin;
B
bellard 已提交
487 488 489 490
    uint64_t agregs[8]; /* alternate general registers */
    uint64_t bgregs[8]; /* backup for normal global registers */
    uint64_t igregs[8]; /* interrupt general registers */
    uint64_t mgregs[8]; /* mmu general registers */
491
    uint64_t glregs[8 * MAXTL_MAX];
B
bellard 已提交
492
    uint64_t fprs;
B
bellard 已提交
493
    uint64_t tick_cmpr, stick_cmpr;
494
    CPUTimer *tick, *stick;
495 496
#define TICK_NPT_MASK        0x8000000000000000ULL
#define TICK_INT_DIS         0x8000000000000000ULL
B
bellard 已提交
497
    uint64_t gsr;
B
blueswir1 已提交
498 499
    uint32_t gl; // UA2005
    /* UA 2005 hyperprivileged registers */
500
    uint64_t hpstate, htstate[MAXTL_MAX], hintp, htba, hver, hstick_cmpr, ssr;
501
    uint64_t scratch[8];
502
    CPUTimer *hstick; // UA 2005
B
Blue Swirl 已提交
503 504 505
    /* Interrupt vector registers */
    uint64_t ivec_status;
    uint64_t ivec_data[3];
506
    uint32_t softint;
B
blueswir1 已提交
507 508
#define SOFTINT_TIMER   1
#define SOFTINT_STIMER  (1 << 16)
509 510
#define SOFTINT_INTRMASK (0xFFFE)
#define SOFTINT_REG_MASK (SOFTINT_STIMER|SOFTINT_INTRMASK|SOFTINT_TIMER)
B
bellard 已提交
511
#endif
512
    sparc_def_t def;
F
Fabien Chouteau 已提交
513 514

    void *irq_manager;
515
    void (*qemu_irq_ack)(CPUSPARCState *env, void *irq_manager, int intno);
F
Fabien Chouteau 已提交
516 517 518

    /* Leon3 cache control */
    uint32_t cache_control;
519
};
B
blueswir1 已提交
520

521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
/**
 * SPARCCPU:
 * @env: #CPUSPARCState
 *
 * A SPARC CPU.
 */
struct SPARCCPU {
    /*< private >*/
    CPUState parent_obj;
    /*< public >*/

    CPUSPARCState env;
};

static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
{
    return container_of(env, SPARCCPU, env);
}

#define ENV_GET_CPU(e) CPU(sparc_env_get_cpu(e))

#define ENV_OFFSET offsetof(SPARCCPU, env)

#ifndef CONFIG_USER_ONLY
extern const struct VMStateDescription vmstate_sparc_cpu;
#endif

void sparc_cpu_do_interrupt(CPUState *cpu);
549
void sparc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
550 551 552
hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
int sparc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
int sparc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
553 554 555 556
void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
                                                 MMUAccessType access_type,
                                                 int mmu_idx,
                                                 uintptr_t retaddr);
557
void cpu_raise_exception_ra(CPUSPARCState *, int, uintptr_t) QEMU_NORETURN;
558

559
#ifndef NO_CPU_IO_DEFS
B
Blue Swirl 已提交
560
/* cpu_init.c */
B
blueswir1 已提交
561
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
562
void sparc_cpu_list(void);
B
Blue Swirl 已提交
563
/* mmu_helper.c */
564 565 566
bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
                        bool probe, uintptr_t retaddr);
567
target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
568
void dump_mmu(CPUSPARCState *env);
B
blueswir1 已提交
569

570
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
571 572
int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
                              uint8_t *buf, int len, bool is_write);
573 574 575
#endif


B
blueswir1 已提交
576
/* translate.c */
577
void sparc_tcg_init(void);
B
blueswir1 已提交
578 579

/* cpu-exec.c */
580

581
/* win_helper.c */
582 583
target_ulong cpu_get_psr(CPUSPARCState *env1);
void cpu_put_psr(CPUSPARCState *env1, target_ulong val);
584
void cpu_put_psr_raw(CPUSPARCState *env1, target_ulong val);
585
#ifdef TARGET_SPARC64
586 587 588 589 590
target_ulong cpu_get_ccr(CPUSPARCState *env1);
void cpu_put_ccr(CPUSPARCState *env1, target_ulong val);
target_ulong cpu_get_cwp64(CPUSPARCState *env1);
void cpu_put_cwp64(CPUSPARCState *env1, int cwp);
void cpu_change_pstate(CPUSPARCState *env1, uint32_t new_pstate);
591
void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl);
592
#endif
593 594 595
int cpu_cwp_inc(CPUSPARCState *env1, int cwp);
int cpu_cwp_dec(CPUSPARCState *env1, int cwp);
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
596

597
/* int_helper.c */
598
void leon3_irq_manager(CPUSPARCState *env, void *irq_manager, int intno);
F
Fabien Chouteau 已提交
599

600 601
/* sun4m.c, sun4u.c */
void cpu_check_irqs(CPUSPARCState *env);
602

F
Fabien Chouteau 已提交
603 604 605
/* leon3.c */
void leon3_irq_ack(void *irq_manager, int intno);

606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
#if defined (TARGET_SPARC64)

static inline int compare_masked(uint64_t x, uint64_t y, uint64_t mask)
{
    return (x & mask) == (y & mask);
}

#define MMU_CONTEXT_BITS 13
#define MMU_CONTEXT_MASK ((1 << MMU_CONTEXT_BITS) - 1)

static inline int tlb_compare_context(const SparcTLBEntry *tlb,
                                      uint64_t context)
{
    return compare_masked(context, tlb->tag, MMU_CONTEXT_MASK);
}

B
blueswir1 已提交
622
#endif
B
bellard 已提交
623 624
#endif

B
blueswir1 已提交
625
/* cpu-exec.c */
P
Paul Brook 已提交
626
#if !defined(CONFIG_USER_ONLY)
627 628 629
void sparc_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
                                 bool is_write, bool is_exec, int is_asi,
                                 unsigned size);
630
#if defined(TARGET_SPARC64)
A
Avi Kivity 已提交
631
hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
632
                                           int mmu_idx);
633
#endif
P
Paul Brook 已提交
634
#endif
635
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
636

637 638
#define SPARC_CPU_TYPE_SUFFIX "-" TYPE_SPARC_CPU
#define SPARC_CPU_TYPE_NAME(model) model SPARC_CPU_TYPE_SUFFIX
639
#define CPU_RESOLVING_TYPE TYPE_SPARC_CPU
640

641
#define cpu_signal_handler cpu_sparc_signal_handler
J
j_mayer 已提交
642
#define cpu_list sparc_cpu_list
643

644
/* MMU modes definitions */
645 646 647 648 649 650
#if defined (TARGET_SPARC64)
#define MMU_USER_IDX   0
#define MMU_USER_SECONDARY_IDX   1
#define MMU_KERNEL_IDX 2
#define MMU_KERNEL_SECONDARY_IDX 3
#define MMU_NUCLEUS_IDX 4
651
#define MMU_PHYS_IDX   5
652
#else
653 654
#define MMU_USER_IDX   0
#define MMU_KERNEL_IDX 1
R
Richard Henderson 已提交
655
#define MMU_PHYS_IDX   2
656 657 658
#endif

#if defined (TARGET_SPARC64)
659
static inline int cpu_has_hypervisor(CPUSPARCState *env1)
660
{
661
    return env1->def.features & CPU_FEATURE_HYPV;
662 663
}

664
static inline int cpu_hypervisor_mode(CPUSPARCState *env1)
665 666 667 668
{
    return cpu_has_hypervisor(env1) && (env1->hpstate & HS_PRIV);
}

669
static inline int cpu_supervisor_mode(CPUSPARCState *env1)
670 671 672
{
    return env1->pstate & PS_PRIV;
}
673 674 675 676 677
#else
static inline int cpu_supervisor_mode(CPUSPARCState *env1)
{
    return env1->psrs;
}
678
#endif
679

R
Richard Henderson 已提交
680
static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
681
{
B
blueswir1 已提交
682
#if defined(CONFIG_USER_ONLY)
683
    return MMU_USER_IDX;
B
blueswir1 已提交
684
#elif !defined(TARGET_SPARC64)
R
Richard Henderson 已提交
685 686 687 688 689
    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
        return MMU_PHYS_IDX;
    } else {
        return env->psrs;
    }
B
blueswir1 已提交
690
#else
R
Richard Henderson 已提交
691 692 693 694 695 696
    /* IMMU or DMMU disabled.  */
    if (ifetch
        ? (env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0
        : (env->lsu & DMMU_E) == 0) {
        return MMU_PHYS_IDX;
    } else if (cpu_hypervisor_mode(env)) {
697
        return MMU_PHYS_IDX;
698 699
    } else if (env->tl > 0) {
        return MMU_NUCLEUS_IDX;
R
Richard Henderson 已提交
700
    } else if (cpu_supervisor_mode(env)) {
701 702 703 704
        return MMU_KERNEL_IDX;
    } else {
        return MMU_USER_IDX;
    }
B
blueswir1 已提交
705 706 707
#endif
}

708
static inline int cpu_interrupts_enabled(CPUSPARCState *env1)
709 710 711 712 713
{
#if !defined (TARGET_SPARC64)
    if (env1->psret != 0)
        return 1;
#else
714
    if ((env1->pstate & PS_IE) && !cpu_hypervisor_mode(env1)) {
715
        return 1;
716
    }
717 718 719 720 721
#endif

    return 0;
}

722
static inline int cpu_pil_allowed(CPUSPARCState *env1, int pil)
723 724 725 726 727 728 729 730 731
{
#if !defined(TARGET_SPARC64)
    /* level 15 is non-maskable on sparc v8 */
    return pil == 15 || pil > env1->psrpil;
#else
    return pil > env1->psrpil;
#endif
}

732
typedef CPUSPARCState CPUArchState;
R
Richard Henderson 已提交
733
typedef SPARCCPU ArchCPU;
734

735
#include "exec/cpu-all.h"
736

B
blueswir1 已提交
737 738
#ifdef TARGET_SPARC64
/* sun4u.c */
739 740 741
void cpu_tick_set_count(CPUTimer *timer, uint64_t count);
uint64_t cpu_tick_get_count(CPUTimer *timer);
void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit);
742
trap_state* cpu_tsptr(CPUSPARCState* env);
B
blueswir1 已提交
743 744
#endif

745 746 747
#define TB_FLAG_MMU_MASK     7
#define TB_FLAG_FPU_ENABLED  (1 << 4)
#define TB_FLAG_AM_ENABLED   (1 << 5)
748 749
#define TB_FLAG_SUPER        (1 << 6)
#define TB_FLAG_HYPER        (1 << 7)
750
#define TB_FLAG_ASI_SHIFT    24
751

752
static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
753
                                        target_ulong *cs_base, uint32_t *pflags)
754
{
755
    uint32_t flags;
756 757
    *pc = env->pc;
    *cs_base = env->npc;
758
    flags = cpu_mmu_index(env, false);
759 760 761 762 763
#ifndef CONFIG_USER_ONLY
    if (cpu_supervisor_mode(env)) {
        flags |= TB_FLAG_SUPER;
    }
#endif
764
#ifdef TARGET_SPARC64
765 766 767 768 769
#ifndef CONFIG_USER_ONLY
    if (cpu_hypervisor_mode(env)) {
        flags |= TB_FLAG_HYPER;
    }
#endif
770
    if (env->pstate & PS_AM) {
771
        flags |= TB_FLAG_AM_ENABLED;
772
    }
773
    if ((env->def.features & CPU_FEATURE_FLOAT)
774
        && (env->pstate & PS_PEF)
775
        && (env->fprs & FPRS_FEF)) {
776
        flags |= TB_FLAG_FPU_ENABLED;
777
    }
778
    flags |= env->asi << TB_FLAG_ASI_SHIFT;
779
#else
780
    if ((env->def.features & CPU_FEATURE_FLOAT) && env->psref) {
781
        flags |= TB_FLAG_FPU_ENABLED;
782 783
    }
#endif
784
    *pflags = flags;
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
}

static inline bool tb_fpu_enabled(int tb_flags)
{
#if defined(CONFIG_USER_ONLY)
    return true;
#else
    return tb_flags & TB_FLAG_FPU_ENABLED;
#endif
}

static inline bool tb_am_enabled(int tb_flags)
{
#ifndef TARGET_SPARC64
    return false;
#else
    return tb_flags & TB_FLAG_AM_ENABLED;
802 803 804
#endif
}

805
#endif