diff options
-rw-r--r-- | arch/powerpc/mm/fsl_booke_mmu.c | 22 | ||||
-rw-r--r-- | arch/powerpc/mm/mmu_decl.h | 3 | ||||
-rw-r--r-- | arch/powerpc/mm/tlb_nohash.c | 24 |
3 files changed, 34 insertions, 15 deletions
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index bb1f88c10377..f3afe3d97f6b 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
@@ -169,7 +169,8 @@ unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, | |||
169 | } | 169 | } |
170 | 170 | ||
171 | static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt, | 171 | static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt, |
172 | unsigned long ram, int max_cam_idx) | 172 | unsigned long ram, int max_cam_idx, |
173 | bool dryrun) | ||
173 | { | 174 | { |
174 | int i; | 175 | int i; |
175 | unsigned long amount_mapped = 0; | 176 | unsigned long amount_mapped = 0; |
@@ -179,7 +180,9 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt, | |||
179 | unsigned long cam_sz; | 180 | unsigned long cam_sz; |
180 | 181 | ||
181 | cam_sz = calc_cam_sz(ram, virt, phys); | 182 | cam_sz = calc_cam_sz(ram, virt, phys); |
182 | settlbcam(i, virt, phys, cam_sz, pgprot_val(PAGE_KERNEL_X), 0); | 183 | if (!dryrun) |
184 | settlbcam(i, virt, phys, cam_sz, | ||
185 | pgprot_val(PAGE_KERNEL_X), 0); | ||
183 | 186 | ||
184 | ram -= cam_sz; | 187 | ram -= cam_sz; |
185 | amount_mapped += cam_sz; | 188 | amount_mapped += cam_sz; |
@@ -187,6 +190,9 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt, | |||
187 | phys += cam_sz; | 190 | phys += cam_sz; |
188 | } | 191 | } |
189 | 192 | ||
193 | if (dryrun) | ||
194 | return amount_mapped; | ||
195 | |||
190 | loadcam_multi(0, i, max_cam_idx); | 196 | loadcam_multi(0, i, max_cam_idx); |
191 | tlbcam_index = i; | 197 | tlbcam_index = i; |
192 | 198 | ||
@@ -199,12 +205,12 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt, | |||
199 | return amount_mapped; | 205 | return amount_mapped; |
200 | } | 206 | } |
201 | 207 | ||
202 | unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx) | 208 | unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, bool dryrun) |
203 | { | 209 | { |
204 | unsigned long virt = PAGE_OFFSET; | 210 | unsigned long virt = PAGE_OFFSET; |
205 | phys_addr_t phys = memstart_addr; | 211 | phys_addr_t phys = memstart_addr; |
206 | 212 | ||
207 | return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx); | 213 | return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx, dryrun); |
208 | } | 214 | } |
209 | 215 | ||
210 | #ifdef CONFIG_PPC32 | 216 | #ifdef CONFIG_PPC32 |
@@ -235,7 +241,7 @@ void __init adjust_total_lowmem(void) | |||
235 | ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem); | 241 | ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem); |
236 | 242 | ||
237 | i = switch_to_as1(); | 243 | i = switch_to_as1(); |
238 | __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM); | 244 | __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, false); |
239 | restore_to_as0(i, 0, 0, 1); | 245 | restore_to_as0(i, 0, 0, 1); |
240 | 246 | ||
241 | pr_info("Memory CAM mapping: "); | 247 | pr_info("Memory CAM mapping: "); |
@@ -303,10 +309,12 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t start) | |||
303 | n = switch_to_as1(); | 309 | n = switch_to_as1(); |
304 | /* map a 64M area for the second relocation */ | 310 | /* map a 64M area for the second relocation */ |
305 | if (memstart_addr > start) | 311 | if (memstart_addr > start) |
306 | map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM); | 312 | map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM, |
313 | false); | ||
307 | else | 314 | else |
308 | map_mem_in_cams_addr(start, PAGE_OFFSET + offset, | 315 | map_mem_in_cams_addr(start, PAGE_OFFSET + offset, |
309 | 0x4000000, CONFIG_LOWMEM_CAM_NUM); | 316 | 0x4000000, CONFIG_LOWMEM_CAM_NUM, |
317 | false); | ||
310 | restore_to_as0(n, offset, __va(dt_ptr), 1); | 318 | restore_to_as0(n, offset, __va(dt_ptr), 1); |
311 | /* We should never reach here */ | 319 | /* We should never reach here */ |
312 | panic("Relocation error"); | 320 | panic("Relocation error"); |
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 27c3a2d3a4f1..9f58ff44a075 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h | |||
@@ -141,7 +141,8 @@ extern void MMU_init_hw(void); | |||
141 | extern unsigned long mmu_mapin_ram(unsigned long top); | 141 | extern unsigned long mmu_mapin_ram(unsigned long top); |
142 | 142 | ||
143 | #elif defined(CONFIG_PPC_FSL_BOOK3E) | 143 | #elif defined(CONFIG_PPC_FSL_BOOK3E) |
144 | extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx); | 144 | extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, |
145 | bool dryrun); | ||
145 | extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, | 146 | extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, |
146 | phys_addr_t phys); | 147 | phys_addr_t phys); |
147 | #ifdef CONFIG_PPC32 | 148 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index a7381fbdd6ab..bb04e4df3100 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -648,7 +648,7 @@ static void early_init_this_mmu(void) | |||
648 | 648 | ||
649 | if (map) | 649 | if (map) |
650 | linear_map_top = map_mem_in_cams(linear_map_top, | 650 | linear_map_top = map_mem_in_cams(linear_map_top, |
651 | num_cams); | 651 | num_cams, false); |
652 | } | 652 | } |
653 | #endif | 653 | #endif |
654 | 654 | ||
@@ -746,10 +746,14 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base, | |||
746 | * entries are supported though that may eventually | 746 | * entries are supported though that may eventually |
747 | * change. | 747 | * change. |
748 | * | 748 | * |
749 | * on FSL Embedded 64-bit, we adjust the RMA size to match the | 749 | * on FSL Embedded 64-bit, usually all RAM is bolted, but with |
750 | * first bolted TLB entry size. We still limit max to 1G even if | 750 | * unusual memory sizes it's possible for some RAM to not be mapped |
751 | * the TLB could cover more. This is due to what the early init | 751 | * (such RAM is not used at all by Linux, since we don't support |
752 | * code is setup to do. | 752 | * highmem on 64-bit). We limit ppc64_rma_size to what would be |
753 | * mappable if this memblock is the only one. Additional memblocks | ||
754 | * can only increase, not decrease, the amount that ends up getting | ||
755 | * mapped. We still limit max to 1G even if we'll eventually map | ||
756 | * more. This is due to what the early init code is set up to do. | ||
753 | * | 757 | * |
754 | * We crop it to the size of the first MEMBLOCK to | 758 | * We crop it to the size of the first MEMBLOCK to |
755 | * avoid going over total available memory just in case... | 759 | * avoid going over total available memory just in case... |
@@ -757,8 +761,14 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base, | |||
757 | #ifdef CONFIG_PPC_FSL_BOOK3E | 761 | #ifdef CONFIG_PPC_FSL_BOOK3E |
758 | if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { | 762 | if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { |
759 | unsigned long linear_sz; | 763 | unsigned long linear_sz; |
760 | linear_sz = calc_cam_sz(first_memblock_size, PAGE_OFFSET, | 764 | unsigned int num_cams; |
761 | first_memblock_base); | 765 | |
766 | /* use a quarter of the TLBCAM for bolted linear map */ | ||
767 | num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; | ||
768 | |||
769 | linear_sz = map_mem_in_cams(first_memblock_size, num_cams, | ||
770 | true); | ||
771 | |||
762 | ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); | 772 | ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); |
763 | } else | 773 | } else |
764 | #endif | 774 | #endif |