From patchwork Sun Oct 4 11:14:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chen Gang X-Patchwork-Id: 526099 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 E424F1402B4 for ; Sun, 4 Oct 2015 22:15:52 +1100 (AEDT) Received: from localhost ([::1]:42082 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZihGh-0004jM-0K for incoming@patchwork.ozlabs.org; Sun, 04 Oct 2015 07:15:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58534) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZihFh-0003lg-Nc for qemu-devel@nongnu.org; Sun, 04 Oct 2015 07:14:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZihFc-0003wi-Cp for qemu-devel@nongnu.org; Sun, 04 Oct 2015 07:14:49 -0400 Received: from col004-omc2s5.hotmail.com ([65.55.34.79]:61362) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZihFc-0003wX-1O for qemu-devel@nongnu.org; Sun, 04 Oct 2015 07:14:44 -0400 Received: from COL130-W51 ([65.55.34.72]) by COL004-OMC2S5.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Sun, 4 Oct 2015 04:14:43 -0700 X-TMN: [fM7bSeE7aPFLcsEtmUWUcj/nAFI5VaTA] X-Originating-Email: [xili_gchen_5257@hotmail.com] Message-ID: From: Chen Gang To: "rth@twiddle.net" , Peter Maydell , Chris Metcalf Date: Sun, 4 Oct 2015 19:14:42 +0800 Importance: Normal MIME-Version: 1.0 X-OriginalArrivalTime: 04 Oct 2015 11:14:43.0245 (UTC) FILETIME=[DEA175D0:01D0FE95] X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 65.55.34.79 Cc: qemu-devel Subject: [Qemu-devel] [PATCH v4] target-tilegx: Support iret instruction and related special registers 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 8e8d35fffd735df997c78324b301f22cf270b515 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Sun, 4 Oct 2015 17:41:14 +0800 Subject: [PATCH v4] target-tilegx: Support iret instruction and related special registers Acording to the __longjmp tilegx libc implementation, and reference from tilegx ISA document, and suggested by tilegx architecture member, we can treat iret instruction as "jrp lr". The related code is below:   ENTRY (__longjmp)          FEEDBACK_ENTER(__longjmp)   #define RESTORE(r) { LD r, r0 ; ADDI_PTR r0, r0, REGSIZE }          FOR_EACH_CALLEE_SAVED_REG(RESTORE)          {           LD r2, r0       ; retrieve ICS bit from jmp_buf           movei r3, 1           CMPEQI r0, r1, 0          }          {           mtspr INTERRUPT_CRITICAL_SECTION, r3           shli r2, r2, SPR_EX_CONTEXT_0_1__ICS_SHIFT          }          {           mtspr EX_CONTEXT_0_0, lr           ori r2, r2, RETURN_PL          }          {           or r0, r1, r0           mtspr EX_CONTEXT_0_1, r2          }          iret          jrp lr EX_CONTEXT_0_0 is used for jumping address, and EX_CONTEXT_0_1 is for INTERRUPT_CRITICAL_SECTION, which should only be 0 or 1 in user mode, or it will cause target SEGV (and the patch doesn't implement system mode). "jrp lr" in __longjmp is for historical reasons, and might get removed in the future. Signed-off-by: Chen Gang ---  target-tilegx/cpu.h       |  2 ++  target-tilegx/helper.c    | 22 ++++++++++++++++++++++  target-tilegx/helper.h    |  1 +  target-tilegx/translate.c | 14 +++++++++++++-  4 files changed, 38 insertions(+), 1 deletion(-) --  1.9.3 diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h index 6f04fe7..6c0fd53 100644 --- a/target-tilegx/cpu.h +++ b/target-tilegx/cpu.h @@ -53,6 +53,8 @@ enum {      TILEGX_SPR_CMPEXCH = 0,      TILEGX_SPR_CRITICAL_SEC = 1,      TILEGX_SPR_SIM_CONTROL = 2, +    TILEGX_SPR_EX_CONTEXT_0_0 = 3, +    TILEGX_SPR_EX_CONTEXT_0_1 = 4,      TILEGX_SPR_COUNT  };   diff --git a/target-tilegx/helper.c b/target-tilegx/helper.c index 36b287f..3c043f8 100644 --- a/target-tilegx/helper.c +++ b/target-tilegx/helper.c @@ -22,6 +22,7 @@  #include "qemu-common.h"  #include "exec/helper-proto.h"  #include /* For crc32 */ +#include "syscall_defs.h"    void helper_exception(CPUTLGState *env, uint32_t excp)  { @@ -31,6 +32,27 @@ void helper_exception(CPUTLGState *env, uint32_t excp)      cpu_loop_exit(cs);  }   +void helper_ext01_ics(CPUTLGState *env) +{ +    uint64_t val = env->spregs[TILEGX_SPR_EX_CONTEXT_0_1]; + +    switch (val) { +    case 0: +    case 1: +        env->spregs[TILEGX_SPR_CRITICAL_SEC] = val; +        break; +    default: +#if defined(CONFIG_USER_ONLY) +        env->signo = TARGET_SIGSEGV; +        env->sigcode = 0; +        helper_exception(env, TILEGX_EXCP_SIGNAL); +#else +        helper_exception(env, TILEGX_EXCP_OPCODE_UNIMPLEMENTED); +#endif +        break; +    } +} +  uint64_t helper_cntlz(uint64_t arg)  {      return clz64(arg); diff --git a/target-tilegx/helper.h b/target-tilegx/helper.h index bbcc476..9281d0f 100644 --- a/target-tilegx/helper.h +++ b/target-tilegx/helper.h @@ -1,4 +1,5 @@  DEF_HELPER_2(exception, noreturn, env, i32) +DEF_HELPER_1(ext01_ics, void, env)  DEF_HELPER_FLAGS_1(cntlz, TCG_CALL_NO_RWG_SE, i64, i64)  DEF_HELPER_FLAGS_1(cnttz, TCG_CALL_NO_RWG_SE, i64, i64)  DEF_HELPER_FLAGS_1(pcnt, TCG_CALL_NO_RWG_SE, i64, i64) diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c index ab3fc81..acb9ec4 100644 --- a/target-tilegx/translate.c +++ b/target-tilegx/translate.c @@ -529,6 +529,15 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,          /* ??? This should yield, especially in system mode.  */          mnemonic = "nap";          goto done0; +    case OE_RR_X1(IRET): +        gen_helper_ext01_ics(cpu_env); +        dc->jmp.cond = TCG_COND_ALWAYS; +        dc->jmp.dest = tcg_temp_new(); +        tcg_gen_ld_tl(dc->jmp.dest, cpu_env, +                      offsetof(CPUTLGState, spregs[TILEGX_SPR_EX_CONTEXT_0_0])); +        tcg_gen_andi_tl(dc->jmp.dest, dc->jmp.dest, ~7); +        mnemonic = "iret"; +        goto done0;      case OE_RR_X1(SWINT0):      case OE_RR_X1(SWINT2):      case OE_RR_X1(SWINT3): @@ -606,7 +615,6 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,          break;      case OE_RR_X0(FSINGLE_PACK1):      case OE_RR_Y0(FSINGLE_PACK1): -    case OE_RR_X1(IRET):          return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;      case OE_RR_X1(LD1S):          memop = MO_SB; @@ -1947,6 +1955,10 @@ static const TileSPR *find_spr(unsigned spr)        offsetof(CPUTLGState, spregs[TILEGX_SPR_CRITICAL_SEC]), 0, 0)      D(SIM_CONTROL,        offsetof(CPUTLGState, spregs[TILEGX_SPR_SIM_CONTROL]), 0, 0) +    D(EX_CONTEXT_0_0, +      offsetof(CPUTLGState, spregs[TILEGX_SPR_EX_CONTEXT_0_0]), 0, 0) +    D(EX_CONTEXT_0_1, +      offsetof(CPUTLGState, spregs[TILEGX_SPR_EX_CONTEXT_0_1]), 0, 0)      }    #undef D