[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 |