summaryrefslogtreecommitdiff
path: root/arch/arm/mach-shmobile/headsmp.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile/headsmp.S')
-rw-r--r--arch/arm/mach-shmobile/headsmp.S55
1 files changed, 54 insertions, 1 deletions
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
index a9d212498987..f93751caf5cb 100644
--- a/arch/arm/mach-shmobile/headsmp.S
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -24,15 +24,68 @@ ENDPROC(shmobile_invalidate_start)
* This will be mapped at address 0 by SBAR register.
* We need _long_ jump to the physical address.
*/
+ .arm
.align 12
ENTRY(shmobile_boot_vector)
ldr r0, 2f
- ldr pc, 1f
+ ldr r1, 1f
+ bx r1
+
ENDPROC(shmobile_boot_vector)
+ .align 2
.globl shmobile_boot_fn
shmobile_boot_fn:
1: .space 4
.globl shmobile_boot_arg
shmobile_boot_arg:
2: .space 4
+
+/*
+ * Per-CPU SMP boot function/argument selection code based on MPIDR
+ */
+
+ENTRY(shmobile_smp_boot)
+ @ r0 = MPIDR_HWID_BITMASK
+ mrc p15, 0, r1, c0, c0, 5 @ r1 = MPIDR
+ and r0, r1, r0 @ r0 = cpu_logical_map() value
+ mov r1, #0 @ r1 = CPU index
+ adr r5, 1f @ array of per-cpu mpidr values
+ adr r6, 2f @ array of per-cpu functions
+ adr r7, 3f @ array of per-cpu arguments
+
+shmobile_smp_boot_find_mpidr:
+ ldr r8, [r5, r1, lsl #2]
+ cmp r8, r0
+ bne shmobile_smp_boot_next
+
+ ldr r9, [r6, r1, lsl #2]
+ cmp r9, #0
+ bne shmobile_smp_boot_found
+
+shmobile_smp_boot_next:
+ add r1, r1, #1
+ cmp r1, #CONFIG_NR_CPUS
+ blo shmobile_smp_boot_find_mpidr
+
+ b shmobile_smp_sleep
+
+shmobile_smp_boot_found:
+ ldr r0, [r7, r1, lsl #2]
+ mov pc, r9
+ENDPROC(shmobile_smp_boot)
+
+ENTRY(shmobile_smp_sleep)
+ wfi
+ b shmobile_smp_boot
+ENDPROC(shmobile_smp_sleep)
+
+ .globl shmobile_smp_mpidr
+shmobile_smp_mpidr:
+1: .space CONFIG_NR_CPUS * 4
+ .globl shmobile_smp_fn
+shmobile_smp_fn:
+2: .space CONFIG_NR_CPUS * 4
+ .globl shmobile_smp_arg
+shmobile_smp_arg:
+3: .space CONFIG_NR_CPUS * 4