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

[Minios-devel] [UNIKRAFT PATCH] plat/xen: Add console support for x86_64



Console support is ported from Mini-OS. It currently
works for x86_64 only.

Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
---
 plat/xen/Config.uk                |   4 +
 plat/xen/console.c                | 162 ++++++++++++++++++++++++++++++++++++--
 plat/xen/include/common/console.h |  48 +++++++++++
 plat/xen/x86/setup.c              |  10 ++-
 4 files changed, 216 insertions(+), 8 deletions(-)
 create mode 100644 plat/xen/include/common/console.h

diff --git a/plat/xen/Config.uk b/plat/xen/Config.uk
index 93fa923..f988d06 100644
--- a/plat/xen/Config.uk
+++ b/plat/xen/Config.uk
@@ -5,8 +5,12 @@ menuconfig PLAT_XEN
        select LIBUKDEBUG
        select LIBNOLIBC if !HAVE_LIBC
        select LIBFDT if ARCH_ARM_32
+       select XEN_DBGEMERGENCY if ARCH_ARM_32
        help
                 Create a Unikraft image that runs as a Xen guest
 
 if (PLAT_XEN)
+       config XEN_DBGEMERGENCY
+       bool "Emergency console for debug output"
+       default n
 endif
diff --git a/plat/xen/console.c b/plat/xen/console.c
index 67f8513..f2f0e78 100644
--- a/plat/xen/console.c
+++ b/plat/xen/console.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
+/* SPDX-License-Identifier: BSD-3-Clause and MIT */
 /*
  * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
  *
@@ -32,38 +32,188 @@
  * 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 <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>
+#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
 
-int ukplat_coutd(const char *str, unsigned int len)
+static struct xencons_interface *console_ring;
+static uint32_t console_evtchn;
+static int console_ready;
+
+#ifdef CONFIG_PARAVIRT
+void _libxenplat_prepare_console(void)
 {
-       int rc;
+       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 */
+}
+#endif
 
-       if (unlikely(len == 0))
-               len = strnlen(str, len);
+#if 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
+
+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;
+
+       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') {
+                       /* Convert: '\n' -> '\r''\n' */
+                       console_ring->out[MASK_XENCONS_IDX(prod++,
+                                                          console_ring->out)] =
+                               '\r';
+                       if ((prod - cons) >= sizeof(console_ring->out))
+                               break; /* no more space left */
+               }
+
+               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;
+
+       if (likely(console_ready && console_evtchn))
+               notify_remote_via_evtchn(console_evtchn);
+       return sent;
+}
+
+static void hvconsole_input(evtchn_port_t port __unused,
+                           struct __regs *regs __unused,
+                           void *data __unused)
+{
+       /* NOT IMPLEMENTED YET */
+}
+
+
+void _libxenplat_init_console(void)
+{
+       int err;
+
+       UK_ASSERT(console_ring != NULL);
+
+       uk_printd(DLVL_EXTRA, "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);
+}
+
+int ukplat_coutd(const char *str, unsigned int len)
+{
+       if (unlikely(len == 0))
+               len = strnlen(str, len);
+
+#if XEN_DBGEMERGENCY
+       return emergency_output(str, len);
+#else
+       return hvconsole_output(str, len);
+#endif
+}
 
 int ukplat_coutk(const char *str __unused, unsigned int len __unused)
 {
-       return 0;
+       if (unlikely(len == 0))
+               len = strnlen(str, len);
+
+       return hvconsole_output(str, len);
 }
 
 int ukplat_cink(char *str __unused, unsigned int maxlen __unused)
diff --git a/plat/xen/include/common/console.h 
b/plat/xen/include/common/console.h
new file mode 100644
index 0000000..c51c69b
--- /dev/null
+++ b/plat/xen/include/common/console.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
+ *
+ * Copyright (c) 2017, NEC Europe Ltd., 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 __CONSOLE_H__
+#define __CONSOLE_H__
+
+/* keeps buffering console message
+ * (on PV: start_info need to be loaded)
+ */
+void _libxenplat_prepare_console(void);
+
+/* initializes the console, sends out buffered messages
+ * (event system has to be initialized)
+ */
+void _libxenplat_init_console(void);
+
+#endif /* __CONSOLE_H__ */
diff --git a/plat/xen/x86/setup.c b/plat/xen/x86/setup.c
index 81cd584..cf8bad2 100644
--- a/plat/xen/x86/setup.c
+++ b/plat/xen/x86/setup.c
@@ -76,6 +76,7 @@
 #include <uk/plat/bootstrap.h>
 
 #include <xen/xen.h>
+#include <common/console.h>
 #include <common/events.h>
 #if LIBUKSCHED
 #include <common/sched.h>
@@ -171,12 +172,15 @@ void _libxenplat_x86entry(void *start_info) __noreturn;
 
 void _libxenplat_x86entry(void *start_info)
 {
-       uk_printd(DLVL_INFO, "Entering from Xen (x86, PV)...\n");
-
        _init_traps();
        _init_cpufeatures();
        HYPERVISOR_start_info = (start_info_t *)start_info;
+       _libxenplat_prepare_console(); /* enables buffering for console */
+
+       uk_printd(DLVL_INFO, "Entering from Xen (x86, PV)...\n");
+
        _init_shared_info(); /* remaps shared info */
+
        strncpy(cmdline, (char *)HYPERVISOR_start_info->cmd_line,
                MAX_CMDLINE_SIZE);
 
@@ -192,5 +196,7 @@ void _libxenplat_x86entry(void *start_info)
 
        _init_mem();
 
+       _libxenplat_init_console();
+
        ukplat_entry_argp(UK_NAME, cmdline, MAX_CMDLINE_SIZE);
 }
-- 
2.7.4


_______________________________________________
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®.