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

[PATCH v1] xen/riscv: add initialization support for virtual SBI UART (vSBI UART)



This is the first step toward supporting a vSBI UART.

The implementation checks for the presence of the "vsbi_uart" property
in the device tree. If present, the vSBI UART is initialized by:
- Allocating a structure that holds Xen console rings and character
  buffers.
- Initializing the vSBI UART spinlock.

This commit introduces the following:
- domain_vsbi_uart_init() and domain_vsbi_uart_deinit() functions.
- A new arch_kernel_info structure with a vsbi_uart member.
- A vsbi_uart structure to hold information related to the vSBI
  driver, including:
  - Whether the vSBI UART backend is in the domain or in Xen.
  - If the backend is in Xen: details such as ring buffer, ring page,
    Xen console ring indexes, and character buffers.
  - A spinlock for synchronization.

Also, introduce init_vuart() which is going to be called by dom0less
generic code during guest domain construction.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
This patch is independent from other RISC-V connected patch series, but it could
be a merge conflict with some patches of other patch series.
---
 xen/arch/riscv/Makefile                |  2 +
 xen/arch/riscv/dom0less-build.c        | 30 +++++++++++++
 xen/arch/riscv/include/asm/domain.h    |  4 ++
 xen/arch/riscv/include/asm/kernel.h    | 21 +++++++++
 xen/arch/riscv/include/asm/vsbi-uart.h | 58 ++++++++++++++++++++++++
 xen/arch/riscv/vsbi-uart.c             | 62 ++++++++++++++++++++++++++
 6 files changed, 177 insertions(+)
 create mode 100644 xen/arch/riscv/dom0less-build.c
 create mode 100644 xen/arch/riscv/include/asm/kernel.h
 create mode 100644 xen/arch/riscv/include/asm/vsbi-uart.h
 create mode 100644 xen/arch/riscv/vsbi-uart.c

diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index d882c57528..89a1897228 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -1,5 +1,6 @@
 obj-y += aplic.o
 obj-y += cpufeature.o
+obj-y += dom0less-build.o
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 obj-y += entry.o
 obj-y += intc.o
@@ -14,6 +15,7 @@ obj-y += stubs.o
 obj-y += time.o
 obj-y += traps.o
 obj-y += vm_event.o
+obj-y += vsbi-uart.o
 
 $(TARGET): $(TARGET)-syms
        $(OBJCOPY) -O binary -S $< $@
diff --git a/xen/arch/riscv/dom0less-build.c b/xen/arch/riscv/dom0less-build.c
new file mode 100644
index 0000000000..afce2f606d
--- /dev/null
+++ b/xen/arch/riscv/dom0less-build.c
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <xen/bug.h>
+#include <xen/device_tree.h>
+#include <xen/errno.h>
+#include <xen/fdt-kernel.h>
+#include <xen/init.h>
+#include <xen/sched.h>
+
+#include <asm/vsbi-uart.h>
+
+int __init init_vuart(struct domain *d, struct kernel_info *kinfo,
+                      const struct dt_device_node *node)
+{
+    int rc = -EINVAL;
+
+    kinfo->arch.vsbi_uart = dt_property_read_bool(node, "vsbi_uart");
+
+    if ( kinfo->arch.vsbi_uart )
+    {
+        rc = domain_vsbi_uart_init(d, NULL);
+        if ( rc < 0 )
+            return rc;
+    }
+
+    if ( rc )
+        panic("%s: what a domain should use as an UART?\n", __func__);
+
+    return rc;
+}
diff --git a/xen/arch/riscv/include/asm/domain.h 
b/xen/arch/riscv/include/asm/domain.h
index c3d965a559..c312827d18 100644
--- a/xen/arch/riscv/include/asm/domain.h
+++ b/xen/arch/riscv/include/asm/domain.h
@@ -5,6 +5,8 @@
 #include <xen/xmalloc.h>
 #include <public/hvm/params.h>
 
