Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Aug 2015 14:49:12 +0000 (UTC)
From:      Zbigniew Bodek <zbb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r287127 - head/sys/arm/arm
Message-ID:  <201508251449.t7PEnCKm075698@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: zbb
Date: Tue Aug 25 14:49:11 2015
New Revision: 287127
URL: https://svnweb.freebsd.org/changeset/base/287127

Log:
  Leave hypervisor mode upon startup on ARMv7
  
  If ARMv7 boots in HYP mode, switch to SVC32.
  
  Reviewed by:   ian
  Submitted by:  Wojciech Macek <wma@semihalf.com>
                 Jakub Palider  <jpa@semihalf.com>
  Obtained from: Semihalf
  Sponsored by:  Annapurna Labs
  Differential Revision: https://reviews.freebsd.org/D1810

Modified:
  head/sys/arm/arm/locore-v6.S

Modified: head/sys/arm/arm/locore-v6.S
==============================================================================
--- head/sys/arm/arm/locore-v6.S	Tue Aug 25 14:39:40 2015	(r287126)
+++ head/sys/arm/arm/locore-v6.S	Tue Aug 25 14:49:11 2015	(r287127)
@@ -45,12 +45,47 @@ __FBSDID("$FreeBSD$");
 #define	PTE1_SIZE	L1_S_SIZE
 #endif
 
+#if __ARM_ARCH >= 7
+#if defined(__ARM_ARCH_7VE__) || defined(__clang__)
+/*
+ * HYP support is in bintuils >= 2.21 and gcc >= 4.9 defines __ARM_ARCH_7VE__
+ * when enabled. llvm >= 3.6 supports it too.
+ */
+.arch_extension virt
+#define	MSR_ELR_HYP(regnum)	msr	elr_hyp, lr
+#define	ERET	eret
+#else
+#define MSR_ELR_HYP(regnum) .word (0xe12ef300 | regnum)
+#define ERET .word 0xe160006e
+#endif
+#endif /* __ARM_ARCH >= 7 */
+
 /* A small statically-allocated stack used only during initarm() and AP startup. */
 #define	INIT_ARM_STACK_SIZE	2048
 
 	.text
 	.align	2
 
+#if __ARM_ARCH >= 7
+#define LEAVE_HYP							\
+       /* Leave HYP mode */						;\
+       mrs	r0, cpsr		   				;\
+       and	r0, r0, #(PSR_MODE)     /* Mode is in the low 5 bits of CPSR */	;\
+       teq	r0, #(PSR_HYP32_MODE)   /* Hyp Mode? */			;\
+       bne	1f							;\
+       /* Ensure that IRQ, FIQ and Aborts will be disabled after eret */;\
+       mrs	r0, spsr						;\
+       orr	r0, r0, #(PSR_I | PSR_F | PSR_A)			;\
+       msr	spsr, r0						;\
+       /* Exit hypervisor mode */					;\
+       adr	lr, 1f							;\
+       MSR_ELR_HYP(14)							;\
+       ERET								;\
+1:
+#else
+#define LEAVE_HYP
+#endif /* __ARM_ARCH >= 7 */
+
 /*
  * On entry for FreeBSD boot ABI:
  *	r0 - metadata pointer or 0 (boothowto on AT91's boot2)
@@ -76,6 +111,8 @@ ASENTRY_NP(_start)
 	mov	r10, r2		/* Save meta data */
 	mov	r11, r3		/* Future expansion */
 
+	LEAVE_HYP
+
 	/*
 	 * Check whether data cache is enabled.  If it is, then we know
 	 * current tags are valid (not power-on garbage values) and there
@@ -401,6 +438,8 @@ ASENTRY_NP(mpentry)
 	/* Make sure interrupts are disabled. */
 	cpsid	ifa
 
+	LEAVE_HYP
+
 	/* Setup core, disable all caches. */
 	mrc	CP15_SCTLR(r0)
 	bic	r0, #CPU_CONTROL_MMU_ENABLE



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508251449.t7PEnCKm075698>