Commit 9d20fdd58e74d4d26dc5216efaaa0f800c23dd3a

Authored by Bill Gatliff
Committed by Russell King
1 parent 7d09e85448

[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 /*