]> git.proxmox.com Git - qemu.git/commitdiff
PPC: E500: Use MAS registers instead of internal TLB representation
authorAlexander Graf <agraf@suse.de>
Thu, 16 Jun 2011 16:45:43 +0000 (18:45 +0200)
committerAlexander Graf <agraf@suse.de>
Fri, 17 Jun 2011 00:58:34 +0000 (02:58 +0200)
The natural format for e500 cores to do TLB manipulation with are the MAS
registers. Instead of converting them into some internal representation
and back again when the guest reads them, we can just keep the data
identical to the way the guest passed it to us.

The main advantage of this approach is that we're getting closer to being
able to share MMU data with KVM using shared memory, so that we don't need
to copy lots of MMU data back and forth all the time. For this to work
however, another patch is required that gets rid of the TLB union, as that
destroys our memory layout that needs to be identical with the kernel one.

Signed-off-by: Alexander Graf <agraf@suse.de>
hw/ppce500_mpc8544ds.c
target-ppc/cpu.h
target-ppc/helper.c
target-ppc/op_helper.c

index 073de3c052fd5c18d8bff717ce050a34ad27f58e..b739ce27eda869022320d30eea6e50214cfcbd73 100644 (file)
@@ -185,18 +185,23 @@ out:
 }
 
 /* Create -kernel TLB entries for BookE, linearly spanning 256MB.  */
+static inline target_phys_addr_t booke206_page_size_to_tlb(uint64_t size)
+{
+    return (ffs(size >> 10) - 1) >> 1;
+}
+
 static void mmubooke_create_initial_mapping(CPUState *env,
                                      target_ulong va,
                                      target_phys_addr_t pa)
 {
-    ppcemb_tlb_t *tlb = booke206_get_tlbe(env, 1, 0, 0);
-
-    tlb->attr = 0;
-    tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
-    tlb->size = 256 * 1024 * 1024;
-    tlb->EPN = va & TARGET_PAGE_MASK;
-    tlb->RPN = pa & TARGET_PAGE_MASK;
-    tlb->PID = 0;
+    ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
+    target_phys_addr_t size;
+
+    size = (booke206_page_size_to_tlb(256 * 1024 * 1024) << MAS1_TSIZE_SHIFT);
+    tlb->mas1 = MAS1_VALID | size;
+    tlb->mas2 = va & TARGET_PAGE_MASK;
+    tlb->mas7_3 = pa & TARGET_PAGE_MASK;
+    tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
 }
 
 static void mpc8544ds_cpu_reset(void *opaque)
index 8e4582f6abfcb41663b51ee5b37fcb714590ea51..758c5549af7fa5d22ce39275a8bc2fcaeef2022a 100644 (file)
@@ -360,9 +360,17 @@ struct ppcemb_tlb_t {
     uint32_t attr; /* Storage attributes */
 };
 
+typedef struct ppcmas_tlb_t {
+     uint32_t mas8;
+     uint32_t mas1;
+     uint64_t mas2;
+     uint64_t mas7_3;
+} ppcmas_tlb_t;
+
 union ppc_tlb_t {
     ppc6xx_tlb_t tlb6;
     ppcemb_tlb_t tlbe;
+    ppcmas_tlb_t tlbm;
 };
 #endif
 
@@ -1075,9 +1083,13 @@ void store_40x_sler (CPUPPCState *env, uint32_t val);
 void store_booke_tcr (CPUPPCState *env, target_ulong val);
 void store_booke_tsr (CPUPPCState *env, target_ulong val);
 void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot);
+target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb);
 int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
                      target_phys_addr_t *raddrp, target_ulong address,
                      uint32_t pid, int ext, int i);
+int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb,
+                     target_phys_addr_t *raddrp, target_ulong address,
+                     uint32_t pid);
 void ppc_tlb_invalidate_all (CPUPPCState *env);
 void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr);
 #if defined(TARGET_PPC64)
