aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2012-10-26 10:40:05 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2012-12-05 06:26:48 -0500
commitf35a92053b45cf8154db5558ede3ba5245c9dc7e (patch)
treefc4b8d9cfcd538251db7ee8a03286bef302d6ba0 /arch/arm64/kernel
parentdc637f1fdaa6f335271a0341fef3914b80ab929c (diff)
arm64: record boot mode when entering the kernel
To be able to signal the availability of EL2 to other parts of the kernel, record the boot mode. Once booted, two predicates indicate if HYP mode is available, and if not, whether this is due to a boot mode mismatch or not. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel')
-rw-r--r--arch/arm64/kernel/head.S25
1 files changed, 22 insertions, 3 deletions
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 90dec55b17a2..bc6d991f8c59 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -31,6 +31,7 @@
31#include <asm/pgtable-hwdef.h> 31#include <asm/pgtable-hwdef.h>
32#include <asm/pgtable.h> 32#include <asm/pgtable.h>
33#include <asm/page.h> 33#include <asm/page.h>
34#include <asm/virt.h>
34 35
35/* 36/*
36 * swapper_pg_dir is the virtual address of the initial page table. We place 37 * swapper_pg_dir is the virtual address of the initial page table. We place
@@ -115,13 +116,13 @@
115 116
116ENTRY(stext) 117ENTRY(stext)
117 mov x21, x0 // x21=FDT 118 mov x21, x0 // x21=FDT
119 bl __calc_phys_offset // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET
118 bl el2_setup // Drop to EL1 120 bl el2_setup // Drop to EL1
119 mrs x22, midr_el1 // x22=cpuid 121 mrs x22, midr_el1 // x22=cpuid
120 mov x0, x22 122 mov x0, x22
121 bl lookup_processor_type 123 bl lookup_processor_type
122 mov x23, x0 // x23=current cpu_table 124 mov x23, x0 // x23=current cpu_table
123 cbz x23, __error_p // invalid processor (x23=0)? 125 cbz x23, __error_p // invalid processor (x23=0)?
124 bl __calc_phys_offset // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET
125 bl __vet_fdt 126 bl __vet_fdt
126 bl __create_page_tables // x25=TTBR0, x26=TTBR1 127 bl __create_page_tables // x25=TTBR0, x26=TTBR1
127 /* 128 /*
@@ -147,11 +148,16 @@ ENTRY(el2_setup)
147 mrs x0, CurrentEL 148 mrs x0, CurrentEL
148 cmp x0, #PSR_MODE_EL2t 149 cmp x0, #PSR_MODE_EL2t
149 ccmp x0, #PSR_MODE_EL2h, #0x4, ne 150 ccmp x0, #PSR_MODE_EL2h, #0x4, ne
151 ldr x0, =__boot_cpu_mode // Compute __boot_cpu_mode
152 add x0, x0, x28
150 b.eq 1f 153 b.eq 1f
154 str wzr, [x0] // Remember we don't have EL2...
151 ret 155 ret
152 156
153 /* Hyp configuration. */ 157 /* Hyp configuration. */
1541: mov x0, #(1 << 31) // 64-bit EL1 1581: ldr w1, =BOOT_CPU_MODE_EL2
159 str w1, [x0, #4] // This CPU has EL2
160 mov x0, #(1 << 31) // 64-bit EL1
155 msr hcr_el2, x0 161 msr hcr_el2, x0
156 162
157 /* Generic timers. */ 163 /* Generic timers. */
@@ -187,6 +193,19 @@ ENTRY(el2_setup)
187 eret 193 eret
188ENDPROC(el2_setup) 194ENDPROC(el2_setup)
189 195
196/*
197 * We need to find out the CPU boot mode long after boot, so we need to
198 * store it in a writable variable.
199 *
200 * This is not in .bss, because we set it sufficiently early that the boot-time
201 * zeroing of .bss would clobber it.
202 */
203 .pushsection .data
204ENTRY(__boot_cpu_mode)
205 .long BOOT_CPU_MODE_EL2
206 .long 0
207 .popsection
208
190 .align 3 209 .align 3
1912: .quad . 2102: .quad .
192 .quad PAGE_OFFSET 211 .quad PAGE_OFFSET
@@ -202,6 +221,7 @@ ENDPROC(el2_setup)
202 * cores are held until we're ready for them to initialise. 221 * cores are held until we're ready for them to initialise.
203 */ 222 */
204ENTRY(secondary_holding_pen) 223ENTRY(secondary_holding_pen)
224 bl __calc_phys_offset // x24=phys offset
205 bl el2_setup // Drop to EL1 225 bl el2_setup // Drop to EL1
206 mrs x0, mpidr_el1 226 mrs x0, mpidr_el1
207 and x0, x0, #15 // CPU number 227 and x0, x0, #15 // CPU number
@@ -227,7 +247,6 @@ ENTRY(secondary_startup)
227 mov x23, x0 // x23=current cpu_table 247 mov x23, x0 // x23=current cpu_table
228 cbz x23, __error_p // invalid processor (x23=0)? 248 cbz x23, __error_p // invalid processor (x23=0)?
229 249
230 bl __calc_phys_offset // x24=phys offset
231 pgtbl x25, x26, x24 // x25=TTBR0, x26=TTBR1 250 pgtbl x25, x26, x24 // x25=TTBR0, x26=TTBR1
232 ldr x12, [x23, #CPU_INFO_SETUP] 251 ldr x12, [x23, #CPU_INFO_SETUP]
233 add x12, x12, x28 // __virt_to_phys 252 add x12, x12, x28 // __virt_to_phys