These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #if !defined (__CPU_ALPHA_H__)
21 #define __CPU_ALPHA_H__
22
23 #include "qemu-common.h"
24
25 #define TARGET_LONG_BITS 64
26 #define ALIGNED_ONLY
27
28 #define CPUArchState struct CPUAlphaState
29
30 #include "exec/cpu-defs.h"
31
32 #include "fpu/softfloat.h"
33
34 #define ICACHE_LINE_SIZE 32
35 #define DCACHE_LINE_SIZE 32
36
37 #define TARGET_PAGE_BITS 13
38
39 #ifdef CONFIG_USER_ONLY
40 /* ??? The kernel likes to give addresses in high memory.  If the host has
41    more virtual address space than the guest, this can lead to impossible
42    allocations.  Honor the long-standing assumption that only kernel addrs
43    are negative, but otherwise allow allocations anywhere.  This could lead
44    to tricky emulation problems for programs doing tagged addressing, but
45    that's far fewer than encounter the impossible allocation problem.  */
46 #define TARGET_PHYS_ADDR_SPACE_BITS  63
47 #define TARGET_VIRT_ADDR_SPACE_BITS  63
48 #else
49 /* ??? EV4 has 34 phys addr bits, EV5 has 40, EV6 has 44.  */
50 #define TARGET_PHYS_ADDR_SPACE_BITS  44
51 #define TARGET_VIRT_ADDR_SPACE_BITS  (30 + TARGET_PAGE_BITS)
52 #endif
53
54 /* Alpha major type */
55 enum {
56     ALPHA_EV3  = 1,
57     ALPHA_EV4  = 2,
58     ALPHA_SIM  = 3,
59     ALPHA_LCA  = 4,
60     ALPHA_EV5  = 5, /* 21164 */
61     ALPHA_EV45 = 6, /* 21064A */
62     ALPHA_EV56 = 7, /* 21164A */
63 };
64
65 /* EV4 minor type */
66 enum {
67     ALPHA_EV4_2 = 0,
68     ALPHA_EV4_3 = 1,
69 };
70
71 /* LCA minor type */
72 enum {
73     ALPHA_LCA_1 = 1, /* 21066 */
74     ALPHA_LCA_2 = 2, /* 20166 */
75     ALPHA_LCA_3 = 3, /* 21068 */
76     ALPHA_LCA_4 = 4, /* 21068 */
77     ALPHA_LCA_5 = 5, /* 21066A */
78     ALPHA_LCA_6 = 6, /* 21068A */
79 };
80
81 /* EV5 minor type */
82 enum {
83     ALPHA_EV5_1 = 1, /* Rev BA, CA */
84     ALPHA_EV5_2 = 2, /* Rev DA, EA */
85     ALPHA_EV5_3 = 3, /* Pass 3 */
86     ALPHA_EV5_4 = 4, /* Pass 3.2 */
87     ALPHA_EV5_5 = 5, /* Pass 4 */
88 };
89
90 /* EV45 minor type */
91 enum {
92     ALPHA_EV45_1 = 1, /* Pass 1 */
93     ALPHA_EV45_2 = 2, /* Pass 1.1 */
94     ALPHA_EV45_3 = 3, /* Pass 2 */
95 };
96
97 /* EV56 minor type */
98 enum {
99     ALPHA_EV56_1 = 1, /* Pass 1 */
100     ALPHA_EV56_2 = 2, /* Pass 2 */
101 };
102
103 enum {
104     IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */
105     IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */
106     IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */
107     IMPLVER_21364 = 3, /* EV7 & EV79 */
108 };
109
110 enum {
111     AMASK_BWX      = 0x00000001,
112     AMASK_FIX      = 0x00000002,
113     AMASK_CIX      = 0x00000004,
114     AMASK_MVI      = 0x00000100,
115     AMASK_TRAP     = 0x00000200,
116     AMASK_PREFETCH = 0x00001000,
117 };
118
119 enum {
120     VAX_ROUND_NORMAL = 0,
121     VAX_ROUND_CHOPPED,
122 };
123
124 enum {
125     IEEE_ROUND_NORMAL = 0,
126     IEEE_ROUND_DYNAMIC,
127     IEEE_ROUND_PLUS,
128     IEEE_ROUND_MINUS,
129     IEEE_ROUND_CHOPPED,
130 };
131
132 /* IEEE floating-point operations encoding */
133 /* Trap mode */
134 enum {
135     FP_TRAP_I   = 0x0,
136     FP_TRAP_U   = 0x1,
137     FP_TRAP_S  = 0x4,
138     FP_TRAP_SU  = 0x5,
139     FP_TRAP_SUI = 0x7,
140 };
141
142 /* Rounding mode */
143 enum {
144     FP_ROUND_CHOPPED = 0x0,
145     FP_ROUND_MINUS   = 0x1,
146     FP_ROUND_NORMAL  = 0x2,
147     FP_ROUND_DYNAMIC = 0x3,
148 };
149
150 /* FPCR bits -- right-shifted 32 so we can use a uint32_t.  */
151 #define FPCR_SUM                (1U << (63 - 32))
152 #define FPCR_INED               (1U << (62 - 32))
153 #define FPCR_UNFD               (1U << (61 - 32))
154 #define FPCR_UNDZ               (1U << (60 - 32))
155 #define FPCR_DYN_SHIFT          (58 - 32)
156 #define FPCR_DYN_CHOPPED        (0U << FPCR_DYN_SHIFT)
157 #define FPCR_DYN_MINUS          (1U << FPCR_DYN_SHIFT)
158 #define FPCR_DYN_NORMAL         (2U << FPCR_DYN_SHIFT)
159 #define FPCR_DYN_PLUS           (3U << FPCR_DYN_SHIFT)
160 #define FPCR_DYN_MASK           (3U << FPCR_DYN_SHIFT)
161 #define FPCR_IOV                (1U << (57 - 32))
162 #define FPCR_INE                (1U << (56 - 32))
163 #define FPCR_UNF                (1U << (55 - 32))
164 #define FPCR_OVF                (1U << (54 - 32))
165 #define FPCR_DZE                (1U << (53 - 32))
166 #define FPCR_INV                (1U << (52 - 32))
167 #define FPCR_OVFD               (1U << (51 - 32))
168 #define FPCR_DZED               (1U << (50 - 32))
169 #define FPCR_INVD               (1U << (49 - 32))
170 #define FPCR_DNZ                (1U << (48 - 32))
171 #define FPCR_DNOD               (1U << (47 - 32))
172 #define FPCR_STATUS_MASK        (FPCR_IOV | FPCR_INE | FPCR_UNF \
173                                  | FPCR_OVF | FPCR_DZE | FPCR_INV)
174
175 /* The silly software trap enables implemented by the kernel emulation.
176    These are more or less architecturally required, since the real hardware
177    has read-as-zero bits in the FPCR when the features aren't implemented.
178    For the purposes of QEMU, we pretend the FPCR can hold everything.  */
179 #define SWCR_TRAP_ENABLE_INV    (1U << 1)
180 #define SWCR_TRAP_ENABLE_DZE    (1U << 2)
181 #define SWCR_TRAP_ENABLE_OVF    (1U << 3)
182 #define SWCR_TRAP_ENABLE_UNF    (1U << 4)
183 #define SWCR_TRAP_ENABLE_INE    (1U << 5)
184 #define SWCR_TRAP_ENABLE_DNO    (1U << 6)
185 #define SWCR_TRAP_ENABLE_MASK   ((1U << 7) - (1U << 1))
186
187 #define SWCR_MAP_DMZ            (1U << 12)
188 #define SWCR_MAP_UMZ            (1U << 13)
189 #define SWCR_MAP_MASK           (SWCR_MAP_DMZ | SWCR_MAP_UMZ)
190
191 #define SWCR_STATUS_INV         (1U << 17)
192 #define SWCR_STATUS_DZE         (1U << 18)
193 #define SWCR_STATUS_OVF         (1U << 19)
194 #define SWCR_STATUS_UNF         (1U << 20)
195 #define SWCR_STATUS_INE         (1U << 21)
196 #define SWCR_STATUS_DNO         (1U << 22)
197 #define SWCR_STATUS_MASK        ((1U << 23) - (1U << 17))
198
199 #define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
200
201 /* MMU modes definitions */
202
203 /* Alpha has 5 MMU modes: PALcode, kernel, executive, supervisor, and user.
204    The Unix PALcode only exposes the kernel and user modes; presumably
205    executive and supervisor are used by VMS.
206
207    PALcode itself uses physical mode for code and kernel mode for data;
208    there are PALmode instructions that can access data via physical mode
209    or via an os-installed "alternate mode", which is one of the 4 above.
210
211    QEMU does not currently properly distinguish between code/data when
212    looking up addresses.  To avoid having to address this issue, our
213    emulated PALcode will cheat and use the KSEG mapping for its code+data
214    rather than physical addresses.
215
216    Moreover, we're only emulating Unix PALcode, and not attempting VMS.
217
218    All of which allows us to drop all but kernel and user modes.
219    Elide the unused MMU modes to save space.  */
220
221 #define NB_MMU_MODES 2
222
223 #define MMU_MODE0_SUFFIX _kernel
224 #define MMU_MODE1_SUFFIX _user
225 #define MMU_KERNEL_IDX   0
226 #define MMU_USER_IDX     1
227
228 typedef struct CPUAlphaState CPUAlphaState;
229
230 struct CPUAlphaState {
231     uint64_t ir[31];
232     float64 fir[31];
233     uint64_t pc;
234     uint64_t unique;
235     uint64_t lock_addr;
236     uint64_t lock_st_addr;
237     uint64_t lock_value;
238
239     /* The FPCR, and disassembled portions thereof.  */
240     uint32_t fpcr;
241     uint32_t fpcr_exc_enable;
242     float_status fp_status;
243     uint8_t fpcr_dyn_round;
244     uint8_t fpcr_flush_to_zero;
245
246     /* The Internal Processor Registers.  Some of these we assume always
247        exist for use in user-mode.  */
248     uint8_t ps;
249     uint8_t intr_flag;
250     uint8_t pal_mode;
251     uint8_t fen;
252
253     uint32_t pcc_ofs;
254
255     /* These pass data from the exception logic in the translator and
256        helpers to the OS entry point.  This is used for both system
257        emulation and user-mode.  */
258     uint64_t trap_arg0;
259     uint64_t trap_arg1;
260     uint64_t trap_arg2;
261
262 #if !defined(CONFIG_USER_ONLY)
263     /* The internal data required by our emulation of the Unix PALcode.  */
264     uint64_t exc_addr;
265     uint64_t palbr;
266     uint64_t ptbr;
267     uint64_t vptptr;
268     uint64_t sysval;
269     uint64_t usp;
270     uint64_t shadow[8];
271     uint64_t scratch[24];
272 #endif
273
274     /* This alarm doesn't exist in real hardware; we wish it did.  */
275     uint64_t alarm_expire;
276
277     /* Those resources are used only in QEMU core */
278     CPU_COMMON
279
280     int error_code;
281
282     uint32_t features;
283     uint32_t amask;
284     int implver;
285 };
286
287 #define cpu_list alpha_cpu_list
288 #define cpu_exec cpu_alpha_exec
289 #define cpu_signal_handler cpu_alpha_signal_handler
290
291 #include "exec/cpu-all.h"
292 #include "cpu-qom.h"
293
294 enum {
295     FEATURE_ASN    = 0x00000001,
296     FEATURE_SPS    = 0x00000002,
297     FEATURE_VIRBND = 0x00000004,
298     FEATURE_TBCHK  = 0x00000008,
299 };
300
301 enum {
302     EXCP_RESET,
303     EXCP_MCHK,
304     EXCP_SMP_INTERRUPT,
305     EXCP_CLK_INTERRUPT,
306     EXCP_DEV_INTERRUPT,
307     EXCP_MMFAULT,
308     EXCP_UNALIGN,
309     EXCP_OPCDEC,
310     EXCP_ARITH,
311     EXCP_FEN,
312     EXCP_CALL_PAL,
313     /* For Usermode emulation.  */
314     EXCP_STL_C,
315     EXCP_STQ_C,
316 };
317
318 /* Alpha-specific interrupt pending bits.  */
319 #define CPU_INTERRUPT_TIMER     CPU_INTERRUPT_TGT_EXT_0
320 #define CPU_INTERRUPT_SMP       CPU_INTERRUPT_TGT_EXT_1
321 #define CPU_INTERRUPT_MCHK      CPU_INTERRUPT_TGT_EXT_2
322
323 /* OSF/1 Page table bits.  */
324 enum {
325     PTE_VALID = 0x0001,
326     PTE_FOR   = 0x0002,  /* used for page protection (fault on read) */
327     PTE_FOW   = 0x0004,  /* used for page protection (fault on write) */
328     PTE_FOE   = 0x0008,  /* used for page protection (fault on exec) */
329     PTE_ASM   = 0x0010,
330     PTE_KRE   = 0x0100,
331     PTE_URE   = 0x0200,
332     PTE_KWE   = 0x1000,
333     PTE_UWE   = 0x2000
334 };
335
336 /* Hardware interrupt (entInt) constants.  */
337 enum {
338     INT_K_IP,
339     INT_K_CLK,
340     INT_K_MCHK,
341     INT_K_DEV,
342     INT_K_PERF,
343 };
344
345 /* Memory management (entMM) constants.  */
346 enum {
347     MM_K_TNV,
348     MM_K_ACV,
349     MM_K_FOR,
350     MM_K_FOE,
351     MM_K_FOW
352 };
353
354 /* Arithmetic exception (entArith) constants.  */
355 enum {
356     EXC_M_SWC = 1,      /* Software completion */
357     EXC_M_INV = 2,      /* Invalid operation */
358     EXC_M_DZE = 4,      /* Division by zero */
359     EXC_M_FOV = 8,      /* Overflow */
360     EXC_M_UNF = 16,     /* Underflow */
361     EXC_M_INE = 32,     /* Inexact result */
362     EXC_M_IOV = 64      /* Integer Overflow */
363 };
364
365 /* Processor status constants.  */
366 enum {
367     /* Low 3 bits are interrupt mask level.  */
368     PS_INT_MASK = 7,
369
370     /* Bits 4 and 5 are the mmu mode.  The VMS PALcode uses all 4 modes;
371        The Unix PALcode only uses bit 4.  */
372     PS_USER_MODE = 8
373 };
374
375 static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch)
376 {
377     if (env->pal_mode) {
378         return MMU_KERNEL_IDX;
379     } else if (env->ps & PS_USER_MODE) {
380         return MMU_USER_IDX;
381     } else {
382         return MMU_KERNEL_IDX;
383     }
384 }
385
386 enum {
387     IR_V0   = 0,
388     IR_T0   = 1,
389     IR_T1   = 2,
390     IR_T2   = 3,
391     IR_T3   = 4,
392     IR_T4   = 5,
393     IR_T5   = 6,
394     IR_T6   = 7,
395     IR_T7   = 8,
396     IR_S0   = 9,
397     IR_S1   = 10,
398     IR_S2   = 11,
399     IR_S3   = 12,
400     IR_S4   = 13,
401     IR_S5   = 14,
402     IR_S6   = 15,
403     IR_FP   = IR_S6,
404     IR_A0   = 16,
405     IR_A1   = 17,
406     IR_A2   = 18,
407     IR_A3   = 19,
408     IR_A4   = 20,
409     IR_A5   = 21,
410     IR_T8   = 22,
411     IR_T9   = 23,
412     IR_T10  = 24,
413     IR_T11  = 25,
414     IR_RA   = 26,
415     IR_T12  = 27,
416     IR_PV   = IR_T12,
417     IR_AT   = 28,
418     IR_GP   = 29,
419     IR_SP   = 30,
420     IR_ZERO = 31,
421 };
422
423 void alpha_translate_init(void);
424
425 AlphaCPU *cpu_alpha_init(const char *cpu_model);
426
427 #define cpu_init(cpu_model) CPU(cpu_alpha_init(cpu_model))
428
429 void alpha_cpu_list(FILE *f, fprintf_function cpu_fprintf);
430 int cpu_alpha_exec(CPUState *cpu);
431 /* you can call this signal handler from your SIGBUS and SIGSEGV
432    signal handlers to inform the virtual CPU of exceptions. non zero
433    is returned if the signal was handled by the virtual CPU.  */
434 int cpu_alpha_signal_handler(int host_signum, void *pinfo,
435                              void *puc);
436 int alpha_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
437                                int mmu_idx);
438 void do_restore_state(CPUAlphaState *, uintptr_t retaddr);
439 void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
440 void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
441
442 uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
443 void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
444 uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg);
445 void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val);
446 #ifndef CONFIG_USER_ONLY
447 QEMU_NORETURN void alpha_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
448                                                bool is_write, bool is_exec,
449                                                int unused, unsigned size);
450 #endif
451
452 /* Bits in TB->FLAGS that control how translation is processed.  */
453 enum {
454     TB_FLAGS_PAL_MODE = 1,
455     TB_FLAGS_FEN = 2,
456     TB_FLAGS_USER_MODE = 8,
457
458     TB_FLAGS_AMASK_SHIFT = 4,
459     TB_FLAGS_AMASK_BWX = AMASK_BWX << TB_FLAGS_AMASK_SHIFT,
460     TB_FLAGS_AMASK_FIX = AMASK_FIX << TB_FLAGS_AMASK_SHIFT,
461     TB_FLAGS_AMASK_CIX = AMASK_CIX << TB_FLAGS_AMASK_SHIFT,
462     TB_FLAGS_AMASK_MVI = AMASK_MVI << TB_FLAGS_AMASK_SHIFT,
463     TB_FLAGS_AMASK_TRAP = AMASK_TRAP << TB_FLAGS_AMASK_SHIFT,
464     TB_FLAGS_AMASK_PREFETCH = AMASK_PREFETCH << TB_FLAGS_AMASK_SHIFT,
465 };
466
467 static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
468                                         target_ulong *cs_base, int *pflags)
469 {
470     int flags = 0;
471
472     *pc = env->pc;
473     *cs_base = 0;
474
475     if (env->pal_mode) {
476         flags = TB_FLAGS_PAL_MODE;
477     } else {
478         flags = env->ps & PS_USER_MODE;
479     }
480     if (env->fen) {
481         flags |= TB_FLAGS_FEN;
482     }
483     flags |= env->amask << TB_FLAGS_AMASK_SHIFT;
484
485     *pflags = flags;
486 }
487
488 #include "exec/exec-all.h"
489
490 #endif /* !defined (__CPU_ALPHA_H__) */