Alpha architecture emulation core.
[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
31 #include <setjmp.h>
32
33 #include "softfloat.h"
34
35 /* XXX: put this in a common place */
36 #define likely(x)   __builtin_expect(!!(x), 1)
37 #define unlikely(x)   __builtin_expect(!!(x), 0)
38
39 #define TARGET_HAS_ICE 1
40
41 #define ELF_MACHINE     EM_ALPHA
42
43 #define ICACHE_LINE_SIZE 32
44 #define DCACHE_LINE_SIZE 32
45
46 #define TARGET_PAGE_BITS 12
47
48 #define VA_BITS 43
49
50 /* Alpha major type */
51 enum {
52     ALPHA_EV3  = 1,
53     ALPHA_EV4  = 2,
54     ALPHA_SIM  = 3,
55     ALPHA_LCA  = 4,
56     ALPHA_EV5  = 5, /* 21164 */
57     ALPHA_EV45 = 6, /* 21064A */
58     ALPHA_EV56 = 7, /* 21164A */
59 };
60
61 /* EV4 minor type */
62 enum {
63     ALPHA_EV4_2 = 0,
64     ALPHA_EV4_3 = 1,
65 };
66
67 /* LCA minor type */
68 enum {
69     ALPHA_LCA_1 = 1, /* 21066 */
70     ALPHA_LCA_2 = 2, /* 20166 */
71     ALPHA_LCA_3 = 3, /* 21068 */
72     ALPHA_LCA_4 = 4, /* 21068 */
73     ALPHA_LCA_5 = 5, /* 21066A */
74     ALPHA_LCA_6 = 6, /* 21068A */
75 };
76
77 /* EV5 minor type */
78 enum {
79     ALPHA_EV5_1 = 1, /* Rev BA, CA */
80     ALPHA_EV5_2 = 2, /* Rev DA, EA */
81     ALPHA_EV5_3 = 3, /* Pass 3 */
82     ALPHA_EV5_4 = 4, /* Pass 3.2 */
83     ALPHA_EV5_5 = 5, /* Pass 4 */
84 };
85
86 /* EV45 minor type */
87 enum {
88     ALPHA_EV45_1 = 1, /* Pass 1 */
89     ALPHA_EV45_2 = 2, /* Pass 1.1 */
90     ALPHA_EV45_3 = 3, /* Pass 2 */
91 };
92
93 /* EV56 minor type */
94 enum {
95     ALPHA_EV56_1 = 1, /* Pass 1 */
96     ALPHA_EV56_2 = 2, /* Pass 2 */
97 };
98
99 enum {
100     IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */
101     IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */
102     IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */
103     IMPLVER_21364 = 3, /* EV7 & EV79 */
104 };
105
106 enum {
107     AMASK_BWX      = 0x00000001,
108     AMASK_FIX      = 0x00000002,
109     AMASK_CIX      = 0x00000004,
110     AMASK_MVI      = 0x00000100,
111     AMASK_TRAP     = 0x00000200,
112     AMASK_PREFETCH = 0x00001000,
113 };
114
115 enum {
116     VAX_ROUND_NORMAL = 0,
117     VAX_ROUND_CHOPPED,
118 };
119
120 enum {
121     IEEE_ROUND_NORMAL = 0,
122     IEEE_ROUND_DYNAMIC,
123     IEEE_ROUND_PLUS,
124     IEEE_ROUND_MINUS,
125     IEEE_ROUND_CHOPPED,
126 };
127
128 /* IEEE floating-point operations encoding */
129 /* Trap mode */
130 enum {
131     FP_TRAP_I   = 0x0,
132     FP_TRAP_U   = 0x1,
133     FP_TRAP_S  = 0x4,
134     FP_TRAP_SU  = 0x5,
135     FP_TRAP_SUI = 0x7,
136 };
137
138 /* Rounding mode */
139 enum {
140     FP_ROUND_CHOPPED = 0x0,
141     FP_ROUND_MINUS   = 0x1,
142     FP_ROUND_NORMAL  = 0x2,
143     FP_ROUND_DYNAMIC = 0x3,
144 };
145
146 /* Internal processor registers */
147 /* XXX: TOFIX: most of those registers are implementation dependant */
148 enum {
149     /* Ebox IPRs */
150     IPR_CC           = 0xC0,
151     IPR_CC_CTL       = 0xC1,
152     IPR_VA           = 0xC2,
153     IPR_VA_CTL       = 0xC4,
154     IPR_VA_FORM      = 0xC3,
155     /* Ibox IPRs */
156     IPR_ITB_TAG      = 0x00,
157     IPR_ITB_PTE      = 0x01,
158     IPT_ITB_IAP      = 0x02,
159     IPT_ITB_IA       = 0x03,
160     IPT_ITB_IS       = 0x04,
161     IPR_PMPC         = 0x05,
162     IPR_EXC_ADDR     = 0x06,
163     IPR_IVA_FORM     = 0x07,
164     IPR_CM           = 0x09,
165     IPR_IER          = 0x0A,
166     IPR_SIRR         = 0x0C,
167     IPR_ISUM         = 0x0D,
168     IPR_HW_INT_CLR   = 0x0E,
169     IPR_EXC_SUM      = 0x0F,
170     IPR_PAL_BASE     = 0x10,
171     IPR_I_CTL        = 0x11,
172     IPR_I_STAT       = 0x16,
173     IPR_IC_FLUSH     = 0x13,
174     IPR_IC_FLUSH_ASM = 0x12,
175     IPR_CLR_MAP      = 0x15,
176     IPR_SLEEP        = 0x17,
177     IPR_PCTX         = 0x40,
178     IPR_PCTR_CTL     = 0x14,
179     /* Mbox IPRs */
180     IPR_DTB_TAG0     = 0x20,
181     IPR_DTB_TAG1     = 0xA0,
182     IPR_DTB_PTE0     = 0x21,
183     IPR_DTB_PTE1     = 0xA1,
184     IPR_DTB_ALTMODE  = 0xA6,
185     IPR_DTB_IAP      = 0xA2,
186     IPR_DTB_IA       = 0xA3,
187     IPR_DTB_IS0      = 0x24,
188     IPR_DTB_IS1      = 0xA4,
189     IPR_DTB_ASN0     = 0x25,
190     IPR_DTB_ASN1     = 0xA5,
191     IPR_MM_STAT      = 0x27,
192     IPR_M_CTL        = 0x28,
193     IPR_DC_CTL       = 0x29,
194     IPR_DC_STAT      = 0x2A,
195     /* Cbox IPRs */
196     IPR_C_DATA       = 0x2B,
197     IPR_C_SHIFT      = 0x2C,
198
199     IPR_ASN,
200     IPR_ASTEN,
201     IPR_ASTSR,
202     IPR_DATFX,
203     IPR_ESP,
204     IPR_FEN,
205     IPR_IPIR,
206     IPR_IPL,
207     IPR_KSP,
208     IPR_MCES,
209     IPR_PERFMON,
210     IPR_PCBB,
211     IPR_PRBR,
212     IPR_PTBR,
213     IPR_SCBB,
214     IPR_SISR,
215     IPR_SSP,
216     IPR_SYSPTBR,
217     IPR_TBCHK,
218     IPR_TBIA,
219     IPR_TBIAP,
220     IPR_TBIS,
221     IPR_TBISD,
222     IPR_TBISI,
223     IPR_USP,
224     IPR_VIRBND,
225     IPR_VPTB,
226     IPR_WHAMI,
227     IPR_ALT_MODE,
228     IPR_LAST,
229 };
230
231 typedef struct CPUAlphaState CPUAlphaState;
232
233 typedef struct pal_handler_t pal_handler_t;
234 struct pal_handler_t {
235     /* Reset */
236     void (*reset)(CPUAlphaState *env);
237     /* Uncorrectable hardware error */
238     void (*machine_check)(CPUAlphaState *env);
239     /* Arithmetic exception */
240     void (*arithmetic)(CPUAlphaState *env);
241     /* Interrupt / correctable hardware error */
242     void (*interrupt)(CPUAlphaState *env);
243     /* Data fault */
244     void (*dfault)(CPUAlphaState *env);
245     /* DTB miss pal */
246     void (*dtb_miss_pal)(CPUAlphaState *env);
247     /* DTB miss native */
248     void (*dtb_miss_native)(CPUAlphaState *env);
249     /* Unaligned access */
250     void (*unalign)(CPUAlphaState *env);
251     /* ITB miss */
252     void (*itb_miss)(CPUAlphaState *env);
253     /* Instruction stream access violation */
254     void (*itb_acv)(CPUAlphaState *env);
255     /* Reserved or privileged opcode */
256     void (*opcdec)(CPUAlphaState *env);
257     /* Floating point exception */
258     void (*fen)(CPUAlphaState *env);
259     /* Call pal instruction */
260     void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
261 };
262
263 struct CPUAlphaState {
264     uint64_t ir[31];
265     float64  fir[31];
266     float_status fp_status;
267     uint64_t fpcr;
268     uint64_t pc;
269     uint64_t lock;
270     uint32_t pcc[2];
271     uint64_t ipr[IPR_LAST];
272     uint64_t ps;
273     uint64_t unique;
274     int saved_mode; /* Used for HW_LD / HW_ST */
275
276     /* */
277     double ft0, ft1, ft2;
278
279     /* Those resources are used only in Qemu core */
280     CPU_COMMON
281
282     jmp_buf jmp_env;
283     int user_mode_only; /* user mode only simulation */
284     uint32_t hflags;
285     int halted;
286
287     int exception_index;
288     int error_code;
289     int interrupt_request;
290
291     uint32_t features;
292     uint32_t amask;
293     int implver;
294     pal_handler_t *pal_handler;
295 };
296
297 #include "cpu-all.h"
298
299 enum {
300     FEATURE_ASN    = 0x00000001,
301     FEATURE_SPS    = 0x00000002,
302     FEATURE_VIRBND = 0x00000004,
303     FEATURE_TBCHK  = 0x00000008,
304 };
305
306 enum {
307     EXCP_RESET            = 0x0000,
308     EXCP_MCHK             = 0x0020,
309     EXCP_ARITH            = 0x0060,
310     EXCP_HW_INTERRUPT     = 0x00E0,
311     EXCP_DFAULT           = 0x01E0,
312     EXCP_DTB_MISS_PAL     = 0x09E0,
313     EXCP_ITB_MISS         = 0x03E0,
314     EXCP_ITB_ACV          = 0x07E0,
315     EXCP_DTB_MISS_NATIVE  = 0x08E0,
316     EXCP_UNALIGN          = 0x11E0,
317     EXCP_OPCDEC           = 0x13E0,
318     EXCP_FEN              = 0x17E0,
319     EXCP_CALL_PAL         = 0x2000,
320     EXCP_CALL_PALP        = 0x3000,
321     EXCP_CALL_PALE        = 0x4000,
322     /* Pseudo exception for console */
323     EXCP_CONSOLE_DISPATCH = 0x4001,
324     EXCP_CONSOLE_FIXUP    = 0x4002,
325 };
326
327 /* Arithmetic exception */
328 enum {
329     EXCP_ARITH_OVERFLOW,
330 };
331
332 enum {
333     PALCODE_CALL = 0x00000000,
334     PALCODE_LD   = 0x01000000,
335     PALCODE_ST   = 0x02000000,
336     PALCODE_MFPR = 0x03000000,
337     PALCODE_MTPR = 0x04000000,
338     PALCODE_REI  = 0x05000000,
339     PALCODE_INIT = 0xF0000000,
340 };
341
342 enum {
343     IR_V0   = 0,
344     IR_T0   = 1,
345     IR_T1   = 2,
346     IR_T2   = 3,
347     IR_T3   = 4,
348     IR_T4   = 5,
349     IR_T5   = 6,
350     IR_T6   = 7,
351     IR_T7   = 8,
352     IR_S0   = 9,
353     IR_S1   = 10,
354     IR_S2   = 11,
355     IR_S3   = 12,
356     IR_S4   = 13,
357     IR_S5   = 14,
358     IR_S6   = 15,
359 #define IR_FP IR_S6
360     IR_A0   = 16,
361     IR_A1   = 17,
362     IR_A2   = 18,
363     IR_A3   = 19,
364     IR_A4   = 20,
365     IR_A5   = 21,
366     IR_T8   = 22,
367     IR_T9   = 23,
368     IR_T10  = 24,
369     IR_T11  = 25,
370     IR_RA   = 26,
371     IR_T12  = 27,
372 #define IR_PV IR_T12
373     IR_AT   = 28,
374     IR_GP   = 29,
375     IR_SP   = 30,
376     IR_ZERO = 31,
377 };
378
379 int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
380 int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
381 void cpu_loop_exit (void);
382 void pal_init (CPUState *env);
383 void call_pal (CPUState *env, int palcode);
384
385 #endif /* !defined (__CPU_ALPHA_H__) */