With function helper_invtlb_page_asid(), 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() Signed-off-by: Bibo Mao <maob...@loongson.cn> --- target/loongarch/tcg/tlb_helper.c | 42 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 913df7edf2..5864858ccf 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -32,6 +32,15 @@ static bool tlb_match_any(int global, int asid, int tlb_asid) return false; } +static bool tlb_match_asid(int global, int asid, int tlb_asid) +{ + if (!global && tlb_asid == asid) { + return true; + } + + return false; +} + bool check_ps(CPULoongArchState *env, uint8_t tlb_ps) { if (tlb_ps >= 64) { @@ -542,30 +551,19 @@ void helper_invtlb_all_asid(CPULoongArchState *env, target_ulong info) void helper_invtlb_page_asid(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_asid; + 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