This patch adds initial support for ARMv7 processors (more specifically,
Cortex-A15) to kvmtool.
Everything is driven by FDT, including dynamic generation of virtio nodes
for MMIO devices (PCI is not used due to lack of a suitable host-bridge).
The virtual timers and virtual interrupt controller (VGIC) are provided
by the kernel and require very little in terms of userspace code.
Signed-off-by: Will Deacon
---
Ok, here's v3 following the feedback on v2. Changes include:
- Stick the wfi instruction in the SMP pen in a loop, in case we
return early
- Fix initcall ordering with SMP pen memcpy (move DT creation to
late_init and treat the SMP pen as firmware).
Cheers,
Will
tools/kvm/Makefile | 22 ++-
tools/kvm/arm/aarch32/cortex-a15.c | 98 ++
tools/kvm/arm/aarch32/include/kvm/barrier.h | 10 +
tools/kvm/arm/aarch32/include/kvm/kvm-arch.h | 30 +++
tools/kvm/arm/aarch32/kvm-cpu.c | 111 +++
tools/kvm/arm/aarch32/smp-pen.S | 35
tools/kvm/arm/fdt.c | 266 +++
tools/kvm/arm/gic.c | 92 +
tools/kvm/arm/include/arm-common/gic.h | 34
tools/kvm/arm/include/arm-common/kvm-arch.h | 34
tools/kvm/arm/include/kvm/kvm-cpu-arch.h | 47 +
tools/kvm/arm/ioport.c | 5 +
tools/kvm/arm/irq.c | 17 ++
tools/kvm/arm/kvm-cpu.c | 107 +++
tools/kvm/arm/kvm.c | 69 +++
tools/kvm/arm/smp.c | 21 +++
16 files changed, 997 insertions(+), 1 deletion(-)
create mode 100644 tools/kvm/arm/aarch32/cortex-a15.c
create mode 100644 tools/kvm/arm/aarch32/include/kvm/barrier.h
create mode 100644 tools/kvm/arm/aarch32/include/kvm/kvm-arch.h
create mode 100644 tools/kvm/arm/aarch32/kvm-cpu.c
create mode 100644 tools/kvm/arm/aarch32/smp-pen.S
create mode 100644 tools/kvm/arm/fdt.c
create mode 100644 tools/kvm/arm/gic.c
create mode 100644 tools/kvm/arm/include/arm-common/gic.h
create mode 100644 tools/kvm/arm/include/arm-common/kvm-arch.h
create mode 100644 tools/kvm/arm/include/kvm/kvm-cpu-arch.h
create mode 100644 tools/kvm/arm/ioport.c
create mode 100644 tools/kvm/arm/irq.c
create mode 100644 tools/kvm/arm/kvm-cpu.c
create mode 100644 tools/kvm/arm/kvm.c
create mode 100644 tools/kvm/arm/smp.c
diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 3f25a14..a83dd10 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -102,7 +102,8 @@ OBJS+= builtin-sandbox.o
OBJS += virtio/mmio.o
# Translate uname -m into ARCH string
-ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/ppc.*/powerpc/)
+ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/ppc.*/powerpc/ \
+ -e s/armv7.*/arm/)
ifeq ($(ARCH),i386)
ARCH := x86
@@ -157,6 +158,25 @@ ifeq ($(ARCH), powerpc)
CFLAGS += -m64
endif
+# ARM
+OBJS_ARM_COMMON:= arm/fdt.o arm/gic.o arm/ioport.o arm/irq.o \
+ arm/kvm.o arm/kvm-cpu.o arm/smp.o
+HDRS_ARM_COMMON:= arm/include
+ifeq ($(ARCH), arm)
+ DEFINES += -DCONFIG_ARM
+ OBJS+= $(OBJS_ARM_COMMON)
+ OBJS+= arm/aarch32/cortex-a15.o
+ OBJS+= arm/aarch32/kvm-cpu.o
+ OBJS+= arm/aarch32/smp-pen.o
+ ARCH_INCLUDE:= $(HDRS_ARM_COMMON)
+ ARCH_INCLUDE+= -Iarm/aarch32/include
+ ASFLAGS += -D__ASSEMBLY__
+ ASFLAGS += -I$(ARCH_INCLUDE)
+ CFLAGS += -march=armv7-a
+ CFLAGS += -I../../scripts/dtc/libfdt
+ OTHEROBJS += $(LIBFDT_OBJS)
+endif
+
###
ifeq (,$(ARCH_INCLUDE))
diff --git a/tools/kvm/arm/aarch32/cortex-a15.c
b/tools/kvm/arm/aarch32/cortex-a15.c
new file mode 100644
index 000..eac0bb9
--- /dev/null
+++ b/tools/kvm/arm/aarch32/cortex-a15.c
@@ -0,0 +1,98 @@
+#include "kvm/fdt.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/util.h"
+
+#include "arm-common/gic.h"
+
+#include
+#include
+
+#define CPU_NAME_MAX_LEN 8
+static void generate_cpu_nodes(void *fdt, struct kvm *kvm)
+{
+ int cpu;
+
+ _FDT(fdt_begin_node(fdt, "cpus"));
+ _FDT(fdt_property_cell(fdt, "#address-cells", 0x1));
+ _FDT(fdt_property_cell(fdt, "#size-cells", 0x0));
+
+ for (cpu = 0; cpu < kvm->nrcpus; ++cpu) {
+ char cpu_name[CPU_NAME_MAX_LEN];
+
+ if (kvm->cpus[cpu]->cpu_type != KVM_ARM_TARGET_CORTEX_A15) {
+ pr_warning("Ignoring unknown type for CPU %d\n", cpu);
+ continue;
+ }
+
+ snprintf(cpu_name, CPU_NAME_MAX_LEN, "cpu@%d", cpu);
+
+ _FDT(fdt_begin_node(fdt, cpu_name));
+ _FDT(fdt_property_string(fdt, "device_type", "cpu"));
+ _F