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