From patchwork Thu Aug 13 10:44:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 52367 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by patches.linaro.org (Postfix) with ESMTPS id DC47A22EC6 for ; Thu, 13 Aug 2015 10:52:47 +0000 (UTC) Received: by lagz9 with SMTP id z9sf15496476lag.3 for ; Thu, 13 Aug 2015 03:52:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=cmeQ3bjElKnNjjKWCy/g+KY5h8nMKochszppep6/9iU=; b=cuqmq9giyrKhHs3UWOUd6kFBjjAoluyu0o5AUuRhIUsZm1zdRW7CkXF1+ONZOsZhuf p1tJIsSz9Nzt4cHWCKLvA4depm7faI9jZ3vS8X4obVBmTrv6bux5sewKXIcPhOTIjttP oBfhBoi68A9dcal+0x+cX1OuPf4rxjV0H9AeBVGNAb7mvgsjpph9YRkAmgVybQwSDoQs DCXAUuDOV9AH1uiWLsaeuah2fpJhiYSZsLQrbukWVQOCNyGAJjSw1VR/Iqw53UU4Hmev ZSnW3hR6IU9Fd3qjiHKBYsViBtc2cnAXAGhTNQbAkxXL23SJlgU+QnB4CL+ZJ6OQDZdY m4Yg== X-Gm-Message-State: ALoCoQl9GBjq8juXECq1i/9D0DAoczHVN4kVKKS8x54NzHjPSqfMCIppwfPjEwmr7HGb3YfO8JCv X-Received: by 10.152.25.233 with SMTP id f9mr10974197lag.5.1439463166821; Thu, 13 Aug 2015 03:52:46 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.1.73 with SMTP id 9ls146418lak.17.gmail; Thu, 13 Aug 2015 03:52:46 -0700 (PDT) X-Received: by 10.112.209.35 with SMTP id mj3mr36601164lbc.77.1439463166658; Thu, 13 Aug 2015 03:52:46 -0700 (PDT) Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com. [209.85.217.177]) by mx.google.com with ESMTPS id ce1si1807532lbd.70.2015.08.13.03.52.46 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Aug 2015 03:52:46 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.177 as permitted sender) client-ip=209.85.217.177; Received: by lbbtg9 with SMTP id tg9so24946593lbb.1 for ; Thu, 13 Aug 2015 03:52:46 -0700 (PDT) X-Received: by 10.112.166.2 with SMTP id zc2mr35342573lbb.29.1439463166205; Thu, 13 Aug 2015 03:52:46 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.7.198 with SMTP id l6csp860694lba; Thu, 13 Aug 2015 03:52:44 -0700 (PDT) X-Received: by 10.107.10.162 with SMTP id 34mr6015924iok.139.1439463162465; Thu, 13 Aug 2015 03:52:42 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id hy5si1184424igb.88.2015.08.13.03.52.41 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 13 Aug 2015 03:52:42 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:41695 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZPq7l-0001YQ-4r for patch@linaro.org; Thu, 13 Aug 2015 06:52:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35971) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZPq0L-0005Qc-Mu for qemu-devel@nongnu.org; Thu, 13 Aug 2015 06:45:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZPq0H-0005Ht-TQ for qemu-devel@nongnu.org; Thu, 13 Aug 2015 06:45:01 -0400 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:34909) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZPq0H-0005DT-JC for qemu-devel@nongnu.org; Thu, 13 Aug 2015 06:44:57 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1ZPq08-00071g-7j for qemu-devel@nongnu.org; Thu, 13 Aug 2015 11:44:48 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 13 Aug 2015 11:44:40 +0100 Message-Id: <1439462687-26903-21-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1439462687-26903-1-git-send-email-peter.maydell@linaro.org> References: <1439462687-26903-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Subject: [Qemu-devel] [PULL 20/27] hw/arm/gic: Kill code duplication X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.177 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Pavel Fedin Extracted duplicated initialization code from SW-emulated and KVM GIC implementations and put into gic_init_irqs_and_mmio() Signed-off-by: Pavel Fedin Message-id: 8ea5b2781ef39cb5989420987fc73c70e377687d.1438758065.git.p.fedin@samsung.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/intc/arm_gic.c | 64 ++++++++++++---------------------------- hw/intc/arm_gic_common.c | 41 +++++++++++++++++++++++++ hw/intc/arm_gic_kvm.c | 28 +----------------- include/hw/intc/arm_gic_common.h | 3 ++ 4 files changed, 64 insertions(+), 72 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 454bfd7..a8c5d19 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -922,12 +922,6 @@ static MemTxResult gic_dist_write(void *opaque, hwaddr offset, uint64_t data, } } -static const MemoryRegionOps gic_dist_ops = { - .read_with_attrs = gic_dist_read, - .write_with_attrs = gic_dist_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset, uint64_t *data, MemTxAttrs attrs) { @@ -1056,10 +1050,17 @@ static MemTxResult gic_do_cpu_write(void *opaque, hwaddr addr, return gic_cpu_write(s, id, addr, value, attrs); } -static const MemoryRegionOps gic_thiscpu_ops = { - .read_with_attrs = gic_thiscpu_read, - .write_with_attrs = gic_thiscpu_write, - .endianness = DEVICE_NATIVE_ENDIAN, +static const MemoryRegionOps gic_ops[2] = { + { + .read_with_attrs = gic_dist_read, + .write_with_attrs = gic_dist_write, + .endianness = DEVICE_NATIVE_ENDIAN, + }, + { + .read_with_attrs = gic_thiscpu_read, + .write_with_attrs = gic_thiscpu_write, + .endianness = DEVICE_NATIVE_ENDIAN, + } }; static const MemoryRegionOps gic_cpu_ops = { @@ -1068,31 +1069,10 @@ static const MemoryRegionOps gic_cpu_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +/* This function is used by nvic model */ void gic_init_irqs_and_distributor(GICState *s) { - SysBusDevice *sbd = SYS_BUS_DEVICE(s); - int i; - - i = s->num_irq - GIC_INTERNAL; - /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU. - * GPIO array layout is thus: - * [0..N-1] SPIs - * [N..N+31] PPIs for CPU 0 - * [N+32..N+63] PPIs for CPU 1 - * ... - */ - if (s->revision != REV_NVIC) { - i += (GIC_INTERNAL * s->num_cpu); - } - qdev_init_gpio_in(DEVICE(s), gic_set_irq, i); - for (i = 0; i < NUM_CPU(s); i++) { - sysbus_init_irq(sbd, &s->parent_irq[i]); - } - for (i = 0; i < NUM_CPU(s); i++) { - sysbus_init_irq(sbd, &s->parent_fiq[i]); - } - memory_region_init_io(&s->iomem, OBJECT(s), &gic_dist_ops, s, - "gic_dist", 0x1000); + gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops); } static void arm_gic_realize(DeviceState *dev, Error **errp) @@ -1110,28 +1090,22 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) return; } - gic_init_irqs_and_distributor(s); + /* This creates distributor and main CPU interface (s->cpuiomem[0]) */ + gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops); - /* Memory regions for the CPU interfaces (NVIC doesn't have these): - * a region for "CPU interface for this core", then a region for - * "CPU interface for core 0", "for core 1", ... + /* Extra core-specific regions for the CPU interfaces. This is + * necessary for "franken-GIC" implementations, for example on + * Exynos 4. * NB that the memory region size of 0x100 applies for the 11MPCore * and also cores following the GIC v1 spec (ie A9). * GIC v2 defines a larger memory region (0x1000) so this will need * to be extended when we implement A15. */ - memory_region_init_io(&s->cpuiomem[0], OBJECT(s), &gic_thiscpu_ops, s, - "gic_cpu", 0x100); for (i = 0; i < NUM_CPU(s); i++) { s->backref[i] = s; memory_region_init_io(&s->cpuiomem[i+1], OBJECT(s), &gic_cpu_ops, &s->backref[i], "gic_cpu", 0x100); - } - /* Distributor */ - sysbus_init_mmio(sbd, &s->iomem); - /* cpu interfaces (one for "current cpu" plus one per cpu) */ - for (i = 0; i <= NUM_CPU(s); i++) { - sysbus_init_mmio(sbd, &s->cpuiomem[i]); + sysbus_init_mmio(sbd, &s->cpuiomem[i+1]); } } diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index a64d071..fe64b51 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -84,6 +84,47 @@ static const VMStateDescription vmstate_gic = { } }; +void gic_init_irqs_and_mmio(GICState *s, qemu_irq_handler handler, + const MemoryRegionOps *ops) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(s); + int i = s->num_irq - GIC_INTERNAL; + + /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU. + * GPIO array layout is thus: + * [0..N-1] SPIs + * [N..N+31] PPIs for CPU 0 + * [N+32..N+63] PPIs for CPU 1 + * ... + */ + if (s->revision != REV_NVIC) { + i += (GIC_INTERNAL * s->num_cpu); + } + qdev_init_gpio_in(DEVICE(s), handler, i); + + for (i = 0; i < s->num_cpu; i++) { + sysbus_init_irq(sbd, &s->parent_irq[i]); + } + for (i = 0; i < s->num_cpu; i++) { + sysbus_init_irq(sbd, &s->parent_fiq[i]); + } + + /* Distributor */ + memory_region_init_io(&s->iomem, OBJECT(s), ops, s, "gic_dist", 0x1000); + sysbus_init_mmio(sbd, &s->iomem); + + if (s->revision != REV_NVIC) { + /* This is the main CPU interface "for this core". It is always + * present because it is required by both software emulation and KVM. + * NVIC is not handled here because its CPU interface is different, + * neither it can use KVM. + */ + memory_region_init_io(&s->cpuiomem[0], OBJECT(s), ops ? &ops[1] : NULL, + s, "gic_cpu", s->revision == 2 ? 0x1000 : 0x100); + sysbus_init_mmio(sbd, &s->cpuiomem[0]); + } +} + static void arm_gic_common_realize(DeviceState *dev, Error **errp) { GICState *s = ARM_GIC_COMMON(dev); diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index f56bff1..e5d0f67 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -543,7 +543,6 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp) { int i; GICState *s = KVM_ARM_GIC(dev); - SysBusDevice *sbd = SYS_BUS_DEVICE(dev); KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s); Error *local_err = NULL; int ret; @@ -560,32 +559,13 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp) return; } - i = s->num_irq - GIC_INTERNAL; - /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU. - * GPIO array layout is thus: - * [0..N-1] SPIs - * [N..N+31] PPIs for CPU 0 - * [N+32..N+63] PPIs for CPU 1 - * ... - */ - i += (GIC_INTERNAL * s->num_cpu); - qdev_init_gpio_in(dev, kvm_arm_gic_set_irq, i); + gic_init_irqs_and_mmio(s, kvm_arm_gic_set_irq, NULL); for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) { qemu_irq irq = qdev_get_gpio_in(dev, i); kvm_irqchip_set_qemuirq_gsi(kvm_state, irq, i); } - /* We never use our outbound IRQ/FIQ lines but provide them so that - * we maintain the same interface as the non-KVM GIC. - */ - for (i = 0; i < s->num_cpu; i++) { - sysbus_init_irq(sbd, &s->parent_irq[i]); - } - for (i = 0; i < s->num_cpu; i++) { - sysbus_init_irq(sbd, &s->parent_fiq[i]); - } - /* Try to create the device via the device control API */ s->dev_fd = -1; ret = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V2, false); @@ -609,9 +589,6 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp) } /* Distributor */ - memory_region_init_reservation(&s->iomem, OBJECT(s), - "kvm-gic_dist", 0x1000); - sysbus_init_mmio(sbd, &s->iomem); kvm_arm_register_device(&s->iomem, (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT) | KVM_VGIC_V2_ADDR_TYPE_DIST, @@ -622,9 +599,6 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp) * provide the "interface for core #N" memory regions, because * cores with a VGIC don't have those. */ - memory_region_init_reservation(&s->cpuiomem[0], OBJECT(s), - "kvm-gic_cpu", 0x1000); - sysbus_init_mmio(sbd, &s->cpuiomem[0]); kvm_arm_register_device(&s->cpuiomem[0], (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT) | KVM_VGIC_V2_ADDR_TYPE_CPU, diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index 899db3d..edca3e0 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -138,4 +138,7 @@ typedef struct ARMGICCommonClass { void (*post_load)(GICState *s); } ARMGICCommonClass; +void gic_init_irqs_and_mmio(GICState *s, qemu_irq_handler handler, + const MemoryRegionOps *ops); + #endif