cpu.h 24.8 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

8 9
#define ALIGNED_ONLY

10
#if !defined(TARGET_SPARC64)
B
bellard 已提交
11
#define TARGET_LONG_BITS 32
12
#define TARGET_DPREGS 16
B
bellard 已提交
13
#define TARGET_PAGE_BITS 12 /* 4k */
14 15 16 17
#define TARGET_PHYS_ADDR_SPACE_BITS 36
#define TARGET_VIRT_ADDR_SPACE_BITS 32
#else
#define TARGET_LONG_BITS 64
18
#define TARGET_DPREGS 32
19
#define TARGET_PAGE_BITS 13 /* 8k */
20 21 22 23 24 25
#define TARGET_PHYS_ADDR_SPACE_BITS 41
# ifdef TARGET_ABI32
#  define TARGET_VIRT_ADDR_SPACE_BITS 32
# else
#  define TARGET_VIRT_ADDR_SPACE_BITS 44
# endif
26
#endif
B
bellard 已提交
27

28
#define CPUArchState struct CPUSPARCState
29

30
#include "exec/cpu-defs.h"
31 32 33

/*#define EXCP_INTERRUPT 0x100*/

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

B
blueswir1 已提交
83 84 85 86 87 88 89 90
#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)
91
#define PSR_ICC   (PSR_NEG|PSR_ZERO|PSR_OVF|PSR_CARRY)
92
#if !defined(TARGET_SPARC64)
B
bellard 已提交
93 94
#define PSR_EF    (1<<12)
#define PSR_PIL   0xf00
95 96 97 98
#define PSR_S     (1<<7)
#define PSR_PS    (1<<6)
#define PSR_ET    (1<<5)
#define PSR_CWP   0x1f
99
#endif
100

101 102 103 104 105
#define CC_SRC (env->cc_src)
#define CC_SRC2 (env->cc_src2)
#define CC_DST (env->cc_dst)
#define CC_OP  (env->cc_op)

106 107 108 109 110
/* 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.
 */
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
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,
};

127 128 129
/* Trap base register */
#define TBR_BASE_MASK 0xfffff000

B
bellard 已提交
130
#if defined(TARGET_SPARC64)
131 132 133 134 135
#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 */
136
#define PS_RMO   (1<<7)
137 138 139
#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 已提交
140 141
#define PS_PRIV  (1<<2)
#define PS_IE    (1<<1)
142
#define PS_AG    (1<<0) /* v9, zero on UA2007 */
B
bellard 已提交
143 144

#define FPRS_FEF (1<<2)
B
blueswir1 已提交
145 146

#define HS_PRIV  (1<<2)
B
bellard 已提交
147 148
#endif

149
/* Fcc */
150 151
#define FSR_RD1        (1ULL << 31)
#define FSR_RD0        (1ULL << 30)
152 153 154 155 156 157
#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)

158 159 160 161 162
#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)
163 164
#define FSR_TEM_MASK (FSR_NVM | FSR_OFM | FSR_UFM | FSR_DZM | FSR_NXM)

165 166 167 168 169
#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)
170 171
#define FSR_AEXC_MASK (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)

172 173 174 175 176
#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)
177 178
#define FSR_CEXC_MASK (FSR_NVC | FSR_OFC | FSR_UFC | FSR_DZC | FSR_NXC)

179 180 181
#define FSR_FTT2   (1ULL << 16)
#define FSR_FTT1   (1ULL << 15)
#define FSR_FTT0   (1ULL << 14)
182 183 184 185 186
//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
187 188 189
#define FSR_LDFSR_OLDMASK  0x0000003f000fc000ULL
#define FSR_LDXFSR_MASK    0x0000003fcfc00fffULL
#define FSR_LDXFSR_OLDMASK 0x00000000000fc000ULL
190 191 192
#else
#define FSR_FTT_NMASK      0xfffe3fffULL
#define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL
193
#define FSR_LDFSR_OLDMASK  0x000fc000ULL
194
#endif
195
#define FSR_LDFSR_MASK     0xcfc00fffULL
196 197 198 199
#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)
200

B
blueswir1 已提交
201
#define FSR_FCC1_SHIFT 11
202
#define FSR_FCC1  (1ULL << FSR_FCC1_SHIFT)
B
blueswir1 已提交
203
#define FSR_FCC0_SHIFT 10
204
#define FSR_FCC0  (1ULL << FSR_FCC0_SHIFT)
205 206

/* MMU */
B
blueswir1 已提交
207 208
#define MMU_E     (1<<0)
#define MMU_NF    (1<<1)
209 210 211 212

