diff --git a/CODEOWNERS b/CODEOWNERS index c18adc71d67..536a7ae1bf6 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -344,6 +344,7 @@ /drivers/serial/serial_test.c @str4t0m /drivers/serial/Kconfig.xen @lorc @firscity /drivers/serial/uart_hvc_xen.c @lorc @firscity +/drivers/serial/uart_hvc_xen_consoleio.c @lorc @firscity /drivers/serial/Kconfig.it8xxx2 @GTLin08 /drivers/serial/uart_ite_it8xxx2.c @GTLin08 /drivers/disk/ @jfischer-no diff --git a/boards/arm64/xenvm/Kconfig.defconfig b/boards/arm64/xenvm/Kconfig.defconfig index 2e8d48bc8f6..bc04e6983b4 100644 --- a/boards/arm64/xenvm/Kconfig.defconfig +++ b/boards/arm64/xenvm/Kconfig.defconfig @@ -6,6 +6,12 @@ if BOARD_XENVM config BUILD_OUTPUT_BIN default y +config XEN_INITIAL_DOMAIN + bool "Zephyr as Xen Domain 0" + default n + help + Built binary will be used as Xen privileged domain. + config BOARD default "xenvm" diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 350c8c2f6c9..acb5195d73a 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -45,6 +45,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_XEC uart_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_UART_NEORV32 uart_neorv32.c) zephyr_library_sources_ifdef(CONFIG_USART_GD32 usart_gd32.c) zephyr_library_sources_ifdef(CONFIG_UART_XEN_HVC uart_hvc_xen.c) +zephyr_library_sources_ifdef(CONFIG_UART_XEN_HVC_CONSOLEIO uart_hvc_xen_consoleio.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE uart_handlers.c) diff --git a/drivers/serial/Kconfig.xen b/drivers/serial/Kconfig.xen index 82b191d8b35..da3bb66cfe3 100644 --- a/drivers/serial/Kconfig.xen +++ b/drivers/serial/Kconfig.xen @@ -5,17 +5,29 @@ # config UART_XEN_HVC - bool "Xen hypervisor console UART Driver" + bool "Xen hypervisor DomU console UART driver" select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT depends on BOARD_XENVM + depends on !XEN_INITIAL_DOMAIN default y help - Enable Xen hypervisor console driver. + Enable Xen ring buffer based hypervisor console driver. Used + for Zephyr as unprivileged domain. + +config UART_XEN_HVC_CONSOLEIO + bool "Xen hypervisor Dom0 console UART driver" + select SERIAL_HAS_DRIVER + depends on BOARD_XENVM + depends on XEN_INITIAL_DOMAIN + default y + help + Enable Xen hypervisor console driver. Used for Zephyr as + privileged domain (Dom0). config XEN_HVC_INIT_PRIORITY int "Xen hypervisor console init priority" - depends on UART_XEN_HVC + depends on UART_XEN_HVC || UART_XEN_HVC_CONSOLEIO default 55 help Set init priority for Xen HVC, should be inited before UART @@ -24,6 +36,7 @@ config XEN_HVC_INIT_PRIORITY config XEN_EARLY_CONSOLEIO bool "Early printk/stdout through console_io Xen interface" depends on BOARD_XENVM + depends on UART_XEN_HVC default n help Enable setting of console_io symbol hook for stdout and printk. diff --git a/drivers/serial/uart_hvc_xen_consoleio.c b/drivers/serial/uart_hvc_xen_consoleio.c new file mode 100644 index 00000000000..899fa740745 --- /dev/null +++ b/drivers/serial/uart_hvc_xen_consoleio.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 EPAM Systems + * + * SPDX-License-Identifier: Apache-2.0 + * + * This driver implements input/output API for Xen domain through the + * Xen consoleio interface. This should be used only for Zephyr as initial + * domain (Dom0). For unprivileged domains regular ring buffer HVC driver + * should be used (uart_hvc_xen.c), this console will not be available. + */ + +#include +#include + +#include +#include +#include +#include + +static int xen_consoleio_poll_in(const struct device *dev, + unsigned char *c) +{ + int ret = 0; + char temp; + + ret = HYPERVISOR_console_io(CONSOLEIO_read, sizeof(temp), &temp); + if (!ret) { + /* Char was not received */ + return -1; + } + + *c = temp; + return 0; +} + +static void xen_consoleio_poll_out(const struct device *dev, + unsigned char c) +{ + (void) HYPERVISOR_console_io(CONSOLEIO_write, sizeof(c), &c); +} + +static const struct uart_driver_api xen_consoleio_hvc_api = { + .poll_in = xen_consoleio_poll_in, + .poll_out = xen_consoleio_poll_out, +}; + +int xen_consoleio_init(const struct device *dev) +{ + /* Nothing to do, but still needed for device API */ + return 0; +} + +DEVICE_DT_DEFINE(DT_NODELABEL(xen_consoleio_hvc), xen_consoleio_init, NULL, NULL, + NULL, PRE_KERNEL_1, CONFIG_XEN_HVC_INIT_PRIORITY, + &xen_consoleio_hvc_api);