#include "linux/sizes.h"

#include "kvm/irq.h"
#include "kvm/kvm.h"
#include "kvm/kvm-cpu.h"
#include "kvm/vfio.h"

#include <assert.h>

#include <sys/ioctl.h>
#include <sys/eventfd.h>
#include <sys/resource.h>
#include <sys/time.h>

#define DUMMU_BINDING_COMPAT		"snps,designware-i2c"

static u32 vfio_mmio_io_space_blocks = KVM_VFIO_MMIO_AREA;

static u32 vfio_mmio_get_io_space_block(u32 size)
{
	u32 block = vfio_mmio_io_space_blocks;

	vfio_mmio_io_space_blocks += size;

	return block;
}

static void generate_qemu_virt_clk(void *fdt) {
	_FDT(fdt_begin_node(fdt, "apb-pclk"));
	_FDT(fdt_property_string(fdt, "clock-output-names", "clk24mhz"));
	_FDT(fdt_property_string(fdt, "compatible", "fixed-clock"));
	_FDT(fdt_property_cell(fdt, "clock-frequency", 0x16e3600));
	_FDT(fdt_property_cell(fdt, "phandle", 0x8000));
	_FDT(fdt_property_cell(fdt, "#clock-cells", 0x00));
	_FDT(fdt_end_node(fdt));
}

static void generate_qemu_iommu(void *fdt, u64 id) {
	_FDT(fdt_begin_node(fdt, "pviommu"));
	_FDT(fdt_property_string(fdt, "compatible", "pkvm,pviommu"));
	_FDT(fdt_property_cell(fdt, "id", id));
	_FDT(fdt_property_cell(fdt, "phandle", 0x9000));
	_FDT(fdt_property_cell(fdt, "#iommu-cells", 1));
	_FDT(fdt_end_node(fdt));
}

/*
 * Ideally we should have either a user passed configuration or a look up table to generate
 * the device tree from certain platform device.
 * As there is many information we can't deduce as dma coherency, compatible string, power
 * domains...
 * For now we just hardcode this value, this is mainly for testing and not intended for production.
 */
static void generate_mmio_fdt_node(void *fdt,
				   struct device_header *dev_hdr,
				   void (*generate_irq_prop)(void *fdt,
							     u8 irq,
							     enum irq_type))
{
	struct vfio_device *vdev = container_of(dev_hdr,
						struct vfio_device, dev_hdr);
	struct vfio_platform_device *pdev = &vdev->platform;
	u32 iommu[] = {
		cpu_to_fdt32(0x9000),	/*phandle of pvIOMMU */
		cpu_to_fdt32(vdev->sid[0]),		/* SID */
	};

	u64 reg_prop[10]; /* Max 5 for now. */
	unsigned int i = 0;

	generate_qemu_virt_clk(fdt);

	generate_qemu_iommu(fdt, vdev->iommu);

	for ( ; i < vdev->info.num_regions ; i++) {
		reg_prop[2 * i] = cpu_to_fdt64(vdev->regions[i].guest_phys_addr); /* Addr */
		reg_prop[2 * i + 1] = cpu_to_fdt64(vdev->regions[i].info.size); /* Size */
	}

	_FDT(fdt_begin_node(fdt, vdev->params->name));
	_FDT(fdt_property_string(fdt, "compatible", DUMMU_BINDING_COMPAT));
	_FDT(fdt_property_string(fdt, "clock-names", "apb_pclk"));
	_FDT(fdt_property_cell(fdt, "clocks", 0x8000));
	_FDT(fdt_property(fdt, "dma-coherent", NULL, 0));
	_FDT(fdt_property(fdt, "iommus", iommu, sizeof(iommu)));
	_FDT(fdt_property(fdt, "reg", reg_prop, sizeof(u64) * vdev->info.num_regions  * 2));
	for (i = 0 ; i < vdev->info.num_irqs ; ++i)
		generate_irq_prop(fdt, pdev->gsi[i], IRQ_TYPE_LEVEL_HIGH);

	_FDT(fdt_end_node(fdt));
}

static int vfio_platform_configure_regs(struct kvm *kvm,
					struct vfio_device *vdev)
{
	int ret = 0;
	unsigned int i = 0;
	struct vfio_region *region;
	struct vfio_region_info *info;

	for (i = 0 ; i < vdev->info.num_regions ; i++) {
		info = &vdev->regions[i].info;
		*info = (struct vfio_region_info) {
			.argsz = sizeof(*info),
			.index = i,
		};
		ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, info);
		vfio_dev_info(vdev, "map vfio[%d] 0x%llx - 0x%llx ", i, info->offset, info->size);

		region = &vdev->regions[i];
		region->vdev = vdev;
		region->is_ioport = false;
		region->guest_phys_addr = vfio_mmio_get_io_space_block(region->info.size);
		vfio_dev_info(vdev, "map vfio[%d] guest_addr %llx ", i, region->guest_phys_addr);

		ret = vfio_map_region(kvm, vdev, region);
		if (ret) {
			vfio_dev_err(vdev, "Failed to map region[%d] at 0x%llx ", i, info->offset);
			break;
		}
	}
	return ret;
}