#define PTE_ENTRYTYPE_MASK 3
#define PTE_ACCESS_MASK    0x1c
#define PTE_ACCESS_SHIFT   2
B
bellard 已提交
213
#define PTE_PPN_SHIFT      7
214 215
#define PTE_ADDR_MASK      0xffffff00

B
blueswir1 已提交
216 217
#define PG_ACCESSED_BIT 5
#define PG_MODIFIED_BIT 6
218 219 220 221 222 223
#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)

224 225 226
/* 3 <= NWINDOWS <= 32. */
#define MIN_NWINDOWS 3
#define MAX_NWINDOWS 32
227

B
blueswir1 已提交
228
#if !defined(TARGET_SPARC64)
R
Richard Henderson 已提交
229
#define NB_MMU_MODES 3
B
blueswir1 已提交
230
#else
231
#define NB_MMU_MODES 6
232 233 234 235 236 237
typedef struct trap_state {
    uint64_t tpc;
    uint64_t tnpc;
    uint64_t tstate;
    uint32_t tt;
} trap_state;
B
blueswir1 已提交
238
#endif
239
#define TARGET_INSN_START_EXTRA_WORDS 1
240

241
struct sparc_def_t {
242 243 244 245 246 247 248 249 250
    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;
251
    uint32_t mxcc_version;
252 253 254
    uint32_t features;
    uint32_t nwindows;
    uint32_t maxtl;
255
};
256

F
Fabien Chouteau 已提交
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
#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" */
272
#define CPU_FEATURE_ASR17        (1 << 15)
F
Fabien Chouteau 已提交
273
#define CPU_FEATURE_CACHE_CTRL   (1 << 16)
274
#define CPU_FEATURE_POWERDOWN    (1 << 17)
275
#define CPU_FEATURE_CASA         (1 << 18)
F
Fabien Chouteau 已提交
276

277 278 279 280 281 282 283 284 285 286
#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 |   \
287 288
                              CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD | \
                              CPU_FEATURE_CASA)
289 290 291 292 293 294 295 296
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

297
#define TTE_VALID_BIT       (1ULL << 63)
298
#define TTE_NFO_BIT         (1ULL << 60)
299 300
#define TTE_USED_BIT        (1ULL << 41)
#define TTE_LOCKED_BIT      (1ULL <<  6)
301
#define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
T
Tsuneo Saito 已提交
302 303
#define TTE_PRIV_BIT        (1ULL <<  2)
#define TTE_W_OK_BIT        (1ULL <<  1)
304
#define TTE_GLOBAL_BIT      (1ULL <<  0)
305

306 307 308 309 310 311 312
#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)

313
#define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
314
#define TTE_IS_NFO(tte)     ((tte) & TTE_NFO_BIT)
315 316
#define TTE_IS_USED(tte)    ((tte) & TTE_USED_BIT)
#define TTE_IS_LOCKED(tte)  ((tte) & TTE_LOCKED_BIT)
317
#define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT)
318
#define TTE_IS_SIDEEFFECT_UA2005(tte) ((tte) & TTE_SIDEEFFECT_BIT_UA2005)
T
Tsuneo Saito 已提交
319 320
#define TTE_IS_PRIV(tte)    ((tte) & TTE_PRIV_BIT)
#define TTE_IS_W_OK(tte)    ((tte) & TTE_W_OK_BIT)
321 322 323 324 325 326 327 328

#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)

329
#define TTE_IS_GLOBAL(tte)  ((tte) & TTE_GLOBAL_BIT)
330 331 332 333

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

T
Tsuneo Saito 已提交
334
#define TTE_PGSIZE(tte)     (((tte) >> 61) & 3ULL)
335
#define TTE_PGSIZE_UA2005(tte)     ((tte) & 7ULL)
T
Tsuneo Saito 已提交
336 337
#define TTE_PA(tte)         ((tte) & 0x1ffffffe000ULL)

338 339 340 341
/* 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 已提交
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
#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)

364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
/* 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 */

385 386 387
#define CONVERT_BIT(X, SRC, DST) \
         (SRC > DST ? (X) / (SRC / DST) & (DST) : ((X) & SRC) * (DST / SRC))

388 389 390 391 392
typedef struct SparcTLBEntry {
    uint64_t tag;
    uint64_t tte;
} SparcTLBEntry;

