diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 1026254605cf994389fd4dabc70831c9afe2cca0..668ddf34cb6a5467fa5f44aa48f07b70731e90b4 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2112,6 +2112,10 @@ static inline ppcmas_tlb_t *booke206_get_tlbm(CPUState *env, const int tlbn, ea &= (1 << (tlb_bits - ways_bits)) - 1; r = (ea << ways_bits) | way; + if (r >= booke206_tlb_size(env, tlbn)) { + return NULL; + } + /* bump up to tlbn index */ for (i = 0; i < tlbn; i++) { r += booke206_tlb_size(env, i); diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 2ce2d9238f31a24912ca3b4a82483ee81e2e4374..672494c593bb1b77d280d571ff0ea73eb52fe9e9 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -1448,6 +1448,9 @@ static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx, for (j = 0; j < ways; j++) { tlb = booke206_get_tlbm(env, i, address, j); + if (!tlb) { + continue; + } ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw, access_type); if (ret != -1) { diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 1f1fa0936847cb9f5a8c6288ff7fbf8a0e632dff..be4e539c2db9d31b67159d7de6edf8dde32ff59d 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -4260,6 +4260,12 @@ void helper_booke206_tlbwe(void) tlb = booke206_cur_tlb(env); + if (!tlb) { + helper_raise_exception_err(POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_INVAL | + POWERPC_EXCP_INVAL_INVAL); + } + /* check that we support the targeted size */ size_tlb = (env->spr[SPR_BOOKE_MAS1] & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; size_ps = booke206_tlbnps(env, tlbn); @@ -4311,7 +4317,11 @@ void helper_booke206_tlbre(void) ppcmas_tlb_t *tlb = NULL; tlb = booke206_cur_tlb(env); - booke206_tlb_to_mas(env, tlb); + if (!tlb) { + env->spr[SPR_BOOKE_MAS1] = 0; + } else { + booke206_tlb_to_mas(env, tlb); + } } void helper_booke206_tlbsx(target_ulong address) @@ -4330,6 +4340,10 @@ void helper_booke206_tlbsx(target_ulong address) for (j = 0; j < ways; j++) { tlb = booke206_get_tlbm(env, i, address, j); + if (!tlb) { + continue; + } + if (ppcmas_tlb_check(env, tlb, &raddr, address, spid)) { continue; } @@ -4373,6 +4387,9 @@ static inline void booke206_invalidate_ea_tlb(CPUState *env, int tlbn, for (i = 0; i < ways; i++) { ppcmas_tlb_t *tlb = booke206_get_tlbm(env, tlbn, ea, i); + if (!tlb) { + continue; + } mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); if (((tlb->mas2 & MAS2_EPN_MASK) == (ea & mask)) && !(tlb->mas1 & MAS1_IPROT)) { @@ -4453,6 +4470,9 @@ void helper_booke206_tlbilx3(target_ulong address) for (j = 0; j < ways; j++) { tlb = booke206_get_tlbm(env, i, address, j); + if (!tlb) { + continue; + } if ((ppcmas_tlb_check(env, tlb, NULL, address, pid) != 0) || (tlb->mas1 & MAS1_IPROT) || ((tlb->mas1 & MAS1_IND) != ind) || diff --git a/target-ppc/translate.c b/target-ppc/translate.c index d8ef7196b4444e9115bbaa38c9aa6c240cc70287..58a4853a0dedabe924cd097dedf14a0c5f8b68dc 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6088,6 +6088,7 @@ static void gen_tlbwe_booke206(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } + gen_update_nip(ctx, ctx->nip - 4); gen_helper_booke206_tlbwe(); #endif }