With function helper_invtlb_page_asid_or_g(), currently it is to search TLB entry one by one. Instead STLB can be searched at first with hash method, and then MTLB.
Here common API loongarch_tlb_search_cb() is used in function helper_invtlb_page_asid_or_g(). Signed-off-by: Bibo Mao <maob...@loongson.cn> --- target/loongarch/tcg/tlb_helper.c | 33 +++++++++++-------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index b8e0ba6588..913df7edf2 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -572,30 +572,19 @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info, void helper_invtlb_page_asid_or_g(CPULoongArchState *env, target_ulong info, target_ulong addr) { - uint16_t asid = info & 0x3ff; - - for (int i = 0; i < LOONGARCH_TLB_MAX; i++) { - LoongArchTLB *tlb = &env->tlb[i]; - uint8_t tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G); - uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID); - uint64_t vpn, tlb_vppn; - uint8_t tlb_ps, compare_shift; - uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); - - if (!tlb_e) { - continue; - } - - tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS); - tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN); - vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1); - compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT; + int index, asid = info & 0x3ff; + LoongArchTLB *tlb; + tlb_match func; + bool ret; - if ((tlb_g || (tlb_asid == asid)) && - (vpn == (tlb_vppn >> compare_shift))) { - tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0); - } + func = tlb_match_any; + ret = loongarch_tlb_search_cb(env, addr, &index, asid, func); + if (!ret) { + return; } + + tlb = &env->tlb[index]; + tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0); tlb_flush(env_cpu(env)); } -- 2.39.3