aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorBill Gatliff <bgat@billgatliff.com>2007-05-31 17:02:22 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-07-12 06:13:33 -0400
commit9d20fdd58e74d4d26dc5216efaaa0f800c23dd3a (patch)
treebc8520791f304ce297a52f575930c2797067521c /arch/arm
parent7d09e85448dfa78e3e58186c934449aaf6d49b50 (diff)
[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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/head-common.S40
-rw-r--r--arch/arm/kernel/head.S7
-rw-r--r--arch/arm/kernel/setup.c6
3 files changed, 48 insertions, 5 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
2501: mov r2, #0
251 mov pc, lr
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 41f98b4ba2ee..7898cbc9861a 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -29,6 +29,10 @@
29#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) 29#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
30#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET) 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 * swapper_pg_dir is the virtual address of the initial page table. 37 * swapper_pg_dir is the virtual address of the initial page table.
34 * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must 38 * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
@@ -61,7 +65,7 @@
61 * 65 *
62 * This is normally called from the decompressor code. The requirements 66 * This is normally called from the decompressor code. The requirements
63 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, 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 * This code is mostly position independent, so if you link the kernel at 70 * This code is mostly position independent, so if you link the kernel at
67 * 0xc0008000, you call this at __pa(0xc0008000). 71 * 0xc0008000, you call this at __pa(0xc0008000).
@@ -85,6 +89,7 @@ ENTRY(stext)
85 bl __lookup_machine_type @ r5=machinfo 89 bl __lookup_machine_type @ r5=machinfo
86 movs r8, r5 @ invalid machine (r5=0)? 90 movs r8, r5 @ invalid machine (r5=0)?
87 beq __error_a @ yes, error 'a' 91 beq __error_a @ yes, error 'a'
92 bl __vet_atags
88 bl __create_page_tables 93 bl __create_page_tables
89 94
90 /* 95 /*
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 650eac1bc0a6..5be2e987b843 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -63,6 +63,8 @@ unsigned int processor_id;
63unsigned int __machine_arch_type; 63unsigned int __machine_arch_type;
64EXPORT_SYMBOL(__machine_arch_type); 64EXPORT_SYMBOL(__machine_arch_type);
65 65
66unsigned int __atags_pointer __initdata;
67
66unsigned int system_rev; 68unsigned int system_rev;
67EXPORT_SYMBOL(system_rev); 69EXPORT_SYMBOL(system_rev);
68 70
@@ -780,7 +782,9 @@ void __init setup_arch(char **cmdline_p)
780 if (mdesc->soft_reboot) 782 if (mdesc->soft_reboot)
781 reboot_setup("s"); 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 tags = phys_to_virt(mdesc->boot_params); 788 tags = phys_to_virt(mdesc->boot_params);
785 789
786 /* 790 /*