Statistics
| Branch: | Revision:

root / target-alpha / cpu.h @ f8cc8534

History | View | Annotate | Download (12.2 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, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
19
 */
20

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

    
24
#include "config.h"
25

    
26
#define TARGET_LONG_BITS 64
27

    
28
#define CPUState struct CPUAlphaState
29

    
30
#include "cpu-defs.h"
31

    
32
#include <setjmp.h>
33

    
34
#include "softfloat.h"
35

    
36
#define TARGET_HAS_ICE 1
37

    
38
#define ELF_MACHINE     EM_ALPHA
39

    
40
#define ICACHE_LINE_SIZE 32
41
#define DCACHE_LINE_SIZE 32
42

    
43
#define TARGET_PAGE_BITS 12
44

    
45
#define VA_BITS 43
46

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

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

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

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

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

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

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

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

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

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

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

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

    
143
/* Internal processor registers */
144
/* XXX: TOFIX: most of those registers are implementation dependant */
145
enum {
146
    /* Ebox IPRs */
147
    IPR_CC           = 0xC0,            /* 21264 */
148
    IPR_CC_CTL       = 0xC1,            /* 21264 */
149
#define IPR_CC_CTL_ENA_SHIFT 32
150
#define IPR_CC_CTL_COUNTER_MASK 0xfffffff0UL
151
    IPR_VA           = 0xC2,            /* 21264 */
152
    IPR_VA_CTL       = 0xC4,            /* 21264 */
153
#define IPR_VA_CTL_VA_48_SHIFT 1
154
#define IPR_VA_CTL_VPTB_SHIFT 30
155
    IPR_VA_FORM      = 0xC3,            /* 21264 */
156
    /* Ibox IPRs */
157
    IPR_ITB_TAG      = 0x00,            /* 21264 */
158
    IPR_ITB_PTE      = 0x01,            /* 21264 */
159
    IPR_ITB_IAP      = 0x02,
160
    IPR_ITB_IA       = 0x03,            /* 21264 */
161
    IPR_ITB_IS       = 0x04,
162
    IPR_PMPC         = 0x05,
163
    IPR_EXC_ADDR     = 0x06,            /* 21264 */
164
    IPR_IVA_FORM     = 0x07,            /* 21264 */
165
    IPR_CM           = 0x09,            /* 21264 */
166
#define IPR_CM_SHIFT 3
167
#define IPR_CM_MASK (3ULL << IPR_CM_SHIFT)      /* 21264 */
168
    IPR_IER          = 0x0A,            /* 21264 */
169
#define IPR_IER_MASK 0x0000007fffffe000ULL
170
    IPR_IER_CM       = 0x0B,            /* 21264: = CM | IER */
171
    IPR_SIRR         = 0x0C,            /* 21264 */
172
#define IPR_SIRR_SHIFT 14
173
#define IPR_SIRR_MASK 0x7fff
174
    IPR_ISUM         = 0x0D,            /* 21264 */
175
    IPR_HW_INT_CLR   = 0x0E,            /* 21264 */
176
    IPR_EXC_SUM      = 0x0F,
177
    IPR_PAL_BASE     = 0x10,
178
    IPR_I_CTL        = 0x11,
179
#define IPR_I_CTL_CHIP_ID_SHIFT 24      /* 21264 */
180
#define IPR_I_CTL_BIST_FAIL (1 << 23)   /* 21264 */
181
#define IPR_I_CTL_IC_EN_SHIFT 2         /* 21264 */
182
#define IPR_I_CTL_SDE1_SHIFT 7          /* 21264 */
183
#define IPR_I_CTL_HWE_SHIFT 12          /* 21264 */
184
#define IPR_I_CTL_VA_48_SHIFT 15        /* 21264 */
185
#define IPR_I_CTL_SPE_SHIFT 3           /* 21264 */
186
#define IPR_I_CTL_CALL_PAL_R23_SHIFT 20 /* 21264 */
187
    IPR_I_STAT       = 0x16,            /* 21264 */
188
    IPR_IC_FLUSH     = 0x13,            /* 21264 */
189
    IPR_IC_FLUSH_ASM = 0x12,            /* 21264 */
190
    IPR_CLR_MAP      = 0x15,
191
    IPR_SLEEP        = 0x17,
192
    IPR_PCTX         = 0x40,
193
    IPR_PCTX_ASN       = 0x01,  /* field */
194
#define IPR_PCTX_ASN_SHIFT 39
195
    IPR_PCTX_ASTER     = 0x02,  /* field */
196
#define IPR_PCTX_ASTER_SHIFT 5
197
    IPR_PCTX_ASTRR     = 0x04,  /* field */
198
#define IPR_PCTX_ASTRR_SHIFT 9
199
    IPR_PCTX_PPCE      = 0x08,  /* field */
200
#define IPR_PCTX_PPCE_SHIFT 1
201
    IPR_PCTX_FPE       = 0x10,  /* field */
202
#define IPR_PCTX_FPE_SHIFT 2
203
    IPR_PCTX_ALL       = 0x5f,  /* all fields */
204
    IPR_PCTR_CTL     = 0x14,            /* 21264 */
205
    /* Mbox IPRs */
206
    IPR_DTB_TAG0     = 0x20,            /* 21264 */
207
    IPR_DTB_TAG1     = 0xA0,            /* 21264 */
208
    IPR_DTB_PTE0     = 0x21,            /* 21264 */
209
    IPR_DTB_PTE1     = 0xA1,            /* 21264 */
210
    IPR_DTB_ALTMODE  = 0xA6,
211
    IPR_DTB_ALTMODE0 = 0x26,            /* 21264 */
212
#define IPR_DTB_ALTMODE_MASK 3
213
    IPR_DTB_IAP      = 0xA2,
214
    IPR_DTB_IA       = 0xA3,            /* 21264 */
215
    IPR_DTB_IS0      = 0x24,
216
    IPR_DTB_IS1      = 0xA4,
217
    IPR_DTB_ASN0     = 0x25,            /* 21264 */
218
    IPR_DTB_ASN1     = 0xA5,            /* 21264 */
219
#define IPR_DTB_ASN_SHIFT 56
220
    IPR_MM_STAT      = 0x27,            /* 21264 */
221
    IPR_M_CTL        = 0x28,            /* 21264 */
222
#define IPR_M_CTL_SPE_SHIFT 1
223
#define IPR_M_CTL_SPE_MASK 7
224
    IPR_DC_CTL       = 0x29,
225
    IPR_DC_STAT      = 0x2A,            /* 21264 */
226
    /* Cbox IPRs */
227
    IPR_C_DATA       = 0x2B,
228
    IPR_C_SHIFT      = 0x2C,
229

    
230
    IPR_ASN,
231
    IPR_ASTEN,
232
    IPR_ASTSR,
233
    IPR_DATFX,
234
    IPR_ESP,
235
    IPR_FEN,
236
    IPR_IPIR,
237
    IPR_IPL,
238
    IPR_KSP,
239
    IPR_MCES,
240
    IPR_PERFMON,
241
    IPR_PCBB,
242
    IPR_PRBR,
243
    IPR_PTBR,
244
    IPR_SCBB,
245
    IPR_SISR,
246
    IPR_SSP,
247
    IPR_SYSPTBR,
248
    IPR_TBCHK,
249
    IPR_TBIA,
250
    IPR_TBIAP,
251
    IPR_TBIS,
252
    IPR_TBISD,
253
    IPR_TBISI,
254
    IPR_USP,
255
    IPR_VIRBND,
256
    IPR_VPTB,
257
    IPR_WHAMI,
258
    IPR_ALT_MODE,
259
    IPR_LAST,
260
};
261

    
262
typedef struct CPUAlphaState CPUAlphaState;
263

    
264
typedef struct pal_handler_t pal_handler_t;
265
struct pal_handler_t {
266
    /* Reset */
267
    void (*reset)(CPUAlphaState *env);
268
    /* Uncorrectable hardware error */
269
    void (*machine_check)(CPUAlphaState *env);
270
    /* Arithmetic exception */
271
    void (*arithmetic)(CPUAlphaState *env);
272
    /* Interrupt / correctable hardware error */
273
    void (*interrupt)(CPUAlphaState *env);
274
    /* Data fault */
275
    void (*dfault)(CPUAlphaState *env);
276
    /* DTB miss pal */
277
    void (*dtb_miss_pal)(CPUAlphaState *env);
278
    /* DTB miss native */
279
    void (*dtb_miss_native)(CPUAlphaState *env);
280
    /* Unaligned access */
281
    void (*unalign)(CPUAlphaState *env);
282
    /* ITB miss */
283
    void (*itb_miss)(CPUAlphaState *env);
284
    /* Instruction stream access violation */
285
    void (*itb_acv)(CPUAlphaState *env);
286
    /* Reserved or privileged opcode */
287
    void (*opcdec)(CPUAlphaState *env);
288
    /* Floating point exception */
289
    void (*fen)(CPUAlphaState *env);
290
    /* Call pal instruction */
291
    void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
292
};
293

    
294
#define NB_MMU_MODES 4
295

    
296
struct CPUAlphaState {
297
    uint64_t ir[31];
298
    float64  fir[31];
299
    float_status fp_status;
300
    uint64_t fpcr;
301
    uint64_t pc;
302
    uint64_t lock;
303
    uint32_t pcc[2];
304
    uint64_t ipr[IPR_LAST];
305
    uint64_t ps;
306
    uint64_t unique;
307
    int saved_mode; /* Used for HW_LD / HW_ST */
308
    int intr_flag; /* For RC and RS */
309

    
310
#if TARGET_LONG_BITS > HOST_LONG_BITS
311
    /* temporary fixed-point registers
312
     * used to emulate 64 bits target on 32 bits hosts
313
     */
314
    target_ulong t0, t1;
315
#endif
316

    
317
    /* Those resources are used only in Qemu core */
318
    CPU_COMMON
319

    
320
    uint32_t hflags;
321

    
322
    int error_code;
323

    
324
    uint32_t features;
325
    uint32_t amask;
326
    int implver;
327
    pal_handler_t *pal_handler;
328
};
329

    
330
#define cpu_init cpu_alpha_init
331
#define cpu_exec cpu_alpha_exec
332
#define cpu_gen_code cpu_alpha_gen_code
333
#define cpu_signal_handler cpu_alpha_signal_handler
334

    
335
/* MMU modes definitions */
336
#define MMU_MODE0_SUFFIX _kernel
337
#define MMU_MODE1_SUFFIX _executive
338
#define MMU_MODE2_SUFFIX _supervisor
339
#define MMU_MODE3_SUFFIX _user
340
#define MMU_USER_IDX 3
341
static inline int cpu_mmu_index (CPUState *env)
342
{
343
    return (env->ps >> 3) & 3;
344
}
345

    
346
#if defined(CONFIG_USER_ONLY)
347
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
348
{
349
    if (newsp)
350
        env->ir[30] = newsp;
351
    /* FIXME: Zero syscall return value.  */
352
}
353
#endif
354

    
355
#include "cpu-all.h"
356
#include "exec-all.h"
357

    
358
enum {
359
    FEATURE_ASN    = 0x00000001,
360
    FEATURE_SPS    = 0x00000002,
361
    FEATURE_VIRBND = 0x00000004,
362
    FEATURE_TBCHK  = 0x00000008,
363
};
364

    
365
enum {
366
    EXCP_RESET            = 0x0000,
367
    EXCP_MCHK             = 0x0020,
368
    EXCP_ARITH            = 0x0060,
369
    EXCP_HW_INTERRUPT     = 0x00E0,
370
    EXCP_DFAULT           = 0x01E0,
371
    EXCP_DTB_MISS_PAL     = 0x09E0,
372
    EXCP_ITB_MISS         = 0x03E0,
373
    EXCP_ITB_ACV          = 0x07E0,
374
    EXCP_DTB_MISS_NATIVE  = 0x08E0,
375
    EXCP_UNALIGN          = 0x11E0,
376
    EXCP_OPCDEC           = 0x13E0,
377
    EXCP_FEN              = 0x17E0,
378
    EXCP_CALL_PAL         = 0x2000,
379
    EXCP_CALL_PALP        = 0x3000,
380
    EXCP_CALL_PALE        = 0x4000,
381
    /* Pseudo exception for console */
382
    EXCP_CONSOLE_DISPATCH = 0x4001,
383
    EXCP_CONSOLE_FIXUP    = 0x4002,
384
};
385

    
386
/* Arithmetic exception */
387
enum {
388
    EXCP_ARITH_OVERFLOW,
389
};
390

    
391
enum {
392
    PALCODE_CALL = 0x00000000,
393
    PALCODE_LD   = 0x01000000,
394
    PALCODE_ST   = 0x02000000,
395
    PALCODE_MFPR = 0x03000000,
396
    PALCODE_MTPR = 0x04000000,
397
    PALCODE_REI  = 0x05000000,
398
    PALCODE_INIT = 0xF0000000,
399
};
400

    
401
enum {
402
    IR_V0   = 0,
403
    IR_T0   = 1,
404
    IR_T1   = 2,
405
    IR_T2   = 3,
406
    IR_T3   = 4,
407
    IR_T4   = 5,
408
    IR_T5   = 6,
409
    IR_T6   = 7,
410
    IR_T7   = 8,
411
    IR_S0   = 9,
412
    IR_S1   = 10,
413
    IR_S2   = 11,
414
    IR_S3   = 12,
415
    IR_S4   = 13,
416
    IR_S5   = 14,
417
    IR_S6   = 15,
418
#define IR_FP IR_S6
419
    IR_A0   = 16,
420
    IR_A1   = 17,
421
    IR_A2   = 18,
422
    IR_A3   = 19,
423
    IR_A4   = 20,
424
    IR_A5   = 21,
425
    IR_T8   = 22,
426
    IR_T9   = 23,
427
    IR_T10  = 24,
428
    IR_T11  = 25,
429
    IR_RA   = 26,
430
    IR_T12  = 27,
431
#define IR_PV IR_T12
432
    IR_AT   = 28,
433
    IR_GP   = 29,
434
    IR_SP   = 30,
435
    IR_ZERO = 31,
436
};
437

    
438
CPUAlphaState * cpu_alpha_init (const char *cpu_model);
439
int cpu_alpha_exec(CPUAlphaState *s);
440
/* you can call this signal handler from your SIGBUS and SIGSEGV
441
   signal handlers to inform the virtual CPU of exceptions. non zero
442
   is returned if the signal was handled by the virtual CPU.  */
443
int cpu_alpha_signal_handler(int host_signum, void *pinfo,
444
                             void *puc);
445
int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
446
                                int mmu_idx, int is_softmmu);
447
void do_interrupt (CPUState *env);
448

    
449
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
450
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
451
void pal_init (CPUState *env);
452
#if !defined (CONFIG_USER_ONLY)
453
void call_pal (CPUState *env);
454
#else
455
void call_pal (CPUState *env, int palcode);
456
#endif
457

    
458
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
459
{
460
    env->pc = tb->pc;
461
}
462

    
463
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
464
                                        target_ulong *cs_base, int *flags)
465
{
466
    *pc = env->pc;
467
    *cs_base = 0;
468
    *flags = env->ps;
469
}
470

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