@@ -1927,12 +1939,12 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
 }
 
 #if !defined(CONFIG_USER_ONLY)
-static inline int booke206_tlbe_id(CPUState *env, ppcemb_tlb_t *tlbe)
+static inline int booke206_tlbm_id(CPUState *env, ppcmas_tlb_t *tlbm)
 {
-    uintptr_t tlbel = (uintptr_t)tlbe;
+    uintptr_t tlbml = (uintptr_t)tlbm;
     uintptr_t tlbl = (uintptr_t)env->tlb;
 
-    return (tlbel - tlbl) / sizeof(env->tlb[0]);
+    return (tlbml - tlbl) / sizeof(env->tlb[0]);
 }
 
 static inline int booke206_tlb_size(CPUState *env, int tlbn)
@@ -1949,9 +1961,9 @@ static inline int booke206_tlb_ways(CPUState *env, int tlbn)
     return r;
 }
 
-static inline int booke206_tlbe_to_tlbn(CPUState *env, ppcemb_tlb_t *tlbe)
+static inline int booke206_tlbm_to_tlbn(CPUState *env, ppcmas_tlb_t *tlbm)
 {
-    int id = booke206_tlbe_id(env, tlbe);
+    int id = booke206_tlbm_id(env, tlbm);
     int end = 0;
     int i;
 
@@ -1966,14 +1978,14 @@ static inline int booke206_tlbe_to_tlbn(CPUState *env, ppcemb_tlb_t *tlbe)
     return 0;
 }
 
-static inline int booke206_tlbe_to_way(CPUState *env, ppcemb_tlb_t *tlb)
+static inline int booke206_tlbm_to_way(CPUState *env, ppcmas_tlb_t *tlb)
 {
-    int tlbn = booke206_tlbe_to_tlbn(env, tlb);
-    int tlbid = booke206_tlbe_id(env, tlb);
+    int tlbn = booke206_tlbm_to_tlbn(env, tlb);
+    int tlbid = booke206_tlbm_id(env, tlb);
     return tlbid & (booke206_tlb_ways(env, tlbn) - 1);
 }
 
-static inline ppcemb_tlb_t *booke206_get_tlbe(CPUState *env, const int tlbn,
+static inline ppcmas_tlb_t *booke206_get_tlbm(CPUState *env, const int tlbn,
                                               target_ulong ea, int way)
 {
     int r;
@@ -1992,7 +2004,7 @@ static inline ppcemb_tlb_t *booke206_get_tlbe(CPUState *env, const int tlbn,
         r += booke206_tlb_size(env, i);
     }
 
-    return &env->tlb[r].tlbe;
+    return &env->tlb[r].tlbm;
 }
 
 #endif
index 2944b062a520da910cf2b5063ed5c62161bbe649..8cf9ee11821e9b45136052665cd6539db0c6fb37 100644 (file)
@@ -1279,8 +1279,8 @@ void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot)
         if (flags & (1 << i)) {
             tlb_size = booke206_tlb_size(env, i);
             for (j = 0; j < tlb_size; j++) {
-                if (!check_iprot || !(tlb[j].tlbe.attr & MAS1_IPROT)) {
-                    tlb[j].tlbe.prot = 0;
+                if (!check_iprot || !(tlb[j].tlbm.mas1 & MAS1_IPROT)) {
+                    tlb[j].tlbm.mas1 &= ~MAS1_VALID;
                 }
             }
         }
@@ -1290,11 +1290,148 @@ void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot)
     tlb_flush(env, 1);
 }
 
