From patchwork Wed Jul 20 17:04:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9240027 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9030160867 for ; Wed, 20 Jul 2016 17:04:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 79A7827CE5 for ; Wed, 20 Jul 2016 17:04:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6ED2C27D5D; Wed, 20 Jul 2016 17:04:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 07B4027D29 for ; Wed, 20 Jul 2016 17:04:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754809AbcGTRES (ORCPT ); Wed, 20 Jul 2016 13:04:18 -0400 Received: from foss.arm.com ([217.140.101.70]:43656 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754054AbcGTREC (ORCPT ); Wed, 20 Jul 2016 13:04:02 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 95EF0BBB; Wed, 20 Jul 2016 10:05:12 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E029E3F387; Wed, 20 Jul 2016 10:04:00 -0700 (PDT) From: Andre Przywara To: Will Deacon , Marc Zyngier Cc: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v7 09/15] arm: FDT: create MSI controller DT node Date: Wed, 20 Jul 2016 18:04:29 +0100 Message-Id: <20160720170435.28090-10-andre.przywara@arm.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20160720170435.28090-1-andre.przywara@arm.com> References: <20160720170435.28090-1-andre.przywara@arm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The ARM GICv3 ITS requires a separate device tree node to describe the ITS. Add this as a child to the GIC interrupt controller node to let a guest discover and use the ITS if the user requests it. Since we now need to specify #address-cells for the GIC node, we have to add two zeroes to the interrupt map to match that. Signed-off-by: Andre Przywara --- arm/gic.c | 23 ++++++++++++++++++++++- arm/pci.c | 12 ++++++++++-- include/kvm/fdt.h | 2 +- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/arm/gic.c b/arm/gic.c index 3544211..12139fe 100644 --- a/arm/gic.c +++ b/arm/gic.c @@ -259,7 +259,8 @@ late_init(gic__init_gic) void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type) { - const char *compatible; + const char *compatible, *msi_compatible = NULL; + u64 msi_prop[2]; u64 reg_prop[] = { cpu_to_fdt64(ARM_GIC_DIST_BASE), cpu_to_fdt64(ARM_GIC_DIST_SIZE), 0, 0, /* to be filled */ @@ -271,6 +272,9 @@ void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type) reg_prop[2] = cpu_to_fdt64(ARM_GIC_CPUI_BASE); reg_prop[3] = cpu_to_fdt64(ARM_GIC_CPUI_SIZE); break; + case IRQCHIP_GICV3_ITS: + msi_compatible = "arm,gic-v3-its"; + /* fall-through */ case IRQCHIP_GICV3: compatible = "arm,gic-v3"; reg_prop[2] = cpu_to_fdt64(gic_redists_base); @@ -286,6 +290,23 @@ void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type) _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0)); _FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop))); _FDT(fdt_property_cell(fdt, "phandle", fdt__get_phandle(PHANDLE_GIC))); + _FDT(fdt_property_cell(fdt, "#address-cells", 2)); + _FDT(fdt_property_cell(fdt, "#size-cells", 2)); + + if (msi_compatible) { + _FDT(fdt_property(fdt, "ranges", NULL, 0)); + + _FDT(fdt_begin_node(fdt, "msic")); + _FDT(fdt_property_string(fdt, "compatible", msi_compatible)); + _FDT(fdt_property(fdt, "msi-controller", NULL, 0)); + _FDT(fdt_property_cell(fdt, "phandle", + fdt__get_phandle(PHANDLE_MSI))); + msi_prop[0] = cpu_to_fdt64(gic_msi_base); + msi_prop[1] = cpu_to_fdt64(gic_msi_size); + _FDT(fdt_property(fdt, "reg", msi_prop, sizeof(msi_prop))); + _FDT(fdt_end_node(fdt)); + } + _FDT(fdt_end_node(fdt)); } diff --git a/arm/pci.c b/arm/pci.c index 9630657..104349a 100644 --- a/arm/pci.c +++ b/arm/pci.c @@ -18,6 +18,8 @@ struct of_gic_irq { struct of_interrupt_map_entry { struct of_pci_irq_mask pci_irq_mask; u32 gic_phandle; + u32 gic_addr_hi; + u32 gic_addr_lo; struct of_gic_irq gic_irq; } __attribute__((packed)); @@ -26,7 +28,7 @@ void pci__generate_fdt_nodes(void *fdt) struct device_header *dev_hdr; struct of_interrupt_map_entry irq_map[OF_PCI_IRQ_MAP_MAX]; unsigned nentries = 0; - u32 gic_phandle = fdt__get_phandle(PHANDLE_GIC); + u32 phandle; /* Bus range */ u32 bus_range[] = { cpu_to_fdt32(0), cpu_to_fdt32(1), }; /* Configuration Space */ @@ -65,7 +67,11 @@ void pci__generate_fdt_nodes(void *fdt) _FDT(fdt_property(fdt, "bus-range", bus_range, sizeof(bus_range))); _FDT(fdt_property(fdt, "reg", &cfg_reg_prop, sizeof(cfg_reg_prop))); _FDT(fdt_property(fdt, "ranges", ranges, sizeof(ranges))); + phandle = fdt__get_phandle(PHANDLE_MSI); + if (FDT_IS_VALID_PHANDLE(phandle)) + _FDT(fdt_property_cell(fdt, "msi-parent", phandle)); + phandle = fdt__get_phandle(PHANDLE_GIC); /* Generate the interrupt map ... */ dev_hdr = device__first_dev(DEVICE_BUS_PCI); while (dev_hdr && nentries < ARRAY_SIZE(irq_map)) { @@ -84,7 +90,9 @@ void pci__generate_fdt_nodes(void *fdt) }, .pci_pin = cpu_to_fdt32(pin), }, - .gic_phandle = cpu_to_fdt32(gic_phandle), + .gic_phandle = cpu_to_fdt32(phandle), + .gic_addr_hi = 0, + .gic_addr_lo = 0, .gic_irq = { .type = cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI), .num = cpu_to_fdt32(irq - GIC_SPI_IRQ_BASE), diff --git a/include/kvm/fdt.h b/include/kvm/fdt.h index cd2bb72..8006e8f 100644 --- a/include/kvm/fdt.h +++ b/include/kvm/fdt.h @@ -11,7 +11,7 @@ #define FDT_INVALID_PHANDLE 0 #define FDT_IS_VALID_PHANDLE(phandle) ((phandle) != FDT_INVALID_PHANDLE) -enum phandles {PHANDLE_GIC, PHANDLES_MAX}; +enum phandles {PHANDLE_GIC, PHANDLE_MSI, PHANDLES_MAX}; /* Those definitions are generic FDT values for specifying IRQ * types and are used in the Linux kernel internally as well as in