[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 1/2] plat/xen: Split emergency and hypervisor console



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
+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
+       emg_console_output(str, len);
+#endif
+#if CONFIG_XEN_DEBUG_HV_CONSOLE
+       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
+       emg_console_output(str, len);
+#endif
+#if CONFIG_XEN_KERNEL_HV_CONSOLE
+       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;
 
-       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.
+ */
+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.
+ */
+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);
 }
-- 
2.11.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.