Statistics
| Branch: | Revision:

root / target-alpha / cpu.h @ ba0e276d

History | View | Annotate | Download (13.8 kB)

1
/*
2
 *  Alpha emulation cpu definitions for qemu.
3
 *
4
 *  Copyright (c) 2007 Jocelyn Mayer
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 */
19

    
20
#if !defined (__CPU_ALPHA_H__)
21
#define __CPU_ALPHA_H__
22

    
23
#include "config.h"
24

    
25
#define TARGET_LONG_BITS 64
26

    
27
#define CPUState struct CPUAlphaState
28

    
29
#include "cpu-defs.h"
30

    
31
#include <setjmp.h>
32

    
33
#include "softfloat.h"
34

    
35
#define TARGET_HAS_ICE 1
36

    
37
#define ELF_MACHINE     EM_ALPHA
38

    
39
#define ICACHE_LINE_SIZE 32
40
#define DCACHE_LINE_SIZE 32
41

    
42
#define TARGET_PAGE_BITS 13
43

    
44
#define VA_BITS 43
45

    
46
/* Alpha major type */
47
enum {
48
    ALPHA_EV3  = 1,
49
    ALPHA_EV4  = 2,
50
    ALPHA_SIM  = 3,
51
    ALPHA_LCA  = 4,
52
    ALPHA_EV5  = 5, /* 21164 */
53
    ALPHA_EV45 = 6, /* 21064A */
54
    ALPHA_EV56 = 7, /* 21164A */
55
};
56

    
57
/* EV4 minor type */
58
enum {
59
    ALPHA_EV4_2 = 0,
60
    ALPHA_EV4_3 = 1,
61
};
62

    
63
/* LCA minor type */
64
enum {
65
    ALPHA_LCA_1 = 1, /* 21066 */
66
    ALPHA_LCA_2 = 2, /* 20166 */
67
    ALPHA_LCA_3 = 3, /* 21068 */
68
    ALPHA_LCA_4 = 4, /* 21068 */
69
    ALPHA_LCA_5 = 5, /* 21066A */
70
    ALPHA_LCA_6 = 6, /* 21068A */
71
};
72

    
73
/* EV5 minor type */
74
enum {
75
    ALPHA_EV5_1 = 1, /* Rev BA, CA */
76
    ALPHA_EV5_2 = 2, /* Rev DA, EA */
77
    ALPHA_EV5_3 = 3, /* Pass 3 */
78
    ALPHA_EV5_4 = 4, /* Pass 3.2 */
79
    ALPHA_EV5_5 = 5, /* Pass 4 */
80
};
81

    
82
/* EV45 minor type */
83
enum {
84
    ALPHA_EV45_1 = 1, /* Pass 1 */
85
    ALPHA_EV45_2 = 2, /* Pass 1.1 */
86
    ALPHA_EV45_3 = 3, /* Pass 2 */
87
};
88

    
89
/* EV56 minor type */
90
enum {
91
    ALPHA_EV56_1 = 1, /* Pass 1 */
92
    ALPHA_EV56_2 = 2, /* Pass 2 */
93
};
94

    
95
enum {
96
    IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */
97
    IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */
98
    IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */
99
    IMPLVER_21364 = 3, /* EV7 & EV79 */
100
};
101

    
102
enum {
103
    AMASK_BWX      = 0x00000001,
104
    AMASK_FIX      = 0x00000002,
105
    AMASK_CIX      = 0x00000004,
106
    AMASK_MVI      = 0x00000100,
107
    AMASK_TRAP     = 0x00000200,
108
    AMASK_PREFETCH = 0x00001000,
109
};
110

    
111
enum {
112
    VAX_ROUND_NORMAL = 0,
113
    VAX_ROUND_CHOPPED,
114
};
115

    
116
enum {
117
    IEEE_ROUND_NORMAL = 0,
118
    IEEE_ROUND_DYNAMIC,
119
    IEEE_ROUND_PLUS,
120
    IEEE_ROUND_MINUS,
121
    IEEE_ROUND_CHOPPED,
122
};
123

    
124
/* IEEE floating-point operations encoding */
125
/* Trap mode */
126
enum {
127
    FP_TRAP_I   = 0x0,
128
    FP_TRAP_U   = 0x1,
129
    FP_TRAP_S  = 0x4,
130
    FP_TRAP_SU  = 0x5,
131
    FP_TRAP_SUI = 0x7,
132
};
133

    
134
/* Rounding mode */
135
enum {
136
    FP_ROUND_CHOPPED = 0x0,
137
    FP_ROUND_MINUS   = 0x1,
138
    FP_ROUND_NORMAL  = 0x2,
139
    FP_ROUND_DYNAMIC = 0x3,
140
};
141

    
142
/* FPCR bits */
143
#define FPCR_SUM                (1ULL << 63)
144
#define FPCR_INED                (1ULL << 62)
145
#define FPCR_UNFD                (1ULL << 61)
146
#define FPCR_UNDZ                (1ULL << 60)
147
#define FPCR_DYN_SHIFT                58
148
#define FPCR_DYN_MASK                (3ULL << FPCR_DYN_SHIFT)
149
#define FPCR_IOV                (1ULL << 57)
150
#define FPCR_INE                (1ULL << 56)
151
#define FPCR_UNF                (1ULL << 55)
152
#define FPCR_OVF                (1ULL << 54)
153
#define FPCR_DZE                (1ULL << 53)
154
#define FPCR_INV                (1ULL << 52)
155
#define FPCR_OVFD                (1ULL << 51)
156
#define FPCR_DZED                (1ULL << 50)
157
#define FPCR_INVD                (1ULL << 49)
158
#define FPCR_DNZ                (1ULL << 48)
159
#define FPCR_DNOD                (1ULL << 47)
160
#define FPCR_STATUS_MASK        (FPCR_IOV | FPCR_INE | FPCR_UNF \
161
                                 | FPCR_OVF | FPCR_DZE | FPCR_INV)
