Commit 9d20fdd58e74d4d26dc5216efaaa0f800c23dd3a
Committed by
Russell King
1 parent
7d09e85448
Exists in
master
and in
7 other branches
[ARM] 4423/1: add ATAGS support
Examines the ATAGS pointer (r2) at boot, and interprets a nonzero value as a reference to an ATAGS structure. A suitable ATAGS structure replaces the kernel's command line. Signed-off-by: Bill Gatliff <bgat@billgatliff.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Showing 3 changed files with 48 additions and 5 deletions Side-by-side Diff
arch/arm/kernel/head-common.S
... | ... | @@ -20,7 +20,8 @@ |
20 | 20 | .long _end @ r7 |
21 | 21 | .long processor_id @ r4 |
22 | 22 | .long __machine_arch_type @ r5 |
23 | - .long cr_alignment @ r6 | |
23 | + .long __atags_pointer @ r6 | |
24 | + .long cr_alignment @ r7 | |
24 | 25 | .long init_thread_union + THREAD_START_SP @ sp |
25 | 26 | |
26 | 27 | /* |
... | ... | @@ -29,6 +30,7 @@ |
29 | 30 | * |
30 | 31 | * r0 = cp#15 control register |
31 | 32 | * r1 = machine ID |
33 | + * r2 = atags pointer | |
32 | 34 | * r9 = processor ID |
33 | 35 | */ |
34 | 36 | .type __mmap_switched, %function |
35 | 37 | |
36 | 38 | |
... | ... | @@ -47,11 +49,12 @@ |
47 | 49 | strcc fp, [r6],#4 |
48 | 50 | bcc 1b |
49 | 51 | |
50 | - ldmia r3, {r4, r5, r6, sp} | |
52 | + ldmia r3, {r4, r5, r6, r7, sp} | |
51 | 53 | str r9, [r4] @ Save processor ID |
52 | 54 | str r1, [r5] @ Save machine type |
55 | + str r2, [r6] @ Save atags pointer | |
53 | 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 | 58 | b start_kernel |
56 | 59 | |
57 | 60 | /* |
... | ... | @@ -215,4 +218,35 @@ |
215 | 218 | bl __lookup_machine_type |
216 | 219 | mov r0, r5 |
217 | 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 |
arch/arm/kernel/head.S
... | ... | @@ -29,6 +29,10 @@ |
29 | 29 | #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) |
30 | 30 | #define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET) |
31 | 31 | |
32 | +#define ATAG_CORE 0x54410001 | |
33 | +#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) | |
34 | + | |
35 | + | |
32 | 36 | /* |
33 | 37 | * swapper_pg_dir is the virtual address of the initial page table. |
34 | 38 | * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must |
... | ... | @@ -61,7 +65,7 @@ |
61 | 65 | * |
62 | 66 | * This is normally called from the decompressor code. The requirements |
63 | 67 | * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, |
64 | - * r1 = machine nr. | |
68 | + * r1 = machine nr, r2 = atags pointer. | |
65 | 69 | * |
66 | 70 | * This code is mostly position independent, so if you link the kernel at |
67 | 71 | * 0xc0008000, you call this at __pa(0xc0008000). |
... | ... | @@ -85,6 +89,7 @@ |
85 | 89 | bl __lookup_machine_type @ r5=machinfo |
86 | 90 | movs r8, r5 @ invalid machine (r5=0)? |
87 | 91 | beq __error_a @ yes, error 'a' |
92 | + bl __vet_atags | |
88 | 93 | bl __create_page_tables |
89 | 94 | |
90 | 95 | /* |
arch/arm/kernel/setup.c
... | ... | @@ -63,6 +63,8 @@ |
63 | 63 | unsigned int __machine_arch_type; |
64 | 64 | EXPORT_SYMBOL(__machine_arch_type); |
65 | 65 | |
66 | +unsigned int __atags_pointer __initdata; | |
67 | + | |
66 | 68 | unsigned int system_rev; |
67 | 69 | EXPORT_SYMBOL(system_rev); |
68 | 70 | |
... | ... | @@ -780,7 +782,9 @@ |
780 | 782 | if (mdesc->soft_reboot) |
781 | 783 | reboot_setup("s"); |
782 | 784 | |
783 | - if (mdesc->boot_params) | |
785 | + if (__atags_pointer) | |
786 | + tags = phys_to_virt(__atags_pointer); | |
787 | + else if (mdesc->boot_params) | |
784 | 788 | tags = phys_to_virt(mdesc->boot_params); |
785 | 789 | |
786 | 790 | /* |