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

#include <zephyr/arch/arm64/hypercall.h>
#include <zephyr/xen/console.h>
#include <zephyr/xen/events.h>
#include <zephyr/xen/generic.h>
#include <zephyr/xen/hvm.h>
#include <zephyr/xen/public/io/console.h>
#include <zephyr/xen/public/sched.h>
#include <zephyr/xen/public/xen.h>

#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/device_mmio.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(uart_hvc_xen, CONFIG_UART_LOG_LEVEL);

static struct hvc_xen_data hvc_data = {0};

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void hvc_uart_evtchn_cb(void *priv);
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

static int read_from_ring(const struct device *dev, char *str, int len)
{
	int recv = 0;
	struct hvc_xen_data *hvc_data = dev->data;
	XENCONS_RING_IDX cons = hvc_data->intf->in_cons;
	XENCONS_RING_IDX prod = hvc_data->intf->in_prod;
	XENCONS_RING_IDX in_idx = 0;

	compiler_barrier();
	__ASSERT((prod - cons) <= sizeof(hvc_data->intf->in),
			"Invalid input ring buffer");

	while (cons != prod && recv < len) {
		in_idx = MASK_XENCONS_IDX(cons, hvc_data->intf->in);
		str[recv] = hvc_data->intf->in[in_idx];
		recv++;
		cons++;
	}

	compiler_barrier();
	hvc_data->intf->in_cons = cons;

	notify_evtchn(hvc_data->evtchn);
	return recv;
}

static int write_to_ring(const struct device *dev, const char *str, int len)
{
	int sent = 0;
	struct hvc_xen_data *hvc_data = dev->data;
	XENCONS_RING_IDX cons = hvc_data->intf->out_cons;
	XENCONS_RING_IDX prod = hvc_data->intf->out_prod;
	XENCONS_RING_IDX out_idx = 0;

	compiler_barrier();
	__ASSERT((prod - cons) <= sizeof(hvc_data->intf->out),
			"Invalid output ring buffer");

	while ((sent < len) && ((prod - cons) < sizeof(hvc_data->intf->out))) {
		out_idx = MASK_XENCONS_IDX(prod, hvc_data->intf->out);
		hvc_data->intf->out[out_idx] = str[sent];
		prod++;
		sent++;
	}

	compiler_barrier();
	hvc_data->intf->out_prod = prod;

	if (sent) {
		notify_evtchn(hvc_data->evtchn);
	}

	return sent;
}

static int xen_hvc_poll_in(const struct device *dev,
			unsigned char *c)
{
	int ret = 0;
	char temp;

	ret = read_from_ring(dev, &temp, sizeof(temp));
	if (!ret) {
		/* Char was not received */
		return -1;
	}

	*c = temp;
	return 0;
}

static void xen_hvc_poll_out(const struct device *dev,
			unsigned char c)
{
	/* Not a good solution (notifying HV every time), but needed for poll_out */
	(void) write_to_ring(dev, &c, sizeof(c));
}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static int xen_hvc_fifo_fill(const struct device *dev, const uint8_t *tx_data,
			 int len)
{
	int ret = 0, sent = 0;

	while (len) {
		sent = write_to_ring(dev, tx_data, len);

		ret += sent;
		tx_data += sent;
		len -= sent;

		if (len) {
			/* Need to be able to read it from another domain */
			HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
		}
	}

	return ret;
}

static int xen_hvc_fifo_read(const struct device *dev, uint8_t *rx_data,
			 const int size)
{
	return read_from_ring(dev, rx_data, size);
}

static void xen_hvc_irq_tx_enable(const struct device *dev)
{
	/*
	 * Need to explicitly call UART callback on TX enabling to
	 * process available buffered TX actions, because no HV events
	 * will be generated on tx_enable.
	 */
	hvc_uart_evtchn_cb(dev->data);
}

static int xen_hvc_irq_tx_ready(const struct device *dev)
{
	return 1;
}

static void xen_hvc_irq_rx_enable(const struct device *dev)
{
	/*
	 * Need to explicitly call UART callback on RX enabling to
	 * process available buffered RX actions, because no HV events
	 * will be generated on rx_enable.
	 */
	hvc_uart_evtchn_cb(dev->data);
}

