diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2010-05-13 15:38:21 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2010-05-14 00:25:07 -0400 |
commit | 500a0e56c36dabb8cb0d8f3c93aac900058ef7af (patch) | |
tree | 987cb9542aa9edc9228df5e9d6d00c980a2d8e64 | |
parent | fa6bd996db2fbecd7a9a408c158105c55a51fe41 (diff) |
powerpc/fsl-booke: Move loadcam_entry back to asm code to fix SMP ftrace
When we build with ftrace enabled its possible that loadcam_entry would
have used the stack pointer (even though the code doesn't need it). We
call loadcam_entry in __secondary_start before the stack is setup. To
ensure that loadcam_entry doesn't use the stack pointer the easiest
solution is to just have it in asm code.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 8 | ||||
-rw-r--r-- | arch/powerpc/mm/fsl_booke_mmu.c | 25 | ||||
-rw-r--r-- | arch/powerpc/mm/mmu_decl.h | 10 | ||||
-rw-r--r-- | arch/powerpc/mm/tlb_nohash_low.S | 28 |
4 files changed, 48 insertions, 23 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index c09138d150d4..b894721dfb08 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -447,6 +447,14 @@ int main(void) | |||
447 | DEFINE(PGD_T_LOG2, PGD_T_LOG2); | 447 | DEFINE(PGD_T_LOG2, PGD_T_LOG2); |
448 | DEFINE(PTE_T_LOG2, PTE_T_LOG2); | 448 | DEFINE(PTE_T_LOG2, PTE_T_LOG2); |
449 | #endif | 449 | #endif |
450 | #ifdef CONFIG_FSL_BOOKE | ||
451 | DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam)); | ||
452 | DEFINE(TLBCAM_MAS0, offsetof(struct tlbcam, MAS0)); | ||
453 | DEFINE(TLBCAM_MAS1, offsetof(struct tlbcam, MAS1)); | ||
454 | DEFINE(TLBCAM_MAS2, offsetof(struct tlbcam, MAS2)); | ||
455 | DEFINE(TLBCAM_MAS3, offsetof(struct tlbcam, MAS3)); | ||
456 | DEFINE(TLBCAM_MAS7, offsetof(struct tlbcam, MAS7)); | ||
457 | #endif | ||
450 | 458 | ||
451 | #ifdef CONFIG_KVM_EXIT_TIMING | 459 | #ifdef CONFIG_KVM_EXIT_TIMING |
452 | DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu, | 460 | DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu, |
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index 1ed6b52f3031..cdc7526e9c93 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Modifications by Kumar Gala (galak@kernel.crashing.org) to support | 2 | * Modifications by Kumar Gala (galak@kernel.crashing.org) to support |
3 | * E500 Book E processors. | 3 | * E500 Book E processors. |
4 | * | 4 | * |
5 | * Copyright 2004 Freescale Semiconductor, Inc | 5 | * Copyright 2004,2010 Freescale Semiconductor, Inc. |
6 | * | 6 | * |
7 | * This file contains the routines for initializing the MMU | 7 | * This file contains the routines for initializing the MMU |
8 | * on the 4xx series of chips. | 8 | * on the 4xx series of chips. |
@@ -56,19 +56,13 @@ | |||
56 | 56 | ||
57 | unsigned int tlbcam_index; | 57 | unsigned int tlbcam_index; |
58 | 58 | ||
59 | #define NUM_TLBCAMS (64) | ||
60 | 59 | ||
61 | #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS) | 60 | #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS) |
62 | #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS" | 61 | #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS" |
63 | #endif | 62 | #endif |
64 | 63 | ||
65 | struct tlbcam { | 64 | #define NUM_TLBCAMS (64) |
66 | u32 MAS0; | 65 | struct tlbcam TLBCAM[NUM_TLBCAMS]; |
67 | u32 MAS1; | ||
68 | unsigned long MAS2; | ||
69 | u32 MAS3; | ||
70 | u32 MAS7; | ||
71 | } TLBCAM[NUM_TLBCAMS]; | ||
72 | 66 | ||
73 | struct tlbcamrange { | 67 | struct tlbcamrange { |
74 | unsigned long start; | 68 | unsigned long start; |
@@ -109,19 +103,6 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) | |||
109 | return 0; | 103 | return 0; |
110 | } | 104 | } |
111 | 105 | ||
112 | void loadcam_entry(int idx) | ||
113 | { | ||
114 | mtspr(SPRN_MAS0, TLBCAM[idx].MAS0); | ||
115 | mtspr(SPRN_MAS1, TLBCAM[idx].MAS1); | ||
116 | mtspr(SPRN_MAS2, TLBCAM[idx].MAS2); | ||
117 | mtspr(SPRN_MAS3, TLBCAM[idx].MAS3); | ||
118 | |||
119 | if (mmu_has_feature(MMU_FTR_BIG_PHYS)) | ||
120 | mtspr(SPRN_MAS7, TLBCAM[idx].MAS7); | ||
121 | |||
122 | asm volatile("isync;tlbwe;isync" : : : "memory"); | ||
123 | } | ||
124 | |||
125 | /* | 106 | /* |
126 | * Set up one of the I/D BAT (block address translation) register pairs. | 107 | * Set up one of the I/D BAT (block address translation) register pairs. |
127 | * The parameters are not checked; in particular size must be a power | 108 | * The parameters are not checked; in particular size must be a power |
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index d49a77503e19..0591f25a9b8c 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h | |||
@@ -149,7 +149,15 @@ extern unsigned long mmu_mapin_ram(unsigned long top); | |||
149 | extern void MMU_init_hw(void); | 149 | extern void MMU_init_hw(void); |
150 | extern unsigned long mmu_mapin_ram(unsigned long top); | 150 | extern unsigned long mmu_mapin_ram(unsigned long top); |
151 | extern void adjust_total_lowmem(void); | 151 | extern void adjust_total_lowmem(void); |
152 | 152 | extern void loadcam_entry(unsigned int index); | |
153 | |||
154 | struct tlbcam { | ||
155 | u32 MAS0; | ||
156 | u32 MAS1; | ||
157 | unsigned long MAS2; | ||
158 | u32 MAS3; | ||
159 | u32 MAS7; | ||
160 | }; | ||
153 | #elif defined(CONFIG_PPC32) | 161 | #elif defined(CONFIG_PPC32) |
154 | /* anything 32-bit except 4xx or 8xx */ | 162 | /* anything 32-bit except 4xx or 8xx */ |
155 | extern void MMU_init_hw(void); | 163 | extern void MMU_init_hw(void); |
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index bbdc5b577b85..8656ecf9e1d7 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S | |||
@@ -271,3 +271,31 @@ _GLOBAL(set_context) | |||
271 | #else | 271 | #else |
272 | #error Unsupported processor type ! | 272 | #error Unsupported processor type ! |
273 | #endif | 273 | #endif |
274 | |||
275 | #if defined(CONFIG_FSL_BOOKE) | ||
276 | /* | ||
277 | * extern void loadcam_entry(unsigned int index) | ||
278 | * | ||
279 | * Load TLBCAM[index] entry in to the L2 CAM MMU | ||
280 | */ | ||
281 | _GLOBAL(loadcam_entry) | ||
282 | LOAD_REG_ADDR(r4, TLBCAM) | ||
283 | mulli r5,r3,TLBCAM_SIZE | ||
284 | add r3,r5,r4 | ||
285 | lwz r4,TLBCAM_MAS0(r3) | ||
286 | mtspr SPRN_MAS0,r4 | ||
287 | lwz r4,TLBCAM_MAS1(r3) | ||
288 | mtspr SPRN_MAS1,r4 | ||
289 | PPC_LL r4,TLBCAM_MAS2(r3) | ||
290 | mtspr SPRN_MAS2,r4 | ||
291 | lwz r4,TLBCAM_MAS3(r3) | ||
292 | mtspr SPRN_MAS3,r4 | ||
293 | BEGIN_MMU_FTR_SECTION | ||
294 | lwz r4,TLBCAM_MAS7(r3) | ||
295 | mtspr SPRN_MAS7,r4 | ||
296 | END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) | ||
297 | isync | ||
298 | tlbwe | ||
299 | isync | ||
300 | blr | ||
301 | #endif | ||