summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--target/ppc/mmu-hash64.c17
-rw-r--r--target/ppc/mmu-hash64.h5
2 files changed, 22 insertions, 0 deletions
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index fbefe5b5aa..3c057a8c70 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -490,6 +490,18 @@ static unsigned hpte_page_shift(const PPCHash64SegmentPageSizes *sps,
     return 0; /* Bad page size encoding */
 }
 
+static void ppc64_v3_new_to_old_hpte(target_ulong *pte0, target_ulong *pte1)
+{
+    /* Insert B into pte0 */
+    *pte0 = (*pte0 & HPTE64_V_COMMON_BITS) |
+            ((*pte1 & HPTE64_R_3_0_SSIZE_MASK) <<
+             (HPTE64_V_SSIZE_SHIFT - HPTE64_R_3_0_SSIZE_SHIFT));
+
+    /* Remove B from pte1 */
+    *pte1 = *pte1 & ~HPTE64_R_3_0_SSIZE_MASK;
+}
+
+
 static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
                                      const PPCHash64SegmentPageSizes *sps,
                                      target_ulong ptem,
@@ -515,6 +527,11 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
         smp_rmb();
         pte1 = ppc_hash64_hpte1(cpu, pteg, i);
 
+        /* Convert format if necessary */
+        if (cpu->env.mmu_model == POWERPC_MMU_3_00 && !cpu->vhyp) {
+            ppc64_v3_new_to_old_hpte(&pte0, &pte1);
+        }
+
         /* This compares V, B, H (secondary) and the AVPN */
         if (HPTE64_V_COMPARE(pte0, ptem)) {
             *pshift = hpte_page_shift(sps, pte0, pte1);
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index f11efc9cbc..016d6b44ee 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -102,6 +102,11 @@ void ppc_hash64_filter_pagesizes(PowerPCCPU *cpu,
 #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
 #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
 
+/* Format changes for ARCH v3 */
+#define HPTE64_V_COMMON_BITS    0x000fffffffffffffULL
+#define HPTE64_R_3_0_SSIZE_SHIFT 58
+#define HPTE64_R_3_0_SSIZE_MASK (3ULL << HPTE64_R_3_0_SSIZE_SHIFT)
+
 static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
 {
     if (cpu->vhyp) {