393 394 395 396 397 398
struct CPUTimer
{
    const char *name;
    uint32_t    frequency;
    uint32_t    disabled;
    uint64_t    disabled_mask;
399 400
    uint32_t    npt;
    uint64_t    npt_mask;
401
    int64_t     clock_offset;
402
    QEMUTimer  *qtimer;
403 404 405 406
};

typedef struct CPUTimer CPUTimer;

407
typedef struct CPUSPARCState CPUSPARCState;
408 409 410 411 412 413 414 415 416 417 418 419 420
#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;
421 422
    uint64_t sun4v_ctx_config[2];
    uint64_t sun4v_tsb_pointers[4];
423 424 425
   };
} SparcV9MMU;
#endif
426
struct CPUSPARCState {
427 428 429 430 431
    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 */
432 433

    /* emulator internal flags handling */
B
blueswir1 已提交
434
    target_ulong cc_src, cc_src2;
435
    target_ulong cc_dst;
436
    uint32_t cc_op;
437

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

441
    uint32_t psr;      /* processor state register */
B
bellard 已提交
442
    target_ulong fsr;      /* FPU state register */
443
    CPU_DoubleU fpr[TARGET_DPREGS];  /* floating point registers */
444 445
    uint32_t cwp;      /* index of current register window (extracted
                          from PSR) */
446
#if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
447
    uint32_t wim;      /* window invalid mask */
448
#endif
B
bellard 已提交
449
    target_ulong tbr;  /* trap base register */
450
#if !defined(TARGET_SPARC64)
451 452 453
    int      psrs;     /* supervisor mode (extracted from PSR) */
    int      psrps;    /* previous supervisor mode */
    int      psret;    /* enable traps */
454
#endif
B
blueswir1 已提交
455 456
    uint32_t psrpil;   /* interrupt blocking level */
    uint32_t pil_in;   /* incoming interrupt level bitmap */
457
#if !defined(TARGET_SPARC64)
B
bellard 已提交
458
    int      psref;    /* enable fpu */
459
#endif
460 461
    int interrupt_index;
    /* NOTE: we allow 8 more registers to handle wrapping */
462
    target_ulong regbase[MAX_NWINDOWS * 16 + 8];
B
bellard 已提交
463

464 465 466
    /* Fields up to this point are cleared by a CPU reset */
    struct {} end_reset_fields;

467 468
    CPU_COMMON

469
    /* Fields from here on are preserved across CPU reset. */
B
Blue Swirl 已提交
470 471 472
    target_ulong version;
    uint32_t nwindows;

473
    /* MMU regs */
B
bellard 已提交
474 475 476 477
#if defined(TARGET_SPARC64)
    uint64_t lsu;
#define DMMU_E 0x8
#define IMMU_E 0x4
478 479
    SparcV9MMU immu;
    SparcV9MMU dmmu;
480 481
    SparcTLBEntry itlb[64];
    SparcTLBEntry dtlb[64];
482
    uint32_t mmu_version;
B
bellard 已提交
483
#else
B
blueswir1 已提交
484
    uint32_t mmuregs[32];
485 486
    uint64_t mxccdata[4];
    uint64_t mxccregs[8];
487 488
    uint32_t mmubpctrv, mmubpctrc, mmubpctrs;
    uint64_t mmubpaction;
489
    uint64_t mmubpregs[4];
490
    uint64_t prom_addr;
B
bellard 已提交
491
#endif
492
    /* temporary float registers */
B
blueswir1 已提交
493
    float128 qt0, qt1;
B
bellard 已提交
494
    float_status fp_status;
495
#if defined(TARGET_SPARC64)
496 497 498
#define MAXTL_MAX 8
#define MAXTL_MASK (MAXTL_MAX - 1)
    trap_state ts[MAXTL_MAX];
B
blueswir1 已提交
499
    uint32_t xcc;               /* Extended integer condition codes */
B
bellard 已提交
500 501 502
    uint32_t asi;
    uint32_t pstate;
    uint32_t tl;
503
    uint32_t maxtl;
B
bellard 已提交
504
    uint32_t cansave, canrestore, otherwin, wstate, cleanwin;
B
bellard 已提交
505 506 507 508
    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 */
509
    uint64_t glregs[8 * MAXTL_MAX];
B
bellard 已提交
510
    uint64_t fprs;
B
bellard 已提交
511
    uint64_t tick_cmpr, stick_cmpr;
512
    CPUTimer *tick, *stick;
513 514
#define TICK_NPT_MASK        0x8000000000000000ULL
#define TICK_INT_DIS         0x8000000000000000ULL
B
bellard 已提交
515
    uint64_t gsr;
B
blueswir1 已提交
516 517
    uint32_t gl; // UA2005
    /* UA 2005 hyperprivileged registers */
518
    uint64_t hpstate, htstate[MAXTL_MAX], hintp, htba, hver, hstick_cmpr, ssr;
519
    uint64_t scratch[8];
520
    CPUTimer *hstick; // UA 2005
B
Blue Swirl 已提交
521 522 523
    /* Interrupt vector registers */
    uint64_t ivec_status;
    uint64_t ivec_data[3];
524
    uint32_t softint;
B
blueswir1 已提交
525 526
#define SOFTINT_TIMER   1
#define SOFTINT_STIMER  (1 << 16)
527 528
#define SOFTINT_INTRMASK (0xFFFE)
#define SOFTINT_REG_MASK (SOFTINT_STIMER|SOFTINT_INTRMASK|SOFTINT_TIMER)
B
bellard 已提交
529
#endif
530
    sparc_def_t def;
F
Fabien Chouteau 已提交
531 532

