xref: /aosp_15_r20/external/igt-gpu-tools/lib/igt_gt.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2014 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  */
23*d83cc019SAndroid Build Coastguard Worker 
24*d83cc019SAndroid Build Coastguard Worker #include <limits.h>
25*d83cc019SAndroid Build Coastguard Worker #include <string.h>
26*d83cc019SAndroid Build Coastguard Worker #include <strings.h>
27*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
28*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
29*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
30*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
31*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
32*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
33*d83cc019SAndroid Build Coastguard Worker 
34*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
35*d83cc019SAndroid Build Coastguard Worker #include "igt_aux.h"
36*d83cc019SAndroid Build Coastguard Worker #include "igt_core.h"
37*d83cc019SAndroid Build Coastguard Worker #include "igt_gt.h"
38*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
39*d83cc019SAndroid Build Coastguard Worker #include "igt_debugfs.h"
40*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
41*d83cc019SAndroid Build Coastguard Worker #include "intel_reg.h"
42*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
43*d83cc019SAndroid Build Coastguard Worker #include "igt_dummyload.h"
44*d83cc019SAndroid Build Coastguard Worker #include "i915/gem_engine_topology.h"
45*d83cc019SAndroid Build Coastguard Worker 
46*d83cc019SAndroid Build Coastguard Worker /**
47*d83cc019SAndroid Build Coastguard Worker  * SECTION:igt_gt
48*d83cc019SAndroid Build Coastguard Worker  * @short_description: GT support library
49*d83cc019SAndroid Build Coastguard Worker  * @title: GT
50*d83cc019SAndroid Build Coastguard Worker  * @include: igt.h
51*d83cc019SAndroid Build Coastguard Worker  *
52*d83cc019SAndroid Build Coastguard Worker  * This library provides various auxiliary helper functions to handle general
53*d83cc019SAndroid Build Coastguard Worker  * interactions with the GT like forcewake handling, injecting hangs or stopping
54*d83cc019SAndroid Build Coastguard Worker  * engines.
55*d83cc019SAndroid Build Coastguard Worker  */
56*d83cc019SAndroid Build Coastguard Worker 
has_gpu_reset(int fd)57*d83cc019SAndroid Build Coastguard Worker static bool has_gpu_reset(int fd)
58*d83cc019SAndroid Build Coastguard Worker {
59*d83cc019SAndroid Build Coastguard Worker 	static int once = -1;
60*d83cc019SAndroid Build Coastguard Worker 	if (once < 0) {
61*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_getparam gp;
62*d83cc019SAndroid Build Coastguard Worker 		int val = 0;
63*d83cc019SAndroid Build Coastguard Worker 
64*d83cc019SAndroid Build Coastguard Worker 		memset(&gp, 0, sizeof(gp));
65*d83cc019SAndroid Build Coastguard Worker 		gp.param = 35; /* HAS_GPU_RESET */
66*d83cc019SAndroid Build Coastguard Worker 		gp.value = &val;
67*d83cc019SAndroid Build Coastguard Worker 
68*d83cc019SAndroid Build Coastguard Worker 		if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
69*d83cc019SAndroid Build Coastguard Worker 			once = intel_gen(intel_get_drm_devid(fd)) >= 5;
70*d83cc019SAndroid Build Coastguard Worker 		else
71*d83cc019SAndroid Build Coastguard Worker 			once = val > 0;
72*d83cc019SAndroid Build Coastguard Worker 	}
73*d83cc019SAndroid Build Coastguard Worker 	return once;
74*d83cc019SAndroid Build Coastguard Worker }
75*d83cc019SAndroid Build Coastguard Worker 
eat_error_state(int dev)76*d83cc019SAndroid Build Coastguard Worker static void eat_error_state(int dev)
77*d83cc019SAndroid Build Coastguard Worker {
78*d83cc019SAndroid Build Coastguard Worker 	int dir;
79*d83cc019SAndroid Build Coastguard Worker 
80*d83cc019SAndroid Build Coastguard Worker 	dir = igt_sysfs_open(dev);
81*d83cc019SAndroid Build Coastguard Worker 	if (dir < 0)
82*d83cc019SAndroid Build Coastguard Worker 		return;
83*d83cc019SAndroid Build Coastguard Worker 
84*d83cc019SAndroid Build Coastguard Worker 	/* Any write to the error state clears it */
85*d83cc019SAndroid Build Coastguard Worker 	igt_sysfs_set(dir, "error", "");
86*d83cc019SAndroid Build Coastguard Worker 	close(dir);
87*d83cc019SAndroid Build Coastguard Worker }
88*d83cc019SAndroid Build Coastguard Worker 
89*d83cc019SAndroid Build Coastguard Worker /**
90*d83cc019SAndroid Build Coastguard Worker  * igt_require_hang_ring:
91*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
92*d83cc019SAndroid Build Coastguard Worker  * @ring: execbuf ring flag
93*d83cc019SAndroid Build Coastguard Worker  *
94*d83cc019SAndroid Build Coastguard Worker  * Convenience helper to check whether advanced hang injection is supported by
95*d83cc019SAndroid Build Coastguard Worker  * the kernel. Uses igt_skip to automatically skip the test/subtest if this
96*d83cc019SAndroid Build Coastguard Worker  * isn't the case.
97*d83cc019SAndroid Build Coastguard Worker  *
98*d83cc019SAndroid Build Coastguard Worker  * Note that we can't simply just call this from igt_hang_ring since some
99*d83cc019SAndroid Build Coastguard Worker  * tests want to exercise gpu wedging behavior. For which we intentionally
100*d83cc019SAndroid Build Coastguard Worker  * disable gpu reset support, but still want to inject a hang, see for example
101*d83cc019SAndroid Build Coastguard Worker  * tests/gem_eio.c Instead, we expect that the first invocation of
102*d83cc019SAndroid Build Coastguard Worker  * igt_require_hand_ring be from a vanilla context and use the has_gpu_reset()
103*d83cc019SAndroid Build Coastguard Worker  * determined then for all later instances. This allows us the convenience
104*d83cc019SAndroid Build Coastguard Worker  * of double checking when injecting hangs, whilst pushing the complexity
105*d83cc019SAndroid Build Coastguard Worker  * to the tests that are deliberating trying to break the box.
106*d83cc019SAndroid Build Coastguard Worker  *
107*d83cc019SAndroid Build Coastguard Worker  * This function is also controlled by the environment variables:
108*d83cc019SAndroid Build Coastguard Worker  *
109*d83cc019SAndroid Build Coastguard Worker  * IGT_HANG (boolean) - if false, skip all tests that try to inject a hang.
110*d83cc019SAndroid Build Coastguard Worker  * Default: true
111*d83cc019SAndroid Build Coastguard Worker  *
112*d83cc019SAndroid Build Coastguard Worker  * IGT_HANG_WITHOUT_RESET (boolean) - if true, allow the hang even if the
113*d83cc019SAndroid Build Coastguard Worker  * kernel does not support GPU recovery. The machine will be wedged afterwards
114*d83cc019SAndroid Build Coastguard Worker  * (and so require a reboot between testing), but it does allow limited testing
115*d83cc019SAndroid Build Coastguard Worker  * to be done under hang injection.
116*d83cc019SAndroid Build Coastguard Worker  * Default: false
117*d83cc019SAndroid Build Coastguard Worker  */
igt_require_hang_ring(int fd,int ring)118*d83cc019SAndroid Build Coastguard Worker void igt_require_hang_ring(int fd, int ring)
119*d83cc019SAndroid Build Coastguard Worker {
120*d83cc019SAndroid Build Coastguard Worker 	if (!igt_check_boolean_env_var("IGT_HANG", true))
121*d83cc019SAndroid Build Coastguard Worker 		igt_skip("hang injection disabled by user");
122*d83cc019SAndroid Build Coastguard Worker 
123*d83cc019SAndroid Build Coastguard Worker 	gem_require_ring(fd, ring);
124*d83cc019SAndroid Build Coastguard Worker 	gem_context_require_bannable(fd);
125*d83cc019SAndroid Build Coastguard Worker 	if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
126*d83cc019SAndroid Build Coastguard Worker 		igt_require(has_gpu_reset(fd));
127*d83cc019SAndroid Build Coastguard Worker }
128*d83cc019SAndroid Build Coastguard Worker 
context_get_ban(int fd,unsigned ctx)129*d83cc019SAndroid Build Coastguard Worker static unsigned context_get_ban(int fd, unsigned ctx)
130*d83cc019SAndroid Build Coastguard Worker {
131*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_context_param param = {
132*d83cc019SAndroid Build Coastguard Worker 		.ctx_id = ctx,
133*d83cc019SAndroid Build Coastguard Worker 		.param = I915_CONTEXT_PARAM_BANNABLE,
134*d83cc019SAndroid Build Coastguard Worker 	};
135*d83cc019SAndroid Build Coastguard Worker 
136*d83cc019SAndroid Build Coastguard Worker 	if (__gem_context_get_param(fd, &param) == -EINVAL) {
137*d83cc019SAndroid Build Coastguard Worker 		igt_assert(param.value == 0);
138*d83cc019SAndroid Build Coastguard Worker 		param.param = I915_CONTEXT_PARAM_BAN_PERIOD;
139*d83cc019SAndroid Build Coastguard Worker 		gem_context_get_param(fd, &param);
140*d83cc019SAndroid Build Coastguard Worker 	}
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker 	return param.value;
143*d83cc019SAndroid Build Coastguard Worker }
144*d83cc019SAndroid Build Coastguard Worker 
context_set_ban(int fd,unsigned ctx,unsigned ban)145*d83cc019SAndroid Build Coastguard Worker static void context_set_ban(int fd, unsigned ctx, unsigned ban)
146*d83cc019SAndroid Build Coastguard Worker {
147*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_context_param param = {
148*d83cc019SAndroid Build Coastguard Worker 		.ctx_id = ctx,
149*d83cc019SAndroid Build Coastguard Worker 		.param = I915_CONTEXT_PARAM_BANNABLE,
150*d83cc019SAndroid Build Coastguard Worker 		.value = ban,
151*d83cc019SAndroid Build Coastguard Worker 	};
152*d83cc019SAndroid Build Coastguard Worker 
153*d83cc019SAndroid Build Coastguard Worker 	if(__gem_context_set_param(fd, &param) == -EINVAL) {
154*d83cc019SAndroid Build Coastguard Worker 		igt_assert(param.value == ban);
155*d83cc019SAndroid Build Coastguard Worker 		param.param = I915_CONTEXT_PARAM_BAN_PERIOD;
156*d83cc019SAndroid Build Coastguard Worker 		gem_context_set_param(fd, &param);
157*d83cc019SAndroid Build Coastguard Worker 	}
158*d83cc019SAndroid Build Coastguard Worker }
159*d83cc019SAndroid Build Coastguard Worker 
igt_allow_hang(int fd,unsigned ctx,unsigned flags)160*d83cc019SAndroid Build Coastguard Worker igt_hang_t igt_allow_hang(int fd, unsigned ctx, unsigned flags)
161*d83cc019SAndroid Build Coastguard Worker {
162*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_context_param param = {
163*d83cc019SAndroid Build Coastguard Worker 		.ctx_id = ctx,
164*d83cc019SAndroid Build Coastguard Worker 	};
165*d83cc019SAndroid Build Coastguard Worker 	unsigned ban;
166*d83cc019SAndroid Build Coastguard Worker 
167*d83cc019SAndroid Build Coastguard Worker 	/*
168*d83cc019SAndroid Build Coastguard Worker 	 * If the driver is already wedged, we don't expect it to be able
169*d83cc019SAndroid Build Coastguard Worker 	 * to recover from reset and for it to remain wedged. It's hard to
170*d83cc019SAndroid Build Coastguard Worker 	 * say even if we do hang/reset making the test suspect.
171*d83cc019SAndroid Build Coastguard Worker 	 */
172*d83cc019SAndroid Build Coastguard Worker 	igt_require_gem(fd);
173*d83cc019SAndroid Build Coastguard Worker 
174*d83cc019SAndroid Build Coastguard Worker 	if (!igt_check_boolean_env_var("IGT_HANG", true))
175*d83cc019SAndroid Build Coastguard Worker 		igt_skip("hang injection disabled by user");
176*d83cc019SAndroid Build Coastguard Worker 	gem_context_require_bannable(fd);
177*d83cc019SAndroid Build Coastguard Worker 	if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
178*d83cc019SAndroid Build Coastguard Worker 		igt_require(has_gpu_reset(fd));
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_set_parameter
181*d83cc019SAndroid Build Coastguard Worker 		    (fd, "reset", "%d", INT_MAX /* any reset method */));
182*d83cc019SAndroid Build Coastguard Worker 
183*d83cc019SAndroid Build Coastguard Worker 	if ((flags & HANG_ALLOW_CAPTURE) == 0) {
184*d83cc019SAndroid Build Coastguard Worker 		param.param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE;
185*d83cc019SAndroid Build Coastguard Worker 		param.value = 1;
186*d83cc019SAndroid Build Coastguard Worker 		/* Older kernels may not have NO_ERROR_CAPTURE, in which case
187*d83cc019SAndroid Build Coastguard Worker 		 * we just eat the error state in post-hang (and hope we eat
188*d83cc019SAndroid Build Coastguard Worker 		 * the right one).
189*d83cc019SAndroid Build Coastguard Worker 		 */
190*d83cc019SAndroid Build Coastguard Worker 		__gem_context_set_param(fd, &param);
191*d83cc019SAndroid Build Coastguard Worker 	}
192*d83cc019SAndroid Build Coastguard Worker 
193*d83cc019SAndroid Build Coastguard Worker 	ban = context_get_ban(fd, ctx);
194*d83cc019SAndroid Build Coastguard Worker 	if ((flags & HANG_ALLOW_BAN) == 0)
195*d83cc019SAndroid Build Coastguard Worker 		context_set_ban(fd, ctx, 0);
196*d83cc019SAndroid Build Coastguard Worker 
197*d83cc019SAndroid Build Coastguard Worker 	return (struct igt_hang){ 0, ctx, ban, flags };
198*d83cc019SAndroid Build Coastguard Worker }
199*d83cc019SAndroid Build Coastguard Worker 
igt_disallow_hang(int fd,igt_hang_t arg)200*d83cc019SAndroid Build Coastguard Worker void igt_disallow_hang(int fd, igt_hang_t arg)
201*d83cc019SAndroid Build Coastguard Worker {
202*d83cc019SAndroid Build Coastguard Worker 	context_set_ban(fd, arg.ctx, arg.ban);
203*d83cc019SAndroid Build Coastguard Worker 
204*d83cc019SAndroid Build Coastguard Worker 	if ((arg.flags & HANG_ALLOW_CAPTURE) == 0) {
205*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_gem_context_param param = {
206*d83cc019SAndroid Build Coastguard Worker 			.ctx_id = arg.ctx,
207*d83cc019SAndroid Build Coastguard Worker 			.param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE,
208*d83cc019SAndroid Build Coastguard Worker 			.value = 0,
209*d83cc019SAndroid Build Coastguard Worker 		};
210*d83cc019SAndroid Build Coastguard Worker 		__gem_context_set_param(fd, &param);
211*d83cc019SAndroid Build Coastguard Worker 
212*d83cc019SAndroid Build Coastguard Worker 		eat_error_state(fd);
213*d83cc019SAndroid Build Coastguard Worker 	}
214*d83cc019SAndroid Build Coastguard Worker }
215*d83cc019SAndroid Build Coastguard Worker 
216*d83cc019SAndroid Build Coastguard Worker /**
217*d83cc019SAndroid Build Coastguard Worker  * has_ctx_exec:
218*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
219*d83cc019SAndroid Build Coastguard Worker  * @ring: execbuf ring flag
220*d83cc019SAndroid Build Coastguard Worker  * @ctx: Context to be checked
221*d83cc019SAndroid Build Coastguard Worker  *
222*d83cc019SAndroid Build Coastguard Worker  * This helper function checks if non default context submission is allowed
223*d83cc019SAndroid Build Coastguard Worker  * on a ring.
224*d83cc019SAndroid Build Coastguard Worker  *
225*d83cc019SAndroid Build Coastguard Worker  * Returns:
226*d83cc019SAndroid Build Coastguard Worker  * True if allowed
227*d83cc019SAndroid Build Coastguard Worker  *
228*d83cc019SAndroid Build Coastguard Worker  */
has_ctx_exec(int fd,unsigned ring,uint32_t ctx)229*d83cc019SAndroid Build Coastguard Worker static bool has_ctx_exec(int fd, unsigned ring, uint32_t ctx)
230*d83cc019SAndroid Build Coastguard Worker {
231*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
232*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 exec;
233*d83cc019SAndroid Build Coastguard Worker 
234*d83cc019SAndroid Build Coastguard Worker 	/* silly ABI, the kernel thinks everyone who has BSD also has BSD2 */
235*d83cc019SAndroid Build Coastguard Worker 	if ((ring & ~(3<<13)) == I915_EXEC_BSD) {
236*d83cc019SAndroid Build Coastguard Worker 		if (ring & (3 << 13) && !gem_has_bsd2(fd))
237*d83cc019SAndroid Build Coastguard Worker 			return false;
238*d83cc019SAndroid Build Coastguard Worker 	}
239*d83cc019SAndroid Build Coastguard Worker 
240*d83cc019SAndroid Build Coastguard Worker 	memset(&exec, 0, sizeof(exec));
241*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
242*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&exec);
243*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
244*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = ring;
245*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd1 = ctx;
246*d83cc019SAndroid Build Coastguard Worker 	/*
247*d83cc019SAndroid Build Coastguard Worker 	 * If context submission is not allowed, this will return EINVAL
248*d83cc019SAndroid Build Coastguard Worker 	 * Otherwise, this will return ENOENT on account of no gem obj
249*d83cc019SAndroid Build Coastguard Worker 	 * being submitted
250*d83cc019SAndroid Build Coastguard Worker 	 */
251*d83cc019SAndroid Build Coastguard Worker 	return __gem_execbuf(fd, &execbuf) == -ENOENT;
252*d83cc019SAndroid Build Coastguard Worker }
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker /**
255*d83cc019SAndroid Build Coastguard Worker  * igt_hang_ring_ctx:
256*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
257*d83cc019SAndroid Build Coastguard Worker  * @ctx: the contxt specifier
258*d83cc019SAndroid Build Coastguard Worker  * @ring: execbuf ring flag
259*d83cc019SAndroid Build Coastguard Worker  * @flags: set of flags to control execution
260*d83cc019SAndroid Build Coastguard Worker  * @offset: The resultant gtt offset of the exec obj
261*d83cc019SAndroid Build Coastguard Worker  *
262*d83cc019SAndroid Build Coastguard Worker  * This helper function injects a hanging batch associated with @ctx into @ring.
263*d83cc019SAndroid Build Coastguard Worker  * It returns a #igt_hang_t structure which must be passed to
264*d83cc019SAndroid Build Coastguard Worker  * igt_post_hang_ring() for hang post-processing (after the gpu hang
265*d83cc019SAndroid Build Coastguard Worker  * interaction has been tested.
266*d83cc019SAndroid Build Coastguard Worker  *
267*d83cc019SAndroid Build Coastguard Worker  * Returns:
268*d83cc019SAndroid Build Coastguard Worker  * Structure with helper internal state for igt_post_hang_ring().
269*d83cc019SAndroid Build Coastguard Worker  */
igt_hang_ctx(int fd,uint32_t ctx,int ring,unsigned flags)270*d83cc019SAndroid Build Coastguard Worker igt_hang_t igt_hang_ctx(int fd, uint32_t ctx, int ring, unsigned flags)
271*d83cc019SAndroid Build Coastguard Worker {
272*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_context_param param;
273*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
274*d83cc019SAndroid Build Coastguard Worker 	unsigned ban;
275*d83cc019SAndroid Build Coastguard Worker 
276*d83cc019SAndroid Build Coastguard Worker 	igt_require_hang_ring(fd, ring);
277*d83cc019SAndroid Build Coastguard Worker 
278*d83cc019SAndroid Build Coastguard Worker 	/* check if non-default ctx submission is allowed */
279*d83cc019SAndroid Build Coastguard Worker 	igt_require(ctx == 0 || has_ctx_exec(fd, ring, ctx));
280*d83cc019SAndroid Build Coastguard Worker 
281*d83cc019SAndroid Build Coastguard Worker 	param.ctx_id = ctx;
282*d83cc019SAndroid Build Coastguard Worker 	param.size = 0;
283*d83cc019SAndroid Build Coastguard Worker 
284*d83cc019SAndroid Build Coastguard Worker 	if ((flags & HANG_ALLOW_CAPTURE) == 0) {
285*d83cc019SAndroid Build Coastguard Worker 		param.param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE;
286*d83cc019SAndroid Build Coastguard Worker 		param.value = 1;
287*d83cc019SAndroid Build Coastguard Worker 		/* Older kernels may not have NO_ERROR_CAPTURE, in which case
288*d83cc019SAndroid Build Coastguard Worker 		 * we just eat the error state in post-hang (and hope we eat
289*d83cc019SAndroid Build Coastguard Worker 		 * the right one).
290*d83cc019SAndroid Build Coastguard Worker 		 */
291*d83cc019SAndroid Build Coastguard Worker 		__gem_context_set_param(fd, &param);
292*d83cc019SAndroid Build Coastguard Worker 	}
293*d83cc019SAndroid Build Coastguard Worker 
294*d83cc019SAndroid Build Coastguard Worker 	ban = context_get_ban(fd, ctx);
295*d83cc019SAndroid Build Coastguard Worker 	if ((flags & HANG_ALLOW_BAN) == 0)
296*d83cc019SAndroid Build Coastguard Worker 		context_set_ban(fd, ctx, 0);
297*d83cc019SAndroid Build Coastguard Worker 
298*d83cc019SAndroid Build Coastguard Worker 	spin = __igt_spin_new(fd,
299*d83cc019SAndroid Build Coastguard Worker 			      .ctx = ctx,
300*d83cc019SAndroid Build Coastguard Worker 			      .engine = ring,
301*d83cc019SAndroid Build Coastguard Worker 			      .flags = IGT_SPIN_NO_PREEMPTION);
302*d83cc019SAndroid Build Coastguard Worker 
303*d83cc019SAndroid Build Coastguard Worker 	return (igt_hang_t){ spin, ctx, ban, flags };
304*d83cc019SAndroid Build Coastguard Worker }
305*d83cc019SAndroid Build Coastguard Worker 
306*d83cc019SAndroid Build Coastguard Worker /**
307*d83cc019SAndroid Build Coastguard Worker  * igt_hang_ring:
308*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
309*d83cc019SAndroid Build Coastguard Worker  * @ring: execbuf ring flag
310*d83cc019SAndroid Build Coastguard Worker  *
311*d83cc019SAndroid Build Coastguard Worker  * This helper function injects a hanging batch into @ring. It returns a
312*d83cc019SAndroid Build Coastguard Worker  * #igt_hang_t structure which must be passed to igt_post_hang_ring() for
313*d83cc019SAndroid Build Coastguard Worker  * hang post-processing (after the gpu hang interaction has been tested.
314*d83cc019SAndroid Build Coastguard Worker  *
315*d83cc019SAndroid Build Coastguard Worker  * Returns:
316*d83cc019SAndroid Build Coastguard Worker  * Structure with helper internal state for igt_post_hang_ring().
317*d83cc019SAndroid Build Coastguard Worker  */
igt_hang_ring(int fd,int ring)318*d83cc019SAndroid Build Coastguard Worker igt_hang_t igt_hang_ring(int fd, int ring)
319*d83cc019SAndroid Build Coastguard Worker {
320*d83cc019SAndroid Build Coastguard Worker 	return igt_hang_ctx(fd, 0, ring, 0);
321*d83cc019SAndroid Build Coastguard Worker }
322*d83cc019SAndroid Build Coastguard Worker 
323*d83cc019SAndroid Build Coastguard Worker /**
324*d83cc019SAndroid Build Coastguard Worker  * igt_post_hang_ring:
325*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
326*d83cc019SAndroid Build Coastguard Worker  * @arg: hang state from igt_hang_ring()
327*d83cc019SAndroid Build Coastguard Worker  *
328*d83cc019SAndroid Build Coastguard Worker  * This function does the necessary post-processing after a gpu hang injected
329*d83cc019SAndroid Build Coastguard Worker  * with igt_hang_ring().
330*d83cc019SAndroid Build Coastguard Worker  */
igt_post_hang_ring(int fd,igt_hang_t arg)331*d83cc019SAndroid Build Coastguard Worker void igt_post_hang_ring(int fd, igt_hang_t arg)
332*d83cc019SAndroid Build Coastguard Worker {
333*d83cc019SAndroid Build Coastguard Worker 	if (!arg.spin)
334*d83cc019SAndroid Build Coastguard Worker 		return;
335*d83cc019SAndroid Build Coastguard Worker 
336*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, arg.spin->handle); /* Wait until it hangs */
337*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, arg.spin);
338*d83cc019SAndroid Build Coastguard Worker 
339*d83cc019SAndroid Build Coastguard Worker 	context_set_ban(fd, arg.ctx, arg.ban);
340*d83cc019SAndroid Build Coastguard Worker 
341*d83cc019SAndroid Build Coastguard Worker 	if ((arg.flags & HANG_ALLOW_CAPTURE) == 0) {
342*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_gem_context_param param = {
343*d83cc019SAndroid Build Coastguard Worker 			.ctx_id = arg.ctx,
344*d83cc019SAndroid Build Coastguard Worker 			.param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE,
345*d83cc019SAndroid Build Coastguard Worker 			.value = 0,
346*d83cc019SAndroid Build Coastguard Worker 		};
347*d83cc019SAndroid Build Coastguard Worker 		__gem_context_set_param(fd, &param);
348*d83cc019SAndroid Build Coastguard Worker 
349*d83cc019SAndroid Build Coastguard Worker 		eat_error_state(fd);
350*d83cc019SAndroid Build Coastguard Worker 	}
351*d83cc019SAndroid Build Coastguard Worker }
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker /**
354*d83cc019SAndroid Build Coastguard Worker  * igt_force_gpu_reset:
355*d83cc019SAndroid Build Coastguard Worker  *
356*d83cc019SAndroid Build Coastguard Worker  * forces a gpu reset using the i915_wedged debugfs interface. To be used to
357*d83cc019SAndroid Build Coastguard Worker  * recover from situations where the hangcheck didn't trigger and/or the gpu is
358*d83cc019SAndroid Build Coastguard Worker  * stuck, either because the test manually disabled gpu resets or because the
359*d83cc019SAndroid Build Coastguard Worker  * test hit an hangcheck bug
360*d83cc019SAndroid Build Coastguard Worker  */
igt_force_gpu_reset(int drm_fd)361*d83cc019SAndroid Build Coastguard Worker void igt_force_gpu_reset(int drm_fd)
362*d83cc019SAndroid Build Coastguard Worker {
363*d83cc019SAndroid Build Coastguard Worker 	int dir, wedged;
364*d83cc019SAndroid Build Coastguard Worker 
365*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Triggering GPU reset\n");
366*d83cc019SAndroid Build Coastguard Worker 
367*d83cc019SAndroid Build Coastguard Worker 	dir = igt_debugfs_dir(drm_fd);
368*d83cc019SAndroid Build Coastguard Worker 
369*d83cc019SAndroid Build Coastguard Worker 	igt_sysfs_set(dir, "i915_wedged", "-1");
370*d83cc019SAndroid Build Coastguard Worker 	igt_sysfs_scanf(dir, "i915_wedged", "%d", &wedged);
371*d83cc019SAndroid Build Coastguard Worker 
372*d83cc019SAndroid Build Coastguard Worker 	close(dir);
373*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
374*d83cc019SAndroid Build Coastguard Worker 
375*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!wedged);
376*d83cc019SAndroid Build Coastguard Worker }
377*d83cc019SAndroid Build Coastguard Worker 
378*d83cc019SAndroid Build Coastguard Worker /* GPU abusers */
379*d83cc019SAndroid Build Coastguard Worker static struct igt_helper_process hang_helper;
380*d83cc019SAndroid Build Coastguard Worker static void __attribute__((noreturn))
hang_helper_process(pid_t pid,int fd)381*d83cc019SAndroid Build Coastguard Worker hang_helper_process(pid_t pid, int fd)
382*d83cc019SAndroid Build Coastguard Worker {
383*d83cc019SAndroid Build Coastguard Worker 	while (1) {
384*d83cc019SAndroid Build Coastguard Worker 		if (kill(pid, 0)) /* Parent has died, so must we. */
385*d83cc019SAndroid Build Coastguard Worker 			exit(0);
386*d83cc019SAndroid Build Coastguard Worker 
387*d83cc019SAndroid Build Coastguard Worker 		igt_post_hang_ring(fd,
388*d83cc019SAndroid Build Coastguard Worker 				   igt_hang_ring(fd, I915_EXEC_DEFAULT));
389*d83cc019SAndroid Build Coastguard Worker 
390*d83cc019SAndroid Build Coastguard Worker 		sleep(1);
391*d83cc019SAndroid Build Coastguard Worker 	}
392*d83cc019SAndroid Build Coastguard Worker }
393*d83cc019SAndroid Build Coastguard Worker 
394*d83cc019SAndroid Build Coastguard Worker /**
395*d83cc019SAndroid Build Coastguard Worker  * igt_fork_hang_helper:
396*d83cc019SAndroid Build Coastguard Worker  *
397*d83cc019SAndroid Build Coastguard Worker  * Fork a child process using #igt_fork_helper to hang the default engine
398*d83cc019SAndroid Build Coastguard Worker  * of the GPU at regular intervals.
399*d83cc019SAndroid Build Coastguard Worker  *
400*d83cc019SAndroid Build Coastguard Worker  * This is useful to exercise slow running code (such as aperture placement)
401*d83cc019SAndroid Build Coastguard Worker  * which needs to be robust against a GPU reset.
402*d83cc019SAndroid Build Coastguard Worker  *
403*d83cc019SAndroid Build Coastguard Worker  * This function automatically skips when test requirements aren't met using
404*d83cc019SAndroid Build Coastguard Worker  * igt_skip().
405*d83cc019SAndroid Build Coastguard Worker  */
igt_fork_hang_helper(void)406*d83cc019SAndroid Build Coastguard Worker void igt_fork_hang_helper(void)
407*d83cc019SAndroid Build Coastguard Worker {
408*d83cc019SAndroid Build Coastguard Worker 	int fd, gen;
409*d83cc019SAndroid Build Coastguard Worker 
410*d83cc019SAndroid Build Coastguard Worker 	fd = drm_open_driver(DRIVER_INTEL);
411*d83cc019SAndroid Build Coastguard Worker 
412*d83cc019SAndroid Build Coastguard Worker 	gen = intel_gen(intel_get_drm_devid(fd));
413*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on(gen < 5);
414*d83cc019SAndroid Build Coastguard Worker 
415*d83cc019SAndroid Build Coastguard Worker 	igt_fork_helper(&hang_helper)
416*d83cc019SAndroid Build Coastguard Worker 		hang_helper_process(getppid(), fd);
417*d83cc019SAndroid Build Coastguard Worker 
418*d83cc019SAndroid Build Coastguard Worker 	close(fd);
419*d83cc019SAndroid Build Coastguard Worker }
420*d83cc019SAndroid Build Coastguard Worker 
421*d83cc019SAndroid Build Coastguard Worker /**
422*d83cc019SAndroid Build Coastguard Worker  * igt_stop_hang_helper:
423*d83cc019SAndroid Build Coastguard Worker  *
424*d83cc019SAndroid Build Coastguard Worker  * Stops the child process spawned with igt_fork_hang_helper().
425*d83cc019SAndroid Build Coastguard Worker  *
426*d83cc019SAndroid Build Coastguard Worker  * In tests with subtests this function can be called outside of failure
427*d83cc019SAndroid Build Coastguard Worker  * catching code blocks like #igt_fixture or #igt_subtest.
428*d83cc019SAndroid Build Coastguard Worker  */
igt_stop_hang_helper(void)429*d83cc019SAndroid Build Coastguard Worker void igt_stop_hang_helper(void)
430*d83cc019SAndroid Build Coastguard Worker {
431*d83cc019SAndroid Build Coastguard Worker 	if (hang_helper.running)
432*d83cc019SAndroid Build Coastguard Worker 		igt_stop_helper(&hang_helper);
433*d83cc019SAndroid Build Coastguard Worker }
434*d83cc019SAndroid Build Coastguard Worker 
435*d83cc019SAndroid Build Coastguard Worker /**
436*d83cc019SAndroid Build Coastguard Worker  * igt_open_forcewake_handle:
437*d83cc019SAndroid Build Coastguard Worker  *
438*d83cc019SAndroid Build Coastguard Worker  * This functions opens the debugfs forcewake file and so prevents the GT from
439*d83cc019SAndroid Build Coastguard Worker  * suspending. The reference is automatically dropped when the is closed.
440*d83cc019SAndroid Build Coastguard Worker  *
441*d83cc019SAndroid Build Coastguard Worker  * Returns:
442*d83cc019SAndroid Build Coastguard Worker  * The file descriptor of the forcewake handle or -1 if that didn't work out.
443*d83cc019SAndroid Build Coastguard Worker  */
igt_open_forcewake_handle(int fd)444*d83cc019SAndroid Build Coastguard Worker int igt_open_forcewake_handle(int fd)
445*d83cc019SAndroid Build Coastguard Worker {
446*d83cc019SAndroid Build Coastguard Worker 	if (getenv("IGT_NO_FORCEWAKE"))
447*d83cc019SAndroid Build Coastguard Worker 		return -1;
448*d83cc019SAndroid Build Coastguard Worker 	return igt_debugfs_open(fd, "i915_forcewake_user", O_WRONLY);
449*d83cc019SAndroid Build Coastguard Worker }
450*d83cc019SAndroid Build Coastguard Worker 
451*d83cc019SAndroid Build Coastguard Worker #if defined(__x86_64__) || defined(__i386__)
452*d83cc019SAndroid Build Coastguard Worker static unsigned int clflush_size;
453*d83cc019SAndroid Build Coastguard Worker 
igt_setup_clflush(void)454*d83cc019SAndroid Build Coastguard Worker int igt_setup_clflush(void)
455*d83cc019SAndroid Build Coastguard Worker {
456*d83cc019SAndroid Build Coastguard Worker 	FILE *file;
457*d83cc019SAndroid Build Coastguard Worker 	char *line = NULL;
458*d83cc019SAndroid Build Coastguard Worker 	size_t size = 0;
459*d83cc019SAndroid Build Coastguard Worker 	int first_stanza = 1;
460*d83cc019SAndroid Build Coastguard Worker 	int has_clflush = 0;
461*d83cc019SAndroid Build Coastguard Worker 
462*d83cc019SAndroid Build Coastguard Worker 	if (clflush_size)
463*d83cc019SAndroid Build Coastguard Worker 		return 1;
464*d83cc019SAndroid Build Coastguard Worker 
465*d83cc019SAndroid Build Coastguard Worker 	file = fopen("/proc/cpuinfo", "r");
466*d83cc019SAndroid Build Coastguard Worker 	if (file == NULL)
467*d83cc019SAndroid Build Coastguard Worker 		return 0;
468*d83cc019SAndroid Build Coastguard Worker 
469*d83cc019SAndroid Build Coastguard Worker 	while (getline(&line, &size, file) != -1) {
470*d83cc019SAndroid Build Coastguard Worker 		if (strncmp(line, "processor", 9) == 0) {
471*d83cc019SAndroid Build Coastguard Worker 			if (!first_stanza)
472*d83cc019SAndroid Build Coastguard Worker 				break;
473*d83cc019SAndroid Build Coastguard Worker 			first_stanza = 0;
474*d83cc019SAndroid Build Coastguard Worker 		}
475*d83cc019SAndroid Build Coastguard Worker 
476*d83cc019SAndroid Build Coastguard Worker 		if (strncmp(line, "flags", 5) == 0) {
477*d83cc019SAndroid Build Coastguard Worker 			if (strstr(line, "clflush"))
478*d83cc019SAndroid Build Coastguard Worker 				has_clflush = 1;
479*d83cc019SAndroid Build Coastguard Worker 		}
480*d83cc019SAndroid Build Coastguard Worker 
481*d83cc019SAndroid Build Coastguard Worker 		if (strncmp(line, "clflush size", 12) == 0) {
482*d83cc019SAndroid Build Coastguard Worker 			char *colon = strchr(line, ':');
483*d83cc019SAndroid Build Coastguard Worker 			if (colon)
484*d83cc019SAndroid Build Coastguard Worker 				clflush_size = atoi(colon + 1);
485*d83cc019SAndroid Build Coastguard Worker 		}
486*d83cc019SAndroid Build Coastguard Worker 	}
487*d83cc019SAndroid Build Coastguard Worker 	free(line);
488*d83cc019SAndroid Build Coastguard Worker 	fclose(file);
489*d83cc019SAndroid Build Coastguard Worker 
490*d83cc019SAndroid Build Coastguard Worker 	return has_clflush && clflush_size;
491*d83cc019SAndroid Build Coastguard Worker }
492*d83cc019SAndroid Build Coastguard Worker 
493*d83cc019SAndroid Build Coastguard Worker __attribute__((target("sse2")))
igt_clflush_range(void * addr,int size)494*d83cc019SAndroid Build Coastguard Worker void igt_clflush_range(void *addr, int size)
495*d83cc019SAndroid Build Coastguard Worker {
496*d83cc019SAndroid Build Coastguard Worker 	char *p, *end;
497*d83cc019SAndroid Build Coastguard Worker 
498*d83cc019SAndroid Build Coastguard Worker 	end = (char *)addr + size;
499*d83cc019SAndroid Build Coastguard Worker 	p = (char *)((uintptr_t)addr & ~((uintptr_t)clflush_size - 1));
500*d83cc019SAndroid Build Coastguard Worker 
501*d83cc019SAndroid Build Coastguard Worker 	__builtin_ia32_mfence();
502*d83cc019SAndroid Build Coastguard Worker 	for (; p < end; p += clflush_size)
503*d83cc019SAndroid Build Coastguard Worker 		__builtin_ia32_clflush(p);
504*d83cc019SAndroid Build Coastguard Worker 	__builtin_ia32_clflush(end - 1); /* magic serialisation for byt+ */
505*d83cc019SAndroid Build Coastguard Worker 	__builtin_ia32_mfence();
506*d83cc019SAndroid Build Coastguard Worker }
507*d83cc019SAndroid Build Coastguard Worker #else
igt_setup_clflush(void)508*d83cc019SAndroid Build Coastguard Worker int igt_setup_clflush(void)
509*d83cc019SAndroid Build Coastguard Worker {
510*d83cc019SAndroid Build Coastguard Worker 	/* requires mfence + clflush, both SSE2 instructions */
511*d83cc019SAndroid Build Coastguard Worker 	return 0;
512*d83cc019SAndroid Build Coastguard Worker }
513*d83cc019SAndroid Build Coastguard Worker 
igt_clflush_range(void * addr,int size)514*d83cc019SAndroid Build Coastguard Worker void igt_clflush_range(void *addr, int size)
515*d83cc019SAndroid Build Coastguard Worker {
516*d83cc019SAndroid Build Coastguard Worker 	fprintf(stderr, "igt_clflush_range() unsupported\n");
517*d83cc019SAndroid Build Coastguard Worker }
518*d83cc019SAndroid Build Coastguard Worker #endif
519*d83cc019SAndroid Build Coastguard Worker 
520*d83cc019SAndroid Build Coastguard Worker /**
521*d83cc019SAndroid Build Coastguard Worker  * intel_detect_and_clear_missed_irq:
522*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor, used to quiesce the gpu
523*d83cc019SAndroid Build Coastguard Worker  *
524*d83cc019SAndroid Build Coastguard Worker  * This functions idles the GPU and then queries whether there has
525*d83cc019SAndroid Build Coastguard Worker  * been a missed interrupt reported by the driver. Afterwards it
526*d83cc019SAndroid Build Coastguard Worker  * clears the missed interrupt flag, in order to disable the timer
527*d83cc019SAndroid Build Coastguard Worker  * fallback for the next test.
528*d83cc019SAndroid Build Coastguard Worker  */
intel_detect_and_clear_missed_interrupts(int fd)529*d83cc019SAndroid Build Coastguard Worker unsigned intel_detect_and_clear_missed_interrupts(int fd)
530*d83cc019SAndroid Build Coastguard Worker {
531*d83cc019SAndroid Build Coastguard Worker 	unsigned missed;
532*d83cc019SAndroid Build Coastguard Worker 	int dir;
533*d83cc019SAndroid Build Coastguard Worker 
534*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(fd);
535*d83cc019SAndroid Build Coastguard Worker 
536*d83cc019SAndroid Build Coastguard Worker 	dir = igt_debugfs_dir(fd);
537*d83cc019SAndroid Build Coastguard Worker 
538*d83cc019SAndroid Build Coastguard Worker 	missed = 0;
539*d83cc019SAndroid Build Coastguard Worker 	igt_sysfs_scanf(dir, "i915_ring_missed_irq", "%x", &missed);
540*d83cc019SAndroid Build Coastguard Worker 	if (missed)
541*d83cc019SAndroid Build Coastguard Worker 		igt_sysfs_set(dir, "i915_ring_missed_irq", "0");
542*d83cc019SAndroid Build Coastguard Worker 
543*d83cc019SAndroid Build Coastguard Worker 	close(dir);
544*d83cc019SAndroid Build Coastguard Worker 
545*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
546*d83cc019SAndroid Build Coastguard Worker 	return missed;
547*d83cc019SAndroid Build Coastguard Worker }
548*d83cc019SAndroid Build Coastguard Worker 
549*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine intel_execution_engines[] = {
550*d83cc019SAndroid Build Coastguard Worker 	{ "default", NULL, 0, 0 },
551*d83cc019SAndroid Build Coastguard Worker 	{ "render", "rcs0", I915_EXEC_RENDER, 0 },
552*d83cc019SAndroid Build Coastguard Worker 	{ "bsd", "vcs0", I915_EXEC_BSD, 0 },
553*d83cc019SAndroid Build Coastguard Worker 	{ "bsd1", "vcs0", I915_EXEC_BSD, 1<<13 /*I915_EXEC_BSD_RING1*/ },
554*d83cc019SAndroid Build Coastguard Worker 	{ "bsd2", "vcs1", I915_EXEC_BSD, 2<<13 /*I915_EXEC_BSD_RING2*/ },
555*d83cc019SAndroid Build Coastguard Worker 	{ "blt", "bcs0", I915_EXEC_BLT, 0 },
556*d83cc019SAndroid Build Coastguard Worker 	{ "vebox", "vecs0", I915_EXEC_VEBOX, 0 },
557*d83cc019SAndroid Build Coastguard Worker 	{ NULL, 0, 0 }
558*d83cc019SAndroid Build Coastguard Worker };
559*d83cc019SAndroid Build Coastguard Worker 
gem_class_can_store_dword(int fd,int class)560*d83cc019SAndroid Build Coastguard Worker bool gem_class_can_store_dword(int fd, int class)
561*d83cc019SAndroid Build Coastguard Worker {
562*d83cc019SAndroid Build Coastguard Worker 	uint16_t devid = intel_get_drm_devid(fd);
563*d83cc019SAndroid Build Coastguard Worker 	const struct intel_device_info *info = intel_get_device_info(devid);
564*d83cc019SAndroid Build Coastguard Worker 	const int gen = ffs(info->gen);
565*d83cc019SAndroid Build Coastguard Worker 
566*d83cc019SAndroid Build Coastguard Worker 	if (gen <= 2) /* requires physical addresses */
567*d83cc019SAndroid Build Coastguard Worker 		return false;
568*d83cc019SAndroid Build Coastguard Worker 
569*d83cc019SAndroid Build Coastguard Worker 	if (gen == 3 && (info->is_grantsdale || info->is_alviso))
570*d83cc019SAndroid Build Coastguard Worker 		return false; /* only supports physical addresses */
571*d83cc019SAndroid Build Coastguard Worker 
572*d83cc019SAndroid Build Coastguard Worker 	if (gen == 6 && class == I915_ENGINE_CLASS_VIDEO)
573*d83cc019SAndroid Build Coastguard Worker 		return false;
574*d83cc019SAndroid Build Coastguard Worker 
575*d83cc019SAndroid Build Coastguard Worker 	if (info->is_broadwater)
576*d83cc019SAndroid Build Coastguard Worker 		return false; /* Not sure yet... */
577*d83cc019SAndroid Build Coastguard Worker 
578*d83cc019SAndroid Build Coastguard Worker 	return true;
579*d83cc019SAndroid Build Coastguard Worker }
580*d83cc019SAndroid Build Coastguard Worker 
gem_can_store_dword(int fd,unsigned int engine)581*d83cc019SAndroid Build Coastguard Worker bool gem_can_store_dword(int fd, unsigned int engine)
582*d83cc019SAndroid Build Coastguard Worker {
583*d83cc019SAndroid Build Coastguard Worker 	return gem_class_can_store_dword(fd,
584*d83cc019SAndroid Build Coastguard Worker 				gem_execbuf_flags_to_engine_class(engine));
585*d83cc019SAndroid Build Coastguard Worker }
586*d83cc019SAndroid Build Coastguard Worker 
587*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine2 intel_execution_engines2[] = {
588*d83cc019SAndroid Build Coastguard Worker 	{ "rcs0", I915_ENGINE_CLASS_RENDER, 0, I915_EXEC_RENDER },
589*d83cc019SAndroid Build Coastguard Worker 	{ "bcs0", I915_ENGINE_CLASS_COPY, 0, I915_EXEC_BLT },
590*d83cc019SAndroid Build Coastguard Worker 	{ "vcs0", I915_ENGINE_CLASS_VIDEO, 0, I915_EXEC_BSD | I915_EXEC_BSD_RING1 },
591*d83cc019SAndroid Build Coastguard Worker 	{ "vcs1", I915_ENGINE_CLASS_VIDEO, 1, I915_EXEC_BSD | I915_EXEC_BSD_RING2 },
592*d83cc019SAndroid Build Coastguard Worker 	{ "vcs2", I915_ENGINE_CLASS_VIDEO, 2, -1 },
593*d83cc019SAndroid Build Coastguard Worker 	{ "vecs0", I915_ENGINE_CLASS_VIDEO_ENHANCE, 0, I915_EXEC_VEBOX },
594*d83cc019SAndroid Build Coastguard Worker 	{ }
595*d83cc019SAndroid Build Coastguard Worker };
596*d83cc019SAndroid Build Coastguard Worker 
gem_execbuf_flags_to_engine_class(unsigned int flags)597*d83cc019SAndroid Build Coastguard Worker int gem_execbuf_flags_to_engine_class(unsigned int flags)
598*d83cc019SAndroid Build Coastguard Worker {
599*d83cc019SAndroid Build Coastguard Worker 	switch (flags & 0x3f) {
600*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_DEFAULT:
601*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_RENDER:
602*d83cc019SAndroid Build Coastguard Worker 		return I915_ENGINE_CLASS_RENDER;
603*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_BLT:
604*d83cc019SAndroid Build Coastguard Worker 		return I915_ENGINE_CLASS_COPY;
605*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_BSD:
606*d83cc019SAndroid Build Coastguard Worker 		return I915_ENGINE_CLASS_VIDEO;
607*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_VEBOX:
608*d83cc019SAndroid Build Coastguard Worker 		return I915_ENGINE_CLASS_VIDEO_ENHANCE;
609*d83cc019SAndroid Build Coastguard Worker 	default:
610*d83cc019SAndroid Build Coastguard Worker 		igt_assert(0);
611*d83cc019SAndroid Build Coastguard Worker 	}
612*d83cc019SAndroid Build Coastguard Worker }
613*d83cc019SAndroid Build Coastguard Worker 
gem_ring_is_physical_engine(int fd,unsigned ring)614*d83cc019SAndroid Build Coastguard Worker bool gem_ring_is_physical_engine(int fd, unsigned ring)
615*d83cc019SAndroid Build Coastguard Worker {
616*d83cc019SAndroid Build Coastguard Worker 	if (ring == I915_EXEC_DEFAULT)
617*d83cc019SAndroid Build Coastguard Worker 		return false;
618*d83cc019SAndroid Build Coastguard Worker 
619*d83cc019SAndroid Build Coastguard Worker 	/* BSD uses an extra flag to chose between aliasing modes */
620*d83cc019SAndroid Build Coastguard Worker 	if ((ring & 63) == I915_EXEC_BSD) {
621*d83cc019SAndroid Build Coastguard Worker 		bool explicit_bsd = ring & (3 << 13);
622*d83cc019SAndroid Build Coastguard Worker 		bool has_bsd2 = gem_has_bsd2(fd);
623*d83cc019SAndroid Build Coastguard Worker 		return explicit_bsd ? has_bsd2 : !has_bsd2;
624*d83cc019SAndroid Build Coastguard Worker 	}
625*d83cc019SAndroid Build Coastguard Worker 
626*d83cc019SAndroid Build Coastguard Worker 	return true;
627*d83cc019SAndroid Build Coastguard Worker }
628*d83cc019SAndroid Build Coastguard Worker 
gem_ring_has_physical_engine(int fd,unsigned ring)629*d83cc019SAndroid Build Coastguard Worker bool gem_ring_has_physical_engine(int fd, unsigned ring)
630*d83cc019SAndroid Build Coastguard Worker {
631*d83cc019SAndroid Build Coastguard Worker 	if (!gem_ring_is_physical_engine(fd, ring))
632*d83cc019SAndroid Build Coastguard Worker 		return false;
633*d83cc019SAndroid Build Coastguard Worker 
634*d83cc019SAndroid Build Coastguard Worker 	return gem_has_ring(fd, ring);
635*d83cc019SAndroid Build Coastguard Worker }
636