From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jonathan Austin Subject: [PATCH 1/2] kvm tools: arm: extract common timer support code for ARM cpus Date: Fri, 27 Sep 2013 18:38:51 +0100 Message-ID: <1380303532-4460-2-git-send-email-jonathan.austin@arm.com> References: <1380303532-4460-1-git-send-email-jonathan.austin@arm.com> Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable Cc: penberg@kernel.org, marc.zyngier@arm.com, christoffer.dall@linaro.org, STFD002@freescale.com, ulrich.hecht@gmail.com, will.deacon@arm.com, Jonathan Austin To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Return-path: Received: from service87.mimecast.com ([91.220.42.44]:49201 "EHLO service87.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753797Ab3I0RjV (ORCPT ); Fri, 27 Sep 2013 13:39:21 -0400 In-Reply-To: <1380303532-4460-1-git-send-email-jonathan.austin@arm.com> Sender: kvm-owner@vger.kernel.org List-ID: The ARM V7 and V8 CPUs use the nearly identical support code for generating timer DT nodes as they both use ARM's architected timers. This code is curr= ently duplicated for AArch32 and AArch64. This cleanup patch generalises timer DT node generation to follow the same pattern as for the GIC. The ability of a DT node to contain multiple compat= ible strings is exploited to allow an identical DT node to be used on V7 and V8 platforms. Signed-off-by: Jonathan Austin Acked-by: Will Deacon --- tools/kvm/Makefile | 6 +-- tools/kvm/arm/aarch32/arm-cpu.c | 35 +++++++++++++ tools/kvm/arm/aarch32/cortex-a15.c | 61 ----------------------- tools/kvm/arm/aarch64/arm-cpu.c | 50 +++++++++++++++++++ tools/kvm/arm/aarch64/cortex-a57.c | 80 --------------------------= ---- tools/kvm/arm/include/arm-common/timer.h | 6 +++ tools/kvm/arm/timer.c | 38 ++++++++++++++ 7 files changed, 132 insertions(+), 144 deletions(-) create mode 100644 tools/kvm/arm/aarch32/arm-cpu.c delete mode 100644 tools/kvm/arm/aarch32/cortex-a15.c create mode 100644 tools/kvm/arm/aarch64/arm-cpu.c delete mode 100644 tools/kvm/arm/aarch64/cortex-a57.c create mode 100644 tools/kvm/arm/include/arm-common/timer.h create mode 100644 tools/kvm/arm/timer.c diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index b614aab..27fb2fb 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -157,12 +157,12 @@ endif =20 # ARM OBJS_ARM_COMMON=09=09:=3D arm/fdt.o arm/gic.o arm/ioport.o arm/irq.o \ -=09=09=09 arm/kvm.o arm/kvm-cpu.o +=09=09=09 arm/kvm.o arm/kvm-cpu.o arm/timer.o HDRS_ARM_COMMON=09=09:=3D arm/include ifeq ($(ARCH), arm) =09DEFINES=09=09+=3D -DCONFIG_ARM =09OBJS=09=09+=3D $(OBJS_ARM_COMMON) -=09OBJS=09=09+=3D arm/aarch32/cortex-a15.o +=09OBJS=09=09+=3D arm/aarch32/arm-cpu.o =09OBJS=09=09+=3D arm/aarch32/kvm-cpu.o =09ARCH_INCLUDE=09:=3D $(HDRS_ARM_COMMON) =09ARCH_INCLUDE=09+=3D -Iarm/aarch32/include @@ -175,7 +175,7 @@ endif ifeq ($(ARCH), arm64) =09DEFINES=09=09+=3D -DCONFIG_ARM64 =09OBJS=09=09+=3D $(OBJS_ARM_COMMON) -=09OBJS=09=09+=3D arm/aarch64/cortex-a57.o +=09OBJS=09=09+=3D arm/aarch64/arm-cpu.o =09OBJS=09=09+=3D arm/aarch64/kvm-cpu.o =09ARCH_INCLUDE=09:=3D $(HDRS_ARM_COMMON) =09ARCH_INCLUDE=09+=3D -Iarm/aarch64/include diff --git a/tools/kvm/arm/aarch32/arm-cpu.c b/tools/kvm/arm/aarch32/arm-cp= u.c new file mode 100644 index 0000000..8817d2a --- /dev/null +++ b/tools/kvm/arm/aarch32/arm-cpu.c @@ -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 +#include + +static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle= ) +{ +=09int timer_interrupts[4] =3D {13, 14, 11, 10}; + +=09gic__generate_fdt_nodes(fdt, gic_phandle); +=09timer__generate_fdt_nodes(fdt, kvm, timer_interrupts); +} + +static int arm_cpu__vcpu_init(struct kvm_cpu *vcpu) +{ +=09vcpu->generate_fdt_nodes =3D generate_fdt_nodes; +=09return 0; +} + +static struct kvm_arm_target target_cortex_a15 =3D { +=09.id=09=09=3D KVM_ARM_TARGET_CORTEX_A15, +=09.compatible=09=3D "arm,cortex-a15", +=09.init=09=09=3D arm_cpu__vcpu_init, +}; + +static int arm_cpu__core_init(struct kvm *kvm) +{ +=09return kvm_cpu__register_kvm_arm_target(&target_cortex_a15); +} +core_init(arm_cpu__core_init); diff --git a/tools/kvm/arm/aarch32/cortex-a15.c b/tools/kvm/arm/aarch32/cor= tex-a15.c deleted file mode 100644 index ca65af7..0000000 --- a/tools/kvm/arm/aarch32/cortex-a15.c +++ /dev/null @@ -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 -#include - -static void generate_timer_nodes(void *fdt, struct kvm *kvm) -{ -=09u32 cpu_mask =3D (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT= ) \ -=09=09 & GIC_FDT_IRQ_PPI_CPU_MASK; -=09u32 irq_prop[] =3D { -=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), -=09=09cpu_to_fdt32(13), -=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), - -=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), -=09=09cpu_to_fdt32(14), -=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), - -=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), -=09=09cpu_to_fdt32(11), -=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), - -=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), -=09=09cpu_to_fdt32(10), -=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), -=09}; - -=09_FDT(fdt_begin_node(fdt, "timer")); -=09_FDT(fdt_property_string(fdt, "compatible", "arm,armv7-timer")); -=09_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop))); -=09_FDT(fdt_end_node(fdt)); -} - -static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle= ) -{ -=09gic__generate_fdt_nodes(fdt, gic_phandle); -=09generate_timer_nodes(fdt, kvm); -} - -static int cortex_a15__vcpu_init(struct kvm_cpu *vcpu) -{ -=09vcpu->generate_fdt_nodes =3D generate_fdt_nodes; -=09return 0; -} - -static struct kvm_arm_target target_cortex_a15 =3D { -=09.id=09=09=3D KVM_ARM_TARGET_CORTEX_A15, -=09.compatible=09=3D "arm,cortex-a15", -=09.init=09=09=3D cortex_a15__vcpu_init, -}; - -static int cortex_a15__core_init(struct kvm *kvm) -{ -=09return kvm_cpu__register_kvm_arm_target(&target_cortex_a15); -} -core_init(cortex_a15__core_init); diff --git a/tools/kvm/arm/aarch64/arm-cpu.c b/tools/kvm/arm/aarch64/arm-cp= u.c new file mode 100644 index 0000000..ce5ea2f --- /dev/null +++ b/tools/kvm/arm/aarch64/arm-cpu.c @@ -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 +#include + +static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle= ) +{ +=09int timer_interrupts[4] =3D {13, 14, 11, 10}; +=09gic__generate_fdt_nodes(fdt, gic_phandle); +=09timer__generate_fdt_nodes(fdt, kvm, timer_interrupts); +} + + +static int arm_cpu__vcpu_init(struct kvm_cpu *vcpu) +{ +=09vcpu->generate_fdt_nodes =3D generate_fdt_nodes; +=09return 0; +} + +static struct kvm_arm_target target_aem_v8 =3D { +=09.id=09=09=3D KVM_ARM_TARGET_AEM_V8, +=09.compatible=09=3D "arm,arm-v8", +=09.init=09=09=3D arm_cpu__vcpu_init, +}; + +static struct kvm_arm_target target_foundation_v8 =3D { +=09.id=09=09=3D KVM_ARM_TARGET_FOUNDATION_V8, +=09.compatible=09=3D "arm,arm-v8", +=09.init=09=09=3D arm_cpu__vcpu_init, +}; + +static struct kvm_arm_target target_cortex_a57 =3D { +=09.id=09=09=3D KVM_ARM_TARGET_CORTEX_A57, +=09.compatible=09=3D "arm,cortex-a57", +=09.init=09=09=3D arm_cpu__vcpu_init, +}; + +static int arm_cpu__core_init(struct kvm *kvm) +{ +=09return (kvm_cpu__register_kvm_arm_target(&target_aem_v8) || +=09=09kvm_cpu__register_kvm_arm_target(&target_foundation_v8) || +=09=09kvm_cpu__register_kvm_arm_target(&target_cortex_a57)); +} +core_init(arm_cpu__core_init); diff --git a/tools/kvm/arm/aarch64/cortex-a57.c b/tools/kvm/arm/aarch64/cor= tex-a57.c deleted file mode 100644 index 0c340fb..0000000 --- a/tools/kvm/arm/aarch64/cortex-a57.c +++ /dev/null @@ -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 -#include - -static void generate_timer_nodes(void *fdt, struct kvm *kvm) -{ -=09u32 cpu_mask =3D (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT= ) \ -=09=09 & GIC_FDT_IRQ_PPI_CPU_MASK; -=09u32 irq_prop[] =3D { -=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), -=09=09cpu_to_fdt32(13), -=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), - -=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), -=09=09cpu_to_fdt32(14), -=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), - -=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), -=09=09cpu_to_fdt32(11), -=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), - -=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), -=09=09cpu_to_fdt32(10), -=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), -=09}; - -=09_FDT(fdt_begin_node(fdt, "timer")); -=09_FDT(fdt_property_string(fdt, "compatible", "arm,armv8-timer")); -=09_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop))); -=09_FDT(fdt_end_node(fdt)); -} - -static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle= ) -{ -=09gic__generate_fdt_nodes(fdt, gic_phandle); -=09generate_timer_nodes(fdt, kvm); -} - - -static int cortex_a57__vcpu_init(struct kvm_cpu *vcpu) -{ -=09vcpu->generate_fdt_nodes =3D generate_fdt_nodes; -=09return 0; -} - -/* - * As far as userspace is concerned, both of these implementations are - * extremely similar. - */ -static struct kvm_arm_target target_aem_v8 =3D { -=09.id=09=09=3D KVM_ARM_TARGET_AEM_V8, -=09.compatible=09=3D "arm,arm-v8", -=09.init=09=09=3D cortex_a57__vcpu_init, -}; - -static struct kvm_arm_target target_foundation_v8 =3D { -=09.id=09=09=3D KVM_ARM_TARGET_FOUNDATION_V8, -=09.compatible=09=3D "arm,arm-v8", -=09.init=09=09=3D cortex_a57__vcpu_init, -}; - -static struct kvm_arm_target target_cortex_a57 =3D { -=09.id=09=09=3D KVM_ARM_TARGET_CORTEX_A57, -=09.compatible=09=3D "arm,cortex-a57", -=09.init=09=09=3D cortex_a57__vcpu_init, -}; - -static int cortex_a57__core_init(struct kvm *kvm) -{ -=09return (kvm_cpu__register_kvm_arm_target(&target_aem_v8) || -=09=09kvm_cpu__register_kvm_arm_target(&target_foundation_v8) || -=09=09kvm_cpu__register_kvm_arm_target(&target_cortex_a57)); -} -core_init(cortex_a57__core_init); diff --git a/tools/kvm/arm/include/arm-common/timer.h b/tools/kvm/arm/inclu= de/arm-common/timer.h new file mode 100644 index 0000000..928e9ea --- /dev/null +++ b/tools/kvm/arm/include/arm-common/timer.h @@ -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 */ diff --git a/tools/kvm/arm/timer.c b/tools/kvm/arm/timer.c new file mode 100644 index 0000000..bd6a0bb --- /dev/null +++ b/tools/kvm/arm/timer.c @@ -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) +{ +=09const char compatible[] =3D "arm,armv8-timer\0arm,armv7-timer"; + +=09u32 cpu_mask =3D (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT= ) \ +=09=09 & GIC_FDT_IRQ_PPI_CPU_MASK; +=09u32 irq_prop[] =3D { +=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), +=09=09cpu_to_fdt32(irqs[0]), +=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), + +=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), +=09=09cpu_to_fdt32(irqs[1]), +=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), + +=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), +=09=09cpu_to_fdt32(irqs[2]), +=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), + +=09=09cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), +=09=09cpu_to_fdt32(irqs[3]), +=09=09cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), +=09}; + +=09_FDT(fdt_begin_node(fdt, "timer")); +=09_FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible))); +=09_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop))); +=09_FDT(fdt_end_node(fdt)); +} + --=20 1.7.9.5