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

mihai at FreeBSD.org mihai at FreeBSD.org
Mon Aug 10 18:40:21 UTC 2015


Author: mihai
Date: Mon Aug 10 18:40:20 2015
New Revision: 289531
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=289531

Log:
  sys: arm: vmm: vgic.c: added vgic probing and skeleton for ditributor emulation

Added:
  soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/vgic.c
  soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/vgic.h

Added: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/vgic.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/vgic.c	Mon Aug 10 18:40:20 2015	(r289531)
@@ -0,0 +1,146 @@
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/param.h>
+#include <machine/cpufunc.h>
+#include <machine/pmap.h>
+#include <machine/vmparam.h>
+#include <machine/gic.h>
+
+#include <machine/vmm.h>
+#include <machine/vmm_instruction_emul.h>
+#include "mmu.h"
+#include "vgic.h"
+#include "arm.h"
+
+
+static struct arm_gic_softc *gic_sc;
+static uint64_t virtual_int_ctrl_vaddr;
+static uint64_t virtual_int_ctrl_paddr;
+static uint32_t virtual_int_ctrl_size;
+
+static uint64_t virtual_cpu_int_paddr;
+static uint32_t virtual_cpu_int_size;
+
+static uint32_t lr_num;
+
+static int
+vgic_dist_mmio_read(void *vm, int vcpuid, uint64_t gpa, uint64_t *rval, int size,
+    void *arg)
+{
+	printf("%s on cpu: %d with gpa: %llx size: %x\n", __func__, vcpuid, gpa, size);
+	return (0);
+}
+
+static int
+vgic_dist_mmio_write(void *vm, int vcpuid, uint64_t gpa, uint64_t val, int size,
+    void *arg)
+{
+	printf("%s on cpu: %d with gpa: %llx size: %x with val: %llx\n", __func__, vcpuid, gpa, size, val);
+	return (0);
+}
+
+int
+vgic_emulate_distributor(void *arg, int vcpuid, struct vm_exit *vme, bool *retu)
+{
+	struct hyp *hyp;
+	int error;
+
+	hyp = arg;
+
+	if (vme->u.inst_emul.gpa < hyp->vgic_distributor.distributor_base ||
+		vme->u.inst_emul.gpa > hyp->vgic_distributor.distributor_base + PAGE_SIZE ||
+		!hyp->vgic_attached) {
+
+		*retu = true;
+		return (0);
+	}
+
+	*retu = false;
+	error = vmm_emulate_instruction(hyp->vm, vcpuid, vme->u.inst_emul.gpa, &vme->u.inst_emul.vie,
+	    vgic_dist_mmio_read, vgic_dist_mmio_write, retu);
+
+	return (error);
+}
+
+int
+vgic_attach(void *arg, uint64_t distributor_paddr, uint64_t cpu_int_paddr)
+{
+	struct hyp *hyp;
+	struct hypctx *hypctx;
+	int i;
+
+	hyp = arg;
+
+	/* 
+	 * Set the distributor address which will be 
+	 * emulated using the MMIO infrasctructure
+	 * */
+	hyp->vgic_distributor.distributor_base = distributor_paddr;
+	hyp->vgic_distributor.cpu_int_base = cpu_int_paddr;
+	hyp->vgic_attached = true;
+	/* 
+	 * Set the Virtual Interface Control address to
+	 * save/restore registers at context switch.
+	 * Also set the number of LRs
+	 * */
+	for (i = 0; i < VM_MAXCPU; i++) {
+		hypctx = &hyp->ctx[i];
+		hypctx->vgic_cpu_int.virtual_int_ctrl = virtual_int_ctrl_vaddr;
+		hypctx->vgic_cpu_int.lr_num = lr_num;
+	}
+
+	/* Map the CPU Interface over the Virtual CPU Interface */
+	lpae_vmmmap_set(arg,
+	    (lpae_vm_vaddr_t)cpu_int_paddr,
+	    (lpae_vm_paddr_t)virtual_cpu_int_paddr,
+	    virtual_cpu_int_size,
+	    VM_PROT_READ | VM_PROT_WRITE);
+
+	return (0);
+}
+
+int
+vgic_hyp_init(void)
+{
+	if (!(gic_sc = get_arm_gic_sc())) {
+		printf("vgic_hyp_init: GIC no present\n");
+		return (ENXIO);
+	}
+	if (gic_sc->gic_res[2] == NULL || gic_sc->gic_res[3] == NULL) {
+		printf("vgic_hyp_init: Virtual CPU interface control"
+			" and registers not present in DTS\n");
+		return (ENXIO);
+	}
+
+	/* Virtual Interface Control */
+	gic_sc->gic_h_bst = rman_get_bustag(gic_sc->gic_res[2]);
+	gic_sc->gic_h_bsh = rman_get_bushandle(gic_sc->gic_res[2]);
+	virtual_int_ctrl_vaddr = (uint64_t)rman_get_virtual(gic_sc->gic_res[2]);
+	virtual_int_ctrl_paddr = (uint64_t)rman_get_start(gic_sc->gic_res[2]);
+	virtual_int_ctrl_size = rman_get_size(gic_sc->gic_res[2]);
+
+	/* Virtual CPU Interface */
+	virtual_cpu_int_paddr = rman_get_start(gic_sc->gic_res[3]);
+	virtual_cpu_int_size = rman_get_size(gic_sc->gic_res[3]);
+
+	lr_num = (gic_h_read_4(gic_sc, GICH_VTR) & 0x3f) + 1;
+
+	lpae_vmmmap_set(NULL,
+	    (lpae_vm_vaddr_t)virtual_int_ctrl_vaddr,
+	    (lpae_vm_paddr_t)virtual_int_ctrl_paddr,
+	    virtual_int_ctrl_size,
+	    VM_PROT_READ | VM_PROT_WRITE);
+
+	return (0);
+}

Added: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/vgic.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/vgic.h	Mon Aug 10 18:40:20 2015	(r289531)
@@ -0,0 +1,34 @@
+#ifndef _VMM_VGIC_H_
+#define	_VMM_VGIC_H_
+
+#define VGIC_LR_NUM	64
+struct vm;
+struct vm_exit;
+
+struct vgic_distributor {
+	uint64_t	distributor_base;
+	uint64_t	cpu_int_base;
+
+	int		nr_irqs;
+};
+
+struct vgic_cpu_int {
+	uint64_t	virtual_int_ctrl;
+	uint32_t	lr_num;
+	uint32_t	hcr;
+	uint32_t	vmcr;
+	uint32_t	misr;
+	uint64_t	eisr;
+	uint64_t	elsr;
+	uint32_t	apr;
+	uint32_t	lr[VGIC_LR_NUM];
+};
+
+int vgic_hyp_init(void);
+
+int vgic_emulate_distributor(void *arg, int vcpuid,
+		struct vm_exit *vme, bool *retu);
+
+int vgic_attach(void *arg, uint64_t distributor_paddr,
+		uint64_t cpu_int_paddr);
+#endif


More information about the svn-soc-all mailing list