socsvn commit: r287815 - soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm

mihai at FreeBSD.org mihai at FreeBSD.org
Wed Jul 1 15:22:04 UTC 2015


Author: mihai
Date: Wed Jul  1 15:22:01 2015
New Revision: 287815
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=287815

Log:
  sys: arm: vmm: call the low-level primitives to initialize, run and clean a virtual machine

Added:
  soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp_helpers.h
Modified:
  soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.c
  soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.h
  soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.S
  soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.h

Modified: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.c
==============================================================================
--- soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.c	Wed Jul  1 15:15:58 2015	(r287814)
+++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.c	Wed Jul  1 15:22:01 2015	(r287815)
@@ -7,15 +7,23 @@
 #include <sys/pcpu.h>
 #include <sys/proc.h>
 #include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
+#include <machine/cpu-v6.h>
 #include <machine/vmm.h>
 #include <machine/vmm_dev.h>
 
 #include "mmu.h"
 #include "arm.h"
+#include "hyp.h"
+
+#define	HANDLED		1
+#define	UNHANDLED	0
 
 MALLOC_DEFINE(M_HYP, "ARM VMM HYP", "ARM VMM HYP");
 
@@ -27,12 +35,43 @@
 lpae_pd_entry_t *hyp_l1pd;
 char *stack;
 
