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>
This commit is contained in:
parent
96e654cf3e
commit
eae570bdcd
1 changed files with 13 additions and 23 deletions
|
|
@ -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;
|
||||
int asid = info & 0x3ff;
|
||||
LoongArchTLB *tlb;
|
||||
tlb_match func;
|
||||
|
||||
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;
|
||||
|
||||
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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue