Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/powerpc/booke Fix some SHIFTOUT to SHIFTIN



details:   https://anonhg.NetBSD.org/src/rev/410be7c80ed2
branches:  trunk
changeset: 780264:410be7c80ed2
user:      matt <matt%NetBSD.org@localhost>
date:      Wed Jul 18 18:29:22 2012 +0000

description:
Fix some SHIFTOUT to SHIFTIN
Add a lookup of tlb1 by pa.  fix comparisions of xtlb entries by using
masks.  (since xtlb can looked up by pa & va and va may not equal pa).

diffstat:

 sys/arch/powerpc/booke/e500_tlb.c |  55 ++++++++++++++++++++++++++------------
 1 files changed, 38 insertions(+), 17 deletions(-)

diffs (136 lines):

diff -r a20b4f86bc0b -r 410be7c80ed2 sys/arch/powerpc/booke/e500_tlb.c
--- a/sys/arch/powerpc/booke/e500_tlb.c Wed Jul 18 17:41:59 2012 +0000
+++ b/sys/arch/powerpc/booke/e500_tlb.c Wed Jul 18 18:29:22 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: e500_tlb.c,v 1.8 2012/03/29 15:48:20 matt Exp $        */
+/*     $NetBSD: e500_tlb.c,v 1.9 2012/07/18 18:29:22 matt Exp $        */
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: e500_tlb.c,v 1.8 2012/03/29 15:48:20 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: e500_tlb.c,v 1.9 2012/07/18 18:29:22 matt Exp $");
 
 #include <sys/param.h>
 
@@ -318,7 +318,7 @@
        const u_int slot = tlb1->tlb1_freelist[--tlb1->tlb1_numfree];
        KASSERT((tlb1->tlb1_entries[slot].e_hwtlb.hwtlb_mas1 & MAS1_V) == 0);
        tlb1->tlb1_entries[slot].e_hwtlb.hwtlb_mas0 = 
-           MAS0_TLBSEL_TLB1 | __SHIFTOUT(slot, MAS0_ESEL);
+           MAS0_TLBSEL_TLB1 | __SHIFTIN(slot, MAS0_ESEL);
        return (int)slot;
 }
 
@@ -644,7 +644,7 @@
 }
 
 static struct e500_xtlb *
