diff options
Diffstat (limited to 'arch/powerpc/mm/tlb_nohash.c')
-rw-r--r-- | arch/powerpc/mm/tlb_nohash.c | 67 |
1 files changed, 62 insertions, 5 deletions
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index d32ec643c231..6c2eabf707b7 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -36,14 +36,49 @@ | |||
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/memblock.h> | 37 | #include <linux/memblock.h> |
38 | #include <linux/of_fdt.h> | 38 | #include <linux/of_fdt.h> |
39 | #include <linux/hugetlb.h> | ||
39 | 40 | ||
40 | #include <asm/tlbflush.h> | 41 | #include <asm/tlbflush.h> |
41 | #include <asm/tlb.h> | 42 | #include <asm/tlb.h> |
42 | #include <asm/code-patching.h> | 43 | #include <asm/code-patching.h> |
44 | #include <asm/hugetlb.h> | ||
43 | 45 | ||
44 | #include "mmu_decl.h" | 46 | #include "mmu_decl.h" |
45 | 47 | ||
46 | #ifdef CONFIG_PPC_BOOK3E | 48 | /* |
49 | * This struct lists the sw-supported page sizes. The hardawre MMU may support | ||
50 | * other sizes not listed here. The .ind field is only used on MMUs that have | ||
51 | * indirect page table entries. | ||
52 | */ | ||
53 | #ifdef CONFIG_PPC_BOOK3E_MMU | ||
54 | #ifdef CONFIG_FSL_BOOKE | ||
55 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | ||
56 | [MMU_PAGE_4K] = { | ||
57 | .shift = 12, | ||
58 | .enc = BOOK3E_PAGESZ_4K, | ||
59 | }, | ||
60 | [MMU_PAGE_4M] = { | ||
61 | .shift = 22, | ||
62 | .enc = BOOK3E_PAGESZ_4M, | ||
63 | }, | ||
64 | [MMU_PAGE_16M] = { | ||
65 | .shift = 24, | ||
66 | .enc = BOOK3E_PAGESZ_16M, | ||
67 | }, | ||
68 | [MMU_PAGE_64M] = { | ||
69 | .shift = 26, | ||
70 | .enc = BOOK3E_PAGESZ_64M, | ||
71 | }, | ||
72 | [MMU_PAGE_256M] = { | ||
73 | .shift = 28, | ||
74 | .enc = BOOK3E_PAGESZ_256M, | ||
75 | }, | ||
76 | [MMU_PAGE_1G] = { | ||
77 | .shift = 30, | ||
78 | .enc = BOOK3E_PAGESZ_1GB, | ||
79 | }, | ||
80 | }; | ||
81 | #else | ||
47 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | 82 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { |
48 | [MMU_PAGE_4K] = { | 83 | [MMU_PAGE_4K] = { |
49 | .shift = 12, | 84 | .shift = 12, |
@@ -77,6 +112,8 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | |||
77 | .enc = BOOK3E_PAGESZ_1GB, | 112 | .enc = BOOK3E_PAGESZ_1GB, |
78 | }, | 113 | }, |
79 | }; | 114 | }; |
115 | #endif /* CONFIG_FSL_BOOKE */ | ||
116 | |||
80 | static inline int mmu_get_tsize(int psize) | 117 | static inline int mmu_get_tsize(int psize) |
81 | { | 118 | { |
82 | return mmu_psize_defs[psize].enc; | 119 | return mmu_psize_defs[psize].enc; |
@@ -87,7 +124,7 @@ static inline int mmu_get_tsize(int psize) | |||
87 | /* This isn't used on !Book3E for now */ | 124 | /* This isn't used on !Book3E for now */ |
88 | return 0; | 125 | return 0; |
89 | } | 126 | } |
90 | #endif | 127 | #endif /* CONFIG_PPC_BOOK3E_MMU */ |
91 | 128 | ||
92 | /* The variables below are currently only used on 64-bit Book3E | 129 | /* The variables below are currently only used on 64-bit Book3E |
93 | * though this will probably be made common with other nohash | 130 | * though this will probably be made common with other nohash |
@@ -266,6 +303,11 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr, | |||
266 | 303 | ||
267 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) | 304 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) |
268 | { | 305 | { |
306 | #ifdef CONFIG_HUGETLB_PAGE | ||
307 | if (is_vm_hugetlb_page(vma)) | ||
308 | flush_hugetlb_page(vma, vmaddr); | ||
309 | #endif | ||
310 | |||
269 | __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, | 311 | __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, |
270 | mmu_get_tsize(mmu_virtual_psize), 0); | 312 | mmu_get_tsize(mmu_virtual_psize), 0); |
271 | } | 313 | } |
@@ -600,13 +642,28 @@ void __cpuinit early_init_mmu_secondary(void) | |||
600 | void setup_initial_memory_limit(phys_addr_t first_memblock_base, | 642 | void setup_initial_memory_limit(phys_addr_t first_memblock_base, |
601 | phys_addr_t first_memblock_size) | 643 | phys_addr_t first_memblock_size) |
602 | { | 644 | { |
603 | /* On Embedded 64-bit, we adjust the RMA size to match | 645 | /* On non-FSL Embedded 64-bit, we adjust the RMA size to match |
604 | * the bolted TLB entry. We know for now that only 1G | 646 | * the bolted TLB entry. We know for now that only 1G |
605 | * entries are supported though that may eventually | 647 | * entries are supported though that may eventually |
606 | * change. We crop it to the size of the first MEMBLOCK to | 648 | * change. |
649 | * | ||
650 | * on FSL Embedded 64-bit, we adjust the RMA size to match the | ||
651 | * first bolted TLB entry size. We still limit max to 1G even if | ||
652 | * the TLB could cover more. This is due to what the early init | ||
653 | * code is setup to do. | ||
654 | * | ||
655 | * We crop it to the size of the first MEMBLOCK to | ||
607 | * avoid going over total available memory just in case... | 656 | * avoid going over total available memory just in case... |
608 | */ | 657 | */ |
609 | ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); | 658 | #ifdef CONFIG_PPC_FSL_BOOK3E |
659 | if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { | ||
660 | unsigned long linear_sz; | ||
661 | linear_sz = calc_cam_sz(first_memblock_size, PAGE_OFFSET, | ||
662 | first_memblock_base); | ||
663 | ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); | ||
664 | } else | ||
665 | #endif | ||
666 | ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); | ||
610 | 667 | ||
611 | /* Finally limit subsequent allocations */ | 668 | /* Finally limit subsequent allocations */ |
612 | memblock_set_current_limit(first_memblock_base + ppc64_rma_size); | 669 | memblock_set_current_limit(first_memblock_base + ppc64_rma_size); |