diff options
Diffstat (limited to 'arch/arm/kernel/head-common.S')
-rw-r--r-- | arch/arm/kernel/head-common.S | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index a52da0ddb43d..024a9cf469b4 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S | |||
@@ -20,7 +20,8 @@ __switch_data: | |||
20 | .long _end @ r7 | 20 | .long _end @ r7 |
21 | .long processor_id @ r4 | 21 | .long processor_id @ r4 |
22 | .long __machine_arch_type @ r5 | 22 | .long __machine_arch_type @ r5 |
23 | .long cr_alignment @ r6 | 23 | .long __atags_pointer @ r6 |
24 | .long cr_alignment @ r7 | ||
24 | .long init_thread_union + THREAD_START_SP @ sp | 25 | .long init_thread_union + THREAD_START_SP @ sp |
25 | 26 | ||
26 | /* | 27 | /* |
@@ -29,6 +30,7 @@ __switch_data: | |||
29 | * | 30 | * |
30 | * r0 = cp#15 control register | 31 | * r0 = cp#15 control register |
31 | * r1 = machine ID | 32 | * r1 = machine ID |
33 | * r2 = atags pointer | ||
32 | * r9 = processor ID | 34 | * r9 = processor ID |
33 | */ | 35 | */ |
34 | .type __mmap_switched, %function | 36 | .type __mmap_switched, %function |
@@ -47,11 +49,12 @@ __mmap_switched: | |||
47 | strcc fp, [r6],#4 | 49 | strcc fp, [r6],#4 |
48 | bcc 1b | 50 | bcc 1b |
49 | 51 | ||
50 | ldmia r3, {r4, r5, r6, sp} | 52 | ldmia r3, {r4, r5, r6, r7, sp} |
51 | str r9, [r4] @ Save processor ID | 53 | str r9, [r4] @ Save processor ID |
52 | str r1, [r5] @ Save machine type | 54 | str r1, [r5] @ Save machine type |
55 | str r2, [r6] @ Save atags pointer | ||
53 | bic r4, r0, #CR_A @ Clear 'A' bit | 56 | bic r4, r0, #CR_A @ Clear 'A' bit |
54 | stmia r6, {r0, r4} @ Save control register values | 57 | stmia r7, {r0, r4} @ Save control register values |
55 | b start_kernel | 58 | b start_kernel |
56 | 59 | ||
57 | /* | 60 | /* |
@@ -215,3 +218,34 @@ ENTRY(lookup_machine_type) | |||
215 | bl __lookup_machine_type | 218 | bl __lookup_machine_type |
216 | mov r0, r5 | 219 | mov r0, r5 |
217 | ldmfd sp!, {r4 - r6, pc} | 220 | ldmfd sp!, {r4 - r6, pc} |
221 | |||
222 | /* Determine validity of the r2 atags pointer. The heuristic requires | ||
223 | * that the pointer be aligned, in the first 16k of physical RAM and | ||
224 | * that the ATAG_CORE marker is first and present. Future revisions | ||
225 | * of this function may be more lenient with the physical address and | ||
226 | * may also be able to move the ATAGS block if necessary. | ||
227 | * | ||
228 | * r8 = machinfo | ||
229 | * | ||
230 | * Returns: | ||
231 | * r2 either valid atags pointer, or zero | ||
232 | * r5, r6 corrupted | ||
233 | */ | ||
234 | |||
235 | .type __vet_atags, %function | ||
236 | __vet_atags: | ||
237 | tst r2, #0x3 @ aligned? | ||
238 | bne 1f | ||
239 | |||
240 | ldr r5, [r2, #0] @ is first tag ATAG_CORE? | ||
241 | subs r5, r5, #ATAG_CORE_SIZE | ||
242 | bne 1f | ||
243 | ldr r5, [r2, #4] | ||
244 | ldr r6, =ATAG_CORE | ||
245 | cmp r5, r6 | ||
246 | bne 1f | ||
247 | |||
248 | mov pc, lr @ atag pointer is ok | ||
249 | |||
250 | 1: mov r2, #0 | ||
251 | mov pc, lr | ||