aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/mm/hash_native_64.c37
-rw-r--r--include/asm-powerpc/mmu-hash64.h12
2 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 7b7fe2d7b9dc..7d722eea4ea8 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -376,31 +376,28 @@ static void hpte_decode(hpte_t *hpte, unsigned long slot,
376 } 376 }
377 } 377 }
378 378
379 /* 379 /* This works for all page sizes, and for 256M and 1T segments */
380 * FIXME, the code below works for 16M, 64K, and 4K pages as these
381 * fall under the p<=23 rules for calculating the virtual address.
382 * In the case of 16M pages, an extra bit is stolen from the AVPN
383 * field to achieve the requisite 24 bits.
384 *
385 * Does not work for 16G pages or 1 TB segments.
386 */
387 shift = mmu_psize_defs[size].shift; 380 shift = mmu_psize_defs[size].shift;
388 if (mmu_psize_defs[size].avpnm) 381 avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm) << 23;
389 avpnm_bits = __ilog2_u64(mmu_psize_defs[size].avpnm) + 1;
390 else
391 avpnm_bits = 0;
392 if (shift - avpnm_bits <= 23) {
393 avpn = HPTE_V_AVPN_VAL(hpte_v) << 23;
394 382
395 if (shift < 23) { 383 if (shift < 23) {
396 unsigned long vpi, pteg; 384 unsigned long vpi, vsid, pteg;
397 385
398 pteg = slot / HPTES_PER_GROUP; 386 pteg = slot / HPTES_PER_GROUP;
399 if (hpte_v & HPTE_V_SECONDARY) 387 if (hpte_v & HPTE_V_SECONDARY)
400 pteg = ~pteg; 388 pteg = ~pteg;
389 switch (hpte_v >> HPTE_V_SSIZE_SHIFT) {
390 case MMU_SEGSIZE_256M:
401 vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask; 391 vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask;
402 avpn |= (vpi << mmu_psize_defs[size].shift); 392 break;
393 case MMU_SEGSIZE_1T:
394 vsid = avpn >> 40;
395 vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask;
396 break;
397 default:
398 avpn = vpi = psize = 0;
403 } 399 }
400 avpn |= (vpi << mmu_psize_defs[size].shift);
404 } 401 }
405 402
406 *va = avpn; 403 *va = avpn;
diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h
index e2ca55bcfe0b..b8dca30bd0b5 100644
--- a/include/asm-powerpc/mmu-hash64.h
+++ b/include/asm-powerpc/mmu-hash64.h
@@ -73,8 +73,9 @@ extern char initial_stab[];
73 73
74#define HPTES_PER_GROUP 8 74#define HPTES_PER_GROUP 8
75 75
76#define HPTE_V_SSIZE_SHIFT 62
76#define HPTE_V_AVPN_SHIFT 7 77#define HPTE_V_AVPN_SHIFT 7
77#define HPTE_V_AVPN ASM_CONST(0xffffffffffffff80) 78#define HPTE_V_AVPN ASM_CONST(0x3fffffffffffff80)
78#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT) 79#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
79#define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & HPTE_V_AVPN)) 80#define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & HPTE_V_AVPN))
80#define HPTE_V_BOLTED ASM_CONST(0x0000000000000010) 81#define HPTE_V_BOLTED ASM_CONST(0x0000000000000010)
@@ -151,6 +152,15 @@ struct mmu_psize_def
151#define MMU_PAGE_16G 5 /* 16G */ 152#define MMU_PAGE_16G 5 /* 16G */
152#define MMU_PAGE_COUNT 6 153#define MMU_PAGE_COUNT 6
153 154
155/*
156 * Segment sizes.
157 * These are the values used by hardware in the B field of
158 * SLB entries and the first dword of MMU hashtable entries.
159 * The B field is 2 bits; the values 2 and 3 are unused and reserved.
160 */
161#define MMU_SEGSIZE_256M 0
162#define MMU_SEGSIZE_1T 1
163
154#ifndef __ASSEMBLY__ 164#ifndef __ASSEMBLY__
155 165
156/* 166/*