xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: manish.jaggi@linaro.org
To: xen-devel@lists.xenproject.org, julien.grall@linaro.org,
	sameer.goel@linaro.org, andre.przywara@linaro.org
Cc: Manish Jaggi <manish.jaggi@linaro.org>, manish.jaggi@cavium.com
Subject: [RFC 10/11] IORT parsing functions to prepare requesterId maps
Date: Tue,  2 Jan 2018 14:58:08 +0530	[thread overview]
Message-ID: <20180102092809.1841-11-manish.jaggi@linaro.org> (raw)
In-Reply-To: <20180102092809.1841-1-manish.jaggi@linaro.org>

From: Manish Jaggi <manish.jaggi@linaro.org>

This patch adds functions to parse the IORT and use the requesterID public API
to update the maps.

Signed-off-by: Manish jaggi <manish.jaggi@linaro.org>
---
 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();
 }
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2018-01-02  9:29 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
2018-01-02  9:27 ` [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid manish.jaggi
2018-01-16 17:53   ` Julien Grall
2018-01-16 18:31   ` Julien Grall
2018-01-19  6:05     ` Manish Jaggi
2018-01-19 12:03       ` Julien Grall
2018-01-22  5:07         ` Manish Jaggi
2018-01-22 13:40           ` Julien Grall
2018-01-02  9:28 ` [RFC 02/11] acpi: arm: API to query estimated size of hardware domain's IORT manish.jaggi
2018-01-16 18:52   ` Julien Grall
2018-01-19  6:10     ` Manish Jaggi
2018-01-22 13:45       ` Julien Grall
2018-01-02  9:28 ` [RFC 03/11] acpi: arm: Code to generate Hardware Domains IORT manish.jaggi
2018-01-18 18:32   ` Julien Grall
2018-01-02  9:28 ` [RFC 04/11] Import iort.c and acpi_iort.h manish.jaggi
2018-01-02  9:28 ` [RFC 05/11] Import fwnode.h from linux manish.jaggi
2018-01-02  9:28 ` [RFC 06/11] fwnode xen spacific changes manish.jaggi
2018-01-18 18:51   ` Julien Grall
2018-03-06 10:27     ` Manish Jaggi
2018-03-06 14:29       ` Julien Grall
2018-03-06 13:43     ` Manish Jaggi
2018-03-06 13:44       ` Manish Jaggi
2018-03-06 14:22         ` Julien Grall
2018-01-02  9:28 ` [RFC 07/11] Add kernel helper functions manish.jaggi
2018-01-18 18:55   ` Julien Grall
2018-01-19  9:33     ` Jan Beulich
2018-02-08 21:56   ` Sameer Goel
2018-01-02  9:28 ` [RFC 08/11] Add ACPI_IORT config manish.jaggi
2018-01-18 19:01   ` Julien Grall
2018-01-02  9:28 ` [RFC 09/11] Xen IORT Changes manish.jaggi
2018-01-18 19:10   ` Julien Grall
2018-01-02  9:28 ` manish.jaggi [this message]
2018-01-02  9:28 ` [RFC 11/11] Add to_pci_dev macro manish.jaggi
2018-01-18 19:15   ` Julien Grall
2018-02-08 21:54   ` Sameer Goel
2018-01-16 17:53 ` [RFC 00/11] acpi: arm: IORT Support for Xen Julien Grall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180102092809.1841-11-manish.jaggi@linaro.org \
    --to=manish.jaggi@linaro.org \
    --cc=andre.przywara@linaro.org \
    --cc=julien.grall@linaro.org \
    --cc=manish.jaggi@cavium.com \
    --cc=sameer.goel@linaro.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).