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 
20 #define DT_DRV_COMPAT xen_hvc_consoleio
21 
xen_consoleio_poll_in(const struct device * dev,unsigned char * c)22 static int xen_consoleio_poll_in(const struct device *dev,
23 			unsigned char *c)
24 {
25 	int ret = 0;
26 	char temp;
27 
28 	ret = HYPERVISOR_console_io(CONSOLEIO_read, sizeof(temp), &temp);
29 	if (!ret) {
30 		/* Char was not received */
31 		return -1;
32 	}
33 
34 	*c = temp;
35 	return 0;
36 }
37 
xen_consoleio_poll_out(const struct device * dev,unsigned char c)38 static void xen_consoleio_poll_out(const struct device *dev,
39 			unsigned char c)
40 {
41 	(void) HYPERVISOR_console_io(CONSOLEIO_write, sizeof(c), &c);
42 }
43 
44 static const struct uart_driver_api xen_consoleio_hvc_api = {
45 	.poll_in = xen_consoleio_poll_in,
46 	.poll_out = xen_consoleio_poll_out,
47 };
48 
xen_consoleio_init(const struct device * dev)49 static int xen_consoleio_init(const struct device *dev)
50 {
51 	/* Nothing to do, but still needed for device API */
52 	return 0;
53 }
54 
55 DEVICE_DT_INST_DEFINE(0, xen_consoleio_init, NULL, NULL,
56 		NULL, PRE_KERNEL_1, CONFIG_XEN_HVC_INIT_PRIORITY,
57 		&xen_consoleio_hvc_api);
58