]> git.proxmox.com Git - mirror_qemu.git/blobdiff - target-alpha/cpu.h
exec: move include files to include/exec/
[mirror_qemu.git] / target-alpha / cpu.h
index c1546f81864f1450f116a3e243b6f0f00c9c227b..137703f6d7818344a9d7a615dea561fdcab46085 100644 (file)
 #define __CPU_ALPHA_H__
 
 #include "config.h"
+#include "qemu-common.h"
 
 #define TARGET_LONG_BITS 64
 
-#define CPUState struct CPUAlphaState
+#define CPUArchState struct CPUAlphaState
 
-#include "cpu-defs.h"
-
-#include <setjmp.h>
+#include "exec/cpu-defs.h"
 
 #include "softfloat.h"
 
 
 #define TARGET_PAGE_BITS 13
 
+#ifdef CONFIG_USER_ONLY
+/* ??? The kernel likes to give addresses in high memory.  If the host has
+   more virtual address space than the guest, this can lead to impossible
+   allocations.  Honor the long-standing assumption that only kernel addrs
+   are negative, but otherwise allow allocations anywhere.  This could lead
+   to tricky emulation problems for programs doing tagged addressing, but
+   that's far fewer than encounter the impossible allocation problem.  */
+#define TARGET_PHYS_ADDR_SPACE_BITS  63
+#define TARGET_VIRT_ADDR_SPACE_BITS  63
+#else
 /* ??? EV4 has 34 phys addr bits, EV5 has 40, EV6 has 44.  */
