From patchwork Fri Sep 27 17:38:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Austin X-Patchwork-Id: 2956461 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 452399F244 for ; Fri, 27 Sep 2013 17:39:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C7A10202A1 for ; Fri, 27 Sep 2013 17:39:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4149520295 for ; Fri, 27 Sep 2013 17:39:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753967Ab3I0RjW (ORCPT ); Fri, 27 Sep 2013 13:39:22 -0400 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 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Fri, 27 Sep 2013 18:39:19 +0100 Received: from e102895-lin.cambridge.arm.com ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.0); Fri, 27 Sep 2013 18:39:18 +0100 From: Jonathan Austin To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu 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 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> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1380303532-4460-1-git-send-email-jonathan.austin@arm.com> References: <1380303532-4460-1-git-send-email-jonathan.austin@arm.com> X-OriginalArrivalTime: 27 Sep 2013 17:39:18.0655 (UTC) FILETIME=[7E33D8F0:01CEBBA8] X-MC-Unique: 113092718391909001 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-9.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 currently 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 compatible 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 # 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 diff --git a/tools/kvm/arm/aarch32/arm-cpu.c b/tools/kvm/arm/aarch32/arm-cpu.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) +{ + 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); diff --git a/tools/kvm/arm/aarch32/cortex-a15.c b/tools/kvm/arm/aarch32/cortex-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) -{ - 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); diff --git a/tools/kvm/arm/aarch64/arm-cpu.c b/tools/kvm/arm/aarch64/arm-cpu.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) +{ + 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); diff --git a/tools/kvm/arm/aarch64/cortex-a57.c b/tools/kvm/arm/aarch64/cortex-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) -{ - 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); diff --git a/tools/kvm/arm/include/arm-common/timer.h b/tools/kvm/arm/include/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) +{ + 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)); +} +