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 <time.h>
25*d83cc019SAndroid Build Coastguard Worker
26*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
27*d83cc019SAndroid Build Coastguard Worker #include "igt_x86.h"
28*d83cc019SAndroid Build Coastguard Worker
29*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Basic check of flushing after batches");
30*d83cc019SAndroid Build Coastguard Worker
31*d83cc019SAndroid Build Coastguard Worker #define UNCACHED 0
32*d83cc019SAndroid Build Coastguard Worker #define COHERENT 1
33*d83cc019SAndroid Build Coastguard Worker #define WC 2
34*d83cc019SAndroid Build Coastguard Worker #define WRITE 4
35*d83cc019SAndroid Build Coastguard Worker #define KERNEL 8
36*d83cc019SAndroid Build Coastguard Worker #define SET_DOMAIN 16
37*d83cc019SAndroid Build Coastguard Worker #define BEFORE 32
38*d83cc019SAndroid Build Coastguard Worker #define INTERRUPTIBLE 64
39*d83cc019SAndroid Build Coastguard Worker #define CMDPARSER 128
40*d83cc019SAndroid Build Coastguard Worker #define BASIC 256
41*d83cc019SAndroid Build Coastguard Worker #define MOVNT 512
42*d83cc019SAndroid Build Coastguard Worker
43*d83cc019SAndroid Build Coastguard Worker #if defined(__x86_64__) && !defined(__clang__)
44*d83cc019SAndroid Build Coastguard Worker #pragma GCC push_options
45*d83cc019SAndroid Build Coastguard Worker #pragma GCC target("sse4.1")
46*d83cc019SAndroid Build Coastguard Worker #include <smmintrin.h>
47*d83cc019SAndroid Build Coastguard Worker __attribute__((noinline))
movnt(uint32_t * map,int i)48*d83cc019SAndroid Build Coastguard Worker static uint32_t movnt(uint32_t *map, int i)
49*d83cc019SAndroid Build Coastguard Worker {
50*d83cc019SAndroid Build Coastguard Worker __m128i tmp;
51*d83cc019SAndroid Build Coastguard Worker
52*d83cc019SAndroid Build Coastguard Worker tmp = _mm_stream_load_si128((__m128i *)map + i/4);
53*d83cc019SAndroid Build Coastguard Worker switch (i%4) { /* gcc! */
54*d83cc019SAndroid Build Coastguard Worker default:
55*d83cc019SAndroid Build Coastguard Worker case 0: return _mm_extract_epi32(tmp, 0);
56*d83cc019SAndroid Build Coastguard Worker case 1: return _mm_extract_epi32(tmp, 1);
57*d83cc019SAndroid Build Coastguard Worker case 2: return _mm_extract_epi32(tmp, 2);
58*d83cc019SAndroid Build Coastguard Worker case 3: return _mm_extract_epi32(tmp, 3);
59*d83cc019SAndroid Build Coastguard Worker }
60*d83cc019SAndroid Build Coastguard Worker }
x86_64_features(void)61*d83cc019SAndroid Build Coastguard Worker static inline unsigned x86_64_features(void)
62*d83cc019SAndroid Build Coastguard Worker {
63*d83cc019SAndroid Build Coastguard Worker return igt_x86_features();
64*d83cc019SAndroid Build Coastguard Worker }
65*d83cc019SAndroid Build Coastguard Worker #pragma GCC pop_options
66*d83cc019SAndroid Build Coastguard Worker #else
x86_64_features(void)67*d83cc019SAndroid Build Coastguard Worker static inline unsigned x86_64_features(void)
68*d83cc019SAndroid Build Coastguard Worker {
69*d83cc019SAndroid Build Coastguard Worker return 0;
70*d83cc019SAndroid Build Coastguard Worker }
movnt(uint32_t * map,int i)71*d83cc019SAndroid Build Coastguard Worker static uint32_t movnt(uint32_t *map, int i)
72*d83cc019SAndroid Build Coastguard Worker {
73*d83cc019SAndroid Build Coastguard Worker igt_assert(!"reached");
74*d83cc019SAndroid Build Coastguard Worker }
75*d83cc019SAndroid Build Coastguard Worker #endif
76*d83cc019SAndroid Build Coastguard Worker
run(int fd,unsigned ring,int nchild,int timeout,unsigned flags)77*d83cc019SAndroid Build Coastguard Worker static void run(int fd, unsigned ring, int nchild, int timeout,
78*d83cc019SAndroid Build Coastguard Worker unsigned flags)
79*d83cc019SAndroid Build Coastguard Worker {
80*d83cc019SAndroid Build Coastguard Worker const int gen = intel_gen(intel_get_drm_devid(fd));
81*d83cc019SAndroid Build Coastguard Worker
82*d83cc019SAndroid Build Coastguard Worker /* The crux of this testing is whether writes by the GPU are coherent
83*d83cc019SAndroid Build Coastguard Worker * from the CPU.
84*d83cc019SAndroid Build Coastguard Worker *
85*d83cc019SAndroid Build Coastguard Worker * For example, using plain clflush (the simplest and most visible
86*d83cc019SAndroid Build Coastguard Worker * in terms of function calls / syscalls) we have two tests which
87*d83cc019SAndroid Build Coastguard Worker * perform:
88*d83cc019SAndroid Build Coastguard Worker *
89*d83cc019SAndroid Build Coastguard Worker * USER (0):
90*d83cc019SAndroid Build Coastguard Worker * execbuf(map[i] = i);
91*d83cc019SAndroid Build Coastguard Worker * sync();
92*d83cc019SAndroid Build Coastguard Worker * clflush(&map[i]);
93*d83cc019SAndroid Build Coastguard Worker * assert(map[i] == i);
94*d83cc019SAndroid Build Coastguard Worker *
95*d83cc019SAndroid Build Coastguard Worker * execbuf(map[i] = i ^ ~0);
96*d83cc019SAndroid Build Coastguard Worker * sync();
97*d83cc019SAndroid Build Coastguard Worker * clflush(&map[i]);
98*d83cc019SAndroid Build Coastguard Worker * assert(map[i] == i ^ ~0);
99*d83cc019SAndroid Build Coastguard Worker *
100*d83cc019SAndroid Build Coastguard Worker * BEFORE:
101*d83cc019SAndroid Build Coastguard Worker * clflush(&map[i]);
102*d83cc019SAndroid Build Coastguard Worker * execbuf(map[i] = i);
103*d83cc019SAndroid Build Coastguard Worker * sync();
104*d83cc019SAndroid Build Coastguard Worker * assert(map[i] == i);
105*d83cc019SAndroid Build Coastguard Worker *
106*d83cc019SAndroid Build Coastguard Worker * clflush(&map[i]);
107*d83cc019SAndroid Build Coastguard Worker * execbuf(map[i] = i ^ ~0);
108*d83cc019SAndroid Build Coastguard Worker * sync();
109*d83cc019SAndroid Build Coastguard Worker * assert(map[i] == i ^ ~0);
110*d83cc019SAndroid Build Coastguard Worker *
111*d83cc019SAndroid Build Coastguard Worker * The assertion here is that the cacheline invalidations are precise
112*d83cc019SAndroid Build Coastguard Worker * and we have no speculative prefetch that can see the future map[i]
113*d83cc019SAndroid Build Coastguard Worker * access and bring it ahead of the execution, or accidental cache
114*d83cc019SAndroid Build Coastguard Worker * pollution by the kernel.
115*d83cc019SAndroid Build Coastguard Worker */
116*d83cc019SAndroid Build Coastguard Worker
117*d83cc019SAndroid Build Coastguard Worker igt_fork(child, nchild) {
118*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
119*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj[3];
120*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc0[1024];
121*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc1[1024];
122*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
123*d83cc019SAndroid Build Coastguard Worker unsigned long cycles = 0;
124*d83cc019SAndroid Build Coastguard Worker bool snoop = false;
125*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr;
126*d83cc019SAndroid Build Coastguard Worker uint32_t *map;
127*d83cc019SAndroid Build Coastguard Worker int i;
128*d83cc019SAndroid Build Coastguard Worker
129*d83cc019SAndroid Build Coastguard Worker memset(obj, 0, sizeof(obj));
130*d83cc019SAndroid Build Coastguard Worker obj[0].handle = gem_create(fd, 4096);
131*d83cc019SAndroid Build Coastguard Worker obj[0].flags |= EXEC_OBJECT_WRITE;
132*d83cc019SAndroid Build Coastguard Worker
133*d83cc019SAndroid Build Coastguard Worker if (flags & WC) {
134*d83cc019SAndroid Build Coastguard Worker igt_assert(flags & COHERENT);
135*d83cc019SAndroid Build Coastguard Worker map = gem_mmap__wc(fd, obj[0].handle, 0, 4096, PROT_WRITE);
136*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[0].handle,
137*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_WC,
138*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_WC);
139*d83cc019SAndroid Build Coastguard Worker } else {
140*d83cc019SAndroid Build Coastguard Worker snoop = flags & COHERENT;
141*d83cc019SAndroid Build Coastguard Worker gem_set_caching(fd, obj[0].handle, snoop);
142*d83cc019SAndroid Build Coastguard Worker map = gem_mmap__cpu(fd, obj[0].handle, 0, 4096, PROT_WRITE);
143*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[0].handle,
144*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU,
145*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU);
146*d83cc019SAndroid Build Coastguard Worker }
147*d83cc019SAndroid Build Coastguard Worker
148*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < 1024; i++)
149*d83cc019SAndroid Build Coastguard Worker map[i] = 0xabcdabcd;
150*d83cc019SAndroid Build Coastguard Worker
151*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[0].handle,
152*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_WC,
153*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_WC);
154*d83cc019SAndroid Build Coastguard Worker
155*d83cc019SAndroid Build Coastguard Worker /* Prepara a mappable binding to prevent pread mighrating */
156*d83cc019SAndroid Build Coastguard Worker if (!snoop) {
157*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__gtt(fd, obj[0].handle, 4096, PROT_READ);
158*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(ptr[0], 0xabcdabcd);
159*d83cc019SAndroid Build Coastguard Worker munmap(ptr, 4096);
160*d83cc019SAndroid Build Coastguard Worker }
161*d83cc019SAndroid Build Coastguard Worker
162*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
163*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(obj);
164*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 3;
165*d83cc019SAndroid Build Coastguard Worker execbuf.flags = ring | (1 << 11) | (1<<12);
166*d83cc019SAndroid Build Coastguard Worker if (gen < 6)
167*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= I915_EXEC_SECURE;
168*d83cc019SAndroid Build Coastguard Worker
169*d83cc019SAndroid Build Coastguard Worker obj[1].handle = gem_create(fd, 1024*64);
170*d83cc019SAndroid Build Coastguard Worker obj[2].handle = gem_create(fd, 1024*64);
171*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[2].handle, 0, &bbe, sizeof(bbe));
172*d83cc019SAndroid Build Coastguard Worker igt_require(__gem_execbuf(fd, &execbuf) == 0);
173*d83cc019SAndroid Build Coastguard Worker
174*d83cc019SAndroid Build Coastguard Worker obj[1].relocation_count = 1;
175*d83cc019SAndroid Build Coastguard Worker obj[2].relocation_count = 1;
176*d83cc019SAndroid Build Coastguard Worker
177*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__wc(fd, obj[1].handle, 0, 64*1024,
178*d83cc019SAndroid Build Coastguard Worker PROT_WRITE | PROT_READ);
179*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[1].handle,
180*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
181*d83cc019SAndroid Build Coastguard Worker
182*d83cc019SAndroid Build Coastguard Worker memset(reloc0, 0, sizeof(reloc0));
183*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < 1024; i++) {
184*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
185*d83cc019SAndroid Build Coastguard Worker uint32_t *b = &ptr[16 * i];
186*d83cc019SAndroid Build Coastguard Worker
187*d83cc019SAndroid Build Coastguard Worker reloc0[i].presumed_offset = obj[0].offset;
188*d83cc019SAndroid Build Coastguard Worker reloc0[i].offset = (b - ptr + 1) * sizeof(*ptr);
189*d83cc019SAndroid Build Coastguard Worker reloc0[i].delta = i * sizeof(uint32_t);
190*d83cc019SAndroid Build Coastguard Worker reloc0[i].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
191*d83cc019SAndroid Build Coastguard Worker reloc0[i].write_domain = I915_GEM_DOMAIN_INSTRUCTION;
192*d83cc019SAndroid Build Coastguard Worker
193*d83cc019SAndroid Build Coastguard Worker offset = obj[0].offset + reloc0[i].delta;
194*d83cc019SAndroid Build Coastguard Worker *b++ = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
195*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
196*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
197*d83cc019SAndroid Build Coastguard Worker *b++ = offset >> 32;
198*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 4) {
199*d83cc019SAndroid Build Coastguard Worker *b++ = 0;
200*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
201*d83cc019SAndroid Build Coastguard Worker reloc0[i].offset += sizeof(*ptr);
202*d83cc019SAndroid Build Coastguard Worker } else {
203*d83cc019SAndroid Build Coastguard Worker b[-1] -= 1;
204*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
205*d83cc019SAndroid Build Coastguard Worker }
206*d83cc019SAndroid Build Coastguard Worker *b++ = i;
207*d83cc019SAndroid Build Coastguard Worker *b++ = MI_BATCH_BUFFER_END;
208*d83cc019SAndroid Build Coastguard Worker }
209*d83cc019SAndroid Build Coastguard Worker munmap(ptr, 64*1024);
210*d83cc019SAndroid Build Coastguard Worker
211*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__wc(fd, obj[2].handle, 0, 64*1024,
212*d83cc019SAndroid Build Coastguard Worker PROT_WRITE | PROT_READ);
213*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[2].handle,
214*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
215*d83cc019SAndroid Build Coastguard Worker
216*d83cc019SAndroid Build Coastguard Worker memset(reloc1, 0, sizeof(reloc1));
217*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < 1024; i++) {
218*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
219*d83cc019SAndroid Build Coastguard Worker uint32_t *b = &ptr[16 * i];
220*d83cc019SAndroid Build Coastguard Worker
221*d83cc019SAndroid Build Coastguard Worker reloc1[i].presumed_offset = obj[0].offset;
222*d83cc019SAndroid Build Coastguard Worker reloc1[i].offset = (b - ptr + 1) * sizeof(*ptr);
223*d83cc019SAndroid Build Coastguard Worker reloc1[i].delta = i * sizeof(uint32_t);
224*d83cc019SAndroid Build Coastguard Worker reloc1[i].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
225*d83cc019SAndroid Build Coastguard Worker reloc1[i].write_domain = I915_GEM_DOMAIN_INSTRUCTION;
226*d83cc019SAndroid Build Coastguard Worker
227*d83cc019SAndroid Build Coastguard Worker offset = obj[0].offset + reloc1[i].delta;
228*d83cc019SAndroid Build Coastguard Worker *b++ = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
229*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
230*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
231*d83cc019SAndroid Build Coastguard Worker *b++ = offset >> 32;
232*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 4) {
233*d83cc019SAndroid Build Coastguard Worker *b++ = 0;
234*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
235*d83cc019SAndroid Build Coastguard Worker reloc1[i].offset += sizeof(*ptr);
236*d83cc019SAndroid Build Coastguard Worker } else {
237*d83cc019SAndroid Build Coastguard Worker b[-1] -= 1;
238*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
239*d83cc019SAndroid Build Coastguard Worker }
240*d83cc019SAndroid Build Coastguard Worker *b++ = i ^ 0xffffffff;
241*d83cc019SAndroid Build Coastguard Worker *b++ = MI_BATCH_BUFFER_END;
242*d83cc019SAndroid Build Coastguard Worker }
243*d83cc019SAndroid Build Coastguard Worker munmap(ptr, 64*1024);
244*d83cc019SAndroid Build Coastguard Worker
245*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(timeout) {
246*d83cc019SAndroid Build Coastguard Worker bool xor = false;
247*d83cc019SAndroid Build Coastguard Worker int idx = cycles++ % 1024;
248*d83cc019SAndroid Build Coastguard Worker
249*d83cc019SAndroid Build Coastguard Worker /* Inspect a different cacheline each iteration */
250*d83cc019SAndroid Build Coastguard Worker i = 16 * (idx % 64) + (idx / 64);
251*d83cc019SAndroid Build Coastguard Worker obj[1].relocs_ptr = to_user_pointer(&reloc0[i]);
252*d83cc019SAndroid Build Coastguard Worker obj[2].relocs_ptr = to_user_pointer(&reloc1[i]);
253*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(reloc0[i].presumed_offset, obj[0].offset);
254*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(reloc1[i].presumed_offset, obj[0].offset);
255*d83cc019SAndroid Build Coastguard Worker execbuf.batch_start_offset = 64*i;
256*d83cc019SAndroid Build Coastguard Worker
257*d83cc019SAndroid Build Coastguard Worker overwrite:
258*d83cc019SAndroid Build Coastguard Worker if ((flags & BEFORE) &&
259*d83cc019SAndroid Build Coastguard Worker !((flags & COHERENT) || gem_has_llc(fd)))
260*d83cc019SAndroid Build Coastguard Worker igt_clflush_range(&map[i], sizeof(map[i]));
261*d83cc019SAndroid Build Coastguard Worker
262*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2 + xor;
263*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
264*d83cc019SAndroid Build Coastguard Worker
265*d83cc019SAndroid Build Coastguard Worker if (flags & SET_DOMAIN) {
266*d83cc019SAndroid Build Coastguard Worker unsigned domain = flags & WC ? I915_GEM_DOMAIN_WC : I915_GEM_DOMAIN_CPU;
267*d83cc019SAndroid Build Coastguard Worker igt_while_interruptible(flags & INTERRUPTIBLE)
268*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[0].handle,
269*d83cc019SAndroid Build Coastguard Worker domain, (flags & WRITE) ? domain : 0);
270*d83cc019SAndroid Build Coastguard Worker
271*d83cc019SAndroid Build Coastguard Worker if (xor)
272*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(map[i], i ^ 0xffffffff);
273*d83cc019SAndroid Build Coastguard Worker else
274*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(map[i], i);
275*d83cc019SAndroid Build Coastguard Worker
276*d83cc019SAndroid Build Coastguard Worker if (flags & WRITE)
277*d83cc019SAndroid Build Coastguard Worker map[i] = 0xdeadbeef;
278*d83cc019SAndroid Build Coastguard Worker } else if (flags & KERNEL) {
279*d83cc019SAndroid Build Coastguard Worker uint32_t val;
280*d83cc019SAndroid Build Coastguard Worker
281*d83cc019SAndroid Build Coastguard Worker igt_while_interruptible(flags & INTERRUPTIBLE)
282*d83cc019SAndroid Build Coastguard Worker gem_read(fd, obj[0].handle,
283*d83cc019SAndroid Build Coastguard Worker i*sizeof(uint32_t),
284*d83cc019SAndroid Build Coastguard Worker &val, sizeof(val));
285*d83cc019SAndroid Build Coastguard Worker
286*d83cc019SAndroid Build Coastguard Worker if (xor)
287*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(val, i ^ 0xffffffff);
288*d83cc019SAndroid Build Coastguard Worker else
289*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(val, i);
290*d83cc019SAndroid Build Coastguard Worker
291*d83cc019SAndroid Build Coastguard Worker if (flags & WRITE) {
292*d83cc019SAndroid Build Coastguard Worker val = 0xdeadbeef;
293*d83cc019SAndroid Build Coastguard Worker igt_while_interruptible(flags & INTERRUPTIBLE)
294*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[0].handle,
295*d83cc019SAndroid Build Coastguard Worker i*sizeof(uint32_t),
296*d83cc019SAndroid Build Coastguard Worker &val, sizeof(val));
297*d83cc019SAndroid Build Coastguard Worker }
298*d83cc019SAndroid Build Coastguard Worker } else if (flags & MOVNT) {
299*d83cc019SAndroid Build Coastguard Worker uint32_t x;
300*d83cc019SAndroid Build Coastguard Worker
301*d83cc019SAndroid Build Coastguard Worker igt_while_interruptible(flags & INTERRUPTIBLE)
302*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, obj[0].handle);
303*d83cc019SAndroid Build Coastguard Worker
304*d83cc019SAndroid Build Coastguard Worker x = movnt(map, i);
305*d83cc019SAndroid Build Coastguard Worker if (xor)
306*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(x, i ^ 0xffffffff);
307*d83cc019SAndroid Build Coastguard Worker else
308*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(x, i);
309*d83cc019SAndroid Build Coastguard Worker
310*d83cc019SAndroid Build Coastguard Worker if (flags & WRITE)
311*d83cc019SAndroid Build Coastguard Worker map[i] = 0xdeadbeef;
312*d83cc019SAndroid Build Coastguard Worker } else {
313*d83cc019SAndroid Build Coastguard Worker igt_while_interruptible(flags & INTERRUPTIBLE)
314*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, obj[0].handle);
315*d83cc019SAndroid Build Coastguard Worker
316*d83cc019SAndroid Build Coastguard Worker if (!(flags & (BEFORE | COHERENT)) &&
317*d83cc019SAndroid Build Coastguard Worker !gem_has_llc(fd))
318*d83cc019SAndroid Build Coastguard Worker igt_clflush_range(&map[i], sizeof(map[i]));
319*d83cc019SAndroid Build Coastguard Worker
320*d83cc019SAndroid Build Coastguard Worker if (xor)
321*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(map[i], i ^ 0xffffffff);
322*d83cc019SAndroid Build Coastguard Worker else
323*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(map[i], i);
324*d83cc019SAndroid Build Coastguard Worker
325*d83cc019SAndroid Build Coastguard Worker if (flags & WRITE) {
326*d83cc019SAndroid Build Coastguard Worker map[i] = 0xdeadbeef;
327*d83cc019SAndroid Build Coastguard Worker if (!(flags & (COHERENT | BEFORE)))
328*d83cc019SAndroid Build Coastguard Worker igt_clflush_range(&map[i], sizeof(map[i]));
329*d83cc019SAndroid Build Coastguard Worker }
330*d83cc019SAndroid Build Coastguard Worker }
331*d83cc019SAndroid Build Coastguard Worker
332*d83cc019SAndroid Build Coastguard Worker if (!xor) {
333*d83cc019SAndroid Build Coastguard Worker xor= true;
334*d83cc019SAndroid Build Coastguard Worker goto overwrite;
335*d83cc019SAndroid Build Coastguard Worker }
336*d83cc019SAndroid Build Coastguard Worker }
337*d83cc019SAndroid Build Coastguard Worker igt_info("Child[%d]: %lu cycles\n", child, cycles);
338*d83cc019SAndroid Build Coastguard Worker
339*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[2].handle);
340*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[1].handle);
341*d83cc019SAndroid Build Coastguard Worker
342*d83cc019SAndroid Build Coastguard Worker munmap(map, 4096);
343*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[0].handle);
344*d83cc019SAndroid Build Coastguard Worker }
345*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
346*d83cc019SAndroid Build Coastguard Worker }
347*d83cc019SAndroid Build Coastguard Worker
348*d83cc019SAndroid Build Coastguard Worker enum batch_mode {
349*d83cc019SAndroid Build Coastguard Worker BATCH_KERNEL,
350*d83cc019SAndroid Build Coastguard Worker BATCH_USER,
351*d83cc019SAndroid Build Coastguard Worker BATCH_CPU,
352*d83cc019SAndroid Build Coastguard Worker BATCH_GTT,
353*d83cc019SAndroid Build Coastguard Worker BATCH_WC,
354*d83cc019SAndroid Build Coastguard Worker };
batch(int fd,unsigned ring,int nchild,int timeout,enum batch_mode mode,unsigned flags)355*d83cc019SAndroid Build Coastguard Worker static void batch(int fd, unsigned ring, int nchild, int timeout,
356*d83cc019SAndroid Build Coastguard Worker enum batch_mode mode, unsigned flags)
357*d83cc019SAndroid Build Coastguard Worker {
358*d83cc019SAndroid Build Coastguard Worker const int gen = intel_gen(intel_get_drm_devid(fd));
359*d83cc019SAndroid Build Coastguard Worker
360*d83cc019SAndroid Build Coastguard Worker if (flags & CMDPARSER) {
361*d83cc019SAndroid Build Coastguard Worker int cmdparser = -1;
362*d83cc019SAndroid Build Coastguard Worker drm_i915_getparam_t gp;
363*d83cc019SAndroid Build Coastguard Worker
364*d83cc019SAndroid Build Coastguard Worker gp.param = I915_PARAM_CMD_PARSER_VERSION;
365*d83cc019SAndroid Build Coastguard Worker gp.value = &cmdparser;
366*d83cc019SAndroid Build Coastguard Worker drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
367*d83cc019SAndroid Build Coastguard Worker igt_require(cmdparser > 0);
368*d83cc019SAndroid Build Coastguard Worker }
369*d83cc019SAndroid Build Coastguard Worker
370*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
371*d83cc019SAndroid Build Coastguard Worker igt_fork(child, nchild) {
372*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
373*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj[2];
374*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc;
375*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
376*d83cc019SAndroid Build Coastguard Worker unsigned long cycles = 0;
377*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr;
378*d83cc019SAndroid Build Coastguard Worker uint32_t *map;
379*d83cc019SAndroid Build Coastguard Worker int i;
380*d83cc019SAndroid Build Coastguard Worker
381*d83cc019SAndroid Build Coastguard Worker memset(obj, 0, sizeof(obj));
382*d83cc019SAndroid Build Coastguard Worker obj[0].handle = gem_create(fd, 4096);
383*d83cc019SAndroid Build Coastguard Worker obj[0].flags |= EXEC_OBJECT_WRITE;
384*d83cc019SAndroid Build Coastguard Worker
385*d83cc019SAndroid Build Coastguard Worker gem_set_caching(fd, obj[0].handle, !!(flags & COHERENT));
386*d83cc019SAndroid Build Coastguard Worker map = gem_mmap__cpu(fd, obj[0].handle, 0, 4096, PROT_WRITE);
387*d83cc019SAndroid Build Coastguard Worker
388*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[0].handle,
389*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU,
390*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU);
391*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < 1024; i++)
392*d83cc019SAndroid Build Coastguard Worker map[i] = 0xabcdabcd;
393*d83cc019SAndroid Build Coastguard Worker
394*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
395*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(obj);
396*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2;
397*d83cc019SAndroid Build Coastguard Worker execbuf.flags = ring | (1 << 11) | (1<<12);
398*d83cc019SAndroid Build Coastguard Worker if (gen < 6)
399*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= I915_EXEC_SECURE;
400*d83cc019SAndroid Build Coastguard Worker
401*d83cc019SAndroid Build Coastguard Worker obj[1].handle = gem_create(fd, 64<<10);
402*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[1].handle, 0, &bbe, sizeof(bbe));
403*d83cc019SAndroid Build Coastguard Worker igt_require(__gem_execbuf(fd, &execbuf) == 0);
404*d83cc019SAndroid Build Coastguard Worker
405*d83cc019SAndroid Build Coastguard Worker obj[1].relocation_count = 1;
406*d83cc019SAndroid Build Coastguard Worker obj[1].relocs_ptr = to_user_pointer(&reloc);
407*d83cc019SAndroid Build Coastguard Worker
408*d83cc019SAndroid Build Coastguard Worker switch (mode) {
409*d83cc019SAndroid Build Coastguard Worker case BATCH_CPU:
410*d83cc019SAndroid Build Coastguard Worker case BATCH_USER:
411*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__cpu(fd, obj[1].handle, 0, 64<<10,
412*d83cc019SAndroid Build Coastguard Worker PROT_WRITE);
413*d83cc019SAndroid Build Coastguard Worker break;
414*d83cc019SAndroid Build Coastguard Worker
415*d83cc019SAndroid Build Coastguard Worker case BATCH_WC:
416*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__wc(fd, obj[1].handle, 0, 64<<10,
417*d83cc019SAndroid Build Coastguard Worker PROT_WRITE);
418*d83cc019SAndroid Build Coastguard Worker break;
419*d83cc019SAndroid Build Coastguard Worker
420*d83cc019SAndroid Build Coastguard Worker case BATCH_GTT:
421*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__gtt(fd, obj[1].handle, 64<<10,
422*d83cc019SAndroid Build Coastguard Worker PROT_WRITE);
423*d83cc019SAndroid Build Coastguard Worker break;
424*d83cc019SAndroid Build Coastguard Worker
425*d83cc019SAndroid Build Coastguard Worker case BATCH_KERNEL:
426*d83cc019SAndroid Build Coastguard Worker ptr = mmap(0, 64<<10, PROT_WRITE,
427*d83cc019SAndroid Build Coastguard Worker MAP_PRIVATE | MAP_ANON, -1, 0);
428*d83cc019SAndroid Build Coastguard Worker break;
429*d83cc019SAndroid Build Coastguard Worker
430*d83cc019SAndroid Build Coastguard Worker default:
431*d83cc019SAndroid Build Coastguard Worker igt_assert(!"reachable");
432*d83cc019SAndroid Build Coastguard Worker ptr = NULL;
433*d83cc019SAndroid Build Coastguard Worker break;
434*d83cc019SAndroid Build Coastguard Worker }
435*d83cc019SAndroid Build Coastguard Worker
436*d83cc019SAndroid Build Coastguard Worker memset(&reloc, 0, sizeof(reloc));
437*d83cc019SAndroid Build Coastguard Worker reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
438*d83cc019SAndroid Build Coastguard Worker reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
439*d83cc019SAndroid Build Coastguard Worker
440*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(timeout) {
441*d83cc019SAndroid Build Coastguard Worker execbuf.batch_start_offset = 0;
442*d83cc019SAndroid Build Coastguard Worker reloc.offset = sizeof(uint32_t);
443*d83cc019SAndroid Build Coastguard Worker if (gen >= 4 && gen < 8)
444*d83cc019SAndroid Build Coastguard Worker reloc.offset += sizeof(uint32_t);
445*d83cc019SAndroid Build Coastguard Worker
446*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < 1024; i++) {
447*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
448*d83cc019SAndroid Build Coastguard Worker uint32_t *start = &ptr[execbuf.batch_start_offset/sizeof(*start)];
449*d83cc019SAndroid Build Coastguard Worker uint32_t *b = start;
450*d83cc019SAndroid Build Coastguard Worker
451*d83cc019SAndroid Build Coastguard Worker switch (mode) {
452*d83cc019SAndroid Build Coastguard Worker case BATCH_CPU:
453*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[1].handle,
454*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
455*d83cc019SAndroid Build Coastguard Worker break;
456*d83cc019SAndroid Build Coastguard Worker
457*d83cc019SAndroid Build Coastguard Worker case BATCH_WC:
458*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[1].handle,
459*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
460*d83cc019SAndroid Build Coastguard Worker break;
461*d83cc019SAndroid Build Coastguard Worker
462*d83cc019SAndroid Build Coastguard Worker case BATCH_GTT:
463*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[1].handle,
464*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
465*d83cc019SAndroid Build Coastguard Worker break;
466*d83cc019SAndroid Build Coastguard Worker
467*d83cc019SAndroid Build Coastguard Worker case BATCH_USER:
468*d83cc019SAndroid Build Coastguard Worker case BATCH_KERNEL:
469*d83cc019SAndroid Build Coastguard Worker break;
470*d83cc019SAndroid Build Coastguard Worker }
471*d83cc019SAndroid Build Coastguard Worker
472*d83cc019SAndroid Build Coastguard Worker reloc.presumed_offset = obj[0].offset;
473*d83cc019SAndroid Build Coastguard Worker reloc.delta = i * sizeof(uint32_t);
474*d83cc019SAndroid Build Coastguard Worker
475*d83cc019SAndroid Build Coastguard Worker offset = reloc.presumed_offset + reloc.delta;
476*d83cc019SAndroid Build Coastguard Worker *b++ = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
477*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
478*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
479*d83cc019SAndroid Build Coastguard Worker *b++ = offset >> 32;
480*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 4) {
481*d83cc019SAndroid Build Coastguard Worker *b++ = 0;
482*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
483*d83cc019SAndroid Build Coastguard Worker } else {
484*d83cc019SAndroid Build Coastguard Worker b[-1] -= 1;
485*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
486*d83cc019SAndroid Build Coastguard Worker }
487*d83cc019SAndroid Build Coastguard Worker *b++ = cycles + i;
488*d83cc019SAndroid Build Coastguard Worker *b++ = MI_BATCH_BUFFER_END;
489*d83cc019SAndroid Build Coastguard Worker
490*d83cc019SAndroid Build Coastguard Worker if (flags & CMDPARSER) {
491*d83cc019SAndroid Build Coastguard Worker execbuf.batch_len =
492*d83cc019SAndroid Build Coastguard Worker (b - start) * sizeof(uint32_t);
493*d83cc019SAndroid Build Coastguard Worker if (execbuf.batch_len & 4)
494*d83cc019SAndroid Build Coastguard Worker execbuf.batch_len += 4;
495*d83cc019SAndroid Build Coastguard Worker }
496*d83cc019SAndroid Build Coastguard Worker
497*d83cc019SAndroid Build Coastguard Worker switch (mode) {
498*d83cc019SAndroid Build Coastguard Worker case BATCH_KERNEL:
499*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[1].handle,
500*d83cc019SAndroid Build Coastguard Worker execbuf.batch_start_offset,
501*d83cc019SAndroid Build Coastguard Worker start, (b - start) * sizeof(uint32_t));
502*d83cc019SAndroid Build Coastguard Worker break;
503*d83cc019SAndroid Build Coastguard Worker
504*d83cc019SAndroid Build Coastguard Worker case BATCH_USER:
505*d83cc019SAndroid Build Coastguard Worker if (!gem_has_llc(fd))
506*d83cc019SAndroid Build Coastguard Worker igt_clflush_range(start,
507*d83cc019SAndroid Build Coastguard Worker (b - start) * sizeof(uint32_t));
508*d83cc019SAndroid Build Coastguard Worker break;
509*d83cc019SAndroid Build Coastguard Worker
510*d83cc019SAndroid Build Coastguard Worker case BATCH_CPU:
511*d83cc019SAndroid Build Coastguard Worker case BATCH_GTT:
512*d83cc019SAndroid Build Coastguard Worker case BATCH_WC:
513*d83cc019SAndroid Build Coastguard Worker break;
514*d83cc019SAndroid Build Coastguard Worker }
515*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
516*d83cc019SAndroid Build Coastguard Worker
517*d83cc019SAndroid Build Coastguard Worker execbuf.batch_start_offset += 64;
518*d83cc019SAndroid Build Coastguard Worker reloc.offset += 64;
519*d83cc019SAndroid Build Coastguard Worker }
520*d83cc019SAndroid Build Coastguard Worker
521*d83cc019SAndroid Build Coastguard Worker if (!(flags & COHERENT)) {
522*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[0].handle,
523*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU,
524*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU);
525*d83cc019SAndroid Build Coastguard Worker } else
526*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, obj[0].handle);
527*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < 1024; i++) {
528*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(map[i], cycles + i);
529*d83cc019SAndroid Build Coastguard Worker map[i] = 0xabcdabcd ^ cycles;
530*d83cc019SAndroid Build Coastguard Worker }
531*d83cc019SAndroid Build Coastguard Worker cycles += 1024;
532*d83cc019SAndroid Build Coastguard Worker
533*d83cc019SAndroid Build Coastguard Worker if (mode == BATCH_USER)
534*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, obj[1].handle);
535*d83cc019SAndroid Build Coastguard Worker }
536*d83cc019SAndroid Build Coastguard Worker igt_info("Child[%d]: %lu cycles\n", child, cycles);
537*d83cc019SAndroid Build Coastguard Worker
538*d83cc019SAndroid Build Coastguard Worker munmap(ptr, 64<<10);
539*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[1].handle);
540*d83cc019SAndroid Build Coastguard Worker
541*d83cc019SAndroid Build Coastguard Worker munmap(map, 4096);
542*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[0].handle);
543*d83cc019SAndroid Build Coastguard Worker }
544*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
545*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
546*d83cc019SAndroid Build Coastguard Worker }
547*d83cc019SAndroid Build Coastguard Worker
yesno(bool x)548*d83cc019SAndroid Build Coastguard Worker static const char *yesno(bool x)
549*d83cc019SAndroid Build Coastguard Worker {
550*d83cc019SAndroid Build Coastguard Worker return x ? "yes" : "no";
551*d83cc019SAndroid Build Coastguard Worker }
552*d83cc019SAndroid Build Coastguard Worker
553*d83cc019SAndroid Build Coastguard Worker igt_main
554*d83cc019SAndroid Build Coastguard Worker {
555*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine *e;
556*d83cc019SAndroid Build Coastguard Worker const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
557*d83cc019SAndroid Build Coastguard Worker const struct batch {
558*d83cc019SAndroid Build Coastguard Worker const char *name;
559*d83cc019SAndroid Build Coastguard Worker unsigned mode;
560*d83cc019SAndroid Build Coastguard Worker } batches[] = {
561*d83cc019SAndroid Build Coastguard Worker { "kernel", BATCH_KERNEL },
562*d83cc019SAndroid Build Coastguard Worker { "user", BATCH_USER },
563*d83cc019SAndroid Build Coastguard Worker { "cpu", BATCH_CPU },
564*d83cc019SAndroid Build Coastguard Worker { "gtt", BATCH_GTT },
565*d83cc019SAndroid Build Coastguard Worker { "wc", BATCH_WC },
566*d83cc019SAndroid Build Coastguard Worker { NULL }
567*d83cc019SAndroid Build Coastguard Worker };
568*d83cc019SAndroid Build Coastguard Worker const struct mode {
569*d83cc019SAndroid Build Coastguard Worker const char *name;
570*d83cc019SAndroid Build Coastguard Worker unsigned flags;
571*d83cc019SAndroid Build Coastguard Worker } modes[] = {
572*d83cc019SAndroid Build Coastguard Worker { "ro", BASIC },
573*d83cc019SAndroid Build Coastguard Worker { "rw", BASIC | WRITE },
574*d83cc019SAndroid Build Coastguard Worker { "ro-before", BEFORE },
575*d83cc019SAndroid Build Coastguard Worker { "rw-before", BEFORE | WRITE },
576*d83cc019SAndroid Build Coastguard Worker { "pro", BASIC | KERNEL },
577*d83cc019SAndroid Build Coastguard Worker { "prw", BASIC | KERNEL | WRITE },
578*d83cc019SAndroid Build Coastguard Worker { "set", BASIC | SET_DOMAIN | WRITE },
579*d83cc019SAndroid Build Coastguard Worker { NULL }
580*d83cc019SAndroid Build Coastguard Worker };
581*d83cc019SAndroid Build Coastguard Worker unsigned cpu = x86_64_features();
582*d83cc019SAndroid Build Coastguard Worker int fd = -1;
583*d83cc019SAndroid Build Coastguard Worker
584*d83cc019SAndroid Build Coastguard Worker igt_fixture {
585*d83cc019SAndroid Build Coastguard Worker igt_require(igt_setup_clflush());
586*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
587*d83cc019SAndroid Build Coastguard Worker igt_require_gem(fd);
588*d83cc019SAndroid Build Coastguard Worker gem_require_mmap_wc(fd);
589*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, 0));
590*d83cc019SAndroid Build Coastguard Worker igt_info("Has LLC? %s\n", yesno(gem_has_llc(fd)));
591*d83cc019SAndroid Build Coastguard Worker
592*d83cc019SAndroid Build Coastguard Worker if (cpu) {
593*d83cc019SAndroid Build Coastguard Worker char str[1024];
594*d83cc019SAndroid Build Coastguard Worker
595*d83cc019SAndroid Build Coastguard Worker igt_info("CPU features: %s\n",
596*d83cc019SAndroid Build Coastguard Worker igt_x86_features_to_string(cpu, str));
597*d83cc019SAndroid Build Coastguard Worker }
598*d83cc019SAndroid Build Coastguard Worker
599*d83cc019SAndroid Build Coastguard Worker igt_fork_hang_detector(fd);
600*d83cc019SAndroid Build Coastguard Worker }
601*d83cc019SAndroid Build Coastguard Worker
602*d83cc019SAndroid Build Coastguard Worker for (e = intel_execution_engines; e->name; e++) igt_subtest_group {
603*d83cc019SAndroid Build Coastguard Worker unsigned ring = e->exec_id | e->flags;
604*d83cc019SAndroid Build Coastguard Worker unsigned timeout = 5 + 120*!!e->exec_id;
605*d83cc019SAndroid Build Coastguard Worker
606*d83cc019SAndroid Build Coastguard Worker igt_fixture {
607*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
608*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, ring));
609*d83cc019SAndroid Build Coastguard Worker }
610*d83cc019SAndroid Build Coastguard Worker
611*d83cc019SAndroid Build Coastguard Worker for (const struct batch *b = batches; b->name; b++) {
612*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%sbatch-%s-%s-uc",
613*d83cc019SAndroid Build Coastguard Worker b == batches && e->exec_id == 0 ? "basic-" : "",
614*d83cc019SAndroid Build Coastguard Worker b->name,
615*d83cc019SAndroid Build Coastguard Worker e->name)
616*d83cc019SAndroid Build Coastguard Worker batch(fd, ring, ncpus, timeout, b->mode, 0);
617*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%sbatch-%s-%s-wb",
618*d83cc019SAndroid Build Coastguard Worker b == batches && e->exec_id == 0 ? "basic-" : "",
619*d83cc019SAndroid Build Coastguard Worker b->name,
620*d83cc019SAndroid Build Coastguard Worker e->name)
621*d83cc019SAndroid Build Coastguard Worker batch(fd, ring, ncpus, timeout, b->mode, COHERENT);
622*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%sbatch-%s-%s-cmd",
623*d83cc019SAndroid Build Coastguard Worker b == batches && e->exec_id == 0 ? "basic-" : "",
624*d83cc019SAndroid Build Coastguard Worker b->name,
625*d83cc019SAndroid Build Coastguard Worker e->name)
626*d83cc019SAndroid Build Coastguard Worker batch(fd, ring, ncpus, timeout, b->mode,
627*d83cc019SAndroid Build Coastguard Worker COHERENT | CMDPARSER);
628*d83cc019SAndroid Build Coastguard Worker }
629*d83cc019SAndroid Build Coastguard Worker
630*d83cc019SAndroid Build Coastguard Worker for (const struct mode *m = modes; m->name; m++) {
631*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%suc-%s-%s",
632*d83cc019SAndroid Build Coastguard Worker (m->flags & BASIC && e->exec_id == 0) ? "basic-" : "",
633*d83cc019SAndroid Build Coastguard Worker m->name,
634*d83cc019SAndroid Build Coastguard Worker e->name)
635*d83cc019SAndroid Build Coastguard Worker run(fd, ring, ncpus, timeout,
636*d83cc019SAndroid Build Coastguard Worker UNCACHED | m->flags);
637*d83cc019SAndroid Build Coastguard Worker
638*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("uc-%s-%s-interruptible",
639*d83cc019SAndroid Build Coastguard Worker m->name,
640*d83cc019SAndroid Build Coastguard Worker e->name)
641*d83cc019SAndroid Build Coastguard Worker run(fd, ring, ncpus, timeout,
642*d83cc019SAndroid Build Coastguard Worker UNCACHED | m->flags | INTERRUPTIBLE);
643*d83cc019SAndroid Build Coastguard Worker
644*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%swb-%s-%s",
645*d83cc019SAndroid Build Coastguard Worker e->exec_id == 0 ? "basic-" : "",
646*d83cc019SAndroid Build Coastguard Worker m->name,
647*d83cc019SAndroid Build Coastguard Worker e->name)
648*d83cc019SAndroid Build Coastguard Worker run(fd, ring, ncpus, timeout,
649*d83cc019SAndroid Build Coastguard Worker COHERENT | m->flags);
650*d83cc019SAndroid Build Coastguard Worker
651*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("wb-%s-%s-interruptible",
652*d83cc019SAndroid Build Coastguard Worker m->name,
653*d83cc019SAndroid Build Coastguard Worker e->name)
654*d83cc019SAndroid Build Coastguard Worker run(fd, ring, ncpus, timeout,
655*d83cc019SAndroid Build Coastguard Worker COHERENT | m->flags | INTERRUPTIBLE);
656*d83cc019SAndroid Build Coastguard Worker
657*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("wc-%s-%s",
658*d83cc019SAndroid Build Coastguard Worker m->name,
659*d83cc019SAndroid Build Coastguard Worker e->name)
660*d83cc019SAndroid Build Coastguard Worker run(fd, ring, ncpus, timeout,
661*d83cc019SAndroid Build Coastguard Worker COHERENT | WC | m->flags);
662*d83cc019SAndroid Build Coastguard Worker
663*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("wc-%s-%s-interruptible",
664*d83cc019SAndroid Build Coastguard Worker m->name,
665*d83cc019SAndroid Build Coastguard Worker e->name)
666*d83cc019SAndroid Build Coastguard Worker run(fd, ring, ncpus, timeout,
667*d83cc019SAndroid Build Coastguard Worker COHERENT | WC | m->flags | INTERRUPTIBLE);
668*d83cc019SAndroid Build Coastguard Worker
669*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("stream-%s-%s",
670*d83cc019SAndroid Build Coastguard Worker m->name,
671*d83cc019SAndroid Build Coastguard Worker e->name) {
672*d83cc019SAndroid Build Coastguard Worker igt_require(cpu & SSE4_1);
673*d83cc019SAndroid Build Coastguard Worker run(fd, ring, ncpus, timeout,
674*d83cc019SAndroid Build Coastguard Worker MOVNT | COHERENT | WC | m->flags);
675*d83cc019SAndroid Build Coastguard Worker }
676*d83cc019SAndroid Build Coastguard Worker
677*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("stream-%s-%s-interruptible",
678*d83cc019SAndroid Build Coastguard Worker m->name,
679*d83cc019SAndroid Build Coastguard Worker e->name) {
680*d83cc019SAndroid Build Coastguard Worker igt_require(cpu & SSE4_1);
681*d83cc019SAndroid Build Coastguard Worker run(fd, ring, ncpus, timeout,
682*d83cc019SAndroid Build Coastguard Worker MOVNT | COHERENT | WC | m->flags | INTERRUPTIBLE);
683*d83cc019SAndroid Build Coastguard Worker }
684*d83cc019SAndroid Build Coastguard Worker }
685*d83cc019SAndroid Build Coastguard Worker }
686*d83cc019SAndroid Build Coastguard Worker
687*d83cc019SAndroid Build Coastguard Worker igt_fixture {
688*d83cc019SAndroid Build Coastguard Worker igt_stop_hang_detector();
689*d83cc019SAndroid Build Coastguard Worker close(fd);
690*d83cc019SAndroid Build Coastguard Worker }
691*d83cc019SAndroid Build Coastguard Worker }
692