    void *irq_manager;
533
    void (*qemu_irq_ack)(CPUSPARCState *env, void *irq_manager, int intno);
F
Fabien Chouteau 已提交
534 535 536

    /* Leon3 cache control */
    uint32_t cache_control;
537
};
B
blueswir1 已提交
538

539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
/**
 * 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);
void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
                          fprintf_function cpu_fprintf, int flags);
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);
572 573 574 575
void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
                                                 MMUAccessType access_type,
                                                 int mmu_idx,
                                                 uintptr_t retaddr);
576
void cpu_raise_exception_ra(CPUSPARCState *, int, uintptr_t) QEMU_NORETURN;
577

578
#ifndef NO_CPU_IO_DEFS
B
Blue Swirl 已提交
579
/* cpu_init.c */
B
blueswir1 已提交
580
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
581
void sparc_cpu_list(void);
B
Blue Swirl 已提交
582
/* mmu_helper.c */
583
int sparc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
584
                               int mmu_idx);
585
target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
586
void dump_mmu(CPUSPARCState *env);
B
blueswir1 已提交
587

588
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
589 590
int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
                              uint8_t *buf, int len, bool is_write);
591 592 593
#endif


B
blueswir1 已提交
594
/* translate.c */
595
void sparc_tcg_init(void);
B
blueswir1 已提交
596 597

/* cpu-exec.c */
598

599
/* win_helper.c */
600 601
target_ulong cpu_get_psr(CPUSPARCState *env1);
void cpu_put_psr(CPUSPARCState *env1, target_ulong val);
602
void cpu_put_psr_raw(CPUSPARCState *env1, target_ulong val);
603
#ifdef TARGET_SPARC64
604 605 606 607 608
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);
609
void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl);
610
#endif
611 612 613
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);
614

615
/* int_helper.c */
616
void leon3_irq_manager(CPUSPARCState *env, void *irq_manager, int intno);
F
Fabien Chouteau 已提交
617

618 619
/* sun4m.c, sun4u.c */
void cpu_check_irqs(CPUSPARCState *env);
620

F
Fabien Chouteau 已提交
621 622 623
/* leon3.c */
void leon3_irq_ack(void *irq_manager, int intno);

624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
#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 已提交
640
#endif
B
bellard 已提交
641 642
#endif

B
blueswir1 已提交
643
/* cpu-exec.c */
P
Paul Brook 已提交
644
#if !defined(CONFIG_USER_ONLY)
645 646 647
void sparc_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
                                 bool is_write, bool is_exec, int is_asi,
                                 unsigned size);
648
#if defined(TARGET_SPARC64)
A
Avi Kivity 已提交
649
hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
650
                                           int mmu_idx);
651
#endif
P
Paul Brook 已提交
652
#endif
653
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
654

655 656
#define SPARC_CPU_TYPE_SUFFIX "-" TYPE_SPARC_CPU
#define SPARC_CPU_TYPE_NAME(model) model SPARC_CPU_TYPE_SUFFIX
657
#define CPU_RESOLVING_TYPE TYPE_SPARC_CPU
658

659
#define cpu_signal_handler cpu_sparc_signal_handler
J
j_mayer 已提交
660
#define cpu_list sparc_cpu_list
661

662
/* MMU modes definitions */
663 664 665 666 667 668
#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
669
#define MMU_PHYS_IDX   5
670
#else
671 672
#define MMU_USER_IDX   0
#define MMU_KERNEL_IDX 1
R
Richard Henderson 已提交
673
#define MMU_PHYS_IDX   2
674 675 676
#endif