-e500_tlb_lookup_xtlb(vaddr_t va, u_int *slotp)
+e500_tlb_lookup_xtlb_pa(vaddr_t pa, u_int *slotp)
 {
        struct e500_tlb1 * const tlb1 = &e500_tlb1;
        struct e500_xtlb *xtlb = tlb1->tlb1_entries;
@@ -653,9 +653,31 @@
         * See if we have a TLB entry for the pa.
         */
        for (u_int i = 0; i < tlb1->tlb1_numentries; i++, xtlb++) {
+               psize_t mask = ~(xtlb->e_tlb.tlb_size - 1);
                if ((xtlb->e_hwtlb.hwtlb_mas1 & MAS1_V)
-                   && xtlb->e_tlb.tlb_va <= va
-                   && va < xtlb->e_tlb.tlb_va + xtlb->e_tlb.tlb_size) {
+                   && ((pa ^ xtlb->e_tlb.tlb_pte) & mask) == 0) {
+                       if (slotp != NULL)
+                               *slotp = i;
+                       return xtlb;
+               }
+       }
+
+       return NULL;
+}
+
+static struct e500_xtlb *
+e500_tlb_lookup_xtlb(vaddr_t va, u_int *slotp)
+{
+       struct e500_tlb1 * const tlb1 = &e500_tlb1;
+       struct e500_xtlb *xtlb = tlb1->tlb1_entries;
+
+       /*
+        * See if we have a TLB entry for the va.
+        */
+       for (u_int i = 0; i < tlb1->tlb1_numentries; i++, xtlb++) {
+               vsize_t mask = ~(xtlb->e_tlb.tlb_size - 1);
+               if ((xtlb->e_hwtlb.hwtlb_mas1 & MAS1_V)
+                   && ((va ^ xtlb->e_tlb.tlb_va) & mask) == 0) {
                        if (slotp != NULL)
                                *slotp = i;
                        return xtlb;
@@ -675,9 +697,10 @@
         * See if we have a TLB entry for the pa.
         */
        for (u_int i = 0; i < tlb1->tlb1_numentries; i++, xtlb++) {
+               vsize_t mask = ~(xtlb->e_tlb.tlb_size - 1);
                if ((xtlb->e_hwtlb.hwtlb_mas1 & MAS1_V)
-                   && xtlb->e_tlb.tlb_va < va + len
-                   && va < xtlb->e_tlb.tlb_va + xtlb->e_tlb.tlb_size) {
+                   && ((va ^ xtlb->e_tlb.tlb_va) & mask) == 0
+                   && (((va + len - 1) ^ va) & mask) == 0) {
                        return xtlb;
                }
        }
@@ -688,7 +711,7 @@
 static void *
 e500_tlb_mapiodev(paddr_t pa, psize_t len, bool prefetchable)
 {
-       struct e500_xtlb * const xtlb = e500_tlb_lookup_xtlb(pa, NULL);
+       struct e500_xtlb * const xtlb = e500_tlb_lookup_xtlb_pa(pa, NULL);
 
        /*
         * See if we have a TLB entry for the pa.  If completely falls within
@@ -696,7 +719,6 @@
         * is not cacheable.
         */
        if (xtlb
-           && pa + len <= xtlb->e_tlb.tlb_va + xtlb->e_tlb.tlb_size
            && (prefetchable
                || (xtlb->e_tlb.tlb_pte & PTE_WIG) == (PTE_I|PTE_G))) {
                xtlb->e_refcnt++;
@@ -726,13 +748,12 @@
        KASSERT(len >= PAGE_SIZE);
        KASSERT((len & (len - 1)) == 0);
        KASSERT((va & (len - 1)) == 0);
-       KASSERT((pte & (len - 1)) == 0);
+       KASSERT(((pte & PTE_RPN_MASK) & (len - 1)) == 0);
 
        if ((xtlb = e500_tlb_lookup_xtlb2(va, len)) != NULL) {
-               if (va < xtlb->e_tlb.tlb_va
-                   || xtlb->e_tlb.tlb_va + xtlb->e_tlb.tlb_size < va + len
-                   || va - xtlb->e_tlb.tlb_va != pte - xtlb->e_tlb.tlb_pte)
-                       return EBUSY;
+               psize_t mask = ~(xtlb->e_tlb.tlb_size - 1);
+               KASSERT(len <= xtlb->e_tlb.tlb_size);
+               KASSERT((pte & mask) == (xtlb->e_tlb.tlb_pte & mask));
                xtlb->e_refcnt++;
                return 0;
        }
@@ -748,7 +769,7 @@
        xtlb->e_tlb.tlb_asid = KERNEL_PID;
 
        xtlb->e_hwtlb = tlb_to_hwtlb(xtlb->e_tlb);
-       xtlb->e_hwtlb.hwtlb_mas0 |= __SHIFTOUT(slot, MAS0_ESEL);
+       xtlb->e_hwtlb.hwtlb_mas0 |= __SHIFTIN(slot, MAS0_ESEL);
        hwtlb_write(xtlb->e_hwtlb, true);
        return 0;
 }
@@ -950,7 +971,7 @@
                kxtlb->e_tlb.tlb_asid = KERNEL_PID;
 
                kxtlb->e_hwtlb = tlb_to_hwtlb(kxtlb->e_tlb);
-               kxtlb->e_hwtlb.hwtlb_mas0 |= __SHIFTOUT(kslot, MAS0_ESEL);
+               kxtlb->e_hwtlb.hwtlb_mas0 |= __SHIFTIN(kslot, MAS0_ESEL);
                kxtlb->e_hwtlb.hwtlb_mas1 |= MAS1_TS;
                hwtlb_write(kxtlb->e_hwtlb, true);
 



Home | Main Index | Thread Index | Old Index