diff options
| author | Bibo Mao <maobibo@loongson.cn> | 2025-09-04 17:52:03 +0800 |
|---|---|---|
| committer | Bibo Mao <maobibo@loongson.cn> | 2025-09-28 16:10:34 +0800 |
| commit | eae570bdcd2d22c0e4bc058faff7f5ff874cb801 (patch) | |
| tree | 91a6a8e4dcec8a9f8a9dbf7e023b6ca435bf3f20 | |
| parent | 96e654cf3e6e03d61de447ad7117f53ed2bff998 (diff) | |
| download | focaccia-qemu-eae570bdcd2d22c0e4bc058faff7f5ff874cb801.tar.gz focaccia-qemu-eae570bdcd2d22c0e4bc058faff7f5ff874cb801.zip | |
target/loongarch: Use loongarch_tlb_search_cb in helper_invtlb_page_asid
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 search MTLB with one by one method Here common API loongarch_tlb_search_cb() is used in function helper_invtlb_page_asid() Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
| -rw-r--r-- | target/loongarch/tcg/tlb_helper.c | 36 |
1 files changed, 13 insertions, 23 deletions
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 0a87354ba9..7a85d9ca55 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -28,6 +28,11 @@ static bool tlb_match_any(bool global, int asid, int tlb_asid) return global || tlb_asid == asid; } +static bool tlb_match_asid(bool global, int asid, int tlb_asid) +{ + return !global && tlb_asid == asid; +} + bool check_ps(CPULoongArchState *env, uint8_t tlb_ps) { if (tlb_ps >= 64) { @@ -529,31 +534,16 @@ 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 asid = info & 0x3ff; + LoongArchTLB *tlb; + tlb_match func; - 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; + tlb = loongarch_tlb_search_cb(env, addr, asid, func); + if (tlb) { + tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0); + tlb_flush(env_cpu(env)); } - tlb_flush(env_cpu(env)); } void helper_invtlb_page_asid_or_g(CPULoongArchState *env, |