#if defined (TARGET_SPARC64)
677
static inline int cpu_has_hypervisor(CPUSPARCState *env1)
678
{
679
    return env1->def.features & CPU_FEATURE_HYPV;
680 681
}

682
static inline int cpu_hypervisor_mode(CPUSPARCState *env1)
683 684 685 686
{
    return cpu_has_hypervisor(env1) && (env1->hpstate & HS_PRIV);
}

687
static inline int cpu_supervisor_mode(CPUSPARCState *env1)
688 689 690
{
    return env1->pstate & PS_PRIV;
}
691 692 693 694 695
#else
static inline int cpu_supervisor_mode(CPUSPARCState *env1)
{
    return env1->psrs;
}
696
#endif
697

R
Richard Henderson 已提交
698
static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
699
{
B
blueswir1 已提交
700
#if defined(CONFIG_USER_ONLY)
701
    return MMU_USER_IDX;
B
blueswir1 已提交
702
#elif !defined(TARGET_SPARC64)
R
Richard Henderson 已提交
703 704 705 706 707
    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
        return MMU_PHYS_IDX;
    } else {
        return env->psrs;
    }
B
blueswir1 已提交
708
#else
R
Richard Henderson 已提交
709 710 711 712 713 714
    /* 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)) {
715
        return MMU_PHYS_IDX;
716 717
    } else if (env->tl > 0) {
        return MMU_NUCLEUS_IDX;
R
Richard Henderson 已提交
718
    } else if (cpu_supervisor_mode(env)) {
719 720 721 722
        return MMU_KERNEL_IDX;
    } else {
        return MMU_USER_IDX;
    }
B
blueswir1 已提交
723 724 725
#endif
}

726
static inline int cpu_interrupts_enabled(CPUSPARCState *env1)
727 728 729 730 731
{
#if !defined (TARGET_SPARC64)
    if (env1->psret != 0)
        return 1;
#else
732
    if ((env1->pstate & PS_IE) && !cpu_hypervisor_mode(env1)) {
733
        return 1;
734
    }
735 736 737 738 739
#endif

    return 0;
}

740
static inline int cpu_pil_allowed(CPUSPARCState *env1, int pil)
741 742 743 744 745 746 747 748 749
{
#if !defined(TARGET_SPARC64)
    /* level 15 is non-maskable on sparc v8 */
    return pil == 15 || pil > env1->psrpil;
#else
    return pil > env1->psrpil;
#endif
}

750
#include "exec/cpu-all.h"
751

B
blueswir1 已提交
752 753
#ifdef TARGET_SPARC64
/* sun4u.c */
754 755 756
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);
757
trap_state* cpu_tsptr(CPUSPARCState* env);
B
blueswir1 已提交
758 759
#endif

760 761 762
#define TB_FLAG_MMU_MASK     7
#define TB_FLAG_FPU_ENABLED  (1 << 4)
#define TB_FLAG_AM_ENABLED   (1 << 5)
763 764
#define TB_FLAG_SUPER        (1 << 6)
#define TB_FLAG_HYPER        (1 << 7)
765
#define TB_FLAG_ASI_SHIFT    24
766

767
static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
768
                                        target_ulong *cs_base, uint32_t *pflags)
769
{
770
    uint32_t flags;
771 772
    *pc = env->pc;
    *cs_base = env->npc;
773
    flags = cpu_mmu_index(env, false);
774 775 776 777 778
#ifndef CONFIG_USER_ONLY
    if (cpu_supervisor_mode(env)) {
        flags |= TB_FLAG_SUPER;
    }
#endif
779
#ifdef TARGET_SPARC64
780 781 782 783 784
#ifndef CONFIG_USER_ONLY
    if (cpu_hypervisor_mode(env)) {
        flags |= TB_FLAG_HYPER;
    }
#endif
785
    if (env->pstate & PS_AM) {
786
        flags |= TB_FLAG_AM_ENABLED;
787
    }
788
    if ((env->def.features & CPU_FEATURE_FLOAT)
789
        && (env->pstate & PS_PEF)
790
        && (env->fprs & FPRS_FEF)) {
791
        flags |= TB_FLAG_FPU_ENABLED;
792
    }
793
    flags |= env->asi << TB_FLAG_ASI_SHIFT;
794
#else
795
    if ((env->def.features & CPU_FEATURE_FLOAT) && env->psref) {
796
        flags |= TB_FLAG_FPU_ENABLED;
797 798
    }
#endif
799
    *pflags = flags;
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
}

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;
817 818 819
#endif
}

820
#endif