summaryrefslogtreecommitdiff
path: root/target-s390x
diff options
context:
space:
mode:
authorhyokeun <hyokeun.jeon@samsung.com>2016-12-27 17:29:09 +0900
committerhyokeun <hyokeun.jeon@samsung.com>2016-12-27 17:29:09 +0900
commit2a84d37c88d606fda46a565bcc80e173b4d0a80a (patch)
tree8b755bb78271e76e13fb7db38b670dbc443479e7 /target-s390x
parentbd54c25035217800f3b1d39f6472d599cd602d5a (diff)
downloadqemu-2a84d37c88d606fda46a565bcc80e173b4d0a80a.tar.gz
qemu-2a84d37c88d606fda46a565bcc80e173b4d0a80a.tar.bz2
qemu-2a84d37c88d606fda46a565bcc80e173b4d0a80a.zip
Imported Upstream version 2.6.1upstream/2.6.1upstream
Diffstat (limited to 'target-s390x')
-rw-r--r--target-s390x/cc_helper.c1
-rw-r--r--target-s390x/cpu-qom.h46
-rw-r--r--target-s390x/cpu.c4
-rw-r--r--target-s390x/cpu.h195
-rw-r--r--target-s390x/fpu_helper.c29
-rw-r--r--target-s390x/gdbstub.c2
-rw-r--r--target-s390x/helper.c10
-rw-r--r--target-s390x/helper.h6
-rw-r--r--target-s390x/int_helper.c1
-rw-r--r--target-s390x/interrupt.c66
-rw-r--r--target-s390x/ioinst.c3
-rw-r--r--target-s390x/ioinst.h246
-rw-r--r--target-s390x/kvm.c44
-rw-r--r--target-s390x/machine.c32
-rw-r--r--target-s390x/mem_helper.c10
-rw-r--r--target-s390x/misc_helper.c23
-rw-r--r--target-s390x/trace-events22
-rw-r--r--target-s390x/translate.c28
18 files changed, 456 insertions, 312 deletions
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
index 1cf855133..0d9411bdf 100644
--- a/target-s390x/cc_helper.c
+++ b/target-s390x/cc_helper.c
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "qemu/host-utils.h"
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 66b5d1808..1c9093396 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -21,6 +21,7 @@
#define QEMU_S390_CPU_QOM_H
#include "qom/cpu.h"
+#include "cpu.h"
#define TYPE_S390_CPU "s390-cpu"
@@ -55,6 +56,49 @@ typedef struct S390CPUClass {
void (*initial_cpu_reset)(CPUState *cpu);
} S390CPUClass;
-typedef struct S390CPU S390CPU;
+/**
+ * S390CPU:
+ * @env: #CPUS390XState.
+ *
+ * An S/390 CPU.
+ */
+typedef struct S390CPU {
+ /*< private >*/
+ CPUState parent_obj;
+ /*< public >*/
+
+ CPUS390XState env;
+ int64_t id;
+ /* needed for live migration */
+ void *irqstate;
+ uint32_t irqstate_saved_size;
+} S390CPU;
+
+static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
+{
+ return container_of(env, S390CPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(S390CPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_s390_cpu;
+#endif
+
+void s390_cpu_do_interrupt(CPUState *cpu);
+bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+ int flags);
+int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+ int cpuid, void *opaque);
+
+hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+hwaddr s390_cpu_get_phys_addr_debug(CPUState *cpu, vaddr addr);
+int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+void s390_cpu_gdb_init(CPUState *cs);
+void s390x_cpu_debug_excp_handler(CPUState *cs);
#endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index e43e2d615..4bfff341d 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -30,12 +30,10 @@
#include "qemu/cutils.h"
#include "qemu/timer.h"
#include "qemu/error-report.h"
+#include "hw/hw.h"
#include "trace.h"
#include "qapi/visitor.h"
-#include "migration/vmstate.h"
-#include "exec/exec-all.h"
#ifndef CONFIG_USER_ONLY
-#include "hw/hw.h"
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "hw/s390x/sclp.h"
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index c216bdace..6d97c089a 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -19,12 +19,10 @@
* You should have received a copy of the GNU (Lesser) General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-
-#ifndef S390X_CPU_H
-#define S390X_CPU_H
+#ifndef CPU_S390X_H
+#define CPU_S390X_H
#include "qemu-common.h"
-#include "cpu-qom.h"
#define TARGET_LONG_BITS 64
@@ -137,8 +135,6 @@ typedef struct CPUS390XState {
uint64_t gbea;
uint64_t pp;
- uint8_t riccb[64];
-
CPU_COMMON
/* reset does memset(0) up to here */
@@ -175,52 +171,8 @@ static inline CPU_DoubleU *get_freg(CPUS390XState *cs, int nr)
return &cs->vregs[nr][0];
}
-/**
- * S390CPU:
- * @env: #CPUS390XState.
- *
- * An S/390 CPU.
- */
-struct S390CPU {
- /*< private >*/
- CPUState parent_obj;
- /*< public >*/
-
- CPUS390XState env;
- int64_t id;
- /* needed for live migration */
- void *irqstate;
- uint32_t irqstate_saved_size;
-};
-
-static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
-{
- return container_of(env, S390CPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(S390CPU, env)
-
-#ifndef CONFIG_USER_ONLY
-extern const struct VMStateDescription vmstate_s390_cpu;
-#endif
-
-void s390_cpu_do_interrupt(CPUState *cpu);
-bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
- int flags);
-int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
- int cpuid, void *opaque);
-
-hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-hwaddr s390_cpu_get_phys_addr_debug(CPUState *cpu, vaddr addr);
-int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void s390_cpu_gdb_init(CPUState *cs);
-void s390x_cpu_debug_excp_handler(CPUState *cs);
-
-#include "sysemu/kvm.h"
+#include "cpu-qom.h"
+#include <sysemu/kvm.h>
/* distinguish between 24 bit and 31 bit addressing */
#define HIGH_ORDER_BIT 0x80000000
@@ -386,7 +338,7 @@ static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx)
}
static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
+ target_ulong *cs_base, int *flags)
{
*pc = env->psw.addr;
*cs_base = 0;
@@ -464,6 +416,7 @@ S390CPU *cpu_s390x_init(const char *cpu_model);
S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp);
S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp);
void s390x_translate_init(void);
+int cpu_s390x_exec(CPUState *cpu);
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
@@ -473,6 +426,8 @@ int cpu_s390x_signal_handler(int host_signum, void *pinfo,
int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);
+#include "ioinst.h"
+
#ifndef CONFIG_USER_ONLY
void do_restart_interrupt(CPUS390XState *env);
@@ -583,26 +538,6 @@ static inline uint8_t s390_cpu_get_state(S390CPU *cpu)
void gtod_save(QEMUFile *f, void *opaque);
int gtod_load(QEMUFile *f, void *opaque, int version_id);
-void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param,
- uint64_t param64);
-
-/* ioinst.c */
-void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
-void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
-void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb);
-void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
-int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
-void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb);
-int ioinst_handle_tpi(S390CPU *cpu, uint32_t ipb);
-void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
- uint32_t ipb);
-void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1);
-
/* service interrupts are floating therefore we must not pass an cpustate */
void s390_sclp_extint(uint32_t parm);
@@ -624,14 +559,45 @@ static inline unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
void cpu_lock(void);
void cpu_unlock(void);
+typedef struct SubchDev SubchDev;
+
+#ifndef CONFIG_USER_ONLY
extern void subsystem_reset(void);
+SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid,
+ uint16_t schid);
+bool css_subch_visible(SubchDev *sch);
+void css_conditional_io_interrupt(SubchDev *sch);
+int css_do_stsch(SubchDev *sch, SCHIB *schib);
+bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid);
+int css_do_msch(SubchDev *sch, const SCHIB *schib);
+int css_do_xsch(SubchDev *sch);
+int css_do_csch(SubchDev *sch);
+int css_do_hsch(SubchDev *sch);
+int css_do_ssch(SubchDev *sch, ORB *orb);
+int css_do_tsch_get_irb(SubchDev *sch, IRB *irb, int *irb_len);
+void css_do_tsch_update_subch(SubchDev *sch);
+int css_do_stcrw(CRW *crw);
+void css_undo_stcrw(CRW *crw);
+int css_do_tpi(IOIntCode *int_code, int lowcore);
+int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
+ int rfmt, void *buf);
+void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo);
+int css_enable_mcsse(void);
+int css_enable_mss(void);
+int css_do_rsch(SubchDev *sch);
+int css_do_rchp(uint8_t cssid, uint8_t chpid);
+bool css_present(uint8_t cssid);
+#endif
#define cpu_init(model) CPU(cpu_s390x_init(model))
+#define cpu_exec cpu_s390x_exec
#define cpu_signal_handler cpu_s390x_signal_handler
void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
#define cpu_list s390_cpu_list
+#include "exec/exec-all.h"
+
#define EXCP_EXT 1 /* external interrupt */
#define EXCP_SVC 2 /* supervisor call (syscall) */
#define EXCP_PGM 3 /* program interruption */
@@ -1096,6 +1062,69 @@ static inline uint64_t tod2time(uint64_t t) {
return (t * 125) >> 9;
}
+static inline void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param,
+ uint64_t param64)
+{
+ CPUS390XState *env = &cpu->env;
+
+ if (env->ext_index == MAX_EXT_QUEUE - 1) {
+ /* ugh - can't queue anymore. Let's drop. */
+ return;
+ }
+
+ env->ext_index++;
+ assert(env->ext_index < MAX_EXT_QUEUE);
+
+ env->ext_queue[env->ext_index].code = code;
+ env->ext_queue[env->ext_index].param = param;
+ env->ext_queue[env->ext_index].param64 = param64;
+
+ env->pending_int |= INTERRUPT_EXT;
+ cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
+
+static inline void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id,
+ uint16_t subchannel_number,
+ uint32_t io_int_parm, uint32_t io_int_word)
+{
+ CPUS390XState *env = &cpu->env;
+ int isc = IO_INT_WORD_ISC(io_int_word);
+
+ if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
+ /* ugh - can't queue anymore. Let's drop. */
+ return;
+ }
+
+ env->io_index[isc]++;
+ assert(env->io_index[isc] < MAX_IO_QUEUE);
+
+ env->io_queue[env->io_index[isc]][isc].id = subchannel_id;
+ env->io_queue[env->io_index[isc]][isc].nr = subchannel_number;
+ env->io_queue[env->io_index[isc]][isc].parm = io_int_parm;
+ env->io_queue[env->io_index[isc]][isc].word = io_int_word;
+
+ env->pending_int |= INTERRUPT_IO;
+ cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
+
+static inline void cpu_inject_crw_mchk(S390CPU *cpu)
+{
+ CPUS390XState *env = &cpu->env;
+
+ if (env->mchk_index == MAX_MCHK_QUEUE - 1) {
+ /* ugh - can't queue anymore. Let's drop. */
+ return;
+ }
+
+ env->mchk_index++;
+ assert(env->mchk_index < MAX_MCHK_QUEUE);
+
+ env->mchk_queue[env->mchk_index].type = 1;
+
+ env->pending_int |= INTERRUPT_MCHK;
+ cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
+
/* from s390-virtio-ccw */
#define MEM_SECTION_SIZE 0x10000000UL
#define MAX_AVAIL_SLOTS 32
@@ -1130,7 +1159,6 @@ void kvm_s390_reset_vcpu(S390CPU *cpu);
int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit);
void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu);
-int kvm_s390_get_ri(void);
void kvm_s390_crypto_reset(void);
#else
static inline void kvm_s390_io_interrupt(uint16_t subchannel_id,
@@ -1181,10 +1209,6 @@ static inline int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu)
{
return 0;
}
-static inline int kvm_s390_get_ri(void)
-{
- return 0;
-}
static inline void kvm_s390_crypto_reset(void)
{
}
@@ -1240,6 +1264,21 @@ static inline void s390_crypto_reset(void)
}
}
+#ifdef CONFIG_KVM
+static inline bool vregs_needed(void *opaque)
+{
+ if (kvm_enabled()) {
+ return kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS);
+ }
+ return 0;
+}
+#else
+static inline bool vregs_needed(void *opaque)
+{
+ return 0;
+}
+#endif
+
/* machine check interruption code */
/* subclasses */
diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c
index e604e9f7b..1c7f67354 100644
--- a/target-s390x/fpu_helper.c
+++ b/target-s390x/fpu_helper.c
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
#include "exec/helper-proto.h"
@@ -267,7 +266,7 @@ uint64_t HELPER(ldeb)(CPUS390XState *env, uint64_t f2)
{
float64 ret = float32_to_float64(f2, &env->fpu_status);
handle_exceptions(env, GETPC());
- return float64_maybe_silence_nan(ret, &env->fpu_status);
+ return float64_maybe_silence_nan(ret);
}
/* convert 128-bit float to 64-bit float */
@@ -275,7 +274,7 @@ uint64_t HELPER(ldxb)(CPUS390XState *env, uint64_t ah, uint64_t al)
{
float64 ret = float128_to_float64(make_float128(ah, al), &env->fpu_status);
handle_exceptions(env, GETPC());
- return float64_maybe_silence_nan(ret, &env->fpu_status);
+ return float64_maybe_silence_nan(ret);
}
/* convert 64-bit float to 128-bit float */
@@ -283,7 +282,7 @@ uint64_t HELPER(lxdb)(CPUS390XState *env, uint64_t f2)
{
float128 ret = float64_to_float128(f2, &env->fpu_status);
handle_exceptions(env, GETPC());
- return RET128(float128_maybe_silence_nan(ret, &env->fpu_status));
+ return RET128(float128_maybe_silence_nan(ret));
}
/* convert 32-bit float to 128-bit float */
@@ -291,7 +290,7 @@ uint64_t HELPER(lxeb)(CPUS390XState *env, uint64_t f2)
{
float128 ret = float32_to_float128(f2, &env->fpu_status);
handle_exceptions(env, GETPC());
- return RET128(float128_maybe_silence_nan(ret, &env->fpu_status));
+ return RET128(float128_maybe_silence_nan(ret));
}
/* convert 64-bit float to 32-bit float */
@@ -299,7 +298,7 @@ uint64_t HELPER(ledb)(CPUS390XState *env, uint64_t f2)
{
float32 ret = float64_to_float32(f2, &env->fpu_status);
handle_exceptions(env, GETPC());
- return float32_maybe_silence_nan(ret, &env->fpu_status);
+ return float32_maybe_silence_nan(ret);
}
/* convert 128-bit float to 32-bit float */
@@ -307,7 +306,7 @@ uint64_t HELPER(lexb)(CPUS390XState *env, uint64_t ah, uint64_t al)
{
float32 ret = float128_to_float32(make_float128(ah, al), &env->fpu_status);
handle_exceptions(env, GETPC());
- return float32_maybe_silence_nan(ret, &env->fpu_status);
+ return float32_maybe_silence_nan(ret);
}
/* 32-bit FP compare */
@@ -624,7 +623,7 @@ uint64_t HELPER(msdb)(CPUS390XState *env, uint64_t f1,
}
/* test data class 32-bit */
-uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2)
+uint32_t HELPER(tceb)(uint64_t f1, uint64_t m2)
{
float32 v1 = f1;
int neg = float32_is_neg(v1);
@@ -633,8 +632,7 @@ uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2)
if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
(float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
(float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
- (float32_is_signaling_nan(v1, &env->fpu_status) &&
- (m2 & (1 << (1-neg))))) {
+ (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
cc = 1;
} else if (m2 & (1 << (9-neg))) {
/* assume normalized number */
@@ -645,7 +643,7 @@ uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2)
}
/* test data class 64-bit */
-uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2)
+uint32_t HELPER(tcdb)(uint64_t v1, uint64_t m2)
{
int neg = float64_is_neg(v1);
uint32_t cc = 0;
@@ -653,8 +651,7 @@ uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2)
if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
(float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
(float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
- (float64_is_signaling_nan(v1, &env->fpu_status) &&
- (m2 & (1 << (1-neg))))) {
+ (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
cc = 1;
} else if (m2 & (1 << (9-neg))) {
/* assume normalized number */
@@ -665,8 +662,7 @@ uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2)
}
/* test data class 128-bit */
-uint32_t HELPER(tcxb)(CPUS390XState *env, uint64_t ah,
- uint64_t al, uint64_t m2)
+uint32_t HELPER(tcxb)(uint64_t ah, uint64_t al, uint64_t m2)
{
float128 v1 = make_float128(ah, al);
int neg = float128_is_neg(v1);
@@ -675,8 +671,7 @@ uint32_t HELPER(tcxb)(CPUS390XState *env, uint64_t ah,
if ((float128_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
(float128_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
(float128_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
- (float128_is_signaling_nan(v1, &env->fpu_status) &&
- (m2 & (1 << (1-neg))))) {
+ (float128_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
cc = 1;
} else if (m2 & (1 << (9-neg))) {
/* assume normalized number */
diff --git a/target-s390x/gdbstub.c b/target-s390x/gdbstub.c
index 3d223dec9..9fc36cb54 100644
--- a/target-s390x/gdbstub.c
+++ b/target-s390x/gdbstub.c
@@ -19,8 +19,6 @@
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
#include "exec/gdbstub.h"
#include "qemu/bitops.h"
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 54a517734..92abe7e67 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -23,9 +23,7 @@
#include "cpu.h"
#include "exec/gdbstub.h"
#include "qemu/timer.h"
-#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
-#include "hw/s390x/ioinst.h"
#ifndef CONFIG_USER_ONLY
#include "sysemu/sysemu.h"
#endif
@@ -70,7 +68,11 @@ void s390x_cpu_timer(void *opaque)
S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp)
{
- return S390_CPU(object_new(TYPE_S390_CPU));
+ S390CPU *cpu;
+
+ cpu = S390_CPU(object_new(TYPE_S390_CPU));
+
+ return cpu;
}
S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp)
@@ -684,7 +686,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs)
will be triggered, it will call load_psw which will recompute
the watchpoints. */
cpu_watchpoint_remove_all(cs, BP_CPU);
- cpu_loop_exit_noexc(cs);
+ cpu_resume_from_signal(cs, NULL);
}
}
#endif /* CONFIG_USER_ONLY */
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index 207a6e7d1..7e06119e9 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -67,9 +67,9 @@ DEF_HELPER_FLAGS_4(maeb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(madb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(mseb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(msdb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
-DEF_HELPER_FLAGS_3(tceb, TCG_CALL_NO_RWG_SE, i32, env, i64, i64)
-DEF_HELPER_FLAGS_3(tcdb, TCG_CALL_NO_RWG_SE, i32, env, i64, i64)
-DEF_HELPER_FLAGS_4(tcxb, TCG_CALL_NO_RWG_SE, i32, env, i64, i64, i64)
+DEF_HELPER_FLAGS_2(tceb, TCG_CALL_NO_RWG_SE, i32, i64, i64)
+DEF_HELPER_FLAGS_2(tcdb, TCG_CALL_NO_RWG_SE, i32, i64, i64)
+DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_NO_RWG_SE, i32, i64, i64, i64)
DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_2(sqeb, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_2(sqdb, TCG_CALL_NO_WG, i64, env, i64)
diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
index 370c94da5..cc1071eea 100644
--- a/target-s390x/int_helper.c
+++ b/target-s390x/int_helper.c
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
diff --git a/target-s390x/interrupt.c b/target-s390x/interrupt.c
index 9edef9679..bad60a7e1 100644
--- a/target-s390x/interrupt.c
+++ b/target-s390x/interrupt.c
@@ -10,77 +10,13 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "sysemu/kvm.h"
-#include "hw/s390x/ioinst.h"
-
-#if !defined(CONFIG_USER_ONLY)
-void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param,
- uint64_t param64)
-{
- CPUS390XState *env = &cpu->env;
-
- if (env->ext_index == MAX_EXT_QUEUE - 1) {
- /* ugh - can't queue anymore. Let's drop. */
- return;
- }
-
- env->ext_index++;
- assert(env->ext_index < MAX_EXT_QUEUE);
-
- env->ext_queue[env->ext_index].code = code;
- env->ext_queue[env->ext_index].param = param;
- env->ext_queue[env->ext_index].param64 = param64;
-
- env->pending_int |= INTERRUPT_EXT;
- cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-}
-
-static void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id,
- uint16_t subchannel_number,
- uint32_t io_int_parm, uint32_t io_int_word)
-{
- CPUS390XState *env = &cpu->env;
- int isc = IO_INT_WORD_ISC(io_int_word);
-
- if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
- /* ugh - can't queue anymore. Let's drop. */
- return;
- }
-
- env->io_index[isc]++;
- assert(env->io_index[isc] < MAX_IO_QUEUE);
-
- env->io_queue[env->io_index[isc]][isc].id = subchannel_id;
- env->io_queue[env->io_index[isc]][isc].nr = subchannel_number;
- env->io_queue[env->io_index[isc]][isc].parm = io_int_parm;
- env->io_queue[env->io_index[isc]][isc].word = io_int_word;
-
- env->pending_int |= INTERRUPT_IO;
- cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-}
-
-static void cpu_inject_crw_mchk(S390CPU *cpu)
-{
- CPUS390XState *env = &cpu->env;
-
- if (env->mchk_index == MAX_MCHK_QUEUE - 1) {
- /* ugh - can't queue anymore. Let's drop. */
- return;
- }
-
- env->mchk_index++;
- assert(env->mchk_index < MAX_MCHK_QUEUE);
-
- env->mchk_queue[env->mchk_index].type = 1;
-
- env->pending_int |= INTERRUPT_MCHK;
- cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-}
/*
* All of the following interrupts are floating, i.e. not per-vcpu.
* We just need a dummy cpustate in order to be able to inject in the
* non-kvm case.
*/
+#if !defined(CONFIG_USER_ONLY)
void s390_sclp_extint(uint32_t parm)
{
if (kvm_enabled()) {
diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index a5a288bec..142ff9384 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -12,7 +12,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "hw/s390x/ioinst.h"
+#include "ioinst.h"
#include "trace.h"
#include "hw/s390x/s390-pci-bus.h"
@@ -509,7 +509,6 @@ static void ioinst_handle_chsc_scsc(ChscReq *req, ChscResp *res)
general_chars[0] = cpu_to_be32(0x03000000);
general_chars[1] = cpu_to_be32(0x00059000);
- general_chars[3] = cpu_to_be32(0x00080000);
chsc_chars[0] = cpu_to_be32(0x40000000);
chsc_chars[3] = cpu_to_be32(0x00040000);
diff --git a/target-s390x/ioinst.h b/target-s390x/ioinst.h
new file mode 100644
index 000000000..013cc9148
--- /dev/null
+++ b/target-s390x/ioinst.h
@@ -0,0 +1,246 @@
+/*
+ * S/390 channel I/O instructions
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+*/
+
+#ifndef IOINST_S390X_H
+#define IOINST_S390X_H
+/*
+ * Channel I/O related definitions, as defined in the Principles
+ * Of Operation (and taken from the Linux implementation).
+ */
+
+/* subchannel status word (command mode only) */
+typedef struct SCSW {
+ uint16_t flags;
+ uint16_t ctrl;
+ uint32_t cpa;
+ uint8_t dstat;
+ uint8_t cstat;
+ uint16_t count;
+} QEMU_PACKED SCSW;
+
+#define SCSW_FLAGS_MASK_KEY 0xf000
+#define SCSW_FLAGS_MASK_SCTL 0x0800
+#define SCSW_FLAGS_MASK_ESWF 0x0400
+#define SCSW_FLAGS_MASK_CC 0x0300
+#define SCSW_FLAGS_MASK_FMT 0x0080
+#define SCSW_FLAGS_MASK_PFCH 0x0040
+#define SCSW_FLAGS_MASK_ISIC 0x0020
+#define SCSW_FLAGS_MASK_ALCC 0x0010
+#define SCSW_FLAGS_MASK_SSI 0x0008
+#define SCSW_FLAGS_MASK_ZCC 0x0004
+#define SCSW_FLAGS_MASK_ECTL 0x0002
+#define SCSW_FLAGS_MASK_PNO 0x0001
+
+#define SCSW_CTRL_MASK_FCTL 0x7000
+#define SCSW_CTRL_MASK_ACTL 0x0fe0
+#define SCSW_CTRL_MASK_STCTL 0x001f
+
+#define SCSW_FCTL_CLEAR_FUNC 0x1000
+#define SCSW_FCTL_HALT_FUNC 0x2000
+#define SCSW_FCTL_START_FUNC 0x4000
+
+#define SCSW_ACTL_SUSP 0x0020
+#define SCSW_ACTL_DEVICE_ACTIVE 0x0040
+#define SCSW_ACTL_SUBCH_ACTIVE 0x0080
+#define SCSW_ACTL_CLEAR_PEND 0x0100
+#define SCSW_ACTL_HALT_PEND 0x0200
+#define SCSW_ACTL_START_PEND 0x0400
+#define SCSW_ACTL_RESUME_PEND 0x0800
+
+#define SCSW_STCTL_STATUS_PEND 0x0001
+#define SCSW_STCTL_SECONDARY 0x0002
+#define SCSW_STCTL_PRIMARY 0x0004
+#define SCSW_STCTL_INTERMEDIATE 0x0008
+#define SCSW_STCTL_ALERT 0x0010
+
+#define SCSW_DSTAT_ATTENTION 0x80
+#define SCSW_DSTAT_STAT_MOD 0x40
+#define SCSW_DSTAT_CU_END 0x20
+#define SCSW_DSTAT_BUSY 0x10
+#define SCSW_DSTAT_CHANNEL_END 0x08
+#define SCSW_DSTAT_DEVICE_END 0x04
+#define SCSW_DSTAT_UNIT_CHECK 0x02
+#define SCSW_DSTAT_UNIT_EXCEP 0x01
+
+#define SCSW_CSTAT_PCI 0x80
+#define SCSW_CSTAT_INCORR_LEN 0x40
+#define SCSW_CSTAT_PROG_CHECK 0x20
+#define SCSW_CSTAT_PROT_CHECK 0x10
+#define SCSW_CSTAT_DATA_CHECK 0x08
+#define SCSW_CSTAT_CHN_CTRL_CHK 0x04
+#define SCSW_CSTAT_INTF_CTRL_CHK 0x02
+#define SCSW_CSTAT_CHAIN_CHECK 0x01
+
+/* path management control word */
+typedef struct PMCW {
+ uint32_t intparm;
+ uint16_t flags;
+ uint16_t devno;
+ uint8_t lpm;
+ uint8_t pnom;
+ uint8_t lpum;
+ uint8_t pim;
+ uint16_t mbi;
+ uint8_t pom;
+ uint8_t pam;
+ uint8_t chpid[8];
+ uint32_t chars;
+} QEMU_PACKED PMCW;
+
+#define PMCW_FLAGS_MASK_QF 0x8000
+#define PMCW_FLAGS_MASK_W 0x4000
+#define PMCW_FLAGS_MASK_ISC 0x3800
+#define PMCW_FLAGS_MASK_ENA 0x0080
+#define PMCW_FLAGS_MASK_LM 0x0060
+#define PMCW_FLAGS_MASK_MME 0x0018
+#define PMCW_FLAGS_MASK_MP 0x0004
+#define PMCW_FLAGS_MASK_TF 0x0002
+#define PMCW_FLAGS_MASK_DNV 0x0001
+#define PMCW_FLAGS_MASK_INVALID 0x0700
+
+#define PMCW_CHARS_MASK_ST 0x00e00000
+#define PMCW_CHARS_MASK_MBFC 0x00000004
+#define PMCW_CHARS_MASK_XMWME 0x00000002
+#define PMCW_CHARS_MASK_CSENSE 0x00000001
+#define PMCW_CHARS_MASK_INVALID 0xff1ffff8
+
+/* subchannel information block */
+typedef struct SCHIB {
+ PMCW pmcw;
+ SCSW scsw;
+ uint64_t mba;
+ uint8_t mda[4];
+} QEMU_PACKED SCHIB;
+
+/* interruption response block */
+typedef struct IRB {
+ SCSW scsw;
+ uint32_t esw[5];
+ uint32_t ecw[8];
+ uint32_t emw[8];
+} QEMU_PACKED IRB;
+
+/* operation request block */
+typedef struct ORB {
+ uint32_t intparm;
+ uint16_t ctrl0;
+ uint8_t lpm;
+ uint8_t ctrl1;
+ uint32_t cpa;
+} QEMU_PACKED ORB;
+
+#define ORB_CTRL0_MASK_KEY 0xf000
+#define ORB_CTRL0_MASK_SPND 0x0800
+#define ORB_CTRL0_MASK_STR 0x0400
+#define ORB_CTRL0_MASK_MOD 0x0200
+#define ORB_CTRL0_MASK_SYNC 0x0100
+#define ORB_CTRL0_MASK_FMT 0x0080
+#define ORB_CTRL0_MASK_PFCH 0x0040
+#define ORB_CTRL0_MASK_ISIC 0x0020
+#define ORB_CTRL0_MASK_ALCC 0x0010
+#define ORB_CTRL0_MASK_SSIC 0x0008
+#define ORB_CTRL0_MASK_C64 0x0002
+#define ORB_CTRL0_MASK_I2K 0x0001
+#define ORB_CTRL0_MASK_INVALID 0x0004
+
+#define ORB_CTRL1_MASK_ILS 0x80
+#define ORB_CTRL1_MASK_MIDAW 0x40
+#define ORB_CTRL1_MASK_ORBX 0x01
+#define ORB_CTRL1_MASK_INVALID 0x3e
+
+/* channel command word (type 0) */
+typedef struct CCW0 {
+ uint8_t cmd_code;
+ uint8_t cda0;
+ uint16_t cda1;
+ uint8_t flags;
+ uint8_t reserved;
+ uint16_t count;
+} QEMU_PACKED CCW0;
+
+/* channel command word (type 1) */
+typedef struct CCW1 {
+ uint8_t cmd_code;
+ uint8_t flags;
+ uint16_t count;
+ uint32_t cda;
+} QEMU_PACKED CCW1;
+
+#define CCW_FLAG_DC 0x80
+#define CCW_FLAG_CC 0x40
+#define CCW_FLAG_SLI 0x20
+#define CCW_FLAG_SKIP 0x10
+#define CCW_FLAG_PCI 0x08
+#define CCW_FLAG_IDA 0x04
+#define CCW_FLAG_SUSPEND 0x02
+
+#define CCW_CMD_NOOP 0x03
+#define CCW_CMD_BASIC_SENSE 0x04
+#define CCW_CMD_TIC 0x08
+#define CCW_CMD_SENSE_ID 0xe4
+
+typedef struct CRW {
+ uint16_t flags;
+ uint16_t rsid;
+} QEMU_PACKED CRW;
+
+#define CRW_FLAGS_MASK_S 0x4000
+#define CRW_FLAGS_MASK_R 0x2000
+#define CRW_FLAGS_MASK_C 0x1000
+#define CRW_FLAGS_MASK_RSC 0x0f00
+#define CRW_FLAGS_MASK_A 0x0080
+#define CRW_FLAGS_MASK_ERC 0x003f
+
+#define CRW_ERC_INIT 0x02
+#define CRW_ERC_IPI 0x04
+
+#define CRW_RSC_SUBCH 0x3
+#define CRW_RSC_CHP 0x4
+#define CRW_RSC_CSS 0xb
+
+/* I/O interruption code */
+typedef struct IOIntCode {
+ uint32_t subsys_id;
+ uint32_t intparm;
+ uint32_t interrupt_id;
+} QEMU_PACKED IOIntCode;
+
+/* schid disintegration */
+#define IOINST_SCHID_ONE(_schid) ((_schid & 0x00010000) >> 16)
+#define IOINST_SCHID_M(_schid) ((_schid & 0x00080000) >> 19)
+#define IOINST_SCHID_CSSID(_schid) ((_schid & 0xff000000) >> 24)
+#define IOINST_SCHID_SSID(_schid) ((_schid & 0x00060000) >> 17)
+#define IOINST_SCHID_NR(_schid) (_schid & 0x0000ffff)
+
+#define IO_INT_WORD_ISC(_int_word) ((_int_word & 0x38000000) >> 27)
+#define ISC_TO_ISC_BITS(_isc) ((0x80 >> _isc) << 24)
+
+#define IO_INT_WORD_AI 0x80000000
+
+int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
+ int *schid);
+void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
+void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
+void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb);
+void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
+int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
+void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb);
+int ioinst_handle_tpi(S390CPU *cpu, uint32_t ipb);
+void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
+ uint32_t ipb);
+void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1);
+
+#endif
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 80ac6215f..e1859cae0 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -23,17 +23,18 @@
#include "qemu/osdep.h"
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <linux/kvm.h>
#include <asm/ptrace.h>
#include "qemu-common.h"
-#include "cpu.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "hw/hw.h"
+#include "cpu.h"
#include "sysemu/device_tree.h"
#include "qapi/qmp/qjson.h"
#include "exec/gdbstub.h"
@@ -45,7 +46,6 @@
#include "hw/s390x/ipl.h"
#include "hw/s390x/ebcdic.h"
#include "exec/memattrs.h"
-#include "hw/s390x/s390-virtio-ccw.h"
/* #define DEBUG_KVM */
@@ -135,7 +135,6 @@ static int cap_sync_regs;
static int cap_async_pf;
static int cap_mem_op;
static int cap_s390_irq;
-static int cap_ri;
static void *legacy_s390_alloc(size_t size, uint64_t *align);
@@ -271,11 +270,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
kvm_vm_enable_cap(s, KVM_CAP_S390_USER_SIGP, 0);
kvm_vm_enable_cap(s, KVM_CAP_S390_VECTOR_REGISTERS, 0);
kvm_vm_enable_cap(s, KVM_CAP_S390_USER_STSI, 0);
- if (ri_allowed()) {
- if (kvm_vm_enable_cap(s, KVM_CAP_S390_RI, 0) == 0) {
- cap_ri = 1;
- }
- }
return 0;
}
@@ -392,11 +386,6 @@ int kvm_arch_put_registers(CPUState *cs, int level)
kvm_set_one_reg(cs, KVM_REG_S390_PP, &env->pp);
}
- if (can_sync_regs(cs, KVM_SYNC_RICCB)) {
- memcpy(cs->kvm_run->s.regs.riccb, env->riccb, 64);
- cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_RICCB;
- }
-
/* pfault parameters */
if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
cs->kvm_run->s.regs.pft = env->pfault_token;
@@ -539,10 +528,6 @@ int kvm_arch_get_registers(CPUState *cs)
kvm_get_one_reg(cs, KVM_REG_S390_PP, &env->pp);
}
- if (can_sync_regs(cs, KVM_SYNC_RICCB)) {
- memcpy(env->riccb, cs->kvm_run->s.regs.riccb, 64);
- }
-
/* pfault parameters */
if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
env->pfault_token = cs->kvm_run->s.regs.pft;
@@ -2070,9 +2055,8 @@ void kvm_s390_io_interrupt(uint16_t subchannel_id,
if (io_int_word & IO_INT_WORD_AI) {
irq.type = KVM_S390_INT_IO(1, 0, 0, 0);
} else {
- irq.type = KVM_S390_INT_IO(0, (subchannel_id & 0xff00) >> 8,
- (subchannel_id & 0x0006),
- subchannel_nr);
+ irq.type = ((subchannel_id & 0xff00) << 24) |
+ ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16);
}
kvm_s390_floating_interrupt(&irq);
}
@@ -2152,11 +2136,6 @@ int kvm_s390_get_memslot_count(KVMState *s)
return kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
}
-int kvm_s390_get_ri(void)
-{
- return cap_ri;
-}
-
int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
{
struct kvm_mp_state mp_state = {};
@@ -2246,10 +2225,10 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint64_t address, uint32_t data, PCIDevice *dev)
{
S390PCIBusDevice *pbdev;
- uint32_t idx = data >> ZPCI_MSI_VEC_BITS;
+ uint32_t fid = data >> ZPCI_MSI_VEC_BITS;
uint32_t vec = data & ZPCI_MSI_VEC_MASK;
- pbdev = s390_pci_find_dev_by_idx(idx);
+ pbdev = s390_pci_find_dev_by_fid(fid);
if (!pbdev) {
DPRINTF("add_msi_route no dev\n");
return -ENODEV;
@@ -2267,17 +2246,6 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
return 0;
}
-int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
- int vector, PCIDevice *dev)
-{
- return 0;
-}
-
-int kvm_arch_release_virq_post(int virq)
-{
- return 0;
-}
-
int kvm_arch_msi_data_to_gsi(uint32_t data)
{
abort();
diff --git a/target-s390x/machine.c b/target-s390x/machine.c
index aa39e5daa..6b2609054 100644
--- a/target-s390x/machine.c
+++ b/target-s390x/machine.c
@@ -76,16 +76,6 @@ static const VMStateDescription vmstate_fpu = {
}
};
-static bool vregs_needed(void *opaque)
-{
-#ifdef CONFIG_KVM
- if (kvm_enabled()) {
- return kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS);
- }
-#endif
- return 0;
-}
-
static const VMStateDescription vmstate_vregs = {
.name = "cpu/vregs",
.version_id = 1,
@@ -145,27 +135,6 @@ static const VMStateDescription vmstate_vregs = {
}
};
-static bool riccb_needed(void *opaque)
-{
-#ifdef CONFIG_KVM
- if (kvm_enabled()) {
- return kvm_s390_get_ri();
- }
-#endif
- return 0;
-}
-
-const VMStateDescription vmstate_riccb = {
- .name = "cpu/riccb",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = riccb_needed,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8_ARRAY(env.riccb, S390CPU, 64),
- VMSTATE_END_OF_LIST()
- }
-};
-
const VMStateDescription vmstate_s390_cpu = {
.name = "cpu",
.post_load = cpu_post_load,
@@ -197,7 +166,6 @@ const VMStateDescription vmstate_s390_cpu = {
.subsections = (const VMStateDescription*[]) {
&vmstate_fpu,
&vmstate_vregs,
- &vmstate_riccb,
NULL
},
};
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index 99bc5e283..707862203 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -21,12 +21,8 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
-
-#if !defined(CONFIG_USER_ONLY)
#include "hw/s390x/storage-keys.h"
-#endif
/*****************************************************************************/
/* Softmmu support */
@@ -36,12 +32,12 @@
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
/* XXX: fix it to restore all registers */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
- int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+ uintptr_t retaddr)
{
int ret;
- ret = s390_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+ ret = s390_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
if (unlikely(ret != 0)) {
if (likely(retaddr)) {
/* now we have a real cpu fault */
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 86da1947b..71cbe34e0 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -29,11 +29,10 @@
#ifdef CONFIG_KVM
#include <linux/kvm.h>
#endif
-#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
+#include "hw/watchdog/wdt_diag288.h"
#if !defined(CONFIG_USER_ONLY)
-#include "hw/watchdog/wdt_diag288.h"
#include "sysemu/cpus.h"
#include "sysemu/sysemu.h"
#include "hw/s390x/ebcdic.h"
@@ -233,23 +232,10 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC);
return;
}
- iplb = g_malloc0(sizeof(IplParameterBlock));
- cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));
- if (!iplb_valid_len(iplb)) {
- env->regs[r1 + 1] = DIAG_308_RC_INVALID;
- goto out;
- }
-
- cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
-
- if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {
- env->regs[r1 + 1] = DIAG_308_RC_INVALID;
- goto out;
- }
-
+ iplb = g_malloc0(sizeof(struct IplParameterBlock));
+ cpu_physical_memory_read(addr, iplb, sizeof(struct IplParameterBlock));
s390_ipl_update_diag308(iplb);
env->regs[r1 + 1] = DIAG_308_RC_OK;
-out:
g_free(iplb);
return;
case 6:
@@ -264,7 +250,8 @@ out:
}
iplb = s390_ipl_get_iplb();
if (iplb) {
- cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));
+ cpu_physical_memory_write(addr, iplb,
+ sizeof(struct IplParameterBlock));
env->regs[r1 + 1] = DIAG_308_RC_OK;
} else {
env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
diff --git a/target-s390x/trace-events b/target-s390x/trace-events
deleted file mode 100644
index df59f5f19..000000000
--- a/target-s390x/trace-events
+++ /dev/null
@@ -1,22 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# target-s390x/mmu_helper.c
-get_skeys_nonzero(int rc) "SKEY: Call to get_skeys unexpectedly returned %d"
-set_skeys_nonzero(int rc) "SKEY: Call to set_skeys unexpectedly returned %d"
-
-# target-s390x/ioinst.c
-ioinst(const char *insn) "IOINST: %s"
-ioinst_sch_id(const char *insn, int cssid, int ssid, int schid) "IOINST: %s (%x.%x.%04x)"
-ioinst_chp_id(const char *insn, int cssid, int chpid) "IOINST: %s (%x.%02x)"
-ioinst_chsc_cmd(uint16_t cmd, uint16_t len) "IOINST: chsc command %04x, len %04x"
-
-# target-s390x/kvm.c
-kvm_enable_cmma(int rc) "CMMA: enabling with result code %d"
-kvm_clear_cmma(int rc) "CMMA: clearing with result code %d"
-kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s"
-kvm_sigp_finished(uint8_t order, int cpu_index, int dst_index, int cc) "SIGP: Finished order %u on cpu %d -> cpu %d with cc=%d"
-
-# target-s390x/cpu.c
-cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8
-cpu_halt(int cpu_index) "halting cpu %d"
-cpu_unhalt(int cpu_index) "unhalting cpu %d"
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 1a07d70b2..c871ef2bb 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -31,7 +31,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "disas/disas.h"
-#include "exec/exec-all.h"
#include "tcg-op.h"
#include "qemu/log.h"
#include "qemu/host-utils.h"
@@ -169,7 +168,6 @@ void s390x_translate_init(void)
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- tcg_ctx.tcg_env = cpu_env;
psw_addr = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUS390XState, psw.addr),
"psw_addr");
@@ -610,17 +608,12 @@ static void gen_op_calc_cc(DisasContext *s)
static int use_goto_tb(DisasContext *s, uint64_t dest)
{
- if (unlikely(s->singlestep_enabled) ||
- (s->tb->cflags & CF_LAST_IO) ||
- (s->tb->flags & FLAG_MASK_PER)) {
- return false;
- }
-#ifndef CONFIG_USER_ONLY
- return (dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
- (dest & TARGET_PAGE_MASK) == (s->pc & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
+ /* NOTE: we handle the case where the TB spans two pages here */
+ return (((dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK)
+ || (dest & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))
+ && !s->singlestep_enabled
+ && !(s->tb->cflags & CF_LAST_IO)
+ && !(s->tb->flags & FLAG_MASK_PER));
}
static void account_noninline_branch(DisasContext *s, int cc_op)
@@ -3986,21 +3979,21 @@ static ExitStatus op_svc(DisasContext *s, DisasOps *o)
static ExitStatus op_tceb(DisasContext *s, DisasOps *o)
{
- gen_helper_tceb(cc_op, cpu_env, o->in1, o->in2);
+ gen_helper_tceb(cc_op, o->in1, o->in2);
set_cc_static(s);
return NO_EXIT;
}
static ExitStatus op_tcdb(DisasContext *s, DisasOps *o)
{
- gen_helper_tcdb(cc_op, cpu_env, o->in1, o->in2);
+ gen_helper_tcdb(cc_op, o->in1, o->in2);
set_cc_static(s);
return NO_EXIT;
}
static ExitStatus op_tcxb(DisasContext *s, DisasOps *o)
{
- gen_helper_tcxb(cc_op, cpu_env, o->out, o->out2, o->in2);
+ gen_helper_tcxb(cc_op, o->out, o->out2, o->in2);
set_cc_static(s);
return NO_EXIT;
}
@@ -5430,8 +5423,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
tb->icount = num_insns;
#if defined(S390X_DEBUG_DISAS)
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
- && qemu_log_in_addr_range(pc_start)) {
+ if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("IN: %s\n", lookup_symbol(pc_start));
log_target_disas(cs, pc_start, dc.pc - pc_start, 1);
qemu_log("\n");