+static uint64_t vmid_generation = 1;
+static struct mtx vmid_generation_mtx;
+
+static void set_vttbr(struct hyp* hyp) {
+	if (hyp->vmid_generation &&
+	    ((hyp->vmid_generation & ~VMID_GENERATION_MASK) != 
+	    (atomic_load_64(&vmid_generation) & ~VMID_GENERATION_MASK)))
+		goto out;
+
+	mtx_lock(&vmid_generation_mtx);
+
+	/* Another VCPU has change the VMID already */
+	if (hyp->vmid_generation &&
+	    ((hyp->vmid_generation & ~VMID_GENERATION_MASK) !=
+	    (vmid_generation & ~VMID_GENERATION_MASK))) {
+		mtx_unlock(&vmid_generation_mtx);
+		goto out;
+	}
+
+	vmid_generation++;
+	if (!(vmid_generation & VMID_GENERATION_MASK))
+		vmid_generation++;
+
+	hyp->vmid_generation = vmid_generation;
+	mtx_unlock(&vmid_generation_mtx);
+out:
+	hyp->vttbr = BUILD_VTTBR((hyp->vmid_generation & VMID_GENERATION_MASK), hyp->l1pd_phys);
+}
+
 static int
 arm_init(int ipinum)
 {
 	char *stack_top;
 	lpae_vm_paddr_t phys_hyp_l1pd;
 
+	mtx_init(&vmid_generation_mtx, "vmid_generation_mtx", NULL, MTX_DEF);
+
 	stack = malloc(PAGE_SIZE, M_HYP, M_WAITOK | M_ZERO);
 	stack_top = stack + PAGE_SIZE;
 
@@ -100,20 +139,18 @@
 arm_cleanup(void)
 {
 	printf("%s before vmm_call_hyp\n", __func__);
-
 	vmm_call_hyp((void *) vtophys(vmm_stub_install), (void *)vtophys(&hypervisor_stub_vect[0]));
 	printf("%s after vmm_call_hyp\n", __func__);
 
 	printf("%s before freestack\n", __func__);
-
 	free(stack, M_HYP);
-	printf("%s before lpae_vmcleanup\n", __func__);
 
+	printf("%s before lpae_vmcleanup\n", __func__);
 	lpae_vmcleanup(NULL);
-	printf("%s before vmm_call_hyp\n", __func__);
 
 	free(hyp_l1pd, M_HYP);
 
+	mtx_destroy(&vmid_generation_mtx);
 
 	return 0;
 }
@@ -128,19 +165,79 @@
 static void *
 arm_vminit(struct vm *vm, pmap_t pmap)
 {
-	return NULL;
+	struct hyp *hyp;
+	struct hypctx *hypctx;
+	int i;
+
+	hyp = malloc(sizeof(struct hyp), M_HYP, M_WAITOK | M_ZERO);
+	if ((uintptr_t)hyp & PAGE_MASK) {
+		panic("malloc of struct hyp not aligned on %d byte boundary",
+		      PAGE_SIZE);
+	}
+	hyp->vm = vm;
+
+	hyp->l1pd_phys = (lpae_pd_entry_t) vtophys(&hyp->l1pd[0]);
+	set_vttbr(hyp);
+	
+	for (i = 0; i < VM_MAXCPU; i++) {
+		hypctx = &hyp->ctx[i];
+		hypctx->vcpu = i;
+		hypctx->hyp = hyp;
+		hypctx->hcr = HCR_GUEST_MASK;
+		hypctx->midr = cpu_ident();
+		hypctx->mpidr = (cp15_mpidr_get() & MPIDR_SMP_MASK) |
+		    MPIDR_AFF1_LEVEL(i) |
+		    MPIDR_AFF0_LEVEL(i);
+	}
+
+	lpae_vmmmap_set(NULL,
+	    (lpae_vm_vaddr_t)hyp,
+	    (lpae_vm_paddr_t)vtophys(hyp),
+	    sizeof(struct hyp),
+	    VM_PROT_READ | VM_PROT_WRITE);
+
+	return (hyp);
 }
 
 static int
 arm_vmrun(void *arg, int vcpu, register_t rip, pmap_t pmap, 
 	void *rend_cookie, void *suspended_cookie)
 {
+	int rc;
+	int handled;
+	struct hyp *hyp;
+	struct hypctx *hypctx;
+	struct vm *vm;
+
+	hyp = arg;
+	hypctx = &hyp->ctx[vcpu];
+	vm = hyp->vm;
+
+	do {
+		handled = UNHANDLED;
+
+		rc = vmm_call_hyp((void *)hyp_enter_guest, hypctx);
+
+		handled = HANDLED;
+
+	} while(handled);
 	return 0;
 }
 
 static void
 arm_vmcleanup(void *arg)
 {
+	struct hyp *hyp = arg;
+
+	/* Unmap from HYP-mode the hyp tructure */
+	lpae_vmmmap_set(NULL,
+	    (lpae_vm_vaddr_t)hyp,
+	    (lpae_vm_paddr_t)vtophys(hyp),
+	    sizeof(struct hyp),
+	    VM_PROT_NONE);
+
+	lpae_vmcleanup(&(hyp->l1pd[0]));
+	free(hyp, M_HYP);
 }
 
 static int

Modified: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.h
==============================================================================
--- soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.h	Wed Jul  1 15:15:58 2015	(r287814)
+++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.h	Wed Jul  1 15:22:01 2015	(r287815)
@@ -2,15 +2,16 @@
 #include <machine/reg.h>
 
 struct hypctx {
+	uint32_t	vcpu;
 	struct hyp*	hyp;
 
-	struct reg	regs;
-
 	uint32_t	hcr;
 
 	uint32_t	midr;
 	uint32_t	mpidr;
 
+	struct reg	regs;
+
 	uint32_t	sp_und;
 	uint32_t	lr_und;
 	uint32_t	spsr_und;
@@ -66,14 +67,27 @@
 struct hyp {
 	lpae_pd_entry_t l1pd[2 * LPAE_L1_ENTRIES];
 	lpae_pd_entry_t	vttbr;
-	struct hypctx	ctx[VM_MAXCPU];
+	uint64_t vmid_generation;
 	struct vm	*vm;
-};
+	lpae_pd_entry_t l1pd_phys;
+	struct hypctx	ctx[VM_MAXCPU];
+	};
 CTASSERT((offsetof(struct hyp, l1pd) & PAGE_MASK) == 0);
 
 uint64_t vmm_call_hyp(void *hyp_func_addr, ...);
 
-void vmm_stub_install(void *hypervisor_stub_vect);
+extern void vmm_stub_install(void *hypervisor_stub_vect);
+extern int hyp_enter_guest(struct hypctx *hypctx);
 
 #define LOW(x)	(x & 0xFFFFFFFF)
 #define HIGH(x)	LOW(x >> 32)
+
+#define VMID_GENERATION_MASK ((1UL<<8) - 1)
+#define BUILD_VTTBR(VMID, PTADDR) ((VMID << 48) | PTADDR);
+
+#define MPIDR_SMP_MASK (0x3 << 30)
+#define MPIDR_AFF1_LEVEL(x) ((x >> 2) << 8)
+#define MPIDR_AFF0_LEVEL(x) ((x & 0x3) << 0)
+
+
+

Modified: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.S
==============================================================================
--- soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.S	Wed Jul  1 15:15:58 2015	(r287814)
+++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.S	Wed Jul  1 15:22:01 2015	(r287815)
@@ -6,8 +6,9 @@
 #include <machine/sysreg.h>
 #include <machine/cpuconf.h>
 
-#include "hyp_assym.h"
 #include "hyp.h"
+#include "hyp_assym.h"
+#include "hyp_helpers.h"
 
 .text
 	.globl	hyp_code_start

Modified: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.h
==============================================================================
--- soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.h	Wed Jul  1 15:15:58 2015	(r287814)
+++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.h	Wed Jul  1 15:22:01 2015	(r287815)
@@ -109,7 +109,7 @@
  */
 #define HCR_GUEST_MASK (HCR_TSW | HCR_TAC | HCR_TIDCP | \
     HCR_TSC | HCR_TWE | HCR_TWI | HCR_BSU_IS | HCR_FB | \
-    HCR_AMO | HCR_IMO | HCR_FMO | HCR_SWIO | HCR_VM
+    HCR_AMO | HCR_IMO | HCR_FMO | HCR_SWIO | HCR_VM)
 
 /* Hyp Coprocessor Trap Register */
 #define HCPTR_TCP(x)	(1 << x)
@@ -148,258 +148,5 @@
 
 #define	HYPCTX_REGS_R(x)	(HYPCTX_REGS + x * 4)
 
