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