qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [PATCH 23/32] mmu-hash64: Separate PTEG searching from permis


From: David Gibson
Subject: [Qemu-ppc] [PATCH 23/32] mmu-hash64: Separate PTEG searching from permissions checking
Date: Fri, 15 Feb 2013 19:01:13 +1100

find_pte64() does several things.  First searches through a PTEG looking
for a PTE matching our virtual address.  Then it does permissions checking
and other processing on that PTE.

This patch separates the search by VA out from the rest.  The search is
combined with the pte64_match() function into a new ppc_has64_pteg_search()
function.

Signed-off-by: David Gibson <address@hidden>
---
 target-ppc/mmu-hash64.c |   64 ++++++++++++++++++++++++-----------------------
 target-ppc/mmu-hash64.h |    4 +++
 2 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 6320228..cb1fc02 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -299,14 +299,6 @@ static int ppc_hash64_check_prot(int prot, int rwx)
     return ret;
 }
 
-static bool pte64_match(target_ulong pte0, target_ulong pte1,
-                        bool secondary, target_ulong ptem)
-{
-    return (pte0 & HPTE_V_VALID)
-        && (secondary == !!(pte0 & HPTE_V_SECONDARY))
-        && HPTE_V_COMPARE(pte0, ptem);
-}
-
 static int pte64_check(struct mmu_ctx_hash64 *ctx, target_ulong pte0,
                        target_ulong pte1, int rwx)
 {
@@ -359,39 +351,49 @@ static int ppc_hash64_pte_update_flags(struct 
mmu_ctx_hash64 *ctx,
     return store;
 }
 
-/* PTE table lookup */
+static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr pteg_off,
+                                     bool secondary, target_ulong ptem,
+                                     ppc_hash_pte64_t *pte)
+{
+    hwaddr pte_offset = pteg_off;
+    target_ulong pte0, pte1;
+    int i;
+
+    for (i = 0; i < HPTES_PER_GROUP; i++) {
+        pte0 = ppc_hash64_load_hpte0(env, pte_offset);
+        pte1 = ppc_hash64_load_hpte1(env, pte_offset);
+
+        if ((pte0 & HPTE_V_VALID)
+            && (secondary == !!(pte0 & HPTE_V_SECONDARY))
+            && HPTE_V_COMPARE(pte0, ptem)) {
+            pte->pte0 = pte0;
+            pte->pte1 = pte1;
+            return pte_offset;
+        }
+
+        pte_offset += HASH_PTE_SIZE_64;
+    }
+
+    return -1;
+}
+
 static int find_pte64(CPUPPCState *env, struct mmu_ctx_hash64 *ctx,
                       target_ulong eaddr, int h, int rwx, int target_page_bits)
 {
-    hwaddr pteg_off;
-    target_ulong pte0, pte1;
-    int i, good = -1;
+    hwaddr pteg_off, pte_offset;
+    ppc_hash_pte64_t pte;
     int ret;
 
     ret = -1; /* No entry found */
     pteg_off = (ctx->hash[h] * HASH_PTEG_SIZE_64) & env->htab_mask;
-    for (i = 0; i < HPTES_PER_GROUP; i++) {
-        pte0 = ppc_hash64_load_hpte0(env, pteg_off + i*HASH_PTE_SIZE_64);
-        pte1 = ppc_hash64_load_hpte1(env, pteg_off + i*HASH_PTE_SIZE_64);
-
-        LOG_MMU("Load pte from %016" HWADDR_PRIx " => " TARGET_FMT_lx " "
-                TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
-                pteg_off + (i * 16), pte0, pte1, !!(pte0 & HPTE_V_VALID),
-                h, !!(pte0 & HPTE_V_SECONDARY), ctx->ptem);
-
-        if (pte64_match(pte0, pte1, h, ctx->ptem)) {
-            good = i;
-            break;
-        }
-    }
-    if (good != -1) {
-        ret = pte64_check(ctx, pte0, pte1, rwx);
+    pte_offset = ppc_hash64_pteg_search(env, pteg_off, h, ctx->ptem, &pte);
+    if (pte_offset != -1) {
+        ret = pte64_check(ctx, pte.pte0, pte.pte1, rwx);
         LOG_MMU("found PTE at addr %08" HWADDR_PRIx " prot=%01x ret=%d\n",
                 ctx->raddr, ctx->prot, ret);
         /* Update page flags */
-        pte1 = ctx->raddr;
-        if (ppc_hash64_pte_update_flags(ctx, &pte1, ret, rwx) == 1) {
-            ppc_hash64_store_hpte1(env, pteg_off + good * HASH_PTE_SIZE_64, 
pte1);
+        if (ppc_hash64_pte_update_flags(ctx, &pte.pte1, ret, rwx) == 1) {
+            ppc_hash64_store_hpte1(env, pte_offset, pte.pte1);
         }
     }
 
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index c932c4b..4730dc2 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -103,4 +103,8 @@ static inline void ppc_hash64_store_hpte1(CPUPPCState *env,
     }
 }
 
+typedef struct {
+    uint64_t pte0, pte1;
+} ppc_hash_pte64_t;
+
 #endif /* !defined (__MMU_HASH64_H__) */
-- 
1.7.10.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]