diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-10-01 10:37:05 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-10-08 05:07:32 -0400 |
commit | 5085f3ff458521045f7e43da62b8c30ea7df2e82 (patch) | |
tree | 3820362ac7e1a52ba398909fa1bd024ba4fc552d /arch/arm/kernel | |
parent | 37b05b63754e995b8cb76f4fbe7ed7219b3ca896 (diff) |
ARM: hotplug cpu: Keep processor information, startup code & __lookup_processor_type
When hotplug CPU is enabled, we need to keep the list of supported CPUs,
their setup functions, and __lookup_processor_type in place so that we
can find and initialize secondary CPUs. Move these into the __CPUINIT
section.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/head-common.S | 81 | ||||
-rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 24 |
2 files changed, 62 insertions, 43 deletions
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index b9505aa267c0..6ad24d2cb14b 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S | |||
@@ -145,45 +145,14 @@ ENDPROC(__error) | |||
145 | 145 | ||
146 | 146 | ||
147 | /* | 147 | /* |
148 | * Read processor ID register (CP#15, CR0), and look up in the linker-built | 148 | * This provides a C-API version of __lookup_processor_type |
149 | * supported processor list. Note that we can't use the absolute addresses | ||
150 | * for the __proc_info lists since we aren't running with the MMU on | ||
151 | * (and therefore, we are not in the correct address space). We have to | ||
152 | * calculate the offset. | ||
153 | * | ||
154 | * r9 = cpuid | ||
155 | * Returns: | ||
156 | * r3, r4, r6 corrupted | ||
157 | * r5 = proc_info pointer in physical address space | ||
158 | * r9 = cpuid (preserved) | ||
159 | */ | ||
160 | __lookup_processor_type: | ||
161 | adr r3, 3f | ||
162 | ldmia r3, {r5 - r7} | ||
163 | add r3, r3, #8 | ||
164 | sub r3, r3, r7 @ get offset between virt&phys | ||
165 | add r5, r5, r3 @ convert virt addresses to | ||
166 | add r6, r6, r3 @ physical address space | ||
167 | 1: ldmia r5, {r3, r4} @ value, mask | ||
168 | and r4, r4, r9 @ mask wanted bits | ||
169 | teq r3, r4 | ||
170 | beq 2f | ||
171 | add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) | ||
172 | cmp r5, r6 | ||
173 | blo 1b | ||
174 | mov r5, #0 @ unknown processor | ||
175 | 2: mov pc, lr | ||
176 | ENDPROC(__lookup_processor_type) | ||
177 | |||
178 | /* | ||
179 | * This provides a C-API version of the above function. | ||
180 | */ | 149 | */ |
181 | ENTRY(lookup_processor_type) | 150 | ENTRY(lookup_processor_type) |
182 | stmfd sp!, {r4 - r7, r9, lr} | 151 | stmfd sp!, {r4 - r6, r9, lr} |
183 | mov r9, r0 | 152 | mov r9, r0 |
184 | bl __lookup_processor_type | 153 | bl __lookup_processor_type |
185 | mov r0, r5 | 154 | mov r0, r5 |
186 | ldmfd sp!, {r4 - r7, r9, pc} | 155 | ldmfd sp!, {r4 - r6, r9, pc} |
187 | ENDPROC(lookup_processor_type) | 156 | ENDPROC(lookup_processor_type) |
188 | 157 | ||
189 | /* | 158 | /* |
@@ -191,8 +160,6 @@ ENDPROC(lookup_processor_type) | |||
191 | * more information about the __proc_info and __arch_info structures. | 160 | * more information about the __proc_info and __arch_info structures. |
192 | */ | 161 | */ |
193 | .align 2 | 162 | .align 2 |
194 | 3: .long __proc_info_begin | ||
195 | .long __proc_info_end | ||
196 | 4: .long . | 163 | 4: .long . |
197 | .long __arch_info_begin | 164 | .long __arch_info_begin |
198 | .long __arch_info_end | 165 | .long __arch_info_end |
@@ -265,3 +232,45 @@ __vet_atags: | |||
265 | 1: mov r2, #0 | 232 | 1: mov r2, #0 |
266 | mov pc, lr | 233 | mov pc, lr |
267 | ENDPROC(__vet_atags) | 234 | ENDPROC(__vet_atags) |
235 | |||
236 | /* | ||
237 | * Read processor ID register (CP#15, CR0), and look up in the linker-built | ||
238 | * supported processor list. Note that we can't use the absolute addresses | ||
239 | * for the __proc_info lists since we aren't running with the MMU on | ||
240 | * (and therefore, we are not in the correct address space). We have to | ||
241 | * calculate the offset. | ||
242 | * | ||
243 | * r9 = cpuid | ||
244 | * Returns: | ||
245 | * r3, r4, r6 corrupted | ||
246 | * r5 = proc_info pointer in physical address space | ||
247 | * r9 = cpuid (preserved) | ||
248 | */ | ||
249 | __CPUINIT | ||
250 | __lookup_processor_type: | ||
251 | adr r3, __lookup_processor_type_data | ||
252 | ldmia r3, {r4 - r6} | ||
253 | sub r3, r3, r4 @ get offset between virt&phys | ||
254 | add r5, r5, r3 @ convert virt addresses to | ||
255 | add r6, r6, r3 @ physical address space | ||
256 | 1: ldmia r5, {r3, r4} @ value, mask | ||
257 | and r4, r4, r9 @ mask wanted bits | ||
258 | teq r3, r4 | ||
259 | beq 2f | ||
260 | add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) | ||
261 | cmp r5, r6 | ||
262 | blo 1b | ||
263 | mov r5, #0 @ unknown processor | ||
264 | 2: mov pc, lr | ||
265 | ENDPROC(__lookup_processor_type) | ||
266 | |||
267 | /* | ||
268 | * Look in <asm/procinfo.h> for information about the __proc_info structure. | ||
269 | */ | ||
270 | .align 2 | ||
271 | .type __lookup_processor_type_data, %object | ||
272 | __lookup_processor_type_data: | ||
273 | .long . | ||
274 | .long __proc_info_begin | ||
275 | .long __proc_info_end | ||
276 | .size __lookup_processor_type_data, . - __lookup_processor_type_data | ||
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index b16c07914b55..1630524a3097 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -8,6 +8,19 @@ | |||
8 | #include <asm/memory.h> | 8 | #include <asm/memory.h> |
9 | #include <asm/page.h> | 9 | #include <asm/page.h> |
10 | 10 | ||
11 | #define PROC_INFO \ | ||
12 | VMLINUX_SYMBOL(__proc_info_begin) = .; \ | ||
13 | *(.proc.info.init) \ | ||
14 | VMLINUX_SYMBOL(__proc_info_end) = .; | ||
15 | |||
16 | #ifdef CONFIG_HOTPLUG_CPU | ||
17 | #define ARM_CPU_DISCARD(x) | ||
18 | #define ARM_CPU_KEEP(x) x | ||
19 | #else | ||
20 | #define ARM_CPU_DISCARD(x) x | ||
21 | #define ARM_CPU_KEEP(x) | ||
22 | #endif | ||
23 | |||
11 | OUTPUT_ARCH(arm) | 24 | OUTPUT_ARCH(arm) |
12 | ENTRY(stext) | 25 | ENTRY(stext) |
13 | 26 | ||
@@ -31,9 +44,7 @@ SECTIONS | |||
31 | HEAD_TEXT | 44 | HEAD_TEXT |
32 | INIT_TEXT | 45 | INIT_TEXT |
33 | _einittext = .; | 46 | _einittext = .; |
34 | __proc_info_begin = .; | 47 | ARM_CPU_DISCARD(PROC_INFO) |
35 | *(.proc.info.init) | ||
36 | __proc_info_end = .; | ||
37 | __arch_info_begin = .; | 48 | __arch_info_begin = .; |
38 | *(.arch.info.init) | 49 | *(.arch.info.init) |
39 | __arch_info_end = .; | 50 | __arch_info_end = .; |
@@ -68,10 +79,8 @@ SECTIONS | |||
68 | /DISCARD/ : { | 79 | /DISCARD/ : { |
69 | *(.ARM.exidx.exit.text) | 80 | *(.ARM.exidx.exit.text) |
70 | *(.ARM.extab.exit.text) | 81 | *(.ARM.extab.exit.text) |
71 | #ifndef CONFIG_HOTPLUG_CPU | 82 | ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text)) |
72 | *(.ARM.exidx.cpuexit.text) | 83 | ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text)) |
73 | *(.ARM.extab.cpuexit.text) | ||
74 | #endif | ||
75 | #ifndef CONFIG_HOTPLUG | 84 | #ifndef CONFIG_HOTPLUG |
76 | *(.ARM.exidx.devexit.text) | 85 | *(.ARM.exidx.devexit.text) |
77 | *(.ARM.extab.devexit.text) | 86 | *(.ARM.extab.devexit.text) |
@@ -100,6 +109,7 @@ SECTIONS | |||
100 | *(.glue_7) | 109 | *(.glue_7) |
101 | *(.glue_7t) | 110 | *(.glue_7t) |
102 | *(.got) /* Global offset table */ | 111 | *(.got) /* Global offset table */ |
112 | ARM_CPU_KEEP(PROC_INFO) | ||
103 | } | 113 | } |
104 | 114 | ||
105 | RO_DATA(PAGE_SIZE) | 115 | RO_DATA(PAGE_SIZE) |