Statistics
| Branch: | Revision:

root / target-alpha / cpu.h @ 7c9bde45

History | View | Annotate | Download (9.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, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
#include "cpu-defs.h"
29

    
30
#include <setjmp.h>
31

    
32
#include "softfloat.h"
33

    
34
#define TARGET_HAS_ICE 1
35

    
36
#define ELF_MACHINE     EM_ALPHA
37

    
38
#define ICACHE_LINE_SIZE 32
39
#define DCACHE_LINE_SIZE 32
40

    
41
#define TARGET_PAGE_BITS 12
42

    
43
#define VA_BITS 43
44

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

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

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

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

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

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

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

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

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

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

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

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

    
141
/* Internal processor registers */
142
/* XXX: TOFIX: most of those registers are implementation dependant */
143
enum {
144
    /* Ebox IPRs */
145
    IPR_CC           = 0xC0,
146
    IPR_CC_CTL       = 0xC1,
147
    IPR_VA           = 0xC2,
148
    IPR_VA_CTL       = 0xC4,
149
    IPR_VA_FORM      = 0xC3,
150
    /* Ibox IPRs */
151
    IPR_ITB_TAG      = 0x00,
152
    IPR_ITB_PTE      = 0x01,
153
    IPT_ITB_IAP      = 0x02,
154
    IPT_ITB_IA       = 0x03,
155
    IPT_ITB_IS       = 0x04,
156
    IPR_PMPC         = 0x05,
157
    IPR_EXC_ADDR     = 0x06,
158
    IPR_IVA_FORM     = 0x07,
159
    IPR_CM           = 0x09,
160
    IPR_IER          = 0x0A,
161
    IPR_SIRR         = 0x0C,
162
    IPR_ISUM         = 0x0D,
163
    IPR_HW_INT_CLR   = 0x0E,
164
    IPR_EXC_SUM      = 0x0F,
165
    IPR_PAL_BASE     = 0x10,
166
    IPR_I_CTL        = 0x11,
167
    IPR_I_STAT       = 0x16,
168
    IPR_IC_FLUSH     = 0x13,
169
    IPR_IC_FLUSH_ASM = 0x12,
170
    IPR_CLR_MAP      = 0x15,
171
    IPR_SLEEP        = 0x17,
172
    IPR_PCTX         = 0x40,
173
    IPR_PCTR_CTL     = 0x14,
174
    /* Mbox IPRs */
175
    IPR_DTB_TAG0     = 0x20,
176
    IPR_DTB_TAG1     = 0xA0,
177
    IPR_DTB_PTE0     = 0x21,
178
    IPR_DTB_PTE1     = 0xA1,
179
    IPR_DTB_ALTMODE  = 0xA6,
180
    IPR_DTB_IAP      = 0xA2,
181
    IPR_DTB_IA       = 0xA3,
182
    IPR_DTB_IS0      = 0x24,
183
    IPR_DTB_IS1      = 0xA4,
184
    IPR_DTB_ASN0     = 0x25,
185
    IPR_DTB_ASN1     = 0xA5,
186
    IPR_MM_STAT      = 0x27,
187
    IPR_M_CTL        = 0x28,
188
    IPR_DC_CTL       = 0x29,
189
    IPR_DC_STAT      = 0x2A,
190
    /* Cbox IPRs */
191
    IPR_C_DATA       = 0x2B,
192
    IPR_C_SHIFT      = 0x2C,
193

    
194
    IPR_ASN,
195
    IPR_ASTEN,
196
    IPR_ASTSR,
197
    IPR_DATFX,
198
    IPR_ESP,
199
    IPR_FEN,
200
    IPR_IPIR,
201
    IPR_IPL,
202
    IPR_KSP,
203
    IPR_MCES,
204
    IPR_PERFMON,
205
    IPR_PCBB,
206
    IPR_PRBR,
207
    IPR_PTBR,
208
    IPR_SCBB,
209
    IPR_SISR,
210
    IPR_SSP,
211
    IPR_SYSPTBR,
212
    IPR_TBCHK,
213
    IPR_TBIA,
214
    IPR_TBIAP,
215
    IPR_TBIS,
216
    IPR_TBISD,
217
    IPR_TBISI,
218
    IPR_USP,
219
    IPR_VIRBND,
220
    IPR_VPTB,
221
    IPR_WHAMI,
222
    IPR_ALT_MODE,
223
    IPR_LAST,
224
};
225

    
226
typedef struct CPUAlphaState CPUAlphaState;
227

    
228
typedef struct pal_handler_t pal_handler_t;
229
struct pal_handler_t {
230
    /* Reset */
231
    void (*reset)(CPUAlphaState *env);
232
    /* Uncorrectable hardware error */
233
    void (*machine_check)(CPUAlphaState *env);
234
    /* Arithmetic exception */
235
    void (*arithmetic)(CPUAlphaState *env);
236
    /* Interrupt / correctable hardware error */
237
    void (*interrupt)(CPUAlphaState *env);
238
    /* Data fault */
239
    void (*dfault)(CPUAlphaState *env);
240
    /* DTB miss pal */
241
    void (*dtb_miss_pal)(CPUAlphaState *env);
242
    /* DTB miss native */
243
    void (*dtb_miss_native)(CPUAlphaState *env);
244
    /* Unaligned access */
245
    void (*unalign)(CPUAlphaState *env);
246
    /* ITB miss */
247
    void (*itb_miss)(CPUAlphaState *env);
248
    /* Instruction stream access violation */
249
    void (*itb_acv)(CPUAlphaState *env);
250
    /* Reserved or privileged opcode */
251
    void (*opcdec)(CPUAlphaState *env);
252
    /* Floating point exception */
253
    void (*fen)(CPUAlphaState *env);
254
    /* Call pal instruction */
255
    void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
256
};
257

    
258
#define NB_MMU_MODES 4
259

    
260
struct CPUAlphaState {
261
    uint64_t ir[31];
262
    float64  fir[31];
263
    float_status fp_status;
264
    uint64_t fpcr;
265
    uint64_t pc;
266
    uint64_t lock;
267
    uint32_t pcc[2];
268
    uint64_t ipr[IPR_LAST];
269
    uint64_t ps;
270
    uint64_t unique;
271
    int saved_mode; /* Used for HW_LD / HW_ST */
272

    
273
#if TARGET_LONG_BITS > HOST_LONG_BITS
274
    /* temporary fixed-point registers
275
     * used to emulate 64 bits target on 32 bits hosts
276
     */
277
    target_ulong t0, t1, t2;
278
#endif
279
    /* */
280
    double ft0, ft1, ft2;
281

    
282
    /* Those resources are used only in Qemu core */
283
    CPU_COMMON
284

    
285
    uint32_t hflags;
286

    
287
    int error_code;
288

    
289
    uint32_t features;
290
    uint32_t amask;
291
    int implver;
292
    pal_handler_t *pal_handler;
293
};
294

    
295
#define CPUState CPUAlphaState
296
#define cpu_init cpu_alpha_init
297
#define cpu_exec cpu_alpha_exec
298
#define cpu_gen_code cpu_alpha_gen_code
299
#define cpu_signal_handler cpu_alpha_signal_handler
300

    
301
/* MMU modes definitions */
302
#define MMU_MODE0_SUFFIX _kernel
303
#define MMU_MODE1_SUFFIX _executive
304
#define MMU_MODE2_SUFFIX _supervisor
305
#define MMU_MODE3_SUFFIX _user
306
#define MMU_USER_IDX 3
307
static inline int cpu_mmu_index (CPUState *env)
308
{
309
    return (env->ps >> 3) & 3;
310
}
311

    
312
#if defined(CONFIG_USER_ONLY)
313
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
314
{
315
    if (newsp)
316
        env->ir[30] = newsp;
317
    /* FIXME: Zero syscall return value.  */
318
}
319
#endif
320

    
321
#include "cpu-all.h"
322

    
323
enum {
324
    FEATURE_ASN    = 0x00000001,
325
    FEATURE_SPS    = 0x00000002,
326
    FEATURE_VIRBND = 0x00000004,
327
    FEATURE_TBCHK  = 0x00000008,
328
};
329

    
330
enum {
331
    EXCP_RESET            = 0x0000,
332
    EXCP_MCHK             = 0x0020,
333
    EXCP_ARITH            = 0x0060,
334
    EXCP_HW_INTERRUPT     = 0x00E0,
335
    EXCP_DFAULT           = 0x01E0,
336
    EXCP_DTB_MISS_PAL     = 0x09E0,
337
    EXCP_ITB_MISS         = 0x03E0,
338
    EXCP_ITB_ACV          = 0x07E0,
339
    EXCP_DTB_MISS_NATIVE  = 0x08E0,
340
    EXCP_UNALIGN          = 0x11E0,
341
    EXCP_OPCDEC           = 0x13E0,
342
    EXCP_FEN              = 0x17E0,
343
    EXCP_CALL_PAL         = 0x2000,
344
    EXCP_CALL_PALP        = 0x3000,
345
    EXCP_CALL_PALE        = 0x4000,
346
    /* Pseudo exception for console */
347
    EXCP_CONSOLE_DISPATCH = 0x4001,
348
    EXCP_CONSOLE_FIXUP    = 0x4002,
349
};
350

    
351
/* Arithmetic exception */
352
enum {
353
    EXCP_ARITH_OVERFLOW,
354
};
355

    
356
enum {
357
    PALCODE_CALL = 0x00000000,
358
    PALCODE_LD   = 0x01000000,
359
    PALCODE_ST   = 0x02000000,
360
    PALCODE_MFPR = 0x03000000,
361
    PALCODE_MTPR = 0x04000000,
362
    PALCODE_REI  = 0x05000000,
363
    PALCODE_INIT = 0xF0000000,
364
};
365

    
366
enum {
367
    IR_V0   = 0,
368
    IR_T0   = 1,
369
    IR_T1   = 2,
370
    IR_T2   = 3,
371
    IR_T3   = 4,
372
    IR_T4   = 5,
373
    IR_T5   = 6,
374
    IR_T6   = 7,
375
    IR_T7   = 8,
376
    IR_S0   = 9,
377
    IR_S1   = 10,
378
    IR_S2   = 11,
379
    IR_S3   = 12,
380
    IR_S4   = 13,
381
    IR_S5   = 14,
382
    IR_S6   = 15,
383
#define IR_FP IR_S6
384
    IR_A0   = 16,
385
    IR_A1   = 17,
386
    IR_A2   = 18,
387
    IR_A3   = 19,
388
    IR_A4   = 20,
389
    IR_A5   = 21,
390
    IR_T8   = 22,
391
    IR_T9   = 23,
392
    IR_T10  = 24,
393
    IR_T11  = 25,
394
    IR_RA   = 26,
395
    IR_T12  = 27,
396
#define IR_PV IR_T12
397
    IR_AT   = 28,
398
    IR_GP   = 29,
399
    IR_SP   = 30,
400
    IR_ZERO = 31,
401
};
402

    
403
CPUAlphaState * cpu_alpha_init (const char *cpu_model);
404
int cpu_alpha_exec(CPUAlphaState *s);
405
/* you can call this signal handler from your SIGBUS and SIGSEGV
406
   signal handlers to inform the virtual CPU of exceptions. non zero
407
   is returned if the signal was handled by the virtual CPU.  */
408
int cpu_alpha_signal_handler(int host_signum, void *pinfo,
409
                             void *puc);
410
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
411
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
412
void cpu_loop_exit (void);
413
void pal_init (CPUState *env);
414
#if !defined (CONFIG_USER_ONLY)
415
void call_pal (CPUState *env);
416
#else
417
void call_pal (CPUState *env, int palcode);
418
#endif
419

    
420
#define CPU_PC_FROM_TB(env, tb) env->pc = tb->pc
421

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