Fix call_pal() prototype for alpha system emulation
[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., 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__) */