Statistics
| Branch: | Revision:

root / target-alpha / cpu.h @ 8443effb

History | View | Annotate | Download (14.3 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_CHOPPED        (0ULL << FPCR_DYN_SHIFT)
149
#define FPCR_DYN_MINUS                (1ULL << FPCR_DYN_SHIFT)
150
#define FPCR_DYN_NORMAL                (2ULL << FPCR_DYN_SHIFT)
151
#define FPCR_DYN_PLUS                (3ULL << FPCR_DYN_SHIFT)
152
#define FPCR_DYN_MASK                (3ULL << FPCR_DYN_SHIFT)
153
#define FPCR_IOV                (1ULL << 57)
154
#define FPCR_INE                (1ULL << 56)
155
#define FPCR_UNF                (1ULL << 55)
156
#define FPCR_OVF                (1ULL << 54)
157
#define FPCR_DZE                (1ULL << 53)
158
#define FPCR_INV                (1ULL << 52)
159
#define FPCR_OVFD                (1ULL << 51)
160
#define FPCR_DZED                (1ULL << 50)
161
#define FPCR_INVD                (1ULL << 49)
162
#define FPCR_DNZ                (1ULL << 48)
163
#define FPCR_DNOD                (1ULL << 47)
164
#define FPCR_STATUS_MASK        (FPCR_IOV | FPCR_INE | FPCR_UNF \
165
                                 | FPCR_OVF | FPCR_DZE | FPCR_INV)
