/* SPDX-License-Identifier: Apache-2.0 */
/*
 * Copyright (c) 2023 EPAM Systems
 *
 */

#include <zephyr/arch/arm64/hypercall.h>
#include <zephyr/xen/dom0/domctl.h>
#include <zephyr/xen/generic.h>
#include <zephyr/xen/public/domctl.h>
#include <zephyr/xen/public/xen.h>

#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <string.h>

static int do_domctl(xen_domctl_t *domctl)
{
	domctl->interface_version = XEN_DOMCTL_INTERFACE_VERSION;
	return HYPERVISOR_domctl(domctl);
}

int xen_domctl_scheduler_op(int domid, struct xen_domctl_scheduler_op *sched_op)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_scheduler_op,
		.domain = domid,
		.u.scheduler_op = *sched_op,
	};

	return do_domctl(&domctl);
}

int xen_domctl_pausedomain(int domid)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_pausedomain,
		.domain = domid,
	};

	return do_domctl(&domctl);
}

int xen_domctl_unpausedomain(int domid)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_unpausedomain,
		.domain = domid,
	};

	return do_domctl(&domctl);
}

int xen_domctl_resumedomain(int domid)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_resumedomain,
		.domain = domid,
	};

	return do_domctl(&domctl);
}

int xen_domctl_getvcpucontext(int domid, int vcpu, vcpu_guest_context_t *ctxt)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_getvcpucontext,
		.domain = domid,
		.u.vcpucontext.vcpu = 0,
	};

	set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);

	return do_domctl(&domctl);
}

int xen_domctl_setvcpucontext(int domid, int vcpu, vcpu_guest_context_t *ctxt)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_setvcpucontext,
		.domain = domid,
		.u.vcpucontext.vcpu = 0,
	};

	set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);

	return do_domctl(&domctl);
}

int xen_domctl_getdomaininfo(int domid, xen_domctl_getdomaininfo_t *dom_info)
{
	int rc;
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_getdomaininfo,
		.domain = domid,
	};

	rc = do_domctl(&domctl);
	if (rc) {
		return rc;
	}

	memcpy(dom_info, &domctl.u.getdomaininfo, sizeof(*dom_info));

	return 0;
}

int xen_domctl_get_paging_mempool_size(int domid, uint64_t *size_mb)
{
	int rc;
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_get_paging_mempool_size,
		.domain = domid,
	};

	rc = do_domctl(&domctl);
	if (rc) {
		return rc;
	}

	*size_mb = domctl.u.paging_mempool.size;

	return 0;
}

int xen_domctl_set_paging_mempool_size(int domid, uint64_t size_mb)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_set_paging_mempool_size,
		.domain = domid,
		.u.paging_mempool.size = size_mb,
	};

	return do_domctl(&domctl);
}

int xen_domctl_max_mem(int domid, uint64_t max_memkb)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_max_mem,
		.domain = domid,
		.u.max_mem.max_memkb = max_memkb,
	};

	return do_domctl(&domctl);
}

int xen_domctl_set_address_size(int domid, int addr_size)
{
	xen_domctl_t domctl = {
		.domain = domid,
		.cmd = XEN_DOMCTL_set_address_size,
		.u.address_size.size = addr_size,
	};

	return do_domctl(&domctl);
}

int xen_domctl_iomem_permission(int domid, uint64_t first_mfn,
		uint64_t nr_mfns, uint8_t allow_access)
{
	xen_domctl_t domctl = {
		.domain = domid,
		.cmd = XEN_DOMCTL_iomem_permission,
		.u.iomem_permission.first_mfn = first_mfn,
		.u.iomem_permission.nr_mfns = nr_mfns,
		.u.iomem_permission.allow_access = allow_access,
	};

	return do_domctl(&domctl);
}

int xen_domctl_memory_mapping(int domid, uint64_t first_gfn, uint64_t first_mfn,
		uint64_t nr_mfns, uint32_t add_mapping)
{
	int ret;
	uint64_t curr, nr_max, done;
	xen_domctl_t domctl = {
		.domain = domid,
		.cmd = XEN_DOMCTL_memory_mapping,
		.u.memory_mapping.add_mapping = add_mapping,
	};

	if (!nr_mfns) {
		return 0;
	}

	/* nr_mfns can be big and we need to handle this here */
	done = 0;
	nr_max = nr_mfns;
	do {
		domctl.u.memory_mapping.first_gfn = first_gfn + done;
		domctl.u.memory_mapping.first_mfn = first_mfn + done;

		curr = MIN(nr_mfns - done, nr_max);
		domctl.u.memory_mapping.nr_mfns = curr;

		ret = do_domctl(&domctl);
		if (ret < 0) {
			if (ret == -E2BIG) {
				/* Check if we not reach min amount */
				if (nr_max <= 1) {
					break;
				}

				/* Decrease amount twice and try again */
				nr_max = nr_max >> 1;
				continue;
			} else {
				break;
			}
		}

		done += curr;
	} while (done < nr_mfns);

	/* We may come here when get E2BIG and reach 1 at nr_max */
	if (!done) {
		ret = -1;
	}

	return ret;
}

int xen_domctl_assign_dt_device(int domid, char *dtdev_path)
{
	xen_domctl_t domctl = {
		.domain = domid,
		.cmd = XEN_DOMCTL_assign_device,
		.u.assign_device.flags = 0,
		.u.assign_device.dev = XEN_DOMCTL_DEV_DT,
		.u.assign_device.u.dt.size = strlen(dtdev_path),
	};

	set_xen_guest_handle(domctl.u.assign_device.u.dt.path, dtdev_path);

	return do_domctl(&domctl);

}

int xen_domctl_bind_pt_irq(int domid, uint32_t machine_irq, uint8_t irq_type,
		uint8_t bus, uint8_t device, uint8_t intx, uint8_t isa_irq,
		uint16_t spi)
{
	xen_domctl_t domctl = {
		.domain = domid,
		.cmd = XEN_DOMCTL_bind_pt_irq,
	};
	struct xen_domctl_bind_pt_irq *bind = &(domctl.u.bind_pt_irq);

	switch (irq_type) {
	case PT_IRQ_TYPE_SPI:
		bind->irq_type = irq_type;
		bind->machine_irq = machine_irq;
		bind->u.spi.spi = spi;
		break;
	default:
		/* TODO: implement other types */
		return -ENOTSUP;
	}

	return do_domctl(&domctl);
}

int xen_domctl_max_vcpus(int domid, int max_vcpus)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_max_vcpus,
		.domain = domid,
		.u.max_vcpus.max = max_vcpus,
	};

	return do_domctl(&domctl);
}

int xen_domctl_createdomain(int domid, struct xen_domctl_createdomain *config)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_createdomain,
		.domain = domid,
		.u.createdomain = *config,
	};

	return do_domctl(&domctl);
}

int xen_domctl_destroydomain(int domid)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_destroydomain,
		.domain = domid,
	};

	return do_domctl(&domctl);
}

int xen_domctl_cacheflush(int domid,  struct xen_domctl_cacheflush *cacheflush)
{
	xen_domctl_t domctl = {
		.cmd = XEN_DOMCTL_cacheflush,
		.domain = domid,
		.u.cacheflush = *cacheflush,
	};

	return do_domctl(&domctl);
}
