#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 {
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;
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;
#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,
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,
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;
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;
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__) */