162

    
163
/* The silly software trap enables implemented by the kernel emulation.
164
   These are more or less architecturally required, since the real hardware
165
   has read-as-zero bits in the FPCR when the features aren't implemented.
166
   For the purposes of QEMU, we pretend the FPCR can hold everything.  */
167
#define SWCR_TRAP_ENABLE_INV        (1ULL << 1)
168
#define SWCR_TRAP_ENABLE_DZE        (1ULL << 2)
169
#define SWCR_TRAP_ENABLE_OVF        (1ULL << 3)
170
#define SWCR_TRAP_ENABLE_UNF        (1ULL << 4)
171
#define SWCR_TRAP_ENABLE_INE        (1ULL << 5)
172
#define SWCR_TRAP_ENABLE_DNO        (1ULL << 6)
173
#define SWCR_TRAP_ENABLE_MASK        ((1ULL << 7) - (1ULL << 1))
174

    
175
#define SWCR_MAP_DMZ                (1ULL << 12)
176
#define SWCR_MAP_UMZ                (1ULL << 13)
177
#define SWCR_MAP_MASK                (SWCR_MAP_DMZ | SWCR_MAP_UMZ)
178

    
179
#define SWCR_STATUS_INV                (1ULL << 17)
180
#define SWCR_STATUS_DZE                (1ULL << 18)
181
#define SWCR_STATUS_OVF                (1ULL << 19)
182
#define SWCR_STATUS_UNF                (1ULL << 20)
183
#define SWCR_STATUS_INE                (1ULL << 21)
184
#define SWCR_STATUS_DNO                (1ULL << 22)
185
#define SWCR_STATUS_MASK        ((1ULL << 23) - (1ULL << 17))
186

    
187
#define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
188

    
189
/* Internal processor registers */
190
/* XXX: TOFIX: most of those registers are implementation dependant */
191
enum {
192
    /* Ebox IPRs */
193
    IPR_CC           = 0xC0,            /* 21264 */
194
    IPR_CC_CTL       = 0xC1,            /* 21264 */
195
#define IPR_CC_CTL_ENA_SHIFT 32
196
#define IPR_CC_CTL_COUNTER_MASK 0xfffffff0UL
197
    IPR_VA           = 0xC2,            /* 21264 */
198
    IPR_VA_CTL       = 0xC4,            /* 21264 */
199
#define IPR_VA_CTL_VA_48_SHIFT 1
200
#define IPR_VA_CTL_VPTB_SHIFT 30
201
    IPR_VA_FORM      = 0xC3,            /* 21264 */
202
    /* Ibox IPRs */
203
    IPR_ITB_TAG      = 0x00,            /* 21264 */
204
    IPR_ITB_PTE      = 0x01,            /* 21264 */
205
    IPR_ITB_IAP      = 0x02,
206
    IPR_ITB_IA       = 0x03,            /* 21264 */
207
    IPR_ITB_IS       = 0x04,            /* 21264 */
208
    IPR_PMPC         = 0x05,
209
    IPR_EXC_ADDR     = 0x06,            /* 21264 */
210
    IPR_IVA_FORM     = 0x07,            /* 21264 */
211
    IPR_CM           = 0x09,            /* 21264 */
212
#define IPR_CM_SHIFT 3
213
#define IPR_CM_MASK (3ULL << IPR_CM_SHIFT)      /* 21264 */
214
    IPR_IER          = 0x0A,            /* 21264 */
215
#define IPR_IER_MASK 0x0000007fffffe000ULL
216
    IPR_IER_CM       = 0x0B,            /* 21264: = CM | IER */
217
    IPR_SIRR         = 0x0C,            /* 21264 */
218
#define IPR_SIRR_SHIFT 14
219
#define IPR_SIRR_MASK 0x7fff
220
    IPR_ISUM         = 0x0D,            /* 21264 */
221
    IPR_HW_INT_CLR   = 0x0E,            /* 21264 */
222
    IPR_EXC_SUM      = 0x0F,
223
    IPR_PAL_BASE     = 0x10,
224
    IPR_I_CTL        = 0x11,
225
#define IPR_I_CTL_CHIP_ID_SHIFT 24      /* 21264 */
226
#define IPR_I_CTL_BIST_FAIL (1 << 23)   /* 21264 */
227
#define IPR_I_CTL_IC_EN_SHIFT 2         /* 21264 */
228
#define IPR_I_CTL_SDE1_SHIFT 7          /* 21264 */
229
#define IPR_I_CTL_HWE_SHIFT 12          /* 21264 */
230
#define IPR_I_CTL_VA_48_SHIFT 15        /* 21264 */
231
#define IPR_I_CTL_SPE_SHIFT 3           /* 21264 */
232
#define IPR_I_CTL_CALL_PAL_R23_SHIFT 20 /* 21264 */
233
    IPR_I_STAT       = 0x16,            /* 21264 */
234
    IPR_IC_FLUSH     = 0x13,            /* 21264 */
235
    IPR_IC_FLUSH_ASM = 0x12,            /* 21264 */
236
    IPR_CLR_MAP      = 0x15,
237
    IPR_SLEEP        = 0x17,
238
    IPR_PCTX         = 0x40,
239
    IPR_PCTX_ASN       = 0x01,  /* field */
240
#define IPR_PCTX_ASN_SHIFT 39
241
    IPR_PCTX_ASTER     = 0x02,  /* field */
242
#define IPR_PCTX_ASTER_SHIFT 5
243
    IPR_PCTX_ASTRR     = 0x04,  /* field */
244
#define IPR_PCTX_ASTRR_SHIFT 9
245
    IPR_PCTX_PPCE      = 0x08,  /* field */
246
#define IPR_PCTX_PPCE_SHIFT 1
247
    IPR_PCTX_FPE       = 0x10,  /* field */
248
#define IPR_PCTX_FPE_SHIFT 2
249
    IPR_PCTX_ALL       = 0x5f,  /* all fields */
250
    IPR_PCTR_CTL     = 0x14,            /* 21264 */
251
    /* Mbox IPRs */
252
    IPR_DTB_TAG0     = 0x20,            /* 21264 */
253
    IPR_DTB_TAG1     = 0xA0,            /* 21264 */
254
    IPR_DTB_PTE0     = 0x21,            /* 21264 */
255
    IPR_DTB_PTE1     = 0xA1,            /* 21264 */
256
    IPR_DTB_ALTMODE  = 0xA6,
257
    IPR_DTB_ALTMODE0 = 0x26,            /* 21264 */
258
#define IPR_DTB_ALTMODE_MASK 3
259
    IPR_DTB_IAP      = 0xA2,
260
    IPR_DTB_IA       = 0xA3,            /* 21264 */
261
    IPR_DTB_IS0      = 0x24,
262
    IPR_DTB_IS1      = 0xA4,
263
    IPR_DTB_ASN0     = 0x25,            /* 21264 */
264
    IPR_DTB_ASN1     = 0xA5,            /* 21264 */
265
#define IPR_DTB_ASN_SHIFT 56
266
    IPR_MM_STAT      = 0x27,            /* 21264 */
267
    IPR_M_CTL        = 0x28,            /* 21264 */
268
#define IPR_M_CTL_SPE_SHIFT 1
269
#define IPR_M_CTL_SPE_MASK 7
270
    IPR_DC_CTL       = 0x29,            /* 21264 */
271
    IPR_DC_STAT      = 0x2A,            /* 21264 */
272
    /* Cbox IPRs */
273
    IPR_C_DATA       = 0x2B,
274
    IPR_C_SHIFT      = 0x2C,
275

    
276
    IPR_ASN,
277
    IPR_ASTEN,
278
    IPR_ASTSR,
279
    IPR_DATFX,
280
    IPR_ESP,
281
    IPR_FEN,
282
    IPR_IPIR,
283
    IPR_IPL,
284
    IPR_KSP,
285
    IPR_MCES,
286
    IPR_PERFMON,
287
    IPR_PCBB,
288
    IPR_PRBR,
289
    IPR_PTBR,
290
    IPR_SCBB,
291
    IPR_SISR,
292
    IPR_SSP,
293
    IPR_SYSPTBR,
294
    IPR_TBCHK,
295
    IPR_TBIA,
296
    IPR_TBIAP,
297
    IPR_TBIS,
298
    IPR_TBISD,
299
    IPR_TBISI,
300
    IPR_USP,
301
    IPR_VIRBND,
302
    IPR_VPTB,
303
    IPR_WHAMI,
304
    IPR_ALT_MODE,
305
    IPR_LAST,
306
};
307

    
308
typedef struct CPUAlphaState CPUAlphaState;
309

    
310
typedef struct pal_handler_t pal_handler_t;
311
struct pal_handler_t {
312
    /* Reset */
313
    void (*reset)(CPUAlphaState *env);
314
    /* Uncorrectable hardware error */
315
    void (*machine_check)(CPUAlphaState *env);
316
    /* Arithmetic exception */
317
    void (*arithmetic)(CPUAlphaState *env);
318
    /* Interrupt / correctable hardware error */
319
    void (*interrupt)(CPUAlphaState *env);
320
    /* Data fault */
321
    void (*dfault)(CPUAlphaState *env);
322
    /* DTB miss pal */
323
    void (*dtb_miss_pal)(CPUAlphaState *env);
324
    /* DTB miss native */
325
    void (*dtb_miss_native)(CPUAlphaState *env);
326
    /* Unaligned access */
327
    void (*unalign)(CPUAlphaState *env);
328
    /* ITB miss */
329
    void (*itb_miss)(CPUAlphaState *env);
330
    /* Instruction stream access violation */
331
    void (*itb_acv)(CPUAlphaState *env);
332
    /* Reserved or privileged opcode */
333
    void (*opcdec)(CPUAlphaState *env);
334
    /* Floating point exception */
335
    void (*fen)(CPUAlphaState *env);
336
    /* Call pal instruction */
337
    void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
338
};
339

    
340
#define NB_MMU_MODES 4
341

    
342
struct CPUAlphaState {
343
    uint64_t ir[31];
344
    float64  fir[31];
345
    float_status fp_status;
346
    uint64_t fpcr;
347
    uint64_t pc;
348
    uint64_t lock;
349
    uint32_t pcc[2];
350
    uint64_t ipr[IPR_LAST];
351
    uint64_t ps;
352
    uint64_t unique;
353
    int saved_mode; /* Used for HW_LD / HW_ST */
354
    int intr_flag; /* For RC and RS */
355

    
356
#if TARGET_LONG_BITS > HOST_LONG_BITS
357
    /* temporary fixed-point registers
358
     * used to emulate 64 bits target on 32 bits hosts
359
     */
360
    target_ulong t0, t1;
361
#endif
362

    
363
    /* Those resources are used only in Qemu core */
364
    CPU_COMMON
365

    
366
    uint32_t hflags;
367

    
368
    int error_code;
369

    
370
    uint32_t features;
371
    uint32_t amask;
372
    int implver;
373
    pal_handler_t *pal_handler;
374
};
375

    
376
#define cpu_init cpu_alpha_init
377
#define cpu_exec cpu_alpha_exec
378
#define cpu_gen_code cpu_alpha_gen_code
379
#define cpu_signal_handler cpu_alpha_signal_handler
380

    
381
/* MMU modes definitions */
382
#define MMU_MODE0_SUFFIX _kernel
383
#define MMU_MODE1_SUFFIX _executive
384
#define MMU_MODE2_SUFFIX _supervisor
385
#define MMU_MODE3_SUFFIX _user
386
#define MMU_USER_IDX 3
387
static inline int cpu_mmu_index (CPUState *env)
388
{
389
    return (env->ps >> 3) & 3;
390
}
391

    
392
#if defined(CONFIG_USER_ONLY)
393
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
394
{
395
    if (newsp)
396
        env->ir[30] = newsp;
397
    /* FIXME: Zero syscall return value.  */
398
}
399
#endif
400

    
401
#include "cpu-all.h"
402
#include "exec-all.h"
403

    
404
enum {
405
    FEATURE_ASN    = 0x00000001,
406
    FEATURE_SPS    = 0x00000002,
407
    FEATURE_VIRBND = 0x00000004,
408
    FEATURE_TBCHK  = 0x00000008,
409
};
410

    
411
enum {
412
    EXCP_RESET            = 0x0000,
413
    EXCP_MCHK             = 0x0020,
414
    EXCP_ARITH            = 0x0060,
415
    EXCP_HW_INTERRUPT     = 0x00E0,
416
    EXCP_DFAULT           = 0x01E0,
417
    EXCP_DTB_MISS_PAL     = 0x09E0,
418
    EXCP_ITB_MISS         = 0x03E0,
419
    EXCP_ITB_ACV          = 0x07E0,
420
    EXCP_DTB_MISS_NATIVE  = 0x08E0,
421
    EXCP_UNALIGN          = 0x11E0,
422
    EXCP_OPCDEC           = 0x13E0,
423
    EXCP_FEN              = 0x17E0,
424
    EXCP_CALL_PAL         = 0x2000,
425
    EXCP_CALL_PALP        = 0x3000,
426
    EXCP_CALL_PALE        = 0x4000,
427
    /* Pseudo exception for console */
428
    EXCP_CONSOLE_DISPATCH = 0x4001,
429
    EXCP_CONSOLE_FIXUP    = 0x4002,
430
};
431

    
432
/* Arithmetic exception */
433
enum {
434
    EXCP_ARITH_OVERFLOW,
435
};
436

    
437
enum {
438
    IR_V0   = 0,
439
    IR_T0   = 1,
440
    IR_T1   = 2,
441
    IR_T2   = 3,
442
    IR_T3   = 4,
443
    IR_T4   = 5,
444
    IR_T5   = 6,
445
    IR_T6   = 7,
446
    IR_T7   = 8,
447
    IR_S0   = 9,
448
    IR_S1   = 10,
449
    IR_S2   = 11,
450
    IR_S3   = 12,
451
    IR_S4   = 13,
452
    IR_S5   = 14,
453
    IR_S6   = 15,
454
#define IR_FP IR_S6
455
    IR_A0   = 16,
456
    IR_A1   = 17,
457
    IR_A2   = 18,
458
    IR_A3   = 19,
459
    IR_A4   = 20,
460
    IR_A5   = 21,
461
    IR_T8   = 22,
462
    IR_T9   = 23,
463
    IR_T10  = 24,
464
    IR_T11  = 25,
465
    IR_RA   = 26,
466
    IR_T12  = 27,
467
#define IR_PV IR_T12
468
    IR_AT   = 28,
469
    IR_GP   = 29,
470
    IR_SP   = 30,
471
    IR_ZERO = 31,
472
};
473

    
474
CPUAlphaState * cpu_alpha_init (const char *cpu_model);
475
int cpu_alpha_exec(CPUAlphaState *s);
476
/* you can call this signal handler from your SIGBUS and SIGSEGV
477
   signal handlers to inform the virtual CPU of exceptions. non zero
478
   is returned if the signal was handled by the virtual CPU.  */
479
int cpu_alpha_signal_handler(int host_signum, void *pinfo,
480
                             void *puc);
481
int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
482
                                int mmu_idx, int is_softmmu);
483
#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
484
void do_interrupt (CPUState *env);
485

    
486
uint64_t cpu_alpha_load_fpcr (CPUState *env);
487
void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
488
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
489
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
490
void pal_init (CPUState *env);
491
#if !defined (CONFIG_USER_ONLY)
492
void call_pal (CPUState *env);
493
#else
494
void call_pal (CPUState *env, int palcode);
495
#endif
496

    
497
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
498
{
499
    env->pc = tb->pc;
500
}
501

    
502
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
503
                                        target_ulong *cs_base, int *flags)
504
{
505
    *pc = env->pc;
506
    *cs_base = 0;
507
    *flags = env->ps;
508
}
509

    
510
#endif /* !defined (__CPU_ALPHA_H__) */