The Jetson TK1 board uses the NVIDIA K1 processor, namely the Tegra124.
The CPU has 4 Cortex-A15 cores and a low-power companion core which we
do not support, though. This SoC apparently contains all virtualization
features we need, specifically full SMMU coverage of I/O devices.
For now, board support is similar to the Banana Pi: We replicate UART
and SMP/PSCI features and add some configs (only one for both demos as
only one UART is accessible).
Open issues, besides adding SMMU support, are managing the access to the
so-called legacy Interrupt controller of the K1 (an additional stage
between devices and GIC) and sub-page access control to various devices
(same issue as with the Allwinner A20). Also, it becomes clearer than
ever that we urgently need to refactor the UART layer as well as
SMP/PSCI support to reduce duplications.
configs/jetson-tk1-demo.c | 54 +++++++++
configs/jetson-tk1.c | 128 +++++++++++++++++++++
hypervisor/arch/arm/Makefile | 2 +
hypervisor/arch/arm/include/asm/platform.h | 17 +++
hypervisor/arch/arm/include/asm/uart-tegra.h | 53 +++++++++
hypervisor/arch/arm/smp-tegra124.c | 26 +++++
hypervisor/arch/arm/uart-tegra.c | 25 ++++
inmates/lib/arm/Makefile.lib | 2 +
.../lib/arm/include/mach-tegra124/mach/gic_v2.h | 14 +++
inmates/lib/arm/include/mach-tegra124/mach/timer.h | 14 +++
inmates/lib/arm/include/mach-tegra124/mach/uart.h | 13 +++
inmates/lib/arm/uart-tegra.c | 24 ++++
12 files changed, 372 insertions(+)
create mode 100644 configs/jetson-tk1-demo.c
create mode 100644 configs/jetson-tk1.c
create mode 100644 hypervisor/arch/arm/include/asm/uart-tegra.h
create mode 100644 hypervisor/arch/arm/smp-tegra124.c
create mode 100644 hypervisor/arch/arm/uart-tegra.c
create mode 100644 inmates/lib/arm/include/mach-tegra124/mach/gic_v2.h
create mode 100644 inmates/lib/arm/include/mach-tegra124/mach/timer.h
create mode 100644 inmates/lib/arm/include/mach-tegra124/mach/uart.h
create mode 100644 inmates/lib/arm/uart-tegra.c
diff --git a/configs/jetson-tk1-demo.c b/configs/jetson-tk1-demo.c
new file mode 100644
index 0000000..02c924d
--- /dev/null
+++ b/configs/jetson-tk1-demo.c
@@ -0,0 +1,54 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Configuration for gic-demo or uart-demo inmate on Jetson TK1:
+ * 1 CPU, 64K RAM, serial port 0
+ *
+ * Copyright (c) Siemens AG, 2015
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <linux/types.h>
+#include <jailhouse/cell-config.h>
+
+#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
+
+struct {
+ struct jailhouse_cell_desc cell;
+ __u64 cpus[1];
+ struct jailhouse_memory mem_regions[2];
+} __attribute__((packed)) config = {
+ .cell = {
+ .name = "jetson-tk1-demo",
+ .flags = JAILHOUSE_CELL_PASSIVE_COMMREG,
+
+ .cpu_set_size = sizeof(config.cpus),
+ .num_memory_regions = ARRAY_SIZE(config.mem_regions),
+ },
+
+ .cpus = {
+ 0x8,
+ },
+
+ .mem_regions = {
+ /* UART */ {
+ .phys_start = 0x70006000,
+ .virt_start = 0x70006000,
+ .size = 0x1000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* RAM */ {
+ .phys_start = 0xfbfe0000,
+ .virt_start = 0,
+ .size = 0x00010000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_EXECUTE | JAILHOUSE_MEM_LOADABLE,
+ },
+ },
+};
diff --git a/configs/jetson-tk1.c b/configs/jetson-tk1.c
new file mode 100644
index 0000000..e230590
--- /dev/null
+++ b/configs/jetson-tk1.c
@@ -0,0 +1,128 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Test configuration for Jetson TK1 board
+ * (NVIDIA Tegra K1 quad-core Cortex-A15, 2G RAM)
+ *
+ * Copyright (c) Siemens AG, 2015
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <linux/types.h>
+#include <jailhouse/cell-config.h>
+
+#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
+
+struct {
+ struct jailhouse_system header;
+ __u64 cpus[1];
+ struct jailhouse_memory mem_regions[10];
+ struct jailhouse_irqchip irqchips[1];
+} __attribute__((packed)) config = {
+ .header = {
+ .hypervisor_memory = {
+ .phys_start = 0xfc000000,
+ .size = 0x4000000 - 0x100000, /* -1MB (PSCI) */
+ },
+ .debug_uart = {
+ .phys_start = 0x70006000,
+ .size = 0x1000,
+ .flags = JAILHOUSE_MEM_IO,
+ },
+ .root_cell = {
+ .name = "Jetson-TK1",
+
+ .cpu_set_size = sizeof(config.cpus),
+ .num_memory_regions = ARRAY_SIZE(config.mem_regions),
+ .num_irqchips = 1,
+ },
+ },
+
+ .cpus = {
+ 0xf,
+ },
+
+ .mem_regions = {
+ /* PCIe */ {
+ .phys_start = 0x01000000,
+ .virt_start = 0x01000000,
+ .size = 0x3f000000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* HACK: Legacy Interrupt Controller */ {
+ .phys_start = 0x60004000,
+ .virt_start = 0x60004000,
+ .size = 0x00001000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* HACK: Clock and Reset Controller */ {
+ .phys_start = 0x60006000,
+ .virt_start = 0x60006000,
+ .size = 0x00001000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* I2C5/6, SPI */ {
+ .phys_start = 0x7000d000,
+ .virt_start = 0x7000d000,
+ .size = 0x00001000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* HACK: Memory Controller */ {
+ .phys_start = 0x70019000,
+ .virt_start = 0x70019000,
+ .size = 0x00001000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* MMC0/1 */ {
+ .phys_start = 0x700b0000,
+ .virt_start = 0x700b0000,
+ .size = 0x00001000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* RTC + PMC */ {
+ .phys_start = 0x7000e000,
+ .virt_start = 0x7000e000,
+ .size = 0x00001000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* USB */ {
+ .phys_start = 0x7d004000,
+ .virt_start = 0x7d004000,
+ .size = 0x00008000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* UART */ {
+ .phys_start = 0x70006000,
+ .virt_start = 0x70006000,
+ .size = 0x1000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_IO,
+ },
+ /* RAM */ {
+ .phys_start = 0x80000000,
+ .virt_start = 0x80000000,
+ .size = 0x7c000000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_EXECUTE,
+ },
+ },
+ .irqchips = {
+ /* GIC */ {
+ .address = 0x50041000,
+ .pin_bitmap = 0xffffffffffffffff,
+ },
+ },
+};
diff --git a/hypervisor/arch/arm/Makefile b/hypervisor/arch/arm/Makefile
index 51e46af..efa56c8 100644
--- a/hypervisor/arch/arm/Makefile
+++ b/hypervisor/arch/arm/Makefile
@@ -25,5 +25,7 @@ obj-$(CONFIG_ARM_GIC_V3) += gic-v3.o
obj-$(CONFIG_ARM_GIC) += gic-v2.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += dbg-write-pl011.o
obj-$(CONFIG_SERIAL_8250_DW) += uart-8250-dw.o
+obj-$(CONFIG_SERIAL_TEGRA) += uart-tegra.o
obj-$(CONFIG_MACH_VEXPRESS) += smp-vexpress.o
obj-$(CONFIG_MACH_SUN7I) += smp-sun7i.o
+obj-$(CONFIG_MACH_TEGRA124) += smp-tegra124.o
diff --git a/hypervisor/arch/arm/include/asm/platform.h b/hypervisor/arch/arm/include/asm/platform.h
index b0d51ee..fa7bfdc 100644
--- a/hypervisor/arch/arm/include/asm/platform.h
+++ b/hypervisor/arch/arm/include/asm/platform.h
@@ -69,6 +69,23 @@
#endif /* CONFIG_MACH_SUN7I */
+#ifdef CONFIG_MACH_TEGRA124
+
+# define GICD_BASE ((void *)0x50041000)
+# define GICD_SIZE 0x1000
+# define GICC_BASE ((void *)0x50042000)
+# define GICC_SIZE 0x2000
+# define GICH_BASE ((void *)0x50044000)
+# define GICH_SIZE 0x2000
+# define GICV_BASE ((void *)0x50046000)
+# define GICV_SIZE 0x2000
+
+# include <asm/gic_v2.h>
+
+# define MAINTENANCE_IRQ 25
+
+#endif /* CONFIG_MACH_TEGRA124 */
+
#define HOTPLUG_SPIN 1
/*
#define HOTPLUG_PSCI 1
diff --git a/hypervisor/arch/arm/include/asm/uart-tegra.h b/hypervisor/arch/arm/include/asm/uart-tegra.h
new file mode 100644
index 0000000..5bed630
--- /dev/null
+++ b/hypervisor/arch/arm/include/asm/uart-tegra.h
@@ -0,0 +1,53 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2015
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <jailhouse/mmio.h>
+#include <jailhouse/processor.h>
+#include <asm/debug.h>
+
+#define UART_TX 0x0
+#define UART_DLL 0x0
+#define UART_DLM 0x4
+#define UART_LCR 0xc
+#define UART_LCR_8N1 0x03
+#define UART_LCR_DLAB 0x80
+#define UART_LSR 0x14
+#define UART_LSR_THRE 0x20
+
+static void uart_init(struct uart_chip *chip)
+{
+ chip->virt_base += 0x300;
+/* if (chip->clock_reg)
+ mmio_write32(chip->clock_reg,
+ mmio_read32(chip->clock_reg) |
+ (1 << chip->gate_nr));
+
+ mmio_write32(chip->virt_base + UART_LCR, UART_LCR_DLAB);
+ mmio_write32(chip->virt_base + UART_DLL, 0x0d);
+ mmio_write32(chip->virt_base + UART_DLM, 0);
+ mmio_write32(chip->virt_base + UART_LCR, UART_LCR_8N1);*/
+}
+
+static void uart_wait(struct uart_chip *chip)
+{
+ while (!(mmio_read32(chip->virt_base + UART_LSR) & UART_LSR_THRE))
+ cpu_relax();
+}
+
+static void uart_busy(struct uart_chip *chip)
+{
+}
+
+static void uart_write(struct uart_chip *chip, char c)
+{
+ mmio_write32(chip->virt_base + UART_TX, c);
+}
diff --git a/hypervisor/arch/arm/smp-tegra124.c b/hypervisor/arch/arm/smp-tegra124.c
new file mode 100644
index 0000000..81f9649
--- /dev/null
+++ b/hypervisor/arch/arm/smp-tegra124.c
@@ -0,0 +1,26 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2014, 2015
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <asm/cell.h>
+#include <asm/psci.h>
+#include <asm/smp.h>
+
+static struct smp_ops tegra124_smp_ops = {
+ .type = SMP_SPIN,
+ .init = psci_cell_init,
+ .cpu_spin = psci_emulate_spin,
+};
+
+void register_smp_ops(struct cell *cell)
+{
+ cell->arch.smp = &tegra124_smp_ops;
+}
diff --git a/hypervisor/arch/arm/uart-tegra.c b/hypervisor/arch/arm/uart-tegra.c
new file mode 100644
index 0000000..634523e
--- /dev/null
+++ b/hypervisor/arch/arm/uart-tegra.c
@@ -0,0 +1,25 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) ARM Limited, 2014
+ * Copyright (c) Siemens AG, 2014, 2015
+ *
+ * Authors:
+ * Jean-Philippe Brucker <
jean-phili...@arm.com>
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <asm/uart-tegra.h>
+
+/* All the helpers are in the header, to make them re-usable by the inmates */
+void uart_chip_init(struct uart_chip *chip)
+{
+ chip->wait = uart_wait;
+ chip->busy = uart_busy;
+ chip->write = uart_write;
+
+ uart_init(chip);
+}
diff --git a/inmates/lib/arm/Makefile.lib b/inmates/lib/arm/Makefile.lib
index 2746eda..0cb6a19 100644
--- a/inmates/lib/arm/Makefile.lib
+++ b/inmates/lib/arm/Makefile.lib
@@ -29,11 +29,13 @@ endef
mach-$(CONFIG_MACH_VEXPRESS) := vexpress
mach-$(CONFIG_MACH_SUN7I) := sun7i
+mach-$(CONFIG_MACH_TEGRA124) := tegra124
gic-$(CONFIG_ARM_GIC) := gic-v2.o
gic-$(CONFIG_ARM_GIC_V3) := gic-v3.o
uart-$(CONFIG_SERIAL_AMBA_PL011) := uart-pl011.o
uart-$(CONFIG_SERIAL_8250_DW) := uart-8250-dw.o
+uart-$(CONFIG_SERIAL_TEGRA) := uart-tegra.o
MACHINE := mach-$(mach-y)
DRIVERS := $(gic-y) $(uart-y)
diff --git a/inmates/lib/arm/include/mach-tegra124/mach/gic_v2.h b/inmates/lib/arm/include/mach-tegra124/mach/gic_v2.h
new file mode 100644
index 0000000..e513194
--- /dev/null
+++ b/inmates/lib/arm/include/mach-tegra124/mach/gic_v2.h
@@ -0,0 +1,14 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2015
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#define GICD_BASE ((void *)0x50041000)
+#define GICC_BASE ((void *)0x50042000)
diff --git a/inmates/lib/arm/include/mach-tegra124/mach/timer.h b/inmates/lib/arm/include/mach-tegra124/mach/timer.h
new file mode 100644
index 0000000..478f6cb
--- /dev/null
+++ b/inmates/lib/arm/include/mach-tegra124/mach/timer.h
@@ -0,0 +1,14 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2015
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#define TIMER_IRQ 27
+#define TIMER_FREQ 12000000
diff --git a/inmates/lib/arm/include/mach-tegra124/mach/uart.h b/inmates/lib/arm/include/mach-tegra124/mach/uart.h
new file mode 100644
index 0000000..7b97dc7
--- /dev/null
+++ b/inmates/lib/arm/include/mach-tegra124/mach/uart.h
@@ -0,0 +1,13 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2015
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#define UART_BASE ((void *)0x70006000)
diff --git a/inmates/lib/arm/uart-tegra.c b/inmates/lib/arm/uart-tegra.c
new file mode 100644
index 0000000..6506195
--- /dev/null
+++ b/inmates/lib/arm/uart-tegra.c
@@ -0,0 +1,24 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) ARM Limited, 2014
+ * Copyright (c) Siemens AG, 2014, 2015
+ *
+ * Authors:
+ * Jean-Philippe Brucker <
jean-phili...@arm.com>
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#include <asm/uart-tegra.h>
+#include <mach/uart.h>
+
+void uart_chip_init(struct uart_chip *chip)
+{
+ chip->virt_base = UART_BASE;
+ chip->wait = uart_wait;
+ chip->write = uart_write;
+ chip->busy = uart_busy;
+ uart_init(chip);
+}
--
2.1.4