static int vfio_platform_configure_dev_irqs(struct kvm *kvm, struct vfio_device *vdev)
{
	int ret = 0;
	unsigned int i = 0, j;
	struct vfio_platform_device *pdev = &vdev->platform;
	struct vfio_irq_info irq_info;
	unsigned int num_irqs = vdev->info.num_irqs;
	union vfio_irq_eventfd	trigger, unmask;
	int trigger_fd, unmask_fd;

	pdev->gsi = malloc(num_irqs * sizeof(pdev->gsi));
	pdev->irqfd = malloc(num_irqs * sizeof(pdev->irqfd));
	pdev->unmaskfd = malloc(num_irqs * sizeof(pdev->unmaskfd));

	for ( ; i <  num_irqs; ++i) {
		irq_info = (struct vfio_irq_info){
			.argsz = sizeof(irq_info),
			.index = i,
		};
		ret = ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);

		if (ret) {
			vfio_dev_err(vdev, "Failed to get irq[%d] info, err %d", i, ret);
			return -EINVAL;
		}

		if (!(irq_info.flags & VFIO_IRQ_INFO_EVENTFD)) {
			vfio_dev_err(vdev, "irq[%d] not eventfd capable", i);
			return -EINVAL;
		}

		/* Assume level interrupt. */
		if (!(irq_info.flags & VFIO_IRQ_INFO_AUTOMASKED)) {
			vfio_dev_err(vdev, "irq[%d] interrupt not AUTOMASKED", i);
			return -EINVAL;
		}

		pdev->gsi[i] = irq__alloc_line();

		trigger_fd = eventfd(0, 0);
		if (trigger_fd < 0) {
			vfio_dev_err(vdev, "Failed to create trigger eventfd");
			return trigger_fd;
		}

		unmask_fd = eventfd(0, 0);
		if (unmask_fd < 0) {
			vfio_dev_err(vdev, "Failed to create unmask eventfd");
			close(trigger_fd);
			return unmask_fd;
		}

		ret = irq__add_irqfd(kvm, pdev->gsi[i] - KVM_IRQ_OFFSET, trigger_fd, unmask_fd);
		if (ret)
			goto err_close;

		trigger.irq = (struct vfio_irq_set) {
			.argsz	= sizeof(trigger),
			.flags	= VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER,
			.index	= i,
			.start	= 0,
			.count	= 1,
		};
		set_vfio_irq_eventd_payload(&trigger, trigger_fd);

		ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &trigger);
		if (ret < 0) {
			vfio_dev_err(vdev, "failed to setup VFIO IRQ");
			goto err_delete_line;
		}

		unmask.irq = (struct vfio_irq_set) {
			.argsz	= sizeof(unmask),
			.flags	= VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_UNMASK,
			.index	= i,
			.start	= 0,
			.count	= 1,
		};
		set_vfio_irq_eventd_payload(&unmask, unmask_fd);

		ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &unmask);
		if (ret < 0) {
			vfio_dev_err(vdev, "Failed to setup unmask IRQ");
			goto err_remove_event;
		}

		pdev->irqfd[i] = trigger_fd;
		pdev->unmaskfd[i] = unmask_fd;

		vfio_dev_info(vdev, "map irq[%d] gsi %d fd %d", i, pdev->gsi[i], pdev->irqfd[i]);
	}

	return 0;

err_remove_event:
	for (j = i - 1 ; j >= 0 && i; --j) {
		/* Remove trigger event */
		trigger.irq.flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
		trigger.irq.count = 0;
		trigger.irq.index = j;
		ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &trigger);
	}

err_delete_line:
	for (j = i - 1 ; j >= 0 && i; --j)
		irq__del_irqfd(kvm, pdev->gsi[j] - KVM_IRQ_OFFSET, pdev->irqfd[j]);

err_close:
	for (j = i - 1 ; j >= 0 && i; --j) {
		close(pdev->irqfd[j]);
		close(pdev->unmaskfd[j]);
	}

	return ret;
}

int vfio_platform_setup_device(struct kvm *kvm, struct vfio_device *vdev)
{
	int ret;

	vfio_dev_info(vdev, "VFIO Platform device setup");

	ret = vfio_platform_configure_regs(kvm, vdev);
	if (ret)
		return ret;

	vdev->dev_hdr = (struct device_header) {
		.bus_type	= DEVICE_BUS_MMIO,
		.data		= generate_mmio_fdt_node,
	};

	ret = device__register(&vdev->dev_hdr);
	if (ret) {
		vfio_dev_err(vdev, "Failed to register VFIO device");
		return ret;
	}

	ret = vfio_platform_configure_dev_irqs(kvm, vdev);
	if (ret) {
		vfio_dev_err(vdev, "Failed to configure IRQs");
		return ret;
	}

	return 0;
}

void vfio_platform_teardown_device(struct kvm *kvm, struct vfio_device *vdev)
{
	size_t i;
	struct vfio_platform_device *pdev = &vdev->platform;

	for (i = 0; i < vdev->info.num_regions; ++i)
		vfio_unmap_region(kvm, &vdev->regions[i]);

	for(i = 0; i < vdev->info.num_irqs; ++i) {
		irq__del_irqfd(kvm, pdev->gsi[i] - KVM_IRQ_OFFSET, pdev->irqfd[i]);
		close(pdev->irqfd[i]);
		close(pdev->unmaskfd[i]);
	}

	device__unregister(&vdev->dev_hdr);
	free(pdev->gsi);
	free(pdev->irqfd);
	free(pdev->unmaskfd);
}
