kvm: Rework dirty bitmap synchronization
[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 13
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,            /* 21264 */
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,            /* 21264 */
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     IR_V0   = 0,
393     IR_T0   = 1,
394     IR_T1   = 2,
395     IR_T2   = 3,
396     IR_T3   = 4,
397     IR_T4   = 5,
398     IR_T5   = 6,
399     IR_T6   = 7,
400     IR_T7   = 8,
401     IR_S0   = 9,
402     IR_S1   = 10,
403     IR_S2   = 11,
404     IR_S3   = 12,
405     IR_S4   = 13,
406     IR_S5   = 14,
407     IR_S6   = 15,
408 #define IR_FP IR_S6
409     IR_A0   = 16,
410     IR_A1   = 17,
411     IR_A2   = 18,
412     IR_A3   = 19,
413     IR_A4   = 20,
414     IR_A5   = 21,
415     IR_T8   = 22,
416     IR_T9   = 23,
417     IR_T10  = 24,
418     IR_T11  = 25,
419     IR_RA   = 26,
420     IR_T12  = 27,
421 #define IR_PV IR_T12
422     IR_AT   = 28,
423     IR_GP   = 29,
424     IR_SP   = 30,
425     IR_ZERO = 31,
426 };
427
428 CPUAlphaState * cpu_alpha_init (const char *cpu_model);
429 int cpu_alpha_exec(CPUAlphaState *s);
430 /* you can call this signal handler from your SIGBUS and SIGSEGV
431    signal handlers to inform the virtual CPU of exceptions. non zero
432    is returned if the signal was handled by the virtual CPU.  */
433 int cpu_alpha_signal_handler(int host_signum, void *pinfo,
434                              void *puc);
435 int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
436                                 int mmu_idx, int is_softmmu);
437 void do_interrupt (CPUState *env);
438
439 int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
440 int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
441 void pal_init (CPUState *env);
442 #if !defined (CONFIG_USER_ONLY)
443 void call_pal (CPUState *env);
444 #else
445 void call_pal (CPUState *env, int palcode);
446 #endif
447
448 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
449 {
450     env->pc = tb->pc;
451 }
452
453 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
454                                         target_ulong *cs_base, int *flags)
455 {
456     *pc = env->pc;
457     *cs_base = 0;
458     *flags = env->ps;
459 }
460
461 #endif /* !defined (__CPU_ALPHA_H__) */