This allows us to use non-memory-mapped devices and is a prerequisite
for bringing uart drivers to a more abstract level.

Currently, those functions are only used by the 8250 driver. 8250 driver
comes with a default register distance of 4 and uses mmio based access
by default.

Independent of reg_in and reg_out, clock registers will still be
accessed via mmio routines.

Signed-off-by: Ralf Ramsauer <[email protected]>
---
 hypervisor/arch/arm-common/include/asm/uart.h |  4 ++++
 hypervisor/arch/arm-common/uart-8250.c        | 34 ++++++++++++++++++---------
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/hypervisor/arch/arm-common/include/asm/uart.h 
b/hypervisor/arch/arm-common/include/asm/uart.h
index 4ca0034f9a..934f345702 100644
--- a/hypervisor/arch/arm-common/include/asm/uart.h
+++ b/hypervisor/arch/arm-common/include/asm/uart.h
@@ -24,6 +24,10 @@ struct uart_chip {
        void (*init)(struct uart_chip *chip);
        bool (*is_busy)(struct uart_chip *chip);
        void (*write_char)(struct uart_chip *chip, char c);
+
+       void (*reg_out)(void *address, u32 value);
+       u32 (*reg_in)(void *address);
+       unsigned int reg_dist;
 };
 
 extern struct uart_chip uart_8250_ops, uart_pl011_ops, uart_xuartps_ops;
diff --git a/hypervisor/arch/arm-common/uart-8250.c 
b/hypervisor/arch/arm-common/uart-8250.c
index 9317eb988d..7a45238267 100644
--- a/hypervisor/arch/arm-common/uart-8250.c
+++ b/hypervisor/arch/arm-common/uart-8250.c
@@ -17,13 +17,24 @@
 
 #define UART_TX                        0x0
 #define UART_DLL               0x0
-#define UART_DLM               0x4
-#define UART_LCR               0xc
+#define UART_DLM               0x1
+#define UART_LCR               0x3
 #define  UART_LCR_8N1          0x03
 #define  UART_LCR_DLAB         0x80
-#define UART_LSR               0x14
+#define UART_LSR               0x5
 #define  UART_LSR_THRE         0x20
 
+static inline void reg_out(struct uart_chip *chip, unsigned int offset,
+                          u32 value)
+{
+       chip->reg_out(chip->virt_base + chip->reg_dist * offset, value);
+}
+
+static inline u32 reg_in(struct uart_chip *chip, unsigned int offset)
+{
+       return chip->reg_in(chip->virt_base + chip->reg_dist * offset);
+}
+
 static void uart_init(struct uart_chip *chip)
 {
        void *clock_reg = (void*)(unsigned long)chip->virt_clock_reg;
@@ -37,26 +48,27 @@ static void uart_init(struct uart_chip *chip)
        if (!chip->debug_console->divider)
                return;
 
-       mmio_write32(chip->virt_base + UART_LCR, UART_LCR_DLAB);
-       mmio_write32(chip->virt_base + UART_DLL,
-                    chip->debug_console->divider & 0xff);
-       mmio_write32(chip->virt_base + UART_DLM,
-                    (chip->debug_console->divider >> 8) & 0xff);
-       mmio_write32(chip->virt_base + UART_LCR, UART_LCR_8N1);
+       reg_out(chip, UART_LCR, UART_LCR_DLAB);
+       reg_out(chip, UART_DLL, chip->debug_console->divider & 0xff);
+       reg_out(chip, UART_DLM, (chip->debug_console->divider >> 8) & 0xff);
+       reg_out(chip, UART_LCR, UART_LCR_8N1);
 }
 
 static bool uart_is_busy(struct uart_chip *chip)
 {
-       return !(mmio_read32(chip->virt_base + UART_LSR) & UART_LSR_THRE);
+       return !(reg_in(chip, UART_LSR) & UART_LSR_THRE);
 }
 
 static void uart_write_char(struct uart_chip *chip, char c)
 {
-       mmio_write32(chip->virt_base + UART_TX, c);
+       reg_out(chip, UART_TX, c);
 }
 
 struct uart_chip uart_8250_ops = {
        .init = uart_init,
        .is_busy = uart_is_busy,
        .write_char = uart_write_char,
+       .reg_dist = 4,
+       .reg_out = mmio_write32,
+       .reg_in = mmio_read32,
 };
-- 
2.12.0

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