aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/head.S
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-01-04 14:04:00 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-02-17 18:27:30 -0500
commit72a20e22f49e2dad3180c23980a9df1c63faab0a (patch)
tree97edaa9db248ecc7e9a6a66c1ef5a054412af5c2 /arch/arm/kernel/head.S
parentb75c178afaa975896e894bb2b6951dc4cd43c977 (diff)
ARM: P2V: eliminate head.S use of PHYS_OFFSET for !XIP_KERNEL
head.S makes use of PHYS_OFFSET. When it becomes a variable, the assembler won't understand this. Compute PHYS_OFFSET by the following method. This code is linked at its virtual address, but run at before the MMU is enabled, so at his physical address. 1: .long . .long PAGE_OFFSET adr r0, 1b @ r0 = physical ',' ldmia r0, {r1, r2} @ r1 = virtual '.', r2 = PAGE_OFFSET sub r1, r0, r1 @ r1 = physical-virtual add r2, r2, r1 @ r2 = PAGE_OFFSET + physical-virtual @ := PHYS_OFFSET. Switch XIP users of PHYS_OFFSET to use PLAT_PHYS_OFFSET - we can't use this method for XIP kernels as the code doesn't execute in RAM. Tested-by: Tony Lindgren <tony@atomide.com> Reviewed-by: Nicolas Pitre <nicolas.pitre@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/head.S')
-rw-r--r--arch/arm/kernel/head.S44
1 files changed, 22 insertions, 22 deletions
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 8a154b940fef..03a588b6e15c 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -26,14 +26,6 @@
26#include <mach/debug-macro.S> 26#include <mach/debug-macro.S>
27#endif 27#endif
28 28
29#if (PHYS_OFFSET & 0x001fffff)
30#error "PHYS_OFFSET must be at an even 2MiB boundary!"
31#endif
32
33#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
34#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
35
36
37/* 29/*
38 * swapper_pg_dir is the virtual address of the initial page table. 30 * swapper_pg_dir is the virtual address of the initial page table.
39 * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must 31 * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
@@ -41,6 +33,7 @@
41 * the least significant 16 bits to be 0x8000, but we could probably 33 * the least significant 16 bits to be 0x8000, but we could probably
42 * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000. 34 * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
43 */ 35 */
36#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
44#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000 37#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
45#error KERNEL_RAM_VADDR must start at 0xXXXX8000 38#error KERNEL_RAM_VADDR must start at 0xXXXX8000
46#endif 39#endif
@@ -48,8 +41,8 @@
48 .globl swapper_pg_dir 41 .globl swapper_pg_dir
49 .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000 42 .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
50 43
51 .macro pgtbl, rd 44 .macro pgtbl, rd, phys
52 ldr \rd, =(KERNEL_RAM_PADDR - 0x4000) 45 add \rd, \phys, #TEXT_OFFSET - 0x4000
53 .endm 46 .endm
54 47
55#ifdef CONFIG_XIP_KERNEL 48#ifdef CONFIG_XIP_KERNEL
@@ -88,9 +81,18 @@ ENTRY(stext)
88 THUMB( it eq ) @ force fixup-able long branch encoding 81 THUMB( it eq ) @ force fixup-able long branch encoding
89 beq __error_p @ yes, error 'p' 82 beq __error_p @ yes, error 'p'
90 83
84#ifndef CONFIG_XIP_KERNEL
85 adr r3, 2f
86 ldmia r3, {r4, r8}
87 sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET)
88 add r8, r8, r4 @ PHYS_OFFSET
89#else
90 ldr r8, =PLAT_PHYS_OFFSET
91#endif
92
91 /* 93 /*
92 * r1 = machine no, r2 = atags, 94 * r1 = machine no, r2 = atags,
93 * r9 = cpuid, r10 = procinfo 95 * r8 = phys_offset, r9 = cpuid, r10 = procinfo
94 */ 96 */
95 bl __vet_atags 97 bl __vet_atags
96#ifdef CONFIG_SMP_ON_UP 98#ifdef CONFIG_SMP_ON_UP
@@ -114,21 +116,24 @@ ENTRY(stext)
1141: b __enable_mmu 1161: b __enable_mmu
115ENDPROC(stext) 117ENDPROC(stext)
116 .ltorg 118 .ltorg
119#ifndef CONFIG_XIP_KERNEL
1202: .long .
121 .long PAGE_OFFSET
122#endif
117 123
118/* 124/*
119 * Setup the initial page tables. We only setup the barest 125 * Setup the initial page tables. We only setup the barest
120 * amount which are required to get the kernel running, which 126 * amount which are required to get the kernel running, which
121 * generally means mapping in the kernel code. 127 * generally means mapping in the kernel code.
122 * 128 *
123 * r9 = cpuid 129 * r8 = phys_offset, r9 = cpuid, r10 = procinfo
124 * r10 = procinfo
125 * 130 *
126 * Returns: 131 * Returns:
127 * r0, r3, r5-r7 corrupted 132 * r0, r3, r5-r7 corrupted
128 * r4 = physical page table address 133 * r4 = physical page table address
129 */ 134 */
130__create_page_tables: 135__create_page_tables:
131 pgtbl r4 @ page table address 136 pgtbl r4, r8 @ page table address
132 137
133 /* 138 /*
134 * Clear the 16K level 1 swapper page table 139 * Clear the 16K level 1 swapper page table
@@ -184,10 +189,8 @@ __create_page_tables:
184 /* 189 /*
185 * Map some ram to cover our .data and .bss areas. 190 * Map some ram to cover our .data and .bss areas.
186 */ 191 */
187 orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000) 192 add r3, r8, #TEXT_OFFSET
188 .if (KERNEL_RAM_PADDR & 0x00f00000) 193 orr r3, r3, r7
189 orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
190 .endif
191 add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18 194 add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
192 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]! 195 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
193 ldr r6, =(_end - 1) 196 ldr r6, =(_end - 1)
@@ -203,10 +206,7 @@ __create_page_tables:
203 * Then map first 1MB of ram in case it contains our boot params. 206 * Then map first 1MB of ram in case it contains our boot params.
204 */ 207 */
205 add r0, r4, #PAGE_OFFSET >> 18 208 add r0, r4, #PAGE_OFFSET >> 18
206 orr r6, r7, #(PHYS_OFFSET & 0xff000000) 209 orr r6, r7, r8
207 .if (PHYS_OFFSET & 0x00f00000)
208 orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
209 .endif
210 str r6, [r0] 210 str r6, [r0]
211 211
212#ifdef CONFIG_DEBUG_LL 212#ifdef CONFIG_DEBUG_LL