@@ -157,12 +157,12 @@ 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/kvm.o arm/kvm-cpu.o arm/timer.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/arm-cpu.o
OBJS += arm/aarch32/kvm-cpu.o
ARCH_INCLUDE := $(HDRS_ARM_COMMON)
ARCH_INCLUDE += -Iarm/aarch32/include
@@ -175,7 +175,7 @@ endif
ifeq ($(ARCH), arm64)
DEFINES += -DCONFIG_ARM64
OBJS += $(OBJS_ARM_COMMON)
- OBJS += arm/aarch64/cortex-a57.o
+ OBJS += arm/aarch64/arm-cpu.o
OBJS += arm/aarch64/kvm-cpu.o
ARCH_INCLUDE := $(HDRS_ARM_COMMON)
ARCH_INCLUDE += -Iarm/aarch64/include
new file mode 100644
@@ -0,0 +1,35 @@
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/util.h"
+
+#include "arm-common/gic.h"
+#include "arm-common/timer.h"
+
+#include <linux/byteorder.h>
+#include <linux/types.h>
+
+static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
+{
+ int timer_interrupts[4] = {13, 14, 11, 10};
+
+ gic__generate_fdt_nodes(fdt, gic_phandle);
+ timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
+}
+
+static int arm_cpu__vcpu_init(struct kvm_cpu *vcpu)
+{
+ vcpu->generate_fdt_nodes = generate_fdt_nodes;
+ return 0;
+}
+
+static struct kvm_arm_target target_cortex_a15 = {
+ .id = KVM_ARM_TARGET_CORTEX_A15,
+ .compatible = "arm,cortex-a15",
+ .init = arm_cpu__vcpu_init,
+};
+
+static int arm_cpu__core_init(struct kvm *kvm)
+{
+ return kvm_cpu__register_kvm_arm_target(&target_cortex_a15);
+}
+core_init(arm_cpu__core_init);
deleted file mode 100644
@@ -1,61 +0,0 @@
-#include "kvm/fdt.h"
-#include "kvm/kvm.h"
-#include "kvm/kvm-cpu.h"
-#include "kvm/util.h"
-
-#include "arm-common/gic.h"
-
-#include <linux/byteorder.h>
-#include <linux/types.h>
-
-static void generate_timer_nodes(void *fdt, struct kvm *kvm)
-{
- u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \
- & GIC_FDT_IRQ_PPI_CPU_MASK;
- u32 irq_prop[] = {
- cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(13),
- cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
-
- cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(14),
- cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
-
- cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(11),
- cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
-
- cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(10),
- cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
- };
-
- _FDT(fdt_begin_node(fdt, "timer"));
- _FDT(fdt_property_string(fdt, "compatible", "arm,armv7-timer"));
- _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
- _FDT(fdt_end_node(fdt));
-}
-
-static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
-{
- gic__generate_fdt_nodes(fdt, gic_phandle);
- generate_timer_nodes(fdt, kvm);
-}
-
-static int cortex_a15__vcpu_init(struct kvm_cpu *vcpu)
-{
- vcpu->generate_fdt_nodes = generate_fdt_nodes;
- return 0;
-}
-
-static struct kvm_arm_target target_cortex_a15 = {
- .id = KVM_ARM_TARGET_CORTEX_A15,
- .compatible = "arm,cortex-a15",
- .init = cortex_a15__vcpu_init,
-};
-
-static int cortex_a15__core_init(struct kvm *kvm)
-{
- return kvm_cpu__register_kvm_arm_target(&target_cortex_a15);
-}
-core_init(cortex_a15__core_init);
new file mode 100644
@@ -0,0 +1,50 @@
+#include "kvm/fdt.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/util.h"
+
+#include "arm-common/gic.h"
+#include "arm-common/timer.h"
+
+#include <linux/byteorder.h>
+#include <linux/types.h>
+
+static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
+{
+ int timer_interrupts[4] = {13, 14, 11, 10};
+ gic__generate_fdt_nodes(fdt, gic_phandle);
+ timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
+}
+
+
+static int arm_cpu__vcpu_init(struct kvm_cpu *vcpu)
+{
+ vcpu->generate_fdt_nodes = generate_fdt_nodes;
+ return 0;
+}
+
+static struct kvm_arm_target target_aem_v8 = {
+ .id = KVM_ARM_TARGET_AEM_V8,
+ .compatible = "arm,arm-v8",
+ .init = arm_cpu__vcpu_init,
+};
+
+static struct kvm_arm_target target_foundation_v8 = {
+ .id = KVM_ARM_TARGET_FOUNDATION_V8,
+ .compatible = "arm,arm-v8",
+ .init = arm_cpu__vcpu_init,
+};
+
+static struct kvm_arm_target target_cortex_a57 = {
+ .id = KVM_ARM_TARGET_CORTEX_A57,
+ .compatible = "arm,cortex-a57",
+ .init = arm_cpu__vcpu_init,
+};
+
+static int arm_cpu__core_init(struct kvm *kvm)
+{
+ return (kvm_cpu__register_kvm_arm_target(&target_aem_v8) ||
+ kvm_cpu__register_kvm_arm_target(&target_foundation_v8) ||
+ kvm_cpu__register_kvm_arm_target(&target_cortex_a57));
+}
+core_init(arm_cpu__core_init);
deleted file mode 100644
@@ -1,80 +0,0 @@
-#include "kvm/fdt.h"
-#include "kvm/kvm.h"
-#include "kvm/kvm-cpu.h"
-#include "kvm/util.h"
-
-#include "arm-common/gic.h"
-
-#include <linux/byteorder.h>
-#include <linux/types.h>
-
-static void generate_timer_nodes(void *fdt, struct kvm *kvm)
-{
- u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \
- & GIC_FDT_IRQ_PPI_CPU_MASK;
- u32 irq_prop[] = {
- cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(13),
- cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
-
- cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(14),
- cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
-
- cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(11),
- cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
-
- cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(10),
- cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
- };
-
- _FDT(fdt_begin_node(fdt, "timer"));
- _FDT(fdt_property_string(fdt, "compatible", "arm,armv8-timer"));
- _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
- _FDT(fdt_end_node(fdt));
-}
-
-static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
-{
- gic__generate_fdt_nodes(fdt, gic_phandle);
- generate_timer_nodes(fdt, kvm);
-}
-
-
-static int cortex_a57__vcpu_init(struct kvm_cpu *vcpu)
-{
- vcpu->generate_fdt_nodes = generate_fdt_nodes;
- return 0;
-}
-
-/*
- * As far as userspace is concerned, both of these implementations are
- * extremely similar.
- */
-static struct kvm_arm_target target_aem_v8 = {
- .id = KVM_ARM_TARGET_AEM_V8,
- .compatible = "arm,arm-v8",
- .init = cortex_a57__vcpu_init,
-};
-
-static struct kvm_arm_target target_foundation_v8 = {
- .id = KVM_ARM_TARGET_FOUNDATION_V8,
- .compatible = "arm,arm-v8",
- .init = cortex_a57__vcpu_init,
-};
-
-static struct kvm_arm_target target_cortex_a57 = {
- .id = KVM_ARM_TARGET_CORTEX_A57,
- .compatible = "arm,cortex-a57",
- .init = cortex_a57__vcpu_init,
-};
-
-static int cortex_a57__core_init(struct kvm *kvm)
-{
- return (kvm_cpu__register_kvm_arm_target(&target_aem_v8) ||
- kvm_cpu__register_kvm_arm_target(&target_foundation_v8) ||
- kvm_cpu__register_kvm_arm_target(&target_cortex_a57));
-}
-core_init(cortex_a57__core_init);
new file mode 100644
@@ -0,0 +1,6 @@
+#ifndef ARM_COMMON__TIMER_H
+#define ARM_COMMON__TIMER_H
+
+void timer__generate_fdt_nodes(void *fdt, struct kvm *kvm, int *irqs);
+
+#endif /* ARM_COMMON__TIMER_H */
new file mode 100644
@@ -0,0 +1,38 @@
+#include "kvm/fdt.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/util.h"
+
+#include "arm-common/gic.h"
+#include "arm-common/timer.h"
+
+void timer__generate_fdt_nodes(void *fdt, struct kvm *kvm, int *irqs)
+{
+ const char compatible[] = "arm,armv8-timer\0arm,armv7-timer";
+
+ u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \
+ & GIC_FDT_IRQ_PPI_CPU_MASK;
+ u32 irq_prop[] = {
+ cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
+ cpu_to_fdt32(irqs[0]),
+ cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
+
+ cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
+ cpu_to_fdt32(irqs[1]),
+ cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
+
+ cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
+ cpu_to_fdt32(irqs[2]),
+ cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
+
+ cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
+ cpu_to_fdt32(irqs[3]),
+ cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
+ };
+
+ _FDT(fdt_begin_node(fdt, "timer"));
+ _FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible)));
+ _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
+ _FDT(fdt_end_node(fdt));
+}
+