diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2012-10-26 10:40:05 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2012-12-05 06:26:48 -0500 |
commit | f35a92053b45cf8154db5558ede3ba5245c9dc7e (patch) | |
tree | fc4b8d9cfcd538251db7ee8a03286bef302d6ba0 /arch/arm64/kernel | |
parent | dc637f1fdaa6f335271a0341fef3914b80ab929c (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.S | 25 |
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 | ||
116 | ENTRY(stext) | 117 | ENTRY(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. */ |
154 | 1: mov x0, #(1 << 31) // 64-bit EL1 | 158 | 1: 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 |
188 | ENDPROC(el2_setup) | 194 | ENDPROC(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 | ||
204 | ENTRY(__boot_cpu_mode) | ||
205 | .long BOOT_CPU_MODE_EL2 | ||
206 | .long 0 | ||
207 | .popsection | ||
208 | |||
190 | .align 3 | 209 | .align 3 |
191 | 2: .quad . | 210 | 2: .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 | */ |
204 | ENTRY(secondary_holding_pen) | 223 | ENTRY(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 |