@@ -551,6 +551,7 @@ DEF_HELPER_FLAGS_2(tlbie, TCG_CALL_NO_RWG, void, env, tl)
DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl)
DEF_HELPER_2(load_slb_esid, tl, env, tl)
DEF_HELPER_2(load_slb_vsid, tl, env, tl)
+DEF_HELPER_2(find_slb_esid, tl, env, tl)
DEF_HELPER_FLAGS_1(slbia, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_2(slbie, TCG_CALL_NO_RWG, void, env, tl)
#endif
@@ -188,6 +188,19 @@ static int ppc_load_slb_vsid(CPUPPCState *env, target_ulong rb,
return 0;
}
+static int ppc_find_slb_esid(CPUPPCState *env, target_ulong rb,
+ target_ulong *rt)
+{
+ ppc_slb_t *slb = slb_lookup(env, rb);
+
+ if (!slb) {
+ return -1;
+ }
+
+ *rt = slb->vsid;
+ return 0;
+}
+
void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs)
{
if (ppc_store_slb(env, rb, rs) < 0) {
@@ -218,6 +231,17 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
return rt;
}
+target_ulong helper_find_slb_esid(CPUPPCState *env, target_ulong rb)
+{
+ target_ulong rt = 0;
+
+ if (ppc_find_slb_esid(env, rb, &rt) < 0) {
+ helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL);
+ }
+ return rt;
+}
+
/*
* 64-bit hash table MMU handling
*/
@@ -4949,6 +4949,30 @@ static void gen_slbmfev(DisasContext *ctx)
cpu_gpr[rB(ctx->opcode)]);
#endif /* defined(CONFIG_USER_ONLY) */
}
+
+static void gen_slbfee_(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_PRIV;
+#else
+ TCGLabel *l1;
+ TCGLabel *l2;
+
+ CHK_SV;
+
+ gen_helper_find_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
+ cpu_gpr[rB(ctx->opcode)]);
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+ tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1);
+ tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
+ tcg_gen_br(l2);
+ gen_set_label(l1);
+ tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0);
+ gen_set_label(l2);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
#endif /* defined(TARGET_PPC64) */
/*** Lookaside buffer management ***/
@@ -9958,6 +9982,7 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
+GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B),
#endif
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
/* XXX Those instructions will need to be handled differently for
Used to lookup SLB entries by address, for some reason it was missing. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> --- target-ppc/helper.h | 1 + target-ppc/mmu-hash64.c | 24 ++++++++++++++++++++++++ target-ppc/translate.c | 25 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+)