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