diff options
author | Dave Martin <dave.martin@linaro.org> | 2012-02-10 21:07:07 -0500 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2012-09-19 03:32:50 -0400 |
commit | 424e5994e63326a42012f003f1174f3c363c7b62 (patch) | |
tree | d8ff950676dac0fc3b38d6801423f996f8b20214 /arch | |
parent | 80c59dafb1a9a86fa996e6e34d06b60567c925ca (diff) |
ARM: zImage/virt: hyp mode entry support for the zImage loader
The zImage loader needs to turn on the MMU in order to take
advantage of caching while decompressing the zImage. Running this
in hyp mode would require the LPAE pagetable format to be
supported; to avoid this complexity, this patch switches out of hyp
mode, and returns back to hyp mode just before booting the kernel.
This implementation assumes that the Hyp mode view of memory and the
PL1 view of memory are coherent, providing that the MMU and caches
are off in both, as required by the boot protocol. The zImage
decompression code must drain the write buffer on completion anyway, and
entry into Hyp mode should flush any prefetch buffer, avoiding hazards
associated with local write buffers and the pipeline.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/boot/compressed/.gitignore | 1 | ||||
-rw-r--r-- | arch/arm/boot/compressed/Makefile | 9 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head.S | 71 | ||||
-rw-r--r-- | arch/arm/kernel/hyp-stub.S | 18 |
4 files changed, 91 insertions, 8 deletions
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index d0d441c429ae..f79a08efe000 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore | |||
@@ -1,6 +1,7 @@ | |||
1 | ashldi3.S | 1 | ashldi3.S |
2 | font.c | 2 | font.c |
3 | lib1funcs.S | 3 | lib1funcs.S |
4 | hyp-stub.S | ||
4 | piggy.gzip | 5 | piggy.gzip |
5 | piggy.lzo | 6 | piggy.lzo |
6 | piggy.lzma | 7 | piggy.lzma |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index bb267562e7ed..a517153a13ea 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -30,6 +30,10 @@ FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c | |||
30 | OBJS += string.o | 30 | OBJS += string.o |
31 | CFLAGS_string.o := -Os | 31 | CFLAGS_string.o := -Os |
32 | 32 | ||
33 | ifeq ($(CONFIG_ARM_VIRT_EXT),y) | ||
34 | OBJS += hyp-stub.o | ||
35 | endif | ||
36 | |||
33 | # | 37 | # |
34 | # Architecture dependencies | 38 | # Architecture dependencies |
35 | # | 39 | # |
@@ -126,7 +130,7 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) | |||
126 | endif | 130 | endif |
127 | 131 | ||
128 | ccflags-y := -fpic -fno-builtin -I$(obj) | 132 | ccflags-y := -fpic -fno-builtin -I$(obj) |
129 | asflags-y := -Wa,-march=all | 133 | asflags-y := -Wa,-march=all -DZIMAGE |
130 | 134 | ||
131 | # Supply kernel BSS size to the decompressor via a linker symbol. | 135 | # Supply kernel BSS size to the decompressor via a linker symbol. |
132 | KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \ | 136 | KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \ |
@@ -198,3 +202,6 @@ $(obj)/font.c: $(FONTC) | |||
198 | 202 | ||
199 | $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG) | 203 | $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG) |
200 | @sed "$(SEDFLAGS)" < $< > $@ | 204 | @sed "$(SEDFLAGS)" < $< > $@ |
205 | |||
206 | $(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S | ||
207 | $(call cmd,shipped) | ||
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index b8c64b80bafc..0749a6184abf 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
12 | #include <asm/assembler.h> | ||
12 | 13 | ||
13 | /* | 14 | /* |
14 | * Debugging stuff | 15 | * Debugging stuff |
@@ -132,7 +133,12 @@ start: | |||
132 | .word start @ absolute load/run zImage address | 133 | .word start @ absolute load/run zImage address |
133 | .word _edata @ zImage end address | 134 | .word _edata @ zImage end address |
134 | THUMB( .thumb ) | 135 | THUMB( .thumb ) |
135 | 1: mov r7, r1 @ save architecture ID | 136 | 1: |
137 | mrs r9, cpsr | ||
138 | #ifdef CONFIG_ARM_VIRT_EXT | ||
139 | bl __hyp_stub_install @ get into SVC mode, reversibly | ||
140 | #endif | ||
141 | mov r7, r1 @ save architecture ID | ||
136 | mov r8, r2 @ save atags pointer | 142 | mov r8, r2 @ save atags pointer |
137 | 143 | ||
138 | #ifndef __ARM_ARCH_2__ | 144 | #ifndef __ARM_ARCH_2__ |
@@ -148,9 +154,9 @@ start: | |||
148 | ARM( swi 0x123456 ) @ angel_SWI_ARM | 154 | ARM( swi 0x123456 ) @ angel_SWI_ARM |
149 | THUMB( svc 0xab ) @ angel_SWI_THUMB | 155 | THUMB( svc 0xab ) @ angel_SWI_THUMB |
150 | not_angel: | 156 | not_angel: |
151 | mrs r2, cpsr @ turn off interrupts to | 157 | safe_svcmode_maskall r0 |
152 | orr r2, r2, #0xc0 @ prevent angel from running | 158 | msr spsr_cxsf, r9 @ Save the CPU boot mode in |
153 | msr cpsr_c, r2 | 159 | @ SPSR |
154 | #else | 160 | #else |
155 | teqp pc, #0x0c000003 @ turn off interrupts | 161 | teqp pc, #0x0c000003 @ turn off interrupts |
156 | #endif | 162 | #endif |
@@ -350,6 +356,20 @@ dtb_check_done: | |||
350 | adr r5, restart | 356 | adr r5, restart |
351 | bic r5, r5, #31 | 357 | bic r5, r5, #31 |
352 | 358 | ||
359 | /* Relocate the hyp vector base if necessary */ | ||
360 | #ifdef CONFIG_ARM_VIRT_EXT | ||
361 | mrs r0, spsr | ||
362 | and r0, r0, #MODE_MASK | ||
363 | cmp r0, #HYP_MODE | ||
364 | bne 1f | ||
365 | |||
366 | bl __hyp_get_vectors | ||
367 | sub r0, r0, r5 | ||
368 | add r0, r0, r10 | ||
369 | bl __hyp_set_vectors | ||
370 | 1: | ||
371 | #endif | ||
372 | |||
353 | sub r9, r6, r5 @ size to copy | 373 | sub r9, r6, r5 @ size to copy |
354 | add r9, r9, #31 @ rounded up to a multiple | 374 | add r9, r9, #31 @ rounded up to a multiple |
355 | bic r9, r9, #31 @ ... of 32 bytes | 375 | bic r9, r9, #31 @ ... of 32 bytes |
@@ -458,11 +478,29 @@ not_relocated: mov r0, #0 | |||
458 | bl decompress_kernel | 478 | bl decompress_kernel |
459 | bl cache_clean_flush | 479 | bl cache_clean_flush |
460 | bl cache_off | 480 | bl cache_off |
461 | mov r0, #0 @ must be zero | ||
462 | mov r1, r7 @ restore architecture number | 481 | mov r1, r7 @ restore architecture number |
463 | mov r2, r8 @ restore atags pointer | 482 | mov r2, r8 @ restore atags pointer |
464 | ARM( mov pc, r4 ) @ call kernel | 483 | |
465 | THUMB( bx r4 ) @ entry point is always ARM | 484 | #ifdef CONFIG_ARM_VIRT_EXT |
485 | mrs r0, spsr @ Get saved CPU boot mode | ||
486 | and r0, r0, #MODE_MASK | ||
487 | cmp r0, #HYP_MODE @ if not booted in HYP mode... | ||
488 | bne __enter_kernel @ boot kernel directly | ||
489 | |||
490 | adr r12, .L__hyp_reentry_vectors_offset | ||
491 | ldr r0, [r12] | ||
492 | add r0, r0, r12 | ||
493 | |||
494 | bl __hyp_set_vectors | ||
495 | __HVC(0) @ otherwise bounce to hyp mode | ||
496 | |||
497 | b . @ should never be reached | ||
498 | |||
499 | .align 2 | ||
500 | .L__hyp_reentry_vectors_offset: .long __hyp_reentry_vectors - . | ||
501 | #else | ||
502 | b __enter_kernel | ||
503 | #endif | ||
466 | 504 | ||
467 | .align 2 | 505 | .align 2 |
468 | .type LC0, #object | 506 | .type LC0, #object |
@@ -1191,6 +1229,25 @@ memdump: mov r12, r0 | |||
1191 | #endif | 1229 | #endif |
1192 | 1230 | ||
1193 | .ltorg | 1231 | .ltorg |
1232 | |||
1233 | #ifdef CONFIG_ARM_VIRT_EXT | ||
1234 | .align 5 | ||
1235 | __hyp_reentry_vectors: | ||
1236 | W(b) . @ reset | ||
1237 | W(b) . @ undef | ||
1238 | W(b) . @ svc | ||
1239 | W(b) . @ pabort | ||
1240 | W(b) . @ dabort | ||
1241 | W(b) __enter_kernel @ hyp | ||
1242 | W(b) . @ irq | ||
1243 | W(b) . @ fiq | ||
1244 | #endif /* CONFIG_ARM_VIRT_EXT */ | ||
1245 | |||
1246 | __enter_kernel: | ||
1247 | mov r0, #0 @ must be 0 | ||
1248 | ARM( mov pc, r4 ) @ call kernel | ||
1249 | THUMB( bx r4 ) @ entry point is always ARM | ||
1250 | |||
1194 | reloc_code_end: | 1251 | reloc_code_end: |
1195 | 1252 | ||
1196 | .align | 1253 | .align |
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index b03e9244e5ad..70609417deaf 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/assembler.h> | 21 | #include <asm/assembler.h> |
22 | #include <asm/virt.h> | 22 | #include <asm/virt.h> |
23 | 23 | ||
24 | #ifndef ZIMAGE | ||
24 | /* | 25 | /* |
25 | * For the kernel proper, we need to find out the CPU boot mode long after | 26 | * For the kernel proper, we need to find out the CPU boot mode long after |
26 | * boot, so we need to store it in a writable variable. | 27 | * boot, so we need to store it in a writable variable. |
@@ -59,6 +60,21 @@ ENTRY(__boot_cpu_mode) | |||
59 | strne r7, [r5, r6] @ record what happened and give up | 60 | strne r7, [r5, r6] @ record what happened and give up |
60 | .endm | 61 | .endm |
61 | 62 | ||
63 | #else /* ZIMAGE */ | ||
64 | |||
65 | .macro store_primary_cpu_mode reg1:req, reg2:req, reg3:req | ||
66 | .endm | ||
67 | |||
68 | /* | ||
69 | * The zImage loader only runs on one CPU, so we don't bother with mult-CPU | ||
70 | * consistency checking: | ||
71 | */ | ||
72 | .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3 | ||
73 | cmp \mode, \mode | ||
74 | .endm | ||
75 | |||
76 | #endif /* ZIMAGE */ | ||
77 | |||
62 | /* | 78 | /* |
63 | * Hypervisor stub installation functions. | 79 | * Hypervisor stub installation functions. |
64 | * | 80 | * |
@@ -174,9 +190,11 @@ ENTRY(__hyp_set_vectors) | |||
174 | bx lr | 190 | bx lr |
175 | ENDPROC(__hyp_set_vectors) | 191 | ENDPROC(__hyp_set_vectors) |
176 | 192 | ||
193 | #ifndef ZIMAGE | ||
177 | .align 2 | 194 | .align 2 |
178 | .L__boot_cpu_mode_offset: | 195 | .L__boot_cpu_mode_offset: |
179 | .long __boot_cpu_mode - . | 196 | .long __boot_cpu_mode - . |
197 | #endif | ||
180 | 198 | ||
181 | .align 5 | 199 | .align 5 |
182 | __hyp_stub_vectors: | 200 | __hyp_stub_vectors: |