aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2009-10-16 19:48:40 -0400
committerKumar Gala <galak@kernel.crashing.org>2010-10-14 01:55:14 -0400
commit55fd766b5fad8240b7a6e994b5779a46d28f73d4 (patch)
treed00d9ddd5fb635d083e573d68675115489c46f19 /arch/powerpc/mm
parent988cf86d4f0da4150e808300c145ba87c0aad02f (diff)
powerpc/fsl-booke64: Use TLB CAMs to cover linear mapping on FSL 64-bit chips
On Freescale parts typically have TLB array for large mappings that we can bolt the linear mapping into. We utilize the code that already exists on PPC32 on the 64-bit side to setup the linear mapping to be cover by bolted TLB entries. We utilize a quarter of the variable size TLB array for this purpose. Additionally, we limit the amount of memory to what we can cover via bolted entries so we don't get secondary faults in the TLB miss handlers. We should fix this limitation in the future. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r--arch/powerpc/mm/Makefile2
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c12
-rw-r--r--arch/powerpc/mm/mmu_decl.h5
-rw-r--r--arch/powerpc/mm/tlb_nohash.c14
-rw-r--r--arch/powerpc/mm/tlb_nohash_low.S2
5 files changed, 27 insertions, 8 deletions
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 53102f306880..bdca46e08382 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \
23 mmu_context_hash$(CONFIG_WORD_SIZE).o 23 mmu_context_hash$(CONFIG_WORD_SIZE).o
24obj-$(CONFIG_40x) += 40x_mmu.o 24obj-$(CONFIG_40x) += 40x_mmu.o
25obj-$(CONFIG_44x) += 44x_mmu.o 25obj-$(CONFIG_44x) += 44x_mmu.o
26obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o 26obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o
27obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o 27obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
28obj-$(CONFIG_PPC_MM_SLICES) += slice.o 28obj-$(CONFIG_PPC_MM_SLICES) += slice.o
29ifeq ($(CONFIG_HUGETLB_PAGE),y) 29ifeq ($(CONFIG_HUGETLB_PAGE),y)
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 1b4354db51bb..67bc8a7c7e0b 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -56,11 +56,6 @@
56 56
57unsigned int tlbcam_index; 57unsigned int tlbcam_index;
58 58
59
60#if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
61#error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
62#endif
63
64#define NUM_TLBCAMS (64) 59#define NUM_TLBCAMS (64)
65struct tlbcam TLBCAM[NUM_TLBCAMS]; 60struct tlbcam TLBCAM[NUM_TLBCAMS];
66 61
@@ -185,6 +180,12 @@ unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
185 return amount_mapped; 180 return amount_mapped;
186} 181}
187 182
183#ifdef CONFIG_PPC32
184
185#if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
186#error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
187#endif
188
188unsigned long __init mmu_mapin_ram(unsigned long top) 189unsigned long __init mmu_mapin_ram(unsigned long top)
189{ 190{
190 return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1; 191 return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1;
@@ -216,3 +217,4 @@ void __init adjust_total_lowmem(void)
216 217
217 __initial_memory_limit_addr = memstart_addr + __max_low_memory; 218 __initial_memory_limit_addr = memstart_addr + __max_low_memory;
218} 219}
220#endif
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 63b84a0d3b10..dd0a2589591d 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -140,10 +140,13 @@ extern void wii_memory_fixups(void);
140extern void MMU_init_hw(void); 140extern void MMU_init_hw(void);
141extern unsigned long mmu_mapin_ram(unsigned long top); 141extern unsigned long mmu_mapin_ram(unsigned long top);
142 142
143#elif defined(CONFIG_FSL_BOOKE) 143#elif defined(CONFIG_PPC_FSL_BOOK3E)
144extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx);
145#ifdef CONFIG_PPC32
144extern void MMU_init_hw(void); 146extern void MMU_init_hw(void);
145extern unsigned long mmu_mapin_ram(unsigned long top); 147extern unsigned long mmu_mapin_ram(unsigned long top);
146extern void adjust_total_lowmem(void); 148extern void adjust_total_lowmem(void);
149#endif
147extern void loadcam_entry(unsigned int index); 150extern void loadcam_entry(unsigned int index);
148 151
149struct tlbcam { 152struct tlbcam {
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index 665189920762..61fe32a256da 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -541,6 +541,20 @@ static void __early_init_mmu(int boot_cpu)
541 */ 541 */
542 linear_map_top = memblock_end_of_DRAM(); 542 linear_map_top = memblock_end_of_DRAM();
543 543
544#ifdef CONFIG_PPC_FSL_BOOK3E
545 if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
546 unsigned int num_cams;
547
548 /* use a quarter of the TLBCAM for bolted linear map */
549 num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
550 linear_map_top = map_mem_in_cams(linear_map_top, num_cams);
551
552 /* limit memory so we dont have linear faults */
553 memblock_enforce_memory_limit(linear_map_top);
554 memblock_analyze();
555 }
556#endif
557
544 /* A sync won't hurt us after mucking around with 558 /* A sync won't hurt us after mucking around with
545 * the MMU configuration 559 * the MMU configuration
546 */ 560 */
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index b9d9fed8f36e..af405eefe48d 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -367,7 +367,7 @@ _GLOBAL(set_context)
367#error Unsupported processor type ! 367#error Unsupported processor type !
368#endif 368#endif
369 369
370#if defined(CONFIG_FSL_BOOKE) 370#if defined(CONFIG_PPC_FSL_BOOK3E)
371/* 371/*
372 * extern void loadcam_entry(unsigned int index) 372 * extern void loadcam_entry(unsigned int index)
373 * 373 *