diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 471188f7be954b82478067488be6ed49374ec8e5..b22f6f205fa8a531c7e8e2989c989084530392a3 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -11,6 +11,7 @@ DEF_HELPER_2(lmw, void, tl, i32) DEF_HELPER_2(stmw, void, tl, i32) DEF_HELPER_1(dcbz, void, tl) DEF_HELPER_1(dcbz_970, void, tl) +DEF_HELPER_1(icbi, void, tl) DEF_HELPER_2(fcmpo, i32, i64, i64) DEF_HELPER_2(fcmpu, i32, i64, i64) diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 6f6f1ec23d96ceb9be079c3e558de72f80cc19f6..98c428990aa206a6daeb12b5d9148a3d179b2394 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -210,6 +210,32 @@ void helper_dcbz_970(target_ulong addr) do_dcbz(addr, env->dcache_line_size); } +void helper_icbi(target_ulong addr) +{ + uint32_t tmp; + + addr = get_addr(addr & ~(env->dcache_line_size - 1)); + /* Invalidate one cache line : + * PowerPC specification says this is to be treated like a load + * (not a fetch) by the MMU. To be sure it will be so, + * do the load "by hand". + */ +#ifdef CONFIG_USER_ONLY + tmp = ldl_raw(addr); +#else + switch (env->mmu_idx) { + default: + case 0: tmp = ldl_user(addr); + break; + case 1: tmp = ldl_kernel(addr); + break; + case 2: tmp = ldl_hypv(addr); + break; + } +#endif + tb_invalidate_page_range(addr, addr + env->icache_line_size); +} + /*****************************************************************************/ /* Fixed point operations helpers */ #if defined(TARGET_PPC64) diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h index 9c0413e57abae4e49107ef94b0fd234040240e0e..48ac651767a15626360af3a0c00a137b8189929c 100644 --- a/target-ppc/op_helper.h +++ b/target-ppc/op_helper.h @@ -23,7 +23,6 @@ /* Memory load/store helpers */ void glue(do_lsw, MEMSUFFIX) (int dst); void glue(do_stsw, MEMSUFFIX) (int src); -void glue(do_icbi, MEMSUFFIX) (void); void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb); void glue(do_POWER2_lfq, MEMSUFFIX) (void); void glue(do_POWER2_lfq_le, MEMSUFFIX) (void); @@ -33,7 +32,6 @@ void glue(do_POWER2_stfq_le, MEMSUFFIX) (void); #if defined(TARGET_PPC64) void glue(do_lsw_64, MEMSUFFIX) (int dst); void glue(do_stsw_64, MEMSUFFIX) (int src); -void glue(do_icbi_64, MEMSUFFIX) (void); #endif #else diff --git a/target-ppc/op_helper_mem.h b/target-ppc/op_helper_mem.h index 2c3d5fa0759ca264e60942bfdb0ed89fabfb711d..9663110693209343a896a8d0f02061e867b297df 100644 --- a/target-ppc/op_helper_mem.h +++ b/target-ppc/op_helper_mem.h @@ -92,37 +92,6 @@ void glue(do_stsw_64, MEMSUFFIX) (int src) } #endif -/* Instruction cache invalidation helper */ -void glue(do_icbi, MEMSUFFIX) (void) -{ - uint32_t tmp; - /* Invalidate one cache line : - * PowerPC specification says this is to be treated like a load - * (not a fetch) by the MMU. To be sure it will be so, - * do the load "by hand". - */ - T0 &= ~(env->icache_line_size - 1); - tmp = glue(ldl, MEMSUFFIX)((uint32_t)T0); - tb_invalidate_page_range((uint32_t)T0, - (uint32_t)(T0 + env->icache_line_size)); -} - -#if defined(TARGET_PPC64) -void glue(do_icbi_64, MEMSUFFIX) (void) -{ - uint64_t tmp; - /* Invalidate one cache line : - * PowerPC specification says this is to be treated like a load - * (not a fetch) by the MMU. To be sure it will be so, - * do the load "by hand". - */ - T0 &= ~(env->icache_line_size - 1); - tmp = glue(ldq, MEMSUFFIX)((uint64_t)T0); - tb_invalidate_page_range((uint64_t)T0, - (uint64_t)(T0 + env->icache_line_size)); -} -#endif - /* PowerPC 601 specific instructions (POWER bridge) */ // XXX: to be tested void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) diff --git a/target-ppc/op_mem.h b/target-ppc/op_mem.h index 6f9eb2054800d973e5481884c8b81c9b152cda55..37fc488d1626cdf0b645807d9f6ad2c83ef5298b 100644 --- a/target-ppc/op_mem.h +++ b/target-ppc/op_mem.h @@ -314,21 +314,6 @@ void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void) } #endif -/* Instruction cache block invalidate */ -void OPPROTO glue(op_icbi, MEMSUFFIX) (void) -{ - glue(do_icbi, MEMSUFFIX)(); - RETURN(); -} - -#if defined(TARGET_PPC64) -void OPPROTO glue(op_icbi_64, MEMSUFFIX) (void) -{ - glue(do_icbi_64, MEMSUFFIX)(); - RETURN(); -} -#endif - /* External access */ void OPPROTO glue(op_eciwx, MEMSUFFIX) (void) { diff --git a/target-ppc/translate.c b/target-ppc/translate.c index b429a5d66e8082fe6c520f4f5ad5de52733212f0..aff9a30753b07babbc2a20edff5247766dcadc49 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -4165,25 +4165,14 @@ GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT) } /* icbi */ -#define op_icbi() (*gen_op_icbi[ctx->mem_idx])() -#define gen_op_icbi_le_raw gen_op_icbi_raw -#define gen_op_icbi_le_user gen_op_icbi_user -#define gen_op_icbi_le_kernel gen_op_icbi_kernel -#define gen_op_icbi_le_hypv gen_op_icbi_hypv -#define gen_op_icbi_le_64_raw gen_op_icbi_64_raw -#define gen_op_icbi_le_64_user gen_op_icbi_64_user -#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel -#define gen_op_icbi_le_64_hypv gen_op_icbi_64_hypv -static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = { - GEN_MEM_FUNCS(icbi), -}; - GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI) { + TCGv t0 = tcg_temp_new(); /* NIP cannot be restored if the memory exception comes from an helper */ gen_update_nip(ctx, ctx->nip - 4); - gen_addr_reg_index(cpu_T[0], ctx); - op_icbi(); + gen_addr_reg_index(t0, ctx); + gen_helper_icbi(t0); + tcg_temp_free(t0); } /* Optional: */