qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 16/45] mmu-hash*: Add header file for definitions


From: David Gibson
Subject: [Qemu-devel] [PATCH 16/45] mmu-hash*: Add header file for definitions
Date: Wed, 6 Mar 2013 14:44:04 +1100

Currently cpu.h contains a number of definitions relating to the 64-bit
hash MMU.  Some are used in the MMU emulation code, but some are only used
in the spapr MMU management hcall implementations.

This patch moves these definitions (except for a few that are needed
more widely) into mmu-hash64.h header, shared between the MMU emulation
code and the spapr hcall code.  The MMU emulation code is also updated to
actually use a number of those definitions in place of hard coded
constants.

Similarly, we add new analogous definitions to mmu-hash32.h and use those
in place of many hard-coded constants in mmu-hash32.c

Signed-off-by: David Gibson <address@hidden>
---
 hw/spapr_hcall.c        |   70 ++++++++++++------------------------------
 target-ppc/cpu.h        |   24 ---------------
 target-ppc/kvm.c        |    1 +
 target-ppc/mmu-hash32.c |   78 +++++++++++++++++++++--------------------------
 target-ppc/mmu-hash32.h |   61 ++++++++++++++++++++++++++++++++++++
 target-ppc/mmu-hash64.c |   35 ++++++++-------------
 target-ppc/mmu-hash64.h |   62 +++++++++++++++++++++++++++++++++++++
 7 files changed, 190 insertions(+), 141 deletions(-)

diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index 77c052f..d706227 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -3,39 +3,7 @@
 #include "sysemu/sysemu.h"
 #include "helper_regs.h"
 #include "hw/spapr.h"
-
-#define HPTES_PER_GROUP 8
-
-#define HPTE_V_SSIZE_SHIFT      62
-#define HPTE_V_AVPN_SHIFT       7
-#define HPTE_V_AVPN             0x3fffffffffffff80ULL
-#define HPTE_V_AVPN_VAL(x)      (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
-#define HPTE_V_COMPARE(x, y)    (!(((x) ^ (y)) & 0xffffffffffffff80UL))
-#define HPTE_V_BOLTED           0x0000000000000010ULL
-#define HPTE_V_LOCK             0x0000000000000008ULL
-#define HPTE_V_LARGE            0x0000000000000004ULL
-#define HPTE_V_SECONDARY        0x0000000000000002ULL
-#define HPTE_V_VALID            0x0000000000000001ULL
-
-#define HPTE_R_PP0              0x8000000000000000ULL
-#define HPTE_R_TS               0x4000000000000000ULL
-#define HPTE_R_KEY_HI           0x3000000000000000ULL
-#define HPTE_R_RPN_SHIFT        12
-#define HPTE_R_RPN              0x3ffffffffffff000ULL
-#define HPTE_R_FLAGS            0x00000000000003ffULL
-#define HPTE_R_PP               0x0000000000000003ULL
-#define HPTE_R_N                0x0000000000000004ULL
-#define HPTE_R_G                0x0000000000000008ULL
-#define HPTE_R_M                0x0000000000000010ULL
-#define HPTE_R_I                0x0000000000000020ULL
-#define HPTE_R_W                0x0000000000000040ULL
-#define HPTE_R_WIMG             0x0000000000000078ULL
-#define HPTE_R_C                0x0000000000000080ULL
-#define HPTE_R_R                0x0000000000000100ULL
-#define HPTE_R_KEY_LO           0x0000000000000e00ULL
-
-#define HPTE_V_1TB_SEG          0x4000000000000000ULL
-#define HPTE_V_VRMA_MASK        0x4001ffffff000000ULL
+#include "mmu-hash64.h"
 
 static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
                                      target_ulong pte_index)
