diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-04 14:04:00 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-02-17 18:27:30 -0500 |
commit | 72a20e22f49e2dad3180c23980a9df1c63faab0a (patch) | |
tree | 97edaa9db248ecc7e9a6a66c1ef5a054412af5c2 /arch/arm/kernel | |
parent | b75c178afaa975896e894bb2b6951dc4cd43c977 (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')
-rw-r--r-- | arch/arm/kernel/head.S | 44 |
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) | |||
114 | 1: b __enable_mmu | 116 | 1: b __enable_mmu |
115 | ENDPROC(stext) | 117 | ENDPROC(stext) |
116 | .ltorg | 118 | .ltorg |
119 | #ifndef CONFIG_XIP_KERNEL | ||
120 | 2: .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 |