Establish a common UART interface.  Architecture dependent functions
arm_uart_write() and x86's uart_write() do now use an architecture
independent interface uart_write().

x86 now uses the 8250 driver by default, and dynamically selects whether
to use PIO or MMIO-based output.

Signed-off-by: Ralf Ramsauer <[email protected]>
---
 hypervisor/Makefile                    |  2 +-
 hypervisor/arch/arm-common/dbg-write.c | 26 +---------
 hypervisor/arch/x86/Kbuild             |  2 +-
 hypervisor/arch/x86/dbg-write.c        | 32 ++++++++++--
 hypervisor/arch/x86/include/asm/uart.h | 14 -----
 hypervisor/arch/x86/uart.c             | 94 ----------------------------------
 hypervisor/include/jailhouse/uart.h    |  3 ++
 hypervisor/uart.c                      | 38 ++++++++++++++
 8 files changed, 72 insertions(+), 139 deletions(-)
 delete mode 100644 hypervisor/arch/x86/include/asm/uart.h
 delete mode 100644 hypervisor/arch/x86/uart.c
 create mode 100644 hypervisor/uart.c

diff --git a/hypervisor/Makefile b/hypervisor/Makefile
index f08e92d5..865fba64 100644
--- a/hypervisor/Makefile
+++ b/hypervisor/Makefile
@@ -31,7 +31,7 @@ KBUILD_CFLAGS += -include $(obj)/include/jailhouse/config.h
 endif
 
 CORE_OBJECTS = setup.o printk.o paging.o control.o lib.o mmio.o pci.o ivshmem.o
-CORE_OBJECTS += uart-8250.o
+CORE_OBJECTS += uart.o uart-8250.o
 
 define filechk_config_mk
 (                                                                      \
diff --git a/hypervisor/arch/arm-common/dbg-write.c 
b/hypervisor/arch/arm-common/dbg-write.c
index 2a632b52..566c72c6 100644
--- a/hypervisor/arch/arm-common/dbg-write.c
+++ b/hypervisor/arch/arm-common/dbg-write.c
@@ -13,34 +13,10 @@
  */
 
 #include <jailhouse/control.h>
-#include <jailhouse/entry.h>
 #include <jailhouse/printk.h>
-#include <jailhouse/processor.h>
 #include <jailhouse/uart.h>
 #include <asm/uart.h>
 
-static struct uart_chip *uart = NULL;
-
-static void arm_uart_write(const char *msg)
-{
-       char c = 0;
-
-       while (1) {
-               if (c == '\n')
-                       c = '\r';
-               else
-                       c = *msg++;
-               if (!c)
-                       break;
-
-               while (uart->is_busy(uart))
-                       cpu_relax();
-               if (panic_in_progress && panic_cpu != phys_processor_id())
-                       break;
-               uart->write_character(uart, c);
-       }
-}
-
 void arch_dbg_write_init(void)
 {
        unsigned char con_type = CON1_TYPE(system_config->debug_console.flags);
@@ -60,6 +36,6 @@ void arch_dbg_write_init(void)
                uart->virt_clock_reg = hypervisor_header.debug_clock_reg;
                uart->virt_base = hypervisor_header.debug_console_base;
                uart->init(uart);
-               arch_dbg_write = arm_uart_write;
+               arch_dbg_write = uart_write;
        }
 }
diff --git a/hypervisor/arch/x86/Kbuild b/hypervisor/arch/x86/Kbuild
index 99c75e8b..7e86e011 100644
--- a/hypervisor/arch/x86/Kbuild
+++ b/hypervisor/arch/x86/Kbuild
@@ -14,7 +14,7 @@
 
 BUILT_IN_OBJECTS := built-in-amd.o built-in-intel.o
 COMMON_OBJECTS := apic.o dbg-write.o entry.o setup.o control.o mmio.o iommu.o \
-                 paging.o pci.o ioapic.o i8042.o vcpu.o uart.o vga.o ivshmem.o
+                 paging.o pci.o ioapic.o i8042.o vcpu.o vga.o ivshmem.o
 
 always := $(BUILT_IN_OBJECTS)
 
diff --git a/hypervisor/arch/x86/dbg-write.c b/hypervisor/arch/x86/dbg-write.c
index 30ddc908..d8549c53 100644
--- a/hypervisor/arch/x86/dbg-write.c
+++ b/hypervisor/arch/x86/dbg-write.c
@@ -2,9 +2,11 @@
  * Jailhouse, a Linux-based partitioning hypervisor
  *
  * Copyright (c) Siemens AG, 2013-2016
+ * Copyright (c) OTH Regensburg, 2017
  *
  * Authors:
  *  Jan Kiszka <[email protected]>
+ *  Ralf Ramsauer <[email protected]>
  *
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
@@ -12,16 +14,38 @@
 
 #include <jailhouse/control.h>
 #include <jailhouse/printk.h>
-#include <asm/uart.h>
+#include <jailhouse/uart.h>
+#include <asm/io.h>
 #include <asm/vga.h>
 
