This is a simple demo for SMP startup and IPI signaling.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
--- /dev/null
+/*
+ * 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,
+ },
+};
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
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
--- /dev/null
+/*
+ * 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();
+ }
+}