xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_exec_capture.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2016 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 <zlib.h>
25*d83cc019SAndroid Build Coastguard Worker 
26*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
27*d83cc019SAndroid Build Coastguard Worker #include "igt_device.h"
28*d83cc019SAndroid Build Coastguard Worker #include "igt_rand.h"
29*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
30*d83cc019SAndroid Build Coastguard Worker 
31*d83cc019SAndroid Build Coastguard Worker #define LOCAL_OBJECT_CAPTURE (1 << 7)
32*d83cc019SAndroid Build Coastguard Worker #define LOCAL_PARAM_HAS_EXEC_CAPTURE 45
33*d83cc019SAndroid Build Coastguard Worker 
34*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Check that we capture the user specified objects on a hang");
35*d83cc019SAndroid Build Coastguard Worker 
check_error_state(int dir,struct drm_i915_gem_exec_object2 * obj)36*d83cc019SAndroid Build Coastguard Worker static void check_error_state(int dir, struct drm_i915_gem_exec_object2 *obj)
37*d83cc019SAndroid Build Coastguard Worker {
38*d83cc019SAndroid Build Coastguard Worker 	char *error, *str;
39*d83cc019SAndroid Build Coastguard Worker 	bool found = false;
40*d83cc019SAndroid Build Coastguard Worker 
41*d83cc019SAndroid Build Coastguard Worker 	error = igt_sysfs_get(dir, "error");
42*d83cc019SAndroid Build Coastguard Worker 	igt_sysfs_set(dir, "error", "Begone!");
43*d83cc019SAndroid Build Coastguard Worker 
44*d83cc019SAndroid Build Coastguard Worker 	igt_assert(error);
45*d83cc019SAndroid Build Coastguard Worker 	igt_debug("%s\n", error);
46*d83cc019SAndroid Build Coastguard Worker 
47*d83cc019SAndroid Build Coastguard Worker 	/* render ring --- user = 0x00000000 ffffd000 */
48*d83cc019SAndroid Build Coastguard Worker 	for (str = error; (str = strstr(str, "--- user = ")); str++) {
49*d83cc019SAndroid Build Coastguard Worker 		uint64_t addr;
50*d83cc019SAndroid Build Coastguard Worker 		uint32_t hi, lo;
51*d83cc019SAndroid Build Coastguard Worker 
52*d83cc019SAndroid Build Coastguard Worker 		igt_assert(sscanf(str, "--- user = 0x%x %x", &hi, &lo) == 2);
53*d83cc019SAndroid Build Coastguard Worker 		addr = hi;
54*d83cc019SAndroid Build Coastguard Worker 		addr <<= 32;
55*d83cc019SAndroid Build Coastguard Worker 		addr |= lo;
56*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u64(addr, obj->offset);
57*d83cc019SAndroid Build Coastguard Worker 		found = true;
58*d83cc019SAndroid Build Coastguard Worker 	}
59*d83cc019SAndroid Build Coastguard Worker 
60*d83cc019SAndroid Build Coastguard Worker 	free(error);
61*d83cc019SAndroid Build Coastguard Worker 	igt_assert(found);
62*d83cc019SAndroid Build Coastguard Worker }
63*d83cc019SAndroid Build Coastguard Worker 
__capture1(int fd,int dir,unsigned ring,uint32_t target)64*d83cc019SAndroid Build Coastguard Worker static void __capture1(int fd, int dir, unsigned ring, uint32_t target)
65*d83cc019SAndroid Build Coastguard Worker {
66*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(fd));
67*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[4];
68*d83cc019SAndroid Build Coastguard Worker #define SCRATCH 0
69*d83cc019SAndroid Build Coastguard Worker #define CAPTURE 1
70*d83cc019SAndroid Build Coastguard Worker #define NOCAPTURE 2
71*d83cc019SAndroid Build Coastguard Worker #define BATCH 3
72*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc[2];
73*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
74*d83cc019SAndroid Build Coastguard Worker 	uint32_t *batch, *seqno;
75*d83cc019SAndroid Build Coastguard Worker 	int i;
76*d83cc019SAndroid Build Coastguard Worker 
77*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
78*d83cc019SAndroid Build Coastguard Worker 	obj[SCRATCH].handle = gem_create(fd, 4096);
79*d83cc019SAndroid Build Coastguard Worker 	obj[CAPTURE].handle = target;
80*d83cc019SAndroid Build Coastguard Worker 	obj[CAPTURE].flags = LOCAL_OBJECT_CAPTURE;
81*d83cc019SAndroid Build Coastguard Worker 	obj[NOCAPTURE].handle = gem_create(fd, 4096);
82*d83cc019SAndroid Build Coastguard Worker 
83*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].handle = gem_create(fd, 4096);
84*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocs_ptr = (uintptr_t)reloc;
85*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocation_count = ARRAY_SIZE(reloc);
86*d83cc019SAndroid Build Coastguard Worker 
87*d83cc019SAndroid Build Coastguard Worker 	memset(reloc, 0, sizeof(reloc));
88*d83cc019SAndroid Build Coastguard Worker 	reloc[0].target_handle = obj[BATCH].handle; /* recurse */
89*d83cc019SAndroid Build Coastguard Worker 	reloc[0].presumed_offset = 0;
90*d83cc019SAndroid Build Coastguard Worker 	reloc[0].offset = 5*sizeof(uint32_t);
91*d83cc019SAndroid Build Coastguard Worker 	reloc[0].delta = 0;
92*d83cc019SAndroid Build Coastguard Worker 	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
93*d83cc019SAndroid Build Coastguard Worker 	reloc[0].write_domain = 0;
94*d83cc019SAndroid Build Coastguard Worker 
95*d83cc019SAndroid Build Coastguard Worker 	reloc[1].target_handle = obj[SCRATCH].handle; /* breadcrumb */
96*d83cc019SAndroid Build Coastguard Worker 	reloc[1].presumed_offset = 0;
97*d83cc019SAndroid Build Coastguard Worker 	reloc[1].offset = sizeof(uint32_t);
98*d83cc019SAndroid Build Coastguard Worker 	reloc[1].delta = 0;
99*d83cc019SAndroid Build Coastguard Worker 	reloc[1].read_domains = I915_GEM_DOMAIN_RENDER;
100*d83cc019SAndroid Build Coastguard Worker 	reloc[1].write_domain = I915_GEM_DOMAIN_RENDER;
101*d83cc019SAndroid Build Coastguard Worker 
102*d83cc019SAndroid Build Coastguard Worker 	seqno = gem_mmap__wc(fd, obj[SCRATCH].handle, 0, 4096, PROT_READ);
103*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, obj[SCRATCH].handle,
104*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
105*d83cc019SAndroid Build Coastguard Worker 
106*d83cc019SAndroid Build Coastguard Worker 	batch = gem_mmap__cpu(fd, obj[BATCH].handle, 0, 4096, PROT_WRITE);
107*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, obj[BATCH].handle,
108*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
109*d83cc019SAndroid Build Coastguard Worker 
110*d83cc019SAndroid Build Coastguard Worker 	i = 0;
111*d83cc019SAndroid Build Coastguard Worker 	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
112*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
113*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
114*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
115*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 4) {
116*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
117*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
118*d83cc019SAndroid Build Coastguard Worker 		reloc[1].offset += sizeof(uint32_t);
119*d83cc019SAndroid Build Coastguard Worker 	} else {
120*d83cc019SAndroid Build Coastguard Worker 		batch[i]--;
121*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
122*d83cc019SAndroid Build Coastguard Worker 	}
123*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = 0xc0ffee;
124*d83cc019SAndroid Build Coastguard Worker 	if (gen < 4)
125*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = MI_NOOP;
126*d83cc019SAndroid Build Coastguard Worker 
127*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = MI_BATCH_BUFFER_START; /* not crashed? try again! */
128*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
129*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8 | 1;
130*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
131*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
132*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 6) {
133*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8;
134*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
135*d83cc019SAndroid Build Coastguard Worker 	} else {
136*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 2 << 6;
137*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
138*d83cc019SAndroid Build Coastguard Worker 		if (gen < 4) {
139*d83cc019SAndroid Build Coastguard Worker 			batch[i] |= 1;
140*d83cc019SAndroid Build Coastguard Worker 			reloc[0].delta = 1;
141*d83cc019SAndroid Build Coastguard Worker 		}
142*d83cc019SAndroid Build Coastguard Worker 	}
143*d83cc019SAndroid Build Coastguard Worker 	munmap(batch, 4096);
144*d83cc019SAndroid Build Coastguard Worker 
145*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
146*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = (uintptr_t)obj;
147*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = ARRAY_SIZE(obj);
148*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = ring;
149*d83cc019SAndroid Build Coastguard Worker 	if (gen > 3 && gen < 6)
150*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags |= I915_EXEC_SECURE;
151*d83cc019SAndroid Build Coastguard Worker 
152*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!READ_ONCE(*seqno));
153*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
154*d83cc019SAndroid Build Coastguard Worker 
155*d83cc019SAndroid Build Coastguard Worker 	/* Wait for the request to start */
156*d83cc019SAndroid Build Coastguard Worker 	while (READ_ONCE(*seqno) != 0xc0ffee)
157*d83cc019SAndroid Build Coastguard Worker 		igt_assert(gem_bo_busy(fd, obj[SCRATCH].handle));
158*d83cc019SAndroid Build Coastguard Worker 	munmap(seqno, 4096);
159*d83cc019SAndroid Build Coastguard Worker 
160*d83cc019SAndroid Build Coastguard Worker 	/* Check that only the buffer we marked is reported in the error */
161*d83cc019SAndroid Build Coastguard Worker 	igt_force_gpu_reset(fd);
162*d83cc019SAndroid Build Coastguard Worker 	check_error_state(dir, &obj[CAPTURE]);
163*d83cc019SAndroid Build Coastguard Worker 
164*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, obj[BATCH].handle);
165*d83cc019SAndroid Build Coastguard Worker 
166*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[BATCH].handle);
167*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[NOCAPTURE].handle);
168*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[SCRATCH].handle);
169*d83cc019SAndroid Build Coastguard Worker }
170*d83cc019SAndroid Build Coastguard Worker 
capture(int fd,int dir,unsigned ring)171*d83cc019SAndroid Build Coastguard Worker static void capture(int fd, int dir, unsigned ring)
172*d83cc019SAndroid Build Coastguard Worker {
173*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
174*d83cc019SAndroid Build Coastguard Worker 
175*d83cc019SAndroid Build Coastguard Worker 	handle = gem_create(fd, 4096);
176*d83cc019SAndroid Build Coastguard Worker 	__capture1(fd, dir, ring, handle);
177*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, handle);
178*d83cc019SAndroid Build Coastguard Worker }
179*d83cc019SAndroid Build Coastguard Worker 
cmp(const void * A,const void * B)180*d83cc019SAndroid Build Coastguard Worker static int cmp(const void *A, const void *B)
181*d83cc019SAndroid Build Coastguard Worker {
182*d83cc019SAndroid Build Coastguard Worker 	const uint64_t *a = A, *b = B;
183*d83cc019SAndroid Build Coastguard Worker 
184*d83cc019SAndroid Build Coastguard Worker 	if (*a < *b)
185*d83cc019SAndroid Build Coastguard Worker 		return -1;
186*d83cc019SAndroid Build Coastguard Worker 
187*d83cc019SAndroid Build Coastguard Worker 	if (*a > *b)
188*d83cc019SAndroid Build Coastguard Worker 		return 1;
189*d83cc019SAndroid Build Coastguard Worker 
190*d83cc019SAndroid Build Coastguard Worker 	return 0;
191*d83cc019SAndroid Build Coastguard Worker }
192*d83cc019SAndroid Build Coastguard Worker 
193*d83cc019SAndroid Build Coastguard Worker static struct offset {
194*d83cc019SAndroid Build Coastguard Worker 	uint64_t addr;
195*d83cc019SAndroid Build Coastguard Worker 	unsigned long idx;
__captureN(int fd,int dir,unsigned ring,unsigned int size,int count,unsigned int flags)196*d83cc019SAndroid Build Coastguard Worker } *__captureN(int fd, int dir, unsigned ring,
197*d83cc019SAndroid Build Coastguard Worker 	      unsigned int size, int count,
198*d83cc019SAndroid Build Coastguard Worker 	      unsigned int flags)
199*d83cc019SAndroid Build Coastguard Worker #define INCREMENTAL 0x1
200*d83cc019SAndroid Build Coastguard Worker {
201*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(fd));
202*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 *obj;
203*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc[2];
204*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
205*d83cc019SAndroid Build Coastguard Worker 	uint32_t *batch, *seqno;
206*d83cc019SAndroid Build Coastguard Worker 	struct offset *offsets;
207*d83cc019SAndroid Build Coastguard Worker 	int i;
208*d83cc019SAndroid Build Coastguard Worker 
209*d83cc019SAndroid Build Coastguard Worker 	offsets = calloc(count , sizeof(*offsets));
210*d83cc019SAndroid Build Coastguard Worker 	igt_assert(offsets);
211*d83cc019SAndroid Build Coastguard Worker 
212*d83cc019SAndroid Build Coastguard Worker 	obj = calloc(count + 2, sizeof(*obj));
213*d83cc019SAndroid Build Coastguard Worker 	igt_assert(obj);
214*d83cc019SAndroid Build Coastguard Worker 
215*d83cc019SAndroid Build Coastguard Worker 	obj[0].handle = gem_create(fd, 4096);
216*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < count; i++) {
217*d83cc019SAndroid Build Coastguard Worker 		obj[i + 1].handle = gem_create(fd, size);
218*d83cc019SAndroid Build Coastguard Worker 		obj[i + 1].flags =
219*d83cc019SAndroid Build Coastguard Worker 			LOCAL_OBJECT_CAPTURE | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
220*d83cc019SAndroid Build Coastguard Worker 		if (flags & INCREMENTAL) {
221*d83cc019SAndroid Build Coastguard Worker 			uint32_t *ptr;
222*d83cc019SAndroid Build Coastguard Worker 
223*d83cc019SAndroid Build Coastguard Worker 			ptr = gem_mmap__cpu(fd, obj[i + 1].handle,
224*d83cc019SAndroid Build Coastguard Worker 					    0, size, PROT_WRITE);
225*d83cc019SAndroid Build Coastguard Worker 			for (unsigned int n = 0; n < size / sizeof(*ptr); n++)
226*d83cc019SAndroid Build Coastguard Worker 				ptr[n] = i * size + n;
227*d83cc019SAndroid Build Coastguard Worker 			munmap(ptr, size);
228*d83cc019SAndroid Build Coastguard Worker 		}
229*d83cc019SAndroid Build Coastguard Worker 	}
230*d83cc019SAndroid Build Coastguard Worker 
231*d83cc019SAndroid Build Coastguard Worker 	obj[count + 1].handle = gem_create(fd, 4096);
232*d83cc019SAndroid Build Coastguard Worker 	obj[count + 1].relocs_ptr = (uintptr_t)reloc;
233*d83cc019SAndroid Build Coastguard Worker 	obj[count + 1].relocation_count = ARRAY_SIZE(reloc);
234*d83cc019SAndroid Build Coastguard Worker 
235*d83cc019SAndroid Build Coastguard Worker 	memset(reloc, 0, sizeof(reloc));
236*d83cc019SAndroid Build Coastguard Worker 	reloc[0].target_handle = obj[count + 1].handle; /* recurse */
237*d83cc019SAndroid Build Coastguard Worker 	reloc[0].presumed_offset = 0;
238*d83cc019SAndroid Build Coastguard Worker 	reloc[0].offset = 5*sizeof(uint32_t);
239*d83cc019SAndroid Build Coastguard Worker 	reloc[0].delta = 0;
240*d83cc019SAndroid Build Coastguard Worker 	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
241*d83cc019SAndroid Build Coastguard Worker 	reloc[0].write_domain = 0;
242*d83cc019SAndroid Build Coastguard Worker 
243*d83cc019SAndroid Build Coastguard Worker 	reloc[1].target_handle = obj[0].handle; /* breadcrumb */
244*d83cc019SAndroid Build Coastguard Worker 	reloc[1].presumed_offset = 0;
245*d83cc019SAndroid Build Coastguard Worker 	reloc[1].offset = sizeof(uint32_t);
246*d83cc019SAndroid Build Coastguard Worker 	reloc[1].delta = 0;
247*d83cc019SAndroid Build Coastguard Worker 	reloc[1].read_domains = I915_GEM_DOMAIN_RENDER;
248*d83cc019SAndroid Build Coastguard Worker 	reloc[1].write_domain = I915_GEM_DOMAIN_RENDER;
249*d83cc019SAndroid Build Coastguard Worker 
250*d83cc019SAndroid Build Coastguard Worker 	seqno = gem_mmap__wc(fd, obj[0].handle, 0, 4096, PROT_READ);
251*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, obj[0].handle,
252*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 	batch = gem_mmap__cpu(fd, obj[count + 1].handle, 0, 4096, PROT_WRITE);
255*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, obj[count + 1].handle,
256*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
257*d83cc019SAndroid Build Coastguard Worker 
258*d83cc019SAndroid Build Coastguard Worker 	i = 0;
259*d83cc019SAndroid Build Coastguard Worker 	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
260*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
261*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
262*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
263*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 4) {
264*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
265*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
266*d83cc019SAndroid Build Coastguard Worker 		reloc[1].offset += sizeof(uint32_t);
267*d83cc019SAndroid Build Coastguard Worker 	} else {
268*d83cc019SAndroid Build Coastguard Worker 		batch[i]--;
269*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
270*d83cc019SAndroid Build Coastguard Worker 	}
271*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = 0xc0ffee;
272*d83cc019SAndroid Build Coastguard Worker 	if (gen < 4)
273*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = MI_NOOP;
274*d83cc019SAndroid Build Coastguard Worker 
275*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = MI_BATCH_BUFFER_START; /* not crashed? try again! */
276*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
277*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8 | 1;
278*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
279*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
280*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 6) {
281*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8;
282*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
283*d83cc019SAndroid Build Coastguard Worker 	} else {
284*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 2 << 6;
285*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
286*d83cc019SAndroid Build Coastguard Worker 		if (gen < 4) {
287*d83cc019SAndroid Build Coastguard Worker 			batch[i] |= 1;
288*d83cc019SAndroid Build Coastguard Worker 			reloc[0].delta = 1;
289*d83cc019SAndroid Build Coastguard Worker 		}
290*d83cc019SAndroid Build Coastguard Worker 	}
291*d83cc019SAndroid Build Coastguard Worker 	munmap(batch, 4096);
292*d83cc019SAndroid Build Coastguard Worker 
293*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
294*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = (uintptr_t)obj;
295*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = count + 2;
296*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = ring;
297*d83cc019SAndroid Build Coastguard Worker 	if (gen > 3 && gen < 6)
298*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags |= I915_EXEC_SECURE;
299*d83cc019SAndroid Build Coastguard Worker 
300*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!READ_ONCE(*seqno));
301*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
302*d83cc019SAndroid Build Coastguard Worker 
303*d83cc019SAndroid Build Coastguard Worker 	/* Wait for the request to start */
304*d83cc019SAndroid Build Coastguard Worker 	while (READ_ONCE(*seqno) != 0xc0ffee)
305*d83cc019SAndroid Build Coastguard Worker 		igt_assert(gem_bo_busy(fd, obj[0].handle));
306*d83cc019SAndroid Build Coastguard Worker 	munmap(seqno, 4096);
307*d83cc019SAndroid Build Coastguard Worker 
308*d83cc019SAndroid Build Coastguard Worker 	igt_force_gpu_reset(fd);
309*d83cc019SAndroid Build Coastguard Worker 
310*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, obj[count + 1].handle);
311*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[count + 1].handle);
312*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < count; i++) {
313*d83cc019SAndroid Build Coastguard Worker 		offsets[i].addr = obj[i + 1].offset;
314*d83cc019SAndroid Build Coastguard Worker 		offsets[i].idx = i;
315*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, obj[i + 1].handle);
316*d83cc019SAndroid Build Coastguard Worker 	}
317*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[0].handle);
318*d83cc019SAndroid Build Coastguard Worker 
319*d83cc019SAndroid Build Coastguard Worker 	qsort(offsets, count, sizeof(*offsets), cmp);
320*d83cc019SAndroid Build Coastguard Worker 	igt_assert(offsets[0].addr <= offsets[count-1].addr);
321*d83cc019SAndroid Build Coastguard Worker 	return offsets;
322*d83cc019SAndroid Build Coastguard Worker }
323*d83cc019SAndroid Build Coastguard Worker 
zlib_inflate(uint32_t ** ptr,unsigned long len)324*d83cc019SAndroid Build Coastguard Worker static unsigned long zlib_inflate(uint32_t **ptr, unsigned long len)
325*d83cc019SAndroid Build Coastguard Worker {
326*d83cc019SAndroid Build Coastguard Worker 	struct z_stream_s zstream;
327*d83cc019SAndroid Build Coastguard Worker 	void *out;
328*d83cc019SAndroid Build Coastguard Worker 
329*d83cc019SAndroid Build Coastguard Worker 	memset(&zstream, 0, sizeof(zstream));
330*d83cc019SAndroid Build Coastguard Worker 
331*d83cc019SAndroid Build Coastguard Worker 	zstream.next_in = (unsigned char *)*ptr;
332*d83cc019SAndroid Build Coastguard Worker 	zstream.avail_in = 4*len;
333*d83cc019SAndroid Build Coastguard Worker 
334*d83cc019SAndroid Build Coastguard Worker 	if (inflateInit(&zstream) != Z_OK)
335*d83cc019SAndroid Build Coastguard Worker 		return 0;
336*d83cc019SAndroid Build Coastguard Worker 
337*d83cc019SAndroid Build Coastguard Worker 	out = malloc(128*4096); /* approximate obj size */
338*d83cc019SAndroid Build Coastguard Worker 	zstream.next_out = out;
339*d83cc019SAndroid Build Coastguard Worker 	zstream.avail_out = 128*4096;
340*d83cc019SAndroid Build Coastguard Worker 
341*d83cc019SAndroid Build Coastguard Worker 	do {
342*d83cc019SAndroid Build Coastguard Worker 		switch (inflate(&zstream, Z_SYNC_FLUSH)) {
343*d83cc019SAndroid Build Coastguard Worker 		case Z_STREAM_END:
344*d83cc019SAndroid Build Coastguard Worker 			goto end;
345*d83cc019SAndroid Build Coastguard Worker 		case Z_OK:
346*d83cc019SAndroid Build Coastguard Worker 			break;
347*d83cc019SAndroid Build Coastguard Worker 		default:
348*d83cc019SAndroid Build Coastguard Worker 			inflateEnd(&zstream);
349*d83cc019SAndroid Build Coastguard Worker 			return 0;
350*d83cc019SAndroid Build Coastguard Worker 		}
351*d83cc019SAndroid Build Coastguard Worker 
352*d83cc019SAndroid Build Coastguard Worker 		if (zstream.avail_out)
353*d83cc019SAndroid Build Coastguard Worker 			break;
354*d83cc019SAndroid Build Coastguard Worker 
355*d83cc019SAndroid Build Coastguard Worker 		out = realloc(out, 2*zstream.total_out);
356*d83cc019SAndroid Build Coastguard Worker 		if (out == NULL) {
357*d83cc019SAndroid Build Coastguard Worker 			inflateEnd(&zstream);
358*d83cc019SAndroid Build Coastguard Worker 			return 0;
359*d83cc019SAndroid Build Coastguard Worker 		}
360*d83cc019SAndroid Build Coastguard Worker 
361*d83cc019SAndroid Build Coastguard Worker 		zstream.next_out = (unsigned char *)out + zstream.total_out;
362*d83cc019SAndroid Build Coastguard Worker 		zstream.avail_out = zstream.total_out;
363*d83cc019SAndroid Build Coastguard Worker 	} while (1);
364*d83cc019SAndroid Build Coastguard Worker end:
365*d83cc019SAndroid Build Coastguard Worker 	inflateEnd(&zstream);
366*d83cc019SAndroid Build Coastguard Worker 	free(*ptr);
367*d83cc019SAndroid Build Coastguard Worker 	*ptr = out;
368*d83cc019SAndroid Build Coastguard Worker 	return zstream.total_out / 4;
369*d83cc019SAndroid Build Coastguard Worker }
370*d83cc019SAndroid Build Coastguard Worker 
371*d83cc019SAndroid Build Coastguard Worker static unsigned long
ascii85_decode(char * in,uint32_t ** out,bool inflate,char ** end)372*d83cc019SAndroid Build Coastguard Worker ascii85_decode(char *in, uint32_t **out, bool inflate, char **end)
373*d83cc019SAndroid Build Coastguard Worker {
374*d83cc019SAndroid Build Coastguard Worker 	unsigned long len = 0, size = 1024;
375*d83cc019SAndroid Build Coastguard Worker 
376*d83cc019SAndroid Build Coastguard Worker 	*out = realloc(*out, sizeof(uint32_t)*size);
377*d83cc019SAndroid Build Coastguard Worker 	if (*out == NULL)
378*d83cc019SAndroid Build Coastguard Worker 		return 0;
379*d83cc019SAndroid Build Coastguard Worker 
380*d83cc019SAndroid Build Coastguard Worker 	while (*in >= '!' && *in <= 'z') {
381*d83cc019SAndroid Build Coastguard Worker 		uint32_t v = 0;
382*d83cc019SAndroid Build Coastguard Worker 
383*d83cc019SAndroid Build Coastguard Worker 		if (len == size) {
384*d83cc019SAndroid Build Coastguard Worker 			size *= 2;
385*d83cc019SAndroid Build Coastguard Worker 			*out = realloc(*out, sizeof(uint32_t)*size);
386*d83cc019SAndroid Build Coastguard Worker 			if (*out == NULL)
387*d83cc019SAndroid Build Coastguard Worker 				return 0;
388*d83cc019SAndroid Build Coastguard Worker 		}
389*d83cc019SAndroid Build Coastguard Worker 
390*d83cc019SAndroid Build Coastguard Worker 		if (*in == 'z') {
391*d83cc019SAndroid Build Coastguard Worker 			in++;
392*d83cc019SAndroid Build Coastguard Worker 		} else {
393*d83cc019SAndroid Build Coastguard Worker 			v += in[0] - 33; v *= 85;
394*d83cc019SAndroid Build Coastguard Worker 			v += in[1] - 33; v *= 85;
395*d83cc019SAndroid Build Coastguard Worker 			v += in[2] - 33; v *= 85;
396*d83cc019SAndroid Build Coastguard Worker 			v += in[3] - 33; v *= 85;
397*d83cc019SAndroid Build Coastguard Worker 			v += in[4] - 33;
398*d83cc019SAndroid Build Coastguard Worker 			in += 5;
399*d83cc019SAndroid Build Coastguard Worker 		}
400*d83cc019SAndroid Build Coastguard Worker 		(*out)[len++] = v;
401*d83cc019SAndroid Build Coastguard Worker 	}
402*d83cc019SAndroid Build Coastguard Worker 	*end = in;
403*d83cc019SAndroid Build Coastguard Worker 
404*d83cc019SAndroid Build Coastguard Worker 	if (!inflate)
405*d83cc019SAndroid Build Coastguard Worker 		return len;
406*d83cc019SAndroid Build Coastguard Worker 
407*d83cc019SAndroid Build Coastguard Worker 	return zlib_inflate(out, len);
408*d83cc019SAndroid Build Coastguard Worker }
409*d83cc019SAndroid Build Coastguard Worker 
many(int fd,int dir,uint64_t size,unsigned int flags)410*d83cc019SAndroid Build Coastguard Worker static void many(int fd, int dir, uint64_t size, unsigned int flags)
411*d83cc019SAndroid Build Coastguard Worker {
412*d83cc019SAndroid Build Coastguard Worker 	uint64_t ram, gtt;
413*d83cc019SAndroid Build Coastguard Worker 	unsigned long count, blobs;
414*d83cc019SAndroid Build Coastguard Worker 	struct offset *offsets;
415*d83cc019SAndroid Build Coastguard Worker 	char *error, *str;
416*d83cc019SAndroid Build Coastguard Worker 
417*d83cc019SAndroid Build Coastguard Worker 	gtt = gem_aperture_size(fd) / size;
418*d83cc019SAndroid Build Coastguard Worker 	ram = (intel_get_avail_ram_mb() << 20) / size;
419*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Available objects in GTT:%"PRIu64", RAM:%"PRIu64"\n",
420*d83cc019SAndroid Build Coastguard Worker 		  gtt, ram);
421*d83cc019SAndroid Build Coastguard Worker 
422*d83cc019SAndroid Build Coastguard Worker 	count = min(gtt, ram) / 4;
423*d83cc019SAndroid Build Coastguard Worker 	igt_require(count > 1);
424*d83cc019SAndroid Build Coastguard Worker 
425*d83cc019SAndroid Build Coastguard Worker 	intel_require_memory(count, size, CHECK_RAM);
426*d83cc019SAndroid Build Coastguard Worker 
427*d83cc019SAndroid Build Coastguard Worker 	offsets = __captureN(fd, dir, 0, size, count, flags);
428*d83cc019SAndroid Build Coastguard Worker 
429*d83cc019SAndroid Build Coastguard Worker 	error = igt_sysfs_get(dir, "error");
430*d83cc019SAndroid Build Coastguard Worker 	igt_sysfs_set(dir, "error", "Begone!");
431*d83cc019SAndroid Build Coastguard Worker 	igt_assert(error);
432*d83cc019SAndroid Build Coastguard Worker 
433*d83cc019SAndroid Build Coastguard Worker 	blobs = 0;
434*d83cc019SAndroid Build Coastguard Worker 	/* render ring --- user = 0x00000000 ffffd000 */
435*d83cc019SAndroid Build Coastguard Worker 	str = strstr(error, "--- user = ");
436*d83cc019SAndroid Build Coastguard Worker 	while (str) {
437*d83cc019SAndroid Build Coastguard Worker 		uint32_t *data = NULL;
438*d83cc019SAndroid Build Coastguard Worker 		unsigned long i, sz;
439*d83cc019SAndroid Build Coastguard Worker 		uint64_t addr;
440*d83cc019SAndroid Build Coastguard Worker 
441*d83cc019SAndroid Build Coastguard Worker 		if (strncmp(str, "--- user = 0x", 13))
442*d83cc019SAndroid Build Coastguard Worker 			break;
443*d83cc019SAndroid Build Coastguard Worker 
444*d83cc019SAndroid Build Coastguard Worker 		str += 13;
445*d83cc019SAndroid Build Coastguard Worker 		addr = strtoul(str, &str, 16);
446*d83cc019SAndroid Build Coastguard Worker 		addr <<= 32;
447*d83cc019SAndroid Build Coastguard Worker 		addr |= strtoul(str + 1, &str, 16);
448*d83cc019SAndroid Build Coastguard Worker 		igt_assert(*str++ == '\n');
449*d83cc019SAndroid Build Coastguard Worker 
450*d83cc019SAndroid Build Coastguard Worker 		if (!(*str == ':' || *str == '~'))
451*d83cc019SAndroid Build Coastguard Worker 			continue;
452*d83cc019SAndroid Build Coastguard Worker 
453*d83cc019SAndroid Build Coastguard Worker 		igt_debug("blob:%.64s\n", str);
454*d83cc019SAndroid Build Coastguard Worker 		sz = ascii85_decode(str + 1, &data, *str == ':', &str);
455*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(4 * sz, size);
456*d83cc019SAndroid Build Coastguard Worker 		igt_assert(*str++ == '\n');
457*d83cc019SAndroid Build Coastguard Worker 		str = strchr(str, '-');
458*d83cc019SAndroid Build Coastguard Worker 
459*d83cc019SAndroid Build Coastguard Worker 		if (flags & INCREMENTAL) {
460*d83cc019SAndroid Build Coastguard Worker 			unsigned long start = 0;
461*d83cc019SAndroid Build Coastguard Worker 			unsigned long end = count;
462*d83cc019SAndroid Build Coastguard Worker 			uint32_t expect;
463*d83cc019SAndroid Build Coastguard Worker 
464*d83cc019SAndroid Build Coastguard Worker 			while (end > start) {
465*d83cc019SAndroid Build Coastguard Worker 				i = (end - start) / 2 + start;
466*d83cc019SAndroid Build Coastguard Worker 				if (offsets[i].addr < addr)
467*d83cc019SAndroid Build Coastguard Worker 					start = i + 1;
468*d83cc019SAndroid Build Coastguard Worker 				else if (offsets[i].addr > addr)
469*d83cc019SAndroid Build Coastguard Worker 					end = i;
470*d83cc019SAndroid Build Coastguard Worker 				else
471*d83cc019SAndroid Build Coastguard Worker 					break;
472*d83cc019SAndroid Build Coastguard Worker 			}
473*d83cc019SAndroid Build Coastguard Worker 			igt_assert(offsets[i].addr == addr);
474*d83cc019SAndroid Build Coastguard Worker 			igt_debug("offset:%"PRIx64", index:%ld\n",
475*d83cc019SAndroid Build Coastguard Worker 				  addr, offsets[i].idx);
476*d83cc019SAndroid Build Coastguard Worker 
477*d83cc019SAndroid Build Coastguard Worker 			expect = offsets[i].idx * size;
478*d83cc019SAndroid Build Coastguard Worker 			for (i = 0; i < sz; i++)
479*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq(data[i], expect++);
480*d83cc019SAndroid Build Coastguard Worker 		} else {
481*d83cc019SAndroid Build Coastguard Worker 			for (i = 0; i < sz; i++)
482*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq(data[i], 0);
483*d83cc019SAndroid Build Coastguard Worker 		}
484*d83cc019SAndroid Build Coastguard Worker 
485*d83cc019SAndroid Build Coastguard Worker 		blobs++;
486*d83cc019SAndroid Build Coastguard Worker 		free(data);
487*d83cc019SAndroid Build Coastguard Worker 	}
488*d83cc019SAndroid Build Coastguard Worker 	igt_info("Captured %lu %"PRId64"-blobs out of a total of %lu\n",
489*d83cc019SAndroid Build Coastguard Worker 		 blobs, size >> 12, count);
490*d83cc019SAndroid Build Coastguard Worker 	igt_assert(count);
491*d83cc019SAndroid Build Coastguard Worker 
492*d83cc019SAndroid Build Coastguard Worker 	free(error);
493*d83cc019SAndroid Build Coastguard Worker 	free(offsets);
494*d83cc019SAndroid Build Coastguard Worker }
495*d83cc019SAndroid Build Coastguard Worker 
userptr(int fd,int dir)496*d83cc019SAndroid Build Coastguard Worker static void userptr(int fd, int dir)
497*d83cc019SAndroid Build Coastguard Worker {
498*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
499*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
500*d83cc019SAndroid Build Coastguard Worker 
501*d83cc019SAndroid Build Coastguard Worker 	igt_assert(posix_memalign(&ptr, 4096, 4096) == 0);
502*d83cc019SAndroid Build Coastguard Worker 	igt_require(__gem_userptr(fd, ptr, 4096, 0, 0, &handle) == 0);
503*d83cc019SAndroid Build Coastguard Worker 
504*d83cc019SAndroid Build Coastguard Worker 	__capture1(fd, dir, 0, handle);
505*d83cc019SAndroid Build Coastguard Worker 
506*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, handle);
507*d83cc019SAndroid Build Coastguard Worker 	free(ptr);
508*d83cc019SAndroid Build Coastguard Worker }
509*d83cc019SAndroid Build Coastguard Worker 
has_capture(int fd)510*d83cc019SAndroid Build Coastguard Worker static bool has_capture(int fd)
511*d83cc019SAndroid Build Coastguard Worker {
512*d83cc019SAndroid Build Coastguard Worker 	drm_i915_getparam_t gp;
513*d83cc019SAndroid Build Coastguard Worker 	int async = -1;
514*d83cc019SAndroid Build Coastguard Worker 
515*d83cc019SAndroid Build Coastguard Worker 	gp.param = LOCAL_PARAM_HAS_EXEC_CAPTURE;
516*d83cc019SAndroid Build Coastguard Worker 	gp.value = &async;
517*d83cc019SAndroid Build Coastguard Worker 	drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
518*d83cc019SAndroid Build Coastguard Worker 
519*d83cc019SAndroid Build Coastguard Worker 	return async > 0;
520*d83cc019SAndroid Build Coastguard Worker }
521*d83cc019SAndroid Build Coastguard Worker 
safer_strlen(const char * s)522*d83cc019SAndroid Build Coastguard Worker static size_t safer_strlen(const char *s)
523*d83cc019SAndroid Build Coastguard Worker {
524*d83cc019SAndroid Build Coastguard Worker 	return s ? strlen(s) : 0;
525*d83cc019SAndroid Build Coastguard Worker }
526*d83cc019SAndroid Build Coastguard Worker 
527*d83cc019SAndroid Build Coastguard Worker igt_main
528*d83cc019SAndroid Build Coastguard Worker {
529*d83cc019SAndroid Build Coastguard Worker 	const struct intel_execution_engine *e;
530*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
531*d83cc019SAndroid Build Coastguard Worker 	int fd = -1;
532*d83cc019SAndroid Build Coastguard Worker 	int dir = -1;
533*d83cc019SAndroid Build Coastguard Worker 
534*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
535*d83cc019SAndroid Build Coastguard Worker 
536*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
537*d83cc019SAndroid Build Coastguard Worker 		int gen;
538*d83cc019SAndroid Build Coastguard Worker 
539*d83cc019SAndroid Build Coastguard Worker 		fd = drm_open_driver(DRIVER_INTEL);
540*d83cc019SAndroid Build Coastguard Worker 
541*d83cc019SAndroid Build Coastguard Worker 		gen = intel_gen(intel_get_drm_devid(fd));
542*d83cc019SAndroid Build Coastguard Worker 		if (gen > 3 && gen < 6) /* ctg and ilk need secure batches */
543*d83cc019SAndroid Build Coastguard Worker 			igt_device_set_master(fd);
544*d83cc019SAndroid Build Coastguard Worker 
545*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(fd);
546*d83cc019SAndroid Build Coastguard Worker 		gem_require_mmap_wc(fd);
547*d83cc019SAndroid Build Coastguard Worker 		igt_require(has_capture(fd));
548*d83cc019SAndroid Build Coastguard Worker 		igt_allow_hang(fd, 0, HANG_ALLOW_CAPTURE);
549*d83cc019SAndroid Build Coastguard Worker 
550*d83cc019SAndroid Build Coastguard Worker 		dir = igt_sysfs_open(fd);
551*d83cc019SAndroid Build Coastguard Worker 		igt_require(igt_sysfs_set(dir, "error", "Begone!"));
552*d83cc019SAndroid Build Coastguard Worker 		igt_require(safer_strlen(igt_sysfs_get(dir, "error")) > 0);
553*d83cc019SAndroid Build Coastguard Worker 	}
554*d83cc019SAndroid Build Coastguard Worker 
555*d83cc019SAndroid Build Coastguard Worker 	for (e = intel_execution_engines; e->name; e++) {
556*d83cc019SAndroid Build Coastguard Worker 		/* default exec-id is purely symbolic */
557*d83cc019SAndroid Build Coastguard Worker 		if (e->exec_id == 0)
558*d83cc019SAndroid Build Coastguard Worker 			continue;
559*d83cc019SAndroid Build Coastguard Worker 
560*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("capture-%s", e->name) {
561*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_ring_has_physical_engine(fd, e->exec_id | e->flags));
562*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_can_store_dword(fd, e->exec_id | e->flags));
563*d83cc019SAndroid Build Coastguard Worker 			capture(fd, dir, e->exec_id | e->flags);
564*d83cc019SAndroid Build Coastguard Worker 		}
565*d83cc019SAndroid Build Coastguard Worker 	}
566*d83cc019SAndroid Build Coastguard Worker 
567*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("many-4K-zero") {
568*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_can_store_dword(fd, 0));
569*d83cc019SAndroid Build Coastguard Worker 		many(fd, dir, 1<<12, 0);
570*d83cc019SAndroid Build Coastguard Worker 	}
571*d83cc019SAndroid Build Coastguard Worker 
572*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("many-4K-incremental") {
573*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_can_store_dword(fd, 0));
574*d83cc019SAndroid Build Coastguard Worker 		many(fd, dir, 1<<12, INCREMENTAL);
575*d83cc019SAndroid Build Coastguard Worker 	}
576*d83cc019SAndroid Build Coastguard Worker 
577*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("many-2M-zero") {
578*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_can_store_dword(fd, 0));
579*d83cc019SAndroid Build Coastguard Worker 		many(fd, dir, 2<<20, 0);
580*d83cc019SAndroid Build Coastguard Worker 	}
581*d83cc019SAndroid Build Coastguard Worker 
582*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("many-2M-incremental") {
583*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_can_store_dword(fd, 0));
584*d83cc019SAndroid Build Coastguard Worker 		many(fd, dir, 2<<20, INCREMENTAL);
585*d83cc019SAndroid Build Coastguard Worker 	}
586*d83cc019SAndroid Build Coastguard Worker 
587*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("many-256M-incremental") {
588*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_can_store_dword(fd, 0));
589*d83cc019SAndroid Build Coastguard Worker 		many(fd, dir, 256<<20, INCREMENTAL);
590*d83cc019SAndroid Build Coastguard Worker 	}
591*d83cc019SAndroid Build Coastguard Worker 
592*d83cc019SAndroid Build Coastguard Worker 	/* And check we can read from different types of objects */
593*d83cc019SAndroid Build Coastguard Worker 
594*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("userptr") {
595*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_can_store_dword(fd, 0));
596*d83cc019SAndroid Build Coastguard Worker 		userptr(fd, dir);
597*d83cc019SAndroid Build Coastguard Worker 	}
598*d83cc019SAndroid Build Coastguard Worker 
599*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
600*d83cc019SAndroid Build Coastguard Worker 		close(dir);
601*d83cc019SAndroid Build Coastguard Worker 		igt_disallow_hang(fd, hang);
602*d83cc019SAndroid Build Coastguard Worker 		close(fd);
603*d83cc019SAndroid Build Coastguard Worker 	}
604*d83cc019SAndroid Build Coastguard Worker }
605