aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/head.S
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-09-04 05:47:48 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-10-04 15:23:36 -0400
commitf00ec48fadf5e37e7889f14cff900aa70d18b644 (patch)
tree421cbce97167a78532aa825624f380caade3c0d2 /arch/arm/kernel/head.S
parent067173526c3bbc2eaeefcf6b7b2a9d998b9e8042 (diff)
ARM: Allow SMP kernels to boot on UP systems
UP systems do not implement all the instructions that SMP systems have, so in order to boot a SMP kernel on a UP system, we need to rewrite parts of the kernel. Do this using an 'alternatives' scheme, where the kernel code and data is modified prior to initialization to replace the SMP instructions, thereby rendering the problematical code ineffectual. We use the linker to generate a list of 32-bit word locations and their replacement values, and run through these replacements when we detect a UP system. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/head.S')
-rw-r--r--arch/arm/kernel/head.S50
1 files changed, 50 insertions, 0 deletions
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index eb62bf947212..b44d21e1e344 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -86,6 +86,9 @@ ENTRY(stext)
86 movs r8, r5 @ invalid machine (r5=0)? 86 movs r8, r5 @ invalid machine (r5=0)?
87 beq __error_a @ yes, error 'a' 87 beq __error_a @ yes, error 'a'
88 bl __vet_atags 88 bl __vet_atags
89#ifdef CONFIG_SMP_ON_UP
90 bl __fixup_smp
91#endif
89 bl __create_page_tables 92 bl __create_page_tables
90 93
91 /* 94 /*
@@ -333,4 +336,51 @@ __create_page_tables:
333ENDPROC(__create_page_tables) 336ENDPROC(__create_page_tables)
334 .ltorg 337 .ltorg
335 338
339#ifdef CONFIG_SMP_ON_UP
340__fixup_smp:
341 mov r7, #0x00070000
342 orr r6, r7, #0xff000000 @ mask 0xff070000
343 orr r7, r7, #0x41000000 @ val 0x41070000
344 and r0, r9, r6
345 teq r0, r7 @ ARM CPU and ARMv6/v7?
346 bne __fixup_smp_on_up @ no, assume UP
347
348 orr r6, r6, #0x0000ff00
349 orr r6, r6, #0x000000f0 @ mask 0xff07fff0
350 orr r7, r7, #0x0000b000
351 orr r7, r7, #0x00000020 @ val 0x4107b020
352 and r0, r9, r6
353 teq r0, r7 @ ARM 11MPCore?
354 moveq pc, lr @ yes, assume SMP
355
356 mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
357 tst r0, #1 << 31
358 movne pc, lr @ bit 31 => SMP
359
360__fixup_smp_on_up:
361 adr r0, 1f
362 ldmia r0, {r3, r6, r7}
363 sub r3, r0, r3
364 add r6, r6, r3
365 add r7, r7, r3
3662: cmp r6, r7
367 ldmia r6!, {r0, r4}
368 strlo r4, [r0, r3]
369 blo 2b
370 mov pc, lr
371ENDPROC(__fixup_smp)
372
3731: .word .
374 .word __smpalt_begin
375 .word __smpalt_end
376
377 .pushsection .data
378 .globl smp_on_up
379smp_on_up:
380 ALT_SMP(.long 1)
381 ALT_UP(.long 0)
382 .popsection
383
384#endif
385
336#include "head-common.S" 386#include "head-common.S"