+#include <asm/vsbi-uart.h>
+
 struct hvm_domain
 {
     uint64_t              params[HVM_NR_PARAMS];
@@ -18,6 +20,8 @@ struct arch_vcpu {
 
 struct arch_domain {
     struct hvm_domain hvm;
+
+    struct vsbi_uart vsbi_uart;
 };
 
 #include <xen/sched.h>
diff --git a/xen/arch/riscv/include/asm/kernel.h 
b/xen/arch/riscv/include/asm/kernel.h
new file mode 100644
index 0000000000..15c13da158
--- /dev/null
+++ b/xen/arch/riscv/include/asm/kernel.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef ASM__RISCV__KERNEL_H
+#define ASM__RISCV__KERNEL_H
+
+struct arch_kernel_info
+{
+    /* Enable vsbi_uart emulation */
+    bool vsbi_uart;
+};
+
+#endif /* #ifdef ASM__RISCV__KERNEL_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/riscv/include/asm/vsbi-uart.h 
b/xen/arch/riscv/include/asm/vsbi-uart.h
new file mode 100644
index 0000000000..144e3191ff
--- /dev/null
+++ b/xen/arch/riscv/include/asm/vsbi-uart.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef ASM__RISCV__VSBI_UART_H
+#define ASM__RISCV__VSBI_UART_H
+
+#include <xen/spinlock.h>
+#include <xen/stdbool.h>
+
+#include <public/io/console.h>
+
+struct domain;
+struct page_info;
+
+#define VSBI_UART_FIFO_SIZE 32
+#define VSBI_UART_OUT_BUF_SIZE 128
+
+struct vsbi_uart_xen_backend {
+    char in[VSBI_UART_FIFO_SIZE];
+    char out[VSBI_UART_OUT_BUF_SIZE];
+    XENCONS_RING_IDX in_cons, in_prod;
+    XENCONS_RING_IDX out_prod;
+};
+
+struct vsbi_uart {
+    bool backend_in_domain;
+    union {
+        struct {
+            void *ring_buf;
+            struct page_info *ring_page;
+        } dom;
+        struct vsbi_uart_xen_backend *xen;
+    } backend;
+
+    spinlock_t lock;
+};
+
+/*
+ * TODO: we don't support an option that backend is in a domain.
+ *       At the moment, backend is ib Xen.
+ *       This structure should be implemented in the case if backend
+ *       is in a domain.
+ */
+struct vsbi_uart_init_info {
+};
+
+int domain_vsbi_uart_init(struct domain *d , struct vsbi_uart_init_info *info);
+void domain_vsbi_uart_deinit(struct domain *d);
+
+#endif /* ASM__RISCV__VSBI_UART_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/riscv/vsbi-uart.c b/xen/arch/riscv/vsbi-uart.c
new file mode 100644
index 0000000000..5fe617ae30
--- /dev/null
+++ b/xen/arch/riscv/vsbi-uart.c
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <xen/errno.h>
+#include <xen/lib.h>
+#include <xen/mm.h>
+#include <xen/sched.h>
+#include <xen/xmalloc.h>
+
+#include <asm/vsbi-uart.h>
+
+int domain_vsbi_uart_init(struct domain *d, struct vsbi_uart_init_info *info)
+{
+    int rc;
+    struct vsbi_uart *vsbi_uart = &d->arch.vsbi_uart;
+
+    if ( vsbi_uart->backend.dom.ring_buf )
+    {
+        printk("%s: ring_buf != 0\n", __func__);
+        return -EINVAL;
+    }
+
+    /*
+     * info is NULL when the backend is in Xen.
+     * info is != NULL when the backend is in a domain.
+     */
+    if ( info != NULL )
+    {
+        printk("%s: vsbi_uart backend in a domain isn't supported\n", 
__func__);
+        rc = -EOPNOTSUPP;
+        goto out;
+    }
+    else
+    {
+        vsbi_uart->backend_in_domain = false;
+
+        vsbi_uart->backend.xen = xzalloc(struct vsbi_uart_xen_backend);
+        if ( vsbi_uart->backend.xen == NULL )
+        {
+            rc = -ENOMEM;
+            goto out;
+        }
+    }
+
+    spin_lock_init(&vsbi_uart->lock);
+
+    return 0;
+
+out:
+    domain_vsbi_uart_deinit(d);
+
+    return rc;
+}
+
+void domain_vsbi_uart_deinit(struct domain *d)
+{
+    struct vsbi_uart *vsbi_uart = &d->arch.vsbi_uart;
+
+    if ( vsbi_uart->backend_in_domain )
+        printk("%s: backed in a domain isn't supported\n", __func__);
+    else
+        XFREE(vsbi_uart->backend.xen);
+}
-- 
2.49.0




 


Rackspace

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