aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/init_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm/init_64.c')
-rw-r--r--arch/powerpc/mm/init_64.c55
1 files changed, 48 insertions, 7 deletions
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 68a821add28d..31582329cd67 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -205,6 +205,47 @@ static int __meminit vmemmap_populated(unsigned long start, int page_size)
205 return 0; 205 return 0;
206} 206}
207 207
208/* On hash-based CPUs, the vmemmap is bolted in the hash table.
209 *
210 * On Book3E CPUs, the vmemmap is currently mapped in the top half of
211 * the vmalloc space using normal page tables, though the size of
212 * pages encoded in the PTEs can be different
213 */
214
215#ifdef CONFIG_PPC_BOOK3E
216static void __meminit vmemmap_create_mapping(unsigned long start,
217 unsigned long page_size,
218 unsigned long phys)
219{
220 /* Create a PTE encoding without page size */
221 unsigned long i, flags = _PAGE_PRESENT | _PAGE_ACCESSED |
222 _PAGE_KERNEL_RW;
223
224 /* PTEs only contain page size encodings up to 32M */
225 BUG_ON(mmu_psize_defs[mmu_vmemmap_psize].enc > 0xf);
226
227 /* Encode the size in the PTE */
228 flags |= mmu_psize_defs[mmu_vmemmap_psize].enc << 8;
229
230 /* For each PTE for that area, map things. Note that we don't
231 * increment phys because all PTEs are of the large size and
232 * thus must have the low bits clear
233 */
234 for (i = 0; i < page_size; i += PAGE_SIZE)
235 BUG_ON(map_kernel_page(start + i, phys, flags));
236}
237#else /* CONFIG_PPC_BOOK3E */
238static void __meminit vmemmap_create_mapping(unsigned long start,
239 unsigned long page_size,
240 unsigned long phys)
241{
242 int mapped = htab_bolt_mapping(start, start + page_size, phys,
243 PAGE_KERNEL, mmu_vmemmap_psize,
244 mmu_kernel_ssize);
245 BUG_ON(mapped < 0);
246}
247#endif /* CONFIG_PPC_BOOK3E */
248
208int __meminit vmemmap_populate(struct page *start_page, 249int __meminit vmemmap_populate(struct page *start_page,
209 unsigned long nr_pages, int node) 250 unsigned long nr_pages, int node)
210{ 251{
@@ -215,8 +256,11 @@ int __meminit vmemmap_populate(struct page *start_page,
215 /* Align to the page size of the linear mapping. */ 256 /* Align to the page size of the linear mapping. */
216 start = _ALIGN_DOWN(start, page_size); 257 start = _ALIGN_DOWN(start, page_size);
217 258
259 pr_debug("vmemmap_populate page %p, %ld pages, node %d\n",
260 start_page, nr_pages, node);
261 pr_debug(" -> map %lx..%lx\n", start, end);
262
218 for (; start < end; start += page_size) { 263 for (; start < end; start += page_size) {
219 int mapped;
220 void *p; 264 void *p;
221 265
222 if (vmemmap_populated(start, page_size)) 266 if (vmemmap_populated(start, page_size))
@@ -226,13 +270,10 @@ int __meminit vmemmap_populate(struct page *start_page,
226 if (!p) 270 if (!p)
227 return -ENOMEM; 271 return -ENOMEM;
228 272
229 pr_debug("vmemmap %08lx allocated at %p, physical %08lx.\n", 273 pr_debug(" * %016lx..%016lx allocated at %p\n",
230 start, p, __pa(p)); 274 start, start + page_size, p);
231 275
232 mapped = htab_bolt_mapping(start, start + page_size, __pa(p), 276 vmemmap_create_mapping(start, page_size, __pa(p));
233 pgprot_val(PAGE_KERNEL),
234 mmu_vmemmap_psize, mmu_kernel_ssize);
235 BUG_ON(mapped < 0);
236 } 277 }
237 278
238 return 0; 279 return 0;