aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2012-02-10 21:07:07 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2012-09-19 03:32:50 -0400
commit424e5994e63326a42012f003f1174f3c363c7b62 (patch)
treed8ff950676dac0fc3b38d6801423f996f8b20214 /arch
parent80c59dafb1a9a86fa996e6e34d06b60567c925ca (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/.gitignore1
-rw-r--r--arch/arm/boot/compressed/Makefile9
-rw-r--r--arch/arm/boot/compressed/head.S71
-rw-r--r--arch/arm/kernel/hyp-stub.S18
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 @@
1ashldi3.S 1ashldi3.S
2font.c 2font.c
3lib1funcs.S 3lib1funcs.S
4hyp-stub.S
4piggy.gzip 5piggy.gzip
5piggy.lzo 6piggy.lzo
6piggy.lzma 7piggy.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
30OBJS += string.o 30OBJS += string.o
31CFLAGS_string.o := -Os 31CFLAGS_string.o := -Os
32 32
33ifeq ($(CONFIG_ARM_VIRT_EXT),y)
34OBJS += hyp-stub.o
35endif
36
33# 37#
34# Architecture dependencies 38# Architecture dependencies
35# 39#
@@ -126,7 +130,7 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
126endif 130endif
127 131
128ccflags-y := -fpic -fno-builtin -I$(obj) 132ccflags-y := -fpic -fno-builtin -I$(obj)
129asflags-y := -Wa,-march=all 133asflags-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.
132KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \ 136KBSS_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 )
1351: mov r7, r1 @ save architecture ID 1361:
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
150not_angel: 156not_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
3701:
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
1194reloc_code_end: 1251reloc_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
175ENDPROC(__hyp_set_vectors) 191ENDPROC(__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: