1/* 2 * SMP support for R-Mobile / SH-Mobile 3 * 4 * Copyright (C) 2010 Magnus Damm 5 * Copyright (C) 2010 Takashi Yoshii 6 * 7 * Based on vexpress, Copyright (c) 2003 ARM Limited, All Rights Reserved 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13#include <linux/init.h> 14#include <linux/linkage.h> 15#include <linux/threads.h> 16#include <asm/assembler.h> 17#include <asm/memory.h> 18 19#define SCTLR_MMU 0x01 20#define BOOTROM_ADDRESS 0xE6340000 21#define RWTCSRA_ADDRESS 0xE6020004 22#define RWTCSRA_WOVF 0x10 23 24/* 25 * Reset vector for secondary CPUs. 26 * This will be mapped at address 0 by SBAR register. 27 * We need _long_ jump to the physical address. 28 */ 29 .arm 30 .align 12 31ENTRY(shmobile_boot_vector) 32 ldr r1, 1f 33 bx r1 34 35ENDPROC(shmobile_boot_vector) 36 37 .align 2 38 .globl shmobile_boot_fn 39shmobile_boot_fn: 401: .space 4 41 .globl shmobile_boot_size 42shmobile_boot_size: 43 .long . - shmobile_boot_vector 44 45#ifdef CONFIG_ARCH_RCAR_GEN2 46/* 47 * Reset vector for R-Car Gen2 and RZ/G1 secondary CPUs. 48 * This will be mapped at address 0 by SBAR register. 49 */ 50ENTRY(shmobile_boot_vector_gen2) 51 mrc p15, 0, r0, c0, c0, 5 @ r0 = MPIDR 52 ldr r1, shmobile_boot_cpu_gen2 53 cmp r0, r1 54 bne shmobile_smp_continue_gen2 55 56 mrc p15, 0, r1, c1, c0, 0 @ r1 = SCTLR 57 and r0, r1, #SCTLR_MMU 58 cmp r0, #SCTLR_MMU 59 beq shmobile_smp_continue_gen2 60 61 ldr r0, rwtcsra 62 mov r1, #0 63 ldrb r1, [r0] 64 and r0, r1, #RWTCSRA_WOVF 65 cmp r0, #RWTCSRA_WOVF 66 bne shmobile_smp_continue_gen2 67 68 ldr r0, bootrom 69 bx r0 70 71shmobile_smp_continue_gen2: 72 ldr r1, shmobile_boot_fn_gen2 73 bx r1 74 75ENDPROC(shmobile_boot_vector_gen2) 76 77 .align 4 78rwtcsra: 79 .word RWTCSRA_ADDRESS 80bootrom: 81 .word BOOTROM_ADDRESS 82 .globl shmobile_boot_cpu_gen2 83shmobile_boot_cpu_gen2: 84 .word 0x00000000 85 86 .align 2 87 .globl shmobile_boot_fn_gen2 88shmobile_boot_fn_gen2: 89 .space 4 90 .globl shmobile_boot_size_gen2 91shmobile_boot_size_gen2: 92 .long . - shmobile_boot_vector_gen2 93#endif /* CONFIG_ARCH_RCAR_GEN2 */ 94 95/* 96 * Per-CPU SMP boot function/argument selection code based on MPIDR 97 */ 98 99ENTRY(shmobile_smp_boot) 100 mrc p15, 0, r1, c0, c0, 5 @ r1 = MPIDR 101 and r0, r1, #0xffffff @ MPIDR_HWID_BITMASK 102 @ r0 = cpu_logical_map() value 103 mov r1, #0 @ r1 = CPU index 104 adr r2, 1f 105 ldmia r2, {r5, r6, r7} 106 add r5, r5, r2 @ array of per-cpu mpidr values 107 add r6, r6, r2 @ array of per-cpu functions 108 add r7, r7, r2 @ array of per-cpu arguments 109 110shmobile_smp_boot_find_mpidr: 111 ldr r8, [r5, r1, lsl #2] 112 cmp r8, r0 113 bne shmobile_smp_boot_next 114 115 ldr r9, [r6, r1, lsl #2] 116 cmp r9, #0 117 bne shmobile_smp_boot_found 118 119shmobile_smp_boot_next: 120 add r1, r1, #1 121 cmp r1, #NR_CPUS 122 blo shmobile_smp_boot_find_mpidr 123 124 b shmobile_smp_sleep 125 126shmobile_smp_boot_found: 127 ldr r0, [r7, r1, lsl #2] 128 ret r9 129ENDPROC(shmobile_smp_boot) 130 131ENTRY(shmobile_smp_sleep) 132 wfi 133 b shmobile_smp_boot 134ENDPROC(shmobile_smp_sleep) 135 136 .align 2 1371: .long shmobile_smp_mpidr - . 138 .long shmobile_smp_fn - 1b 139 .long shmobile_smp_arg - 1b 140 141 .bss 142 .globl shmobile_smp_mpidr 143shmobile_smp_mpidr: 144 .space NR_CPUS * 4 145 .globl shmobile_smp_fn 146shmobile_smp_fn: 147 .space NR_CPUS * 4 148 .globl shmobile_smp_arg 149shmobile_smp_arg: 150 .space NR_CPUS * 4 151