From nobody Tue Feb 10 13:01:45 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 150060509215133.23383289135063; Thu, 20 Jul 2017 19:44:52 -0700 (PDT) Received: from localhost ([::1]:40719 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dYNvt-00014U-Ve for importer@patchew.org; Thu, 20 Jul 2017 22:44:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40075) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dYNoo-0003uT-5R for qemu-devel@nongnu.org; Thu, 20 Jul 2017 22:37:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dYNom-0007Wh-PH for qemu-devel@nongnu.org; Thu, 20 Jul 2017 22:37:30 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:44231) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dYNom-0007WI-Gu for qemu-devel@nongnu.org; Thu, 20 Jul 2017 22:37:28 -0400 Received: from HHMAIL01.hh.imgtec.org (unknown [10.100.10.19]) by Forcepoint Email with ESMTPS id B4C9343E2B0F2; Fri, 21 Jul 2017 03:37:24 +0100 (IST) Received: from hhmipssw204.hh.imgtec.org (10.100.21.121) by HHMAIL01.hh.imgtec.org (10.100.10.21) with Microsoft SMTP Server (TLS) id 14.3.294.0; Fri, 21 Jul 2017 03:37:26 +0100 From: Yongbok Kim To: Date: Fri, 21 Jul 2017 03:37:07 +0100 Message-ID: <1500604635-15027-7-git-send-email-yongbok.kim@imgtec.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1500604635-15027-1-git-send-email-yongbok.kim@imgtec.com> References: <1500604635-15027-1-git-send-email-yongbok.kim@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.21.121] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 195.59.15.196 Subject: [Qemu-devel] [PULL 06/14] target/mips: Decode MIPS32 EVA load & store instructions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , James Hogan , Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: James Hogan Implement decoding of MIPS32 EVA loads and stores. These access the user address space from kernel mode when implemented, so for each instruction we need to check that EVA is available from Config5.EVA & check for sufficient COP0 privilege (with the new check_eva()), and then override the mem_idx used for the operation. Unfortunately some Loongson 2E instructions use overlapping encodings, so we must be careful not to prevent those from being decoded when EVA is absent. Signed-off-by: James Hogan Cc: Yongbok Kim Cc: Aurelien Jarno Reviewed-by: Yongbok Kim Signed-off-by: Yongbok Kim --- target/mips/translate.c | 106 ++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 106 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 38887a1..93fb8f3 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -427,6 +427,24 @@ enum { OPC_EXTR_W_DSP =3D 0x38 | OPC_SPECIAL3, OPC_DEXTR_W_DSP =3D 0x3C | OPC_SPECIAL3, =20 + /* EVA */ + OPC_LWLE =3D 0x19 | OPC_SPECIAL3, + OPC_LWRE =3D 0x1A | OPC_SPECIAL3, + OPC_CACHEE =3D 0x1B | OPC_SPECIAL3, + OPC_SBE =3D 0x1C | OPC_SPECIAL3, + OPC_SHE =3D 0x1D | OPC_SPECIAL3, + OPC_SCE =3D 0x1E | OPC_SPECIAL3, + OPC_SWE =3D 0x1F | OPC_SPECIAL3, + OPC_SWLE =3D 0x21 | OPC_SPECIAL3, + OPC_SWRE =3D 0x22 | OPC_SPECIAL3, + OPC_PREFE =3D 0x23 | OPC_SPECIAL3, + OPC_LBUE =3D 0x28 | OPC_SPECIAL3, + OPC_LHUE =3D 0x29 | OPC_SPECIAL3, + OPC_LBE =3D 0x2C | OPC_SPECIAL3, + OPC_LHE =3D 0x2D | OPC_SPECIAL3, + OPC_LLE =3D 0x2E | OPC_SPECIAL3, + OPC_LWE =3D 0x2F | OPC_SPECIAL3, + /* R6 */ R6_OPC_PREF =3D 0x35 | OPC_SPECIAL3, R6_OPC_CACHE =3D 0x25 | OPC_SPECIAL3, @@ -1431,6 +1449,7 @@ typedef struct DisasContext { bool bp; uint64_t PAMask; bool mvh; + bool eva; int CP0_LLAddr_shift; bool ps; bool vp; @@ -2216,29 +2235,47 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL); gen_store_gpr(t0, rt); break; + case OPC_LWE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_LW: tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | ctx->default_tcg_memop_mask); gen_store_gpr(t0, rt); break; + case OPC_LHE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_LH: tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | ctx->default_tcg_memop_mask); gen_store_gpr(t0, rt); break; + case OPC_LHUE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_LHU: tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | ctx->default_tcg_memop_mask); gen_store_gpr(t0, rt); break; + case OPC_LBE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_LB: tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); gen_store_gpr(t0, rt); break; + case OPC_LBUE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_LBU: tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); gen_store_gpr(t0, rt); break; + case OPC_LWLE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_LWL: t1 =3D tcg_temp_new(); /* Do a byte access to possibly trigger a page @@ -2262,6 +2299,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_ext32s_tl(t0, t0); gen_store_gpr(t0, rt); break; + case OPC_LWRE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_LWR: t1 =3D tcg_temp_new(); /* Do a byte access to possibly trigger a page @@ -2286,6 +2326,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_ext32s_tl(t0, t0); gen_store_gpr(t0, rt); break; + case OPC_LLE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_LL: case R6_OPC_LL: op_ld_ll(t0, t0, mem_idx, ctx); @@ -2318,20 +2361,35 @@ static void gen_st (DisasContext *ctx, uint32_t opc= , int rt, gen_helper_0e2i(sdr, t1, t0, mem_idx); break; #endif + case OPC_SWE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_SW: tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | ctx->default_tcg_memop_mask); break; + case OPC_SHE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_SH: tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | ctx->default_tcg_memop_mask); break; + case OPC_SBE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_SB: tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); break; + case OPC_SWLE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_SWL: gen_helper_0e2i(swl, t1, t0, mem_idx); break; + case OPC_SWRE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_SWR: gen_helper_0e2i(swr, t1, t0, mem_idx); break; @@ -2364,6 +2422,9 @@ static void gen_st_cond (DisasContext *ctx, uint32_t = opc, int rt, op_st_scd(t1, t0, rt, mem_idx, ctx); break; #endif + case OPC_SCE: + mem_idx =3D MIPS_HFLAG_UM; + /* fall through */ case OPC_SC: case R6_OPC_SC: op_st_sc(t1, t0, rt, mem_idx, ctx); @@ -18020,13 +18081,57 @@ static void decode_opc_special3(CPUMIPSState *env= , DisasContext *ctx) { int rs, rt, rd, sa; uint32_t op1, op2; + int16_t imm; =20 rs =3D (ctx->opcode >> 21) & 0x1f; rt =3D (ctx->opcode >> 16) & 0x1f; rd =3D (ctx->opcode >> 11) & 0x1f; sa =3D (ctx->opcode >> 6) & 0x1f; + imm =3D sextract32(ctx->opcode, 7, 9); =20 op1 =3D MASK_SPECIAL3(ctx->opcode); + + /* + * EVA loads and stores overlap Loongson 2E instructions decoded by + * decode_opc_special3_legacy(), so be careful to allow their decoding= when + * EVA is absent. + */ + if (ctx->eva) { + switch (op1) { + case OPC_LWLE ... OPC_LWRE: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + /* fall through */ + case OPC_LBUE ... OPC_LHUE: + case OPC_LBE ... OPC_LWE: + check_cp0_enabled(ctx); + gen_ld(ctx, op1, rt, rs, imm); + return; + case OPC_SWLE ... OPC_SWRE: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + /* fall through */ + case OPC_SBE ... OPC_SHE: + case OPC_SWE: + check_cp0_enabled(ctx); + gen_st(ctx, op1, rt, rs, imm); + return; + case OPC_SCE: + check_cp0_enabled(ctx); + gen_st_cond(ctx, op1, rt, rs, imm); + return; + case OPC_CACHEE: + check_cp0_enabled(ctx); + if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { + gen_cache_operation(ctx, rt, rs, imm); + } + /* Treat as NOP. */ + return; + case OPC_PREFE: + check_cp0_enabled(ctx); + /* Treat as NOP. */ + return; + } + } + switch (op1) { case OPC_EXT: case OPC_INS: @@ -19925,6 +20030,7 @@ void gen_intermediate_code(CPUState *cs, struct Tra= nslationBlock *tb) ctx.bp =3D (env->CP0_Config3 >> CP0C3_BP) & 1; ctx.PAMask =3D env->PAMask; ctx.mvh =3D (env->CP0_Config5 >> CP0C5_MVH) & 1; + ctx.eva =3D (env->CP0_Config5 >> CP0C5_EVA) & 1; ctx.CP0_LLAddr_shift =3D env->CP0_LLAddr_shift; ctx.cmgcr =3D (env->CP0_Config3 >> CP0C3_CMGCR) & 1; /* Restore delay slot state from the tb context. */ --=20 2.7.4