+target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb)
+{
+    uint32_t tlbncfg;
+    int tlbn = booke206_tlbm_to_tlbn(env, tlb);
+    target_phys_addr_t tlbm_size;
+
+    tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
+
+    if (tlbncfg & TLBnCFG_AVAIL) {
+        tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
+    } else {
+        tlbm_size = (tlbncfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
+    }
+
+    return (1 << (tlbm_size << 1)) << 10;
+}
+
+/* TLB check function for MAS based SoftTLBs */
+int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb,
+                     target_phys_addr_t *raddrp,
+                     target_ulong address, uint32_t pid)
+{
+    target_ulong mask;
+    uint32_t tlb_pid;
+
+    /* Check valid flag */
+    if (!(tlb->mas1 & MAS1_VALID)) {
+        return -1;
+    }
+
+    mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
+    LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx " PID=0x%x MAS1=0x%x MAS2=0x%"
+              PRIx64 " mask=0x" TARGET_FMT_lx " MAS7_3=0x%" PRIx64 " MAS8=%x\n",
+              __func__, address, pid, tlb->mas1, tlb->mas2, mask, tlb->mas7_3,
+              tlb->mas8);
+
+    /* Check PID */
+    tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
+    if (tlb_pid != 0 && tlb_pid != pid) {
+        return -1;
+    }
+
+    /* Check effective address */
+    if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) {
+        return -1;
+    }
+    *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
+
+    return 0;
+}
+
+static int mmubooke206_check_tlb(CPUState *env, ppcmas_tlb_t *tlb,
+                                 target_phys_addr_t *raddr, int *prot,
+                                 target_ulong address, int rw,
+                                 int access_type)
+{
+    int ret;
+    int _prot = 0;
+
+    if (ppcmas_tlb_check(env, tlb, raddr, address,
+                         env->spr[SPR_BOOKE_PID]) >= 0) {
+        goto found_tlb;
+    }
+
+    if (env->spr[SPR_BOOKE_PID1] &&
+        ppcmas_tlb_check(env, tlb, raddr, address,
+                         env->spr[SPR_BOOKE_PID1]) >= 0) {
+        goto found_tlb;
+    }
+
+    if (env->spr[SPR_BOOKE_PID2] &&
+        ppcmas_tlb_check(env, tlb, raddr, address,
+                         env->spr[SPR_BOOKE_PID2]) >= 0) {
+        goto found_tlb;
+    }
+
+    LOG_SWTLB("%s: TLB entry not found\n", __func__);
+    return -1;
+
+found_tlb:
+
+    if (msr_pr != 0) {
+        if (tlb->mas7_3 & MAS3_UR) {
+            _prot |= PAGE_READ;
+        }
+        if (tlb->mas7_3 & MAS3_UW) {
+            _prot |= PAGE_WRITE;
+        }
+        if (tlb->mas7_3 & MAS3_UX) {
+            _prot |= PAGE_EXEC;
+        }
+    } else {
+        if (tlb->mas7_3 & MAS3_SR) {
+            _prot |= PAGE_READ;
+        }
+        if (tlb->mas7_3 & MAS3_SW) {
+            _prot |= PAGE_WRITE;
+        }
+        if (tlb->mas7_3 & MAS3_SX) {
+            _prot |= PAGE_EXEC;
+        }
+    }
+
+    /* Check the address space and permissions */
+    if (access_type == ACCESS_CODE) {
+        if (msr_ir != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
+            LOG_SWTLB("%s: AS doesn't match\n", __func__);
+            return -1;
+        }
+
+        *prot = _prot;
+        if (_prot & PAGE_EXEC) {
+            LOG_SWTLB("%s: good TLB!\n", __func__);
+            return 0;
+        }
+
+        LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, _prot);
+        ret = -3;
+    } else {
+        if (msr_dr != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
+            LOG_SWTLB("%s: AS doesn't match\n", __func__);
+            return -1;
+        }
+
+        *prot = _prot;
+        if ((!rw && _prot & PAGE_READ) || (rw && (_prot & PAGE_WRITE))) {
+            LOG_SWTLB("%s: found TLB!\n", __func__);
+            return 0;
+        }
+
+        LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, _prot);
+        ret = -2;
+    }
+
+    return ret;
+}
+
 static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
