#ifndef CPU_S390X_H
#define CPU_S390X_H
+#include "config.h"
+#include "qemu-common.h"
+
#define TARGET_LONG_BITS 64
#define ELF_MACHINE EM_S390
-#define CPUState struct CPUS390XState
+#define CPUArchState struct CPUS390XState
-#include "cpu-defs.h"
+#include "exec/cpu-defs.h"
#define TARGET_PAGE_BITS 12
#define TARGET_PHYS_ADDR_SPACE_BITS 64
#define TARGET_VIRT_ADDR_SPACE_BITS 64
-#include "cpu-all.h"
+#include "exec/cpu-all.h"
#include "softfloat.h"
PSW psw;
- uint32_t cc;
uint32_t cc_op;
uint64_t cc_src;
uint64_t cc_dst;
int pending_int;
ExtQueue ext_queue[MAX_EXT_QUEUE];
+ int ext_index;
+
+ CPU_COMMON
+
/* reset does memset(0) up to here */
- int ext_index;
int cpu_num;
uint8_t *storage_keys;
QEMUTimer *tod_timer;
QEMUTimer *cpu_timer;
-
- CPU_COMMON
} CPUS390XState;
+#include "cpu-qom.h"
+
#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUS390XState *env, target_ulong newsp)
{
if (newsp) {
env->regs[15] = newsp;
#define FLAG_MASK_64 (PSW_MASK_64 >> 32)
#define FLAG_MASK_32 0x00001000
-static inline int cpu_mmu_index (CPUState *env)
+static inline int cpu_mmu_index (CPUS390XState *env)
{
if (env->psw.mask & PSW_MASK_PSTATE) {
return 1;
return 0;
}
-static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc,
+static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
*pc = env->psw.addr;
#define ILC_LATER_INC_2 0x22
-CPUS390XState *cpu_s390x_init(const char *cpu_model);
+S390CPU *cpu_s390x_init(const char *cpu_model);
void s390x_translate_init(void);
int cpu_s390x_exec(CPUS390XState *s);
void cpu_s390x_close(CPUS390XState *s);
-void do_interrupt (CPUState *env);
+void do_interrupt (CPUS390XState *env);
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
int cpu_s390x_signal_handler(int host_signum, void *pinfo,
void *puc);
int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw,
- int mmu_idx, int is_softmuu);
+ int mmu_idx);
#define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault
#ifndef CONFIG_USER_ONLY
-int s390_virtio_hypercall(CPUState *env, uint64_t mem, uint64_t hypercall);
+void s390x_tod_timer(void *opaque);
+void s390x_cpu_timer(void *opaque);
+
+int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall);
-void kvm_s390_interrupt(CPUState *env, int type, uint32_t code);
-void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token);
-void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
+#ifdef CONFIG_KVM
+void kvm_s390_interrupt(CPUS390XState *env, int type, uint32_t code);
+void kvm_s390_virtio_irq(CPUS390XState *env, int config_change, uint64_t token);
+void kvm_s390_interrupt_internal(CPUS390XState *env, int type, uint32_t parm,
uint64_t parm64, int vm);
-CPUState *s390_cpu_addr2state(uint16_t cpu_addr);
-
-#ifndef KVM_S390_SIGP_STOP
-#define KVM_S390_SIGP_STOP 0
-#define KVM_S390_PROGRAM_INT 0
-#define KVM_S390_SIGP_SET_PREFIX 0
-#define KVM_S390_RESTART 0
-#define KVM_S390_INT_VIRTIO 0
-#define KVM_S390_INT_SERVICE 0
-#define KVM_S390_INT_EMERGENCY 0
+#else
+static inline void kvm_s390_interrupt(CPUS390XState *env, int type, uint32_t code)
+{
+}
+
+static inline void kvm_s390_virtio_irq(CPUS390XState *env, int config_change,
+ uint64_t token)
+{
+}
+
+static inline void kvm_s390_interrupt_internal(CPUS390XState *env, int type,
+ uint32_t parm, uint64_t parm64,
+ int vm)
+{
+}
#endif
+S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
+void s390_add_running_cpu(CPUS390XState *env);
+unsigned s390_del_running_cpu(CPUS390XState *env);
+
+/* service interrupts are floating therefore we must not pass an cpustate */
+void s390_sclp_extint(uint32_t parm);
+/* from s390-virtio-bus */
+extern const hwaddr virtio_size;
+
+#else
+static inline void s390_add_running_cpu(CPUS390XState *env)
+{
+}
+
+static inline unsigned s390_del_running_cpu(CPUS390XState *env)
+{
+ return 0;
+}
#endif
void cpu_lock(void);
void cpu_unlock(void);
env->aregs[1] = newtls & 0xffffffffULL;
}
-#define cpu_init cpu_s390x_init
+#define cpu_init(model) (&cpu_s390x_init(model)->env)
#define cpu_exec cpu_s390x_exec
#define cpu_gen_code cpu_s390x_gen_code
#define cpu_signal_handler cpu_s390x_signal_handler
-#include "exec-all.h"
+#include "exec/exec-all.h"
#ifdef CONFIG_USER_ONLY
CC_OP_ADD_64, /* overflow on add (64bit) */
CC_OP_ADDU_64, /* overflow on unsigned add (64bit) */
- CC_OP_SUB_64, /* overflow on substraction (64bit) */
- CC_OP_SUBU_64, /* overflow on unsigned substraction (64bit) */
+ CC_OP_SUB_64, /* overflow on subtraction (64bit) */
+ CC_OP_SUBU_64, /* overflow on unsigned subtraction (64bit) */
CC_OP_ABS_64, /* sign eval on abs (64bit) */
CC_OP_NABS_64, /* sign eval on nabs (64bit) */
CC_OP_ADD_32, /* overflow on add (32bit) */
CC_OP_ADDU_32, /* overflow on unsigned add (32bit) */
- CC_OP_SUB_32, /* overflow on substraction (32bit) */
- CC_OP_SUBU_32, /* overflow on unsigned substraction (32bit) */
+ CC_OP_SUB_32, /* overflow on subtraction (32bit) */
+ CC_OP_SUBU_32, /* overflow on unsigned subtraction (32bit) */
CC_OP_ABS_32, /* sign eval on abs (64bit) */
CC_OP_NABS_32, /* sign eval on nabs (64bit) */
return cc_names[cc_op];
}
-/* SCLP PV interface defines */
-#define SCLP_CMDW_READ_SCP_INFO 0x00020001
-#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
-
-#define SCP_LENGTH 0x00
-#define SCP_FUNCTION_CODE 0x02
-#define SCP_CONTROL_MASK 0x03
-#define SCP_RESPONSE_CODE 0x06
-#define SCP_MEM_CODE 0x08
-#define SCP_INCREMENT 0x0a
-
typedef struct LowCore
{
/* prefix area: defined by architecture */
/* align to the top of the prefix area */
uint8_t pad18[0x2000-0x1400]; /* 0x1400 */
-} __attribute__((packed)) LowCore;
+} QEMU_PACKED LowCore;
/* STSI */
#define STSI_LEVEL_MASK 0x00000000f0000000ULL
#define _PAGE_RO 0x200 /* HW read-only bit */
#define _PAGE_INVALID 0x400 /* HW invalid bit */
+#define SK_C (0x1 << 1)
+#define SK_R (0x1 << 2)
+#define SK_F (0x1 << 3)
+#define SK_ACC_MASK (0xf << 4)
/* EBCDIC handling */
#define SIGP_STAT_INVALID_ORDER 0x00000002UL
#define SIGP_STAT_RECEIVER_CHECK 0x00000001UL
-void load_psw(CPUState *env, uint64_t mask, uint64_t addr);
-int mmu_translate(CPUState *env, target_ulong vaddr, int rw, uint64_t asc,
+void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr);
+int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
target_ulong *raddr, int *flags);
-int sclp_service_call(CPUState *env, uint32_t sccb, uint64_t code);
-uint32_t calc_cc(CPUState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
+int sclp_service_call(uint32_t sccb, uint64_t code);
+uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
uint64_t vr);
#define TARGET_HAS_ICE 1
return (ns << 9) / 125;
}
-static inline void cpu_inject_ext(CPUState *env, uint32_t code, uint32_t param,
+static inline void cpu_inject_ext(CPUS390XState *env, uint32_t code, uint32_t param,
uint64_t param64)
{
if (env->ext_index == MAX_EXT_QUEUE - 1) {
cpu_interrupt(env, CPU_INTERRUPT_HARD);
}
+static inline bool cpu_has_work(CPUState *cpu)
+{
+ CPUS390XState *env = &S390_CPU(cpu)->env;
+
+ return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->psw.mask & PSW_MASK_EXT);
+}
+
+static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
+{
+ env->psw.addr = tb->pc;
+}
+
+/* fpu_helper.c */
+uint32_t set_cc_f32(CPUS390XState *env, float32 v1, float32 v2);
+uint32_t set_cc_f64(CPUS390XState *env, float64 v1, float64 v2);
+uint32_t set_cc_nz_f32(float32 v);
+uint32_t set_cc_nz_f64(float64 v);
+
+/* misc_helper.c */
+void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
+
#endif