From 31b4e4124d55f2bb6b2a1f4d6ced5717898e58e3 Mon Sep 17 00:00:00 2001 From: Dmytro Firsov Date: Thu, 7 Oct 2021 17:58:42 +0300 Subject: [PATCH] xenvm: drivers: serial: Add consoleio Xen serial driver for Domain 0 This commit adds Xen consoleio serial driver. It is needed to receive kernel messages from Zephyr in case it runs as Xen privileged domain (Dom0). There is no console ring buffer for such domain, so regular uart_hvc_xen driver can not be used (privileged domain input/output are possible only through consoleio interface). Signed-off-by: Dmytro Firsov --- CODEOWNERS | 1 + boards/arm64/xenvm/Kconfig.defconfig | 6 +++ drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig.xen | 19 +++++++-- drivers/serial/uart_hvc_xen_consoleio.c | 55 +++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 drivers/serial/uart_hvc_xen_consoleio.c 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);