From patchwork Sat Sep 26 05:00:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Gang X-Patchwork-Id: 523069 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 15D9A140549 for ; Sat, 26 Sep 2015 15:01:18 +1000 (AEST) Received: from localhost ([::1]:51947 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zfhbn-00062w-Tq for incoming@patchwork.ozlabs.org; Sat, 26 Sep 2015 01:01:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35854) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZfhbY-0005lM-Jq for qemu-devel@nongnu.org; Sat, 26 Sep 2015 01:01:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZfhbV-0002vt-Cn for qemu-devel@nongnu.org; Sat, 26 Sep 2015 01:01:00 -0400 Received: from smtpbg62.qq.com ([103.7.29.139]:20613 helo=smtpbg64.qq.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZfhbU-0002lT-HV for qemu-devel@nongnu.org; Sat, 26 Sep 2015 01:00:57 -0400 X-QQ-mid: esmtp32t1443243637t771t15918 Received: from localhost.localdomain (unknown [223.72.67.103]) by esmtp4.qq.com (ESMTP) with id ; Sat, 26 Sep 2015 13:00:36 +0800 (CST) X-QQ-SSF: 01000000000000F0FH600F00002000H X-QQ-FEAT: QX/rXDl9P1spsd84sos+vL4RmqIjhZvKzBsvQ1oDEybCu/xFAuwN1b8Nhfql8 JtKybEJS+0OD2e0j90nyg2Gx6TlbKTI14EZXSIz+Gf6aW29z6KwySoCSDTn2Q6z6spgiKSC 9ZmPghb5VA91Z8hPPG76z2ShmZfwNBxwgOktNFqxcpdDVRWzGfz9xIAPp1lGAa6s6/0s7Am +CpWZdWrqazzC8FQCZGAdh2xhFOlcDnnOzu+0z3WZgHrplnwb4KXf X-QQ-GoodBg: 0 X-QQ-CSender: gang.chen.5i5j@qq.com From: gang.chen.5i5j@gmail.com To: riku.voipio@iki.fi, peter.maydell@linaro.org, rth@twiddle.net Date: Sat, 26 Sep 2015 13:00:35 +0800 Message-Id: <1443243635-4886-1-git-send-email-gang.chen.5i5j@gmail.com> X-Mailer: git-send-email 1.9.3 X-QQ-SENDSIZE: 520 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 103.7.29.139 Cc: cmetcalf@ezchip.com, qemu-devel@nongnu.org, xili_gchen_5257@hotmail.com, Chen Gang Subject: [Qemu-devel] [PATCH] tilegx: Generate ill related instructions according to Linux kernel 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 From: Chen Gang At present, tilegx qemu will abort for "setup_frame: not implemented", when meet raise instruction. Signed-off-by: Chen Gang --- linux-user/main.c | 14 ++++++++ target-tilegx/cpu.h | 3 ++ target-tilegx/translate.c | 89 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 92 insertions(+), 14 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 782037d..7e49931 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3436,6 +3436,17 @@ static void gen_sigill_reg(CPUTLGState *env) queue_signal(env, info.si_signo, &info); } +static void gen_sigill(CPUTLGState *env) +{ + target_siginfo_t info; + + info.si_signo = env->signo; + info.si_errno = 0; + info.si_code = env->sigcode; + info._sifields._sigfault._addr = env->pc; + queue_signal(env, info.si_signo, &info); +} + static void set_regval(CPUTLGState *env, uint8_t reg, uint64_t val) { if (unlikely(reg >= TILEGX_R_COUNT)) { @@ -3622,6 +3633,9 @@ void cpu_loop(CPUTLGState *env) case TILEGX_EXCP_OPCODE_FETCHOR4: do_fetch(env, trapnr, false); break; + case TILEGX_EXCP_OPCODE_ILL: + gen_sigill(env); + break; case TILEGX_EXCP_REG_IDN_ACCESS: case TILEGX_EXCP_REG_UDN_ACCESS: gen_sigill_reg(env); diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h index b9f5082..72a1878 100644 --- a/target-tilegx/cpu.h +++ b/target-tilegx/cpu.h @@ -75,6 +75,7 @@ typedef enum { TILEGX_EXCP_OPCODE_FETCHAND4 = 0x10c, TILEGX_EXCP_OPCODE_FETCHOR = 0x10d, TILEGX_EXCP_OPCODE_FETCHOR4 = 0x10e, + TILEGX_EXCP_OPCODE_ILL = 0x10f, TILEGX_EXCP_REG_IDN_ACCESS = 0x181, TILEGX_EXCP_REG_UDN_ACCESS = 0x182, TILEGX_EXCP_UNALIGNMENT = 0x201, @@ -86,6 +87,8 @@ typedef struct CPUTLGState { uint64_t spregs[TILEGX_SPR_COUNT]; /* Special used registers by outside */ uint64_t pc; /* Current pc */ + uint64_t signo; /* Signal number */ + uint64_t sigcode; /* Signal code */ #if defined(CONFIG_USER_ONLY) uint64_t atomic_srca; /* Arguments to atomic "exceptions" */ uint64_t atomic_srcb; diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c index 6622aeb..969c66e 100644 --- a/target-tilegx/translate.c +++ b/target-tilegx/translate.c @@ -23,6 +23,8 @@ #include "disas/disas.h" #include "tcg-op.h" #include "exec/cpu_ldst.h" +#include "linux-user/syscall_defs.h" + #include "opcode_tilegx.h" #include "spr_def_64.h" @@ -378,8 +380,74 @@ static void gen_v4op(TCGv d64, TCGv a64, TCGv b64, tcg_temp_free_i32(bh); } +static TileExcp gen_ill(DisasContext *dc, int signo, int sigcode, + const char *mnemonic) +{ + TCGv t0 = tcg_const_tl(signo); + TCGv t1 = tcg_const_tl(sigcode); + + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUTLGState, signo)); + tcg_gen_st_tl(t1, cpu_env, offsetof(CPUTLGState, sigcode)); + + tcg_temp_free(t1); + tcg_temp_free(t0); + + qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic); + return TILEGX_EXCP_OPCODE_ILL; +} + +static int parse_from_addli(uint64_t bundle, int *signo, int *sigcode) +{ + if ((get_Opcode_X0(bundle) != ADDLI_OPCODE_X0) + || (get_Dest_X0(bundle) != TILEGX_R_ZERO) + || (get_SrcA_X0(bundle) != TILEGX_R_ZERO)) { + return 0; + } + + *signo = get_Imm16_X0(bundle) & 0x3f; + *sigcode = (get_Imm16_X0(bundle) >> 6) & 0xf; + + switch (*signo) { + case TARGET_SIGILL: + return *sigcode <= TARGET_NSIGILL; + case TARGET_SIGFPE: + return *sigcode <= TARGET_NSIGFPE; + case TARGET_SIGSEGV: + return *sigcode <= TARGET_NSIGSEGV; + case TARGET_SIGBUS: + return *sigcode <= TARGET_NSIGBUS; + case TARGET_SIGTRAP: + return *sigcode <= TARGET_NSIGTRAP; + default: + return 0; + } +} + +static TileExcp gen_specill(DisasContext *dc, unsigned dest, unsigned srca, + uint64_t bundle) +{ + const char *mnemonic; + int signo; + int sigcode; + + if (dest == 0x1c && srca == 0x25) { + signo = TARGET_SIGTRAP; + sigcode = TARGET_TRAP_BRKPT; + mnemonic = "bpt"; + } else if (dest == 0x1d && srca == 0x25 + && parse_from_addli(bundle, &signo, &sigcode)) { + mnemonic = "raise"; + } else { + signo = TARGET_SIGILL; + sigcode = TARGET_ILL_ILLOPC; + mnemonic = "ill"; + } + + return gen_ill(dc, signo, sigcode, mnemonic); +} + static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext, - unsigned dest, unsigned srca) + unsigned dest, unsigned srca, uint64_t bundle) { TCGv tdest, tsrca; const char *mnemonic; @@ -407,16 +475,9 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext, mnemonic = "flushwb"; goto done0; case OE_RR_X1(ILL): - if (dest == 0x1c && srca == 0x25) { - mnemonic = "bpt"; - goto done2; - } - /* Fall through */ + return gen_specill(dc, dest, srca, bundle); case OE_RR_Y1(ILL): - mnemonic = "ill"; - done2: - qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic); - return TILEGX_EXCP_OPCODE_UNKNOWN; + return gen_ill(dc, TARGET_SIGILL, TARGET_ILL_ILLOPC, "ill"); case OE_RR_X1(MF): mnemonic = "mf"; goto done0; @@ -1806,7 +1867,7 @@ static TileExcp decode_y0(DisasContext *dc, tilegx_bundle_bits bundle) case RRR_1_OPCODE_Y0: if (ext == UNARY_RRR_1_OPCODE_Y0) { ext = get_UnaryOpcodeExtension_Y0(bundle); - return gen_rr_opcode(dc, OE(opc, ext, Y0), dest, srca); + return gen_rr_opcode(dc, OE(opc, ext, Y0), dest, srca, bundle); } /* fallthru */ case RRR_0_OPCODE_Y0: @@ -1852,7 +1913,7 @@ static TileExcp decode_y1(DisasContext *dc, tilegx_bundle_bits bundle) case RRR_1_OPCODE_Y1: if (ext == UNARY_RRR_1_OPCODE_Y0) { ext = get_UnaryOpcodeExtension_Y1(bundle); - return gen_rr_opcode(dc, OE(opc, ext, Y1), dest, srca); + return gen_rr_opcode(dc, OE(opc, ext, Y1), dest, srca, bundle); } /* fallthru */ case RRR_0_OPCODE_Y1: @@ -1954,7 +2015,7 @@ static TileExcp decode_x0(DisasContext *dc, tilegx_bundle_bits bundle) ext = get_RRROpcodeExtension_X0(bundle); if (ext == UNARY_RRR_0_OPCODE_X0) { ext = get_UnaryOpcodeExtension_X0(bundle); - return gen_rr_opcode(dc, OE(opc, ext, X0), dest, srca); + return gen_rr_opcode(dc, OE(opc, ext, X0), dest, srca, bundle); } srcb = get_SrcB_X0(bundle); return gen_rrr_opcode(dc, OE(opc, ext, X0), dest, srca, srcb); @@ -2001,7 +2062,7 @@ static TileExcp decode_x1(DisasContext *dc, tilegx_bundle_bits bundle) switch (ext) { case UNARY_RRR_0_OPCODE_X1: ext = get_UnaryOpcodeExtension_X1(bundle); - return gen_rr_opcode(dc, OE(opc, ext, X1), dest, srca); + return gen_rr_opcode(dc, OE(opc, ext, X1), dest, srca, bundle); case ST1_RRR_0_OPCODE_X1: return gen_st_opcode(dc, dest, srca, srcb, MO_UB, "st1"); case ST2_RRR_0_OPCODE_X1: