diff mbox

[04/10] ARM: zImage/virt: hyp mode entry support for the zImage loader

Message ID 1329329763-31508-5-git-send-email-dave.martin@linaro.org
State Not Applicable
Headers show

Commit Message

Dave Martin Feb. 15, 2012, 6:15 p.m. UTC
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.

Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
 arch/arm/boot/compressed/.gitignore |    1 +
 arch/arm/boot/compressed/Makefile   |    8 +++++
 arch/arm/boot/compressed/head.S     |   50 ++++++++++++++++++++++++++++++++---
 arch/arm/include/asm/assembler.h    |   15 ++++++++++
 arch/arm/kernel/head.S              |   15 ----------
 5 files changed, 70 insertions(+), 19 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
index e0936a1..8b05d09 100644
--- a/arch/arm/boot/compressed/.gitignore
+++ b/arch/arm/boot/compressed/.gitignore
@@ -1,5 +1,6 @@ 
 font.c
 lib1funcs.S
+hyp-stub.S
 piggy.gzip
 piggy.lzo
 piggy.lzma
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index cf0a64c..2a597d1 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -30,6 +30,11 @@  FONTC	= $(srctree)/drivers/video/console/font_acorn_8x8.c
 OBJS		+= string.o
 CFLAGS_string.o	:= -Os
 
+ifeq ($(CONFIG_ARM_VIRT),y)
+OBJS		+= hyp-stub.o
+AFLAGS_hyp-stub.o := -Wa,-march=armv7-a+virt
+endif
+
 #
 # Architecture dependencies
 #
@@ -189,3 +194,6 @@  $(obj)/font.c: $(FONTC)
 
 $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG)
 	@sed "$(SEDFLAGS)" < $< > $@
+
+$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
+	$(call cmd,shipped)
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index c5d6025..1f9b498 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -9,6 +9,7 @@ 
  * published by the Free Software Foundation.
  */
 #include <linux/linkage.h>
+#include <asm/assembler.h>
 
 /*
  * Debugging stuff
@@ -132,7 +133,13 @@  start:
 		.word	start			@ absolute load/run zImage address
 		.word	_edata			@ zImage end address
  THUMB(		.thumb			)
-1:		mov	r7, r1			@ save architecture ID
+1:
+#ifdef CONFIG_ARM_VIRT
+		bl	__hyp_stub_install	@ get into SVC mode, reversibly
+#endif
+		safe_svcmode_maskall r4
+
+		mov	r7, r1			@ save architecture ID
 		mov	r8, r2			@ save atags pointer
 
 #ifndef __ARM_ARCH_2__
@@ -458,11 +465,27 @@  not_relocated:	mov	r0, #0
 		bl	decompress_kernel
 		bl	cache_clean_flush
 		bl	cache_off
-		mov	r0, #0			@ must be zero
 		mov	r1, r7			@ restore architecture number
 		mov	r2, r8			@ restore atags pointer
- ARM(		mov	pc, r4	)		@ call kernel
- THUMB(		bx	r4	)		@ entry point is always ARM
+
+#ifdef CONFIG_ARM_VIRT
+		ldr	r0, =__boot_cpu_mode
+		and	r0, r0, #MODE_MASK
+		cmp	r0, #HYP_MODE		@ if not booted in HYP mode...
+		bne	__enter_kernel		@ boot kernel directly
+	
+		adr	r12, .L__hyp_reentry_vectors_offset
+		ldr	r0, [r12]
+		add	r0, r0, r12
+	
+		bl	__hyp_set_vectors
+		hvc	#0			@ otherwise bounce via HVC call
+
+		b	.			@ should never be reached
+
+		.align	2
+.L__hyp_reentry_vectors_offset:	.long	__hyp_set_vectors - .
+#endif
 
 		.align	2
 		.type	LC0, #object
@@ -1220,6 +1243,25 @@  memdump:	mov	r12, r0
 #endif
 
 		.ltorg
+
+#ifdef CONFIG_ARM_VIRT
+.align 5
+__hyp_reentry_vectors:
+		W(b)	.			@ reset
+		W(b)	.			@ undef
+		W(b)	.			@ svc
+		W(b)	.			@ pabort
+		W(b)	.			@ dabort
+						@ hyp trap is at __enter_kernel
+#endif /* CONFIG_ARM_VIRT */
+
+		@ Don't insert any code here unless you know what you're doing!
+
+__enter_kernel:					
+		mov	r0, #0			@ must be 0
+ ARM(		mov	pc, r4	)		@ call kernel
+ THUMB(		bx	r4	)		@ entry point is always ARM
+
 reloc_code_end:
 
 		.align
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index b6e65de..fab3ca1 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -233,6 +233,21 @@ 
 #endif
 
 /*
+ * Helper macro to enter SVC mode cleanly and mask interrupts.  reg is a
+ * scratch register available for the macro to overwrite.
+ */
+.macro safe_svcmode_maskall reg:req
+	mrs	\reg , cpsr
+	orr	\reg , \reg , #PSR_A_BIT | PSR_I_BIT | PSR_F_BIT
+	bic	\reg , \reg , #MODE_MASK
+	orr	\reg , \reg , #SVC_MODE
+	msr	spsr_cxsf, \reg
+	adr	\reg , BSYM(1f)
+	movs	pc, \reg
+1:
+.endm
+
+/*
  * STRT/LDRT access macros with ARM and Thumb-2 variants
  */
 #ifdef CONFIG_THUMB2_KERNEL
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index bafaf99..ab1a941 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -64,21 +64,6 @@ 
 #endif
 
 /*
- * Helper macro to enter SVC mode cleanly and mask interrupts.  reg is a
- * scratch register available for the macro to overwrite.
- */
-.macro safe_svcmode_maskall reg:req
-	mrs	\reg , cpsr
-	orr	\reg , \reg , #PSR_A_BIT | PSR_I_BIT | PSR_F_BIT
-	bic	\reg , \reg , #MODE_MASK
-	orr	\reg , \reg , #SVC_MODE
-	msr	spsr_cxsf, \reg
-	adr	\reg , BSYM(1f)
-	movs	pc, \reg
-1:
-.endm
-
-/*
  * Kernel startup entry point.
  * ---------------------------
  *