static int xen_hvc_irq_tx_complete(const struct device *dev)
{
	/*
	 * TX is performed by copying in ring buffer by fifo_fill,
	 * so it will be always completed.
	 */
	return 1;
}

static int xen_hvc_irq_rx_ready(const struct device *dev)
{
	struct hvc_xen_data *data = dev->data;

	/* RX is ready only if data is available in ring buffer */
	return (data->intf->in_prod != data->intf->in_cons);
}

static int xen_hvc_irq_is_pending(const struct device *dev)
{
	return xen_hvc_irq_rx_ready(dev);
}

static int xen_hvc_irq_update(const struct device *dev)
{
	/* Nothing needs to be updated before actual ISR */
	return 1;
}

static void xen_hvc_irq_callback_set(const struct device *dev,
		 uart_irq_callback_user_data_t cb, void *user_data)
{
	struct hvc_xen_data *data = dev->data;

	data->irq_cb = cb;
	data->irq_cb_data = user_data;
}
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

static const struct uart_driver_api xen_hvc_api = {
	.poll_in = xen_hvc_poll_in,
	.poll_out = xen_hvc_poll_out,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	.fifo_fill = xen_hvc_fifo_fill,
	.fifo_read = xen_hvc_fifo_read,
	.irq_tx_enable = xen_hvc_irq_tx_enable,
	.irq_tx_ready = xen_hvc_irq_tx_ready,
	.irq_rx_enable = xen_hvc_irq_rx_enable,
	.irq_tx_complete = xen_hvc_irq_tx_complete,
	.irq_rx_ready = xen_hvc_irq_rx_ready,
	.irq_is_pending = xen_hvc_irq_is_pending,
	.irq_update = xen_hvc_irq_update,
	.irq_callback_set = xen_hvc_irq_callback_set,
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
};

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void hvc_uart_evtchn_cb(void *priv)
{
	struct hvc_xen_data *data = priv;

	if (data->irq_cb) {
		data->irq_cb(data->dev, data->irq_cb_data);
	}
}
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

int xen_console_init(const struct device *dev)
{
	int ret = 0;
	uint64_t console_pfn = 0;
	uintptr_t console_addr = 0;
	struct hvc_xen_data *data = dev->data;

	data->dev = dev;

	ret = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &data->evtchn);
	if (ret) {
		LOG_ERR("%s: failed to get Xen console evtchn, ret = %d\n",
				__func__, ret);
		return ret;
	}

	ret = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &console_pfn);
	if (ret) {
		LOG_ERR("%s: failed to get Xen console PFN, ret = %d\n",
				__func__, ret);
		return ret;
	}

	console_addr = (uintptr_t) (console_pfn << XEN_PAGE_SHIFT);
	device_map(DEVICE_MMIO_RAM_PTR(dev), console_addr, XEN_PAGE_SIZE,
		K_MEM_CACHE_WB);

	data->intf = (struct xencons_interface *) DEVICE_MMIO_GET(dev);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	bind_event_channel(data->evtchn, hvc_uart_evtchn_cb, data);
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

	LOG_INF("Xen HVC inited successfully\n");

	return 0;
}

DEVICE_DT_DEFINE(DT_NODELABEL(xen_hvc), xen_console_init, NULL, &hvc_data,
		NULL, PRE_KERNEL_1, CONFIG_XEN_HVC_INIT_PRIORITY,
		&xen_hvc_api);

#ifdef CONFIG_XEN_EARLY_CONSOLEIO
extern void __printk_hook_install(int (*fn)(int));
extern void __stdout_hook_install(int (*fn)(int));

int xen_consoleio_putc(int c)
{
	char symbol = (char) c;

	HYPERVISOR_console_io(CONSOLEIO_write, sizeof(symbol), &symbol);
	return c;
}



int consoleio_hooks_set(const struct device *dev)
{
	ARG_UNUSED(dev);

	/* Will be replaced with poll_in/poll_out by uart_console.c later on boot */
	__stdout_hook_install(xen_consoleio_putc);
	__printk_hook_install(xen_consoleio_putc);

	return 0;
}

SYS_INIT(consoleio_hooks_set, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
#endif /* CONFIG_XEN_EARLY_CONSOLEIO */
