From patchwork Thu Aug 20 21:44:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chen Gang X-Patchwork-Id: 509177 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 C6A6B140772 for ; Fri, 21 Aug 2015 07:44:18 +1000 (AEST) Received: from localhost ([::1]:37299 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZSXdA-0007Zz-PT for incoming@patchwork.ozlabs.org; Thu, 20 Aug 2015 17:44:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48240) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZSXbn-0006Uj-B8 for qemu-devel@nongnu.org; Thu, 20 Aug 2015 17:42:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZSXbi-00063P-5P for qemu-devel@nongnu.org; Thu, 20 Aug 2015 17:42:51 -0400 Received: from blu004-omc1s1.hotmail.com ([65.55.116.12]:64951) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZSXbi-00063B-2W for qemu-devel@nongnu.org; Thu, 20 Aug 2015 17:42:46 -0400 Received: from BLU436-SMTP10 ([65.55.116.8]) by BLU004-OMC1S1.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Thu, 20 Aug 2015 14:42:45 -0700 X-TMN: [zT6ClnddXSe4OVggrGflw9wEQPie+/gh] X-Originating-Email: [xili_gchen_5257@hotmail.com] Message-ID: Date: Fri, 21 Aug 2015 05:44:27 +0800 From: Chen Gang User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: Peter Maydell , "rth@twiddle.net" , Chris Metcalf , =?windows-1252?Q?Andreas_F=E4rber?= , "walt@tilera.com" , Riku Voipio References: In-Reply-To: X-OriginalArrivalTime: 20 Aug 2015 21:42:44.0136 (UTC) FILETIME=[259A6280:01D0DB91] X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 65.55.116.12 Cc: qemu-devel Subject: [Qemu-devel] [PATCH 11/16 v1] target-tilegx: Add related feature to support iret instruction 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 In fact, iret itself needs nothing, but the related previous and next instructions need to be implemented. SPR_EX_CONTEXT_0_0 and SPR_EX_CONTEXT_0_1 are related with iret, so let them in a patch. Signed-off-by: Chen Gang --- target-tilegx/cpu.h | 2 ++ target-tilegx/translate.c | 86 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h index e404025..808f4e5 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/translate.c b/target-tilegx/translate.c index 1dd3a43..541d603 100644 --- a/target-tilegx/translate.c +++ b/target-tilegx/translate.c @@ -48,7 +48,7 @@ static const char * const reg_names[] = { }; static const char * const spreg_names[] = { - "cmpexch", "criticalsec", "simcontrol" + "cmpexch", "criticalsec", "simcontrol", "excontext00", "excontext01" }; /* It is for temporary registers */ @@ -174,6 +174,71 @@ static void gen_swint1(struct DisasContext *dc) } /* + * Description + * + * Returns from an interrupt. Transfers control flow to the program counter + * location and protection level contained in the current PL ’s EX_CONTEXT + * registers, and restores the interrupt critical section bit to the value + * contained in those registers. + * + * Functional Description + * + * setNextPC(sprf [EX_CONTEXT_SPRF_OFFSET + + * (getCurrentProtectionLevel() * EX_CONTEXT_SIZE) + + * PC_EX_CONTEXT_OFFSET]); + * branchPredictedIncorrect(); + * setProtectionLevel(sprf [EX_CONTEXT_SPRF_OFFSET + + * (getCurrentProtectionLevel() * EX_CONTEXT_SIZE) + + * PROTECTION_LEVEL_EX_CONTEXT_OFFSET]); + * setInterruptCriticalSection( + * sprf [EX_CONTEXT_SPRF_OFFSET + + * (getCurrentProtectionLevel() * EX_CONTEXT_SIZE) + + * INTERRUPT_CRITICAL_SECTION_EX_CONTEXT_OFFSET]); + * + * besides the PC we need to set our new protection level, and set the interrupt + * critical section bit atomically inside of this instruction + */ +static void gen_iret(struct DisasContext *dc) +{ + qemu_log_mask(CPU_LOG_TB_IN_ASM, "iret\n"); + /* + * In user mode, all related things are already done by previous and next + * instructions, so just skip it. Can reference __longjmp code for it. + * + * 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 + */ +} + +/* * Many SPR reads/writes have side effects and cannot be buffered. However, they * are all in the X1 pipe, which we are excuting last, therefore we need not do * additional buffering. @@ -197,6 +262,12 @@ static void gen_mfspr(struct DisasContext *dc, uint8_t rdst, uint16_t imm14) case SPR_SIM_CONTROL: tcg_gen_mov_i64(cpu_regs[rdst], cpu_spregs[TILEGX_SPR_SIM_CONTROL]); return; + case SPR_EX_CONTEXT_0_0: + tcg_gen_mov_i64(cpu_regs[rdst], cpu_spregs[TILEGX_SPR_EX_CONTEXT_0_0]); + return; + case SPR_EX_CONTEXT_0_1: + tcg_gen_mov_i64(cpu_regs[rdst], cpu_spregs[TILEGX_SPR_EX_CONTEXT_0_1]); + return; default: qemu_log_mask(LOG_UNIMP, "UNIMP mfspr 0x%x.\n", imm14); } @@ -218,6 +289,12 @@ static void gen_mtspr(struct DisasContext *dc, uint8_t rsrc, uint16_t imm14) case SPR_SIM_CONTROL: tcg_gen_mov_i64(cpu_spregs[TILEGX_SPR_SIM_CONTROL], load_gr(dc, rsrc)); return; + case SPR_EX_CONTEXT_0_0: + tcg_gen_mov_i64(cpu_spregs[TILEGX_SPR_EX_CONTEXT_0_0], load_gr(dc, rsrc)); + return; + case SPR_EX_CONTEXT_0_1: + tcg_gen_mov_i64(cpu_spregs[TILEGX_SPR_EX_CONTEXT_0_1], load_gr(dc, rsrc)); + return; default: qemu_log_mask(LOG_UNIMP, "UNIMP mtspr 0x%x.\n", imm14); } @@ -2257,6 +2334,12 @@ static void decode_u_opcode_ex_x1(struct DisasContext *dc, return; } break; + case IRET_UNARY_OPCODE_X1: + if (!rdst && !rsrc) { + gen_iret(dc); + return; + } + break; case SWINT1_UNARY_OPCODE_X1: if (!rsrc && !rdst) { gen_swint1(dc); @@ -2277,7 +2360,6 @@ static void decode_u_opcode_ex_x1(struct DisasContext *dc, case ICOH_UNARY_OPCODE_X1: case ILL_UNARY_OPCODE_X1: case INV_UNARY_OPCODE_X1: - case IRET_UNARY_OPCODE_X1: case LDNT1S_UNARY_OPCODE_X1: case LDNT1U_UNARY_OPCODE_X1: case LDNT2S_UNARY_OPCODE_X1: