diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2012-09-09 22:52:49 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-09-17 02:31:49 -0400 |
commit | dcda287a9b26309ae43a091d0ecde16f8f61b4c0 (patch) | |
tree | 7372499b3030326f50d34772a45fad1d76fef30c | |
parent | f6412b742ac754b4bbf3acaa9c05f825505671a1 (diff) |
powerpc/mm: Simplify hpte_decode
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>
-rw-r--r-- | arch/powerpc/mm/hash_native_64.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index f21e8ce8db33..ebf685af4af2 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -351,9 +351,10 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va, | |||
351 | static void hpte_decode(struct hash_pte *hpte, unsigned long slot, | 351 | static void hpte_decode(struct hash_pte *hpte, unsigned long slot, |
352 | int *psize, int *ssize, unsigned long *va) | 352 | int *psize, int *ssize, unsigned long *va) |
353 | { | 353 | { |
354 | unsigned long avpn, pteg, vpi; | ||
354 | unsigned long hpte_r = hpte->r; | 355 | unsigned long hpte_r = hpte->r; |
355 | unsigned long hpte_v = hpte->v; | 356 | unsigned long hpte_v = hpte->v; |
356 | unsigned long avpn; | 357 | unsigned long vsid, seg_off; |
357 | int i, size, shift, penc; | 358 | int i, size, shift, penc; |
358 | 359 | ||
359 | if (!(hpte_v & HPTE_V_LARGE)) | 360 | if (!(hpte_v & HPTE_V_LARGE)) |
@@ -380,32 +381,38 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, | |||
380 | } | 381 | } |
381 | 382 | ||
382 | /* This works for all page sizes, and for 256M and 1T segments */ | 383 | /* This works for all page sizes, and for 256M and 1T segments */ |
384 | *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT; | ||
383 | shift = mmu_psize_defs[size].shift; | 385 | shift = mmu_psize_defs[size].shift; |
384 | avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm) << 23; | ||
385 | |||
386 | if (shift < 23) { | ||
387 | unsigned long vpi, vsid, pteg; | ||
388 | 386 | ||
389 | pteg = slot / HPTES_PER_GROUP; | 387 | avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm); |
390 | if (hpte_v & HPTE_V_SECONDARY) | 388 | pteg = slot / HPTES_PER_GROUP; |
391 | pteg = ~pteg; | 389 | if (hpte_v & HPTE_V_SECONDARY) |
392 | switch (hpte_v >> HPTE_V_SSIZE_SHIFT) { | 390 | pteg = ~pteg; |
393 | case MMU_SEGSIZE_256M: | 391 | |
394 | vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask; | 392 | switch (*ssize) { |
395 | break; | 393 | case MMU_SEGSIZE_256M: |
396 | case MMU_SEGSIZE_1T: | 394 | /* We only have 28 - 23 bits of seg_off in avpn */ |
397 | vsid = avpn >> 40; | 395 | seg_off = (avpn & 0x1f) << 23; |
396 | vsid = avpn >> 5; | ||
397 | /* We can find more bits from the pteg value */ | ||
398 | if (shift < 23) { | ||
399 | vpi = (vsid ^ pteg) & htab_hash_mask; | ||
400 | seg_off |= vpi << shift; | ||
401 | } | ||
402 | *va = vsid << SID_SHIFT | seg_off; | ||
403 | case MMU_SEGSIZE_1T: | ||
404 | /* We only have 40 - 23 bits of seg_off in avpn */ | ||
405 | seg_off = (avpn & 0x1ffff) << 23; | ||
406 | vsid = avpn >> 17; | ||
407 | if (shift < 23) { | ||
398 | vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask; | 408 | vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask; |
399 | break; | 409 | seg_off |= vpi << shift; |
400 | default: | ||
401 | avpn = vpi = size = 0; | ||
402 | } | 410 | } |
403 | avpn |= (vpi << mmu_psize_defs[size].shift); | 411 | *va = vsid << SID_SHIFT_1T | seg_off; |
412 | default: | ||
413 | *va = size = 0; | ||
404 | } | 414 | } |
405 | |||
406 | *va = avpn; | ||
407 | *psize = size; | 415 | *psize = size; |
408 | *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT; | ||
409 | } | 416 | } |
410 | 417 | ||
411 | /* | 418 | /* |