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 <maobibo@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