diff options
-rw-r--r-- | arch/powerpc/mm/hash_native_64.c | 37 | ||||
-rw-r--r-- | include/asm-powerpc/mmu-hash64.h | 12 |
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 | /* |