diff options
author | Ilya Yanok <yanok@emcraft.com> | 2008-12-10 20:55:41 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-12-28 17:53:25 -0500 |
commit | ca9153a3a2a7556d091dfe080e42b0e67881fff6 (patch) | |
tree | 35b5ce24f190690cf7a726cbb97980da51704855 /arch/powerpc/mm | |
parent | 6ca4f7494bde078b2b730e28e4ea1dc36a772f70 (diff) |
powerpc/44x: Support 16K/64K base page sizes on 44x
This adds support for 16k and 64k page sizes on PowerPC 44x processors.
The PGDIR table is much smaller than a page when using 16k or 64k
pages (512 and 32 bytes respectively) so we allocate the PGDIR with
kzalloc() instead of __get_free_pages().
One PTE table covers rather a large memory area when using 16k or 64k
pages (32MB or 512MB respectively), so we can easily put FIXMAP and
PKMAP in the area covered by one PTE table.
Signed-off-by: Yuri Tikhonov <yur@emcraft.com>
Signed-off-by: Vladimir Panfilov <pvr@emcraft.com>
Signed-off-by: Ilya Yanok <yanok@emcraft.com>
Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r-- | arch/powerpc/mm/pgtable_32.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 8cba46fc9e3b..38ff35f2142a 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c | |||
@@ -68,24 +68,29 @@ extern unsigned long p_mapped_by_tlbcam(unsigned long pa); | |||
68 | #define p_mapped_by_tlbcam(x) (0UL) | 68 | #define p_mapped_by_tlbcam(x) (0UL) |
69 | #endif /* HAVE_TLBCAM */ | 69 | #endif /* HAVE_TLBCAM */ |
70 | 70 | ||
71 | #ifdef CONFIG_PTE_64BIT | 71 | #define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT) |
72 | /* Some processors use an 8kB pgdir because they have 8-byte Linux PTEs. */ | ||
73 | #define PGDIR_ORDER 1 | ||
74 | #else | ||
75 | #define PGDIR_ORDER 0 | ||
76 | #endif | ||
77 | 72 | ||
78 | pgd_t *pgd_alloc(struct mm_struct *mm) | 73 | pgd_t *pgd_alloc(struct mm_struct *mm) |
79 | { | 74 | { |
80 | pgd_t *ret; | 75 | pgd_t *ret; |
81 | 76 | ||
82 | ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGDIR_ORDER); | 77 | /* pgdir take page or two with 4K pages and a page fraction otherwise */ |
78 | #ifndef CONFIG_PPC_4K_PAGES | ||
79 | ret = (pgd_t *)kzalloc(1 << PGDIR_ORDER, GFP_KERNEL); | ||
80 | #else | ||
81 | ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, | ||
82 | PGDIR_ORDER - PAGE_SHIFT); | ||
83 | #endif | ||
83 | return ret; | 84 | return ret; |
84 | } | 85 | } |
85 | 86 | ||
86 | void pgd_free(struct mm_struct *mm, pgd_t *pgd) | 87 | void pgd_free(struct mm_struct *mm, pgd_t *pgd) |
87 | { | 88 | { |
88 | free_pages((unsigned long)pgd, PGDIR_ORDER); | 89 | #ifndef CONFIG_PPC_4K_PAGES |
90 | kfree((void *)pgd); | ||
91 | #else | ||
92 | free_pages((unsigned long)pgd, PGDIR_ORDER - PAGE_SHIFT); | ||
93 | #endif | ||
89 | } | 94 | } |
90 | 95 | ||
91 | __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 96 | __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |
@@ -385,7 +390,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable) | |||
385 | #endif /* CONFIG_DEBUG_PAGEALLOC */ | 390 | #endif /* CONFIG_DEBUG_PAGEALLOC */ |
386 | 391 | ||
387 | static int fixmaps; | 392 | static int fixmaps; |
388 | unsigned long FIXADDR_TOP = 0xfffff000; | 393 | unsigned long FIXADDR_TOP = (-PAGE_SIZE); |
389 | EXPORT_SYMBOL(FIXADDR_TOP); | 394 | EXPORT_SYMBOL(FIXADDR_TOP); |
390 | 395 | ||
391 | void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) | 396 | void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) |