From patchwork Wed Jun 17 10:42:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 485343 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B04E61401DA for ; Wed, 17 Jun 2015 20:54:30 +1000 (AEST) Received: from localhost ([::1]:45636 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z5AzE-0007ln-Ns for incoming@patchwork.ozlabs.org; Wed, 17 Jun 2015 06:54:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55578) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z5AoP-0004aN-9A for qemu-devel@nongnu.org; Wed, 17 Jun 2015 06:43:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z5AoK-0005WU-ET for qemu-devel@nongnu.org; Wed, 17 Jun 2015 06:43:17 -0400 Received: from cantor2.suse.de ([195.135.220.15]:52303 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z5AoK-0005VP-4M for qemu-devel@nongnu.org; Wed, 17 Jun 2015 06:43:12 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id BAED47501E; Wed, 17 Jun 2015 10:43:10 +0000 (UTC) From: Alexander Graf To: qemu-devel@nongnu.org Date: Wed, 17 Jun 2015 12:42:53 +0200 Message-Id: <1434537789-63782-11-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1434537789-63782-1-git-send-email-agraf@suse.de> References: <1434537789-63782-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 195.135.220.15 Cc: peter.maydell@linaro.org, Aurelien Jarno Subject: [Qemu-devel] [PULL 10/26] target-s390x: wire up I/O instructions in TCG mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The code handling the I/O instructions for KVM decodes the instruction itself. In TCG mode also pass the full instruction word to the helpers. Signed-off-by: Alexander Graf Signed-off-by: Aurelien Jarno Signed-off-by: Alexander Graf --- target-s390x/helper.h | 11 ++++++ target-s390x/insn-data.def | 22 +++++------ target-s390x/misc_helper.c | 62 +++++++++++++++++++++++++++++ target-s390x/translate.c | 98 ++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 179 insertions(+), 14 deletions(-) diff --git a/target-s390x/helper.h b/target-s390x/helper.h index 6be9f44..53db519 100644 --- a/target-s390x/helper.h +++ b/target-s390x/helper.h @@ -116,4 +116,15 @@ DEF_HELPER_FLAGS_2(lura, TCG_CALL_NO_WG, i64, env, i64) DEF_HELPER_FLAGS_2(lurag, TCG_CALL_NO_WG, i64, env, i64) DEF_HELPER_FLAGS_3(stura, TCG_CALL_NO_WG, void, env, i64, i64) DEF_HELPER_FLAGS_3(sturg, TCG_CALL_NO_WG, void, env, i64, i64) + +DEF_HELPER_2(xsch, void, env, i64) +DEF_HELPER_2(csch, void, env, i64) +DEF_HELPER_2(hsch, void, env, i64) +DEF_HELPER_3(msch, void, env, i64, i64) +DEF_HELPER_2(rchp, void, env, i64) +DEF_HELPER_2(rsch, void, env, i64) +DEF_HELPER_3(ssch, void, env, i64, i64) +DEF_HELPER_3(stsch, void, env, i64, i64) +DEF_HELPER_3(tsch, void, env, i64, i64) +DEF_HELPER_2(chsc, void, env, i64) #endif diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def index fe5e591..075ff59 100644 --- a/target-s390x/insn-data.def +++ b/target-s390x/insn-data.def @@ -915,17 +915,17 @@ /* TEST PROTECTION */ C(0xe501, TPROT, SSE, Z, la1, a2, 0, 0, tprot, 0) -/* I/O Instructions. For each we simply indicate non-operation. */ - C(0xb276, XSCH, S, Z, 0, 0, 0, 0, subchannel, 0) - C(0xb230, CSCH, S, Z, 0, 0, 0, 0, subchannel, 0) - C(0xb231, HSCH, S, Z, 0, 0, 0, 0, subchannel, 0) - C(0xb232, MSCH, S, Z, 0, 0, 0, 0, subchannel, 0) - C(0xb23b, RCHP, S, Z, 0, 0, 0, 0, subchannel, 0) - C(0xb238, RSCH, S, Z, 0, 0, 0, 0, subchannel, 0) - C(0xb233, SSCH, S, Z, 0, 0, 0, 0, subchannel, 0) - C(0xb234, STSCH, S, Z, 0, 0, 0, 0, subchannel, 0) - C(0xb235, TSCH, S, Z, 0, 0, 0, 0, subchannel, 0) +/* CCW I/O Instructions */ + C(0xb276, XSCH, S, Z, 0, 0, 0, 0, xsch, 0) + C(0xb230, CSCH, S, Z, 0, 0, 0, 0, csch, 0) + C(0xb231, HSCH, S, Z, 0, 0, 0, 0, hsch, 0) + C(0xb232, MSCH, S, Z, 0, insn, 0, 0, msch, 0) + C(0xb23b, RCHP, S, Z, 0, 0, 0, 0, rchp, 0) + C(0xb238, RSCH, S, Z, 0, 0, 0, 0, rsch, 0) + C(0xb233, SSCH, S, Z, 0, insn, 0, 0, ssch, 0) + C(0xb234, STSCH, S, Z, 0, insn, 0, 0, stsch, 0) + C(0xb235, TSCH, S, Z, 0, insn, 0, 0, tsch, 0) /* ??? Not listed in PoO ninth edition, but there's a linux driver that uses it: "A CHSC subchannel is usually present on LPAR only." */ - C(0xb25f, CHSC, S, Z, 0, 0, 0, 0, subchannel, 0) + C(0xb25f, CHSC, RRE, Z, 0, insn, 0, 0, chsc, 0) #endif /* CONFIG_USER_ONLY */ diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c index c32aebf..7d66ce1 100644 --- a/target-s390x/misc_helper.c +++ b/target-s390x/misc_helper.c @@ -532,3 +532,65 @@ uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1, return cc; } #endif + +#ifndef CONFIG_USER_ONLY +void HELPER(xsch)(CPUS390XState *env, uint64_t r1) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_xsch(cpu, r1); +} + +void HELPER(csch)(CPUS390XState *env, uint64_t r1) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_csch(cpu, r1); +} + +void HELPER(hsch)(CPUS390XState *env, uint64_t r1) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_hsch(cpu, r1); +} + +void HELPER(msch)(CPUS390XState *env, uint64_t r1, uint64_t inst) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_msch(cpu, r1, inst >> 16); +} + +void HELPER(rchp)(CPUS390XState *env, uint64_t r1) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_rchp(cpu, r1); +} + +void HELPER(rsch)(CPUS390XState *env, uint64_t r1) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_rsch(cpu, r1); +} + +void HELPER(ssch)(CPUS390XState *env, uint64_t r1, uint64_t inst) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_ssch(cpu, r1, inst >> 16); +} + +void HELPER(stsch)(CPUS390XState *env, uint64_t r1, uint64_t inst) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_stsch(cpu, r1, inst >> 16); +} + +void HELPER(tsch)(CPUS390XState *env, uint64_t r1, uint64_t inst) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_tsch(cpu, r1, inst >> 16); +} + +void HELPER(chsc)(CPUS390XState *env, uint64_t inst) +{ + S390CPU *cpu = s390_env_get_cpu(env); + ioinst_handle_chsc(cpu, inst >> 16); +} +#endif diff --git a/target-s390x/translate.c b/target-s390x/translate.c index bde5e8a..df3389d 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -1001,6 +1001,7 @@ enum DisasFieldIndexC { }; struct DisasFields { + uint64_t raw_insn; unsigned op:8; unsigned op2:8; unsigned presentC:16; @@ -3588,11 +3589,93 @@ static ExitStatus op_spx(DisasContext *s, DisasOps *o) return NO_EXIT; } -static ExitStatus op_subchannel(DisasContext *s, DisasOps *o) +static ExitStatus op_xsch(DisasContext *s, DisasOps *o) { check_privileged(s); - /* Not operational. */ - gen_op_movi_cc(s, 3); + potential_page_fault(s); + gen_helper_xsch(cpu_env, regs[1]); + set_cc_static(s); + return NO_EXIT; +} + +static ExitStatus op_csch(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + potential_page_fault(s); + gen_helper_csch(cpu_env, regs[1]); + set_cc_static(s); + return NO_EXIT; +} + +static ExitStatus op_hsch(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + potential_page_fault(s); + gen_helper_hsch(cpu_env, regs[1]); + set_cc_static(s); + return NO_EXIT; +} + +static ExitStatus op_msch(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + potential_page_fault(s); + gen_helper_msch(cpu_env, regs[1], o->in2); + set_cc_static(s); + return NO_EXIT; +} + +static ExitStatus op_rchp(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + potential_page_fault(s); + gen_helper_rchp(cpu_env, regs[1]); + set_cc_static(s); + return NO_EXIT; +} + +static ExitStatus op_rsch(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + potential_page_fault(s); + gen_helper_rsch(cpu_env, regs[1]); + set_cc_static(s); + return NO_EXIT; +} + +static ExitStatus op_ssch(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + potential_page_fault(s); + gen_helper_ssch(cpu_env, regs[1], o->in2); + set_cc_static(s); + return NO_EXIT; +} + +static ExitStatus op_stsch(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + potential_page_fault(s); + gen_helper_stsch(cpu_env, regs[1], o->in2); + set_cc_static(s); + return NO_EXIT; +} + +static ExitStatus op_tsch(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + potential_page_fault(s); + gen_helper_tsch(cpu_env, regs[1], o->in2); + set_cc_static(s); + return NO_EXIT; +} + +static ExitStatus op_chsc(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + potential_page_fault(s); + gen_helper_chsc(cpu_env, o->in2); + set_cc_static(s); return NO_EXIT; } @@ -4843,6 +4926,14 @@ static void in2_i2_32u_shl(DisasContext *s, DisasFields *f, DisasOps *o) } #define SPEC_in2_i2_32u_shl 0 +#ifndef CONFIG_USER_ONLY +static void in2_insn(DisasContext *s, DisasFields *f, DisasOps *o) +{ + o->in2 = tcg_const_i64(s->fields->raw_insn); +} +#define SPEC_in2_insn 0 +#endif + /* ====================================================================== */ /* Find opc within the table of insns. This is formulated as a switch @@ -5019,6 +5110,7 @@ static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s, } memset(f, 0, sizeof(*f)); + f->raw_insn = insn; f->op = op; f->op2 = op2;