This allows jailhouse to power up UART devices without being initialised
from Linux before.

In most scenarios, Linux will power up clocks.

Default for Bananapi and Jetson TK1 values can be found as comments
inside system configurations.

Note, that this is currently only supported on ARM together with the
8250 driver. This is currently not supported by ARM64.

Signed-off-by: Ralf Ramsauer <[email protected]>
---
 configs/bananapi.c                            |  2 ++
 configs/jetson-tk1.c                          |  2 ++
 driver/main.c                                 | 18 +++++++++++++++++-
 hypervisor/arch/arm-common/dbg-write.c        |  1 +
 hypervisor/arch/arm-common/include/asm/uart.h |  4 +---
 hypervisor/arch/arm-common/uart-8250.c        | 10 ++++++----
 hypervisor/include/jailhouse/cell-config.h    |  3 ++-
 hypervisor/include/jailhouse/header.h         |  3 +++
 hypervisor/paging.c                           | 11 +++++++++++
 9 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/configs/bananapi.c b/configs/bananapi.c
index b79f639e29..ce641f7a4d 100644
--- a/configs/bananapi.c
+++ b/configs/bananapi.c
@@ -33,6 +33,8 @@ struct {
                .debug_console = {
                        .address = 0x01c28000,
                        .size = 0x1000,
+                       /* .clock_reg = 0x01c2006c, */
+                       /* .gate_nr = 16 */
                        /* .divider = 0x0d, */
                        .flags = JAILHOUSE_DBG_TYPE_UART_ARM |
                                 JAILHOUSE_DBG_FLAG_MMIO,
diff --git a/configs/jetson-tk1.c b/configs/jetson-tk1.c
index d5d7c5dfdb..18e2840b6d 100644
--- a/configs/jetson-tk1.c
+++ b/configs/jetson-tk1.c
@@ -36,6 +36,8 @@ struct {
                .debug_console = {
                        .address = 0x70006300,
                        .size = 0x40,
+                       /* .clock_reg = 0x60006000 + 0x330, */
+                       /* .gate_nr = (65 % 32), */
                        /* .divider = 0xdd, */
                        .flags = JAILHOUSE_DBG_TYPE_UART_ARM |
                                 JAILHOUSE_DBG_FLAG_MMIO,
diff --git a/driver/main.c b/driver/main.c
index 907fe61884..bc46f82719 100644
--- a/driver/main.c
+++ b/driver/main.c
@@ -191,7 +191,7 @@ static int jailhouse_cmd_enable(struct jailhouse_system 
__user *arg)
        struct jailhouse_memory *hv_mem = &config_header.hypervisor_memory;
        struct jailhouse_header *header;
        unsigned long remap_addr = 0;
-       void __iomem *console = NULL;
+       void __iomem *console = NULL, *clock_reg = NULL;
        unsigned long config_size;
        const char *fw_name;
        long max_cpus;
@@ -311,6 +311,18 @@ static int jailhouse_cmd_enable(struct jailhouse_system 
__user *arg)
                 * to enforce conversion. */
                header->debug_console_base = (void * __force)console;
        }
+
+       if (config->debug_console.clock_reg) {
+               clock_reg = ioremap(config->debug_console.clock_reg, 1);
+               if (!clock_reg) {
+                       err = -EINVAL;
+                       pr_err("jailhouse: Unable to map hypervisor debug "
+                              "clock register at %08lx\n",
+                              (unsigned long)config->debug_console.clock_reg);
+                       goto error_unmap;
+               }
+               header->debug_clock_reg = (void * __force)clock_reg;
+       }
 #endif
 
        err = jailhouse_cell_prepare_root(&config->root_cell);
@@ -337,6 +349,8 @@ static int jailhouse_cmd_enable(struct jailhouse_system 
__user *arg)
 
        if (console)
                iounmap(console);
+       if (clock_reg)
+               iounmap(clock_reg);
 
        release_firmware(hypervisor);
 
@@ -358,6 +372,8 @@ error_unmap:
        vunmap(hypervisor_mem);
        if (console)
                iounmap(console);
+       if (clock_reg)
+               iounmap(clock_reg);
 
 error_release_fw:
        release_firmware(hypervisor);
diff --git a/hypervisor/arch/arm-common/dbg-write.c 
b/hypervisor/arch/arm-common/dbg-write.c
index 71cf3a544b..fed8492acc 100644
--- a/hypervisor/arch/arm-common/dbg-write.c
+++ b/hypervisor/arch/arm-common/dbg-write.c
@@ -50,6 +50,7 @@ void arch_dbg_write_init(void)
                return;
 
        uart.debug_console = &system_config->debug_console;
+       uart.virt_clock_reg = hypervisor_header.debug_clock_reg;
        uart.virt_base = hypervisor_header.debug_console_base;
        uart_chip_init(&uart);
        arch_dbg_write = arm_uart_write;
diff --git a/hypervisor/arch/arm-common/include/asm/uart.h 
b/hypervisor/arch/arm-common/include/asm/uart.h
index 17cc5613d4..77c8024a8d 100644
--- a/hypervisor/arch/arm-common/include/asm/uart.h
+++ b/hypervisor/arch/arm-common/include/asm/uart.h
@@ -18,13 +18,11 @@
 /* Defines the bare minimum for debug writes */
 struct uart_chip {
        void            *virt_base;
+       void            *virt_clock_reg;
        struct jailhouse_debug_console *debug_console;
 
        void (*wait)(struct uart_chip *);
        void (*write)(struct uart_chip *, char c);
-
-       void            *clock_reg;
-       unsigned int    gate_nr;
 };
 
 void uart_chip_init(struct uart_chip *chip);
diff --git a/hypervisor/arch/arm-common/uart-8250.c 
b/hypervisor/arch/arm-common/uart-8250.c
index 613f2cabc7..e7c8d2d61d 100644
--- a/hypervisor/arch/arm-common/uart-8250.c
+++ b/hypervisor/arch/arm-common/uart-8250.c
@@ -27,10 +27,12 @@
 
 static void uart_init(struct uart_chip *chip)
 {
-       if (chip->clock_reg)
-               mmio_write32(chip->clock_reg,
-                            mmio_read32(chip->clock_reg) |
-                            (1 << chip->gate_nr));
+       void *clock_reg = (void*)(unsigned long)chip->virt_clock_reg;
+       unsigned int gate_nr = chip->debug_console->gate_nr;
+
+       if (clock_reg)
+               mmio_write32(clock_reg,
+                            mmio_read32(clock_reg) | (1 << gate_nr));
 
        /* only initialise if divider is not zero */
        if (!chip->debug_console->divider)
diff --git a/hypervisor/include/jailhouse/cell-config.h 
b/hypervisor/include/jailhouse/cell-config.h
index 8cfbc1787a..65bf28ed9e 100644
--- a/hypervisor/include/jailhouse/cell-config.h
+++ b/hypervisor/include/jailhouse/cell-config.h
@@ -186,7 +186,8 @@ struct jailhouse_debug_console {
        __u32 size;
        __u32 flags;
        __u32 divider;
-       __u32 __reserved;
+       __u32 gate_nr;
+       __u64 clock_reg;
 } __attribute__((packed));
 
 #define JAILHOUSE_SYSTEM_SIGNATURE     "JAILSYST"
diff --git a/hypervisor/include/jailhouse/header.h 
b/hypervisor/include/jailhouse/header.h
index 54cfab9426..4fe159c621 100644
--- a/hypervisor/include/jailhouse/header.h
+++ b/hypervisor/include/jailhouse/header.h
@@ -55,4 +55,7 @@ struct jailhouse_header {
        /** Virtual base address of the debug console device (if used).
         * @note Filled by Linux loader driver before entry. */
        void *debug_console_base;
+       /** Virtual address of the clock gate register (if used).
+        * @note Filled by Linux loader driver before entry. */
+       void *debug_clock_reg;
 };
diff --git a/hypervisor/paging.c b/hypervisor/paging.c
index 3b030d6b10..a6759baa2d 100644
--- a/hypervisor/paging.c
+++ b/hypervisor/paging.c
@@ -611,6 +611,17 @@ int paging_init(void)
                        return err;
        }
 
+       vaddr = (unsigned long)hypervisor_header.debug_clock_reg;
+       if (vaddr) {
+               err = paging_create(&hv_paging_structs,
+                                   system_config->debug_console.clock_reg,
+                                   1, vaddr,
+                                   PAGE_DEFAULT_FLAGS | PAGE_FLAG_DEVICE,
+                                   PAGING_NON_COHERENT);
+               if (err)
+                       return err;
+       }
+
        /* Make sure any remappings to the temporary regions can be performed
         * without allocations of page table pages. */
        return paging_create(&hv_paging_structs, 0,
-- 
2.11.0.rc2

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