The _exit syscall is used for both thread termination in NPTL applications,
[qemu] / target-alpha / cpu.h
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,
148     IPR_CC_CTL       = 0xC1,
149     IPR_VA           = 0xC2,
150     IPR_VA_CTL       = 0xC4,
151     IPR_VA_FORM      = 0xC3,
152     /* Ibox IPRs */
153     IPR_ITB_TAG      = 0x00,
154     IPR_ITB_PTE      = 0x01,
155     IPT_ITB_IAP      = 0x02,
156     IPT_ITB_IA       = 0x03,
157     IPT_ITB_IS       = 0x04,
158     IPR_PMPC         = 0x05,
159     IPR_EXC_ADDR     = 0x06,
160     IPR_IVA_FORM     = 0x07,
161     IPR_CM           = 0x09,
162     IPR_IER          = 0x0A,
163     IPR_SIRR         = 0x0C,
164     IPR_ISUM         = 0x0D,
165     IPR_HW_INT_CLR   = 0x0E,
166     IPR_EXC_SUM      = 0x0F,
167     IPR_PAL_BASE     = 0x10,
168     IPR_I_CTL        = 0x11,
169     IPR_I_STAT       = 0x16,
170     IPR_IC_FLUSH     = 0x13,
171     IPR_IC_FLUSH_ASM = 0x12,
172     IPR_CLR_MAP      = 0x15,
173     IPR_SLEEP        = 0x17,
174     IPR_PCTX         = 0x40,
175     IPR_PCTR_CTL     = 0x14,
176     /* Mbox IPRs */
177     IPR_DTB_TAG0     = 0x20,
178     IPR_DTB_TAG1     = 0xA0,
179     IPR_DTB_PTE0     = 0x21,
180     IPR_DTB_PTE1     = 0xA1,
181     IPR_DTB_ALTMODE  = 0xA6,
182     IPR_DTB_IAP      = 0xA2,
183     IPR_DTB_IA       = 0xA3,
184     IPR_DTB_IS0      = 0x24,
185     IPR_DTB_IS1      = 0xA4,
186     IPR_DTB_ASN0     = 0x25,
187     IPR_DTB_ASN1     = 0xA5,
188     IPR_MM_STAT      = 0x27,
189     IPR_M_CTL        = 0x28,
190     IPR_DC_CTL       = 0x29,
191     IPR_DC_STAT      = 0x2A,
192     /* Cbox IPRs */
193     IPR_C_DATA       = 0x2B,
194     IPR_C_SHIFT      = 0x2C,
195
196     IPR_ASN,
197     IPR_ASTEN,
198     IPR_ASTSR,
199     IPR_DATFX,
200     IPR_ESP,
201     IPR_FEN,
202     IPR_IPIR,
203     IPR_IPL,
204     IPR_KSP,
205     IPR_MCES,
206     IPR_PERFMON,
207     IPR_PCBB,
208     IPR_PRBR,
209     IPR_PTBR,
210     IPR_SCBB,
211     IPR_SISR,
212     IPR_SSP,
213     IPR_SYSPTBR,
214     IPR_TBCHK,
215     IPR_TBIA,
216     IPR_TBIAP,
217     IPR_TBIS,
218     IPR_TBISD,
219     IPR_TBISI,
220     IPR_USP,
221     IPR_VIRBND,
222     IPR_VPTB,
223     IPR_WHAMI,
224     IPR_ALT_MODE,
225     IPR_LAST,
226 };
227
228 typedef struct CPUAlphaState CPUAlphaState;
229
230 typedef struct pal_handler_t pal_handler_t;
231 struct pal_handler_t {
232     /* Reset */
233     void (*reset)(CPUAlphaState *env);
234     /* Uncorrectable hardware error */
235     void (*machine_check)(CPUAlphaState *env);
236     /* Arithmetic exception */
237     void (*arithmetic)(CPUAlphaState *env);
238     /* Interrupt / correctable hardware error */
239     void (*interrupt)(CPUAlphaState *env);
240     /* Data fault */
241     void (*dfault)(CPUAlphaState *env);
242     /* DTB miss pal */
243     void (*dtb_miss_pal)(CPUAlphaState *env);
244     /* DTB miss native */
245     void (*dtb_miss_native)(CPUAlphaState *env);
246     /* Unaligned access */
247     void (*unalign)(CPUAlphaState *env);
248     /* ITB miss */
249     void (*itb_miss)(CPUAlphaState *env);
250     /* Instruction stream access violation */
251     void (*itb_acv)(CPUAlphaState *env);
252     /* Reserved or privileged opcode */
253     void (*opcdec)(CPUAlphaState *env);
254     /* Floating point exception */
255     void (*fen)(CPUAlphaState *env);
256     /* Call pal instruction */
257     void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
258 };
259
260 #define NB_MMU_MODES 4
261
262 struct CPUAlphaState {
263     uint64_t ir[31];
264     float64  fir[31];
265     float_status fp_status;
266     uint64_t fpcr;
267     uint64_t pc;
268     uint64_t lock;
269     uint32_t pcc[2];
270     uint64_t ipr[IPR_LAST];
271     uint64_t ps;
272     uint64_t unique;
273     int saved_mode; /* Used for HW_LD / HW_ST */
274     int intr_flag; /* For RC and RS */
275
276 #if TARGET_LONG_BITS > HOST_LONG_BITS
277     /* temporary fixed-point registers
278      * used to emulate 64 bits target on 32 bits hosts
279      */
280     target_ulong t0, t1;
281 #endif
282
283     /* Those resources are used only in Qemu core */
284     CPU_COMMON
285
286     uint32_t hflags;
287
288     int error_code;
289
290     uint32_t features;
291     uint32_t amask;
292     int implver;
293     pal_handler_t *pal_handler;
294 };
295
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 #include "exec-all.h"
323
324 enum {
325     FEATURE_ASN    = 0x00000001,
326     FEATURE_SPS    = 0x00000002,
327     FEATURE_VIRBND = 0x00000004,
328     FEATURE_TBCHK  = 0x00000008,
329 };
330
331 enum {
332     EXCP_RESET            = 0x0000,
333     EXCP_MCHK             = 0x0020,
334     EXCP_ARITH            = 0x0060,
335     EXCP_HW_INTERRUPT     = 0x00E0,
336     EXCP_DFAULT           = 0x01E0,
337     EXCP_DTB_MISS_PAL     = 0x09E0,
338     EXCP_ITB_MISS         = 0x03E0,
339     EXCP_ITB_ACV          = 0x07E0,
340     EXCP_DTB_MISS_NATIVE  = 0x08E0,
341     EXCP_UNALIGN          = 0x11E0,
342     EXCP_OPCDEC           = 0x13E0,
343     EXCP_FEN              = 0x17E0,
344     EXCP_CALL_PAL         = 0x2000,
345     EXCP_CALL_PALP        = 0x3000,
346     EXCP_CALL_PALE        = 0x4000,
347     /* Pseudo exception for console */
348     EXCP_CONSOLE_DISPATCH = 0x4001,
349     EXCP_CONSOLE_FIXUP    = 0x4002,
350 };
351
352 /* Arithmetic exception */
353 enum {
354     EXCP_ARITH_OVERFLOW,
355 };
356
357 enum {
358     PALCODE_CALL = 0x00000000,
359     PALCODE_LD   = 0x01000000,
360     PALCODE_ST   = 0x02000000,
361     PALCODE_MFPR = 0x03000000,
362     PALCODE_MTPR = 0x04000000,
363     PALCODE_REI  = 0x05000000,
364     PALCODE_INIT = 0xF0000000,
365 };
366
367 enum {
368     IR_V0   = 0,
369     IR_T0   = 1,
370     IR_T1   = 2,
371     IR_T2   = 3,
372     IR_T3   = 4,
373     IR_T4   = 5,
374     IR_T5   = 6,
375     IR_T6   = 7,
376     IR_T7   = 8,
377     IR_S0   = 9,
378     IR_S1   = 10,
379     IR_S2   = 11,
380     IR_S3   = 12,
381     IR_S4   = 13,
382     IR_S5   = 14,
383     IR_S6   = 15,
384 #define IR_FP IR_S6
385     IR_A0   = 16,
386     IR_A1   = 17,
387     IR_A2   = 18,
388     IR_A3   = 19,
389     IR_A4   = 20,
390     IR_A5   = 21,
391     IR_T8   = 22,
392     IR_T9   = 23,
393     IR_T10  = 24,
394     IR_T11  = 25,
395     IR_RA   = 26,
396     IR_T12  = 27,
397 #define IR_PV IR_T12
398     IR_AT   = 28,
399     IR_GP   = 29,
400     IR_SP   = 30,
401     IR_ZERO = 31,
402 };
403
404 CPUAlphaState * cpu_alpha_init (const char *cpu_model);
405 int cpu_alpha_exec(CPUAlphaState *s);
406 /* you can call this signal handler from your SIGBUS and SIGSEGV
407    signal handlers to inform the virtual CPU of exceptions. non zero
408    is returned if the signal was handled by the virtual CPU.  */
409 int cpu_alpha_signal_handler(int host_signum, void *pinfo,
410                              void *puc);
411 int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
412                                 int mmu_idx, int is_softmmu);
413 void do_interrupt (CPUState *env);
414
415 int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
416 int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
417 void pal_init (CPUState *env);
418 #if !defined (CONFIG_USER_ONLY)
419 void call_pal (CPUState *env);
420 #else
421 void call_pal (CPUState *env, int palcode);
422 #endif
423
424 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
425 {
426     env->pc = tb->pc;
427 }
428
429 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
430                                         target_ulong *cs_base, int *flags)
431 {
432     *pc = env->pc;
433     *cs_base = 0;
434     *flags = env->ps;
435 }
436
437 #endif /* !defined (__CPU_ALPHA_H__) */