-#define TARGET_PHYS_ADDR_SPACE_BITS    44
-#define TARGET_VIRT_ADDR_SPACE_BITS    (30 + TARGET_PAGE_BITS)
+#define TARGET_PHYS_ADDR_SPACE_BITS  44
+#define TARGET_VIRT_ADDR_SPACE_BITS  (30 + TARGET_PAGE_BITS)
+#endif
 
 /* Alpha major type */
 enum {
@@ -235,7 +245,6 @@ struct CPUAlphaState {
     uint8_t fpcr_exc_mask;
     uint8_t fpcr_dyn_round;
     uint8_t fpcr_flush_to_zero;
-    uint8_t fpcr_dnz;
     uint8_t fpcr_dnod;
     uint8_t fpcr_undz;
 
@@ -267,14 +276,11 @@ struct CPUAlphaState {
     uint64_t scratch[24];
 #endif
 
-#if TARGET_LONG_BITS > HOST_LONG_BITS
-    /* temporary fixed-point registers
-     * used to emulate 64 bits target on 32 bits hosts
-     */
-    target_ulong t0, t1;
-#endif
+    /* This alarm doesn't exist in real hardware; we wish it did.  */
+    struct QEMUTimer *alarm_timer;
+    uint64_t alarm_expire;
 
-    /* Those resources are used only in Qemu core */
+    /* Those resources are used only in QEMU core */
     CPU_COMMON
 
     int error_code;
@@ -289,7 +295,8 @@ struct CPUAlphaState {
 #define cpu_gen_code cpu_alpha_gen_code
 #define cpu_signal_handler cpu_alpha_signal_handler
 
-#include "cpu-all.h"
+#include "exec/cpu-all.h"
+#include "cpu-qom.h"
 
 enum {
     FEATURE_ASN    = 0x00000001,
@@ -315,6 +322,24 @@ enum {
     EXCP_STQ_C,
 };
 
+/* Alpha-specific interrupt pending bits.  */
+#define CPU_INTERRUPT_TIMER    CPU_INTERRUPT_TGT_EXT_0
+#define CPU_INTERRUPT_SMP      CPU_INTERRUPT_TGT_EXT_1
+#define CPU_INTERRUPT_MCHK     CPU_INTERRUPT_TGT_EXT_2
+
+/* OSF/1 Page table bits.  */
+enum {
+    PTE_VALID = 0x0001,
+    PTE_FOR   = 0x0002,  /* used for page protection (fault on read) */
+    PTE_FOW   = 0x0004,  /* used for page protection (fault on write) */
+    PTE_FOE   = 0x0008,  /* used for page protection (fault on exec) */
+    PTE_ASM   = 0x0010,
+    PTE_KRE   = 0x0100,
+    PTE_URE   = 0x0200,
+    PTE_KWE   = 0x1000,
+    PTE_UWE   = 0x2000
+};
+
 /* Hardware interrupt (entInt) constants.  */
 enum {
     INT_K_IP,
@@ -354,7 +379,7 @@ enum {
     PS_USER_MODE = 8
 };
 
-static inline int cpu_mmu_index(CPUState *env)
+static inline int cpu_mmu_index(CPUAlphaState *env)
 {
     if (env->pal_mode) {
         return MMU_KERNEL_IDX;
@@ -409,25 +434,61 @@ int cpu_alpha_exec(CPUAlphaState *s);
    is returned if the signal was handled by the virtual CPU.  */
 int cpu_alpha_signal_handler(int host_signum, void *pinfo,
                              void *puc);
-int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
-                                int mmu_idx, int is_softmmu);
+int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw,
+                                int mmu_idx);
 #define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
-void do_interrupt (CPUState *env);
+void do_interrupt (CPUAlphaState *env);
+void do_restore_state(CPUAlphaState *, uintptr_t retaddr);
+void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
+void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
+
+uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
+void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
+#ifndef CONFIG_USER_ONLY
+void swap_shadow_regs(CPUAlphaState *env);
+QEMU_NORETURN void cpu_unassigned_access(CPUAlphaState *env1,
+                                         hwaddr addr, int is_write,
+                                         int is_exec, int unused, int size);
+#endif
 
-uint64_t cpu_alpha_load_fpcr (CPUState *env);
-void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
-extern void swap_shadow_regs(CPUState *env);
+/* Bits in TB->FLAGS that control how translation is processed.  */
+enum {
+    TB_FLAGS_PAL_MODE = 1,
+    TB_FLAGS_FEN = 2,
+    TB_FLAGS_USER_MODE = 8,
+
+    TB_FLAGS_AMASK_SHIFT = 4,
+    TB_FLAGS_AMASK_BWX = AMASK_BWX << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_FIX = AMASK_FIX << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_CIX = AMASK_CIX << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_MVI = AMASK_MVI << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_TRAP = AMASK_TRAP << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_PREFETCH = AMASK_PREFETCH << TB_FLAGS_AMASK_SHIFT,
+};
 
-static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
-                                        target_ulong *cs_base, int *flags)
+static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
+                                        target_ulong *cs_base, int *pflags)
 {
+    int flags = 0;
+
     *pc = env->pc;
     *cs_base = 0;
-    *flags = env->ps;
+
+    if (env->pal_mode) {
+        flags = TB_FLAGS_PAL_MODE;
+    } else {
+        flags = env->ps & PS_USER_MODE;
+    }
+    if (env->fen) {
+        flags |= TB_FLAGS_FEN;
+    }
+    flags |= env->amask << TB_FLAGS_AMASK_SHIFT;
+
+    *pflags = flags;
 }
 
 #if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUAlphaState *env, target_ulong newsp)
 {
     if (newsp) {
         env->ir[IR_SP] = newsp;
@@ -436,10 +497,34 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
     env->ir[IR_A3] = 0;
 }
 
-static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
+static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
 {
     env->unique = newtls;
 }
 #endif
 
+static inline bool cpu_has_work(CPUState *cpu)
+{
+    CPUAlphaState *env = &ALPHA_CPU(cpu)->env;
+
+    /* Here we are checking to see if the CPU should wake up from HALT.
+       We will have gotten into this state only for WTINT from PALmode.  */
+    /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
+       asleep even if (some) interrupts have been asserted.  For now,
+       assume that if a CPU really wants to stay asleep, it will mask
+       interrupts at the chipset level, which will prevent these bits
+       from being set in the first place.  */
+    return env->interrupt_request & (CPU_INTERRUPT_HARD
+                                     | CPU_INTERRUPT_TIMER
+                                     | CPU_INTERRUPT_SMP
+                                     | CPU_INTERRUPT_MCHK);
+}
+
+#include "exec/exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUAlphaState *env, TranslationBlock *tb)
+{
+    env->pc = tb->pc;
+}
+
 #endif /* !defined (__CPU_ALPHA_H__) */