@@ -44,17 +12,17 @@ static target_ulong compute_tlbie_rb(target_ulong v, 
target_ulong r,
 
     rb = (v & ~0x7fULL) << 16; /* AVA field */
     va_low = pte_index >> 3;
-    if (v & HPTE_V_SECONDARY) {
+    if (v & HPTE64_V_SECONDARY) {
         va_low = ~va_low;
     }
     /* xor vsid from AVA */
-    if (!(v & HPTE_V_1TB_SEG)) {
+    if (!(v & HPTE64_V_1TB_SEG)) {
         va_low ^= v >> 12;
     } else {
         va_low ^= v >> 24;
     }
     va_low &= 0x7ff;
-    if (v & HPTE_V_LARGE) {
+    if (v & HPTE64_V_LARGE) {
         rb |= 1;                         /* L field */
 #if 0 /* Disable that P7 specific bit for now */
         if (r & 0xff000) {
@@ -87,7 +55,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment 
*spapr,
     uint8_t *hpte;
 
     /* only handle 4k and 16M pages for now */
-    if (pteh & HPTE_V_LARGE) {
+    if (pteh & HPTE64_V_LARGE) {
 #if 0 /* We don't support 64k pages yet */
         if ((ptel & 0xf000) == 0x1000) {
             /* 64k page */
@@ -105,11 +73,11 @@ static target_ulong h_enter(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
         }
     }
 
-    raddr = (ptel & HPTE_R_RPN) & ~((1ULL << page_shift) - 1);
+    raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << page_shift) - 1);
 
     if (raddr < spapr->ram_limit) {
         /* Regular RAM - should have WIMG=0010 */
-        if ((ptel & HPTE_R_WIMG) != HPTE_R_M) {
+        if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) {
             return H_PARAMETER;
         }
     } else {
@@ -117,7 +85,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
         /* FIXME: What WIMG combinations could be sensible for IO?
          * For now we allow WIMG=010x, but are there others? */
         /* FIXME: Should we check against registered IO addresses? */
-        if ((ptel & (HPTE_R_W | HPTE_R_I | HPTE_R_M)) != HPTE_R_I) {
+        if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) {
             return H_PARAMETER;
         }
     }
@@ -134,7 +102,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
             if (i == 8) {
                 return H_PTEG_FULL;
             }
-            if ((ldq_p(hpte) & HPTE_V_VALID) == 0) {
+            if ((ldq_p(hpte) & HPTE64_V_VALID) == 0) {
                 break;
             }
             hpte += HASH_PTE_SIZE_64;
@@ -142,7 +110,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
     } else {
         i = 0;
         hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
-        if (ldq_p(hpte) & HPTE_V_VALID) {
+        if (ldq_p(hpte) & HPTE64_V_VALID) {
             return H_PTEG_FULL;
         }
     }
@@ -178,7 +146,7 @@ static target_ulong remove_hpte(CPUPPCState *env, 
target_ulong ptex,
     v = ldq_p(hpte);
     r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
 
-    if ((v & HPTE_V_VALID) == 0 ||
+    if ((v & HPTE64_V_VALID) == 0 ||
         ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
         ((flags & H_ANDCOND) && (v & avpn) != 0)) {
         return REMOVE_NOT_FOUND;
@@ -271,7 +239,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
 
         switch (ret) {
         case REMOVE_SUCCESS:
-            *tsh |= (r & (HPTE_R_C | HPTE_R_R)) << 43;
+            *tsh |= (r & (HPTE64_R_C | HPTE64_R_R)) << 43;
             break;
 
         case REMOVE_PARM:
@@ -304,18 +272,18 @@ static target_ulong h_protect(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
     v = ldq_p(hpte);
     r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
 
-    if ((v & HPTE_V_VALID) == 0 ||
+    if ((v & HPTE64_V_VALID) == 0 ||
         ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
         return H_NOT_FOUND;
     }
 
-    r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N |
-           HPTE_R_KEY_HI | HPTE_R_KEY_LO);
-    r |= (flags << 55) & HPTE_R_PP0;
-    r |= (flags << 48) & HPTE_R_KEY_HI;
-    r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO);
+    r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
+           HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
+    r |= (flags << 55) & HPTE64_R_PP0;
+    r |= (flags << 48) & HPTE64_R_KEY_HI;
+    r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
     rb = compute_tlbie_rb(v, r, pte_index);
-    stq_p(hpte, v & ~HPTE_V_VALID);
+    stq_p(hpte, v & ~HPTE64_V_VALID);
     ppc_tlb_invalidate_one(env, rb);
     stq_p(hpte + (HASH_PTE_SIZE_64/2), r);
     /* Don't need a memory barrier, due to qemu's global lock */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 044c8f4..dd9a7a9 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -395,36 +395,12 @@ union ppc_tlb_t {
 #define SDR_64_HTABSIZE        0x000000000000001FULL
 #endif /* defined(TARGET_PPC64 */
 
-#define HASH_PTE_SIZE_32       8
-#define HASH_PTE_SIZE_64       16
-
 typedef struct ppc_slb_t ppc_slb_t;
 struct ppc_slb_t {
     uint64_t esid;
     uint64_t vsid;
 };
 
-/* Bits in the SLB ESID word */
-#define SLB_ESID_ESID           0xFFFFFFFFF0000000ULL
-#define SLB_ESID_V              0x0000000008000000ULL /* valid */
-
-/* Bits in the SLB VSID word */
-#define SLB_VSID_SHIFT          12
-#define SLB_VSID_SHIFT_1T       24
-#define SLB_VSID_SSIZE_SHIFT    62
-#define SLB_VSID_B              0xc000000000000000ULL
-#define SLB_VSID_B_256M         0x0000000000000000ULL
-#define SLB_VSID_B_1T           0x4000000000000000ULL
-#define SLB_VSID_VSID           0x3FFFFFFFFFFFF000ULL
-#define SLB_VSID_PTEM           (SLB_VSID_B | SLB_VSID_VSID)
-#define SLB_VSID_KS             0x0000000000000800ULL
-#define SLB_VSID_KP             0x0000000000000400ULL
-#define SLB_VSID_N              0x0000000000000200ULL /* no-execute */
-#define SLB_VSID_L              0x0000000000000100ULL
-#define SLB_VSID_C              0x0000000000000080ULL /* class */
-#define SLB_VSID_LP             0x0000000000000030ULL
-#define SLB_VSID_ATTR           0x0000000000000FFFULL
-
 #define SEGMENT_SHIFT_256M      28
 #define SEGMENT_MASK_256M       (~((1ULL << SEGMENT_SHIFT_256M) - 1))
 
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index f8456bd..a45a185 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -32,6 +32,7 @@
 #include "sysemu/device_tree.h"
 #include "hw/sysbus.h"
 #include "hw/spapr.h"
+#include "mmu-hash64.h"
 
 #include "hw/sysbus.h"
 #include "hw/spapr.h"
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index 5b48aa8..a1bbd50 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -51,7 +51,6 @@ struct mmu_ctx_hash32 {
     int nx;                        /* Non-execute area          */
 };
 
-#define PTE_PTEM_MASK 0x7FFFFFBF
 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
 
 static int ppc_hash32_pp_check(int key, int pp, int nx)
@@ -127,13 +126,13 @@ static void hash32_bat_size_prot(CPUPPCState *env, 
target_ulong *blp,
     target_ulong bl;
     int pp, valid, prot;
 
-    bl = (*BATu & 0x00001FFC) << 15;
+    bl = (*BATu & BATU32_BL) << 15;
     valid = 0;
     prot = 0;
-    if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
-        ((msr_pr != 0) && (*BATu & 0x00000001))) {
+    if (((msr_pr == 0) && (*BATu & BATU32_VS)) ||
+        ((msr_pr != 0) && (*BATu & BATU32_VP))) {
         valid = 1;
-        pp = *BATl & 0x00000003;
+        pp = *BATl & BATL32_PP;
         if (pp != 0) {
             prot = PAGE_READ | PAGE_EXEC;
             if (pp == 0x2) {
@@ -153,17 +152,17 @@ static void hash32_bat_601_size_prot(CPUPPCState *env, 
target_ulong *blp,
     target_ulong bl;
     int key, pp, valid, prot;
 
-    bl = (*BATl & 0x0000003F) << 17;
+    bl = (*BATl & BATL32_601_BL) << 17;
     LOG_BATS("b %02x ==> bl " TARGET_FMT_lx " msk " TARGET_FMT_lx "\n",
-             (uint8_t)(*BATl & 0x0000003F), bl, ~bl);
+             (uint8_t)(*BATl & BATL32_601_BL), bl, ~bl);
     prot = 0;
-    valid = (*BATl >> 6) & 1;
+    valid = !!(*BATl & BATL32_601_V);
     if (valid) {
-        pp = *BATu & 0x00000003;
+        pp = *BATu & BATU32_601_PP;
         if (msr_pr == 0) {
-            key = (*BATu >> 3) & 1;
+            key = !!(*BATu & BATU32_601_KS);
         } else {
-            key = (*BATu >> 2) & 1;
+            key = !!(*BATu & BATU32_601_KP);
         }
         prot = ppc_hash32_pp_check(key, pp, 0);
     }
@@ -195,8 +194,8 @@ static int ppc_hash32_get_bat(CPUPPCState *env, struct 
mmu_ctx_hash32 *ctx,
     for (i = 0; i < env->nb_BATs; i++) {
         BATu = &BATut[i];
         BATl = &BATlt[i];
-        BEPIu = *BATu & 0xF0000000;
-        BEPIl = *BATu & 0x0FFE0000;
+        BEPIu = *BATu & BATU32_BEPIU;
+        BEPIl = *BATu & BATU32_BEPIL;
         if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
             hash32_bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
         } else {
@@ -205,13 +204,13 @@ static int ppc_hash32_get_bat(CPUPPCState *env, struct 
mmu_ctx_hash32 *ctx,
         LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
                  " BATl " TARGET_FMT_lx "\n", __func__,
                  type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl);
-        if ((virtual & 0xF0000000) == BEPIu &&
-            ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
+        if ((virtual & BATU32_BEPIU) == BEPIu &&
+            ((virtual & BATU32_BEPIL) & ~bl) == BEPIl) {
             /* BAT matches */
             if (valid != 0) {
                 /* Get physical address */
-                ctx->raddr = (*BATl & 0xF0000000) |
-                    ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
+                ctx->raddr = (*BATl & BATL32_BRPNU) |
+                    ((virtual & BATU32_BEPIL & bl) | (*BATl & BATL32_BRPNL)) |
                     (virtual & 0x0001F000);
                 /* Compute access rights */
                 ctx->prot = prot;
@@ -232,8 +231,8 @@ static int ppc_hash32_get_bat(CPUPPCState *env, struct 
mmu_ctx_hash32 *ctx,
             for (i = 0; i < 4; i++) {
                 BATu = &BATut[i];
                 BATl = &BATlt[i];
-                BEPIu = *BATu & 0xF0000000;
-                BEPIl = *BATu & 0x0FFE0000;
+                BEPIu = *BATu & BATU32_BEPIU;
+                BEPIl = *BATu & BATU32_BEPIL;
                 bl = (*BATu & 0x00001FFC) << 15;
                 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
                          " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
@@ -248,28 +247,19 @@ static int ppc_hash32_get_bat(CPUPPCState *env, struct 
mmu_ctx_hash32 *ctx,
     return ret;
 }
 
-
-static inline int pte_is_valid_hash32(target_ulong pte0)
-{
-    return pte0 & 0x80000000 ? 1 : 0;
-}
-
 static int pte_check_hash32(struct mmu_ctx_hash32 *ctx, target_ulong pte0,
                             target_ulong pte1, int h, int rw, int type)
 {
-    target_ulong ptem, mmask;
-    int access, ret, pteh, ptev, pp;
+    target_ulong mmask;
+    int access, ret, pp;
 
     ret = -1;
     /* Check validity and table match */
-    ptev = pte_is_valid_hash32(pte0);
-    pteh = (pte0 >> 6) & 1;
-    if (ptev && h == pteh) {
+    if ((pte0 & HPTE32_V_VALID) && (h == !!(pte0 & HPTE32_V_SECONDARY))) {
         /* Check vsid & api */
-        ptem = pte0 & PTE_PTEM_MASK;
         mmask = PTE_CHECK_MASK;
-        pp = pte1 & 0x00000003;
-        if (ptem == ctx->ptem) {
+        pp = pte1 & HPTE32_R_PP;
+        if (HPTE32_V_COMPARE(pte0, ctx->ptem)) {
             if (ctx->raddr != (hwaddr)-1ULL) {
                 /* all matches should have equal RPN, WIMG & PP */
                 if ((ctx->raddr & mmask) != (pte1 & mmask)) {
@@ -302,15 +292,15 @@ static int ppc_hash32_pte_update_flags(struct 
mmu_ctx_hash32 *ctx, target_ulong
     int store = 0;
 
     /* Update page flags */
-    if (!(*pte1p & 0x00000100)) {
+    if (!(*pte1p & HPTE32_R_R)) {
         /* Update accessed flag */
-        *pte1p |= 0x00000100;
+        *pte1p |= HPTE32_R_R;
         store = 1;
     }
-    if (!(*pte1p & 0x00000080)) {
+    if (!(*pte1p & HPTE32_R_C)) {
         if (rw == 1 && ret == 0) {
             /* Update changed flag */
-            *pte1p |= 0x00000080;
+            *pte1p |= HPTE32_R_C;
             store = 1;
         } else {
             /* Force page fault for first write access */
@@ -323,7 +313,7 @@ static int ppc_hash32_pte_update_flags(struct 
mmu_ctx_hash32 *ctx, target_ulong
 
 hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash)
 {
-    return (hash * HASH_PTE_SIZE_32 * 8) & env->htab_mask;
+    return (hash * HASH_PTEG_SIZE_32) & env->htab_mask;
 }
 
 /* PTE table lookup */
@@ -337,7 +327,7 @@ static int find_pte32(CPUPPCState *env, struct 
mmu_ctx_hash32 *ctx, int h,
 
     ret = -1; /* No entry found */
     pteg_off = get_pteg_offset32(env, ctx->hash[h]);
-    for (i = 0; i < 8; i++) {
+    for (i = 0; i < HPTES_PER_GROUP; i++) {
         if (env->external_htab) {
             pte0 = ldl_p(env->external_htab + pteg_off + (i * 8));
             pte1 = ldl_p(env->external_htab + pteg_off + (i * 8) + 4);
@@ -413,11 +403,11 @@ static int get_segment32(CPUPPCState *env, struct 
mmu_ctx_hash32 *ctx,
     ctx->eaddr = eaddr;
 
     sr = env->sr[eaddr >> 28];
-    ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
-                ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
-    ds = sr & 0x80000000 ? 1 : 0;
-    ctx->nx = sr & 0x10000000 ? 1 : 0;
-    vsid = sr & 0x00FFFFFF;
+    ctx->key = (((sr & SR32_KP) && (pr != 0)) ||
+                ((sr & SR32_KS) && (pr == 0))) ? 1 : 0;
+    ds = !!(sr & SR32_T);
+    ctx->nx = !!(sr & SR32_NX);
+    vsid = sr & SR32_VSID;
     target_page_bits = TARGET_PAGE_BITS;
     LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
             TARGET_FMT_lx " lr=" TARGET_FMT_lx
diff --git a/target-ppc/mmu-hash32.h b/target-ppc/mmu-hash32.h
index 0774103..033e1f8 100644
--- a/target-ppc/mmu-hash32.h
+++ b/target-ppc/mmu-hash32.h
@@ -6,4 +6,65 @@ hwaddr ppc_hash32_get_phys_page_debug(CPUPPCState *env, 
target_ulong addr);
 int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
                                 int mmu_idx);
 
+/*
+ * Segment register definitions
+ */
+
+#define SR32_T                  0x80000000
+#define SR32_KS                 0x40000000
+#define SR32_KP                 0x20000000
+#define SR32_NX                 0x10000000
+#define SR32_VSID               0x00ffffff
+
+/*
+ * Block Address Translation (BAT) definitions
+ */
+
+#define BATU32_BEPIU            0xf0000000
+#define BATU32_BEPIL            0x0ffe0000
+#define BATU32_BEPI             0xfffe0000
+#define BATU32_BL               0x00001ffc
+#define BATU32_VS               0x00000002
+#define BATU32_VP               0x00000001
+
+
+#define BATL32_BRPNU            0xf0000000
+#define BATL32_BRPNL            0x0ffe0000
+#define BATL32_BRPN             0xfffe0000
+#define BATL32_WIMG             0x00000078
+#define BATL32_PP               0x00000003
+
+/* PowerPC 601 has slightly different BAT registers */
+
+#define BATU32_601_KS           0x00000008
+#define BATU32_601_KP           0x00000004
+#define BATU32_601_PP           0x00000003
+
+#define BATL32_601_V            0x00000040
+#define BATL32_601_BL           0x0000003f
+
+/*
+ * Hash page table definitions
+ */
+
+#define HPTES_PER_GROUP         8
+#define HASH_PTE_SIZE_32        8
+#define HASH_PTEG_SIZE_32       (HASH_PTE_SIZE_32 * HPTES_PER_GROUP)
+
+#define HPTE32_V_VALID          0x80000000
+#define HPTE32_V_VSID           0x7fffff80
+#define HPTE32_V_SECONDARY      0x00000040
+#define HPTE32_V_API            0x0000003f
+#define HPTE32_V_COMPARE(x, y)  (!(((x) ^ (y)) & 0x7fffffbf))
+
+#define HPTE32_R_RPN            0xfffff000
+#define HPTE32_R_R              0x00000100
+#define HPTE32_R_C              0x00000080
+#define HPTE32_R_W              0x00000040
+#define HPTE32_R_I              0x00000020
+#define HPTE32_R_M              0x00000010
+#define HPTE32_R_G              0x00000008
+#define HPTE32_R_WIMG           0x00000078
+#define HPTE32_R_PP             0x00000003
+
 #endif /* __MMU_HASH32_H__ */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 3008be8..f3223dd 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -233,7 +233,6 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, 
target_ulong rb)
  * 64-bit hash table MMU handling
  */
 
-#define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
 
 static int ppc_hash64_pp_check(int key, int pp, int nx)
@@ -304,29 +303,21 @@ static int ppc_hash64_check_prot(int prot, int rw, int 
access_type)
     return ret;
 }
 
-static inline int pte64_is_valid(target_ulong pte0)
-{
-    return pte0 & 0x0000000000000001ULL ? 1 : 0;
-}
-
 static int pte64_check(struct mmu_ctx_hash64 *ctx, target_ulong pte0,
                        target_ulong pte1, int h, int rw, int type)
 {
-    target_ulong ptem, mmask;
-    int access, ret, pteh, ptev, pp;
+    target_ulong mmask;
+    int access, ret, pp;
 
     ret = -1;
     /* Check validity and table match */
-    ptev = pte64_is_valid(pte0);
-    pteh = (pte0 >> 1) & 1;
-    if (ptev && h == pteh) {
+    if ((pte0 & HPTE64_V_VALID) && (h == !!(pte0 & HPTE64_V_SECONDARY))) {
         /* Check vsid & api */
-        ptem = pte0 & PTE64_PTEM_MASK;
         mmask = PTE64_CHECK_MASK;
-        pp = (pte1 & 0x00000003) | ((pte1 >> 61) & 0x00000004);
-        ctx->nx  = (pte1 >> 2) & 1; /* No execute bit */
-        ctx->nx |= (pte1 >> 3) & 1; /* Guarded bit    */
-        if (ptem == ctx->ptem) {
+        pp = (pte1 & HPTE64_R_PP) | ((pte1 & HPTE64_R_PP0) >> 61);
+        /* No execute if either noexec or guarded bits set */
+        ctx->nx = (pte1 & HPTE64_R_N) || (pte1 & HPTE64_R_G);
+        if (HPTE64_V_COMPARE(pte0, ctx->ptem)) {
             if (ctx->raddr != (hwaddr)-1ULL) {
                 /* all matches should have equal RPN, WIMG & PP */
                 if ((ctx->raddr & mmask) != (pte1 & mmask)) {
@@ -360,15 +351,15 @@ static int ppc_hash64_pte_update_flags(struct 
mmu_ctx_hash64 *ctx,
     int store = 0;
 
     /* Update page flags */
-    if (!(*pte1p & 0x00000100)) {
+    if (!(*pte1p & HPTE64_R_R)) {
         /* Update accessed flag */
-        *pte1p |= 0x00000100;
+        *pte1p |= HPTE64_R_R;
         store = 1;
     }
-    if (!(*pte1p & 0x00000080)) {
+    if (!(*pte1p & HPTE64_R_C)) {
         if (rw == 1 && ret == 0) {
             /* Update changed flag */
-            *pte1p |= 0x00000080;
+            *pte1p |= HPTE64_R_C;
             store = 1;
         } else {
             /* Force page fault for first write access */
@@ -389,8 +380,8 @@ static int find_pte64(CPUPPCState *env, struct 
mmu_ctx_hash64 *ctx, int h,
     int ret, r;
 
     ret = -1; /* No entry found */
-    pteg_off = (ctx->hash[h] * HASH_PTE_SIZE_64 * 8) & env->htab_mask;
-    for (i = 0; i < 8; i++) {
+    pteg_off = (ctx->hash[h] * HASH_PTEG_SIZE_64) & env->htab_mask;
+    for (i = 0; i < HPTES_PER_GROUP; i++) {
         if (env->external_htab) {
             pte0 = ldq_p(env->external_htab + pteg_off + (i * 16));
             pte1 = ldq_p(env->external_htab + pteg_off + (i * 16) + 8);
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index e6d61af..b4cfedf 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -9,4 +9,66 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong 
address, int rw,
                                 int mmu_idx);
 #endif
 
+/*
+ * SLB definitions
+ */
+
+/* Bits in the SLB ESID word */
+#define SLB_ESID_ESID           0xFFFFFFFFF0000000ULL
+#define SLB_ESID_V              0x0000000008000000ULL /* valid */
+
+/* Bits in the SLB VSID word */
+#define SLB_VSID_SHIFT          12
+#define SLB_VSID_SHIFT_1T       24
+#define SLB_VSID_SSIZE_SHIFT    62
+#define SLB_VSID_B              0xc000000000000000ULL
+#define SLB_VSID_B_256M         0x0000000000000000ULL
+#define SLB_VSID_B_1T           0x4000000000000000ULL
+#define SLB_VSID_VSID           0x3FFFFFFFFFFFF000ULL
+#define SLB_VSID_PTEM           (SLB_VSID_B | SLB_VSID_VSID)
+#define SLB_VSID_KS             0x0000000000000800ULL
+#define SLB_VSID_KP             0x0000000000000400ULL
+#define SLB_VSID_N              0x0000000000000200ULL /* no-execute */
+#define SLB_VSID_L              0x0000000000000100ULL
+#define SLB_VSID_C              0x0000000000000080ULL /* class */
+#define SLB_VSID_LP             0x0000000000000030ULL
+#define SLB_VSID_ATTR           0x0000000000000FFFULL
+
+/*
+ * Hash page table definitions
+ */
+
+#define HPTES_PER_GROUP         8
+#define HASH_PTE_SIZE_64        16
+#define HASH_PTEG_SIZE_64       (HASH_PTE_SIZE_64 * HPTES_PER_GROUP)
+
+#define HPTE64_V_SSIZE_SHIFT    62
+#define HPTE64_V_AVPN_SHIFT     7
+#define HPTE64_V_AVPN           0x3fffffffffffff80ULL
+#define HPTE64_V_AVPN_VAL(x)    (((x) & HPTE64_V_AVPN) >> HPTE64_V_AVPN_SHIFT)
+#define HPTE64_V_COMPARE(x, y)  (!(((x) ^ (y)) & 0xffffffffffffff80UL))
+#define HPTE64_V_LARGE          0x0000000000000004ULL
+#define HPTE64_V_SECONDARY      0x0000000000000002ULL
+#define HPTE64_V_VALID          0x0000000000000001ULL
+
+#define HPTE64_R_PP0            0x8000000000000000ULL
+#define HPTE64_R_TS             0x4000000000000000ULL
+#define HPTE64_R_KEY_HI         0x3000000000000000ULL
+#define HPTE64_R_RPN_SHIFT      12
+#define HPTE64_R_RPN            0x0ffffffffffff000ULL
+#define HPTE64_R_FLAGS          0x00000000000003ffULL
+#define HPTE64_R_PP             0x0000000000000003ULL
+#define HPTE64_R_N              0x0000000000000004ULL
+#define HPTE64_R_G              0x0000000000000008ULL
+#define HPTE64_R_M              0x0000000000000010ULL
+#define HPTE64_R_I              0x0000000000000020ULL
+#define HPTE64_R_W              0x0000000000000040ULL
+#define HPTE64_R_WIMG           0x0000000000000078ULL
+#define HPTE64_R_C              0x0000000000000080ULL
+#define HPTE64_R_R              0x0000000000000100ULL
+#define HPTE64_R_KEY_LO         0x0000000000000e00ULL
+
+#define HPTE64_V_1TB_SEG        0x4000000000000000ULL
+#define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
+
 #endif /* !defined (__MMU_HASH64_H__) */
-- 
1.7.10.4




reply via email to

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