aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrent Piepho <tpiepho@freescale.com>2008-11-19 06:13:14 -0500
committerKumar Gala <galak@kernel.crashing.org>2008-12-03 09:19:18 -0500
commitb3898895355f73973eb3aef3489e999d3fb8e2bc (patch)
treec9738f5585158948f6d2cd3955aa4969b2b4b935
parent6a800f36acd5bf06b5fe2cb27c4d0524d60c3df5 (diff)
powerpc: Better setup of boot page TLB entry
The initial TLB mapping for the kernel boot didn't set the memory coherent attribute, MAS2[M], in SMP mode. If this code supported booting a secondary processor, which it doesn't yet, but if it did, then when a secondary processor boots, it would probably signal the primary processor by setting a variable called something like __secondary_hold_acknowledge. However, due to the lack of the M bit, the primary processor would not snoop the transaction (even if a transaction were broadcast). If primary CPU's L1 D-cache had a copy, it would not be flushed and the CPU would never see the ack. Which would have resulted in the primary CPU spinning for a long time, perhaps a full second before it gives up, while it would have waited for the ack from the secondary CPU that it wouldn't have been able to see because of the stale cache. The value of MAS2 for the boot page TLB1 entry is a compile time constant, so there is no need to calculate it in powerpc assembly language. Also, from the MPC8572 manual section 6.12.5.3, "Bits that represent offsets within a page are ignored and should be cleared." Existing code didn't clear them, this code does. The same when the page of KERNELBASE is found; we don't need to use asm to mask the lower 12 bits off. In the code that computes the address to rfi from, don't hard code the offset to 24 bytes, but have the assembler figure that out for us. Signed-off-by: Trent Piepho <tpiepho@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/mmu-fsl-booke.h2
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S22
2 files changed, 15 insertions, 9 deletions
diff --git a/arch/powerpc/include/asm/mmu-fsl-booke.h b/arch/powerpc/include/asm/mmu-fsl-booke.h
index 925d93cf64d8..5588a41f439c 100644
--- a/arch/powerpc/include/asm/mmu-fsl-booke.h
+++ b/arch/powerpc/include/asm/mmu-fsl-booke.h
@@ -40,6 +40,8 @@
40#define MAS2_M 0x00000004 40#define MAS2_M 0x00000004
41#define MAS2_G 0x00000002 41#define MAS2_G 0x00000002
42#define MAS2_E 0x00000001 42#define MAS2_E 0x00000001
43#define MAS2_EPN_MASK(size) (~0 << (2*(size) + 10))
44#define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags))
43 45
44#define MAS3_RPN 0xFFFFF000 46#define MAS3_RPN 0xFFFFF000
45#define MAS3_U0 0x00000200 47#define MAS3_U0 0x00000200
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 837e3cc9cc85..8942d7a82faf 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -235,36 +235,40 @@ skpinv: addi r6,r6,1 /* Increment */
235 tlbivax 0,r9 235 tlbivax 0,r9
236 TLBSYNC 236 TLBSYNC
237 237
238/* The mapping only needs to be cache-coherent on SMP */
239#ifdef CONFIG_SMP
240#define M_IF_SMP MAS2_M
241#else
242#define M_IF_SMP 0
243#endif
244
238/* 6. Setup KERNELBASE mapping in TLB1[0] */ 245/* 6. Setup KERNELBASE mapping in TLB1[0] */
239 lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ 246 lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
240 mtspr SPRN_MAS0,r6 247 mtspr SPRN_MAS0,r6
241 lis r6,(MAS1_VALID|MAS1_IPROT)@h 248 lis r6,(MAS1_VALID|MAS1_IPROT)@h
242 ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l 249 ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
243 mtspr SPRN_MAS1,r6 250 mtspr SPRN_MAS1,r6
244 li r7,0 251 lis r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@h
245 lis r6,PAGE_OFFSET@h 252 ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@l
246 ori r6,r6,PAGE_OFFSET@l
247 rlwimi r6,r7,0,20,31
248 mtspr SPRN_MAS2,r6 253 mtspr SPRN_MAS2,r6
249 mtspr SPRN_MAS3,r8 254 mtspr SPRN_MAS3,r8
250 tlbwe 255 tlbwe
251 256
252/* 7. Jump to KERNELBASE mapping */ 257/* 7. Jump to KERNELBASE mapping */
253 lis r6,KERNELBASE@h 258 lis r6,(KERNELBASE & ~0xfff)@h
254 ori r6,r6,KERNELBASE@l 259 ori r6,r6,(KERNELBASE & ~0xfff)@l
255 rlwimi r6,r7,0,20,31
256 lis r7,MSR_KERNEL@h 260 lis r7,MSR_KERNEL@h
257 ori r7,r7,MSR_KERNEL@l 261 ori r7,r7,MSR_KERNEL@l
258 bl 1f /* Find our address */ 262 bl 1f /* Find our address */
2591: mflr r9 2631: mflr r9
260 rlwimi r6,r9,0,20,31 264 rlwimi r6,r9,0,20,31
261 addi r6,r6,24 265 addi r6,r6,(2f - 1b)
262 mtspr SPRN_SRR0,r6 266 mtspr SPRN_SRR0,r6
263 mtspr SPRN_SRR1,r7 267 mtspr SPRN_SRR1,r7
264 rfi /* start execution out of TLB1[0] entry */ 268 rfi /* start execution out of TLB1[0] entry */
265 269
266/* 8. Clear out the temp mapping */ 270/* 8. Clear out the temp mapping */
267 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ 2712: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
268 rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ 272 rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
269 mtspr SPRN_MAS0,r7 273 mtspr SPRN_MAS0,r7
270 tlbre 274 tlbre