|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH 1/2] plat/xen: Split emergency and hypervisor console
Hey Sharan,
On 12.02.19, 18:48, "Sharan Santhanam" <Sharan.Santhanam@xxxxxxxxx> wrote:
Hello Simon,
Please find the comments inline.
I think the console in the xen platform is inspired from the kvm
platform. Some of the issue we have here might be common across both the
platforms. I wouldn't mind if we were to take this patch as such and fix
the console interface on the both platform in a separate series.
Yes, I agree. I actually was using the same style as we have for KVM, but it is
indeed not the best. I think this is not critical but let's do it. KVM we
should fix later by using this as an example.
Thanks & Regards
Sharan
Thanks,
Simon
On 2/11/19 3:53 PM, Simon Kuenzer wrote:
> Splits the two console implemetations (hvc, emergency) from each other.
> Similar to plat/kvm, a console option menu is populated in the platform
> configuration where each console can be individually selected as output
> for kernel or debug messages. Because hvc is currently not yet supported
> on Arm32, we set the debug console as default output on Arm32.
>
> Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> ---
> plat/xen/Config.uk | 34 ++++-
> plat/xen/Makefile.uk | 6 +
> plat/xen/console.c | 254
++++++----------------------------
> plat/xen/emg_console.c | 87 ++++++++++++
> plat/xen/hv_console.c | 252
+++++++++++++++++++++++++++++++++
> plat/xen/include/common/console.h | 9 +-
> plat/xen/include/common/emg_console.h | 45 ++++++
> plat/xen/include/common/hv_console.h | 49 +++++++
> plat/xen/shutdown.c | 2 +-
> plat/xen/x86/setup.c | 4 +-
> 10 files changed, 514 insertions(+), 228 deletions(-)
> create mode 100644 plat/xen/emg_console.c
> create mode 100644 plat/xen/hv_console.c
> create mode 100644 plat/xen/include/common/emg_console.h
> create mode 100644 plat/xen/include/common/hv_console.h
>
> diff --git a/plat/xen/Config.uk b/plat/xen/Config.uk
> index 9cfe90a2..a29e0ff9 100644
> --- a/plat/xen/Config.uk
> +++ b/plat/xen/Config.uk
> @@ -10,14 +10,36 @@ menuconfig PLAT_XEN
> Create a Unikraft image that runs as a Xen guest
>
> if (PLAT_XEN)
> - config XEN_DBGEMERGENCY
> - bool "Emergency console for debug output"
> +menu "Console Options"
> +
> +config XEN_KERNEL_HV_CONSOLE
> + bool "Hypervisor console for kernel prints"
> + default y
> + depends on ARCH_X86_64
> + help
> + Send kernel messages to the hypervisor console.
> +
> +config XEN_KERNEL_EMG_CONSOLE
> + bool "Emergency console for kernel prints"
> + default y if ARCH_ARM_32
> default n
> help
> - Send debug messages to the emergency console
> - instead of the hypervisor console. When this
> - option is enabled the hypervisor console is used
> - for kernel messages only.
> + Send kernel messages to the emergency console.
> +
> +config XEN_DEBUG_HV_CONSOLE
> + bool "Hypervisor console for debug prints"
> + default y
> + depends on ARCH_X86_64
> + help
> + Send debug messages to the hypervisor console.
> +
> +config XEN_DEBUG_EMG_CONSOLE
> + bool "Emergency console for debug prints"
> + default y if ARCH_ARM_32
> + default n
> + help
> + Send debug messages to the emergency console.
> +endmenu
>
> config XEN_GNTTAB
> bool "Grant table support"
> diff --git a/plat/xen/Makefile.uk b/plat/xen/Makefile.uk
> index 3439a0d9..7a3fcc93 100644
> --- a/plat/xen/Makefile.uk
> +++ b/plat/xen/Makefile.uk
> @@ -70,6 +70,12 @@ LIBXENPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
$(LIBXENPLAT_BASE)/arm/hypercalls64.S
>
> LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/lcpu.c
> LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/console.c
> +ifeq ($(findstring y,$(CONFIG_XEN_KERNEL_HV_CONSOLE)
$(CONFIG_XEN_DEBUG_HV_CONSOLE)),y)
> +LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/hv_console.c
LIBXENPLAT_SRCS-$(CONFIG_ARCH_X86_64)
> +endif
> +ifeq ($(findstring y,$(CONFIG_XEN_KERNEL_EMG_CONSOLE)
$(CONFIG_XEN_DEBUG_EMG_CONSOLE)),y)
> +LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/emg_console.c
> +endif
> LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/shutdown.c
> LIBXENPLAT_SRCS-y += $(LIBXENPLAT_BASE)/events.c
>
> diff --git a/plat/xen/console.c b/plat/xen/console.c
> index a70ec5ff..ed594004 100644
> --- a/plat/xen/console.c
> +++ b/plat/xen/console.c
> @@ -2,7 +2,8 @@
> /*
> * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> *
> - * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights
reserved.
> + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
> + * All rights reserved.
> *
> * Redistribution and use in source and binary forms, with or without
> * modification, are permitted provided that the following conditions
> @@ -32,210 +33,38 @@
> * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
> */
>
> -/*
> - * Some of this code was ported from Mini-OS:
> - * console/xencons_ring.c and console/console.c
> - */
> -/*
> -
****************************************************************************
> - * (C) 2006 - Grzegorz Milos - Cambridge University
> -
****************************************************************************
> - *
> - * File: console.h
> - * Author: Grzegorz Milos
> - * Changes:
> - *
> - * Date: Mar 2006
> - *
> - * Environment: Xen Minimal OS
> - * Description: Console interface.
> - *
> - * Handles console I/O. Defines printk.
> - *
> -
****************************************************************************
> - * Permission is hereby granted, free of charge, to any person obtaining
a copy
> - * of this software and associated documentation files (the "Software"),
to
> - * deal in the Software without restriction, including without
limitation the
> - * rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or
> - * sell copies of the Software, and to permit persons to whom the
Software is
> - * furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be
included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE
> - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING
> - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> - * DEALINGS IN THE SOFTWARE.
> - */
> -
> -#include <inttypes.h>
> -#include <string.h>
> +#include <uk/config.h>
> #include <uk/plat/console.h>
> +#include <string.h>
> #include <uk/arch/lcpu.h>
> -#include <uk/assert.h>
> #include <uk/essentials.h>
> -#include <uk/config.h>
> -
> -#include <common/console.h>
> -#include <common/events.h>
> -#include <common/hypervisor.h>
> -#include <xen/xen.h>
>
> -#if (defined __X86_32__) || (defined __X86_64__)
> -#include <xen-x86/setup.h>
> -#include <xen-x86/mm.h>
> -#if defined __X86_32__
> -#include <xen-x86/hypercall32.h>
> -#elif defined __X86_64__
> -#include <xen-x86/hypercall64.h>
> +#if (CONFIG_XEN_KERNEL_HV_CONSOLE || CONFIG_XEN_DEBUG_HV_CONSOLE)
> +#include <common/hv_console.h>
> #endif
> -#elif (defined __ARM_32__) || (defined __ARM_64__)
> -#include <xen-arm/mm.h>
> -#include <xen-arm/hypercall.h>
> +#if (CONFIG_XEN_KERNEL_EMG_CONSOLE || CONFIG_XEN_DEBUG_EMG_CONSOLE)
> +#include <common/emg_console.h>
> #endif
> -#include <xen/io/console.h>
> -#include <xen/io/protocols.h>
> -#include <xen/io/ring.h>
> -#ifndef CONFIG_PARAVIRT
> -#include <xen/hvm/params.h>
> -#endif
> -
> -static struct xencons_interface *console_ring;
> -static uint32_t console_evtchn;
> -static int console_ready;
>
> -#ifdef CONFIG_PARAVIRT
> -void _libxenplat_prepare_console(void)
> +void prepare_console(void)
> {
> - console_ring = mfn_to_virt(HYPERVISOR_start_info->console.domU.mfn);
> - console_evtchn = HYPERVISOR_start_info->console.domU.evtchn;
> -}
> -#else
> -void _libxenplat_prepare_console(void)
> -{
> - /* NOT IMPLEMENTED YET */
> -}
> +#if (CONFIG_XEN_KERNEL_HV_CONSOLE || CONFIG_XEN_DEBUG_HV_CONSOLE)
> + hv_console_prepare();
> #endif
> -
> -#if CONFIG_XEN_DBGEMERGENCY
> -static int emergency_output(const char *str, unsigned int len)
> -{
> - int rc;
> -
> - rc = HYPERVISOR_console_io(CONSOLEIO_write, len, DECONST(char *, str));
> - if (unlikely(rc < 0))
> - return rc;
> - return len;
> -}
> -#endif
> -
> -/*
> - * hvconsole_output can operate in two modes: buffered and initialized.
> - * The buffered mode is automatically activated after
> - * _libxenplat_prepare_console() was called and we know where the
console ring
> - * is. The output string is put to the console ring until the ring is
full. Any
> - * further characters are discarded. Since the event channel is not
initialized
> - * yet, the backend is not notified. This mode is introduced to support
early
> - * printing, even before events are not initialized.
> - * _libxenplat_init_console() finalizes the initialization and enables
> - * the event channel. From now on, the console backend is notified
whenever
> - * we put characters on the console ring. Whenever this ring is full and
there
> - * are still characters that should be printed, we are entering a busy
loop and
> - * wait for the backend to make us space again. Of course this is slow:
do not
> - * print so much! ;-)
> - */
> -static int hvconsole_output(const char *str, unsigned int len)
> -{
> - unsigned int sent = 0;
> - XENCONS_RING_IDX cons, prod;
> -
> - if (unlikely(!console_ring))
> - return sent;
> -
> -retry:
> - cons = console_ring->out_cons;
> - prod = console_ring->out_prod;
> -
> - mb(); /* make sure we have cons & prod before touching the ring */
> - UK_BUGON((prod - cons) > sizeof(console_ring->out));
> -
> - while ((sent < len) && ((prod - cons) < sizeof(console_ring->out))) {
> - if (str[sent] == '\n') {
> - /* prepend '\r' for converting '\n' to '\r''\n' */
> - if ((prod + 1 - cons) >= sizeof(console_ring->out))
> - break; /* not enough space for '\r' and '\n'! */
> -
> - console_ring->out[MASK_XENCONS_IDX(prod++,
> - console_ring->out)] =
> - '\r';
> - }
> -
> - console_ring->out[MASK_XENCONS_IDX(prod++, console_ring->out)] =
> - str[sent];
> - sent++;
> - }
> - wmb(); /* ensure characters are written before increasing out_prod */
> - console_ring->out_prod = prod;
> -
> - /* Is the console fully initialized?
> - * Are we able to notify the backend?
> - */
> - if (likely(console_ready && console_evtchn)) {
> - notify_remote_via_evtchn(console_evtchn);
> -
> - /* There are still bytes left to send out? If yes, do not
> - * discard them, retry sending (enters busy waiting)
> - */
> - if (sent < len)
> - goto retry;
> - }
> - return sent;
> }
>
> -static void hvconsole_input(evtchn_port_t port __unused,
> - struct __regs *regs __unused,
> - void *data __unused)
> +void flush_console(void)
> {
> - /* NOT IMPLEMENTED YET */
> -}
> -
> -void hvconsole_flush(void)
> -{
> - struct xencons_interface *intf;
> -
> - if (!console_ready)
> - return;
> -
> - intf = console_ring;
> - if (unlikely(!intf))
> - return;
> -
> - while (intf->out_cons < intf->out_prod)
> - barrier();
> +#if (CONFIG_XEN_KERNEL_HV_CONSOLE || CONFIG_XEN_DEBUG_HV_CONSOLE)
> + hv_console_flush();
> +#endif
> }
>
> -void _libxenplat_init_console(void)
> +void init_console(void)
> {
> - int err;
> -
> - UK_ASSERT(console_ring != NULL);
> -
> - uk_pr_debug("hvconsole @ %p (evtchn: %"PRIu32")\n",
> - console_ring, console_evtchn);
> -
> - err = bind_evtchn(console_evtchn, hvconsole_input, NULL);
> - if (err <= 0)
> - UK_CRASH("Failed to bind event channel for hvconsole: %i\n",
> - err);
> - unmask_evtchn(console_evtchn);
> -
> - console_ready = 1; /* enable notification of backend */
> - /* flush queued output */
> - notify_remote_via_evtchn(console_evtchn);
> +#if (CONFIG_XEN_KERNEL_HV_CONSOLE || CONFIG_XEN_DEBUG_HV_CONSOLE)
> + hv_console_init();
> +#endif
> }
>
> int ukplat_coutd(const char *str, unsigned int len)
> @@ -243,41 +72,36 @@ int ukplat_coutd(const char *str, unsigned int len)
> if (unlikely(len == 0))
> len = strnlen(str, len);
>
> -#if CONFIG_XEN_DBGEMERGENCY
> - return emergency_output(str, len);
> -#else
> - return hvconsole_output(str, len);
> +#if CONFIG_XEN_DEBUG_EMG_CONSOLE
Error check missing on the console driver
> + emg_console_output(str, len);
> +#endif
> +#if CONFIG_XEN_DEBUG_HV_CONSOLE
Error check missing on the console driver
> + hv_console_output(str, len);
> #endif
> + return len;
> }
>
> -int ukplat_coutk(const char *str __unused, unsigned int len __unused)
> +int ukplat_coutk(const char *str, unsigned int len)
> {
> if (unlikely(len == 0))
> len = strnlen(str, len);
>
> - return hvconsole_output(str, len);
> +#if CONFIG_XEN_KERNEL_EMG_CONSOLE
Error check missing on the console driver
> + emg_console_output(str, len);
> +#endif
> +#if CONFIG_XEN_KERNEL_HV_CONSOLE
Error check missing on the console driver
> + hv_console_output(str, len);
> +#endif
> + return len;
> }
>
> -int ukplat_cink(char *str, unsigned int maxlen)
> +int ukplat_cink(char *str __maybe_unused, unsigned int maxlen
__maybe_unused)
> {
> - int read = 0;
> - XENCONS_RING_IDX cons, prod;
> + int ret = 0;
if we don't support HV_CONSOLE should we not report an error
-ENOTSUP.
This is actually a good point. We should probably add the same to the other
functions too.
>
> - cons = console_ring->in_cons;
> - prod = console_ring->in_prod;
> - rmb(); /* make sure in_cons, in_prod are read before enqueuing */
> - UK_BUGON((prod - cons) > sizeof(console_ring->in));
> -
> - while (cons != prod && maxlen > 0) {
> - *(str + read) = *(console_ring->in+
> - MASK_XENCONS_IDX(cons, console_ring->in));
> - read++;
> - cons++;
> - maxlen--;
> - }
> -
> - wmb(); /* ensure finished operation before updating in_cons */
> - console_ring->in_cons = cons;
> +#if CONFIG_XEN_KERNEL_HV_CONSOLE
> + ret = hv_console_input(str, maxlen);
> +#endif
>
> - return read;
> + return ret;
> }
> diff --git a/plat/xen/emg_console.c b/plat/xen/emg_console.c
> new file mode 100644
> index 00000000..e2e4df6e
> --- /dev/null
> +++ b/plat/xen/emg_console.c
> @@ -0,0 +1,87 @@
> +/* SPDX-License-Identifier: BSD-3-Clause and MIT */
> +/*
> + * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> + *
> + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in the
> + * documentation and/or other materials provided with the
distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived
from
> + * this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + *
> + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
> + */
> +
> +/*
> + * Some of this code was ported from Mini-OS:
> + * console/xencons_ring.c and console/console.c
> + */
> +/*
> +
****************************************************************************
> + * (C) 2006 - Grzegorz Milos - Cambridge University
> +
****************************************************************************
> + *
> + * File: console.h
> + * Author: Grzegorz Milos
> + * Changes:
> + *
> + * Date: Mar 2006
> + *
> + * Environment: Xen Minimal OS
> + * Description: Console interface.
> + *
> + * Handles console I/O. Defines printk.
> + *
> +
****************************************************************************
> + * Permission is hereby granted, free of charge, to any person obtaining
a copy
> + * of this software and associated documentation files (the "Software"),
to
> + * deal in the Software without restriction, including without
limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or
> + * sell copies of the Software, and to permit persons to whom the
Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be
included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include <uk/essentials.h>
> +#include <common/hypervisor.h>
> +
> +int emg_console_output(const char *str, unsigned int len)
> +{
> + int rc;
> +
> + rc = HYPERVISOR_console_io(CONSOLEIO_write, len, DECONST(char *, str));
> + if (unlikely(rc < 0))
> + return rc;
> + return len;
> +}
> diff --git a/plat/xen/hv_console.c b/plat/xen/hv_console.c
> new file mode 100644
> index 00000000..28f86f25
> --- /dev/null
> +++ b/plat/xen/hv_console.c
> @@ -0,0 +1,252 @@
> +/* SPDX-License-Identifier: BSD-3-Clause and MIT */
> +/*
> + * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> + *
> + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in the
> + * documentation and/or other materials provided with the
distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived
from
> + * this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + *
> + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
> + */
> +
> +/*
> + * Some of this code was ported from Mini-OS:
> + * console/xencons_ring.c and console/console.c
> + */
> +/*
> +
****************************************************************************
> + * (C) 2006 - Grzegorz Milos - Cambridge University
> +
****************************************************************************
> + *
> + * File: console.h
> + * Author: Grzegorz Milos
> + * Changes:
> + *
> + * Date: Mar 2006
> + *
> + * Environment: Xen Minimal OS
> + * Description: Console interface.
> + *
> + * Handles console I/O. Defines printk.
> + *
> +
****************************************************************************
> + * Permission is hereby granted, free of charge, to any person obtaining
a copy
> + * of this software and associated documentation files (the "Software"),
to
> + * deal in the Software without restriction, including without
limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or
> + * sell copies of the Software, and to permit persons to whom the
Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be
included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include <inttypes.h>
> +#include <string.h>
> +#include <uk/plat/console.h>
> +#include <uk/arch/lcpu.h>
> +#include <uk/assert.h>
> +#include <uk/essentials.h>
> +#include <uk/config.h>
> +
> +#include <common/hv_console.h>
> +#include <common/events.h>
> +#include <common/hypervisor.h>
> +#include <xen/xen.h>
> +
> +#if (defined __X86_32__) || (defined __X86_64__)
> +#include <xen-x86/setup.h>
> +#include <xen-x86/mm.h>
> +#if defined __X86_32__
> +#include <xen-x86/hypercall32.h>
> +#elif defined __X86_64__
> +#include <xen-x86/hypercall64.h>
> +#endif
> +#elif (defined __ARM_32__) || (defined __ARM_64__)
> +#include <xen-arm/mm.h>
> +#include <xen-arm/hypercall.h>
> +#endif
> +#include <xen/io/console.h>
> +#include <xen/io/protocols.h>
> +#include <xen/io/ring.h>
> +#ifndef CONFIG_PARAVIRT
> +#include <xen/hvm/params.h>
> +#endif
> +
> +static struct xencons_interface *console_ring;
> +static uint32_t console_evtchn;
> +static int console_ready;
> +
> +#ifdef CONFIG_PARAVIRT
> +void hv_console_prepare(void)
> +{
> + console_ring = mfn_to_virt(HYPERVISOR_start_info->console.domU.mfn);
> + console_evtchn = HYPERVISOR_start_info->console.domU.evtchn;
> +}
> +#else
> +void hv_console_prepare(void)
> +{
> + /* NOT IMPLEMENTED YET */
> +}
> +#endif
> +
> +/*
> + * hv_console_output operates in two modes: buffered and initialized.
> + * The buffered mode is automatically activated after
> + * _libxenplat_prepare_console() was called and we know where the
console ring
> + * is. The output string is put to the console ring until the ring is
full. Any
> + * further characters are discarded. Since the event channel is not
initialized
> + * yet, the backend is not notified. This mode is introduced to support
early
> + * printing, even before events are not initialized.
> + * _libxenplat_init_console() finalizes the initialization and enables
> + * the event channel. From now on, the console backend is notified
whenever
> + * we put characters on the console ring. Whenever this ring is full and
there
> + * are still characters that should be printed, we are entering a busy
loop and
> + * wait for the backend to make us space again. Of course this is slow:
do not
> + * print so much! ;-)
> + */
> +int hv_console_output(const char *str, unsigned int len)
> +{
> + unsigned int sent = 0;
> + XENCONS_RING_IDX cons, prod;
> +
> + if (unlikely(!console_ring))
> + return sent;
> +
> +retry:
> + cons = console_ring->out_cons;
> + prod = console_ring->out_prod;
> +
> + mb(); /* make sure we have cons & prod before touching the ring */
> + UK_BUGON((prod - cons) > sizeof(console_ring->out));
> +
> + while ((sent < len) && ((prod - cons) < sizeof(console_ring->out))) {
> + if (str[sent] == '\n') {
> + /* prepend '\r' for converting '\n' to '\r''\n' */
> + if ((prod + 1 - cons) >= sizeof(console_ring->out))
> + break; /* not enough space for '\r' and '\n'! */
> +
> + console_ring->out[MASK_XENCONS_IDX(prod++,
> + console_ring->out)] =
> + '\r';
> + }
> +
> + console_ring->out[MASK_XENCONS_IDX(prod++, console_ring->out)] =
> + str[sent];
> + sent++;
> + }
> + wmb(); /* ensure characters are written before increasing out_prod */
> + console_ring->out_prod = prod;
> +
> + /* Is the console fully initialized?
> + * Are we able to notify the backend?
> + */
> + if (likely(console_ready && console_evtchn)) {
> + notify_remote_via_evtchn(console_evtchn);
> +
> + /* There are still bytes left to send out? If yes, do not
> + * discard them, retry sending (enters busy waiting)
> + */
> + if (sent < len)
> + goto retry;
> + }
> + return sent;
> +}
> +
> +void hv_console_flush(void)
> +{
> + struct xencons_interface *intf;
> +
> + if (!console_ready)
> + return;
> +
> + intf = console_ring;
> + if (unlikely(!intf))
> + return;
> +
> + while (intf->out_cons < intf->out_prod)
> + barrier();
> +}
> +
> +int hv_console_input(char *str, unsigned int maxlen)
> +{
> + int read = 0;
> + XENCONS_RING_IDX cons, prod;
> +
> + cons = console_ring->in_cons;
> + prod = console_ring->in_prod;
> + rmb(); /* make sure in_cons, in_prod are read before enqueuing */
> + UK_BUGON((prod - cons) > sizeof(console_ring->in));
> +
> + while (cons != prod && maxlen > 0) {
> + *(str + read) = *(console_ring->in+
> + MASK_XENCONS_IDX(cons, console_ring->in));
> + read++;
> + cons++;
> + maxlen--;
> + }
> +
> + wmb(); /* ensure finished operation before updating in_cons */
> + console_ring->in_cons = cons;
> +
> + return read;
> +}
> +
> +static void hv_console_event(evtchn_port_t port __unused,
> + struct __regs *regs __unused,
> + void *data __unused)
> +{
> + /* NOT IMPLEMENTED YET */
> +}
> +
> +void hv_console_init(void)
> +{
> + int err;
> +
> + UK_ASSERT(console_ring != NULL);
> +
> + uk_pr_debug("hv_console @ %p (evtchn: %"PRIu32")\n",
> + console_ring, console_evtchn);
> +
> + err = bind_evtchn(console_evtchn, hv_console_event, NULL);
> + if (err <= 0)
> + UK_CRASH("Failed to bind event channel for hv_console: %i\n",
> + err);
> + unmask_evtchn(console_evtchn);
> +
> + console_ready = 1; /* enable notification of backend */
> + /* flush queued output */
> + notify_remote_via_evtchn(console_evtchn);
> +}
> diff --git a/plat/xen/include/common/console.h
b/plat/xen/include/common/console.h
> index b4f1b51e..23c6b32e 100644
> --- a/plat/xen/include/common/console.h
> +++ b/plat/xen/include/common/console.h
> @@ -2,7 +2,8 @@
> /*
> * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> *
> - * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights
reserved.
> + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
> + * All rights reserved.
> *
> * Redistribution and use in source and binary forms, with or without
> * modification, are permitted provided that the following conditions
> @@ -38,14 +39,14 @@
> /* keeps buffering console message
> * (on PV: start_info need to be loaded)
> */
> -void _libxenplat_prepare_console(void);
> +void prepare_console(void);
>
> /* initializes the console, sends out buffered messages
> * (event system has to be initialized)
> */
> -void _libxenplat_init_console(void);
> +void init_console(void);
>
>
> -void hvconsole_flush(void);
> +void flush_console(void);
>
> #endif /* __CONSOLE_H__ */
> diff --git a/plat/xen/include/common/emg_console.h
b/plat/xen/include/common/emg_console.h
> new file mode 100644
> index 00000000..b9309321
> --- /dev/null
> +++ b/plat/xen/include/common/emg_console.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: BSD-3-Clause */
> +/*
> + * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> + *
> + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in the
> + * documentation and/or other materials provided with the
distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived
from
> + * this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + *
> + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
> + */
> +
> +#ifndef __XEN_EMGCONSOLE_H__
> +#define __XEN_EMGCONSOLE_H__
> +
> +/*
> + * NOTE: Do not use these functions directly. They are for internal use.
> + * Use defintions in console.h instead.
s/defintions/definitions
I prefer to report an compiler error using #error if the user were to
include the file directly rather than a note.
Okay, this is fine with me. Let's also move hv_console.h and emg_console.h to
the directory where the dot-c files are. This should minimize the confusion.
> + */
> +int emg_console_output(const char *str, unsigned int len);
> +
> +#endif /* __XEN_EMGCONSOLE_H__ */
> diff --git a/plat/xen/include/common/hv_console.h
b/plat/xen/include/common/hv_console.h
> new file mode 100644
> index 00000000..10de9271
> --- /dev/null
> +++ b/plat/xen/include/common/hv_console.h
> @@ -0,0 +1,49 @@
> +/* SPDX-License-Identifier: BSD-3-Clause */
> +/*
> + * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> + *
> + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in the
> + * documentation and/or other materials provided with the
distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived
from
> + * this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + *
> + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
> + */
> +
> +#ifndef __XEN_HVCONSOLE_H__
> +#define __XEN_HVCONSOLE_H__
> +
> +/*
> + * NOTE: Do not use these functions directly. They are for internal use.
> + * Use defintions in console.h instead.
s/defintions/definitions
I prefer to report an compiler error using #error if the user were to
include the file directly rather than a note.
> + */
> +void hv_console_prepare(void);
> +void hv_console_init(void);
> +int hv_console_output(const char *str, unsigned int len);
> +void hv_console_flush(void);
> +int hv_console_input(char *str, unsigned int maxlen);
> +
> +#endif /* __XEN_HVCONSOLE_H__ */
> diff --git a/plat/xen/shutdown.c b/plat/xen/shutdown.c
> index 272ece47..c7bf12d7 100644
> --- a/plat/xen/shutdown.c
> +++ b/plat/xen/shutdown.c
> @@ -66,7 +66,7 @@ void ukplat_terminate(enum ukplat_gstate request)
> break;
> }
>
> - hvconsole_flush();
> + flush_console();
>
> for (;;) {
> struct sched_shutdown sched_shutdown = { .reason =
reason };
> diff --git a/plat/xen/x86/setup.c b/plat/xen/x86/setup.c
> index 60a9f9e6..3c5631d3 100644
> --- a/plat/xen/x86/setup.c
> +++ b/plat/xen/x86/setup.c
> @@ -173,7 +173,7 @@ void _libxenplat_x86entry(void *start_info)
> _init_traps();
> _init_cpufeatures();
> HYPERVISOR_start_info = (start_info_t *)start_info;
> - _libxenplat_prepare_console(); /* enables buffering for console */
> + prepare_console(); /* enables buffering for console */
>
> uk_pr_info("Entering from Xen (x86, PV)...\n");
>
> @@ -191,7 +191,7 @@ void _libxenplat_x86entry(void *start_info)
>
> _init_mem();
>
> - _libxenplat_init_console();
> + init_console();
>
> ukplat_entry_argp(CONFIG_UK_NAME, cmdline, MAX_CMDLINE_SIZE);
> }
>
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |