From patchwork Tue Jan 2 09:28:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manish Jaggi X-Patchwork-Id: 123105 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp8755163qgn; Tue, 2 Jan 2018 01:31:18 -0800 (PST) X-Google-Smtp-Source: ACJfBot6ay4DayEQHs9WhMM9DfcZtkK05A1CxEVmU2w4BPQBtq/xKX+yebcgxsRypn+6fMBUA+yh X-Received: by 10.36.164.74 with SMTP id v10mr60293371iti.26.1514885478314; Tue, 02 Jan 2018 01:31:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1514885478; cv=none; d=google.com; s=arc-20160816; b=ZJ3nZwIALmsKBtPvqr4xfog1fY8Zpfk8XOfnJPvzcbCAA9m9krZH7ATGvboPCST1Fl LVCLMkHLaPDy8Nqj0lV7o+4MIiko3OWMmmba5pEM36cWz2BXRGpDm4Xv3IYYpuiXz6qc SeNJ+K3eYMYWVtCd5IMkxl7mF2gD40/0sHY4NEH8vPcyN3YLa6ak7viUSq+KkKvgeRw6 8/AACuPW9/p0SR9heoCfTmW7l5Fdnmt9Q2528IohwNEVJCNxf8lX798Ve8eXhA4DCKx1 +kkfjc49prjhL3ZWABt1vkKcbYgMH8cIGB74PTFxS77kHoLWFvTeVDspPgPFkbo0UYN/ vekg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=COcoFmlrU8mhyXk4S+VWMRuBtsObcO7ckN5494Re3mY=; b=Jj7BKy+61VkbpFeKx+fnnFcIUu/KsJNwmO75z++9YAWVl3rJVXAhfEeg4d3b2IT0XY uTomxV44BL1ter8muQ2O9fFFF3za7Mft57Av429Y1KV3Cve4OX6JUR0WKaL+K3LOKgoX NTzFWteUIG18vsbrHZv3E7d/57Fkdspkh+Cr1MSxmRV0d6a+vfnQnpnxjPu+CYDiMc5r kSkD+us2rh63QupFYjxNanGz+dttGWP2K32AZJtMQoZwMyVmJfvVoVkNvD5y7gVinzX1 4c0rViaUjZTzqQky4G4IwMFLR2A2aOfR5BAFmeqiq/POgCWseqFxxaAw2YF/+QVqrdRs JYFw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=EVCv39Z8; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id u140si23538166itc.55.2018.01.02.01.31.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Jan 2018 01:31:18 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=EVCv39Z8; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eWIsj-0002na-Jv; Tue, 02 Jan 2018 09:29:13 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eWIsi-0002mU-Cr for xen-devel@lists.xenproject.org; Tue, 02 Jan 2018 09:29:12 +0000 X-Inumbo-ID: 3c014eb4-ef9f-11e7-b4a6-bc764e045a96 Received: from mail-pl0-x243.google.com (unknown [2607:f8b0:400e:c01::243]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 3c014eb4-ef9f-11e7-b4a6-bc764e045a96; Tue, 02 Jan 2018 10:28:04 +0100 (CET) Received: by mail-pl0-x243.google.com with SMTP id s10so28314522plj.5 for ; Tue, 02 Jan 2018 01:29:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=R6aXx5d6zfzvk/s5m+EwifCdhy5Kayh9+ltEzmfvJnY=; b=EVCv39Z8Os3uSXpWw+xz+/ZWmv6QZqjmL6KlpwkPdRTnebHNfQ9HwwTgZfCKpVkDPw acCxjoQmOylAD05jg677i8IiTXZoHGiWIaYebRkOOhNcgk4RrPQuY3i4VGcCT+k/Tp2b pq86wyMsFsRsQ7NDEmwCB//ASNu+sB4lpvsRI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=R6aXx5d6zfzvk/s5m+EwifCdhy5Kayh9+ltEzmfvJnY=; b=M+IcVpa7QwfyJcwP4pFBy27AVVMeTH/7GKYnl57fH1fuygt/riO0J03zOMDeXkRL2M m5aK2RKMl5tKBZ1U02+qamXKop7zfMOGuJZr/T0dGUC9ISWWJc9ORTWnN7R78KEzjimX FRYpx+ZilOAV1IV8VfDMeCdB44vBiNhCl6Mbd+srgxAi3thvUnt0s0NHyFodmYYjkaA7 KgFrRJQthSiJuyap/DDtM9ZwMIcBwvqIrkGXJ6XNlexxeNdV72a7AAoKYbU+cVbvpLY8 WD0vh7MxESJN8wA5ciSkk9uuBjJhV84G5uxuCbPwU4quzh+x/fh2D4FiLdi8m7TMWeEj NhWw== X-Gm-Message-State: AKGB3mL0NpkaMV8raLJnapuuUyoTRZmWFi/1mPfQh1FR5K4ts0lFzVSK 85ZtR5VfVTr5fayWg7XE38iUsYCgtnY= X-Received: by 10.84.131.130 with SMTP id d2mr44591445pld.226.1514885349942; Tue, 02 Jan 2018 01:29:09 -0800 (PST) Received: from thunder-dev-box.domain.name ([111.93.218.67]) by smtp.gmail.com with ESMTPSA id e8sm22065207pgs.44.2018.01.02.01.29.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Jan 2018 01:29:09 -0800 (PST) From: manish.jaggi@linaro.org To: xen-devel@lists.xenproject.org, julien.grall@linaro.org, sameer.goel@linaro.org, andre.przywara@linaro.org Date: Tue, 2 Jan 2018 14:58:08 +0530 Message-Id: <20180102092809.1841-11-manish.jaggi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180102092809.1841-1-manish.jaggi@linaro.org> References: <20180102092809.1841-1-manish.jaggi@linaro.org> Cc: Manish Jaggi , manish.jaggi@cavium.com Subject: [Xen-devel] [RFC 10/11] IORT parsing functions to prepare requesterId maps X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" From: Manish Jaggi This patch adds functions to parse the IORT and use the requesterID public API to update the maps. Signed-off-by: Manish jaggi --- xen/drivers/acpi/arm/iort.c | 200 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/xen/drivers/acpi/arm/iort.c b/xen/drivers/acpi/arm/iort.c index a47ee2df4c..00a9f18046 100644 --- a/xen/drivers/acpi/arm/iort.c +++ b/xen/drivers/acpi/arm/iort.c @@ -353,6 +353,205 @@ static inline struct fwnode_handle *acpi_alloc_fwnode_static(void) return fwnode; } +static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) +{ + return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr); +} + +static inline bool is_acpi_static_node(const struct fwnode_handle *fwnode) +{ + return !IS_ERR_OR_NULL(fwnode) && + fwnode->ops == &acpi_static_fwnode_ops; +} + +static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode) +{ + if (WARN_ON(!is_acpi_static_node(fwnode))) + return; + + kfree(fwnode); +} +int fixup_rid_deviceid_map(struct acpi_iort_node *inode, + struct acpi_iort_id_mapping *pci_idmap, + struct acpi_iort_node *smmu_node) +{ + + unsigned int p_input_base, p_output_base, p_id_count; + unsigned int s_input_base, s_output_base, s_id_count; + unsigned int delta, i; + int ret = 0; + struct acpi_iort_id_mapping *smmu_idmap = NULL; + struct acpi_iort_node *its_node; + struct acpi_table_iort *iort; + + iort = (struct acpi_table_iort*) iort_table; + + p_input_base = pci_idmap->input_base; + p_output_base = pci_idmap->output_base; + p_id_count = pci_idmap->id_count; + + smmu_idmap = (struct acpi_iort_id_mapping*) ((u8*) smmu_node + + smmu_node->mapping_offset); + + for (i = 0; i < smmu_node->mapping_count; i++, smmu_idmap++) { + s_input_base = smmu_idmap->input_base; + s_output_base = smmu_idmap->output_base; + s_id_count = smmu_idmap->id_count; + its_node = ACPI_ADD_PTR(struct acpi_iort_node, iort, + smmu_idmap->output_reference); + + if (s_input_base <= p_output_base) { + int count; + if (s_input_base + s_id_count < p_output_base) + continue; + + delta = p_output_base - s_input_base; + count = s_input_base + s_id_count <= p_output_base + + p_id_count ? s_id_count - delta : p_id_count; + + ret = add_rid_deviceid_map (inode, its_node, + p_input_base, + s_output_base + delta, + count); + if (ret) + return ret; + } else { + int count; + if (p_output_base + p_id_count < s_input_base) + continue; + + delta = s_input_base - p_output_base; + count = s_input_base + s_id_count < p_output_base + + p_id_count ? s_id_count : p_id_count - delta; + + ret = add_rid_deviceid_map (inode, its_node, + p_input_base + delta, + s_output_base, count); + + if (ret) + return ret; + } + } + + return ret; +} + +void parse_pcirc_node(struct acpi_iort_node *iort_node) +{ + int j , ret; + struct acpi_iort_id_mapping *idmap; + struct acpi_iort_node *onode; + struct acpi_table_iort *iort; + + iort = (struct acpi_table_iort*) iort_table; + idmap = ACPI_ADD_PTR(struct acpi_iort_id_mapping, iort_node, + iort_node->mapping_offset); + + /* iterate over idmap */ + for ( j = 0; j < iort_node->mapping_count; j++ ) { + + struct acpi_iort_node *its_node; + struct acpi_iort_node *smmu_node; + onode = ACPI_ADD_PTR(struct acpi_iort_node, iort, + idmap->output_reference); + + switch (onode->type) { + case ACPI_IORT_NODE_ITS_GROUP: + + its_node = ACPI_ADD_PTR(struct acpi_iort_node, iort, + idmap->output_reference); + + ret = add_rid_deviceid_map(iort_node, its_node, + idmap->input_base, + idmap->output_base, + idmap->id_count); + if (ret) { + pr_err("%s: add_rid_deviceid_map" + "failed with ret=%d \r\n", + __func__, ret); + break; + } + break; + + case ACPI_IORT_NODE_SMMU: + case ACPI_IORT_NODE_SMMU_V3: + + smmu_node = ACPI_ADD_PTR( + struct acpi_iort_node, + iort_table, + idmap->output_reference); + + ret = add_rid_streamid_map(iort_node, + smmu_node, + idmap->input_base, + idmap->output_base, + idmap->id_count); + if (ret) { + pr_err("%s: add_rid_streamid_map" + "failed with ret=%d \r\n", + __func__, ret); + break; + } + + ret = fixup_rid_deviceid_map(iort_node, idmap, + onode); + if (ret) { + pr_err("%s: fixup_rid_deviceid_map" + "failed with ret=%d \r\n", + __func__, ret); + break; + } + break; + } + idmap++; + } +} + +void parse_smmu_node(struct acpi_iort_node *iort_node) +{ + int ret; + struct fwnode_handle *fwnode; + fwnode = acpi_alloc_fwnode_static(); + if (!fwnode) + return; + + iort_set_fwnode(iort_node, fwnode); + ret = iort_add_smmu_platform_device(iort_node); + if (ret) + acpi_free_fwnode_static(fwnode); +} + +void parse_iort(void) +{ + struct acpi_iort_node *iort_node, *iort_end; + struct acpi_table_iort *iort; + int i; + + iort = (struct acpi_table_iort*) iort_table; + iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort, + iort->node_offset); + iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort, + iort->header.length); + init_ridmaps(); + + for (i = 0; i < iort->node_count; i++) { + if ( iort_node >= iort_end ) { + pr_err("iort node pointer overflows, bad table\n"); + return; + } + + if ( iort_node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ) + parse_pcirc_node(iort_node); + else if ( (iort_node->type == ACPI_IORT_NODE_SMMU || + iort_node->type == ACPI_IORT_NODE_SMMU_V3) ) + parse_smmu_node(iort_node); + + iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node, + iort_node->length); + } +} + + void __init acpi_iort_init(void) { acpi_status status; @@ -366,4 +565,5 @@ void __init acpi_iort_init(void) } return; } + parse_iort(); }