+static void uart_pio_out(void *address, u32 value)
+{
+       outb(value, (u16)(unsigned long long)address);
+}
+
+static u32 uart_pio_in(void *address)
+{
+       return inb((u16)(unsigned long long)address);
+}
+
 void arch_dbg_write_init(void)
 {
-       unsigned char dbg_type = CON1_TYPE(system_config->debug_console.flags);
+       const u32 flags = system_config->debug_console.flags;
+       unsigned char dbg_type = CON1_TYPE(flags);
 
-       /* PIO / MMIO differentiation is done inside the driver code */
        if (dbg_type == JAILHOUSE_CON1_TYPE_UART_X86) {
-               uart_init();
+               uart = &uart_8250_ops;
+
+               uart->debug_console = &system_config->debug_console;
+               if (CON1_IS_MMIO(flags)) {
+                       uart->virt_base = hypervisor_header.debug_console_base;
+               } else {
+                       uart->virt_base = 
(void*)system_config->debug_console.address;
+                       uart->reg_out = uart_pio_out;
+                       uart->reg_in = uart_pio_in;
+                       uart->reg_dist = 1;
+               }
+               uart->init(uart);
                arch_dbg_write = uart_write;
        } else if (dbg_type == JAILHOUSE_CON1_TYPE_VGA) {
                vga_init();
diff --git a/hypervisor/arch/x86/include/asm/uart.h 
b/hypervisor/arch/x86/include/asm/uart.h
deleted file mode 100644
index a38b12c8..00000000
--- a/hypervisor/arch/x86/include/asm/uart.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Jailhouse, a Linux-based partitioning hypervisor
- *
- * Copyright (c) OTH Regensburg, 2016
- *
- * Authors:
- *  Ralf Ramsauer <[email protected]>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- */
-
-void uart_init(void);
-void uart_write(const char *msg);
diff --git a/hypervisor/arch/x86/uart.c b/hypervisor/arch/x86/uart.c
deleted file mode 100644
index a260e4bb..00000000
--- a/hypervisor/arch/x86/uart.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Jailhouse, a Linux-based partitioning hypervisor
- *
- * Copyright (c) Siemens AG, 2013-2016
- *
- * Authors:
- *  Jan Kiszka <[email protected]>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- */
-
-#include <jailhouse/control.h>
-#include <jailhouse/mmio.h>
-#include <jailhouse/printk.h>
-#include <jailhouse/processor.h>
-#include <asm/io.h>
-#include <asm/uart.h>
-#include <asm/vga.h>
-
-#define UART_TX                        0x0
-#define UART_DLL               0x0
-#define UART_DLM               0x1
-#define UART_LCR               0x3
-#define UART_LCR_8N1           0x03
-#define UART_LCR_DLAB          0x80
-#define UART_LSR               0x5
-#define UART_LSR_THRE          0x20
-
-static u64 uart_base;
-
-static void uart_pio_out(unsigned int reg, u8 value)
-{
-       outb(value, uart_base + reg);
-}
-
-static u8 uart_pio_in(unsigned int reg)
-{
-       return inb(uart_base + reg);
-}
-
-static void uart_mmio32_out(unsigned int reg, u8 value)
-{
-       mmio_write32((void *)(uart_base + reg * 4), value);
-}
-
-static u8 uart_mmio32_in(unsigned int reg)
-{
-       return mmio_read32((void *)(uart_base + reg * 4));
-}
-
-static void (*uart_reg_out)(unsigned int, u8) = uart_pio_out;
-static u8 (*uart_reg_in)(unsigned int) = uart_pio_in;
-
-void uart_init(void)
-{
-       u32 flags = system_config->debug_console.flags;
-       u32 divider = system_config->debug_console.divider;
-
-       if (CON1_IS_MMIO(flags)) {
-               uart_reg_out = uart_mmio32_out;
-               uart_reg_in = uart_mmio32_in;
-               uart_base = (u64)hypervisor_header.debug_console_base;
-       } else {
-               uart_base = system_config->debug_console.address;
-       }
-
-       if (!divider)
-               return;
-
-       uart_reg_out(UART_LCR, UART_LCR_DLAB);
-       uart_reg_out(UART_DLL, divider & 0xff);
-       uart_reg_out(UART_DLM, (divider >> 8) & 0xff);
-       uart_reg_out(UART_LCR, UART_LCR_8N1);
-}
-
-void uart_write(const char *msg)
-{
-       char c = 0;
-
-       while (1) {
-               if (c == '\n')
-                       c = '\r';
-               else
-                       c = *msg++;
-               if (!c)
-                       break;
-               while (!(uart_reg_in(UART_LSR) & UART_LSR_THRE))
-                       cpu_relax();
-               if (panic_in_progress && panic_cpu != phys_processor_id())
-                       break;
-               uart_reg_out(UART_TX, c);
-       }
-}
diff --git a/hypervisor/include/jailhouse/uart.h 
b/hypervisor/include/jailhouse/uart.h
index 7ae225f7..c0ebe982 100644
--- a/hypervisor/include/jailhouse/uart.h
+++ b/hypervisor/include/jailhouse/uart.h
@@ -27,4 +27,7 @@ struct uart_chip {
        void (*write_character)(struct uart_chip *chip, char c);
 };
 
+void uart_write(const char *msg);
+
+extern struct uart_chip *uart;
 extern struct uart_chip uart_8250_ops;
diff --git a/hypervisor/uart.c b/hypervisor/uart.c
new file mode 100644
index 00000000..615a1c94
--- /dev/null
+++ b/hypervisor/uart.c
@@ -0,0 +1,38 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) OTH Regensburg, 2016
+ *
+ * Authors:
+ *  Ralf Ramsauer <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <jailhouse/types.h>
+#include <jailhouse/uart.h>
+#include <jailhouse/control.h>
+#include <jailhouse/processor.h>
+
+struct uart_chip *uart = NULL;
+
+void uart_write(const char *msg)
+{
+       char c = 0;
+
+       while (1) {
+               if (c == '\n')
+                       c = '\r';
+               else
+                       c = *msg++;
+               if (!c)
+                       break;
+
+               while (uart->is_busy(uart))
+                       cpu_relax();
+               if (panic_in_progress && panic_cpu != phys_processor_id())
+                       break;
+               uart->write_character(uart, c);
+       }
+}
-- 
2.11.1

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to