1 /*
2  * Copyright (c) 2021 EPAM Systems
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * This driver implements input/output API for Xen domain through the
7  * Xen consoleio interface. This should be used only for Zephyr as initial
8  * domain (Dom0). For unprivileged domains regular ring buffer HVC driver
9  * should be used (uart_hvc_xen.c), this console will not be available.
10  */
11 
12 #include <zephyr/arch/arm64/hypercall.h>
13 #include <zephyr/xen/public/xen.h>
14 
15 #include <zephyr/device.h>
16 #include <zephyr/drivers/uart.h>
17 #include <zephyr/init.h>
18 #include <zephyr/kernel.h>
19 
xen_consoleio_poll_in(const struct device * dev,unsigned char * c)20 static int xen_consoleio_poll_in(const struct device *dev,
21 			unsigned char *c)
22 {
23 	int ret = 0;
24 	char temp;
25 
26 	ret = HYPERVISOR_console_io(CONSOLEIO_read, sizeof(temp), &temp);
27 	if (!ret) {
28 		/* Char was not received */
29 		return -1;
30 	}
31 
32 	*c = temp;
33 	return 0;
34 }
35 
xen_consoleio_poll_out(const struct device * dev,unsigned char c)36 static void xen_consoleio_poll_out(const struct device *dev,
37 			unsigned char c)
38 {
39 	(void) HYPERVISOR_console_io(CONSOLEIO_write, sizeof(c), &c);
40 }
41 
42 static const struct uart_driver_api xen_consoleio_hvc_api = {
43 	.poll_in = xen_consoleio_poll_in,
44 	.poll_out = xen_consoleio_poll_out,
45 };
46 
xen_consoleio_init(const struct device * dev)47 int xen_consoleio_init(const struct device *dev)
48 {
49 	/* Nothing to do, but still needed for device API */
50 	return 0;
51 }
52 
53 DEVICE_DT_DEFINE(DT_NODELABEL(xen_consoleio_hvc), xen_consoleio_init, NULL, NULL,
54 		NULL, PRE_KERNEL_1, CONFIG_XEN_HVC_INIT_PRIORITY,
55 		&xen_consoleio_hvc_api);
56