-                                        target_ulong address, int rw,
-                                        int access_type)
+                                            target_ulong address, int rw,
+                                            int access_type)
 {
-    ppcemb_tlb_t *tlb;
+    ppcmas_tlb_t *tlb;
     target_phys_addr_t raddr;
     int i, j, ret;
 
@@ -1305,9 +1442,9 @@ static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
         int ways = booke206_tlb_ways(env, i);
 
         for (j = 0; j < ways; j++) {
-            tlb = booke206_get_tlbe(env, i, address, j);
-            ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw,
-                                     access_type, j);
+            tlb = booke206_get_tlbm(env, i, address, j);
+            ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
+                                        rw, access_type);
             if (ret != -1) {
                 goto found_tlb;
             }
@@ -1412,7 +1549,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
                                                 rw, access_type);
         } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
             ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
-                                               access_type);
+                                                   access_type);
         } else {
             /* No address translation.  */
             ret = check_physical(env, ctx, eaddr, rw);
index 15d9222c7249f2c81f7aa2b75eaba25305c31ad8..135211dee66442f8d29ab798192fa418d24200b6 100644 (file)
@@ -4196,7 +4196,7 @@ target_ulong helper_440_tlbsx (target_ulong address)
 
 /* PowerPC BookE 2.06 TLB management */
 
-static ppcemb_tlb_t *booke206_cur_tlb(CPUState *env)
+static ppcmas_tlb_t *booke206_cur_tlb(CPUState *env)
 {
     uint32_t tlbncfg = 0;
     int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT;
@@ -4210,17 +4210,7 @@ static ppcemb_tlb_t *booke206_cur_tlb(CPUState *env)
         cpu_abort(env, "we don't support HES yet\n");
     }
 
-    return booke206_get_tlbe(env, tlb, ea, esel);
-}
-
-static inline target_phys_addr_t booke206_tlb_to_page_size(int size)
-{
-    return (1 << (size << 1)) << 10;
-}
-
-static inline target_phys_addr_t booke206_page_size_to_tlb(uint64_t size)
-{
-    return (ffs(size >> 10) - 1) >> 1;
+    return booke206_get_tlbm(env, tlb, ea, esel);
 }
 
 void helper_booke_setpid(uint32_t pidn, target_ulong pid)
