[Intel-gfx] [PATCH] drm/i915: Engine discovery, the HW bits

Chris Wilson chris at chris-wilson.co.uk
Thu Mar 14 16:24:17 UTC 2019


Not only do we want to discover the user topology of the engines,
sometimes we also want to delve into the inner most workings of the HW,
such as determining context image sizes and mmio offset, in a platform
independent way.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Cc: Mika Kuoppala <mika.kuoppala at intel.com>
---
 drivers/gpu/drm/i915/i915_query.c | 60 +++++++++++++++++++++++++++++++
 include/uapi/drm/i915_drm.h       | 21 +++++++++++
 2 files changed, 81 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c
index 782183b78f49..778d8417ef0e 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -96,9 +96,69 @@ static int query_topology_info(struct drm_i915_private *dev_priv,
 	return total_length;
 }
 
+static int
+query_engine_hw_info_v1(struct drm_i915_private *i915,
+			struct drm_i915_query_item *query_item)
+{
+	struct drm_i915_query_engine_hw_info_v1 __user *query_ptr =
+		u64_to_user_ptr(query_item->data_ptr);
+	struct drm_i915_query_engine_hw_info_v1 query;
+	struct i915_engine_hw_info_v1 __user *out;
+	struct i915_engine_hw_info_v1 info = {};
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+	int ret, i;
+	size_t sz;
+
+	if (query_item->flags)
+		return -EINVAL;
+
+	sz = struct_size(query_ptr, engines, RUNTIME_INFO(i915)->num_engines);
+	if (sz > INT_MAX)
+		return -EINVAL;
+
+	ret = copy_query_item(&query, sizeof(query), sz, query_item);
+	if (ret)
+		return ret;
+
+	if (query.num_engines)
+		return -EINVAL;
+
+	if (query.flags)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(query.rsvd); i++) {
+		if (query.rsvd[i])
+			return -EINVAL;
+	}
+
+	query.flags |= I915_QUERY_HW_INFO_HAS_HW_ID;
+	query.flags |= I915_QUERY_HW_INFO_HAS_MMIO_BASE;
+	query.flags |= I915_QUERY_HW_INFO_HAS_CONTEXT_SIZE;
+
+	out = query_ptr->engines;
+	for_each_engine(engine, i915, id) {
+		info.hw_id = engine->hw_id;
+		info.mmio_base = engine->mmio_base;
+		info.context_size = engine->context_size;
+
+		if (__copy_to_user(out, &info, sizeof(info)))
+			return -EFAULT;
+
+		out++;
+	}
+	query.num_engines = out - query_ptr->engines;
+
+	if (__copy_to_user(query_ptr, &query, sizeof(query)))
+		return -EFAULT;
+
+	return sz;
+}
+
 static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
 					struct drm_i915_query_item *query_item) = {
 	query_topology_info,
+	query_engine_hw_info_v1,
 };
 
 int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 08f680dd2b1c..3c684afd7bb6 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1982,6 +1982,27 @@ struct drm_i915_query_item {
 	__u64 data_ptr;
 };
 
+struct i915_engine_hw_info_v1 {
+	__u64 flags;
+
+	__u32 hw_id;
+	__u32 mmio_base;
+	__u32 context_size;
+
+	__u32 rsvd[9];
+};
+
+struct drm_i915_query_engine_hw_info_v1 {
+	__u32 num_engines;
+	__u32 flags;
+#define I915_QUERY_HW_INFO_HAS_HW_ID		(1u << 0)
+#define I915_QUERY_HW_INFO_HAS_MMIO_BASE	(1u << 1)
+#define I915_QUERY_HW_INFO_HAS_CONTEXT_SIZE	(1u << 2)
+	__u32 rsvd[10]; /* mbz */
+
+	struct i915_engine_hw_info_v1 engines[0];
+};
+
 struct drm_i915_query {
 	__u32 num_items;
 
-- 
2.20.1



More information about the Intel-gfx mailing list