]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
inmates, configs: Add x86 SMP demo
authorJan Kiszka <jan.kiszka@siemens.com>
Fri, 15 May 2015 06:49:22 +0000 (08:49 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 15 May 2015 07:14:26 +0000 (09:14 +0200)
This is a simple demo for SMP startup and IPI signaling.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
configs/smp-demo.c [new file with mode: 0644]
inmates/demos/x86/Makefile
inmates/demos/x86/smp-demo.c [new file with mode: 0644]

diff --git a/configs/smp-demo.c b/configs/smp-demo.c
new file mode 100644 (file)
index 0000000..8649466
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Minimal configuration for SMP demo inmates, 3 CPUs, 1 MB RAM, 1 serial port
+ *
+ * Copyright (c) Siemens AG, 2013-2015
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kiszka@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];
+       __u8 pio_bitmap[0x2000];
+} __attribute__((packed)) config = {
+       .cell = {
+               .name = "smp-demo",
+               .flags = JAILHOUSE_CELL_PASSIVE_COMMREG,
+
+               .cpu_set_size = sizeof(config.cpus),
+               .num_memory_regions = ARRAY_SIZE(config.mem_regions),
+               .num_irqchips = 0,
+               .pio_bitmap_size = ARRAY_SIZE(config.pio_bitmap),
+               .num_pci_devices = 0,
+       },
+
+       .cpus = {
+               0xe,
+       },
+
+       .mem_regions = {
+               /* RAM */ {
+                       .phys_start = 0x3f100000,
+                       .virt_start = 0,
+                       .size = 0x00100000,
+                       .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+                               JAILHOUSE_MEM_EXECUTE | JAILHOUSE_MEM_LOADABLE,
+               },
+               /* communication region */ {
+                       .virt_start = 0x00100000,
+                       .size = 0x00001000,
+                       .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+                               JAILHOUSE_MEM_COMM_REGION,
+               },
+       },
+
+       .pio_bitmap = {
+               [     0/8 ...  0x2f7/8] = -1,
+               [ 0x2f8/8 ...  0x2ff/8] = 0, /* serial2 */
+               [ 0x300/8 ... 0xdfff/8] = -1,
+               [0xe000/8 ... 0xe007/8] = 0, /* OXPCIe952 serial2 */
+               [0xe008/8 ... 0xffff/8] = -1,
+       },
+};
index 110501f0e7e5c54bc7a848cd7b1e0a218a2f94a5..8defc67cee57b34c72cbe2b04d7a5ed4b4cbcf2b 100644 (file)
@@ -13,7 +13,7 @@
 include $(INMATES_LIB)/Makefile.lib
 
 INMATES := tiny-demo.bin apic-demo.bin ioapic-demo.bin 32-bit-demo.bin \
-       pci-demo.bin e1000-demo.bin ivshmem-demo.bin
+       pci-demo.bin e1000-demo.bin ivshmem-demo.bin smp-demo.bin
 
 tiny-demo-y    := tiny-demo.o
 apic-demo-y    := apic-demo.o
@@ -21,6 +21,7 @@ ioapic-demo-y := ioapic-demo.o
 pci-demo-y     := pci-demo.o
 e1000-demo-y   := e1000-demo.o
 ivshmem-demo-y := ivshmem-demo.o
+smp-demo-y     := smp-demo.o
 
 $(eval $(call DECLARE_32_BIT,32-bit-demo))
 32-bit-demo-y  := 32-bit-demo.o
diff --git a/inmates/demos/x86/smp-demo.c b/inmates/demos/x86/smp-demo.c
new file mode 100644 (file)
index 0000000..a5567be
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2013-2015
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kiszka@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 <inmate.h>
+
+#ifdef CONFIG_UART_OXPCIE952
+#define UART_BASE              0xe000
+#else
+#define UART_BASE              0x2f8
+#endif
+
+#define IPI_VECTOR             40
+
+static volatile bool done;
+static unsigned int main_cpu;
+
+static void ipi_handler(void)
+{
+       printk("Received IPI on %d\n", cpu_id());
+       done = true;
+}
+
+static void secondary_main(void)
+{
+       printk("Hello from CPU %d!\n", cpu_id());
+       int_send_ipi(main_cpu, IPI_VECTOR);
+}
+
+void inmate_main(void)
+{
+       unsigned int n;
+
+       printk_uart_base = UART_BASE;
+
+       main_cpu = cpu_id();
+       printk("SMP demo, primary CPU: %d\n", main_cpu);
+
+       printk("Waiting for the rest...");
+       smp_wait_for_all_cpus();
+       printk("\nFound %d other CPU(s)\n", smp_num_cpus - 1);
+
+       int_init();
+       int_set_handler(IPI_VECTOR, ipi_handler);
+
+       asm volatile("sti");
+
+       for (n = 1; n < smp_num_cpus; n++) {
+               printk(" Starting CPU %d\n", smp_cpu_ids[n]);
+               done = false;
+               smp_start_cpu(smp_cpu_ids[n], secondary_main);
+               while (!done)
+                       cpu_relax();
+       }
+}