-/* Banked registers */
-#define SAVE_GUEST_BANKED_REG(reg)		\
-	mrs	r2, reg;			\
-	str	r2, [r0, #HYPCTX_##reg]
-#define SAVE_GUEST_BANKED_MODE(mode)		\
-	SAVE_GUEST_BANKED_REG(SP_##mode);	\
-	SAVE_GUEST_BANKED_REG(LR_##mode);	\
-	SAVE_GUEST_BANKED_REG(SPSR_##mode)
-
-#define RESTORE_GUEST_BANKED_REG(reg)		\
-	ldr	r2, [r0, #HYPCTX_##reg];	\
-	msr	reg, r2
-#define RESTORE_GUEST_BANKED_MODE(mode)		\
-	RESTORE_GUEST_BANKED_REG(SP_##mode);	\
-	RESTORE_GUEST_BANKED_REG(LR_##mode);	\
-	RESTORE_GUEST_BANKED_REG(SPSR_##mode)
-
-#define	save_guest_regs						\
-	/* r0 - address of the hypctx */			\
-	add	r2, r0, #HYPCTX_REGS_R(3);			\
-	stm	r2, {r3-r12};					\
-	pop	{r3-r5};	@ Get r0-r2 from the stack	\
-	add	r2, r0, #HYPCTX_REGS_R(0);			\
-	stm	r2, {r3-r5};					\
-								\
-	str	lr, [r0, #HYPCTX_REGS_LR];			\
-	mrs	r2, SP_usr;					\
-	str	r2, [r0, #HYPCTX_REGS_SP];			\
-								\
-	mrs	r2, ELR_hyp;					\
-	str	r2, [r0, #HYPCTX_REGS_PC];			\
-	mrs	r2, spsr;					\
-	str	r2, [r0, #HYPCTX_REGS_CPSR];			\
-								\
-	SAVE_GUEST_BANKED_MODE(svc);				\
-	SAVE_GUEST_BANKED_MODE(abt);				\
-	SAVE_GUEST_BANKED_MODE(und);				\
-	SAVE_GUEST_BANKED_MODE(irq);				\
-	SAVE_GUEST_BANKED_MODE(fiq);				\
-	SAVE_GUEST_BANKED_REG(r8_fiq);				\
-	SAVE_GUEST_BANKED_REG(r9_fiq);				\
-	SAVE_GUEST_BANKED_REG(r10_fiq);				\
-	SAVE_GUEST_BANKED_REG(r11_fiq);				\
-	SAVE_GUEST_BANKED_REG(r12_fiq)
-
-#define	restore_guest_regs					\
-	/* r0 - address of the hypctx */			\
-	RESTORE_GUEST_BANKED_MODE(svc);				\
-	RESTORE_GUEST_BANKED_MODE(abt);				\
-	RESTORE_GUEST_BANKED_MODE(und);				\
-	RESTORE_GUEST_BANKED_MODE(irq);				\
-	RESTORE_GUEST_BANKED_MODE(fiq);				\
-	RESTORE_GUEST_BANKED_REG(r8_fiq);			\
-	RESTORE_GUEST_BANKED_REG(r9_fiq);			\
-	RESTORE_GUEST_BANKED_REG(r10_fiq);			\
-	RESTORE_GUEST_BANKED_REG(r11_fiq);			\
-	RESTORE_GUEST_BANKED_REG(r12_fiq);			\
-								\
-	ldr	r2, [r0, #HYPCTX_REGS_PC];			\
-	msr	ELR_hyp, r2;					\
-	ldr	r2, [r0, #HYPCTX_REGS_CPSR];			\
-	msr	SPSR_cxsf, r2;					\
-								\
-	ldr	lr, [r0, #HYPCTX_REGS_LR];			\
-	ldr	r2, [r0, #HYPCTX_REGS_SP];			\
-	msr	SP_usr, r2;					\
-								\
-	add	r2, r0, #HYPCTX_REGS_R(0);			\
-	ldm	r2, {r0-r12}
-
-
-#define SAVE_HOST_BANKED_REG(reg)		\
-	mrs	r2, reg;			\
-	push	{r2}
-#define SAVE_HOST_BANKED_MODE(mode)		\
-	SAVE_HOST_BANKED_REG(SP_##mode);	\
-	SAVE_HOST_BANKED_REG(LR_##mode);	\
-	SAVE_HOST_BANKED_REG(SPSR_##mode)
-
-#define RESTORE_HOST_BANKED_REG(reg)		\
-	pop	{r2};				\
-	msr	reg, r2
-#define RESTORE_HOST_BANKED_MODE(mode)		\
-	RESTORE_HOST_BANKED_REG(SPSR_##mode);	\
-	RESTORE_HOST_BANKED_REG(LR_##mode);	\
-	RESTORE_HOST_BANKED_REG(SP_##mode)
-
-#define	save_host_regs						\
-	/* SPSR was saved when entered HYP mode */		\
-	mrs	r2, ELR_hyp;					\
-	push	{r2};						\
-								\
-	push	{r4-r12};					\
-	mrs	r2, SP_usr;					\
-	push	{r2};						\
-	push	{lr};						\
-								\
-	SAVE_HOST_BANKED_MODE(svc);				\
-	SAVE_HOST_BANKED_MODE(abt);				\
-	SAVE_HOST_BANKED_MODE(und);				\
-	SAVE_HOST_BANKED_MODE(irq);				\
-	SAVE_HOST_BANKED_MODE(fiq);				\
-	SAVE_HOST_BANKED_REG(r8_fiq);				\
-	SAVE_HOST_BANKED_REG(r9_fiq);				\
-	SAVE_HOST_BANKED_REG(r10_fiq);				\
-	SAVE_HOST_BANKED_REG(r11_fiq);				\
-	SAVE_HOST_BANKED_REG(r12_fiq)
-
-#define	restore_host_regs					\
-	RESTORE_HOST_BANKED_REG(r12_fiq);			\
-	RESTORE_HOST_BANKED_REG(r11_fiq);			\
-	RESTORE_HOST_BANKED_REG(r10_fiq);			\
-	RESTORE_HOST_BANKED_REG(r9_fiq);			\
-	RESTORE_HOST_BANKED_REG(r8_fiq);			\
-	RESTORE_HOST_BANKED_MODE(fiq);				\
-	RESTORE_HOST_BANKED_MODE(irq);				\
-	RESTORE_HOST_BANKED_MODE(und);				\
-	RESTORE_HOST_BANKED_MODE(abt);				\
-	RESTORE_HOST_BANKED_MODE(svc);				\
-								\
-	pop	{lr};						\
-	pop	{r2};						\
-	msr	SP_usr, r2;					\
-	pop	{r4-r12};					\
-								\
-	pop	{r2};						\
-	msr	ELR_hyp, r2
-
-#define	load_cp15_regs_batch1					\
-	mrc	p15, 0, r2, c1, c0, 0;		@ SCTLR		\
-	mrc	p15, 0, r3, c1, c0, 2;		@ CPACR		\
-	mrc	p15, 0, r4, c2, c0, 2;		@ TTBCR		\
-	mrc	p15, 0, r5, c3, c0, 0;		@ DACR		\
-	mrrc	p15, 0, r6, r7, c2;		@ TTBR 0	\
-	mrrc	p15, 1, r8, r9, c2;		@ TTBR 1	\
-	mrc	p15, 0, r10, c10, c2, 0;	@ PRRR		\
-	mrc	p15, 0, r11, c10, c2, 1;	@ NMRR		\
-	mrc	p15, 2, r12, c0, c0, 0		@ CSSELR
-
-#define	load_cp15_regs_batch2					\
-	mrc	p15, 0, r2, c13, c0, 1;		@ CID		\
-	mrc	p15, 0, r3, c13, c0, 2;		@ TID_URW	\
-	mrc	p15, 0, r4, c13, c0, 3;		@ TID_URO	\
-	mrc	p15, 0, r5, c13, c0, 4;		@ TID_PRIV	\
-	mrc	p15, 0, r6, c5, c0, 0;		@ DFSR		\
-	mrc	p15, 0, r7, c5, c0, 1;		@ IFSR		\
-	mrc	p15, 0, r8, c5, c1, 0;		@ ADFSR		\
-	mrc	p15, 0, r9, c5, c1, 1;		@ AIFSR		\
-	mrc	p15, 0, r10, c6, c0, 0;		@ DFAR		\
-	mrc	p15, 0, r11, c6, c0, 2;		@ IFAR		\
-	mrc	p15, 0, r12, c12, c0, 0		@ VBAR
-
-#define	load_cp15_regs_batch3					\
-	mrc	p15, 0, r2, c14, c1, 0;		@ CNTKCTL	\
-	mrrc	p15, 0, r3, r4, c7;		@ PAR		\
-	mrc	p15, 0, r5, c10, c3, 0;		@ AMAIR0	\
-	mrc	p15, 0, r6, c10, c3, 1		@ AMAIR1
-
-#define	store_cp15_regs_batch1					\
-	mcr	p15, 0, r2, c1, c0, 0;		@ SCTLR		\
-	mcr	p15, 0, r3, c1, c0, 2;		@ CPACR		\
-	mcr	p15, 0, r4, c2, c0, 2;		@ TTBCR		\
-	mcr	p15, 0, r5, c3, c0, 0;		@ DACR		\
-	mcrr	p15, 0, r6, r7, c2;		@ TTBR 0	\
-	mcrr	p15, 1, r8, r9, c2;		@ TTBR 1	\
-	mcr	p15, 0, r10, c10, c2, 0;	@ PRRR		\
-	mcr	p15, 0, r11, c10, c2, 1;	@ NMRR		\
-	mcr	p15, 2, r12, c0, c0, 0		@ CSSELR
-
-#define	store_cp15_regs_batch2					\
-	mcr	p15, 0, r2, c13, c0, 1;		@ CID		\
-	mcr	p15, 0, r3, c13, c0, 2;		@ TID_URW	\
-	mcr	p15, 0, r4, c13, c0, 3;		@ TID_URO	\
-	mcr	p15, 0, r5, c13, c0, 4;		@ TID_PRIV	\
-	mcr	p15, 0, r6, c5, c0, 0;		@ DFSR		\
-	mcr	p15, 0, r7, c5, c0, 1;		@ IFSR		\
-	mcr	p15, 0, r8, c5, c1, 0;		@ ADFSR		\
-	mcr	p15, 0, r9, c5, c1, 1;		@ AIFSR		\
-	mcr	p15, 0, r10, c6, c0, 0;		@ DFAR		\
-	mcr	p15, 0, r11, c6, c0, 2;		@ IFAR		\
-	mcr	p15, 0, r12, c12, c0, 0		@ VBAR
-
-#define	store_cp15_regs_batch3					\
-	mcr	p15, 0, r2, c14, c1, 0;		@ CNTKCTL	\
-	mcrr	p15, 0, r3, r4, c7;		@ PAR		\
-	mcr	p15, 0, r5, c10, c3, 0;		@ AMAIR0	\
-	mcr	p15, 0, r6, c10, c3, 1		@ AMAIR1
-
-#define	store_guest_cp15_regs_batch1				\
-	str	r2, [r0, #HYPCTX_CP15_SCTLR];			\
-	str	r3, [r0, #HYPCTX_CP15_CPACR];			\
-	str	r4, [r0, #HYPCTX_CP15_TTBCR];			\
-	str	r5, [r0, #HYPCTX_CP15_DACR];			\
-	add	r2, r0, #HYPCTX_CP15_TTBR0;			\
-	strd	r6, r7, [r2];					\
-	add	r2, r0, #HYPCTX_CP15_TTBR1;			\
-	strd	r8, r9, [r2];					\
-	str	r10, [r0, #HYPCTX_CP15_PRRR];			\
-	str	r11, [r0, #HYPCTX_CP15_NMRR];			\
-	str	r12, [r0, #HYPCTX_CP15_CSSELR]
-
-#define	store_guest_cp15_regs_batch2				\
-	str	r2, [r0, #HYPCTX_CP15_CID];			\
-	str	r3, [r0, #HYPCTX_CP15_TID_URW];			\
-	str	r4, [r0, #HYPCTX_CP15_TID_URO];			\
-	str	r5, [r0, #HYPCTX_CP15_TID_PRIV];		\
-	str	r6, [r0, #HYPCTX_CP15_DFSR];			\
-	str	r7, [r0, #HYPCTX_CP15_IFSR];			\
-	str	r8, [r0, #HYPCTX_CP15_ADFSR];			\
-	str	r9, [r0, #HYPCTX_CP15_AIFSR];			\
-	str	r10, [r0, #HYPCTX_CP15_DFAR];			\
-	str	r11, [r0, #HYPCTX_CP15_IFAR];			\
-	str	r12, [r0, #HYPCTX_CP15_VBAR]
-
-#define	store_guest_cp15_regs_batch3				\
-	str	r2, [r0, #HYPCTX_CP15_CNTKCTL];			\
-	add	r2, r0, #HYPCTX_CP15_PAR;			\
-	strd	r4, r5, [r2];					\
-	str	r3, [r0, #HYPCTX_CP15_AMAIR0];			\
-	str	r6, [r0, #HYPCTX_CP15_AMAIR1]
-
-#define	load_guest_cp15_regs_batch1				\
-	ldr	r2, [r0, #HYPCTX_CP15_SCTLR];			\
-	ldr	r3, [r0, #HYPCTX_CP15_CPACR];			\
-	ldr	r4, [r0, #HYPCTX_CP15_TTBCR];			\
-	ldr	r5, [r0, #HYPCTX_CP15_DACR];			\
-	add	r2, r0, #HYPCTX_CP15_TTBR0;			\
-	ldrd	r6, r7, [r2];					\
-	add	r2, r0, #HYPCTX_CP15_TTBR1;			\
-	ldrd	r8, r9, [r2];					\
-	ldr	r10, [r0, #HYPCTX_CP15_PRRR];			\
-	ldr	r11, [r0, #HYPCTX_CP15_NMRR];			\
-	ldr	r12, [r0, #HYPCTX_CP15_CSSELR]
-
-#define	load_guest_cp15_regs_batch2				\
-	ldr	r2, [r0, #HYPCTX_CP15_CID];			\
-	ldr	r3, [r0, #HYPCTX_CP15_TID_URW];			\
-	ldr	r4, [r0, #HYPCTX_CP15_TID_URO];			\
-	ldr	r5, [r0, #HYPCTX_CP15_TID_PRIV];		\
-	ldr	r6, [r0, #HYPCTX_CP15_DFSR];			\
-	ldr	r7, [r0, #HYPCTX_CP15_IFSR];			\
-	ldr	r8, [r0, #HYPCTX_CP15_ADFSR];			\
-	ldr	r9, [r0, #HYPCTX_CP15_AIFSR];			\
-	ldr	r10, [r0, #HYPCTX_CP15_DFAR];			\
-	ldr	r11, [r0, #HYPCTX_CP15_IFAR];			\
-	ldr	r12, [r0, #HYPCTX_CP15_VBAR]
-
-#define	load_guest_cp15_regs_batch3				\
-	ldr	r2, [r0, #HYPCTX_CP15_CNTKCTL];			\
-	add	r2, r0, #HYPCTX_CP15_PAR;			\
-	ldrd	r4, r5, [r2];					\
-	ldr	r3, [r0, #HYPCTX_CP15_AMAIR0];			\
-	ldr	r6, [r0, #HYPCTX_CP15_AMAIR1]
-
 #endif
+

Added: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp_helpers.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp_helpers.h	Wed Jul  1 15:22:01 2015	(r287815)
@@ -0,0 +1,259 @@
+#ifndef _VMM_HYP_HELPERS_H_
+#define	_VMM_HYP_HELPERS_H_
+
+
+/* Banked registers */
+#define SAVE_GUEST_BANKED_REG(reg)		\
+	mrs	r2, reg;			\
+	str	r2, [r0, #HYPCTX_##reg]
+#define SAVE_GUEST_BANKED_MODE(mode)		\
+	SAVE_GUEST_BANKED_REG(SP_##mode);	\
+	SAVE_GUEST_BANKED_REG(LR_##mode);	\
+	SAVE_GUEST_BANKED_REG(SPSR_##mode)
+
+#define RESTORE_GUEST_BANKED_REG(reg)		\
+	ldr	r2, [r0, #HYPCTX_##reg];	\
+	msr	reg, r2
+#define RESTORE_GUEST_BANKED_MODE(mode)		\
+	RESTORE_GUEST_BANKED_REG(SP_##mode);	\
+	RESTORE_GUEST_BANKED_REG(LR_##mode);	\
+	RESTORE_GUEST_BANKED_REG(SPSR_##mode)
+
+#define	save_guest_regs						\
+	/* r0 - address of the hypctx */			\
+	add	r2, r0, #HYPCTX_REGS_R(3);			\
+	stm	r2, {r3-r12};					\
+	pop	{r3-r5};	@ Get r0-r2 from the stack	\
+	add	r2, r0, #HYPCTX_REGS_R(0);			\
+	stm	r2, {r3-r5};					\
+								\
+	str	lr, [r0, #HYPCTX_REGS_LR];			\
+	mrs	r2, SP_usr;					\
+	str	r2, [r0, #HYPCTX_REGS_SP];			\
+								\
+	mrs	r2, ELR_hyp;					\
+	str	r2, [r0, #HYPCTX_REGS_PC];			\
+	mrs	r2, spsr;					\
+	str	r2, [r0, #HYPCTX_REGS_CPSR];			\
+								\
+	SAVE_GUEST_BANKED_MODE(svc);				\
+	SAVE_GUEST_BANKED_MODE(abt);				\
+	SAVE_GUEST_BANKED_MODE(und);				\
+	SAVE_GUEST_BANKED_MODE(irq);				\
+	SAVE_GUEST_BANKED_MODE(fiq);				\
+	SAVE_GUEST_BANKED_REG(r8_fiq);				\
+	SAVE_GUEST_BANKED_REG(r9_fiq);				\
+	SAVE_GUEST_BANKED_REG(r10_fiq);				\
+	SAVE_GUEST_BANKED_REG(r11_fiq);				\
+	SAVE_GUEST_BANKED_REG(r12_fiq)
+
+#define	restore_guest_regs					\
+	/* r0 - address of the hypctx */			\
+	RESTORE_GUEST_BANKED_MODE(svc);				\
+	RESTORE_GUEST_BANKED_MODE(abt);				\
+	RESTORE_GUEST_BANKED_MODE(und);				\
+	RESTORE_GUEST_BANKED_MODE(irq);				\
+	RESTORE_GUEST_BANKED_MODE(fiq);				\
+	RESTORE_GUEST_BANKED_REG(r8_fiq);			\
+	RESTORE_GUEST_BANKED_REG(r9_fiq);			\
+	RESTORE_GUEST_BANKED_REG(r10_fiq);			\
+	RESTORE_GUEST_BANKED_REG(r11_fiq);			\
+	RESTORE_GUEST_BANKED_REG(r12_fiq);			\
+								\
+	ldr	r2, [r0, #HYPCTX_REGS_PC];			\
+	msr	ELR_hyp, r2;					\
+	ldr	r2, [r0, #HYPCTX_REGS_CPSR];			\
+	msr	SPSR_cxsf, r2;					\
+								\
+	ldr	lr, [r0, #HYPCTX_REGS_LR];			\
+	ldr	r2, [r0, #HYPCTX_REGS_SP];			\
+	msr	SP_usr, r2;					\
+								\
+	add	r2, r0, #HYPCTX_REGS_R(0);			\
+	ldm	r2, {r0-r12}
+
+
+#define SAVE_HOST_BANKED_REG(reg)		\
+	mrs	r2, reg;			\
+	push	{r2}
+#define SAVE_HOST_BANKED_MODE(mode)		\
+	SAVE_HOST_BANKED_REG(SP_##mode);	\
+	SAVE_HOST_BANKED_REG(LR_##mode);	\
+	SAVE_HOST_BANKED_REG(SPSR_##mode)
+
+#define RESTORE_HOST_BANKED_REG(reg)		\
+	pop	{r2};				\
+	msr	reg, r2
+#define RESTORE_HOST_BANKED_MODE(mode)		\
+	RESTORE_HOST_BANKED_REG(SPSR_##mode);	\
+	RESTORE_HOST_BANKED_REG(LR_##mode);	\
+	RESTORE_HOST_BANKED_REG(SP_##mode)
+
+#define	save_host_regs						\
+	/* SPSR was saved when entered HYP mode */		\
+	mrs	r2, ELR_hyp;					\
+	push	{r2};						\
+								\
+	push	{r4-r12};					\
+	mrs	r2, SP_usr;					\
+	push	{r2};						\
+	push	{lr};						\
+								\
+	SAVE_HOST_BANKED_MODE(svc);				\
+	SAVE_HOST_BANKED_MODE(abt);				\
+	SAVE_HOST_BANKED_MODE(und);				\
+	SAVE_HOST_BANKED_MODE(irq);				\
+	SAVE_HOST_BANKED_MODE(fiq);				\
+	SAVE_HOST_BANKED_REG(r8_fiq);				\
+	SAVE_HOST_BANKED_REG(r9_fiq);				\
+	SAVE_HOST_BANKED_REG(r10_fiq);				\
+	SAVE_HOST_BANKED_REG(r11_fiq);				\
+	SAVE_HOST_BANKED_REG(r12_fiq)
+
+#define	restore_host_regs					\
+	RESTORE_HOST_BANKED_REG(r12_fiq);			\
+	RESTORE_HOST_BANKED_REG(r11_fiq);			\
+	RESTORE_HOST_BANKED_REG(r10_fiq);			\
+	RESTORE_HOST_BANKED_REG(r9_fiq);			\
+	RESTORE_HOST_BANKED_REG(r8_fiq);			\
+	RESTORE_HOST_BANKED_MODE(fiq);				\
+	RESTORE_HOST_BANKED_MODE(irq);				\
+	RESTORE_HOST_BANKED_MODE(und);				\
+	RESTORE_HOST_BANKED_MODE(abt);				\
+	RESTORE_HOST_BANKED_MODE(svc);				\
+								\
+	pop	{lr};						\
+	pop	{r2};						\
+	msr	SP_usr, r2;					\
+	pop	{r4-r12};					\
+								\
+	pop	{r2};						\
+	msr	ELR_hyp, r2
+
+#define	load_cp15_regs_batch1					\
+	mrc	p15, 0, r2, c1, c0, 0;		@ SCTLR		\
+	mrc	p15, 0, r3, c1, c0, 2;		@ CPACR		\
+	mrc	p15, 0, r4, c2, c0, 2;		@ TTBCR		\
+	mrc	p15, 0, r5, c3, c0, 0;		@ DACR		\
+	mrrc	p15, 0, r6, r7, c2;		@ TTBR 0	\
+	mrrc	p15, 1, r8, r9, c2;		@ TTBR 1	\
+	mrc	p15, 0, r10, c10, c2, 0;	@ PRRR		\
+	mrc	p15, 0, r11, c10, c2, 1;	@ NMRR		\
+	mrc	p15, 2, r12, c0, c0, 0		@ CSSELR
+
+#define	load_cp15_regs_batch2					\
+	mrc	p15, 0, r2, c13, c0, 1;		@ CID		\
+	mrc	p15, 0, r3, c13, c0, 2;		@ TID_URW	\
+	mrc	p15, 0, r4, c13, c0, 3;		@ TID_URO	\
+	mrc	p15, 0, r5, c13, c0, 4;		@ TID_PRIV	\
+	mrc	p15, 0, r6, c5, c0, 0;		@ DFSR		\
+	mrc	p15, 0, r7, c5, c0, 1;		@ IFSR		\
+	mrc	p15, 0, r8, c5, c1, 0;		@ ADFSR		\
+	mrc	p15, 0, r9, c5, c1, 1;		@ AIFSR		\
+	mrc	p15, 0, r10, c6, c0, 0;		@ DFAR		\
+	mrc	p15, 0, r11, c6, c0, 2;		@ IFAR		\
+	mrc	p15, 0, r12, c12, c0, 0		@ VBAR
+
+#define	load_cp15_regs_batch3					\
+	mrc	p15, 0, r2, c14, c1, 0;		@ CNTKCTL	\
+	mrrc	p15, 0, r3, r4, c7;		@ PAR		\
+	mrc	p15, 0, r5, c10, c3, 0;		@ AMAIR0	\
+	mrc	p15, 0, r6, c10, c3, 1		@ AMAIR1
+
+#define	store_cp15_regs_batch1					\
+	mcr	p15, 0, r2, c1, c0, 0;		@ SCTLR		\
+	mcr	p15, 0, r3, c1, c0, 2;		@ CPACR		\
+	mcr	p15, 0, r4, c2, c0, 2;		@ TTBCR		\
+	mcr	p15, 0, r5, c3, c0, 0;		@ DACR		\
+	mcrr	p15, 0, r6, r7, c2;		@ TTBR 0	\
+	mcrr	p15, 1, r8, r9, c2;		@ TTBR 1	\
+	mcr	p15, 0, r10, c10, c2, 0;	@ PRRR		\
+	mcr	p15, 0, r11, c10, c2, 1;	@ NMRR		\
+	mcr	p15, 2, r12, c0, c0, 0		@ CSSELR
+
+#define	store_cp15_regs_batch2					\
+	mcr	p15, 0, r2, c13, c0, 1;		@ CID		\
+	mcr	p15, 0, r3, c13, c0, 2;		@ TID_URW	\
+	mcr	p15, 0, r4, c13, c0, 3;		@ TID_URO	\
+	mcr	p15, 0, r5, c13, c0, 4;		@ TID_PRIV	\
+	mcr	p15, 0, r6, c5, c0, 0;		@ DFSR		\
+	mcr	p15, 0, r7, c5, c0, 1;		@ IFSR		\
+	mcr	p15, 0, r8, c5, c1, 0;		@ ADFSR		\
+	mcr	p15, 0, r9, c5, c1, 1;		@ AIFSR		\
+	mcr	p15, 0, r10, c6, c0, 0;		@ DFAR		\
+	mcr	p15, 0, r11, c6, c0, 2;		@ IFAR		\
+	mcr	p15, 0, r12, c12, c0, 0		@ VBAR
+
+#define	store_cp15_regs_batch3					\
+	mcr	p15, 0, r2, c14, c1, 0;		@ CNTKCTL	\
+	mcrr	p15, 0, r3, r4, c7;		@ PAR		\
+	mcr	p15, 0, r5, c10, c3, 0;		@ AMAIR0	\
+	mcr	p15, 0, r6, c10, c3, 1		@ AMAIR1
+
+#define	store_guest_cp15_regs_batch1				\
+	str	r2, [r0, #HYPCTX_CP15_SCTLR];			\
+	str	r3, [r0, #HYPCTX_CP15_CPACR];			\
+	str	r4, [r0, #HYPCTX_CP15_TTBCR];			\
+	str	r5, [r0, #HYPCTX_CP15_DACR];			\
+	add	r2, r0, #HYPCTX_CP15_TTBR0;			\
+	strd	r6, r7, [r2];					\
+	add	r2, r0, #HYPCTX_CP15_TTBR1;			\
+	strd	r8, r9, [r2];					\
+	str	r10, [r0, #HYPCTX_CP15_PRRR];			\
+	str	r11, [r0, #HYPCTX_CP15_NMRR];			\
+	str	r12, [r0, #HYPCTX_CP15_CSSELR]
+
+#define	store_guest_cp15_regs_batch2				\
+	str	r2, [r0, #HYPCTX_CP15_CID];			\
+	str	r3, [r0, #HYPCTX_CP15_TID_URW];			\
+	str	r4, [r0, #HYPCTX_CP15_TID_URO];			\
+	str	r5, [r0, #HYPCTX_CP15_TID_PRIV];		\
+	str	r6, [r0, #HYPCTX_CP15_DFSR];			\
+	str	r7, [r0, #HYPCTX_CP15_IFSR];			\
+	str	r8, [r0, #HYPCTX_CP15_ADFSR];			\
+	str	r9, [r0, #HYPCTX_CP15_AIFSR];			\
+	str	r10, [r0, #HYPCTX_CP15_DFAR];			\
+	str	r11, [r0, #HYPCTX_CP15_IFAR];			\
+	str	r12, [r0, #HYPCTX_CP15_VBAR]
+
+#define	store_guest_cp15_regs_batch3				\
+	str	r2, [r0, #HYPCTX_CP15_CNTKCTL];			\
+	add	r2, r0, #HYPCTX_CP15_PAR;			\
+	strd	r4, r5, [r2];					\
+	str	r3, [r0, #HYPCTX_CP15_AMAIR0];			\
+	str	r6, [r0, #HYPCTX_CP15_AMAIR1]
+
+#define	load_guest_cp15_regs_batch1				\
+	ldr	r2, [r0, #HYPCTX_CP15_SCTLR];			\
+	ldr	r3, [r0, #HYPCTX_CP15_CPACR];			\
+	ldr	r4, [r0, #HYPCTX_CP15_TTBCR];			\
+	ldr	r5, [r0, #HYPCTX_CP15_DACR];			\
+	add	r2, r0, #HYPCTX_CP15_TTBR0;			\
+	ldrd	r6, r7, [r2];					\
+	add	r2, r0, #HYPCTX_CP15_TTBR1;			\
+	ldrd	r8, r9, [r2];					\
+	ldr	r10, [r0, #HYPCTX_CP15_PRRR];			\
+	ldr	r11, [r0, #HYPCTX_CP15_NMRR];			\
+	ldr	r12, [r0, #HYPCTX_CP15_CSSELR]
+
+#define	load_guest_cp15_regs_batch2				\
+	ldr	r2, [r0, #HYPCTX_CP15_CID];			\
+	ldr	r3, [r0, #HYPCTX_CP15_TID_URW];			\
+	ldr	r4, [r0, #HYPCTX_CP15_TID_URO];			\
+	ldr	r5, [r0, #HYPCTX_CP15_TID_PRIV];		\
+	ldr	r6, [r0, #HYPCTX_CP15_DFSR];			\
+	ldr	r7, [r0, #HYPCTX_CP15_IFSR];			\
+	ldr	r8, [r0, #HYPCTX_CP15_ADFSR];			\
+	ldr	r9, [r0, #HYPCTX_CP15_AIFSR];			\
+	ldr	r10, [r0, #HYPCTX_CP15_DFAR];			\
+	ldr	r11, [r0, #HYPCTX_CP15_IFAR];			\
+	ldr	r12, [r0, #HYPCTX_CP15_VBAR]
+
+#define	load_guest_cp15_regs_batch3				\
+	ldr	r2, [r0, #HYPCTX_CP15_CNTKCTL];			\
+	add	r2, r0, #HYPCTX_CP15_PAR;			\
+	ldrd	r4, r5, [r2];					\
+	ldr	r3, [r0, #HYPCTX_CP15_AMAIR0];			\
+	ldr	r6, [r0, #HYPCTX_CP15_AMAIR1]
+
+#endif


More information about the svn-soc-all mailing list