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
#include "fpu/softfloat.h"
B
bellard 已提交
33

34 35
/*#define EXCP_INTERRUPT 0x100*/

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

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

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

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

129 130 131
/* Trap base register */
#define TBR_BASE_MASK 0xfffff000

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

#define FPRS_FEF (1<<2)
B
blueswir1 已提交
147 148

#define HS_PRIV  (1<<2)
B
bellard 已提交
149 150
#endif

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

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

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

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

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

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

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

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

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

226 227 228
/* 3 <= NWINDOWS <= 32. */
#define MIN_NWINDOWS 3
#define MAX_NWINDOWS 32
229

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

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

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

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

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

308 309 310 311 312 313 314
#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)

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

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

331
#define TTE_IS_GLOBAL(tte)  ((tte) & TTE_GLOBAL_BIT)
332 333 334 335

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

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

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

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

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

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

typedef struct CPUTimer CPUTimer;

406
typedef struct CPUSPARCState CPUSPARCState;
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
#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;
   };
} SparcV9MMU;
#endif
423
struct CPUSPARCState {
424 425 426 427 428
    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 */
429 430

    /* emulator internal flags handling */
B
blueswir1 已提交
431
    target_ulong cc_src, cc_src2;
432
    target_ulong cc_dst;
433
    uint32_t cc_op;
434

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

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

461 462 463
    /* Fields up to this point are cleared by a CPU reset */
    struct {} end_reset_fields;

464 465
    CPU_COMMON

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

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

    void *irq_manager;
530
    void (*qemu_irq_ack)(CPUSPARCState *env, void *irq_manager, int intno);
F
Fabien Chouteau 已提交
531 532 533

    /* Leon3 cache control */
    uint32_t cache_control;
534
};
B
blueswir1 已提交
535

536 537 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
/**
 * 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);
569 570 571 572
void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
                                                 MMUAccessType access_type,
                                                 int mmu_idx,
                                                 uintptr_t retaddr);
573
void cpu_raise_exception_ra(CPUSPARCState *, int, uintptr_t) QEMU_NORETURN;
574

575
#ifndef NO_CPU_IO_DEFS
B
Blue Swirl 已提交
576
/* cpu_init.c */
577
SPARCCPU *cpu_sparc_init(const char *cpu_model);
B
blueswir1 已提交
578
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
579
void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf);
B
Blue Swirl 已提交
580
/* mmu_helper.c */
581
int sparc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
582
                               int mmu_idx);
583
target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
584
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env);
B
blueswir1 已提交
585

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


B
blueswir1 已提交
592 593 594 595
/* translate.c */
void gen_intermediate_code_init(CPUSPARCState *env);

/* cpu-exec.c */
596

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

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

616 617
/* sun4m.c, sun4u.c */
void cpu_check_irqs(CPUSPARCState *env);
618

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

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

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

653
#ifndef NO_CPU_IO_DEFS
654
#define cpu_init(cpu_model) CPU(cpu_sparc_init(cpu_model))
655 656
#endif

657
#define cpu_signal_handler cpu_sparc_signal_handler
J
j_mayer 已提交
658
#define cpu_list sparc_cpu_list
659

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

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

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

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

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

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

    return 0;
}

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

748
#include "exec/cpu-all.h"
749

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

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

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

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;
815 816 817
#endif
}

818
#endif