From patchwork Tue Nov 17 09:40:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shannon Zhao X-Patchwork-Id: 7634871 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2741FBF90C for ; Tue, 17 Nov 2015 09:59:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 36EB720489 for ; Tue, 17 Nov 2015 09:59:22 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3AD1720483 for ; Tue, 17 Nov 2015 09:59:21 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zyd0g-0005CB-K7; Tue, 17 Nov 2015 09:57:10 +0000 Received: from mail-wm0-x22c.google.com ([2a00:1450:400c:c09::22c]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZycpH-0007lU-GR for linux-arm-kernel@lists.infradead.org; Tue, 17 Nov 2015 09:45:33 +0000 Received: by wmvv187 with SMTP id v187so217829227wmv.1 for ; Tue, 17 Nov 2015 01:45:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=F5M4KvGSwT+kViYl+WE69oW/I8h8cU5/gsnCmSzQY7U=; b=bHQfJEG0XB9p4QahllxgMh/UcXbuVZDGVfbUh2xQDnEgQteRqiBKg75h7kyKhZ5JZd 5r8qehFhskW1NXbIzKkjW52TD7y3IIHw7zrC/eZvYuTzVejMCrTygJvCyXPm8z2fNWd8 4u6zEBiNagcBXsTVW9hqThoIxUMmn+iONMOMDgwsaVRQoHyH9J2WMz7nqCqoZymG0/ym D3pEgAdgVrtifkSfqPI5z6ZigcX/WvyaTidVXJpCCMDx5qdeu0a7riY0Pf3/8v4zYhG9 2CRgUR8tHnzM1ou/O1dWl1PJ7p6NfHTkb3J80RXweh05WWMMkzBBHwBaF3P/mMa7h+59 qCsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=F5M4KvGSwT+kViYl+WE69oW/I8h8cU5/gsnCmSzQY7U=; b=Su6lhsnsyYT5hfSu8IsKndupSJ3DvpvZ7lNtAqhweJ7F+Bo2CUHWSuryM5bSdBbTXU STTHILlxSKe3Rs3J3OV4rNJ6iGf+9UY9vy9iI6QRMeeClxgLRh+xdxwJvHuyapNkxV+R WRk6qvDF1zfw8sLCMNRDeL8btTG1P4esp8GhiKJ6KPgPzkHEQ1aA4DTuj7SCjXcnPJgM XoVZ0Fb/xahe4TN8RBPsUBeHLt0qAVxuzsRcg2J1gqR/y77oZ3k6o0d1MZAqSMIfAb+N nxMoVD9zThEDj6N029jYeB+gj5UlKXG8wen9b1mXgA6WJXjHDIj/WMIPi2cw6Lkn/oCH GqNA== X-Gm-Message-State: ALoCoQkLghawX8nHxTHkViA+1y3NHbnEopJKwpYbD88hMTjcQmNU3pBIRHLjXVo0piNdvvMIlR84 X-Received: by 10.28.229.15 with SMTP id c15mr1521539wmh.76.1447753501801; Tue, 17 Nov 2015 01:45:01 -0800 (PST) Received: from localhost ([78.129.251.54]) by smtp.gmail.com with ESMTPSA id l20sm17425920wmd.20.2015.11.17.01.44.59 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 17 Nov 2015 01:45:01 -0800 (PST) From: shannon.zhao@linaro.org To: ian.campbell@citrix.com, stefano.stabellini@citrix.com, keir@xen.org, jbeulich@suse.com, andrew.cooper3@citrix.com, julien.grall@citrix.com, xen-devel@lists.xen.org Subject: [PATCH v3 26/62] arm/gic-v2: Add ACPI boot support for GICv2 Date: Tue, 17 Nov 2015 17:40:25 +0800 Message-Id: <1447753261-7552-27-git-send-email-shannon.zhao@linaro.org> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1447753261-7552-1-git-send-email-shannon.zhao@linaro.org> References: <1447753261-7552-1-git-send-email-shannon.zhao@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151117_014524_236600_C5487888 X-CRM114-Status: GOOD ( 15.77 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, hangaohuai@huawei.com, ard.biesheuvel@linaro.org, shannon.zhao@linaro.org, christoffer.dall@linaro.org, peter.huangpeng@huawei.com, david.vrabel@citrix.com, zhaoshenglong@huawei.com, linux-arm-kernel@lists.infradead.org, roger.pau@citrix.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,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 From: Parth Dixit ACPI on Xen hypervisor uses MADT table for proper GIC initialization. First get the GIC version from GIC Distributor. Then parse GIC related subtables, collect CPU interface and distributor addresses and call driver initialization function (which is hardware abstraction agnostic). In a similar way, FDT initialize GICv2. Signed-off-by: Tomasz Nowicki Signed-off-by: Hanjun Guo Signed-off-by: Naresh Bhat Signed-off-by: Parth Dixit Signed-off-by: Shannon Zhao --- xen/arch/arm/gic-v2.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index e31d38e..9a9fcd5 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include @@ -36,6 +38,7 @@ #include #include +#include /* * LR register definitions are GIC v2 specific. @@ -681,11 +684,113 @@ static void __init dt_gicv2_init(void) csize, vsize); } +#ifdef CONFIG_ACPI +static int __init +gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, + const unsigned long end) +{ + static int cpu_base_assigned = 0; + struct acpi_madt_generic_interrupt *processor; + + processor = (struct acpi_madt_generic_interrupt *)header; + + if ( BAD_MADT_ENTRY(processor, end) ) + return -EINVAL; + + /* Read from APIC table and fill up the GIC variables */ + if ( cpu_base_assigned == 0 ) + { + cbase = processor->base_address; + csize = SZ_8K; + hbase = processor->gich_base_address; + vbase = processor->gicv_base_address; + gicv2_info.maintenance_irq = processor->vgic_interrupt; + + if( processor->flags & ACPI_MADT_VGIC_IRQ_MODE ) + irq_set_type(gicv2_info.maintenance_irq, ACPI_IRQ_TYPE_EDGE_BOTH); + else + irq_set_type(gicv2_info.maintenance_irq, ACPI_IRQ_TYPE_LEVEL_MASK); + + cpu_base_assigned = 1; + } + else + { + if ( cbase != processor->base_address + || hbase != processor->gich_base_address + || vbase != processor->gicv_base_address + || gicv2_info.maintenance_irq != processor->vgic_interrupt ) + { + printk("GICv2: GICC entries are not same in MADT table\n"); + return -EINVAL; + } + } + + return 0; +} + +static int __init +gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_madt_generic_distributor *dist; + + dist = (struct acpi_madt_generic_distributor *)header; + + if ( BAD_MADT_ENTRY(dist, end) ) + return -EINVAL; + + dbase = dist->base_address; + + return 0; +} + +static void __init acpi_gicv2_init(void) +{ + acpi_status status; + struct acpi_table_header *table; + int count; + + status = acpi_get_table(ACPI_SIG_MADT, 0, &table); + + if ( ACPI_FAILURE(status) ) + { + const char *msg = acpi_format_exception(status); + + panic("GICv2: Failed to get MADT table, %s", msg); + } + + /* Collect CPU base addresses */ + count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt), + gic_acpi_parse_madt_cpu, table, + ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0); + if ( count <= 0 ) + panic("GICv2: No valid GICC entries exists"); + + /* + * Find distributor base address. We expect one distributor entry since + * ACPI 5.0 spec neither support multi-GIC instances nor GIC cascade. + */ + count = acpi_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt), + gic_acpi_parse_madt_distributor, table, + ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0); + if ( count <= 0 ) + panic("GICv2: No valid GICD entries exists"); +} +#else +static void __init acpi_gicv2_init(void) +{ +/* Should never reach here */ +} +#endif + static int __init gicv2_init(void) { uint32_t aliased_offset = 0; - dt_gicv2_init(); + if( acpi_disabled ) + dt_gicv2_init(); + else + acpi_gicv2_init(); printk("GICv2 initialization:\n" " gic_dist_addr=%"PRIpaddr"\n" @@ -793,6 +898,21 @@ DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC) .init = dt_gicv2_preinit, DT_DEVICE_END +#ifdef CONFIG_ACPI +/* Set up the GIC */ +static int __init acpi_gicv2_preinit(const void *data) +{ + gicv2_info.hw_version = GIC_V2; + register_gic_ops(&gicv2_ops); + + return 0; +} + +ACPI_DEVICE_START(agicv2, "GICv2", DEVICE_GIC) + .class_type = GIC_V2, + .init = acpi_gicv2_preinit, +ACPI_DEVICE_END +#endif /* * Local variables: * mode: C