From: Yongbok Kim <yongbok.kim@imgtec.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
James Hogan <james.hogan@imgtec.com>,
Aurelien Jarno <aurelien@aurel32.net>
Subject: [Qemu-devel] [PULL 06/14] target/mips: Decode MIPS32 EVA load & store instructions
Date: Fri, 21 Jul 2017 03:37:07 +0100 [thread overview]
Message-ID: <1500604635-15027-7-git-send-email-yongbok.kim@imgtec.com> (raw)
In-Reply-To: <1500604635-15027-1-git-send-email-yongbok.kim@imgtec.com>
From: James Hogan <james.hogan@imgtec.com>
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 <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
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 = 0x38 | OPC_SPECIAL3,
OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
+ /* EVA */
+ OPC_LWLE = 0x19 | OPC_SPECIAL3,
+ OPC_LWRE = 0x1A | OPC_SPECIAL3,
+ OPC_CACHEE = 0x1B | OPC_SPECIAL3,
+ OPC_SBE = 0x1C | OPC_SPECIAL3,
+ OPC_SHE = 0x1D | OPC_SPECIAL3,
+ OPC_SCE = 0x1E | OPC_SPECIAL3,
+ OPC_SWE = 0x1F | OPC_SPECIAL3,
+ OPC_SWLE = 0x21 | OPC_SPECIAL3,
+ OPC_SWRE = 0x22 | OPC_SPECIAL3,
+ OPC_PREFE = 0x23 | OPC_SPECIAL3,
+ OPC_LBUE = 0x28 | OPC_SPECIAL3,
+ OPC_LHUE = 0x29 | OPC_SPECIAL3,
+ OPC_LBE = 0x2C | OPC_SPECIAL3,
+ OPC_LHE = 0x2D | OPC_SPECIAL3,
+ OPC_LLE = 0x2E | OPC_SPECIAL3,
+ OPC_LWE = 0x2F | OPC_SPECIAL3,
+
/* R6 */
R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
R6_OPC_CACHE = 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 = 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 = 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 = 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 = 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 = 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 = MIPS_HFLAG_UM;
+ /* fall through */
case OPC_LWL:
t1 = 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 = MIPS_HFLAG_UM;
+ /* fall through */
case OPC_LWR:
t1 = 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 = 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 = 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 = 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 = 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 = MIPS_HFLAG_UM;
+ /* fall through */
case OPC_SWL:
gen_helper_0e2i(swl, t1, t0, mem_idx);
break;
+ case OPC_SWRE:
+ mem_idx = 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 = 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;
rs = (ctx->opcode >> 21) & 0x1f;
rt = (ctx->opcode >> 16) & 0x1f;
rd = (ctx->opcode >> 11) & 0x1f;
sa = (ctx->opcode >> 6) & 0x1f;
+ imm = sextract32(ctx->opcode, 7, 9);
op1 = 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 TranslationBlock *tb)
ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
ctx.PAMask = env->PAMask;
ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
+ ctx.eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
/* Restore delay slot state from the tb context. */
--
2.7.4
next prev parent reply other threads:[~2017-07-21 2:37 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-21 2:37 [Qemu-devel] [PULL 00/14] target-mips queue Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 01/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 02/14] target/mips: Fix TLBWI shadow flush for EHINV, XI, RI Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 03/14] target/mips: Weaken TLB flush on UX, SX, KX, ASID changes Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 04/14] target/mips: Add CP0_Ebase.WG (write gate) support Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 05/14] target/mips: Prepare loads/stores for EVA Yongbok Kim
2017-07-21 2:37 ` Yongbok Kim [this message]
2017-07-21 2:37 ` [Qemu-devel] [PULL 07/14] target/mips: Decode microMIPS EVA load & store instructions Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 08/14] target/mips: Check memory permissions with mem_idx Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 09/14] target/mips: Abstract mmu_idx from hflags Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 10/14] target/mips: Add an MMU mode for ERL Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 11/14] target/mips: Add segmentation control registers Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 12/14] target/mips: Implement segmentation control Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 13/14] target/mips: Add EVA support to P5600 Yongbok Kim
2017-07-21 2:37 ` [Qemu-devel] [PULL 14/14] target/mips: Enable CP0_EBase.WG on MIPS64 CPUs Yongbok Kim
2017-07-21 13:08 ` [Qemu-devel] [PULL 00/14] target-mips queue Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1500604635-15027-7-git-send-email-yongbok.kim@imgtec.com \
--to=yongbok.kim@imgtec.com \
--cc=aurelien@aurel32.net \
--cc=james.hogan@imgtec.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).