powerpc/mm: Simplify hpte_decode
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Mon, 10 Sep 2012 02:52:49 +0000 (02:52 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 17 Sep 2012 06:31:49 +0000 (16:31 +1000)
This patch simplify hpte_decode for easy switching of virtual address to
virtual page number in the later patch

Reviewed-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/mm/hash_native_64.c

index f21e8ce..ebf685a 100644 (file)
@@ -351,9 +351,10 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
 static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
                        int *psize, int *ssize, unsigned long *va)
 {
+       unsigned long avpn, pteg, vpi;
        unsigned long hpte_r = hpte->r;
        unsigned long hpte_v = hpte->v;
-       unsigned long avpn;
+       unsigned long vsid, seg_off;
        int i, size, shift, penc;
 
        if (!(hpte_v & HPTE_V_LARGE))
@@ -380,32 +381,38 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
        }
 
        /* This works for all page sizes, and for 256M and 1T segments */
+       *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT;
        shift = mmu_psize_defs[size].shift;
-       avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm) << 23;
-
-       if (shift < 23) {
-               unsigned long vpi, vsid, pteg;
 
-               pteg = slot / HPTES_PER_GROUP;
-               if (hpte_v & HPTE_V_SECONDARY)
-                       pteg = ~pteg;
-               switch (hpte_v >> HPTE_V_SSIZE_SHIFT) {
-               case MMU_SEGSIZE_256M:
-                       vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask;
-                       break;
-               case MMU_SEGSIZE_1T:
-                       vsid = avpn >> 40;
+       avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm);
+       pteg = slot / HPTES_PER_GROUP;
+       if (hpte_v & HPTE_V_SECONDARY)
+               pteg = ~pteg;
+
+       switch (*ssize) {
+       case MMU_SEGSIZE_256M:
+               /* We only have 28 - 23 bits of seg_off in avpn */
+               seg_off = (avpn & 0x1f) << 23;
+               vsid    =  avpn >> 5;
+               /* We can find more bits from the pteg value */
+               if (shift < 23) {
+                       vpi = (vsid ^ pteg) & htab_hash_mask;
+                       seg_off |= vpi << shift;
+               }
+               *va = vsid << SID_SHIFT | seg_off;
+       case MMU_SEGSIZE_1T:
+               /* We only have 40 - 23 bits of seg_off in avpn */
+               seg_off = (avpn & 0x1ffff) << 23;
+               vsid    = avpn >> 17;
+               if (shift < 23) {
                        vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask;
-                       break;
-               default:
-                       avpn = vpi = size = 0;
+                       seg_off |= vpi << shift;
                }
-               avpn |= (vpi << mmu_psize_defs[size].shift);
+               *va = vsid << SID_SHIFT_1T | seg_off;
+       default:
+               *va = size = 0;
        }
-
-       *va = avpn;
        *psize = size;
-       *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT;
 }
 
 /*