From patchwork Sun Oct 9 23:42:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 680125 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 3ssgKL5jd2z9ry7 for ; Mon, 10 Oct 2016 11:01:58 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=UIdDQjbG; dkim-atps=neutral Received: from localhost ([::1]:46432 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1btO2V-00019k-L8 for incoming@patchwork.ozlabs.org; Sun, 09 Oct 2016 20:01:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45028) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1btNkW-0002KA-KP for qemu-devel@nongnu.org; Sun, 09 Oct 2016 19:43:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1btNkU-0000cG-PA for qemu-devel@nongnu.org; Sun, 09 Oct 2016 19:43:20 -0400 Received: from mail-qt0-x244.google.com ([2607:f8b0:400d:c0d::244]:36182) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1btNkU-0000bl-JB for qemu-devel@nongnu.org; Sun, 09 Oct 2016 19:43:18 -0400 Received: by mail-qt0-x244.google.com with SMTP id y38so2812469qta.3 for ; Sun, 09 Oct 2016 16:43:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=zvS9o99YS/9jF1qXGOu8uo29FdtOiSpuF9Z4jCyX2zw=; b=UIdDQjbG/diuXqObnTLyd+M79UKwip8hzJNHkn0qZBU1ZXPy//0hx34a/5I/n9VxOD H/v9+3/Jf5YgTp6yyt+HCy+8wNlU6Ft8rUdfoNvxZgoi01IlWXkNieTMiS/WRgvc9PdI LwNxXuPaGKil8EBydqVmKlpUWpSp1UfLFxb2MU5Gq4rxdo/QLlWbIA70cumsiN7Yqx82 8kbrsh9T/MwVmzhO4lNekd5RmE/NXWZlwoYiDG0FuItqyKXM/LICMvJ6ityLugWychGY PzsZ/e+eiy4eIER7Xg25Fh+iI0w6O7lzMvOPPtQDbI9jLb2IbYIP1ryund9QrtmrdbQv BHsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=zvS9o99YS/9jF1qXGOu8uo29FdtOiSpuF9Z4jCyX2zw=; b=OO74EtxkJWfGSK+TWOdDQcsbJQtv/0EVp/BKCTYtufVkns90Ko4iEVM2M4PObAfvby +WwYQsYfSy4aJTzNiPwvFqEBs0DMQTh491qmlouShZt8CSVhk5CucZx/H6xjSYvDfCea 8Zdkv89aMRv4qnX5u14CFlOtSSbNZHDAj1Lcd+f6Fj0YH7Rx509DbFCp3ypT24U9Nl3o XDl1qa/Uh543wJupzX0rEd1lT73x+B7f4KCXsYdsXeGtPFNHeNFgOob4UB1BYzArqT4e O3M9rnQyi4hN/ydZVLWl1ig3KbpORPxn9RvtR635c2gqtwE/ZEcaYajM8AJ7xzz2Y8Xe zrlA== X-Gm-Message-State: AA6/9Rk+nbU244t3ki21GOpIIz3JHI3SgGOaAbbCJ8XHEf7GejTdgAbTMBttqxBEOrP/qg== X-Received: by 10.200.34.66 with SMTP id p2mr6297401qtp.107.1476056598038; Sun, 09 Oct 2016 16:43:18 -0700 (PDT) Received: from bigtime.com ([187.217.227.243]) by smtp.gmail.com with ESMTPSA id g63sm10741172qkf.47.2016.10.09.16.43.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 09 Oct 2016 16:43:17 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sun, 9 Oct 2016 18:42:05 -0500 Message-Id: <1476056526-30740-35-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476056526-30740-1-git-send-email-rth@twiddle.net> References: <1476056526-30740-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c0d::244 Subject: [Qemu-devel] [PATCH v5 34/35] target-alpha: Introduce MMU_PHYS_IDX 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: alex.bennee@linaro.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Rather than using helpers for physical accesses, use a mmu index. The primary cleanup is with store-conditional on physical addresses. Signed-off-by: Richard Henderson --- target-alpha/cpu.h | 18 +++++------- target-alpha/helper.c | 8 ++++++ target-alpha/helper.h | 9 ------ target-alpha/mem_helper.c | 73 ----------------------------------------------- target-alpha/translate.c | 50 ++++++++++++++++++-------------- 5 files changed, 44 insertions(+), 114 deletions(-) diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index dcdd041..871d9ba 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -201,7 +201,7 @@ enum { /* MMU modes definitions */ -/* Alpha has 5 MMU modes: PALcode, kernel, executive, supervisor, and user. +/* Alpha has 5 MMU modes: PALcode, Kernel, Executive, Supervisor, and User. The Unix PALcode only exposes the kernel and user modes; presumably executive and supervisor are used by VMS. @@ -209,22 +209,18 @@ enum { there are PALmode instructions that can access data via physical mode or via an os-installed "alternate mode", which is one of the 4 above. - QEMU does not currently properly distinguish between code/data when - looking up addresses. To avoid having to address this issue, our - emulated PALcode will cheat and use the KSEG mapping for its code+data - rather than physical addresses. + That said, we're only emulating Unix PALcode, and not attempting VMS, + so we don't need to implement Executive and Supervisor. QEMU's own + PALcode cheats and usees the KSEG mapping for its code+data rather than + physical addresses. */ - Moreover, we're only emulating Unix PALcode, and not attempting VMS. - - All of which allows us to drop all but kernel and user modes. - Elide the unused MMU modes to save space. */ - -#define NB_MMU_MODES 2 +#define NB_MMU_MODES 3 #define MMU_MODE0_SUFFIX _kernel #define MMU_MODE1_SUFFIX _user #define MMU_KERNEL_IDX 0 #define MMU_USER_IDX 1 +#define MMU_PHYS_IDX 2 typedef struct CPUAlphaState CPUAlphaState; diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 85168b7..9ba3e1a 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -126,6 +126,14 @@ static int get_physical_address(CPUAlphaState *env, target_ulong addr, int prot = 0; int ret = MM_K_ACV; + /* Handle physical accesses. */ + if (mmu_idx == MMU_PHYS_IDX) { + phys = addr; + prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + ret = -1; + goto exit; + } + /* Ensure that the virtual address is properly sign-extended from the last implemented virtual address bit. */ if (saddr >> TARGET_VIRT_ADDR_SPACE_BITS != saddr >> 63) { diff --git a/target-alpha/helper.h b/target-alpha/helper.h index c3d8a3e..004221d 100644 --- a/target-alpha/helper.h +++ b/target-alpha/helper.h @@ -92,15 +92,6 @@ DEF_HELPER_FLAGS_2(ieee_input_cmp, TCG_CALL_NO_WG, void, env, i64) DEF_HELPER_FLAGS_2(ieee_input_s, TCG_CALL_NO_WG, void, env, i64) #if !defined (CONFIG_USER_ONLY) -DEF_HELPER_2(ldl_phys, i64, env, i64) -DEF_HELPER_2(ldq_phys, i64, env, i64) -DEF_HELPER_2(ldl_l_phys, i64, env, i64) -DEF_HELPER_2(ldq_l_phys, i64, env, i64) -DEF_HELPER_3(stl_phys, void, env, i64, i64) -DEF_HELPER_3(stq_phys, void, env, i64, i64) -DEF_HELPER_3(stl_c_phys, i64, env, i64, i64) -DEF_HELPER_3(stq_c_phys, i64, env, i64, i64) - DEF_HELPER_FLAGS_1(tbia, TCG_CALL_NO_RWG, void, env) DEF_HELPER_FLAGS_2(tbis, TCG_CALL_NO_RWG, void, env, i64) DEF_HELPER_FLAGS_1(tb_flush, TCG_CALL_NO_RWG, void, env) diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c index 1b2be50..78a7d45 100644 --- a/target-alpha/mem_helper.c +++ b/target-alpha/mem_helper.c @@ -25,79 +25,6 @@ /* Softmmu support */ #ifndef CONFIG_USER_ONLY - -uint64_t helper_ldl_phys(CPUAlphaState *env, uint64_t p) -{ - CPUState *cs = CPU(alpha_env_get_cpu(env)); - return (int32_t)ldl_phys(cs->as, p); -} - -uint64_t helper_ldq_phys(CPUAlphaState *env, uint64_t p) -{ - CPUState *cs = CPU(alpha_env_get_cpu(env)); - return ldq_phys(cs->as, p); -} - -uint64_t helper_ldl_l_phys(CPUAlphaState *env, uint64_t p) -{ - CPUState *cs = CPU(alpha_env_get_cpu(env)); - env->lock_addr = p; - return env->lock_value = (int32_t)ldl_phys(cs->as, p); -} - -uint64_t helper_ldq_l_phys(CPUAlphaState *env, uint64_t p) -{ - CPUState *cs = CPU(alpha_env_get_cpu(env)); - env->lock_addr = p; - return env->lock_value = ldq_phys(cs->as, p); -} - -void helper_stl_phys(CPUAlphaState *env, uint64_t p, uint64_t v) -{ - CPUState *cs = CPU(alpha_env_get_cpu(env)); - stl_phys(cs->as, p, v); -} - -void helper_stq_phys(CPUAlphaState *env, uint64_t p, uint64_t v) -{ - CPUState *cs = CPU(alpha_env_get_cpu(env)); - stq_phys(cs->as, p, v); -} - -uint64_t helper_stl_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v) -{ - CPUState *cs = CPU(alpha_env_get_cpu(env)); - uint64_t ret = 0; - - if (p == env->lock_addr) { - int32_t old = ldl_phys(cs->as, p); - if (old == (int32_t)env->lock_value) { - stl_phys(cs->as, p, v); - ret = 1; - } - } - env->lock_addr = -1; - - return ret; -} - -uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v) -{ - CPUState *cs = CPU(alpha_env_get_cpu(env)); - uint64_t ret = 0; - - if (p == env->lock_addr) { - uint64_t old = ldq_phys(cs->as, p); - if (old == env->lock_value) { - stq_phys(cs->as, p, v); - ret = 1; - } - } - env->lock_addr = -1; - - return ret; -} - void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr) diff --git a/target-alpha/translate.c b/target-alpha/translate.c index c27c7b9..a2e2a62 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -392,7 +392,8 @@ static inline void gen_store_mem(DisasContext *ctx, } static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb, - int32_t disp16, int quad) + int32_t disp16, int mem_idx, + TCGMemOp op) { TCGv addr; @@ -414,7 +415,7 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb, /* ??? This is handled via a complicated version of compare-and-swap in the cpu_loop. Hopefully one day we'll have a real CAS opcode in TCG so that this isn't necessary. */ - return gen_excp(ctx, quad ? EXCP_STQ_C : EXCP_STL_C, ra); + return gen_excp(ctx, (op & MO_SIZE) == MO_64 ? EXCP_STQ_C : EXCP_STL_C, ra); #else /* ??? In system mode we are never multi-threaded, so CAS can be implemented via a non-atomic load-compare-store sequence. */ @@ -427,11 +428,10 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb, tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail); val = tcg_temp_new(); - tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, quad ? MO_LEQ : MO_LESL); + tcg_gen_qemu_ld_i64(val, addr, mem_idx, op); tcg_gen_brcond_i64(TCG_COND_NE, val, cpu_lock_value, lab_fail); - tcg_gen_qemu_st_i64(ctx->ir[ra], addr, ctx->mem_idx, - quad ? MO_LEQ : MO_LEUL); + tcg_gen_qemu_st_i64(ctx->ir[ra], addr, mem_idx, op); tcg_gen_movi_i64(ctx->ir[ra], 1); tcg_gen_br(lab_done); @@ -2423,19 +2423,19 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) switch ((insn >> 12) & 0xF) { case 0x0: /* Longword physical access (hw_ldl/p) */ - gen_helper_ldl_phys(va, cpu_env, addr); + tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL); break; case 0x1: /* Quadword physical access (hw_ldq/p) */ - gen_helper_ldq_phys(va, cpu_env, addr); + tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEQ); break; case 0x2: /* Longword physical access with lock (hw_ldl_l/p) */ - gen_helper_ldl_l_phys(va, cpu_env, addr); + gen_qemu_ldl_l(va, addr, MMU_PHYS_IDX); break; case 0x3: /* Quadword physical access with lock (hw_ldq_l/p) */ - gen_helper_ldq_l_phys(va, cpu_env, addr); + gen_qemu_ldq_l(va, addr, MMU_PHYS_IDX); break; case 0x4: /* Longword virtual PTE fetch (hw_ldl/v) */ @@ -2674,27 +2674,34 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) #ifndef CONFIG_USER_ONLY REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE); { - TCGv addr = tcg_temp_new(); - va = load_gpr(ctx, ra); - vb = load_gpr(ctx, rb); - - tcg_gen_addi_i64(addr, vb, disp12); switch ((insn >> 12) & 0xF) { case 0x0: /* Longword physical access */ - gen_helper_stl_phys(cpu_env, addr, va); + va = load_gpr(ctx, ra); + vb = load_gpr(ctx, rb); + tmp = tcg_temp_new(); + tcg_gen_addi_i64(tmp, vb, disp12); + tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LESL); + tcg_temp_free(tmp); break; case 0x1: /* Quadword physical access */ - gen_helper_stq_phys(cpu_env, addr, va); + va = load_gpr(ctx, ra); + vb = load_gpr(ctx, rb); + tmp = tcg_temp_new(); + tcg_gen_addi_i64(tmp, vb, disp12); + tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LEQ); + tcg_temp_free(tmp); break; case 0x2: /* Longword physical access with lock */ - gen_helper_stl_c_phys(dest_gpr(ctx, ra), cpu_env, addr, va); + ret = gen_store_conditional(ctx, ra, rb, disp12, + MMU_PHYS_IDX, MO_LESL); break; case 0x3: /* Quadword physical access with lock */ - gen_helper_stq_c_phys(dest_gpr(ctx, ra), cpu_env, addr, va); + ret = gen_store_conditional(ctx, ra, rb, disp12, + MMU_PHYS_IDX, MO_LEQ); break; case 0x4: /* Longword virtual access */ @@ -2733,7 +2740,6 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) /* Invalid */ goto invalid_opc; } - tcg_temp_free(addr); break; } #else @@ -2797,11 +2803,13 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x2E: /* STL_C */ - ret = gen_store_conditional(ctx, ra, rb, disp16, 0); + ret = gen_store_conditional(ctx, ra, rb, disp16, + ctx->mem_idx, MO_LESL); break; case 0x2F: /* STQ_C */ - ret = gen_store_conditional(ctx, ra, rb, disp16, 1); + ret = gen_store_conditional(ctx, ra, rb, disp16, + ctx->mem_idx, MO_LEQ); break; case 0x30: /* BR */