diff options
author | Matthew Leach <matthew.leach@arm.com> | 2013-10-11 09:52:16 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2013-10-25 10:59:39 -0400 |
commit | 828e9834e9a5b7e61046aa3c5f603a4fecba2fb4 (patch) | |
tree | 0a0e3cd11b88f88b718e71fcb7990152486cf1a7 /arch/arm64/kernel/head.S | |
parent | e68bedaa03c950ae8045e7899e7a6b2a97d1bf41 (diff) |
arm64: head: create a new function for setting the boot_cpu_mode flag
Currently, the code for setting the __cpu_boot_mode flag is munged in
with el2_setup. This makes things difficult on a BE bringup as a
memory access has to have occurred before el2_setup which is the place
that we'd like to set the endianess on the current EL.
Create a new function for setting __cpu_boot_mode and have el2_setup
return the mode the CPU. Also define a new constant in virt.h,
BOOT_CPU_MODE_EL1, for readability.
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Matthew Leach <matthew.leach@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/head.S')
-rw-r--r-- | arch/arm64/kernel/head.S | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index bf7efdf2d7e7..775ecb313ee7 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -123,8 +123,9 @@ | |||
123 | 123 | ||
124 | ENTRY(stext) | 124 | ENTRY(stext) |
125 | mov x21, x0 // x21=FDT | 125 | mov x21, x0 // x21=FDT |
126 | bl el2_setup // Drop to EL1, w20=cpu_boot_mode | ||
126 | bl __calc_phys_offset // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET | 127 | bl __calc_phys_offset // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET |
127 | bl el2_setup // Drop to EL1 | 128 | bl set_cpu_boot_mode_flag |
128 | mrs x22, midr_el1 // x22=cpuid | 129 | mrs x22, midr_el1 // x22=cpuid |
129 | mov x0, x22 | 130 | mov x0, x22 |
130 | bl lookup_processor_type | 131 | bl lookup_processor_type |
@@ -150,21 +151,20 @@ ENDPROC(stext) | |||
150 | /* | 151 | /* |
151 | * If we're fortunate enough to boot at EL2, ensure that the world is | 152 | * If we're fortunate enough to boot at EL2, ensure that the world is |
152 | * sane before dropping to EL1. | 153 | * sane before dropping to EL1. |
154 | * | ||
155 | * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in x20 if | ||
156 | * booted in EL1 or EL2 respectively. | ||
153 | */ | 157 | */ |
154 | ENTRY(el2_setup) | 158 | ENTRY(el2_setup) |
155 | mrs x0, CurrentEL | 159 | mrs x0, CurrentEL |
156 | cmp x0, #PSR_MODE_EL2t | 160 | cmp x0, #PSR_MODE_EL2t |
157 | ccmp x0, #PSR_MODE_EL2h, #0x4, ne | 161 | ccmp x0, #PSR_MODE_EL2h, #0x4, ne |
158 | ldr x0, =__boot_cpu_mode // Compute __boot_cpu_mode | ||
159 | add x0, x0, x28 | ||
160 | b.eq 1f | 162 | b.eq 1f |
161 | str wzr, [x0] // Remember we don't have EL2... | 163 | mov w20, #BOOT_CPU_MODE_EL1 // This cpu booted in EL1 |
162 | ret | 164 | ret |
163 | 165 | ||
164 | /* Hyp configuration. */ | 166 | /* Hyp configuration. */ |
165 | 1: ldr w1, =BOOT_CPU_MODE_EL2 | 167 | 1: mov x0, #(1 << 31) // 64-bit EL1 |
166 | str w1, [x0, #4] // This CPU has EL2 | ||
167 | mov x0, #(1 << 31) // 64-bit EL1 | ||
168 | msr hcr_el2, x0 | 168 | msr hcr_el2, x0 |
169 | 169 | ||
170 | /* Generic timers. */ | 170 | /* Generic timers. */ |
@@ -204,10 +204,25 @@ ENTRY(el2_setup) | |||
204 | PSR_MODE_EL1h) | 204 | PSR_MODE_EL1h) |
205 | msr spsr_el2, x0 | 205 | msr spsr_el2, x0 |
206 | msr elr_el2, lr | 206 | msr elr_el2, lr |
207 | mov w20, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2 | ||
207 | eret | 208 | eret |
208 | ENDPROC(el2_setup) | 209 | ENDPROC(el2_setup) |
209 | 210 | ||
210 | /* | 211 | /* |
212 | * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed | ||
213 | * in x20. See arch/arm64/include/asm/virt.h for more info. | ||
214 | */ | ||
215 | ENTRY(set_cpu_boot_mode_flag) | ||
216 | ldr x1, =__boot_cpu_mode // Compute __boot_cpu_mode | ||
217 | add x1, x1, x28 | ||
218 | cmp w20, #BOOT_CPU_MODE_EL2 | ||
219 | b.ne 1f | ||
220 | add x1, x1, #4 | ||
221 | 1: str w20, [x1] // This CPU has booted in EL1 | ||
222 | ret | ||
223 | ENDPROC(set_cpu_boot_mode_flag) | ||
224 | |||
225 | /* | ||
211 | * We need to find out the CPU boot mode long after boot, so we need to | 226 | * We need to find out the CPU boot mode long after boot, so we need to |
212 | * store it in a writable variable. | 227 | * store it in a writable variable. |
213 | * | 228 | * |
@@ -234,8 +249,9 @@ ENTRY(__boot_cpu_mode) | |||
234 | * cores are held until we're ready for them to initialise. | 249 | * cores are held until we're ready for them to initialise. |
235 | */ | 250 | */ |
236 | ENTRY(secondary_holding_pen) | 251 | ENTRY(secondary_holding_pen) |
237 | bl __calc_phys_offset // x24=phys offset | 252 | bl el2_setup // Drop to EL1, w20=cpu_boot_mode |
238 | bl el2_setup // Drop to EL1 | 253 | bl __calc_phys_offset // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET |
254 | bl set_cpu_boot_mode_flag | ||
239 | mrs x0, mpidr_el1 | 255 | mrs x0, mpidr_el1 |
240 | ldr x1, =MPIDR_HWID_BITMASK | 256 | ldr x1, =MPIDR_HWID_BITMASK |
241 | and x0, x0, x1 | 257 | and x0, x0, x1 |