166

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

    
179
#define SWCR_MAP_DMZ                (1ULL << 12)
180
#define SWCR_MAP_UMZ                (1ULL << 13)
181
#define SWCR_MAP_MASK                (SWCR_MAP_DMZ | SWCR_MAP_UMZ)
182

    
183
#define SWCR_STATUS_INV                (1ULL << 17)
184
#define SWCR_STATUS_DZE                (1ULL << 18)
185
#define SWCR_STATUS_OVF                (1ULL << 19)
186
#define SWCR_STATUS_UNF                (1ULL << 20)
187
#define SWCR_STATUS_INE                (1ULL << 21)
188
#define SWCR_STATUS_DNO                (1ULL << 22)
189
#define SWCR_STATUS_MASK        ((1ULL << 23) - (1ULL << 17))
190

    
191
#define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
192

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

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

    
312
typedef struct CPUAlphaState CPUAlphaState;
313

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

    
344
#define NB_MMU_MODES 4
345

    
346
struct CPUAlphaState {
347
    uint64_t ir[31];
348
    float64 fir[31];
349
    uint64_t pc;
350
    uint64_t lock;
351
    uint32_t pcc[2];
352
    uint64_t ipr[IPR_LAST];
353
    uint64_t ps;
354
    uint64_t unique;
355
    float_status fp_status;
356
    /* The following fields make up the FPCR, but in FP_STATUS format.  */
357
    uint8_t fpcr_exc_status;
358
    uint8_t fpcr_exc_mask;
359
    uint8_t fpcr_dyn_round;
360
    uint8_t fpcr_flush_to_zero;
361
    uint8_t fpcr_dnz;
362
    uint8_t fpcr_dnod;
363
    uint8_t fpcr_undz;
364

    
365
    /* Used for HW_LD / HW_ST */
366
    uint8_t saved_mode;
367
    /* For RC and RS */
368
    uint8_t intr_flag;
369

    
370
#if TARGET_LONG_BITS > HOST_LONG_BITS
371
    /* temporary fixed-point registers
372
     * used to emulate 64 bits target on 32 bits hosts
373
     */
374
    target_ulong t0, t1;
375
#endif
376

    
377
    /* Those resources are used only in Qemu core */
378
    CPU_COMMON
379

    
380
    uint32_t hflags;
381

    
382
    int error_code;
383

    
384
    uint32_t features;
385
    uint32_t amask;
386
    int implver;
387
    pal_handler_t *pal_handler;
388
};
389

    
390
#define cpu_init cpu_alpha_init
391
#define cpu_exec cpu_alpha_exec
392
#define cpu_gen_code cpu_alpha_gen_code
393
#define cpu_signal_handler cpu_alpha_signal_handler
394

    
395
/* MMU modes definitions */
396
#define MMU_MODE0_SUFFIX _kernel
397
#define MMU_MODE1_SUFFIX _executive
398
#define MMU_MODE2_SUFFIX _supervisor
399
#define MMU_MODE3_SUFFIX _user
400
#define MMU_USER_IDX 3
401
static inline int cpu_mmu_index (CPUState *env)
402
{
403
    return (env->ps >> 3) & 3;
404
}
405

    
406
#if defined(CONFIG_USER_ONLY)
407
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
408
{
409
    if (newsp)
410
        env->ir[30] = newsp;
411
    /* FIXME: Zero syscall return value.  */
412
}
413
#endif
414

    
415
#include "cpu-all.h"
416
#include "exec-all.h"
417

    
418
enum {
419
    FEATURE_ASN    = 0x00000001,
420
    FEATURE_SPS    = 0x00000002,
421
    FEATURE_VIRBND = 0x00000004,
422
    FEATURE_TBCHK  = 0x00000008,
423
};
424

    
425
enum {
426
    EXCP_RESET            = 0x0000,
427
    EXCP_MCHK             = 0x0020,
428
    EXCP_ARITH            = 0x0060,
429
    EXCP_HW_INTERRUPT     = 0x00E0,
430
    EXCP_DFAULT           = 0x01E0,
431
    EXCP_DTB_MISS_PAL     = 0x09E0,
432
    EXCP_ITB_MISS         = 0x03E0,
433
    EXCP_ITB_ACV          = 0x07E0,
434
    EXCP_DTB_MISS_NATIVE  = 0x08E0,
435
    EXCP_UNALIGN          = 0x11E0,
436
    EXCP_OPCDEC           = 0x13E0,
437
    EXCP_FEN              = 0x17E0,
438
    EXCP_CALL_PAL         = 0x2000,
439
    EXCP_CALL_PALP        = 0x3000,
440
    EXCP_CALL_PALE        = 0x4000,
441
    /* Pseudo exception for console */
442
    EXCP_CONSOLE_DISPATCH = 0x4001,
443
    EXCP_CONSOLE_FIXUP    = 0x4002,
444
};
445

    
446
/* Arithmetic exception */
447
enum {
448
    EXCP_ARITH_OVERFLOW,
449
};
450

    
451
enum {
452
    IR_V0   = 0,
453
    IR_T0   = 1,
454
    IR_T1   = 2,
455
    IR_T2   = 3,
456
    IR_T3   = 4,
457
    IR_T4   = 5,
458
    IR_T5   = 6,
459
    IR_T6   = 7,
460
    IR_T7   = 8,
461
    IR_S0   = 9,
462
    IR_S1   = 10,
463
    IR_S2   = 11,
464
    IR_S3   = 12,
465
    IR_S4   = 13,
466
    IR_S5   = 14,
467
    IR_S6   = 15,
468
#define IR_FP IR_S6
469
    IR_A0   = 16,
470
    IR_A1   = 17,
471
    IR_A2   = 18,
472
    IR_A3   = 19,
473
    IR_A4   = 20,
474
    IR_A5   = 21,
475
    IR_T8   = 22,
476
    IR_T9   = 23,
477
    IR_T10  = 24,
478
    IR_T11  = 25,
479
    IR_RA   = 26,
480
    IR_T12  = 27,
481
#define IR_PV IR_T12
482
    IR_AT   = 28,
483
    IR_GP   = 29,
484
    IR_SP   = 30,
485
    IR_ZERO = 31,
486
};
487

    
488
CPUAlphaState * cpu_alpha_init (const char *cpu_model);
489
int cpu_alpha_exec(CPUAlphaState *s);
490
/* you can call this signal handler from your SIGBUS and SIGSEGV
491
   signal handlers to inform the virtual CPU of exceptions. non zero
492
   is returned if the signal was handled by the virtual CPU.  */
493
int cpu_alpha_signal_handler(int host_signum, void *pinfo,
494
                             void *puc);
495
int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
496
                                int mmu_idx, int is_softmmu);
497
#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
498
void do_interrupt (CPUState *env);
499

    
500
uint64_t cpu_alpha_load_fpcr (CPUState *env);
501
void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
502
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
503
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
504
void pal_init (CPUState *env);
505
#if !defined (CONFIG_USER_ONLY)
506
void call_pal (CPUState *env);
507
#else
508
void call_pal (CPUState *env, int palcode);
509
#endif
510

    
511
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
512
{
513
    env->pc = tb->pc;
514
}
515

    
516
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
517
                                        target_ulong *cs_base, int *flags)
518
{
519
    *pc = env->pc;
520
    *cs_base = 0;
521
    *flags = env->ps;
522
}
523

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