From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48460) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bh7EE-0000zN-MX for qemu-devel@nongnu.org; Mon, 05 Sep 2016 23:39:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bh7E5-0007AN-Qd for qemu-devel@nongnu.org; Mon, 05 Sep 2016 23:39:17 -0400 From: David Gibson Date: Tue, 6 Sep 2016 13:40:27 +1000 Message-Id: <1473133253-17598-41-git-send-email-david@gibson.dropbear.id.au> In-Reply-To: <1473133253-17598-1-git-send-email-david@gibson.dropbear.id.au> References: <1473133253-17598-1-git-send-email-david@gibson.dropbear.id.au> Subject: [Qemu-devel] [PULL 40/66] ppc: Speed up dcbz List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: peter.maydell@linearo.org Cc: agraf@suse.de, qemu-devel@nongnu.org, qemu-ppc@nongnu.org, Benjamin Herrenschmidt , David Gibson From: Benjamin Herrenschmidt Use tlb_vaddr_to_host to do a fast path single translate for the whole cache line. Also make the reservation check match the entire range. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David Gibson --- target-ppc/mem_helper.c | 46 +++++++++++++++++++++++++--------------------- target-ppc/translate.c | 11 ++++------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/target-ppc/mem_helper.c b/target-ppc/mem_helper.c index 92a594c..6548715 100644 --- a/target-ppc/mem_helper.c +++ b/target-ppc/mem_helper.c @@ -141,35 +141,39 @@ void helper_stsw(CPUPPCState *env, target_ulong addr, uint32_t nb, } } -static void do_dcbz(CPUPPCState *env, target_ulong addr, int dcache_line_size, - uintptr_t raddr) +void helper_dcbz(CPUPPCState *env, target_ulong addr, uint32_t opcode) { - int i; - - addr &= ~(dcache_line_size - 1); - for (i = 0; i < dcache_line_size; i += 4) { - cpu_stl_data_ra(env, addr + i, 0, raddr); - } - if (env->reserve_addr == addr) { - env->reserve_addr = (target_ulong)-1ULL; - } -} - -void helper_dcbz(CPUPPCState *env, target_ulong addr, uint32_t is_dcbzl) -{ - int dcbz_size = env->dcache_line_size; + target_ulong mask, dcbz_size = env->dcache_line_size; + uint32_t i; + void *haddr; #if defined(TARGET_PPC64) - if (!is_dcbzl && - (env->excp_model == POWERPC_EXCP_970) && - ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) { + /* Check for dcbz vs dcbzl on 970 */ + if (env->excp_model == POWERPC_EXCP_970 && + !(opcode & 0x00200000) && ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) { dcbz_size = 32; } #endif - /* XXX add e500mc support */ + /* Align address */ + mask = ~(dcbz_size - 1); + addr &= mask; + + /* Check reservation */ + if ((env->reserve_addr & mask) == (addr & mask)) { + env->reserve_addr = (target_ulong)-1ULL; + } - do_dcbz(env, addr, dcbz_size, GETPC()); + /* Try fast path translate */ + haddr = tlb_vaddr_to_host(env, addr, MMU_DATA_STORE, env->dmmu_idx); + if (haddr) { + memset(haddr, 0, dcbz_size); + } else { + /* Slow path */ + for (i = 0; i < dcbz_size; i += 8) { + cpu_stq_data_ra(env, addr + i, 0, GETPC()); + } + } } void helper_icbi(CPUPPCState *env, target_ulong addr) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 7aa8d77..ac2c79b 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -4088,18 +4088,15 @@ static void gen_dcbtls(DisasContext *ctx) static void gen_dcbz(DisasContext *ctx) { TCGv tcgv_addr; - TCGv_i32 tcgv_is_dcbzl; - int is_dcbzl = ctx->opcode & 0x00200000 ? 1 : 0; + TCGv_i32 tcgv_op; gen_set_access_type(ctx, ACCESS_CACHE); tcgv_addr = tcg_temp_new(); - tcgv_is_dcbzl = tcg_const_i32(is_dcbzl); - + tcgv_op = tcg_const_i32(ctx->opcode & 0x03FF000); gen_addr_reg_index(ctx, tcgv_addr); - gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_is_dcbzl); - + gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_op); tcg_temp_free(tcgv_addr); - tcg_temp_free_i32(tcgv_is_dcbzl); + tcg_temp_free_i32(tcgv_op); } /* dst / dstt */ -- 2.7.4