@@ -4233,9 +4223,7 @@ void helper_booke_setpid(uint32_t pidn, target_ulong pid)
 void helper_booke206_tlbwe(void)
 {
     uint32_t tlbncfg, tlbn;
-    ppcemb_tlb_t *tlb;
-    target_phys_addr_t rpn;
-    int tlbe_size;
+    ppcmas_tlb_t *tlb;
 
     switch (env->spr[SPR_BOOKE_MAS0] & MAS0_WQ_MASK) {
     case MAS0_WQ_ALWAYS:
@@ -4269,116 +4257,43 @@ void helper_booke206_tlbwe(void)
 
     if (msr_gs) {
         cpu_abort(env, "missing HV implementation\n");
-    } else {
-        rpn = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) |
-              (env->spr[SPR_BOOKE_MAS3] & 0xfffff000);
-    }
-    tlb->RPN = rpn;
-
-    tlb->PID = (env->spr[SPR_BOOKE_MAS1] & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
-    if (tlbncfg & TLBnCFG_AVAIL) {
-        tlbe_size = (env->spr[SPR_BOOKE_MAS1] & MAS1_TSIZE_MASK)
-                    >> MAS1_TSIZE_SHIFT;
-    } else {
-        tlbe_size = (tlbncfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
     }
+    tlb->mas7_3 = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) |
+                  env->spr[SPR_BOOKE_MAS3];
+    tlb->mas1 = env->spr[SPR_BOOKE_MAS1];
+    /* XXX needs to change when supporting 64-bit e500 */
+    tlb->mas2 = env->spr[SPR_BOOKE_MAS2] & 0xffffffff;
 
-    tlb->size = booke206_tlb_to_page_size(tlbe_size);
-    tlb->EPN = (uint32_t)(env->spr[SPR_BOOKE_MAS2] & MAS2_EPN_MASK);
-    tlb->attr = env->spr[SPR_BOOKE_MAS2] & (MAS2_ACM | MAS2_VLE | MAS2_W |
-                                            MAS2_I | MAS2_M | MAS2_G | MAS2_E)
-                << 1;
-
-    if (tlbncfg & TLBnCFG_IPROT) {
-        tlb->attr |= env->spr[SPR_BOOKE_MAS1] & MAS1_IPROT;
-    }
-    tlb->attr |= (env->spr[SPR_BOOKE_MAS3] &
-                  ((MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3)) << 8);
-    if (env->spr[SPR_BOOKE_MAS1] & MAS1_TS) {
-        tlb->attr |= 1;
-    }
-
-    tlb->prot = 0;
-
-    if (env->spr[SPR_BOOKE_MAS1] & MAS1_VALID) {
-        tlb->prot |= PAGE_VALID;
-    }
-    if (env->spr[SPR_BOOKE_MAS3] & MAS3_UX) {
-        tlb->prot |= PAGE_EXEC;
-    }
-    if (env->spr[SPR_BOOKE_MAS3] & MAS3_SX) {
-        tlb->prot |= PAGE_EXEC << 4;
-    }
-    if (env->spr[SPR_BOOKE_MAS3] & MAS3_UW) {
-        tlb->prot |= PAGE_WRITE;
-    }
-    if (env->spr[SPR_BOOKE_MAS3] & MAS3_SW) {
-        tlb->prot |= PAGE_WRITE << 4;
-    }
-    if (env->spr[SPR_BOOKE_MAS3] & MAS3_UR) {
-        tlb->prot |= PAGE_READ;
-    }
-    if (env->spr[SPR_BOOKE_MAS3] & MAS3_SR) {
-        tlb->prot |= PAGE_READ << 4;
+    if (!(tlbncfg & TLBnCFG_IPROT)) {
+        /* no IPROT supported by TLB */
+        tlb->mas1 &= ~MAS1_IPROT;
     }
 
-    if (tlb->size == TARGET_PAGE_SIZE) {
-        tlb_flush_page(env, tlb->EPN);
+    if (booke206_tlb_to_page_size(env, tlb) == TARGET_PAGE_SIZE) {
+        tlb_flush_page(env, tlb->mas2 & MAS2_EPN_MASK);
     } else {
         tlb_flush(env, 1);
     }
 }
 
-static inline void booke206_tlb_to_mas(CPUState *env, ppcemb_tlb_t *tlb)
+static inline void booke206_tlb_to_mas(CPUState *env, ppcmas_tlb_t *tlb)
 {
-    int tlbn = booke206_tlbe_to_tlbn(env, tlb);
-    int way = booke206_tlbe_to_way(env, tlb);
+    int tlbn = booke206_tlbm_to_tlbn(env, tlb);
+    int way = booke206_tlbm_to_way(env, tlb);
 
     env->spr[SPR_BOOKE_MAS0] = tlbn << MAS0_TLBSEL_SHIFT;
     env->spr[SPR_BOOKE_MAS0] |= way << MAS0_ESEL_SHIFT;
-
-    env->spr[SPR_BOOKE_MAS1] = MAS1_VALID;
-    env->spr[SPR_BOOKE_MAS2] = 0;
-
-    env->spr[SPR_BOOKE_MAS7] = (uint64_t)tlb->RPN >> 32;
-    env->spr[SPR_BOOKE_MAS3] = tlb->RPN;
-    env->spr[SPR_BOOKE_MAS1] |= tlb->PID << MAS1_TID_SHIFT;
-    env->spr[SPR_BOOKE_MAS1] |= booke206_page_size_to_tlb(tlb->size)
-                                << MAS1_TSIZE_SHIFT;
-    env->spr[SPR_BOOKE_MAS1] |= tlb->attr & MAS1_IPROT;
-    if (tlb->attr & 1) {
-        env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
-    }
-
-    env->spr[SPR_BOOKE_MAS2] = tlb->EPN;
-    env->spr[SPR_BOOKE_MAS2] |= (tlb->attr >> 1) &
-        (MAS2_ACM | MAS2_VLE | MAS2_W | MAS2_I | MAS2_M | MAS2_G | MAS2_E);
-
-    if (tlb->prot & PAGE_EXEC) {
-        env->spr[SPR_BOOKE_MAS3] |= MAS3_UX;
-    }
-    if (tlb->prot & (PAGE_EXEC << 4)) {
-        env->spr[SPR_BOOKE_MAS3] |= MAS3_SX;
-    }
-    if (tlb->prot & PAGE_WRITE) {
-        env->spr[SPR_BOOKE_MAS3] |= MAS3_UW;
-    }
-    if (tlb->prot & (PAGE_WRITE << 4)) {
-        env->spr[SPR_BOOKE_MAS3] |= MAS3_SW;
-    }
-    if (tlb->prot & PAGE_READ) {
-        env->spr[SPR_BOOKE_MAS3] |= MAS3_UR;
-    }
-    if (tlb->prot & (PAGE_READ << 4)) {
-        env->spr[SPR_BOOKE_MAS3] |= MAS3_SR;
-    }
-
     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
+
+    env->spr[SPR_BOOKE_MAS1] = tlb->mas1;
+    env->spr[SPR_BOOKE_MAS2] = tlb->mas2;
+    env->spr[SPR_BOOKE_MAS3] = tlb->mas7_3;
+    env->spr[SPR_BOOKE_MAS7] = tlb->mas7_3 >> 32;
 }
 
 void helper_booke206_tlbre(void)
 {
-    ppcemb_tlb_t *tlb = NULL;
+    ppcmas_tlb_t *tlb = NULL;
 
     tlb = booke206_cur_tlb(env);
     booke206_tlb_to_mas(env, tlb);
@@ -4386,7 +4301,7 @@ void helper_booke206_tlbre(void)
 
 void helper_booke206_tlbsx(target_ulong address)
 {
-    ppcemb_tlb_t *tlb = NULL;
+    ppcmas_tlb_t *tlb = NULL;
     int i, j;
     target_phys_addr_t raddr;
     uint32_t spid, sas;
@@ -4398,13 +4313,13 @@ void helper_booke206_tlbsx(target_ulong address)
         int ways = booke206_tlb_ways(env, i);
 
         for (j = 0; j < ways; j++) {
-            tlb = booke206_get_tlbe(env, i, address, j);
+            tlb = booke206_get_tlbm(env, i, address, j);
 
-            if (ppcemb_tlb_check(env, tlb, &raddr, address, spid, 0, j)) {
+            if (ppcmas_tlb_check(env, tlb, &raddr, address, spid)) {
                 continue;
             }
 
-            if (sas != (tlb->attr & MAS6_SAS)) {
+            if (sas != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
                 continue;
             }
 
@@ -4439,13 +4354,14 @@ static inline void booke206_invalidate_ea_tlb(CPUState *env, int tlbn,
 {
     int i;
     int ways = booke206_tlb_ways(env, tlbn);
+    target_ulong mask;
 
     for (i = 0; i < ways; i++) {
-        ppcemb_tlb_t *tlb = booke206_get_tlbe(env, tlbn, ea, i);
-        target_phys_addr_t masked_ea = ea & ~(tlb->size - 1);
-        if ((tlb->EPN == (masked_ea >> MAS2_EPN_SHIFT)) &&
-            !(tlb->attr & MAS1_IPROT)) {
-            tlb->prot = 0;
+        ppcmas_tlb_t *tlb = booke206_get_tlbm(env, tlbn, ea, i);
+        mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
+        if (((tlb->mas2 & MAS2_EPN_MASK) == (ea & mask)) &&
+            !(tlb->mas1 & MAS1_IPROT)) {
+            tlb->mas1 &= ~MAS1_VALID;
         }
     }
 }