Function loongarch_check_pte() can get physical address and access
priviledge, it works on both TLB entry and pte entry. It can be used
at page table walking.

Signed-off-by: Bibo Mao <maob...@loongson.cn>
---
 target/loongarch/cpu_helper.c | 35 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 25 deletions(-)

diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index ed72ca1640..e185273950 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -108,13 +108,15 @@ int loongarch_check_pte(CPULoongArchState *env, hwaddr 
*physical, int *prot,
 }
 
 static int loongarch_page_table_walker(CPULoongArchState *env, hwaddr 
*physical,
-                                 int *prot, target_ulong address)
+                                       int *prot, target_ulong address,
+                                       int access_type, int mmu_idx)
 {
     CPUState *cs = env_cpu(env);
     target_ulong index, phys;
     uint64_t dir_base, dir_width;
     uint64_t base;
     int level;
+    pte_context context;
 
     if ((address >> 63) & 0x1) {
         base = env->CSR_PGDH;
@@ -157,29 +159,11 @@ static int loongarch_page_table_walker(CPULoongArchState 
*env, hwaddr *physical,
         base = ldq_phys(cs->as, phys);
     }
 
-    /* TODO: check plv and other bits? */
-
-    /* base is pte, in normal pte format */
-    if (!FIELD_EX64(base, TLBENTRY, V)) {
-        return TLBRET_NOMATCH;
-    }
-
-    if (!FIELD_EX64(base, TLBENTRY, D)) {
-        *prot = PAGE_READ;
-    } else {
-        *prot = PAGE_READ | PAGE_WRITE;
-    }
-
-    /* get TARGET_PAGE_SIZE aligned physical address */
-    base += (address & TARGET_PHYS_MASK) & ((1 << dir_base) - 1);
-    /* mask RPLV, NX, NR bits */
-    base = FIELD_DP64(base, TLBENTRY_64, RPLV, 0);
-    base = FIELD_DP64(base, TLBENTRY_64, NX, 0);
-    base = FIELD_DP64(base, TLBENTRY_64, NR, 0);
-    /* mask other attribute bits */
-    *physical = base & TARGET_PAGE_MASK;
-
-    return 0;
+    context.vaddr = address;
+    context.page_shift = dir_base;
+    context.pte = base;
+    return loongarch_check_pte(env, physical, prot, &context, access_type,
+                               mmu_idx);
 }
 
 static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
@@ -203,7 +187,8 @@ static int loongarch_map_address(CPULoongArchState *env, 
hwaddr *physical,
          * legal mapping, even if the mapping is not yet in TLB. return 0 if
          * there is a valid map, else none zero.
          */
-        return loongarch_page_table_walker(env, physical, prot, address);
+        return loongarch_page_table_walker(env, physical, prot, address,
+                                           access_type, mmu_idx);
     }
 
     return TLBRET_NOMATCH;
-- 
2.39.3


Reply via email to